diff --git a/src/Gui/ApplicationPy.cpp b/src/Gui/ApplicationPy.cpp index 6b04456f78..d0d5678179 100644 --- a/src/Gui/ApplicationPy.cpp +++ b/src/Gui/ApplicationPy.cpp @@ -1377,6 +1377,8 @@ PyObject* Application::sShowPreferences(PyObject * /*self*/, PyObject *args) wc.restoreCursor(); cDlg.exec(); wc.setWaitCursor(); + cDlg.isRebootRequired(); //The user may have applied first, then clicked the cancel button so it's not in the if(cDlg.exec()) + wc.setWaitCursor(); Py_Return; } diff --git a/src/Gui/CommandStd.cpp b/src/Gui/CommandStd.cpp index 4141b754fd..9af6dab2cf 100644 --- a/src/Gui/CommandStd.cpp +++ b/src/Gui/CommandStd.cpp @@ -383,6 +383,7 @@ void StdCmdDlgPreferences::activated(int iMsg) if (cDlg.exec()) { cDlg.activeGroupPage(groupName, index); } + cDlg.isRebootRequired(); //The user may have applied first, then clicked the cancel button so it's not in the if(cDlg.exec()) } //=========================================================================== diff --git a/src/Gui/DlgPreferencesImp.cpp b/src/Gui/DlgPreferencesImp.cpp index e2b98f5c60..53a2df622c 100644 --- a/src/Gui/DlgPreferencesImp.cpp +++ b/src/Gui/DlgPreferencesImp.cpp @@ -32,6 +32,8 @@ # include # include # include +# include +# include #endif #include @@ -67,7 +69,7 @@ DlgPreferencesImp* DlgPreferencesImp::_activeDialog = nullptr; */ DlgPreferencesImp::DlgPreferencesImp(QWidget* parent, Qt::WindowFlags fl) : QDialog(parent, fl), ui(new Ui_DlgPreferences), - invalidParameter(false), canEmbedScrollArea(true) + invalidParameter(false), canEmbedScrollArea(true), rebootRequired(false) { ui->setupUi(this); QFontMetrics fm(font()); @@ -458,8 +460,10 @@ void DlgPreferencesImp::applyChanges() auto tabWidget = static_cast(ui->tabWidgetStack->widget(i)); for (int j=0; jcount(); j++) { auto page = qobject_cast(tabWidget->widget(j)); - if (page) + if (page) { page->saveSettings(); + rebootRequired = rebootRequired || page->isRebootRequired(); + } } } @@ -471,6 +475,34 @@ void DlgPreferencesImp::applyChanges() } } +void DlgPreferencesImp::isRebootRequired() +{ + if (rebootRequired) { + QMessageBox* restartBox = new QMessageBox(); + restartBox->setIcon(QMessageBox::Warning); + restartBox->setWindowTitle(tr("Restart required")); + restartBox->setText(tr("You must restart FreeCAD for changes to take effect.")); + restartBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + restartBox->setDefaultButton(QMessageBox::Cancel); + auto okBtn = restartBox->button(QMessageBox::Ok); + auto cancelBtn = restartBox->button(QMessageBox::Cancel); + okBtn->setText(tr("Restart now")); + cancelBtn->setText(tr("Restart later")); + + int exec = restartBox->exec(); + + if (exec == QMessageBox::Ok) { + //restart FreeCAD after a delay to give time to this dialog to close + QTimer::singleShot(1000, []() + { + QStringList args = QApplication::arguments(); + if (getMainWindow()->close()) + QProcess::startDetached(QApplication::applicationFilePath(), args); + }); + } + } +} + void DlgPreferencesImp::showEvent(QShowEvent* ev) { this->adjustSize(); diff --git a/src/Gui/DlgPreferencesImp.h b/src/Gui/DlgPreferencesImp.h index 2c5de5d002..0b71d7067c 100644 --- a/src/Gui/DlgPreferencesImp.h +++ b/src/Gui/DlgPreferencesImp.h @@ -125,6 +125,7 @@ public: void reload(); void activateGroupPage(const QString& group, int index); void activeGroupPage(QString& group, int& index) const; + void isRebootRequired(); protected: void changeEvent(QEvent *e) override; @@ -160,6 +161,7 @@ private: std::unique_ptr ui; bool invalidParameter; bool canEmbedScrollArea; + bool rebootRequired; static const int GroupNameRole; /**< A name for our Qt::UserRole, used when storing user data in a list item */ diff --git a/src/Gui/DlgSettingsWorkbenches.ui b/src/Gui/DlgSettingsWorkbenches.ui index a92c528dda..f21e38e188 100644 --- a/src/Gui/DlgSettingsWorkbenches.ui +++ b/src/Gui/DlgSettingsWorkbenches.ui @@ -29,7 +29,7 @@ - <html><head/><body><p>You can enable, disable and reorder workbenches (requires restart). Additional workbenches can be installed through the addon manager.</p><p> + <html><head/><body><p>You can reorder workbenches by drag and drop. Additional workbenches can be installed through the addon manager.</p><p> Currently, your system has the following workbenches:</p></body></html> diff --git a/src/Gui/DlgSettingsWorkbenchesImp.cpp b/src/Gui/DlgSettingsWorkbenchesImp.cpp index 657378b923..87325e126e 100644 --- a/src/Gui/DlgSettingsWorkbenchesImp.cpp +++ b/src/Gui/DlgSettingsWorkbenchesImp.cpp @@ -180,7 +180,7 @@ void wbListItem::setStartupWb(bool val) autoloadCheckBox->setChecked(true); enableCheckBox->setEnabled(!val); - autoloadCheckBox->setEnabled(!val); + autoloadCheckBox->setEnabled(!val && textLabel->isEnabled()); } void wbListItem::setShortcutLabel(int index) @@ -236,8 +236,8 @@ DlgSettingsWorkbenchesImp::DlgSettingsWorkbenchesImp( QWidget* parent ) ui->wbList->setDefaultDropAction(Qt::MoveAction); connect(ui->wbList->model(), &QAbstractItemModel::rowsMoved, this, &DlgSettingsWorkbenchesImp::wbItemMoved); - - connect(ui->AutoloadModuleCombo, QOverload::of(&QComboBox::activated), this, [this](int index) { onStartWbChanged(index); }); + connect(ui->AutoloadModuleCombo, QOverload::of(&QComboBox::activated), this, &DlgSettingsWorkbenchesImp::onStartWbChanged); + connect(ui->WorkbenchSelectorPosition, QOverload::of(&QComboBox::activated), this, &DlgSettingsWorkbenchesImp::onWbSelectorChanged); } /** @@ -330,6 +330,8 @@ Build the list of unloaded workbenches. */ void DlgSettingsWorkbenchesImp::buildWorkbenchList() { + QSignalBlocker sigblk(ui->wbList); + QStringList workbenches = Application::Instance->workbenches(); QStringList enabledWbs = getEnabledWorkbenches(); QStringList disabledWbs = getDisabledWorkbenches(); @@ -437,6 +439,8 @@ void DlgSettingsWorkbenchesImp::saveWorkbenchSelector() void DlgSettingsWorkbenchesImp::loadWorkbenchSelector() { + QSignalBlocker sigblk(ui->WorkbenchSelectorPosition); + //workbench selector position combobox setup ui->WorkbenchSelectorPosition->clear(); ui->WorkbenchSelectorPosition->addItem(tr("Toolbar")); @@ -447,6 +451,8 @@ void DlgSettingsWorkbenchesImp::loadWorkbenchSelector() void DlgSettingsWorkbenchesImp::wbToggled(const QString& wbName, bool enabled) { + requireReboot(); + setStartWorkbenchComboItems(); //reorder the list of items. @@ -519,6 +525,7 @@ void DlgSettingsWorkbenchesImp::setStartWorkbenchComboItems() void DlgSettingsWorkbenchesImp::wbItemMoved() { + requireReboot(); for (int i = 0; i < ui->wbList->count(); i++) { wbListItem* wbItem = dynamic_cast(ui->wbList->itemWidget(ui->wbList->item(i))); if (wbItem) { @@ -527,7 +534,7 @@ void DlgSettingsWorkbenchesImp::wbItemMoved() } } -void Gui::Dialog::DlgSettingsWorkbenchesImp::onStartWbChanged(int index) +void DlgSettingsWorkbenchesImp::onStartWbChanged(int index) { //Update _startupModule QVariant data = ui->AutoloadModuleCombo->itemData(index); @@ -543,5 +550,10 @@ void Gui::Dialog::DlgSettingsWorkbenchesImp::onStartWbChanged(int index) } } +void Gui::Dialog::DlgSettingsWorkbenchesImp::onWbSelectorChanged(int index) +{ + requireReboot(); +} + #include "moc_DlgSettingsWorkbenchesImp.cpp" #include "DlgSettingsWorkbenchesImp.moc" \ No newline at end of file diff --git a/src/Gui/DlgSettingsWorkbenchesImp.h b/src/Gui/DlgSettingsWorkbenchesImp.h index 9a790ef822..4d0fd86d61 100644 --- a/src/Gui/DlgSettingsWorkbenchesImp.h +++ b/src/Gui/DlgSettingsWorkbenchesImp.h @@ -52,6 +52,8 @@ public: protected Q_SLOTS: void wbToggled(const QString& wbName, bool enabled); void wbItemMoved(); + void onWbSelectorChanged(int index); + void onStartWbChanged(int index); protected: void buildWorkbenchList(); @@ -65,7 +67,6 @@ private: void saveWorkbenchSelector(); void loadWorkbenchSelector(); - void onStartWbChanged(int index); std::vector _backgroundAutoloadedModules; std::string _startupModule; diff --git a/src/Gui/PropertyPage.cpp b/src/Gui/PropertyPage.cpp index a26772c23e..8c5154176b 100644 --- a/src/Gui/PropertyPage.cpp +++ b/src/Gui/PropertyPage.cpp @@ -96,7 +96,7 @@ void PropertyPage::onReset() // ---------------------------------------------------------------- /** Construction */ -PreferencePage::PreferencePage(QWidget* parent) : QWidget(parent) +PreferencePage::PreferencePage(QWidget* parent) : QWidget(parent), rebootRequired(false) { } @@ -105,6 +105,18 @@ void PreferencePage::changeEvent(QEvent* event) QWidget::changeEvent(event); } +bool PreferencePage::isRebootRequired() +{ + return rebootRequired; +} + +void PreferencePage::requireReboot() +{ + rebootRequired = true; +} + + + // ---------------------------------------------------------------- PreferenceUiForm::PreferenceUiForm(const QString& fn, QWidget* parent) diff --git a/src/Gui/PropertyPage.h b/src/Gui/PropertyPage.h index 1794c6800f..4afafaa42c 100644 --- a/src/Gui/PropertyPage.h +++ b/src/Gui/PropertyPage.h @@ -71,12 +71,18 @@ public: explicit PreferencePage(QWidget* parent = nullptr); ~PreferencePage() override = default; + bool isRebootRequired(); + void requireReboot(); + public Q_SLOTS: virtual void loadSettings()=0; virtual void saveSettings()=0; protected: void changeEvent(QEvent* event) override = 0; + +private: + bool rebootRequired; }; /** Subclass that embeds a form from a UI file.