diff --git a/src/Gui/Action.cpp b/src/Gui/Action.cpp index d2bb7ba96d..bd0e4113c3 100644 --- a/src/Gui/Action.cpp +++ b/src/Gui/Action.cpp @@ -48,7 +48,7 @@ #include "BitmapFactory.h" #include "Command.h" #include "DlgUndoRedo.h" -#include "DlgWorkbenchesImp.h" +#include "DlgSettingsWorkbenchesImp.h" #include "Document.h" #include "EditorView.h" #include "FileDialog.h" @@ -801,8 +801,8 @@ void WorkbenchGroup::setWorkbenchData(int index, const QString& wb) void WorkbenchGroup::refreshWorkbenchList() { QStringList items = Application::Instance->workbenches(); - QStringList enabled_wbs_list = DlgWorkbenchesImp::load_enabled_workbenches(); - QStringList disabled_wbs_list = DlgWorkbenchesImp::load_disabled_workbenches(); + QStringList enabled_wbs_list = DlgSettingsWorkbenchesImp::getEnabledWorkbenches(); + QStringList disabled_wbs_list = DlgSettingsWorkbenchesImp::getDisabledWorkbenches(); QStringList enable_wbs; // Go through the list of enabled workbenches and verify that they really exist because 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/CMakeLists.txt b/src/Gui/CMakeLists.txt index d38d4c8644..76117d2ea5 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -325,13 +325,12 @@ SET(Gui_UIC_SRCS DlgSettingsColorGradient.ui DlgSettingsDocument.ui DlgSettingsImage.ui - DlgSettingsLazyLoaded.ui + DlgSettingsWorkbenches.ui DlgSettingsMacro.ui DlgSettingsNotificationArea.ui DlgSettingsPythonConsole.ui DlgCheckableMessageBox.ui DlgToolbars.ui - DlgWorkbenches.ui DlgTreeWidget.ui DlgLocationAngle.ui DlgLocationPos.ui @@ -526,8 +525,8 @@ SET(Dialog_Customize_CPP_SRCS DlgCustomizeSpNavSettings.cpp DlgKeyboardImp.cpp DlgToolbarsImp.cpp - DlgWorkbenchesImp.cpp QListWidgetCustom.cpp + ListWidgetDragBugFix.cpp ) SET(Dialog_Customize_HPP_SRCS DlgActionsImp.h @@ -537,8 +536,8 @@ SET(Dialog_Customize_HPP_SRCS DlgCustomizeSpNavSettings.h DlgKeyboardImp.h DlgToolbarsImp.h - DlgWorkbenchesImp.h QListWidgetCustom.h + ListWidgetDragBugFix.h ) SET(Dialog_Customize_SRCS ${Dialog_Customize_CPP_SRCS} @@ -549,7 +548,6 @@ SET(Dialog_Customize_SRCS DlgCustomizeSpNavSettings.ui DlgKeyboard.ui DlgToolbars.ui - DlgWorkbenches.ui ) SOURCE_GROUP("Dialog\\Customize" FILES ${Dialog_Customize_SRCS}) @@ -569,7 +567,7 @@ SET(Dialog_Settings_CPP_SRCS DlgSettingsColorGradientImp.cpp DlgSettingsDocumentImp.cpp DlgSettingsImageImp.cpp - DlgSettingsLazyLoadedImp.cpp + DlgSettingsWorkbenchesImp.cpp DlgSettingsMacroImp.cpp DlgSettingsNotificationArea.cpp DlgSettingsPythonConsole.cpp @@ -589,7 +587,7 @@ SET(Dialog_Settings_HPP_SRCS DlgSettingsColorGradientImp.h DlgSettingsDocumentImp.h DlgSettingsImageImp.h - DlgSettingsLazyLoadedImp.h + DlgSettingsWorkbenchesImp.h DlgSettingsMacroImp.h DlgSettingsNotificationArea.h DlgSettingsPythonConsole.h @@ -611,7 +609,7 @@ SET(Dialog_Settings_SRCS DlgSettingsColorGradient.ui DlgSettingsDocument.ui DlgSettingsImage.ui - DlgSettingsLazyLoaded.ui + DlgSettingsWorkbenches.ui DlgSettingsMacro.ui DlgSettingsNotificationArea.ui DlgSettingsPythonConsole.ui diff --git a/src/Gui/CommandStd.cpp b/src/Gui/CommandStd.cpp index 4141b754fd..9d58e84e72 100644 --- a/src/Gui/CommandStd.cpp +++ b/src/Gui/CommandStd.cpp @@ -1,24 +1,26 @@ -/*************************************************************************** - * Copyright (c) 2002 Jürgen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library 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 Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ + // SPDX-License-Identifier: LGPL-2.1-or-later + + /**************************************************************************** + * Copyright (c) 2002 Jürgen Riegel * + * Copyright (c) 2023 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ @@ -383,6 +385,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/DlgGeneral.ui b/src/Gui/DlgGeneral.ui index d2a43592ab..b54c5e08dd 100644 --- a/src/Gui/DlgGeneral.ui +++ b/src/Gui/DlgGeneral.ui @@ -508,43 +508,6 @@ this according to your screen size or personal taste - - - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Workbench selector position : - - - - - - - Customize where the workbench selector appears (restart required). - -'Toolbar': In the toolbars, as a movable toolbar. -'Left Corner': In the menu bar, on the left corner. -'Right Corner': In the menu bar, on the right corner. - - - - - @@ -570,40 +533,6 @@ this according to your screen size or personal taste 6 - - - 0 - - - 0 - - - 0 - - - 0 - - - 6 - - - - - Auto load module after start up: - - - - - - - Choose which workbench will be activated and shown -after FreeCAD launches - - - - - - A Splash screen is a small loading window that is shown diff --git a/src/Gui/DlgGeneralImp.cpp b/src/Gui/DlgGeneralImp.cpp index fcfb8da8f7..bc5edc477e 100644 --- a/src/Gui/DlgGeneralImp.cpp +++ b/src/Gui/DlgGeneralImp.cpp @@ -1,24 +1,26 @@ -/*************************************************************************** - * Copyright (c) 2004 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library 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 Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ +// SPDX-License-Identifier: LGPL-2.1-or-later + + /**************************************************************************** + * Copyright (c) 2004 Werner Mayer * + * Copyright (c) 2023 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ #include "PreCompiled.h" @@ -41,7 +43,6 @@ #include "DlgRevertToBackupConfigImp.h" #include "MainWindow.h" #include "PreferencePackManager.h" -#include "UserSettings.h" #include "Language/Translator.h" using namespace Gui::Dialog; @@ -63,37 +64,6 @@ DlgGeneralImp::DlgGeneralImp( QWidget* parent ) { ui->setupUi(this); - // fills the combo box with all available workbenches - // sorted by their menu text - QStringList work = Application::Instance->workbenches(); - QMap menuText; - for (const auto & it : work) { - QString text = Application::Instance->workbenchMenuText(it); - menuText[text] = it; - } - - { // add special workbench to selection - QPixmap px = Application::Instance->workbenchIcon(QString::fromLatin1("NoneWorkbench")); - QString key = QString::fromLatin1(""); - QString value = QString::fromLatin1("$LastModule"); - if (px.isNull()) { - ui->AutoloadModuleCombo->addItem(key, QVariant(value)); - } - else { - ui->AutoloadModuleCombo->addItem(px, key, QVariant(value)); - } - } - - for (QMap::Iterator it = menuText.begin(); it != menuText.end(); ++it) { - QPixmap px = Application::Instance->workbenchIcon(it.value()); - if (px.isNull()) { - ui->AutoloadModuleCombo->addItem(it.key(), QVariant(it.value())); - } - else { - ui->AutoloadModuleCombo->addItem(px, it.key(), QVariant(it.value())); - } - } - recreatePreferencePackMenu(); connect(ui->ImportConfig, &QPushButton::clicked, this, &DlgGeneralImp::onImportConfigClicked); @@ -178,12 +148,6 @@ void DlgGeneralImp::setDecimalPointConversion(bool on) void DlgGeneralImp::saveSettings() { - int index = ui->AutoloadModuleCombo->currentIndex(); - QVariant data = ui->AutoloadModuleCombo->itemData(index); - QString startWbName = data.toString(); - App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")-> - SetASCII("AutoloadModule", startWbName.toLatin1()); - ui->SubstituteDecimal->onSave(); ui->UseLocaleFormatting->onSave(); ui->RecentFiles->onSave(); @@ -223,8 +187,6 @@ void DlgGeneralImp::saveSettings() hGrp->GetGroup("TreeView")->SetBool("Enabled",treeView); hGrp->GetGroup("PropertyView")->SetBool("Enabled",propertyView); - saveWorkbenchSelector(); - hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow"); hGrp->SetBool("TiledBackground", ui->tiledBackground->isChecked()); @@ -235,12 +197,6 @@ void DlgGeneralImp::saveSettings() void DlgGeneralImp::loadSettings() { - std::string start = App::Application::Config()["StartWorkbench"]; - start = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")-> - GetASCII("AutoloadModule", start.c_str()); - QString startWbName = QLatin1String(start.c_str()); - ui->AutoloadModuleCombo->setCurrentIndex(ui->AutoloadModuleCombo->findData(startWbName)); - ui->SubstituteDecimal->onRestore(); ui->UseLocaleFormatting->onRestore(); ui->RecentFiles->onRestore(); @@ -310,9 +266,6 @@ void DlgGeneralImp::loadSettings() } ui->treeMode->setCurrentIndex(index); - //workbench selector position combobox setup - loadWorkbenchSelector(); - hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow"); ui->tiledBackground->setChecked(hGrp->GetBool("TiledBackground", false)); @@ -509,21 +462,4 @@ void DlgGeneralImp::onLoadPreferencePackClicked(const std::string& packName) } } -void DlgGeneralImp::saveWorkbenchSelector() -{ - //save workbench selector position - auto index = ui->WorkbenchSelectorPosition->currentIndex(); - WorkbenchSwitcher::setIndex(index); -} - -void DlgGeneralImp::loadWorkbenchSelector() -{ - //workbench selector position combobox setup - ui->WorkbenchSelectorPosition->clear(); - ui->WorkbenchSelectorPosition->addItem(tr("Toolbar")); - ui->WorkbenchSelectorPosition->addItem(tr("Left corner")); - ui->WorkbenchSelectorPosition->addItem(tr("Right corner")); - ui->WorkbenchSelectorPosition->setCurrentIndex(WorkbenchSwitcher::getIndex()); -} - #include "moc_DlgGeneralImp.cpp" diff --git a/src/Gui/DlgGeneralImp.h b/src/Gui/DlgGeneralImp.h index c92f9c0fc8..d3aa1afecb 100644 --- a/src/Gui/DlgGeneralImp.h +++ b/src/Gui/DlgGeneralImp.h @@ -1,24 +1,26 @@ -/*************************************************************************** - * Copyright (c) 2004 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library 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 Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ +// SPDX-License-Identifier: LGPL-2.1-or-later + + /**************************************************************************** + * Copyright (c) 2004 Werner Mayer * + * Copyright (c) 2023 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ #ifndef GUI_DIALOG_DLGGENERALIMP_H @@ -69,8 +71,6 @@ private: bool setLanguage(); //Returns true if language has been changed void setNumberLocale(bool force = false); void setDecimalPointConversion(bool on); - void saveWorkbenchSelector(); - void loadWorkbenchSelector(); private: int localeIndex; diff --git a/src/Gui/DlgPreferencesImp.cpp b/src/Gui/DlgPreferencesImp.cpp index e2b98f5c60..4133b00636 100644 --- a/src/Gui/DlgPreferencesImp.cpp +++ b/src/Gui/DlgPreferencesImp.cpp @@ -1,24 +1,26 @@ -/*************************************************************************** - * Copyright (c) 2002 Jürgen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library 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 Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ +// SPDX-License-Identifier: LGPL-2.1-or-later + + /**************************************************************************** + * Copyright (c) 2002 Jürgen Riegel * + * Copyright (c) 2023 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ @@ -32,6 +34,8 @@ # include # include # include +# include +# include #endif #include @@ -67,7 +71,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 +462,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 +477,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..ec3fccfc00 100644 --- a/src/Gui/DlgPreferencesImp.h +++ b/src/Gui/DlgPreferencesImp.h @@ -1,24 +1,26 @@ -/*************************************************************************** - * Copyright (c) 2002 Jürgen Riegel * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library 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 Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ + // SPDX-License-Identifier: LGPL-2.1-or-later + + /**************************************************************************** + * Copyright (c) 2002 Jürgen Riegel * + * Copyright (c) 2023 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ #ifndef GUI_DIALOG_DLGPREFERENCESIMP_H @@ -125,6 +127,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 +163,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/DlgSettings3DView.ui b/src/Gui/DlgSettings3DView.ui index c947251286..138c0bea19 100644 --- a/src/Gui/DlgSettings3DView.ui +++ b/src/Gui/DlgSettings3DView.ui @@ -129,25 +129,6 @@ will be shown at the lower left corner in opened files - - - - If checked, application will remember which workbench is active for each tab of the viewport - - - Remember active workbench by tab - - - false - - - SaveWBbyTab - - - View - - - diff --git a/src/Gui/DlgSettings3DViewImp.cpp b/src/Gui/DlgSettings3DViewImp.cpp index 4bcb3ad5ab..1d5a80320e 100644 --- a/src/Gui/DlgSettings3DViewImp.cpp +++ b/src/Gui/DlgSettings3DViewImp.cpp @@ -82,7 +82,6 @@ void DlgSettings3DViewImp::saveSettings() ui->CheckBox_CornerCoordSystem->onSave(); ui->SpinBox_CornerCoordSystemSize->onSave(); ui->CheckBox_ShowAxisCross->onSave(); - ui->CheckBox_WbByTab->onSave(); ui->CheckBox_ShowFPS->onSave(); ui->spinPickRadius->onSave(); ui->CheckBox_use_SW_OpenGL->onSave(); @@ -100,7 +99,6 @@ void DlgSettings3DViewImp::loadSettings() ui->CheckBox_CornerCoordSystem->onRestore(); ui->SpinBox_CornerCoordSystemSize->onRestore(); ui->CheckBox_ShowAxisCross->onRestore(); - ui->CheckBox_WbByTab->onRestore(); ui->CheckBox_ShowFPS->onRestore(); ui->spinPickRadius->onRestore(); ui->CheckBox_use_SW_OpenGL->onRestore(); diff --git a/src/Gui/DlgSettingsLazyLoaded.ui b/src/Gui/DlgSettingsLazyLoaded.ui deleted file mode 100644 index 34f8232b54..0000000000 --- a/src/Gui/DlgSettingsLazyLoaded.ui +++ /dev/null @@ -1,77 +0,0 @@ - - - Gui::Dialog::DlgSettingsLazyLoaded - - - - 0 - 0 - 607 - 859 - - - - Available Workbenches - - - - - - - 0 - 0 - - - - - 0 - 50 - - - - <html><head/><body><p>To preserve resources, FreeCAD does not load workbenches until they are used. Loading them may provide access to additional preferences related to their functionality.</p><p>The following workbenches are available in your installation:</p></body></html> - - - true - - - - - - - false - - - false - - - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Gui/DlgSettingsLazyLoadedImp.cpp b/src/Gui/DlgSettingsLazyLoadedImp.cpp deleted file mode 100644 index e41bb5d152..0000000000 --- a/src/Gui/DlgSettingsLazyLoadedImp.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2020 Chris Hennes (chennes@pioneerlibrarysystem.org) * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library 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 Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -#include "PreCompiled.h" -#ifndef _PreComp_ -#include -#include -#include -#endif - -#include "DlgSettingsLazyLoadedImp.h" -#include "ui_DlgSettingsLazyLoaded.h" -#include "Application.h" -#include "Workbench.h" -#include "WorkbenchManager.h" - - -using namespace Gui::Dialog; - -const uint DlgSettingsLazyLoadedImp::WorkbenchNameRole = Qt::UserRole; - -// this enum defines the order of the columns -enum Column { - Load, - CheckBox, - Icon, - Name -}; - -/* TRANSLATOR Gui::Dialog::DlgSettingsLazyLoadedImp */ - -/** - * Constructs a DlgSettingsLazyLoadedImp - */ -DlgSettingsLazyLoadedImp::DlgSettingsLazyLoadedImp( QWidget* parent ) - : PreferencePage( parent ) - , ui(new Ui_DlgSettingsLazyLoaded) -{ - ui->setupUi(this); -} - -/** - * Destroys the object and frees any allocated resources - */ -DlgSettingsLazyLoadedImp::~DlgSettingsLazyLoadedImp() -{ -} - - -void DlgSettingsLazyLoadedImp::saveSettings() -{ - std::ostringstream csv; - for (const auto& checkBox : _autoloadCheckBoxes) { - if (checkBox.second->isChecked()) { - if (!csv.str().empty()) - csv << ","; - csv << checkBox.first.toStdString(); - } - } - App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")-> - SetASCII("BackgroundAutoloadModules", csv.str().c_str()); -} - -void DlgSettingsLazyLoadedImp::loadSettings() -{ - // There are two different "autoload" settings: the first, in FreeCAD since 2004, - // controls the module the user sees first when starting FreeCAD, and defaults to the Start workbench - std::string start = App::Application::Config()["StartWorkbench"]; - _startupModule = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")-> - GetASCII("AutoloadModule", start.c_str()); - - // The second autoload setting does a background autoload of any number of other modules - std::string autoloadCSV = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")-> - GetASCII("BackgroundAutoloadModules", ""); - - // Tokenize the comma-separated list - _backgroundAutoloadedModules.clear(); - std::stringstream stream(autoloadCSV); - std::string workbench; - while (std::getline(stream, workbench, ',')) - _backgroundAutoloadedModules.push_back(workbench); - - - buildUnloadedWorkbenchList(); -} - -void DlgSettingsLazyLoadedImp::onLoadClicked(const QString &wbName) -{ - // activate selected workbench - Workbench* originalActiveWB = WorkbenchManager::instance()->active(); - Application::Instance->activateWorkbench(wbName.toStdString().c_str()); - Application::Instance->activateWorkbench(originalActiveWB->name().c_str()); - - // replace load button with loaded indicator - auto wbDisplayName = Application::Instance->workbenchMenuText(wbName); - for (int i = 0; i < ui->workbenchTable->rowCount(); i++) { - QWidget* widget = ui->workbenchTable->cellWidget(i, Name); - auto textLabel = dynamic_cast(widget); - if (textLabel && textLabel->text() == wbDisplayName) { - auto label = new QLabel(tr("Loaded")); - label->setAlignment(Qt::AlignCenter); - ui->workbenchTable->setCellWidget(i, Load, label); - break; - } - } -} - - -/** -Build the list of unloaded workbenches. -*/ -void DlgSettingsLazyLoadedImp::buildUnloadedWorkbenchList() -{ - QStringList workbenches = Application::Instance->workbenches(); - workbenches.sort(); - - ui->workbenchTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); - ui->workbenchTable->setRowCount(0); - _autoloadCheckBoxes.clear(); // setRowCount(0) just invalidated all of these pointers - ui->workbenchTable->setColumnCount(4); - ui->workbenchTable->setSelectionMode(QAbstractItemView::SelectionMode::NoSelection); - ui->workbenchTable->horizontalHeader()->setSectionResizeMode(Icon, QHeaderView::ResizeMode::ResizeToContents); - ui->workbenchTable->horizontalHeader()->setSectionResizeMode(Name, QHeaderView::ResizeMode::Stretch); - ui->workbenchTable->horizontalHeader()->setSectionResizeMode(CheckBox, QHeaderView::ResizeMode::ResizeToContents); - ui->workbenchTable->horizontalHeader()->setSectionResizeMode(Load, QHeaderView::ResizeMode::ResizeToContents); - QStringList columnHeaders; - for (int i = 0; i < 4; i++) { - switch (i) { - case Icon : columnHeaders << QString(); break; - case Name : columnHeaders << tr("Workbench Name"); break; - case CheckBox: columnHeaders << tr("Autoload?"); break; - case Load : columnHeaders << QString(); break; - } - } - ui->workbenchTable->setHorizontalHeaderLabels(columnHeaders); - - unsigned int rowNumber = 0; - for (const auto& wbName : workbenches) { - if (wbName.toStdString() == "NoneWorkbench") - continue; // Do not list the default empty Workbench - - ui->workbenchTable->insertRow(rowNumber); - auto wbTooltip = Application::Instance->workbenchToolTip(wbName); - - // Column 1: Workbench Icon - auto wbIcon = Application::Instance->workbenchIcon(wbName); - auto iconLabel = new QLabel(); - iconLabel->setPixmap(wbIcon.scaled(QSize(20,20), Qt::AspectRatioMode::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation)); - iconLabel->setToolTip(wbTooltip); - iconLabel->setContentsMargins(5, 3, 3, 3); // Left, top, right, bottom - ui->workbenchTable->setCellWidget(rowNumber, Icon, iconLabel); - - // Column 2: Workbench Display Name - auto wbDisplayName = Application::Instance->workbenchMenuText(wbName); - auto textLabel = new QLabel(wbDisplayName); - textLabel->setToolTip(wbTooltip); - ui->workbenchTable->setCellWidget(rowNumber, Name, textLabel); - - // Column 3: Autoloaded checkBox - // - // To get the checkBox centered, we have to jump through some hoops... - auto checkWidget = new QWidget(this); - auto autoloadCheckBox = new QCheckBox(this); - autoloadCheckBox->setToolTip(tr("If checked, %1 will be loaded automatically when FreeCAD starts up").arg(wbDisplayName)); - auto checkLayout = new QHBoxLayout(checkWidget); - checkLayout->addWidget(autoloadCheckBox); - checkLayout->setAlignment(Qt::AlignCenter); - checkLayout->setContentsMargins(0, 0, 0, 0); - - // Figure out whether to check and/or disable this checkBox: - if (wbName.toStdString() == _startupModule) { - autoloadCheckBox->setChecked(true); - autoloadCheckBox->setEnabled(false); - autoloadCheckBox->setToolTip(tr("This is the current startup module, and must be autoloaded. See Preferences/General/Autoload to change.")); - } - else if (std::find(_backgroundAutoloadedModules.begin(), _backgroundAutoloadedModules.end(), - wbName.toStdString()) != _backgroundAutoloadedModules.end()) { - autoloadCheckBox->setChecked(true); - _autoloadCheckBoxes.insert(std::make_pair(wbName, autoloadCheckBox)); - } - else { - _autoloadCheckBoxes.insert(std::make_pair(wbName, autoloadCheckBox)); - } - ui->workbenchTable->setCellWidget(rowNumber, CheckBox, checkWidget); - - // Column 4: Load button/loaded indicator - if (WorkbenchManager::instance()->getWorkbench(wbName.toStdString())) { - auto label = new QLabel(tr("Loaded")); - label->setAlignment(Qt::AlignCenter); - ui->workbenchTable->setCellWidget(rowNumber, Load, label); - } - else { - auto button = new QPushButton(tr("Load now")); - connect(button, &QPushButton::clicked, this, [this,wbName]() { onLoadClicked(wbName); }); - ui->workbenchTable->setCellWidget(rowNumber, Load, button); - } - - ++rowNumber; - } -} - -/** - * Sets the strings of the subwidgets using the current language. - */ -void DlgSettingsLazyLoadedImp::changeEvent(QEvent *e) -{ - if (e->type() == QEvent::LanguageChange) { - ui->retranslateUi(this); - } - else { - QWidget::changeEvent(e); - } -} - -#include "moc_DlgSettingsLazyLoadedImp.cpp" diff --git a/src/Gui/DlgSettingsLazyLoadedImp.h b/src/Gui/DlgSettingsLazyLoadedImp.h deleted file mode 100644 index 75a5e65e2e..0000000000 --- a/src/Gui/DlgSettingsLazyLoadedImp.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2020 Chris Hennes (chennes@pioneerlibrarysystem.org) * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library 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 Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - - -#ifndef GUI_DIALOG_DLGSETTINGSLAZYLOADED_IMP_H -#define GUI_DIALOG_DLGSETTINGSLAZYLOADED_IMP_H - -#include "PropertyPage.h" -#include - -class QCheckBox; - -namespace Gui { -namespace Dialog { -class Ui_DlgSettingsLazyLoaded; - - -/** - * The DlgSettingsLazyLoadedImp class implements a pseudo-preference page explain why - * the remaining preference pages aren't loaded yet, and to help the user do so on demand. - * \author Jürgen Riegel - */ -class DlgSettingsLazyLoadedImp : public PreferencePage -{ - Q_OBJECT - -public: - explicit DlgSettingsLazyLoadedImp( QWidget* parent = nullptr ); - ~DlgSettingsLazyLoadedImp() override; - - void saveSettings() override; - void loadSettings() override; - -protected Q_SLOTS: - void onLoadClicked(const QString& wbName); - -protected: - void buildUnloadedWorkbenchList(); - void changeEvent(QEvent *e) override; - -private: - std::unique_ptr ui; - static const uint WorkbenchNameRole; - - std::vector _backgroundAutoloadedModules; - std::string _startupModule; - std::map _autoloadCheckBoxes; -}; - -} // namespace Dialog -} // namespace Gui - -#endif // GUI_DIALOG_DLGSETTINGSLAZYLOADED_IMP_H diff --git a/src/Gui/DlgSettingsWorkbenches.ui b/src/Gui/DlgSettingsWorkbenches.ui new file mode 100644 index 0000000000..e6eb241d4d --- /dev/null +++ b/src/Gui/DlgSettingsWorkbenches.ui @@ -0,0 +1,150 @@ + + + Gui::Dialog::DlgSettingsWorkbenches + + + + 0 + 0 + 607 + 859 + + + + Available Workbenches + + + + + + + 0 + 0 + + + + + 0 + 50 + + + + <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> + + + true + + + + + + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Start up workbench: + + + + + + + Choose which workbench will be activated and shown +after FreeCAD launches + + + + + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Workbench selector position : + + + + + + + Customize where the workbench selector appears (restart required). + +'Toolbar': In the toolbars, as a movable toolbar. +'Left Corner': In the menu bar, on the left corner. +'Right Corner': In the menu bar, on the right corner. + + + + + + + + + If checked, application will remember which workbench is active for each tab of the viewport + + + Remember active workbench by tab + + + false + + + SaveWBbyTab + + + View + + + + + + + + + ListWidgetDragBugFix + QListWidget +
ListWidgetDragBugFix.h
+
+ + Gui::PrefCheckBox + QCheckBox +
Gui/PrefWidgets.h
+
+
+ + +
diff --git a/src/Gui/DlgSettingsWorkbenchesImp.cpp b/src/Gui/DlgSettingsWorkbenchesImp.cpp new file mode 100644 index 0000000000..d0581c3a04 --- /dev/null +++ b/src/Gui/DlgSettingsWorkbenchesImp.cpp @@ -0,0 +1,576 @@ + // SPDX-License-Identifier: LGPL-2.1-or-later + + /**************************************************************************** + * Copyright (c) 2020 Chris Hennes (chennes@pioneerlibrarysystem.org) * + * Copyright (c) 2023 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +#include +#include +#include +#include +#endif + +#include "DlgSettingsWorkbenchesImp.h" +#include "ui_DlgSettingsWorkbenches.h" +#include "Application.h" +#include "UserSettings.h" +#include "Workbench.h" +#include "WorkbenchManager.h" + + +using namespace Gui::Dialog; + +namespace Gui::Dialog { +class wbListItem : public QWidget +{ + Q_OBJECT + +public: + explicit wbListItem(const QString& wbName, bool enabled, bool startupWb, bool autoLoad, int index, QWidget* parent = nullptr); + ~wbListItem() override; + + bool isEnabled(); + bool isAutoLoading(); + void setStartupWb(bool val); + + void setShortcutLabel(int index); + +protected Q_SLOTS: + void onLoadClicked(); + void onWbToggled(bool checked); + +Q_SIGNALS: + void wbToggled(const QString& wbName, bool enabled); + +private: + QCheckBox* enableCheckBox; + QCheckBox* autoloadCheckBox; + QLabel* iconLabel; + QLabel* textLabel; + QLabel* shortcutLabel; + QLabel* loadLabel; + QPushButton* loadButton; +}; +} + +wbListItem::wbListItem(const QString& wbName, bool enabled, bool startupWb, bool autoLoad, int index, QWidget* parent) : QWidget(parent) +{ + this->setObjectName(wbName); + + auto wbTooltip = Application::Instance->workbenchToolTip(wbName); + auto wbDisplayName = Application::Instance->workbenchMenuText(wbName); + + // 1: Enable checkbox + enableCheckBox = new QCheckBox(this); + enableCheckBox->setToolTip(tr("If unchecked, %1 will not appear in the available workbenches.").arg(wbDisplayName)); + enableCheckBox->setChecked(enabled); + if (startupWb) { + enableCheckBox->setChecked(true); + enableCheckBox->setEnabled(false); + enableCheckBox->setToolTip(tr("This is the current startup module, and must be enabled. See Preferences/General/Autoload to change.")); + } + connect(enableCheckBox, &QCheckBox::toggled, this, [this](bool checked) { onWbToggled(checked); }); + + QWidget* subWidget = new QWidget(this); + // 2: Workbench Icon + auto wbIcon = Application::Instance->workbenchIcon(wbName); + iconLabel = new QLabel(wbDisplayName, this); + iconLabel->setPixmap(wbIcon.scaled(QSize(20, 20), Qt::AspectRatioMode::KeepAspectRatio, Qt::TransformationMode::SmoothTransformation)); + iconLabel->setToolTip(wbTooltip); + iconLabel->setContentsMargins(5, 0, 0, 5); // Left, top, right, bottom + iconLabel->setEnabled(enableCheckBox->isChecked()); + + // 3: Workbench Display Name + textLabel = new QLabel(wbDisplayName, this); + textLabel->setToolTip(wbTooltip); + QFont font = textLabel->font(); + font.setBold(true); + textLabel->setFont(font); + textLabel->setEnabled(enableCheckBox->isChecked()); + + // 4: shortcut + shortcutLabel = new QLabel(QString::fromLatin1("(W, %1)").arg(index + 1), this); + shortcutLabel->setToolTip(tr("Shortcut to activate this workbench.")); + shortcutLabel->setEnabled(enableCheckBox->isChecked()); + shortcutLabel->setVisible(index < 9); + + auto subLayout = new QHBoxLayout(subWidget); + subLayout->addWidget(iconLabel); + subLayout->addWidget(textLabel); + subLayout->addWidget(shortcutLabel); + subLayout->setAlignment(Qt::AlignLeft); + subLayout->setContentsMargins(5, 0, 0, 5); + subWidget->setMinimumSize(250, 0); + + // 5: Autoloaded checkBox. + autoloadCheckBox = new QCheckBox(this); + autoloadCheckBox->setText(tr("Auto-load")); + autoloadCheckBox->setToolTip(tr("If checked, %1 will be loaded automatically when FreeCAD starts up").arg(wbDisplayName)); + autoloadCheckBox->setEnabled(enableCheckBox->isChecked()); + + if (startupWb) { // Figure out whether to check and/or disable this checkBox: + autoloadCheckBox->setChecked(true); + autoloadCheckBox->setEnabled(false); + autoloadCheckBox->setToolTip(tr("This is the current startup module, and must be autoloaded. See Preferences/General/Autoload to change.")); + } + else if (autoLoad) { + autoloadCheckBox->setChecked(true); + } + + // 6: Load button/loaded indicator + loadLabel = new QLabel(tr("Loaded"), this); + loadLabel->setAlignment(Qt::AlignCenter); + loadLabel->setEnabled(enableCheckBox->isChecked()); + loadButton = new QPushButton(tr("Load"), this); + loadButton->setToolTip(tr("To preserve resources, FreeCAD does not load workbenches until they are used. Loading them may provide access to additional preferences related to their functionality.")); + loadButton->setEnabled(enableCheckBox->isChecked()); + connect(loadButton, &QPushButton::clicked, this, [this]() { onLoadClicked(); }); + if (WorkbenchManager::instance()->getWorkbench(wbName.toStdString())) { + loadButton->setVisible(false); + } + else { + loadLabel->setVisible(false); + } + + auto layout = new QHBoxLayout(this); + layout->addWidget(enableCheckBox); + layout->addWidget(subWidget); + layout->addWidget(autoloadCheckBox); + layout->addWidget(loadButton); + layout->addWidget(loadLabel); + layout->setAlignment(Qt::AlignLeft); + layout->setContentsMargins(10, 0, 0, 0); +} + +wbListItem::~wbListItem() +{ +} + +bool wbListItem::isEnabled() +{ + return enableCheckBox->isChecked(); +} + +bool wbListItem::isAutoLoading() +{ + return autoloadCheckBox->isChecked(); +} + +void wbListItem::setStartupWb(bool val) +{ + if(val) + autoloadCheckBox->setChecked(true); + + enableCheckBox->setEnabled(!val); + autoloadCheckBox->setEnabled(!val && textLabel->isEnabled()); +} + +void wbListItem::setShortcutLabel(int index) +{ + shortcutLabel->setText(QString::fromLatin1("(W, %1)").arg(index + 1)); + shortcutLabel->setVisible(index < 9); +} + +void wbListItem::onLoadClicked() +{ + // activate selected workbench + Workbench* originalActiveWB = WorkbenchManager::instance()->active(); + Application::Instance->activateWorkbench(objectName().toStdString().c_str()); + Application::Instance->activateWorkbench(originalActiveWB->name().c_str()); + + // replace load button with loaded indicator + loadButton->setVisible(false); + loadLabel->setVisible(true); +} + +void wbListItem::onWbToggled(bool checked) +{ + // activate/deactivate the widgets + iconLabel->setEnabled(checked); + textLabel->setEnabled(checked); + shortcutLabel->setEnabled(checked); + loadLabel->setEnabled(checked); + loadButton->setEnabled(checked); + autoloadCheckBox->setEnabled(checked); + if (!checked) //disabling wb disable auto-load. + autoloadCheckBox->setChecked(false); + + // Reset the start combo items. + Q_EMIT wbToggled(objectName(), checked); +} + +/* TRANSLATOR Gui::Dialog::DlgSettingsWorkbenchesImp */ + +/** + * Constructs a DlgSettingsWorkbenchesImp + */ +DlgSettingsWorkbenchesImp::DlgSettingsWorkbenchesImp( QWidget* parent ) + : PreferencePage( parent ) + , ui(new Ui_DlgSettingsWorkbenches) +{ + ui->setupUi(this); + + ui->wbList->setDragDropMode(QAbstractItemView::InternalMove); + ui->wbList->setSelectionMode(QAbstractItemView::SingleSelection); + ui->wbList->viewport()->setAcceptDrops(true); + ui->wbList->setDropIndicatorShown(true); + ui->wbList->setDragEnabled(true); + ui->wbList->setDefaultDropAction(Qt::MoveAction); + + connect(ui->wbList->model(), &QAbstractItemModel::rowsMoved, this, &DlgSettingsWorkbenchesImp::wbItemMoved); + connect(ui->AutoloadModuleCombo, QOverload::of(&QComboBox::activated), this, &DlgSettingsWorkbenchesImp::onStartWbChanged); + connect(ui->WorkbenchSelectorPosition, QOverload::of(&QComboBox::activated), this, &DlgSettingsWorkbenchesImp::onWbSelectorChanged); + connect(ui->CheckBox_WbByTab, &QCheckBox::toggled, this, &DlgSettingsWorkbenchesImp::onWbByTabToggled); +} + +/** + * Destroys the object and frees any allocated resources + */ +DlgSettingsWorkbenchesImp::~DlgSettingsWorkbenchesImp() +{ +} + + +void DlgSettingsWorkbenchesImp::saveSettings() +{ + std::ostringstream enabledStr, disabledStr, autoloadStr; + + auto addStrToOss = [](std::string wbName, std::ostringstream& oss) { + if (!oss.str().empty()) + oss << ","; + oss << wbName; + }; + + for (int i = 0; i < ui->wbList->count(); i++) { + wbListItem* wbItem = dynamic_cast(ui->wbList->itemWidget(ui->wbList->item(i))); + if (!wbItem) + continue; + std::string wbName = wbItem->objectName().toStdString(); + + if (wbItem->isEnabled()) { + addStrToOss(wbName, enabledStr); + } + else { + addStrToOss(wbName, disabledStr); + } + + if (wbItem->isAutoLoading()) { + addStrToOss(wbName, autoloadStr); + } + } + + if (enabledStr.str().empty()) //make sure that we have at least one enabled workbench. + enabledStr << "NoneWorkbench"; + else { + addStrToOss("NoneWorkbench", disabledStr); //Note, NoneWorkbench is not in the table so it's not added before. + } + + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Workbenches"); + hGrp->SetASCII("Enabled", enabledStr.str().c_str()); + hGrp->SetASCII("Disabled", disabledStr.str().c_str()); + + App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")-> + SetASCII("BackgroundAutoloadModules", autoloadStr.str().c_str()); + + saveWorkbenchSelector(); + + int index = ui->AutoloadModuleCombo->currentIndex(); + QVariant data = ui->AutoloadModuleCombo->itemData(index); + QString startWbName = data.toString(); + App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")-> + SetASCII("AutoloadModule", startWbName.toLatin1()); + + ui->CheckBox_WbByTab->onSave(); +} + +void DlgSettingsWorkbenchesImp::loadSettings() +{ + loadWorkbenchSelector(); + + // There are two different "autoload" settings: the first, in FreeCAD since 2004, + // controls the module the user sees first when starting FreeCAD, and defaults to the Start workbench + std::string start = App::Application::Config()["StartWorkbench"]; + _startupModule = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")-> + GetASCII("AutoloadModule", start.c_str()); + + // The second autoload setting does a background autoload of any number of other modules + std::string autoloadCSV = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General")-> + GetASCII("BackgroundAutoloadModules", ""); + + // Tokenize the comma-separated list + _backgroundAutoloadedModules.clear(); + std::stringstream stream(autoloadCSV); + std::string workbench; + while (std::getline(stream, workbench, ',')) + _backgroundAutoloadedModules.push_back(workbench); + + buildWorkbenchList(); + + //We set the startup setting after building the list so that we can put only the enabled wb. + setStartWorkbenchComboItems(); + + { + QSignalBlocker sigblk(ui->CheckBox_WbByTab); + ui->CheckBox_WbByTab->onRestore(); + } +} + +/** +Build the list of unloaded workbenches. +*/ +void DlgSettingsWorkbenchesImp::buildWorkbenchList() +{ + QSignalBlocker sigblk(ui->wbList); + + QStringList workbenches = Application::Instance->workbenches(); + QStringList enabledWbs = getEnabledWorkbenches(); + QStringList disabledWbs = getDisabledWorkbenches(); + + //First we add the enabled wbs in their saved order. + for (const auto& wbName : enabledWbs) { + if (workbenches.contains(wbName)) { + addWorkbench(wbName, true); + } + else { + Base::Console().Warning("Ignoring unknown %s workbench found in user preferences.", wbName.toStdString().c_str()); + } + } + //Second we add workbench in alphabetical order that are either Disabled, or !enabled && !disabled, ie newly added wb. + for (const auto& wbName : workbenches) { + if (disabledWbs.contains(wbName)) { + addWorkbench(wbName, false); + } + else if (!enabledWbs.contains(wbName)) { + Base::Console().Warning("Adding unknown %s workbench.", wbName.toStdString().c_str()); + addWorkbench(wbName, false); + } + } +} + +void DlgSettingsWorkbenchesImp::addWorkbench(const QString& wbName, bool enabled) +{ + if (wbName.toStdString() == "NoneWorkbench") + return; // Do not list the default empty Workbench + + bool isStartupWb = wbName.toStdString() == _startupModule; + bool autoLoad = std::find(_backgroundAutoloadedModules.begin(), _backgroundAutoloadedModules.end(), + wbName.toStdString()) != _backgroundAutoloadedModules.end(); + wbListItem* widget = new wbListItem(wbName, enabled, isStartupWb, autoLoad, ui->wbList->count(), this); + connect(widget, &wbListItem::wbToggled, this, &DlgSettingsWorkbenchesImp::wbToggled); + auto wItem = new QListWidgetItem(); + wItem->setSizeHint(widget->sizeHint()); + ui->wbList->addItem(wItem); + ui->wbList->setItemWidget(wItem, widget); +} + + +QStringList DlgSettingsWorkbenchesImp::getEnabledWorkbenches() +{ + QString enabled_wbs; + QStringList enabled_wbs_list; + ParameterGrp::handle hGrp; + QString allWorkbenches = QString::fromLatin1("ALL"); + + hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Workbenches"); + enabled_wbs = QString::fromStdString(hGrp->GetASCII("Enabled", allWorkbenches.toStdString().c_str()).c_str()); +#if QT_VERSION >= QT_VERSION_CHECK(5,15,0) + enabled_wbs_list = enabled_wbs.split(QLatin1String(","), Qt::SkipEmptyParts); +#else + enabled_wbs_list = enabled_wbs.split(QLatin1String(","), QString::SkipEmptyParts); +#endif + + if (enabled_wbs_list.at(0) == allWorkbenches) { + enabled_wbs_list.removeFirst(); + QStringList workbenches = Application::Instance->workbenches(); + for (QStringList::Iterator it = workbenches.begin(); it != workbenches.end(); ++it) { + enabled_wbs_list.append(*it); + } + enabled_wbs_list.sort(); + } + return enabled_wbs_list; +} + +QStringList DlgSettingsWorkbenchesImp::getDisabledWorkbenches() +{ + QString disabled_wbs; + QStringList disabled_wbs_list; + ParameterGrp::handle hGrp; + + hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Workbenches"); + disabled_wbs = QString::fromStdString(hGrp->GetASCII("Disabled", "")); +#if QT_VERSION >= QT_VERSION_CHECK(5,15,0) + disabled_wbs_list = disabled_wbs.split(QLatin1String(","), Qt::SkipEmptyParts); +#else + disabled_wbs_list = disabled_wbs.split(QLatin1String(","), QString::SkipEmptyParts); +#endif + + return disabled_wbs_list; +} + +/** + * Sets the strings of the subwidgets using the current language. + */ +void DlgSettingsWorkbenchesImp::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(this); + } + else { + QWidget::changeEvent(e); + } +} + +void DlgSettingsWorkbenchesImp::saveWorkbenchSelector() +{ + //save workbench selector position + auto index = ui->WorkbenchSelectorPosition->currentIndex(); + WorkbenchSwitcher::setIndex(index); +} + +void DlgSettingsWorkbenchesImp::loadWorkbenchSelector() +{ + QSignalBlocker sigblk(ui->WorkbenchSelectorPosition); + + //workbench selector position combobox setup + ui->WorkbenchSelectorPosition->clear(); + ui->WorkbenchSelectorPosition->addItem(tr("Toolbar")); + ui->WorkbenchSelectorPosition->addItem(tr("Left corner")); + ui->WorkbenchSelectorPosition->addItem(tr("Right corner")); + ui->WorkbenchSelectorPosition->setCurrentIndex(WorkbenchSwitcher::getIndex()); +} + +void DlgSettingsWorkbenchesImp::wbToggled(const QString& wbName, bool enabled) +{ + requireReboot(); + + setStartWorkbenchComboItems(); + + //reorder the list of items. + int wbIndex = 0; + for (int i = 0; i < ui->wbList->count(); i++) { + wbListItem* wbItem = dynamic_cast(ui->wbList->itemWidget(ui->wbList->item(i))); + if (wbItem && wbItem->objectName() == wbName) { + wbIndex = i; + } + } + + int destinationIndex = ui->wbList->count(); + + for (int i = 0; i < ui->wbList->count(); i++) { + wbListItem* wbItem = dynamic_cast(ui->wbList->itemWidget(ui->wbList->item(i))); + if (wbItem && !wbItem->isEnabled() && (enabled || ((wbItem->objectName()).toStdString() > wbName.toStdString()))) { + //If the wb was enabled, then it was in the disabled wbs. So it moves to the row of the currently first disabled wb + //If the wb was disabled. Then it goes to the disabled wb where it belongs alphabetically. + destinationIndex = i; + break; + } + } + ui->wbList->model()->moveRow(QModelIndex(), wbIndex, QModelIndex(), destinationIndex); + +} + +void DlgSettingsWorkbenchesImp::setStartWorkbenchComboItems() +{ + ui->AutoloadModuleCombo->clear(); + + // fills the combo box with activated workbenches. + QStringList enabledWbs; + for (int i = 0; i < ui->wbList->count(); i++) { + wbListItem* wbItem = dynamic_cast(ui->wbList->itemWidget(ui->wbList->item(i))); + if (wbItem && wbItem->isEnabled()) { + enabledWbs << wbItem->objectName(); + } + } + + QMap menuText; + for (const auto& it : enabledWbs) { + QString text = Application::Instance->workbenchMenuText(it); + menuText[text] = it; + } + + { // add special workbench to selection + QPixmap px = Application::Instance->workbenchIcon(QString::fromLatin1("NoneWorkbench")); + QString key = QString::fromLatin1(""); + QString value = QString::fromLatin1("$LastModule"); + if (px.isNull()) { + ui->AutoloadModuleCombo->addItem(key, QVariant(value)); + } + else { + ui->AutoloadModuleCombo->addItem(px, key, QVariant(value)); + } + } + + for (QMap::Iterator it = menuText.begin(); it != menuText.end(); ++it) { + QPixmap px = Application::Instance->workbenchIcon(it.value()); + if (px.isNull()) { + ui->AutoloadModuleCombo->addItem(it.key(), QVariant(it.value())); + } + else { + ui->AutoloadModuleCombo->addItem(px, it.key(), QVariant(it.value())); + } + } + + ui->AutoloadModuleCombo->setCurrentIndex(ui->AutoloadModuleCombo->findData(QString::fromStdString(_startupModule))); +} + +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) { + wbItem->setShortcutLabel(i); + } + } +} + +void DlgSettingsWorkbenchesImp::onStartWbChanged(int index) +{ + //Update _startupModule + QVariant data = ui->AutoloadModuleCombo->itemData(index); + QString wbName = data.toString(); + _startupModule = wbName.toStdString(); + + //Change wb that user can't deactivate. + for (int i = 0; i < ui->wbList->count(); i++) { + wbListItem* wbItem = dynamic_cast(ui->wbList->itemWidget(ui->wbList->item(i))); + if (wbItem) { + wbItem->setStartupWb(wbItem->objectName() == wbName); + } + } +} + +void DlgSettingsWorkbenchesImp::onWbSelectorChanged(int index) +{ + Q_UNUSED(index); + requireReboot(); +} + +void DlgSettingsWorkbenchesImp::onWbByTabToggled(bool val) +{ + Q_UNUSED(val); + 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 new file mode 100644 index 0000000000..ce91a31034 --- /dev/null +++ b/src/Gui/DlgSettingsWorkbenchesImp.h @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/**************************************************************************** +* Copyright (c) 2020 Chris Hennes (chennes@pioneerlibrarysystem.org) * +* Copyright (c) 2023 FreeCAD Project Association * +* * +* This file is part of FreeCAD. * +* * +* FreeCAD is free software: you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as * +* published by the Free Software Foundation, either version 2.1 of the * +* License, or (at your option) any later version. * +* * +* FreeCAD 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 * +* Lesser General Public License for more details. * +* * +* You should have received a copy of the GNU Lesser General Public * +* License along with FreeCAD. If not, see * +* . * +* * +***************************************************************************/ + + +#ifndef GUI_DIALOG_DLGSETTINGSWORKBENCHES_IMP_H +#define GUI_DIALOG_DLGSETTINGSWORKBENCHES_IMP_H + +#include "PropertyPage.h" +#include + +namespace Gui::Dialog { +class Ui_DlgSettingsWorkbenches; + +/** + * The DlgSettingsWorkbenchesImp class implements a pseudo-preference page explain why + * the remaining preference pages aren't loaded yet, and to help the user do so on demand. + * \author Jürgen Riegel + */ +class DlgSettingsWorkbenchesImp : public PreferencePage +{ + Q_OBJECT + +public: + explicit DlgSettingsWorkbenchesImp( QWidget* parent = nullptr ); + ~DlgSettingsWorkbenchesImp() override; + + void saveSettings() override; + void loadSettings() override; + + static QStringList getEnabledWorkbenches(); + static QStringList getDisabledWorkbenches(); + +protected Q_SLOTS: + void wbToggled(const QString& wbName, bool enabled); + void wbItemMoved(); + void onWbSelectorChanged(int index); + void onStartWbChanged(int index); + void onWbByTabToggled(bool val); + +protected: + void buildWorkbenchList(); + void changeEvent(QEvent *e) override; + +private: + void addWorkbench(const QString& it, bool enabled); + + void setStartWorkbenchComboItems(); + + void saveWorkbenchSelector(); + void loadWorkbenchSelector(); + + + std::vector _backgroundAutoloadedModules; + std::string _startupModule; + + std::unique_ptr ui; +}; + +} // namespace Gui::Dialog + +#endif // GUI_DIALOG_DLGSETTINGSWORKBENCHES_IMP_H diff --git a/src/Gui/DlgWorkbenches.ui b/src/Gui/DlgWorkbenches.ui deleted file mode 100644 index 328f7d9fa3..0000000000 --- a/src/Gui/DlgWorkbenches.ui +++ /dev/null @@ -1,289 +0,0 @@ - - - Gui::Dialog::DlgWorkbenches - - - - 0 - 0 - 421 - 354 - - - - Workbenches - - - - 9 - - - 6 - - - - - 6 - - - 0 - - - - - Disabled workbenches - - - - - - - - - - - - 6 - - - 0 - - - - - Enabled workbenches - - - - - - - - - - - - true - - - - 30 - 30 - - - - Move right - - - <html><head/><body><p><span style=" font-weight:600;">Move the selected workbench to enabled workbenches.</span></p></body></html> - - - - - - - :/icons/button_right.svg:/icons/button_right.svg - - - - - - - true - - - - 30 - 30 - - - - Move up - - - <html><head/><body><p><span style=" font-weight:600;">Move the selected item up.</span></p><p>The item will be moved up.</p></body></html> - - - - - - - :/icons/button_up.svg:/icons/button_up.svg - - - - - - - true - - - - 30 - 30 - - - - Add all to enabled workbenches - - - <html><head/><body><p><span style=" font-weight:600;">Remove the selected workbench from enabled workbenches</span></p></body></html> - - - - - - - :/icons/button_add_all.svg:/icons/button_add_all.svg - - - true - - - false - - - - - - - true - - - - 30 - 30 - - - - Sort enabled workbenches - - - <p>Sort enabled workbenches</p> - - - - - - - :/icons/button_sort.svg:/icons/button_sort.svg - - - true - - - - - - - true - - - - 30 - 30 - - - - Move left - - - <html><head/><body><p><span style=" font-weight:600;">Remove the selected workbench from enabled workbenches</span></p></body></html> - - - - - - - :/icons/button_left.svg:/icons/button_left.svg - - - true - - - false - - - - - - - true - - - - 30 - 30 - - - - Move down - - - <html><head/><body><p><span style=" font-weight:600;">Move the selected item down.</span></p><p>The item will be moved down</p></body></html> - - - - - - - :/icons/button_down.svg:/icons/button_down.svg - - - true - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 33 - 57 - - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 33 - 57 - - - - - - - - <html><head/><body><p><span style=" font-size:8pt; font-weight:600;">Note:</span><span style=" font-family:'MS Shell Dlg 2'; font-size:8pt;"> The changes become active the next time you start the application</span></p></body></html> - - - - - - - - QListWidgetCustom - QListWidget -
QListWidgetCustom.h
-
-
- - - - -
diff --git a/src/Gui/DlgWorkbenchesImp.cpp b/src/Gui/DlgWorkbenchesImp.cpp deleted file mode 100644 index 45da472f35..0000000000 --- a/src/Gui/DlgWorkbenchesImp.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2015 FreeCAD Developers * - * Author: Przemo Firszt * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library 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 Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -// Based on DlgToolbars.cpp - -#include "PreCompiled.h" - -#ifndef _PreComp_ -# include -# include -#endif - -#include "DlgWorkbenchesImp.h" -#include "ui_DlgWorkbenches.h" -#include "Application.h" -#include "QListWidgetCustom.h" - - -using namespace Gui::Dialog; - -const QString DlgWorkbenchesImp::all_workbenches = QString::fromLatin1("ALL"); - -/* TRANSLATOR Gui::Dialog::DlgWorkbenchesImp */ - -DlgWorkbenchesImp::DlgWorkbenchesImp(QWidget* parent) - : CustomizeActionPage(parent) - , ui(new Ui_DlgWorkbenches) -{ - ui->setupUi(this); - set_lw_properties(ui->lw_enabled_workbenches); - set_lw_properties(ui->lw_disabled_workbenches); - ui->lw_disabled_workbenches->setProperty("OnlyAcceptFrom", - QStringList() << ui->lw_enabled_workbenches->objectName()); - ui->lw_disabled_workbenches->setSortingEnabled(true); - - ui->lw_enabled_workbenches->setProperty("OnlyAcceptFrom", - QStringList() << ui->lw_enabled_workbenches->objectName() - << ui->lw_disabled_workbenches->objectName()); - - QStringList enabled_wbs_list = load_enabled_workbenches(); - QStringList disabled_wbs_list = load_disabled_workbenches(); - QStringList workbenches = Application::Instance->workbenches(); - - for (QStringList::Iterator it = enabled_wbs_list.begin(); it != enabled_wbs_list.end(); ++it) { - if (workbenches.contains(*it)) { - add_workbench(ui->lw_enabled_workbenches, *it); - } else { - qDebug() << "Ignoring unknown" << *it << "workbench found in user preferences."; - } - } - for (QStringList::Iterator it = workbenches.begin(); it != workbenches.end(); ++it) { - if (disabled_wbs_list.contains(*it)){ - add_workbench(ui->lw_disabled_workbenches, *it); - } else if (!enabled_wbs_list.contains(*it)){ - qDebug() << "Adding unknown " << *it << "workbench."; - add_workbench(ui->lw_enabled_workbenches, *it); - } - } - ui->lw_enabled_workbenches->setCurrentRow(0); - ui->lw_disabled_workbenches->setCurrentRow(0); -} - -/** Destroys the object and frees any allocated resources */ -DlgWorkbenchesImp::~DlgWorkbenchesImp() -{ -} - -void DlgWorkbenchesImp::set_lw_properties(QListWidgetCustom *lw) -{ - lw->setDragDropMode(QAbstractItemView::DragDrop); - lw->setSelectionMode(QAbstractItemView::SingleSelection); - lw->viewport()->setAcceptDrops(true); - lw->setDropIndicatorShown(true); - lw->setDragEnabled(true); - lw->setDefaultDropAction(Qt::MoveAction); -} - -void DlgWorkbenchesImp::add_workbench(QListWidgetCustom *lw, const QString& it) -{ - QPixmap px = Application::Instance->workbenchIcon(it); - QString mt = Application::Instance->workbenchMenuText(it); - auto wi = (new QListWidgetItem(QIcon(px), mt)); - wi->setData(Qt::UserRole, QVariant(it)); - lw->addItem(wi); -} - -void DlgWorkbenchesImp::changeEvent(QEvent *e) -{ - if (e->type() == QEvent::LanguageChange) { - ui->retranslateUi(this); - } - else { - QWidget::changeEvent(e); - } -} - -void DlgWorkbenchesImp::hideEvent(QHideEvent * event) -{ - Q_UNUSED(event); - save_workbenches(); -} - -void DlgWorkbenchesImp::onAddMacroAction(const QByteArray& macro) -{ - Q_UNUSED(macro); -} - -void DlgWorkbenchesImp::onRemoveMacroAction(const QByteArray& macro) -{ - Q_UNUSED(macro); -} - -void DlgWorkbenchesImp::onModifyMacroAction(const QByteArray& macro) -{ - Q_UNUSED(macro); -} - -void DlgWorkbenchesImp::move_workbench(QListWidgetCustom *lwc_dest, - QListWidgetItem *wi) -{ - QListWidgetItem* item = wi->clone(); - lwc_dest->addItem(item); - lwc_dest->setCurrentItem(item); - delete wi; -} - -void DlgWorkbenchesImp::on_add_to_enabled_workbenches_btn_clicked() -{ - QListWidgetItem* ci = ui->lw_disabled_workbenches->currentItem(); - if (ci) { - move_workbench(ui->lw_enabled_workbenches, ci); - } -} - -void DlgWorkbenchesImp::on_remove_from_enabled_workbenches_btn_clicked() -{ - QListWidgetItem* ci = ui->lw_enabled_workbenches->currentItem(); - if (ci) { - move_workbench(ui->lw_disabled_workbenches, ci); - } -} - -void DlgWorkbenchesImp::shift_workbench(bool up) -{ - int direction; - if (up){ - direction = -1; - } else { - direction = 1; - } - if (ui->lw_enabled_workbenches->currentItem()) { - int index = ui->lw_enabled_workbenches->currentRow(); - QListWidgetItem *item = ui->lw_enabled_workbenches->takeItem(index); - ui->lw_enabled_workbenches->insertItem(index + direction, item); - ui->lw_enabled_workbenches->setCurrentRow(index + direction); - } -} - -void DlgWorkbenchesImp::on_shift_workbench_up_btn_clicked() -{ - shift_workbench(true); -} - -void DlgWorkbenchesImp::on_shift_workbench_down_btn_clicked() -{ - shift_workbench(false); -} - -void DlgWorkbenchesImp::on_sort_enabled_workbenches_btn_clicked() -{ - ui->lw_enabled_workbenches->sortItems(); -} - -void DlgWorkbenchesImp::on_add_all_to_enabled_workbenches_btn_clicked() -{ - while (ui->lw_disabled_workbenches->count() > 0) { - QListWidgetItem* item = ui->lw_disabled_workbenches->item(0); - move_workbench(ui->lw_enabled_workbenches, item); - } -} - -QStringList DlgWorkbenchesImp::load_enabled_workbenches() -{ - QString enabled_wbs; - QStringList enabled_wbs_list; - ParameterGrp::handle hGrp; - - hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Workbenches"); - enabled_wbs = QString::fromStdString(hGrp->GetASCII("Enabled", all_workbenches.toStdString().c_str()).c_str()); -#if QT_VERSION >= QT_VERSION_CHECK(5,15,0) - enabled_wbs_list = enabled_wbs.split(QLatin1String(","), Qt::SkipEmptyParts); -#else - enabled_wbs_list = enabled_wbs.split(QLatin1String(","), QString::SkipEmptyParts); -#endif - - if (enabled_wbs_list.at(0) == all_workbenches) { - enabled_wbs_list.removeFirst(); - QStringList workbenches = Application::Instance->workbenches(); - for (QStringList::Iterator it = workbenches.begin(); it != workbenches.end(); ++it) { - enabled_wbs_list.append(*it); - } - enabled_wbs_list.sort(); - } - return enabled_wbs_list; -} - -QStringList DlgWorkbenchesImp::load_disabled_workbenches() -{ - QString disabled_wbs; - QStringList disabled_wbs_list; - ParameterGrp::handle hGrp; - - hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Workbenches"); - disabled_wbs = QString::fromStdString(hGrp->GetASCII("Disabled", "")); -#if QT_VERSION >= QT_VERSION_CHECK(5,15,0) - disabled_wbs_list = disabled_wbs.split(QLatin1String(","), Qt::SkipEmptyParts); -#else - disabled_wbs_list = disabled_wbs.split(QLatin1String(","), QString::SkipEmptyParts); -#endif - - return disabled_wbs_list; -} - -void DlgWorkbenchesImp::save_workbenches() -{ - QString enabled_wbs; - QString disabled_wbs; - ParameterGrp::handle hGrp; - - hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Workbenches"); - hGrp->Clear(); - - if (ui->lw_enabled_workbenches->count() == 0) { - enabled_wbs.append(QString::fromLatin1("NoneWorkbench")); - } else { - for (int i = 0; i < ui->lw_enabled_workbenches->count(); i++) { - QVariant item_data = ui->lw_enabled_workbenches->item(i)->data(Qt::UserRole); - QString name = item_data.toString(); - enabled_wbs.append(name + QString::fromLatin1(",")); - } - } - hGrp->SetASCII("Enabled", enabled_wbs.toLatin1()); - - for (int i = 0; i < ui->lw_disabled_workbenches->count(); i++) { - QVariant item_data = ui->lw_disabled_workbenches->item(i)->data(Qt::UserRole); - QString name = item_data.toString(); - disabled_wbs.append(name + QString::fromLatin1(",")); - } - hGrp->SetASCII("Disabled", disabled_wbs.toLatin1()); -} - -#include "moc_DlgWorkbenchesImp.cpp" - diff --git a/src/Gui/DlgWorkbenchesImp.h b/src/Gui/DlgWorkbenchesImp.h deleted file mode 100644 index dc3cf907e3..0000000000 --- a/src/Gui/DlgWorkbenchesImp.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2015 FreeCAD Developers * - * Author: Przemo Firszt * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library 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 Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ - -// Based on DlgToolbars.h file - - -#ifndef GUI_DIALOG_DLGWORKBENCHES_IMP_H -#define GUI_DIALOG_DLGWORKBENCHES_IMP_H - -#include "PropertyPage.h" -#include - -class QListWidgetCustom; -class QListWidgetItem; - -namespace Gui { -namespace Dialog { -class Ui_DlgWorkbenches; - -class DlgWorkbenchesImp : public CustomizeActionPage -{ - Q_OBJECT - -public: - explicit DlgWorkbenchesImp(QWidget* parent = nullptr); - ~DlgWorkbenchesImp() override; - static QStringList load_enabled_workbenches(); - static QStringList load_disabled_workbenches(); - static const QString all_workbenches; - -protected: - void changeEvent(QEvent *e) override; - void hideEvent(QHideEvent * event) override; - -protected Q_SLOTS: - void onAddMacroAction(const QByteArray&) override; - void onRemoveMacroAction(const QByteArray&) override; - void onModifyMacroAction(const QByteArray&) override; - void on_add_to_enabled_workbenches_btn_clicked(); - void on_remove_from_enabled_workbenches_btn_clicked(); - void on_shift_workbench_up_btn_clicked(); - void on_shift_workbench_down_btn_clicked(); - void on_sort_enabled_workbenches_btn_clicked(); - void on_add_all_to_enabled_workbenches_btn_clicked(); - -private: - void set_lw_properties(QListWidgetCustom *lw); - void add_workbench(QListWidgetCustom *lw, const QString& it); - void move_workbench(QListWidgetCustom *lwc_dest, - QListWidgetItem *wi); - void save_workbenches(); - void shift_workbench(bool up); - -private: - std::unique_ptr ui; -}; - -} // namespace Dialog -} // namespace Gui - -#endif // GUI_DIALOG_DLGWORKBENCHES_IMP_H diff --git a/src/Gui/ListWidgetDragBugFix.cpp b/src/Gui/ListWidgetDragBugFix.cpp new file mode 100644 index 0000000000..d679f7b248 --- /dev/null +++ b/src/Gui/ListWidgetDragBugFix.cpp @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + + /**************************************************************************** + * Copyright (c) 2023 Boyer Pierre-louis * + * Copyright (c) 2023 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +# include +#endif + +#include "ListWidgetDragBugFix.h" + + +ListWidgetDragBugFix::ListWidgetDragBugFix(QWidget * parent) + : QListWidget(parent) +{ +} + +ListWidgetDragBugFix::~ListWidgetDragBugFix() +{ +} + +void ListWidgetDragBugFix::dragMoveEvent(QDragMoveEvent *e) +{ + if ((row(itemAt(e->pos())) == currentRow() + 1) + || (currentRow() == count() - 1 && row(itemAt(e->pos())) == -1)) { + e->ignore(); + return; + } + QListWidget::dragMoveEvent(e); +} + +#include "moc_ListWidgetDragBugFix.cpp" diff --git a/src/Gui/ListWidgetDragBugFix.h b/src/Gui/ListWidgetDragBugFix.h new file mode 100644 index 0000000000..9436a43f9c --- /dev/null +++ b/src/Gui/ListWidgetDragBugFix.h @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + + /**************************************************************************** + * Copyright (c) 2023 Boyer Pierre-louis * + * Copyright (c) 2023 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ + +#ifndef QLISTWIDGETDRAGBUGFIX_HPP +#define QLISTWIDGETDRAGBUGFIX_HPP + +#include +#include + + /* Qt has a recent bug (2023, https://bugreports.qt.io/browse/QTBUG-100128) + * where the items disappears in certain conditions when drag and dropping. + * Here we prevent the situation where this happens. + * 1 - If the item is dropped on the item below such that the item doesn't move (ie superior half of the below item) + * 2 - The item is the last one and user drop it on the empty space below. + * In both those cases the item widget was lost. + * When Qt solve this bug, this class should not be required anymore. + */ +class ListWidgetDragBugFix : public QListWidget +{ + Q_OBJECT + +public: + explicit ListWidgetDragBugFix(QWidget *parent); + ~ListWidgetDragBugFix() override; + +protected: + void dragMoveEvent(QDragMoveEvent *e) override; +}; + +#endif diff --git a/src/Gui/PropertyPage.cpp b/src/Gui/PropertyPage.cpp index a26772c23e..19b7e0916f 100644 --- a/src/Gui/PropertyPage.cpp +++ b/src/Gui/PropertyPage.cpp @@ -1,23 +1,25 @@ -/*************************************************************************** - * Copyright (c) 2004 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library 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 Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * +// SPDX-License-Identifier: LGPL-2.1-or-later + +/**************************************************************************** + * Copyright (c) 2004 Werner Mayer * + * Copyright (c) 2023 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * ***************************************************************************/ #include "PreCompiled.h" @@ -96,7 +98,7 @@ void PropertyPage::onReset() // ---------------------------------------------------------------- /** Construction */ -PreferencePage::PreferencePage(QWidget* parent) : QWidget(parent) +PreferencePage::PreferencePage(QWidget* parent) : QWidget(parent), rebootRequired(false) { } @@ -105,6 +107,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..702aba60bc 100644 --- a/src/Gui/PropertyPage.h +++ b/src/Gui/PropertyPage.h @@ -1,24 +1,26 @@ -/*************************************************************************** - * Copyright (c) 2004 Werner Mayer * - * * - * This file is part of the FreeCAD CAx development system. * - * * - * This library is free software; you can redistribute it and/or * - * modify it under the terms of the GNU Library General Public * - * License as published by the Free Software Foundation; either * - * version 2 of the License, or (at your option) any later version. * - * * - * This library 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 Library General Public License for more details. * - * * - * You should have received a copy of the GNU Library General Public * - * License along with this library; see the file COPYING.LIB. If not, * - * write to the Free Software Foundation, Inc., 59 Temple Place, * - * Suite 330, Boston, MA 02111-1307, USA * - * * - ***************************************************************************/ + // SPDX-License-Identifier: LGPL-2.1-or-later + + /**************************************************************************** + * Copyright (c) 2004 Werner Mayer * + * Copyright (c) 2023 FreeCAD Project Association * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD 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 * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ #ifndef GUI_DIALOG_PROPERTYPAGE_H @@ -71,12 +73,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. diff --git a/src/Gui/resource.cpp b/src/Gui/resource.cpp index 8e84edf1e2..b0ec59c799 100644 --- a/src/Gui/resource.cpp +++ b/src/Gui/resource.cpp @@ -42,10 +42,9 @@ #include "DlgSettingsUnitsImp.h" #include "DlgSettingsDocumentImp.h" #include "DlgReportViewImp.h" -#include "DlgSettingsLazyLoadedImp.h" +#include "DlgSettingsWorkbenchesImp.h" #include "DlgToolbarsImp.h" -#include "DlgWorkbenchesImp.h" #include "DlgActionsImp.h" #include "DlgCommandsImp.h" #include "DlgKeyboardImp.h" @@ -80,14 +79,13 @@ WidgetFactorySupplier::WidgetFactorySupplier() new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","Display") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","Display") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","Display") ); - new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","Workbenches") ); + new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","Workbenches") ); // ADD YOUR CUSTOMIZE PAGES HERE // // new CustomPageProducer; new CustomPageProducer; - new CustomPageProducer; new CustomPageProducer; new CustomPageProducer; new CustomPageProducer;