UI: AppsPage: Add group options.

This commit is contained in:
Nodir Temirkhodjaev 2019-12-23 12:23:46 +05:00
parent 947a7114f9
commit 7eb2f5ded3
9 changed files with 366 additions and 18 deletions

View File

@ -18,6 +18,7 @@ SOURCES += \
control/controlworker.cpp \ control/controlworker.cpp \
driver/drivermanager.cpp \ driver/drivermanager.cpp \
driver/driverworker.cpp \ driver/driverworker.cpp \
form/controls/checkspincombo.cpp \
form/controls/controlutil.cpp \ form/controls/controlutil.cpp \
form/controls/tabbar.cpp \ form/controls/tabbar.cpp \
form/graph/axistickerspeed.cpp \ form/graph/axistickerspeed.cpp \
@ -108,6 +109,7 @@ HEADERS += \
control/controlworker.h \ control/controlworker.h \
driver/drivermanager.h \ driver/drivermanager.h \
driver/driverworker.h \ driver/driverworker.h \
form/controls/checkspincombo.h \
form/controls/controlutil.h \ form/controls/controlutil.h \
form/controls/tabbar.h \ form/controls/tabbar.h \
form/graph/axistickerspeed.h \ form/graph/axistickerspeed.h \

View File

@ -0,0 +1,85 @@
#include "checkspincombo.h"
#include <QCheckBox>
#include <QComboBox>
#include <QHBoxLayout>
#include <QSpinBox>
CheckSpinCombo::CheckSpinCombo(QWidget *parent) :
QWidget(parent)
{
setupUi();
}
void CheckSpinCombo::setValues(const ValuesList &v)
{
if (m_values != v) {
m_values = v;
emit valuesChanged();
}
}
void CheckSpinCombo::setNames(const QStringList &v)
{
if (m_names != v) {
m_names = v;
emit namesChanged();
}
}
void CheckSpinCombo::setupUi()
{
auto layout = new QHBoxLayout();
m_checkBox = new QCheckBox();
setupSpin();
setupCombo();
layout->addWidget(m_checkBox, 1);
layout->addWidget(m_spinBox);
layout->addWidget(m_comboBox);
this->setLayout(layout);
}
void CheckSpinCombo::setupSpin()
{
m_spinBox = new QSpinBox();
m_spinBox->setMinimumWidth(80);
m_spinBox->setRange(0, 9999);
connect(m_spinBox, QOverload<int>::of(&QSpinBox::valueChanged),
this, &CheckSpinCombo::updateComboBoxIndex);
}
void CheckSpinCombo::setupCombo()
{
m_comboBox = new QComboBox();
connect(m_comboBox, QOverload<int>::of(&QComboBox::activated),
this, &CheckSpinCombo::updateSpinBoxValue);
connect(this, &CheckSpinCombo::namesChanged, [&] {
m_comboBox->clear();
m_comboBox->addItems(names());
updateComboBoxIndex(m_spinBox->value());
});
}
void CheckSpinCombo::updateSpinBoxValue(int index)
{
m_spinBox->setValue(values().at(index));
}
void CheckSpinCombo::updateComboBoxIndex(int value)
{
m_comboBox->setCurrentIndex(getIndexByValue(value));
}
int CheckSpinCombo::getIndexByValue(int value) const
{
const int index = values().indexOf(value);
return (index <= 0) ? 0 : index;
}

View File

@ -0,0 +1,51 @@
#ifndef CHECKSPINCOMBO_H
#define CHECKSPINCOMBO_H
#include <QWidget>
QT_FORWARD_DECLARE_CLASS(QCheckBox)
QT_FORWARD_DECLARE_CLASS(QComboBox)
QT_FORWARD_DECLARE_CLASS(QSpinBox)
using ValuesList = QVector<int>;
class CheckSpinCombo : public QWidget
{
Q_OBJECT
public:
explicit CheckSpinCombo(QWidget *parent = nullptr);
const ValuesList &values() const { return m_values; }
void setValues(const ValuesList &v);
QStringList names() const { return m_names; }
void setNames(const QStringList &v);
QCheckBox *checkBox() const { return m_checkBox; }
QSpinBox *spinBox() const { return m_spinBox; }
QComboBox *comboBox() const { return m_comboBox; }
signals:
void valuesChanged();
void namesChanged();
private:
void setupUi();
void setupSpin();
void setupCombo();
void updateSpinBoxValue(int index);
void updateComboBoxIndex(int value);
int getIndexByValue(int value) const;
private:
ValuesList m_values;
QStringList m_names;
QCheckBox *m_checkBox = nullptr;
QSpinBox *m_spinBox = nullptr;
QComboBox *m_comboBox = nullptr;
};
#endif // CHECKSPINCOMBO_H

View File

@ -165,20 +165,30 @@ void AddressesPage::retranslateAddressesPlaceholderText()
m_excludeAddresses->editIpText()->setPlaceholderText(placeholderText); m_excludeAddresses->editIpText()->setPlaceholderText(placeholderText);
} }
void AddressesPage::setupAddressGroup() void AddressesPage::refreshGroup()
{ {
const auto refreshAddressGroup = [&] {
const int tabIndex = m_tabBar->currentIndex();
m_addressGroup = conf()->addressGroupsList().at(tabIndex);
m_includeAddresses->cbUseAll()->setChecked(addressGroup()->includeAll()); m_includeAddresses->cbUseAll()->setChecked(addressGroup()->includeAll());
m_includeAddresses->editIpText()->setPlainText(addressGroup()->includeText()); m_includeAddresses->editIpText()->setPlainText(addressGroup()->includeText());
m_excludeAddresses->cbUseAll()->setChecked(addressGroup()->excludeAll()); m_excludeAddresses->cbUseAll()->setChecked(addressGroup()->excludeAll());
m_excludeAddresses->editIpText()->setPlainText(addressGroup()->excludeText()); m_excludeAddresses->editIpText()->setPlainText(addressGroup()->excludeText());
}
void AddressesPage::setupAddressGroup()
{
const auto refreshAddressGroup = [&] {
const int tabIndex = m_tabBar->currentIndex();
m_addressGroup = addressGroupByIndex(tabIndex);
refreshGroup();
}; };
refreshAddressGroup(); refreshAddressGroup();
connect(m_tabBar, &QTabBar::currentChanged, this, refreshAddressGroup); connect(m_tabBar, &QTabBar::currentChanged, this, refreshAddressGroup);
} }
AddressGroup *AddressesPage::addressGroupByIndex(int index) const
{
return conf()->addressGroupsList().at(index);
}

View File

@ -14,8 +14,6 @@ public:
explicit AddressesPage(OptionsController *ctrl = nullptr, explicit AddressesPage(OptionsController *ctrl = nullptr,
QWidget *parent = nullptr); QWidget *parent = nullptr);
AddressGroup *addressGroup() const { return m_addressGroup; }
protected slots: protected slots:
void onRetranslateUi() override; void onRetranslateUi() override;
@ -26,8 +24,12 @@ private:
void setupExcludeAddresses(); void setupExcludeAddresses();
void setupAddressesUseAllEnabled(); void setupAddressesUseAllEnabled();
void retranslateAddressesPlaceholderText(); void retranslateAddressesPlaceholderText();
void refreshGroup();
void setupAddressGroup(); void setupAddressGroup();
AddressGroup *addressGroup() const { return m_addressGroup; }
AddressGroup *addressGroupByIndex(int index) const;
private: private:
AddressGroup *m_addressGroup = nullptr; AddressGroup *m_addressGroup = nullptr;

View File

@ -3,15 +3,30 @@
#include <QCheckBox> #include <QCheckBox>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QLineEdit> #include <QLineEdit>
#include <QMenu>
#include <QPushButton> #include <QPushButton>
#include <QSpinBox>
#include <QVBoxLayout> #include <QVBoxLayout>
#include <QWidgetAction>
#include "../../../conf/appgroup.h" #include "../../../conf/appgroup.h"
#include "../../../conf/firewallconf.h" #include "../../../conf/firewallconf.h"
#include "../../../util/net/netutil.h"
#include "../../controls/checkspincombo.h"
#include "../../controls/controlutil.h" #include "../../controls/controlutil.h"
#include "../../controls/tabbar.h" #include "../../controls/tabbar.h"
#include "../optionscontroller.h" #include "../optionscontroller.h"
namespace {
const ValuesList speedLimitValues = {
10, 0, 20, 30, 50, 75, 100, 150, 200, 300, 500, 900,
1024, qRound(1.5 * 1024), 2 * 1024, 3 * 1024, 5 * 1024, qRound(7.5 * 1024),
10 * 1024, 15 * 1024, 20 * 1024, 30 * 1024, 50 * 1024
};
}
ApplicationsPage::ApplicationsPage(OptionsController *ctrl, ApplicationsPage::ApplicationsPage(OptionsController *ctrl,
QWidget *parent) : QWidget *parent) :
BasePage(ctrl, parent) BasePage(ctrl, parent)
@ -27,6 +42,12 @@ void ApplicationsPage::onRetranslateUi()
m_cbBlockAll->setText(tr("Block All")); m_cbBlockAll->setText(tr("Block All"));
m_cbAllowAll->setText(tr("Allow All")); m_cbAllowAll->setText(tr("Allow All"));
m_btGroupOptions->setText(tr("Options"));
m_cscLimitIn->checkBox()->setText(tr("Download speed limit, KiB/s:"));
m_cscLimitOut->checkBox()->setText(tr("Upload speed limit, KiB/s:"));
retranslateGroupLimits();
m_cbFragmentPacket->setText(tr("Fragment first TCP packet"));
} }
void ApplicationsPage::setupUi() void ApplicationsPage::setupUi()
@ -41,6 +62,12 @@ void ApplicationsPage::setupUi()
setupTabBar(); setupTabBar();
layout->addWidget(m_tabBar); layout->addWidget(m_tabBar);
// App Group
auto groupHeader = setupGroupHeader();
layout->addLayout(groupHeader);
setupAppGroup();
layout->addStretch(); layout->addStretch();
this->setLayout(layout); this->setLayout(layout);
@ -107,7 +134,7 @@ void ApplicationsPage::setupRenameGroup()
const int tabIndex = m_tabBar->currentIndex(); const int tabIndex = m_tabBar->currentIndex();
m_tabBar->setTabText(tabIndex, text); m_tabBar->setTabText(tabIndex, text);
appGroup(tabIndex)->setName(text); appGroup()->setName(text);
resetGroupName(); resetGroupName();
ctrl()->setConfEdited(true); ctrl()->setConfEdited(true);
@ -159,7 +186,7 @@ void ApplicationsPage::setupTabBar()
m_tabBar->removeTab(index); m_tabBar->removeTab(index);
} else { } else {
// Reset alone tab to default one // Reset alone tab to default one
m_tabBar->setTabText(0, appGroup(0)->name()); m_tabBar->setTabText(0, appGroup()->name());
} }
ctrl()->setConfEdited(true); ctrl()->setConfEdited(true);
@ -177,14 +204,162 @@ int ApplicationsPage::addTab(const QString &text)
return tabIndex; return tabIndex;
} }
QLayout *ApplicationsPage::setupGroupHeader()
{
auto layout = new QHBoxLayout();
setupGroupOptions();
layout->addWidget(m_btGroupOptions);
layout->addStretch();
return layout;
}
void ApplicationsPage::setupGroupOptions()
{
m_btGroupOptions = new QPushButton();
m_btGroupOptions->setIcon(QIcon(":/images/application_key.png"));
setupGroupLimitIn();
setupGroupLimitOut();
setupGroupFragmentPacket();
// Menu
auto menu = new QMenu(m_btGroupOptions);
auto waLimitIn = new QWidgetAction(this);
waLimitIn->setDefaultWidget(m_cscLimitIn);
menu->addAction(waLimitIn);
auto waLimitOut = new QWidgetAction(this);
waLimitOut->setDefaultWidget(m_cscLimitOut);
menu->addAction(waLimitOut);
menu->addSeparator();
auto waFragmentPacket = new QWidgetAction(this);
waFragmentPacket->setDefaultWidget(m_cbFragmentPacket);
menu->addAction(waFragmentPacket);
m_btGroupOptions->setMenu(menu);
}
void ApplicationsPage::setupGroupLimitIn()
{
m_cscLimitIn = new CheckSpinCombo();
m_cscLimitIn->spinBox()->setRange(0, 99999);
m_cscLimitIn->setValues(speedLimitValues);
connect(m_cscLimitIn->checkBox(), &QCheckBox::toggled, [&](bool checked) {
if (appGroup()->limitInEnabled() == checked)
return;
appGroup()->setLimitInEnabled(checked);
ctrl()->setConfEdited(true);
});
connect(m_cscLimitIn->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), [&](int value) {
const auto speedLimit = quint32(value);
if (appGroup()->speedLimitIn() == speedLimit)
return;
appGroup()->setSpeedLimitIn(speedLimit);
ctrl()->setConfEdited(true);
});
}
void ApplicationsPage::setupGroupLimitOut()
{
m_cscLimitOut = new CheckSpinCombo();
m_cscLimitOut->spinBox()->setRange(0, 99999);
m_cscLimitOut->setValues(speedLimitValues);
connect(m_cscLimitOut->checkBox(), &QCheckBox::toggled, [&](bool checked) {
if (appGroup()->limitOutEnabled() == checked)
return;
appGroup()->setLimitOutEnabled(checked);
ctrl()->setConfEdited(true);
});
connect(m_cscLimitOut->spinBox(), QOverload<int>::of(&QSpinBox::valueChanged), [&](int value) {
const auto speedLimit = quint32(value);
if (appGroup()->speedLimitOut() == speedLimit)
return;
appGroup()->setSpeedLimitOut(speedLimit);
ctrl()->setConfEdited(true);
});
}
void ApplicationsPage::setupGroupFragmentPacket()
{
m_cbFragmentPacket = ControlUtil::createCheckBox(false, [&](bool checked) {
if (appGroup()->fragmentPacket() == checked)
return;
appGroup()->setFragmentPacket(checked);
ctrl()->setConfEdited(true);
});
}
void ApplicationsPage::retranslateGroupLimits()
{
QStringList list;
list.append(tr("Custom"));
list.append(tr("Disabled"));
int index = 0;
for (const int v : speedLimitValues) {
if (++index > 2) {
list.append(formatSpeed(v));
}
}
m_cscLimitIn->setNames(list);
m_cscLimitOut->setNames(list);
}
void ApplicationsPage::refreshGroup()
{
m_cscLimitIn->checkBox()->setChecked(appGroup()->limitInEnabled());
m_cscLimitIn->spinBox()->setValue(int(appGroup()->speedLimitIn()));
m_cscLimitOut->checkBox()->setChecked(appGroup()->limitOutEnabled());
m_cscLimitOut->spinBox()->setValue(int(appGroup()->speedLimitOut()));
m_cbFragmentPacket->setChecked(appGroup()->fragmentPacket());
}
void ApplicationsPage::setupAppGroup()
{
const auto refreshAppGroup = [&] {
const int tabIndex = m_tabBar->currentIndex();
m_appGroup = appGroupByIndex(tabIndex);
refreshGroup();
};
refreshAppGroup();
connect(m_tabBar, &QTabBar::currentChanged, this, refreshAppGroup);
}
int ApplicationsPage::appGroupsCount() const int ApplicationsPage::appGroupsCount() const
{ {
return conf()->appGroupsList().size(); return conf()->appGroupsList().size();
} }
AppGroup *ApplicationsPage::appGroup(int tabIndex) const AppGroup *ApplicationsPage::appGroupByIndex(int index) const
{ {
return conf()->appGroupsList().at(tabIndex); return conf()->appGroupsList().at(index);
} }
void ApplicationsPage::resetGroupName() void ApplicationsPage::resetGroupName()
@ -192,3 +367,8 @@ void ApplicationsPage::resetGroupName()
m_editGroupName->setText(QString()); m_editGroupName->setText(QString());
m_editGroupName->setFocus(); m_editGroupName->setFocus();
} }
QString ApplicationsPage::formatSpeed(int kbytes)
{
return NetUtil::formatSpeed(quint32(kbytes * 1024));
}

View File

@ -5,6 +5,7 @@
QT_FORWARD_DECLARE_CLASS(AppGroup) QT_FORWARD_DECLARE_CLASS(AppGroup)
QT_FORWARD_DECLARE_CLASS(TabBar) QT_FORWARD_DECLARE_CLASS(TabBar)
QT_FORWARD_DECLARE_CLASS(CheckSpinCombo)
class ApplicationsPage : public BasePage class ApplicationsPage : public BasePage
{ {
@ -25,18 +26,35 @@ private:
void setupBlockAllowAll(); void setupBlockAllowAll();
void setupTabBar(); void setupTabBar();
int addTab(const QString &text); int addTab(const QString &text);
QLayout *setupGroupHeader();
void setupGroupOptions();
void setupGroupLimitIn();
void setupGroupLimitOut();
void setupGroupFragmentPacket();
void retranslateGroupLimits();
void refreshGroup();
void setupAppGroup();
int appGroupsCount() const; int appGroupsCount() const;
AppGroup *appGroup(int tabIndex) const; AppGroup *appGroup() const { return m_appGroup; }
AppGroup *appGroupByIndex(int index) const;
void resetGroupName(); void resetGroupName();
static QString formatSpeed(int kbytes);
private: private:
AppGroup *m_appGroup = nullptr;
QLineEdit *m_editGroupName = nullptr; QLineEdit *m_editGroupName = nullptr;
QPushButton *m_btAddGroup = nullptr; QPushButton *m_btAddGroup = nullptr;
QPushButton *m_btRenameGroup = nullptr; QPushButton *m_btRenameGroup = nullptr;
QCheckBox *m_cbBlockAll = nullptr; QCheckBox *m_cbBlockAll = nullptr;
QCheckBox *m_cbAllowAll = nullptr; QCheckBox *m_cbAllowAll = nullptr;
TabBar *m_tabBar = nullptr; TabBar *m_tabBar = nullptr;
QPushButton *m_btGroupOptions = nullptr;
CheckSpinCombo *m_cscLimitIn = nullptr;
CheckSpinCombo *m_cscLimitOut = nullptr;
QCheckBox *m_cbFragmentPacket = nullptr;
}; };
#endif // APPLICATIONSPAGE_H #endif // APPLICATIONSPAGE_H

View File

@ -1,6 +1,6 @@
#include "appscolumn.h" #include "appscolumn.h"
AppsColumn::AppsColumn(QObject *parent) : AppsColumn::AppsColumn(QWidget *parent) :
QObject(parent) QWidget(parent)
{ {
} }

View File

@ -1,14 +1,14 @@
#ifndef APPSCOLUMN_H #ifndef APPSCOLUMN_H
#define APPSCOLUMN_H #define APPSCOLUMN_H
#include <QObject> #include <QWidget>
class AppsColumn : public QObject class AppsColumn : public QWidget
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit AppsColumn(QObject *parent = nullptr); explicit AppsColumn(QWidget *parent = nullptr);
}; };