diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 4282978fe7..589bc7968f 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -320,6 +320,7 @@ SET(Gui_UIC_SRCS DlgSettingsNavigation.ui DlgSettingsSelection.ui DlgSettingsViewColor.ui + DlgSettingsTheme.ui DlgSettingsColorGradient.ui DlgSettingsDocument.ui DlgSettingsImage.ui @@ -565,6 +566,7 @@ SET(Dialog_Settings_CPP_SRCS DlgSettingsNavigation.cpp DlgSettingsSelection.cpp DlgSettingsViewColor.cpp + DlgSettingsTheme.cpp DlgSettingsColorGradientImp.cpp DlgSettingsDocumentImp.cpp DlgSettingsImageImp.cpp @@ -584,6 +586,7 @@ SET(Dialog_Settings_HPP_SRCS DlgSettingsNavigation.h DlgSettingsSelection.h DlgSettingsViewColor.h + DlgSettingsTheme.h DlgSettingsColorGradientImp.h DlgSettingsDocumentImp.h DlgSettingsImageImp.h @@ -605,6 +608,7 @@ SET(Dialog_Settings_SRCS DlgSettingsNavigation.ui DlgSettingsSelection.ui DlgSettingsViewColor.ui + DlgSettingsTheme.ui DlgSettingsColorGradient.ui DlgSettingsDocument.ui DlgSettingsImage.ui diff --git a/src/Gui/DlgGeneral.ui b/src/Gui/DlgGeneral.ui index 70a13f7c8d..acac1b0652 100644 --- a/src/Gui/DlgGeneral.ui +++ b/src/Gui/DlgGeneral.ui @@ -212,16 +212,16 @@ dot/period will always be printed. 6 - + - Style sheet: + Theme: - + - Style sheet how user interface will look like + Customize how user interface will look like diff --git a/src/Gui/DlgGeneralImp.cpp b/src/Gui/DlgGeneralImp.cpp index 7a45f5b551..e1ba708532 100644 --- a/src/Gui/DlgGeneralImp.cpp +++ b/src/Gui/DlgGeneralImp.cpp @@ -66,6 +66,7 @@ using namespace Base; DlgGeneralImp::DlgGeneralImp( QWidget* parent ) : PreferencePage(parent) , localeIndex(0) + , themeChanged(false) , ui(new Ui_DlgGeneral) { ui->setupUi(this); @@ -74,6 +75,7 @@ DlgGeneralImp::DlgGeneralImp( QWidget* parent ) connect(ui->ImportConfig, &QPushButton::clicked, this, &DlgGeneralImp::onImportConfigClicked); connect(ui->SaveNewPreferencePack, &QPushButton::clicked, this, &DlgGeneralImp::saveAsNewPreferencePack); + connect(ui->themesCombobox, qOverload(&QComboBox::activated), this, &DlgGeneralImp::onThemeChanged); ui->ManagePreferencePacks->setToolTip(tr("Manage preference packs")); connect(ui->ManagePreferencePacks, &QPushButton::clicked, this, &DlgGeneralImp::onManagePreferencePacksClicked); @@ -246,9 +248,8 @@ void DlgGeneralImp::saveSettings() hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow"); hGrp->SetBool("TiledBackground", ui->tiledBackground->isChecked()); - QVariant sheet = ui->StyleSheets->itemData(ui->StyleSheets->currentIndex()); - hGrp->SetASCII("StyleSheet", (const char*)sheet.toByteArray()); - Application::Instance->setStyleSheet(sheet.toString(), ui->tiledBackground->isChecked()); + if (themeChanged) + saveThemes(); } void DlgGeneralImp::loadSettings() @@ -348,54 +349,55 @@ void DlgGeneralImp::loadSettings() hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow"); ui->tiledBackground->setChecked(hGrp->GetBool("TiledBackground", false)); - // List all .qss/.css files - QMap cssFiles; - QDir dir; - QStringList filter; - filter << QString::fromLatin1("*.qss"); - filter << QString::fromLatin1("*.css"); + loadThemes(); +} - // read from user, resource and built-in directory - QStringList qssPaths = QDir::searchPaths(QString::fromLatin1("qss")); - for (const auto & qssPath : qssPaths) { - dir.setPath(qssPath); - QFileInfoList fileNames = dir.entryInfoList(filter, QDir::Files, QDir::Name); - for (const auto & fileName : qAsConst(fileNames)) { - if (cssFiles.find(fileName.baseName()) == cssFiles.end()) { - cssFiles[fileName.baseName()] = fileName.fileName(); - } +void DlgGeneralImp::saveThemes() +{ + // First we save the name of the theme + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow"); + + std::string theme = ui->themesCombobox->currentText().toStdString(); + hGrp->SetASCII("Theme", theme); + + // Then we apply the themepack. + Application::Instance->prefPackManager()->rescan(); + auto packs = Application::Instance->prefPackManager()->preferencePacks(); + + for (const auto& pack : packs) { + if (pack.first == theme) { + + Application::Instance->prefPackManager()->apply(pack.first); + break; } } - // now add all unique items - ui->StyleSheets->clear(); - ui->StyleSheets->addItem(tr("No style sheet"), QString::fromLatin1("")); - for (QMap::iterator it = cssFiles.begin(); it != cssFiles.end(); ++it) { - ui->StyleSheets->addItem(it.key(), it.value()); - } + // Set the StyleSheet + QString sheet = QString::fromStdString(hGrp->GetASCII("StyleSheet")); + bool tiledBackground = hGrp->GetBool("TiledBackground", false); + Application::Instance->setStyleSheet(sheet, tiledBackground); +} - QString selectedStyleSheet = QString::fromLatin1(hGrp->GetASCII("StyleSheet").c_str()); - index = ui->StyleSheets->findData(selectedStyleSheet); +void DlgGeneralImp::loadThemes() +{ + ui->themesCombobox->clear(); - // might be an absolute path name - if (index < 0 && !selectedStyleSheet.isEmpty()) { - QFileInfo fi(selectedStyleSheet); - if (fi.isAbsolute()) { - QString path = fi.absolutePath(); - if (qssPaths.indexOf(path) >= 0) { - selectedStyleSheet = fi.fileName(); - } - else { - selectedStyleSheet = fi.absoluteFilePath(); - ui->StyleSheets->addItem(fi.baseName(), selectedStyleSheet); - } + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow"); - index = ui->StyleSheets->findData(selectedStyleSheet); + QString currentTheme = QString::fromLatin1(hGrp->GetASCII("Theme", "").c_str()); + + Application::Instance->prefPackManager()->rescan(); + auto packs = Application::Instance->prefPackManager()->preferencePacks(); + for (const auto& pack : packs) { + if (pack.second.metadata().type() == "Theme") { + ui->themesCombobox->addItem(QString::fromStdString(pack.first)); } } - if (index > -1) - ui->StyleSheets->setCurrentIndex(index); + int index = ui->themesCombobox->findText(currentTheme); + if (index >= 0 && index < ui->themesCombobox->count()) { + ui->themesCombobox->setCurrentIndex(index); + } } void DlgGeneralImp::changeEvent(QEvent *event) @@ -561,4 +563,9 @@ void DlgGeneralImp::onUnitSystemIndexChanged(int index) } } +void DlgGeneralImp::onThemeChanged(int index) { + Q_UNUSED(index); + themeChanged = true; +} + #include "moc_DlgGeneralImp.cpp" diff --git a/src/Gui/DlgGeneralImp.h b/src/Gui/DlgGeneralImp.h index 4039012aeb..7309c44873 100644 --- a/src/Gui/DlgGeneralImp.h +++ b/src/Gui/DlgGeneralImp.h @@ -54,6 +54,9 @@ public: void saveSettings() override; void loadSettings() override; + void saveThemes(); + void loadThemes(); + protected: void changeEvent(QEvent *event) override; @@ -63,6 +66,7 @@ protected Q_SLOTS: void newPreferencePackDialogAccepted(); void onManagePreferencePacksClicked(); void onImportConfigClicked(); + void onThemeChanged(int index); public Q_SLOTS: void onUnitSystemIndexChanged(int index); @@ -77,6 +81,7 @@ private: private: int localeIndex; + bool themeChanged; std::unique_ptr ui; std::unique_ptr newPreferencePackDialog; std::unique_ptr preferencePackManagementDialog; diff --git a/src/Gui/DlgSettingsTheme.cpp b/src/Gui/DlgSettingsTheme.cpp new file mode 100644 index 0000000000..c043dddf44 --- /dev/null +++ b/src/Gui/DlgSettingsTheme.cpp @@ -0,0 +1,160 @@ +/*************************************************************************** + * Copyright (c) 2009 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 * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +# include +#endif + +#include "DlgSettingsTheme.h" +#include "ui_DlgSettingsTheme.h" +#include "Application.h" +#include "PreferencePackManager.h" + + +using namespace Gui::Dialog; + +/* TRANSLATOR Gui::Dialog::DlgSettingsTheme */ + +/** + * Constructs a DlgSettingsTheme which is a child of 'parent', with the + * name 'name' and widget flags set to 'f' + */ +DlgSettingsTheme::DlgSettingsTheme(QWidget* parent) + : PreferencePage(parent) + , ui(new Ui_DlgSettingsTheme) + , styleSheetChanged(false) +{ + ui->setupUi(this); + + connect(ui->styleSheetsCombobox, qOverload(&QComboBox::activated), this, &DlgSettingsTheme::onStyleSheetChanged); +} + +/** + * Destroys the object and frees any allocated resources + */ +DlgSettingsTheme::~DlgSettingsTheme() +{ + // no need to delete child widgets, Qt does it all for us +} + +void DlgSettingsTheme::saveSettings() +{ + ui->ThemeSecondaryColor->onSave(); + + if (styleSheetChanged) + saveStyleSheet(); +} + +void DlgSettingsTheme::loadSettings() +{ + ui->ThemeSecondaryColor->onRestore(); + + loadStyleSheet(); +} + +void DlgSettingsTheme::saveStyleSheet() +{ + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow"); + + QVariant sheet = ui->styleSheetsCombobox->itemData(ui->styleSheetsCombobox->currentIndex()); + hGrp->SetASCII("StyleSheet", (const char*)sheet.toByteArray()); + bool tiledBackground = hGrp->GetBool("TiledBackground", false); + Application::Instance->setStyleSheet(sheet.toString(), tiledBackground); +} + +void DlgSettingsTheme::loadStyleSheet() +{ + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/MainWindow"); + + // List all .qss/.css files + QMap cssFiles; + QDir dir; + QStringList filter; + filter << QString::fromLatin1("*.qss"); + filter << QString::fromLatin1("*.css"); + + // read from user, resource and built-in directory + QStringList qssPaths = QDir::searchPaths(QString::fromLatin1("qss")); + for (const auto& qssPath : qssPaths) { + dir.setPath(qssPath); + QFileInfoList fileNames = dir.entryInfoList(filter, QDir::Files, QDir::Name); + for (const auto& fileName : qAsConst(fileNames)) { + if (cssFiles.find(fileName.baseName()) == cssFiles.end()) { + cssFiles[fileName.baseName()] = fileName.fileName(); + } + } + } + + // now add all unique items + ui->styleSheetsCombobox->clear(); + ui->styleSheetsCombobox->addItem(tr("No style sheet"), QString::fromLatin1("")); + for (QMap::iterator it = cssFiles.begin(); it != cssFiles.end(); ++it) { + ui->styleSheetsCombobox->addItem(it.key(), it.value()); + } + + QString selectedStyleSheet = QString::fromLatin1(hGrp->GetASCII("StyleSheet").c_str()); + int index = ui->styleSheetsCombobox->findData(selectedStyleSheet); + + // might be an absolute path name + if (index < 0 && !selectedStyleSheet.isEmpty()) { + QFileInfo fi(selectedStyleSheet); + if (fi.isAbsolute()) { + QString path = fi.absolutePath(); + if (qssPaths.indexOf(path) >= 0) { + selectedStyleSheet = fi.fileName(); + } + else { + selectedStyleSheet = fi.absoluteFilePath(); + ui->styleSheetsCombobox->addItem(fi.baseName(), selectedStyleSheet); + } + + index = ui->styleSheetsCombobox->findData(selectedStyleSheet); + } + } + + if (index > -1) + ui->styleSheetsCombobox->setCurrentIndex(index); +} + +void DlgSettingsTheme::onStyleSheetChanged(int index) { + Q_UNUSED(index); + Base::Console().Warning("Hello"); + styleSheetChanged = true; +} + +/** + * Sets the strings of the subwidgets using the current language. + */ +void DlgSettingsTheme::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(this); + } + else { + QWidget::changeEvent(e); + } +} + + +#include "moc_DlgSettingsTheme.cpp" + diff --git a/src/Gui/DlgSettingsTheme.h b/src/Gui/DlgSettingsTheme.h new file mode 100644 index 0000000000..516ca320ad --- /dev/null +++ b/src/Gui/DlgSettingsTheme.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (c) 2009 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_DIALOG_DLGSETTINGSTHEME_H +#define GUI_DIALOG_DLGSETTINGSTHEME_H + +#include "PropertyPage.h" +#include + +namespace Gui { +namespace Dialog { +class Ui_DlgSettingsTheme; + +/** + * The DlgSettingsTheme class implements a preference page to change theme settings. + * @author Pierre-Louis Boyer + */ +class DlgSettingsTheme : public PreferencePage +{ + Q_OBJECT + +public: + explicit DlgSettingsTheme(QWidget* parent = nullptr); + ~DlgSettingsTheme() override; + + void saveSettings() override; + void loadSettings() override; + + void saveStyleSheet(); + void loadStyleSheet(); + +protected: + void changeEvent(QEvent *e) override; + +protected Q_SLOTS: + void onStyleSheetChanged(int index); + +private: + std::unique_ptr ui; + bool styleSheetChanged; +}; + +} // namespace Dialog +} // namespace Gui + +#endif // GUI_DIALOG_DLGSETTINGSTHEME_H diff --git a/src/Gui/DlgSettingsTheme.ui b/src/Gui/DlgSettingsTheme.ui new file mode 100644 index 0000000000..f2bbc0fd2e --- /dev/null +++ b/src/Gui/DlgSettingsTheme.ui @@ -0,0 +1,178 @@ + + + Gui::Dialog::DlgSettingsTheme + + + + 0 + 0 + 405 + 400 + + + + Theme + + + + + + This page let you customize your current theme. The offered settings are optional for theme developpers so they may or may not have an effect in your current theme. + + + true + + + + + + + + + + + Style sheet: + + + + + + + Style sheet how user interface will look like + + + + + + + Secondary theme color + + + + + + + + 0 + 0 + + + + This color might be used by your theme to let you customize it. + + + + 85 + 123 + 182 + + + + ThemeSecondaryColor + + + Themes + + + + + + + + + Qt::Horizontal + + + + 183 + 23 + + + + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + + Gui::ColorButton + QPushButton +
Gui/Widgets.h
+
+ + Gui::PrefColorButton + Gui::ColorButton +
Gui/PrefWidgets.h
+
+ + Gui::PrefRadioButton + QRadioButton +
Gui/PrefWidgets.h
+
+ + Gui::PrefCheckBox + QCheckBox +
Gui/PrefWidgets.h
+
+
+ + checkBoxPreselection + HighlightColor + checkBoxSelection + SelectionColor + SelectionColor_Background + backgroundColorFrom + backgroundColorTo + checkMidColor + backgroundColorMid + + + + + checkBoxPreselection + toggled(bool) + HighlightColor + setEnabled(bool) + + + 70 + 45 + + + 310 + 54 + + + + + checkBoxSelection + toggled(bool) + SelectionColor + setEnabled(bool) + + + 158 + 76 + + + 291 + 75 + + + + +
diff --git a/src/Gui/resource.cpp b/src/Gui/resource.cpp index 034450934f..f7d4d9329f 100644 --- a/src/Gui/resource.cpp +++ b/src/Gui/resource.cpp @@ -34,6 +34,7 @@ #include "DlgSettingsNavigation.h" #include "DlgSettingsSelection.h" #include "DlgSettingsViewColor.h" +#include "DlgSettingsTheme.h" #include "DlgGeneralImp.h" #include "DlgEditorImp.h" #include "DlgSettingsNotificationArea.h" @@ -73,6 +74,7 @@ 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","Display") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject","Workbenches") ); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject", "Python")); new PrefPageProducer ( QT_TRANSLATE_NOOP("QObject", "Python"));