From 5176bc46be937e15fc5ed0adcba0c7c698d77308 Mon Sep 17 00:00:00 2001 From: Nodir Temirkhodjaev Date: Sat, 16 Dec 2023 08:10:07 +0300 Subject: [PATCH] UI: Extract ZoneSelector --- src/ui/FortFirewallUI.pro | 2 + src/ui/conf/addressgroup.cpp | 50 ++---- src/ui/conf/addressgroup.h | 14 +- src/ui/form/controls/zonesselector.cpp | 158 +++++++++++++++++ src/ui/form/controls/zonesselector.h | 45 +++++ .../opt/pages/addresses/addressescolumn.cpp | 22 +-- .../opt/pages/addresses/addressescolumn.h | 13 +- src/ui/form/opt/pages/addressespage.cpp | 167 +++--------------- src/ui/form/opt/pages/addressespage.h | 16 +- 9 files changed, 262 insertions(+), 225 deletions(-) create mode 100644 src/ui/form/controls/zonesselector.cpp create mode 100644 src/ui/form/controls/zonesselector.h diff --git a/src/ui/FortFirewallUI.pro b/src/ui/FortFirewallUI.pro index 075c41f1..9cc377ec 100644 --- a/src/ui/FortFirewallUI.pro +++ b/src/ui/FortFirewallUI.pro @@ -55,6 +55,7 @@ SOURCES += \ form/controls/tableview.cpp \ form/controls/textarea2splitter.cpp \ form/controls/textarea2splitterhandle.cpp \ + form/controls/zonesselector.cpp \ form/dialog/dialogutil.cpp \ form/dialog/passworddialog.cpp \ form/graph/axistickerspeed.cpp \ @@ -249,6 +250,7 @@ HEADERS += \ form/controls/tableview.h \ form/controls/textarea2splitter.h \ form/controls/textarea2splitterhandle.h \ + form/controls/zonesselector.h \ form/dialog/dialogutil.h \ form/dialog/passworddialog.h \ form/graph/axistickerspeed.h \ diff --git a/src/ui/conf/addressgroup.cpp b/src/ui/conf/addressgroup.cpp index 3c5435bd..88a84793 100644 --- a/src/ui/conf/addressgroup.cpp +++ b/src/ui/conf/addressgroup.cpp @@ -5,40 +5,6 @@ AddressGroup::AddressGroup(QObject *parent) : { } -void AddressGroup::addIncludeZone(int zoneId) -{ - addZone(m_includeZones, zoneId); -} - -void AddressGroup::removeIncludeZone(int zoneId) -{ - removeZone(m_includeZones, zoneId); -} - -void AddressGroup::addExcludeZone(int zoneId) -{ - addZone(m_excludeZones, zoneId); -} - -void AddressGroup::removeExcludeZone(int zoneId) -{ - removeZone(m_excludeZones, zoneId); -} - -void AddressGroup::addZone(quint32 &zones, int zoneId) -{ - zones |= (quint32(1) << (zoneId - 1)); - - setEdited(true); -} - -void AddressGroup::removeZone(quint32 &zones, int zoneId) -{ - zones &= ~(quint32(1) << (zoneId - 1)); - - setEdited(true); -} - void AddressGroup::setIncludeAll(bool includeAll) { if (m_includeAll != includeAll) { @@ -55,6 +21,22 @@ void AddressGroup::setExcludeAll(bool excludeAll) } } +void AddressGroup::setIncludeZones(quint32 v) +{ + if (m_includeZones != v) { + m_includeZones = v; + setEdited(true); + } +} + +void AddressGroup::setExcludeZones(quint32 v) +{ + if (m_excludeZones != v) { + m_excludeZones = v; + setEdited(true); + } +} + void AddressGroup::setIncludeText(const QString &includeText) { if (m_includeText != includeText) { diff --git a/src/ui/conf/addressgroup.h b/src/ui/conf/addressgroup.h index ded98b43..fc02735d 100644 --- a/src/ui/conf/addressgroup.h +++ b/src/ui/conf/addressgroup.h @@ -25,16 +25,10 @@ public: void setId(qint64 id) { m_id = id; } quint32 includeZones() const { return m_includeZones; } - void setIncludeZones(quint32 v) { m_includeZones = v; } + void setIncludeZones(quint32 v); quint32 excludeZones() const { return m_excludeZones; } - void setExcludeZones(quint32 v) { m_excludeZones = v; } - - void addIncludeZone(int zoneId); - void removeIncludeZone(int zoneId); - - void addExcludeZone(int zoneId); - void removeExcludeZone(int zoneId); + void setExcludeZones(quint32 v); QString includeText() const { return m_includeText; } void setIncludeText(const QString &includeText); @@ -47,10 +41,6 @@ public: QVariant toVariant() const; void fromVariant(const QVariant &v); -private: - void addZone(quint32 &zones, int zoneId); - void removeZone(quint32 &zones, int zoneId); - private: bool m_edited : 1; diff --git a/src/ui/form/controls/zonesselector.cpp b/src/ui/form/controls/zonesselector.cpp new file mode 100644 index 00000000..9dfa9c48 --- /dev/null +++ b/src/ui/form/controls/zonesselector.cpp @@ -0,0 +1,158 @@ +#include "zonesselector.h" + +#include + +#include +#include +#include
+#include +#include +#include + +namespace { + +constexpr quint32 getZoneMask(int zoneId) +{ + return quint32(1) << (zoneId - 1); +} + +} + +ZonesSelector::ZonesSelector(QWidget *parent) : QPushButton(parent) +{ + setupUi(); +} + +void ZonesSelector::setZones(quint32 zones) +{ + if (m_zones == zones) + return; + + m_zones = zones; + + retranslateZonesText(); +} + +int ZonesSelector::zonesCount() const +{ + return DriverCommon::bitCount(m_zones); +} + +void ZonesSelector::retranslateUi() +{ + retranslateZonesText(); + + this->setToolTip(tr("Select Zones")); +} + +void ZonesSelector::retranslateZonesText() +{ + this->setText(tr("Zones") + QString(" (%1)").arg(zonesCount())); +} + +void ZonesSelector::setupUi() +{ + setIcon(IconCache::icon(":/icons/ip_class.png")); + + setupZones(); +} + +void ZonesSelector::setupZones() +{ + m_menuZones = ControlUtil::createMenu(this); + this->setMenu(m_menuZones); + + connect(m_menuZones, &QMenu::aboutToShow, this, &ZonesSelector::updateZonesMenu); + + auto confManager = IoC(); + + connect(confManager, &ConfManager::zoneRemoved, this, [&](int zoneId) { + removeZone(zoneId); + retranslateZonesText(); + }); + + auto zoneListModel = IoC(); + + connect(zoneListModel, &ZoneListModel::modelChanged, this, [&] { + clearZonesMenu(); + updateZonesMenuEnabled(); + }); + + updateZonesMenuEnabled(); +} + +void ZonesSelector::clearZonesMenu() +{ + m_menuZones->close(); + m_menuZones->clear(); +} + +void ZonesSelector::createZonesMenu() +{ + auto zoneListModel = IoC(); + + const int zoneCount = zoneListModel->rowCount(); + for (int row = 0; row < zoneCount; ++row) { + const auto zoneRow = zoneListModel->zoneRowAt(row); + + auto action = new QAction(zoneRow.zoneName, m_menuZones); + action->setCheckable(true); + action->setData(zoneRow.zoneId); + + connect(action, &QAction::triggered, this, &ZonesSelector::onZoneClicked); + + m_menuZones->addAction(action); + } +} + +void ZonesSelector::updateZonesMenu() +{ + if (m_menuZones->isEmpty()) { + createZonesMenu(); + } + + const auto actions = m_menuZones->actions(); + + for (auto action : actions) { + const int zoneId = action->data().toInt(); + const quint32 zoneMask = getZoneMask(zoneId); + const bool checked = (m_zones & zoneMask) != 0; + + action->setChecked(checked); + } +} + +void ZonesSelector::updateZonesMenuEnabled() +{ + auto zoneListModel = IoC(); + + const bool isZoneExist = (zoneListModel->rowCount() != 0); + + this->setEnabled(isZoneExist); +} + +void ZonesSelector::addZone(int zoneId) +{ + m_zones |= getZoneMask(zoneId); +} + +void ZonesSelector::removeZone(int zoneId) +{ + m_zones &= ~getZoneMask(zoneId); +} + +void ZonesSelector::onZoneClicked(bool checked) +{ + auto action = qobject_cast(sender()); + const int zoneId = action->data().toInt(); + + if (checked) { + addZone(zoneId); + } else { + removeZone(zoneId); + } + + emit zonesChanged(); + + retranslateZonesText(); +} diff --git a/src/ui/form/controls/zonesselector.h b/src/ui/form/controls/zonesselector.h new file mode 100644 index 00000000..722e8084 --- /dev/null +++ b/src/ui/form/controls/zonesselector.h @@ -0,0 +1,45 @@ +#ifndef ZONESSELECTOR_H +#define ZONESSELECTOR_H + +#include + +class ZonesSelector : public QPushButton +{ + Q_OBJECT + +public: + explicit ZonesSelector(QWidget *parent = nullptr); + + quint32 zones() const { return m_zones; } + void setZones(quint32 zones); + + int zonesCount() const; + + void retranslateUi(); + +signals: + void zonesChanged(); + +private: + void retranslateZonesText(); + + void setupUi(); + void setupZones(); + + void clearZonesMenu(); + void createZonesMenu(); + void updateZonesMenu(); + void updateZonesMenuEnabled(); + + void addZone(int zoneId); + void removeZone(int zoneId); + + void onZoneClicked(bool checked); + +private: + quint32 m_zones = 0; + + QMenu *m_menuZones = nullptr; +}; + +#endif // ZONESSELECTOR_H diff --git a/src/ui/form/opt/pages/addresses/addressescolumn.cpp b/src/ui/form/opt/pages/addresses/addressescolumn.cpp index 6774d1c4..808ea49f 100644 --- a/src/ui/form/opt/pages/addresses/addressescolumn.cpp +++ b/src/ui/form/opt/pages/addresses/addressescolumn.cpp @@ -3,12 +3,12 @@ #include #include #include -#include #include #include #include #include +#include #include #include @@ -17,25 +17,9 @@ AddressesColumn::AddressesColumn(QWidget *parent) : QWidget(parent) setupUi(); } -void AddressesColumn::setZonesCount(qint8 v) -{ - if (m_zonesCount == v) - return; - - m_zonesCount = v; - - retranslateZonesText(); -} - void AddressesColumn::retranslateUi() { - retranslateZonesText(); - m_btSelectZones->setToolTip(tr("Select Zones")); -} - -void AddressesColumn::retranslateZonesText() -{ - m_btSelectZones->setText(tr("Zones") + QString(" (%1)").arg(zonesCount())); + m_btSelectZones->retranslateUi(); } void AddressesColumn::setupUi() @@ -64,7 +48,7 @@ QLayout *AddressesColumn::setupHeaderLayout() m_cbUseAll = new QCheckBox(); // Select Zones - m_btSelectZones = ControlUtil::createButton(":/icons/ip_class.png"); + m_btSelectZones = new ZonesSelector(); auto layout = new QHBoxLayout(); layout->addWidget(m_labelTitle); diff --git a/src/ui/form/opt/pages/addresses/addressescolumn.h b/src/ui/form/opt/pages/addresses/addressescolumn.h index e4ed8cc9..deb95239 100644 --- a/src/ui/form/opt/pages/addresses/addressescolumn.h +++ b/src/ui/form/opt/pages/addresses/addressescolumn.h @@ -5,9 +5,9 @@ QT_FORWARD_DECLARE_CLASS(QCheckBox) QT_FORWARD_DECLARE_CLASS(QLabel) -QT_FORWARD_DECLARE_CLASS(QPushButton) class PlainTextEdit; +class ZonesSelector; class AddressesColumn : public QWidget { @@ -16,29 +16,22 @@ class AddressesColumn : public QWidget public: explicit AddressesColumn(QWidget *parent = nullptr); - qint8 zonesCount() const { return m_zonesCount; } - void setZonesCount(qint8 v); - QLabel *labelTitle() const { return m_labelTitle; } QCheckBox *cbUseAll() const { return m_cbUseAll; } - QPushButton *btSelectZones() const { return m_btSelectZones; } + ZonesSelector *btSelectZones() const { return m_btSelectZones; } PlainTextEdit *editIpText() const { return m_editIpText; } public slots: void retranslateUi(); private: - void retranslateZonesText(); - void setupUi(); QLayout *setupHeaderLayout(); private: - qint8 m_zonesCount = 0; - QLabel *m_labelTitle = nullptr; QCheckBox *m_cbUseAll = nullptr; - QPushButton *m_btSelectZones = nullptr; + ZonesSelector *m_btSelectZones = nullptr; PlainTextEdit *m_editIpText = nullptr; }; diff --git a/src/ui/form/opt/pages/addressespage.cpp b/src/ui/form/opt/pages/addressespage.cpp index 6dea5c50..aa459d53 100644 --- a/src/ui/form/opt/pages/addressespage.cpp +++ b/src/ui/form/opt/pages/addressespage.cpp @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -14,15 +13,14 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include -#include #include #include #include @@ -214,17 +212,6 @@ void AddressesPage::setupSplitterButtons() layout->addWidget(m_btAddLocals, 0, Qt::AlignHCenter); } -void AddressesPage::updateGroup() -{ - m_includeAddresses->cbUseAll()->setChecked(addressGroup()->includeAll()); - m_includeAddresses->editIpText()->setText(addressGroup()->includeText()); - - m_excludeAddresses->cbUseAll()->setChecked(addressGroup()->excludeAll()); - m_excludeAddresses->editIpText()->setText(addressGroup()->excludeText()); - - updateZonesTextAll(); -} - void AddressesPage::setupAddressGroup() { connect(this, &AddressesPage::addressGroupChanged, this, &AddressesPage::updateGroup); @@ -239,127 +226,43 @@ void AddressesPage::setupAddressGroup() connect(m_tabBar, &QTabBar::currentChanged, this, refreshAddressGroup); } -void AddressesPage::clearZonesMenu() -{ - m_menuZones->close(); - m_menuZones->clear(); -} - -void AddressesPage::createZonesMenu() -{ - const auto onZoneActionTriggered = [&](bool checked) { - auto action = qobject_cast(sender()); - const int zoneId = action->data().toInt(); - - const bool include = m_includeAddresses->btSelectZones()->isDown(); - auto addrGroup = this->addressGroup(); - - if (checked) { - if (include) { - addrGroup->addIncludeZone(zoneId); - } else { - addrGroup->addExcludeZone(zoneId); - } - } else { - if (include) { - addrGroup->removeIncludeZone(zoneId); - } else { - addrGroup->removeExcludeZone(zoneId); - } - } - - ctrl()->setOptEdited(); - - updateZonesText(include); - }; - - const int zoneCount = zoneListModel()->rowCount(); - for (int row = 0; row < zoneCount; ++row) { - const auto zoneRow = zoneListModel()->zoneRowAt(row); - - auto action = new QAction(zoneRow.zoneName, m_menuZones); - action->setCheckable(true); - action->setData(zoneRow.zoneId); - - connect(action, &QAction::triggered, this, onZoneActionTriggered); - - m_menuZones->addAction(action); - } -} - -void AddressesPage::updateZonesMenu(bool include) -{ - if (m_menuZones->isEmpty()) { - createZonesMenu(); - } - - const auto actions = m_menuZones->actions(); - if (actions.isEmpty()) - return; - - const quint32 zonesMask = addressGroupZones(include); - - for (auto action : actions) { - const int zoneId = action->data().toInt(); - const quint32 zoneMask = (quint32(1) << (zoneId - 1)); - const bool checked = (zonesMask & zoneMask) != 0; - - action->setChecked(checked); - } -} - -void AddressesPage::updateZonesMenuEnabled() -{ - const bool isZoneExist = (zoneListModel()->rowCount() != 0); - - m_includeAddresses->btSelectZones()->setEnabled(isZoneExist); - m_excludeAddresses->btSelectZones()->setEnabled(isZoneExist); -} - -void AddressesPage::updateZonesText(bool include) -{ - AddressesColumn *addressesColumn = include ? m_includeAddresses : m_excludeAddresses; - - addressesColumn->setZonesCount(zonesCount(include)); -} - -void AddressesPage::updateZonesTextAll() -{ - updateZonesText(/*include=*/true); - updateZonesText(/*include=*/false); -} - void AddressesPage::setupZones() { - m_menuZones = ControlUtil::createMenu(this); + connect(m_includeAddresses->btSelectZones(), &ZonesSelector::zonesChanged, this, [&] { + const quint32 zones = m_includeAddresses->btSelectZones()->zones(); - const auto refreshZonesMenu = [&] { - const bool include = (sender() == m_includeAddresses->btSelectZones()); + if (addressGroup()->includeZones() == zones) + return; - updateZonesMenu(include); - }; + addressGroup()->setIncludeZones(zones); - connect(m_includeAddresses->btSelectZones(), &QPushButton::pressed, this, refreshZonesMenu); - connect(m_excludeAddresses->btSelectZones(), &QPushButton::pressed, this, refreshZonesMenu); - - m_includeAddresses->btSelectZones()->setMenu(m_menuZones); - m_excludeAddresses->btSelectZones()->setMenu(m_menuZones); - updateZonesMenuEnabled(); - - connect(confManager(), &ConfManager::zoneRemoved, this, [&](int zoneId) { - for (auto addrGroup : addressGroups()) { - addrGroup->removeIncludeZone(zoneId); - addrGroup->removeExcludeZone(zoneId); - } - updateZonesTextAll(); + ctrl()->setOptEdited(); }); - connect(zoneListModel(), &ZoneListModel::modelChanged, this, [&] { - clearZonesMenu(); - updateZonesMenuEnabled(); - updateZonesTextAll(); + + connect(m_excludeAddresses->btSelectZones(), &ZonesSelector::zonesChanged, this, [&] { + const quint32 zones = m_excludeAddresses->btSelectZones()->zones(); + + if (addressGroup()->excludeZones() == zones) + return; + + addressGroup()->setExcludeZones(zones); + + ctrl()->setOptEdited(); }); } +void AddressesPage::updateGroup() +{ + m_includeAddresses->cbUseAll()->setChecked(addressGroup()->includeAll()); + m_includeAddresses->editIpText()->setText(addressGroup()->includeText()); + + m_excludeAddresses->cbUseAll()->setChecked(addressGroup()->excludeAll()); + m_excludeAddresses->editIpText()->setText(addressGroup()->excludeText()); + + m_includeAddresses->btSelectZones()->setZones(addressGroup()->includeZones()); + m_excludeAddresses->btSelectZones()->setZones(addressGroup()->excludeZones()); +} + const QList &AddressesPage::addressGroups() const { return conf()->addressGroups(); @@ -369,15 +272,3 @@ AddressGroup *AddressesPage::addressGroupByIndex(int index) const { return addressGroups().at(index); } - -quint32 AddressesPage::addressGroupZones(bool include) const -{ - return include ? addressGroup()->includeZones() : addressGroup()->excludeZones(); -} - -qint8 AddressesPage::zonesCount(bool include) const -{ - const quint32 zonesMask = addressGroupZones(include); - - return DriverCommon::bitCount(zonesMask); -} diff --git a/src/ui/form/opt/pages/addressespage.h b/src/ui/form/opt/pages/addressespage.h index e06d5e6e..0f394bc2 100644 --- a/src/ui/form/opt/pages/addressespage.h +++ b/src/ui/form/opt/pages/addressespage.h @@ -6,6 +6,7 @@ class AddressGroup; class AddressesColumn; class TextArea2Splitter; +class ZonesSelector; class AddressesPage : public OptBasePage { @@ -37,23 +38,15 @@ private: void setupAddressesUseAllEnabled(); void setupSplitter(); void setupSplitterButtons(); - void updateGroup(); + void setupAddressGroup(); - void clearZonesMenu(); - void createZonesMenu(); - void updateZonesMenu(bool include); - void updateZonesMenuEnabled(); - void updateZonesText(bool include); - void updateZonesTextAll(); void setupZones(); + void updateGroup(); + const QList &addressGroups() const; AddressGroup *addressGroupByIndex(int index) const; - quint32 addressGroupZones(bool include) const; - - qint8 zonesCount(bool include) const; - private: int m_addressGroupIndex = -1; @@ -62,7 +55,6 @@ private: AddressesColumn *m_excludeAddresses = nullptr; TextArea2Splitter *m_splitter = nullptr; QToolButton *m_btAddLocals = nullptr; - QMenu *m_menuZones = nullptr; }; #endif // ADDRESSESPAGE_H