From b71c919f2a5cc92cdb8c0f7b0d3a76e268244549 Mon Sep 17 00:00:00 2001 From: Nils Fenner Date: Sun, 7 Aug 2016 04:56:10 +0200 Subject: [PATCH] feat(settings): add RecursiveSignalBlocker can be used to block any signals during settings ui initialization --- qtox.pro | 2 + src/core/recursivesignalblocker.cpp | 60 +++++++++++++++++++++++ src/core/recursivesignalblocker.h | 40 +++++++++++++++ src/widget/form/settings/aboutform.cpp | 18 ++++--- src/widget/form/settings/advancedform.cpp | 14 ++++-- src/widget/form/settings/avform.cpp | 6 ++- src/widget/form/settings/generalform.cpp | 13 +++-- src/widget/form/settings/privacyform.cpp | 28 ++++++----- 8 files changed, 153 insertions(+), 28 deletions(-) create mode 100644 src/core/recursivesignalblocker.cpp create mode 100644 src/core/recursivesignalblocker.h diff --git a/qtox.pro b/qtox.pro index 1327fd25a..8b1becda7 100644 --- a/qtox.pro +++ b/qtox.pro @@ -273,6 +273,7 @@ HEADERS += \ src/core/cstring.h \ src/core/toxid.h \ src/core/indexedlist.h \ + src/core/recursivesignalblocker.h \ src/core/toxcall.h \ src/net/toxuri.h \ src/net/toxdns.h \ @@ -378,6 +379,7 @@ SOURCES += \ src/core/coreencryption.cpp \ src/core/corefile.cpp \ src/core/corestructs.cpp \ + src/core/recursivesignalblocker.cpp \ src/core/toxid.cpp \ src/core/toxcall.cpp \ src/chatlog/chatlog.cpp \ diff --git a/src/core/recursivesignalblocker.cpp b/src/core/recursivesignalblocker.cpp new file mode 100644 index 000000000..0d98a2db0 --- /dev/null +++ b/src/core/recursivesignalblocker.cpp @@ -0,0 +1,60 @@ +/* + Copyright © 2016 by The qTox Project + + This file is part of qTox, a Qt-based graphical interface for Tox. + + qTox is libre software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + qTox is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with qTox. If not, see . +*/ + +#include "recursivesignalblocker.h" + +#include +#include + +/** +@class RecursiveSignalBlocker +@brief Recursively blocks all signals from an object and its children. +@note All children must be created before the blocker is used. + +Wraps a QSignalBlocker on each object. Signals will be unblocked when the +blocker gets destroyed. According to QSignalBlocker, we are also exception safe. +*/ + +/** +@brief Creates a QSignalBlocker recursively on the object and child objects. +@param[in] object the object, which signals should be blocked +*/ +RecursiveSignalBlocker::RecursiveSignalBlocker(QObject* object) +{ + recursiveBlock(object); +} + +RecursiveSignalBlocker::~RecursiveSignalBlocker() +{ + qDeleteAll(mBlockers); +} + +/** +@brief Recursively blocks all signals of the object. +@param[in] object the object to block +*/ +void RecursiveSignalBlocker::recursiveBlock(QObject* object) +{ + mBlockers << new QSignalBlocker(object); + + for (QObject* child : object->children()) + { + recursiveBlock(child); + } +} diff --git a/src/core/recursivesignalblocker.h b/src/core/recursivesignalblocker.h new file mode 100644 index 000000000..34141a6d8 --- /dev/null +++ b/src/core/recursivesignalblocker.h @@ -0,0 +1,40 @@ +/* + Copyright © 2016 by The qTox Project + + This file is part of qTox, a Qt-based graphical interface for Tox. + + qTox is libre software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + qTox is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with qTox. If not, see . +*/ + +#ifndef QTOX_RECURSIVESIGNALBLOCKER_H +#define QTOX_RECURSIVESIGNALBLOCKER_H + +#include + +class QObject; +class QSignalBlocker; + +class RecursiveSignalBlocker +{ +public: + explicit RecursiveSignalBlocker(QObject* object); + ~RecursiveSignalBlocker(); + + void recursiveBlock(QObject* object); + +private: + QVector mBlockers; +}; + +#endif diff --git a/src/widget/form/settings/aboutform.cpp b/src/widget/form/settings/aboutform.cpp index edab523f0..1ef0d0958 100644 --- a/src/widget/form/settings/aboutform.cpp +++ b/src/widget/form/settings/aboutform.cpp @@ -1,5 +1,5 @@ /* - Copyright © 2014-2015 by The qTox Project + Copyright © 2014-2016 by The qTox Project This file is part of qTox, a Qt-based graphical interface for Tox. @@ -17,27 +17,32 @@ along with qTox. If not, see . */ +#include "aboutform.h" #include "ui_aboutsettings.h" -#include "aboutform.h" +#include #include "src/widget/translator.h" #include "tox/tox.h" #include "src/net/autoupdate.h" #include #include -AboutForm::AboutForm() : - GenericForm(QPixmap(":/img/settings/general.png")) +AboutForm::AboutForm() + : GenericForm(QPixmap(":/img/settings/general.png")) + , bodyUI(new Ui::AboutSettings) + , progressTimer(new QTimer(this)) { - bodyUI = new Ui::AboutSettings; bodyUI->setupUi(this); + + // block all child signals during initialization + const RecursiveSignalBlocker signalBlocker(this); + replaceVersions(); if (QString(GIT_VERSION).indexOf(" ") > -1) bodyUI->gitVersion->setOpenExternalLinks(false); showUpdateProgress(); - progressTimer = new QTimer(); progressTimer->setInterval(500); progressTimer->setSingleShot(false); connect(progressTimer, &QTimer::timeout, this, &AboutForm::showUpdateProgress); @@ -107,7 +112,6 @@ void AboutForm::replaceVersions() AboutForm::~AboutForm() { Translator::unregister(this); - delete progressTimer; delete bodyUI; } diff --git a/src/widget/form/settings/advancedform.cpp b/src/widget/form/settings/advancedform.cpp index 58d5e39c9..b48b7aa4f 100644 --- a/src/widget/form/settings/advancedform.cpp +++ b/src/widget/form/settings/advancedform.cpp @@ -1,5 +1,5 @@ /* - Copyright © 2014-2015 by The qTox Project + Copyright © 2014-2016 by The qTox Project This file is part of qTox, a Qt-based graphical interface for Tox. @@ -17,19 +17,23 @@ along with qTox. If not, see . */ +#include "advancedform.h" #include "ui_advancedsettings.h" -#include "advancedform.h" +#include #include "src/persistence/settings.h" #include "src/persistence/db/plaindb.h" #include "src/widget/translator.h" -AdvancedForm::AdvancedForm() : - GenericForm(QPixmap(":/img/settings/general.png")) +AdvancedForm::AdvancedForm() + : GenericForm(QPixmap(":/img/settings/general.png")) + , bodyUI (new Ui::AdvancedSettings) { - bodyUI = new Ui::AdvancedSettings; bodyUI->setupUi(this); + // block all child signals during initialization + const RecursiveSignalBlocker signalBlocker(this); + bodyUI->cbMakeToxPortable->setChecked(Settings::getInstance().getMakeToxPortable()); connect(bodyUI->cbMakeToxPortable, &QCheckBox::stateChanged, this, &AdvancedForm::onMakeToxPortableUpdated); diff --git a/src/widget/form/settings/avform.cpp b/src/widget/form/settings/avform.cpp index cd3b75a4d..06fe7181f 100644 --- a/src/widget/form/settings/avform.cpp +++ b/src/widget/form/settings/avform.cpp @@ -1,5 +1,5 @@ /* - Copyright © 2014-2015 by The qTox Project + Copyright © 2014-2016 by The qTox Project This file is part of qTox, a Qt-based graphical interface for Tox. @@ -28,6 +28,7 @@ #include "src/widget/tool/screenshotgrabber.h" #include "src/core/core.h" #include "src/core/coreav.h" +#include "src/core/recursivesignalblocker.h" #include #include @@ -46,6 +47,9 @@ AVForm::AVForm() { setupUi(this); + // block all child signals during initialization + const RecursiveSignalBlocker signalBlocker(this); + const Audio& audio = Audio::getInstance(); const Settings& s = Settings::getInstance(); diff --git a/src/widget/form/settings/generalform.cpp b/src/widget/form/settings/generalform.cpp index 976a42ed1..85907f2d8 100644 --- a/src/widget/form/settings/generalform.cpp +++ b/src/widget/form/settings/generalform.cpp @@ -17,8 +17,10 @@ along with qTox. If not, see . */ -#include "ui_generalsettings.h" #include "generalform.h" +#include "ui_generalsettings.h" + +#include #include "src/widget/form/settingswidget.h" #include "src/widget/widget.h" #include "src/persistence/settings.h" @@ -104,14 +106,17 @@ static QStringList timeFormats = {"hh:mm AP", "hh:mm", "hh:mm:ss AP", "hh:mm:ss" // http://doc.qt.io/qt-4.8/qdate.html#fromString static QStringList dateFormats = {"yyyy-MM-dd", "dd-MM-yyyy", "d-MM-yyyy", "dddd d-MM-yyyy", "dddd d-MM", "dddd dd MMMM"}; -GeneralForm::GeneralForm(SettingsWidget *myParent) : - GenericForm(QPixmap(":/img/settings/general.png")) +GeneralForm::GeneralForm(SettingsWidget *myParent) + : GenericForm(QPixmap(":/img/settings/general.png")) + , bodyUI(new Ui::GeneralSettings) { parent = myParent; - bodyUI = new Ui::GeneralSettings; bodyUI->setupUi(this); + // block all child signals during initialization + const RecursiveSignalBlocker signalBlocker(this); + Settings& s = Settings::getInstance(); bodyUI->checkUpdates->setVisible(AUTOUPDATE_ENABLED); diff --git a/src/widget/form/settings/privacyform.cpp b/src/widget/form/settings/privacyform.cpp index 6afd7d756..d2a328860 100644 --- a/src/widget/form/settings/privacyform.cpp +++ b/src/widget/form/settings/privacyform.cpp @@ -1,5 +1,5 @@ /* - Copyright © 2014-2015 by The qTox Project + Copyright © 2014-2016 by The qTox Project This file is part of qTox, a Qt-based graphical interface for Tox. @@ -19,26 +19,32 @@ #include "privacyform.h" #include "ui_privacysettings.h" -#include "src/widget/form/settingswidget.h" -#include "src/persistence/settings.h" + #include "src/core/core.h" -#include "src/widget/widget.h" -#include "src/widget/gui.h" -#include "src/widget/form/setpassworddialog.h" -#include "src/widget/translator.h" +#include #include "src/nexus.h" -#include "src/persistence/profile.h" #include "src/persistence/history.h" +#include "src/persistence/profile.h" +#include "src/persistence/settings.h" +#include "src/widget/form/setpassworddialog.h" +#include "src/widget/form/settingswidget.h" +#include "src/widget/gui.h" +#include "src/widget/translator.h" +#include "src/widget/widget.h" + #include #include #include -PrivacyForm::PrivacyForm() : - GenericForm(QPixmap(":/img/settings/privacy.png")) +PrivacyForm::PrivacyForm() + : GenericForm(QPixmap(":/img/settings/privacy.png")) + , bodyUI(new Ui::PrivacySettings) { - bodyUI = new Ui::PrivacySettings; bodyUI->setupUi(this); + // block all child signals during initialization + const RecursiveSignalBlocker signalBlocker(this); + connect(bodyUI->cbTypingNotification, SIGNAL(stateChanged(int)), this, SLOT(onTypingNotificationEnabledUpdated())); connect(bodyUI->cbKeepHistory, SIGNAL(stateChanged(int)), this, SLOT(onEnableLoggingUpdated())); connect(bodyUI->nospamLineEdit, SIGNAL(editingFinished()), this, SLOT(setNospam()));