From 353f1e2463d9057465cc4de09cddb62242d7f72d Mon Sep 17 00:00:00 2001 From: Martchus Date: Wed, 31 Jul 2019 20:16:43 +0200 Subject: [PATCH] Allow to distinguish icon colors within UI and system tray This is useful because sometimes the background color of the system tray is dark but the overall system UI still uses a light theme. For the Plasmoid this should never be the case, though. Hence the extra settings are not available there. --- .../syncthingfileitemactionstaticdata.cpp | 2 +- model/syncthingicons.cpp | 1 + model/syncthingicons.h | 32 +++++++++++-- plasmoid/lib/syncthingapplet.cpp | 2 +- tray/gui/traywidget.cpp | 2 +- widgets/misc/dbusstatusnotifier.cpp | 4 +- widgets/misc/dbusstatusnotifier.h | 2 +- widgets/misc/statusinfo.cpp | 23 ++++----- widgets/settings/iconsoptionpage.ui | 25 +++++++++- widgets/settings/settings.cpp | 8 +++- widgets/settings/settings.h | 6 ++- widgets/settings/settingsdialog.cpp | 47 +++++++++++++++++-- widgets/settings/settingsdialog.h | 6 ++- 13 files changed, 130 insertions(+), 30 deletions(-) diff --git a/fileitemactionplugin/syncthingfileitemactionstaticdata.cpp b/fileitemactionplugin/syncthingfileitemactionstaticdata.cpp index 4ccc07f..157c2b9 100644 --- a/fileitemactionplugin/syncthingfileitemactionstaticdata.cpp +++ b/fileitemactionplugin/syncthingfileitemactionstaticdata.cpp @@ -67,7 +67,7 @@ void SyncthingFileItemActionStaticData::initialize() } // use default icon settings - IconManager::instance().applySettings(StatusIconSettings()); + IconManager::instance().applySettings(); m_initialized = true; } diff --git a/model/syncthingicons.cpp b/model/syncthingicons.cpp index 066dd70..9eb974b 100644 --- a/model/syncthingicons.cpp +++ b/model/syncthingicons.cpp @@ -278,6 +278,7 @@ FontAwesomeIcons::FontAwesomeIcons(const QColor &color, const QSize &size, int m IconManager::IconManager() : m_statusIcons() + , m_trayIcons(m_statusIcons) , m_fontAwesomeIconsForLightTheme(QColor(10, 10, 10), QSize(64, 64), 8) , m_fontAwesomeIconsForDarkTheme(Qt::white, QSize(64, 64), 8) { diff --git a/model/syncthingicons.h b/model/syncthingicons.h index 366d41d..c400c92 100644 --- a/model/syncthingicons.h +++ b/model/syncthingicons.h @@ -87,6 +87,8 @@ struct LIB_SYNCTHING_MODEL_EXPORT StatusIconSettings { struct LIB_SYNCTHING_MODEL_EXPORT StatusIcons { StatusIcons(); StatusIcons(const StatusIconSettings &settings); + StatusIcons(const StatusIcons &other) = default; + StatusIcons &operator=(const StatusIcons &other) = default; QIcon disconnected; QIcon idling; QIcon scanninig; @@ -133,25 +135,37 @@ class LIB_SYNCTHING_MODEL_EXPORT IconManager : public QObject { public: static IconManager &instance(); - void applySettings(const StatusIconSettings &settings); + void applySettings(const StatusIconSettings *statusIconSettings = nullptr, const StatusIconSettings *trayIconSettings = nullptr); const StatusIcons &statusIcons() const; + const StatusIcons &trayIcons() const; const FontAwesomeIcons &fontAwesomeIconsForLightTheme() const; const FontAwesomeIcons &fontAwesomeIconsForDarkTheme() const; Q_SIGNALS: - void statusIconsChanged(const StatusIcons &newStatusIcons); + void statusIconsChanged(const StatusIcons &newStatusIcons, const StatusIcons &newTrayIcons); private: IconManager(); StatusIcons m_statusIcons; + StatusIcons m_trayIcons; FontAwesomeIcons m_fontAwesomeIconsForLightTheme; FontAwesomeIcons m_fontAwesomeIconsForDarkTheme; }; -inline void IconManager::applySettings(const StatusIconSettings &settings) +inline void IconManager::applySettings(const StatusIconSettings *statusIconSettings, const StatusIconSettings *trayIconSettings) { - emit statusIconsChanged(m_statusIcons = StatusIcons(settings)); + if (statusIconSettings) { + m_statusIcons = StatusIcons(*statusIconSettings); + } else { + m_statusIcons = StatusIcons(StatusIconSettings()); + } + if (trayIconSettings) { + m_trayIcons = StatusIcons(*trayIconSettings); + } else { + m_trayIcons = m_statusIcons; + } + emit statusIconsChanged(m_statusIcons, m_trayIcons); } inline const StatusIcons &IconManager::statusIcons() const @@ -159,6 +173,11 @@ inline const StatusIcons &IconManager::statusIcons() const return m_statusIcons; } +inline const StatusIcons &IconManager::trayIcons() const +{ + return m_trayIcons; +} + inline const FontAwesomeIcons &IconManager::fontAwesomeIconsForLightTheme() const { return m_fontAwesomeIconsForLightTheme; @@ -174,6 +193,11 @@ inline const StatusIcons &statusIcons() return IconManager::instance().statusIcons(); } +inline const StatusIcons &trayIcons() +{ + return IconManager::instance().trayIcons(); +} + inline const FontAwesomeIcons &fontAwesomeIconsForLightTheme() { return IconManager::instance().fontAwesomeIconsForLightTheme(); diff --git a/plasmoid/lib/syncthingapplet.cpp b/plasmoid/lib/syncthingapplet.cpp index 4a73b7d..3d54b25 100644 --- a/plasmoid/lib/syncthingapplet.cpp +++ b/plasmoid/lib/syncthingapplet.cpp @@ -398,7 +398,7 @@ void SyncthingApplet::handleSettingsChanged() m_dirModel.setBrightColors(brightColors); m_devModel.setBrightColors(brightColors); m_downloadModel.setBrightColors(brightColors); - IconManager::instance().applySettings(settings.statusIcons); + IconManager::instance().applySettings(&settings.icons.status); // restore selected states // note: The settings dialog writes this to the Plasmoid's config like the other settings. However, it diff --git a/tray/gui/traywidget.cpp b/tray/gui/traywidget.cpp index e01c8d5..84a7438 100644 --- a/tray/gui/traywidget.cpp +++ b/tray/gui/traywidget.cpp @@ -465,7 +465,7 @@ void TrayWidget::applySettings(const QString &connectionConfig) m_dirModel.setBrightColors(settings.appearance.brightTextColors); m_devModel.setBrightColors(settings.appearance.brightTextColors); m_dlModel.setBrightColors(settings.appearance.brightTextColors); - IconManager::instance().applySettings(settings.statusIcons); + IconManager::instance().applySettings(&settings.icons.status, settings.icons.distinguishTrayIcons ? &settings.icons.tray : nullptr); // show warning when explicitely specified connection configuration was not found if (!specifiedConnectionConfigFound && !connectionConfig.isEmpty()) { diff --git a/widgets/misc/dbusstatusnotifier.cpp b/widgets/misc/dbusstatusnotifier.cpp index 92aa372..053ccc6 100644 --- a/widgets/misc/dbusstatusnotifier.cpp +++ b/widgets/misc/dbusstatusnotifier.cpp @@ -58,10 +58,10 @@ DBusStatusNotifier::DBusStatusNotifier(QObject *parent) const auto &iconManager = IconManager::instance(); connect(&iconManager, &Data::IconManager::statusIconsChanged, this, &DBusStatusNotifier::setIcons); - setIcons(iconManager.statusIcons()); + setIcons(iconManager.statusIcons(), iconManager.trayIcons()); } -void DBusStatusNotifier::setIcons(const StatusIcons &icons) +void DBusStatusNotifier::setIcons(const StatusIcons &, const StatusIcons &icons) { if (!icons.isValid) { return; diff --git a/widgets/misc/dbusstatusnotifier.h b/widgets/misc/dbusstatusnotifier.h index aa0e332..d85d028 100644 --- a/widgets/misc/dbusstatusnotifier.h +++ b/widgets/misc/dbusstatusnotifier.h @@ -32,7 +32,7 @@ public Q_SLOTS: void showSyncComplete(const QString &message); void showNewDev(const QString &devId, const QString &message); void showNewDir(const QString &devId, const QString &dirId, const QString &message); - void setIcons(const Data::StatusIcons &icons); + void setIcons(const Data::StatusIcons &statusIcons, const Data::StatusIcons &icons); Q_SIGNALS: void connectRequested(); diff --git a/widgets/misc/statusinfo.cpp b/widgets/misc/statusinfo.cpp index c710700..2eb72af 100644 --- a/widgets/misc/statusinfo.cpp +++ b/widgets/misc/statusinfo.cpp @@ -15,7 +15,7 @@ namespace QtGui { StatusInfo::StatusInfo() : m_statusText(QCoreApplication::translate("QtGui::StatusInfo", "Initializing ...")) - , m_statusIcon(&statusIcons().disconnected) + , m_statusIcon(&trayIcons().disconnected) { } @@ -36,6 +36,7 @@ void StatusInfo::updateConnectionStatus(const SyncthingConnection &connection) { m_additionalStatusInfo.clear(); + const auto &icons = trayIcons(); switch (connection.status()) { case SyncthingStatus::Disconnected: if (connection.autoReconnectInterval() > 0) { @@ -45,11 +46,11 @@ void StatusInfo::updateConnectionStatus(const SyncthingConnection &connection) } else { m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "Not connected to Syncthing"); } - m_statusIcon = &statusIcons().disconnected; + m_statusIcon = &icons.disconnected; break; case SyncthingStatus::Reconnecting: m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "Reconnecting ..."); - m_statusIcon = &statusIcons().disconnected; + m_statusIcon = &icons.disconnected; break; default: if (connection.hasOutOfSyncDirs()) { @@ -57,36 +58,36 @@ void StatusInfo::updateConnectionStatus(const SyncthingConnection &connection) case SyncthingStatus::Synchronizing: m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "Synchronization is ongoing"); m_additionalStatusInfo = QCoreApplication::translate("QtGui::StatusInfo", "At least one directory is out of sync"); - m_statusIcon = &statusIcons().errorSync; + m_statusIcon = &icons.errorSync; break; default: m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "At least one directory is out of sync"); - m_statusIcon = &statusIcons().error; + m_statusIcon = &icons.error; } } else if (connection.hasUnreadNotifications()) { m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "Notifications available"); - m_statusIcon = &statusIcons().notify; + m_statusIcon = &icons.notify; } else { switch (connection.status()) { case SyncthingStatus::Idle: m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "Syncthing is idling"); - m_statusIcon = &statusIcons().idling; + m_statusIcon = &icons.idling; break; case SyncthingStatus::Scanning: m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "Syncthing is scanning"); - m_statusIcon = &statusIcons().scanninig; + m_statusIcon = &icons.scanninig; break; case SyncthingStatus::Paused: m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "At least one device is paused"); - m_statusIcon = &statusIcons().pause; + m_statusIcon = &icons.pause; break; case SyncthingStatus::Synchronizing: m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "Synchronization is ongoing"); - m_statusIcon = &statusIcons().sync; + m_statusIcon = &icons.sync; break; default: m_statusText = QCoreApplication::translate("QtGui::StatusInfo", "Status is unknown"); - m_statusIcon = &statusIcons().disconnected; + m_statusIcon = &icons.disconnected; } } } diff --git a/widgets/settings/iconsoptionpage.ui b/widgets/settings/iconsoptionpage.ui index c032457..4a11f48 100644 --- a/widgets/settings/iconsoptionpage.ui +++ b/widgets/settings/iconsoptionpage.ui @@ -10,6 +10,12 @@ .. + + + + + + @@ -128,5 +134,22 @@ - + + + contextCheckBox + toggled(bool) + statusIconsGroupBox + setDisabled(bool) + + + 224 + 39 + + + 224 + 115 + + + + diff --git a/widgets/settings/settings.cpp b/widgets/settings/settings.cpp index 1799aaf..b31e6cc 100644 --- a/widgets/settings/settings.cpp +++ b/widgets/settings/settings.cpp @@ -257,7 +257,9 @@ void restore() appearance.frameStyle = settings.value(QStringLiteral("frameStyle"), appearance.frameStyle).toInt(); appearance.tabPosition = settings.value(QStringLiteral("tabPos"), appearance.tabPosition).toInt(); appearance.brightTextColors = settings.value(QStringLiteral("brightTextColors"), appearance.brightTextColors).toBool(); - v.statusIcons = StatusIconSettings(settings.value(QStringLiteral("statusIcons")).toString()); + v.icons.status = StatusIconSettings(settings.value(QStringLiteral("statusIcons")).toString()); + v.icons.tray = StatusIconSettings(settings.value(QStringLiteral("trayIcons")).toString()); + v.icons.distinguishTrayIcons = settings.value(QStringLiteral("distinguishTrayIcons")).toBool(); settings.beginGroup(QStringLiteral("positioning")); auto &positioning = appearance.positioning; positioning.useCursorPosition = settings.value(QStringLiteral("useCursorPos"), positioning.useCursorPosition).toBool(); @@ -353,7 +355,9 @@ void save() settings.setValue(QStringLiteral("frameStyle"), appearance.frameStyle); settings.setValue(QStringLiteral("tabPos"), appearance.tabPosition); settings.setValue(QStringLiteral("brightTextColors"), appearance.brightTextColors); - settings.setValue(QStringLiteral("statusIcons"), v.statusIcons.toString()); + settings.setValue(QStringLiteral("statusIcons"), v.icons.status.toString()); + settings.setValue(QStringLiteral("trayIcons"), v.icons.tray.toString()); + settings.setValue(QStringLiteral("distinguishTrayIcons"), v.icons.distinguishTrayIcons); settings.beginGroup(QStringLiteral("positioning")); settings.setValue(QStringLiteral("useCursorPos"), appearance.positioning.useCursorPosition); settings.setValue(QStringLiteral("assumedIconPos"), appearance.positioning.assumedIconPosition); diff --git a/widgets/settings/settings.h b/widgets/settings/settings.h index 7837ca1..4f3961d 100644 --- a/widgets/settings/settings.h +++ b/widgets/settings/settings.h @@ -134,7 +134,11 @@ struct SYNCTHINGWIDGETS_EXPORT Settings { #endif unsigned int ignoreInavailabilityAfterStart = 15; Appearance appearance; - Data::StatusIconSettings statusIcons; + struct SYNCTHINGWIDGETS_EXPORT Icons { + Data::StatusIconSettings status; + Data::StatusIconSettings tray; + bool distinguishTrayIcons = false; + } icons; Launcher launcher; #ifdef LIB_SYNCTHING_CONNECTOR_SUPPORT_SYSTEMD Systemd systemd; diff --git a/widgets/settings/settingsdialog.cpp b/widgets/settings/settingsdialog.cpp index 893c300..d887962 100644 --- a/widgets/settings/settingsdialog.cpp +++ b/widgets/settings/settingsdialog.cpp @@ -505,8 +505,9 @@ void AppearanceOptionPage::reset() } // IconsOptionPage -IconsOptionPage::IconsOptionPage(QWidget *parentWidget) +IconsOptionPage::IconsOptionPage(Context context, QWidget *parentWidget) : IconsOptionPageBase(parentWidget) + , m_context(context) { } @@ -518,6 +519,24 @@ QWidget *IconsOptionPage::setupWidget() { auto *const widget = IconsOptionPageBase::setupWidget(); + // set context-specific elements + switch (m_context) { + case Context::Combined: + ui()->contextLabel->hide(); + ui()->contextCheckBox->hide(); + break; + case Context::UI: + widget->setWindowTitle(QCoreApplication::translate("QtGui::IconsOptionPageBase", "UI icons")); + ui()->contextLabel->setText(QCoreApplication::translate("QtGui::IconsOptionPageBase", "These icon colors are used within Syncthing Tray's UI.")); + ui()->contextCheckBox->hide(); + break; + case Context::System: + widget->setWindowTitle(QCoreApplication::translate("QtGui::IconsOptionPageBase", "System icons")); + ui()->contextLabel->setText(QCoreApplication::translate("QtGui::IconsOptionPageBase", "These icon colors are used for the system tray icon and the notifications.")); + ui()->contextCheckBox->setText(QCoreApplication::translate("QtGui::IconsOptionPageBase", "Use same colors as for UI icons")); + break; + } + // populate form for status icon colors auto *const gridLayout = ui()->gridLayout; auto *const statusIconsGroupBox = ui()->statusIconsGroupBox; @@ -586,7 +605,17 @@ bool IconsOptionPage::apply() widgetsForColor.colorButtons[2]->color(), }; } - values().statusIcons = m_settings; + auto &iconSettings = values().icons; + switch (m_context) { + case Context::Combined: + case Context::UI: + iconSettings.status = m_settings; + break; + case Context::System: + iconSettings.tray = m_settings; + iconSettings.distinguishTrayIcons = !ui()->contextCheckBox->isChecked(); + break; + } return true; } @@ -601,7 +630,17 @@ void IconsOptionPage::update() void IconsOptionPage::reset() { - m_settings = values().statusIcons; + const auto &iconSettings = values().icons; + switch (m_context) { + case Context::Combined: + case Context::UI: + m_settings = iconSettings.status; + break; + case Context::System: + m_settings = iconSettings.tray; + ui()->contextCheckBox->setChecked(!iconSettings.distinguishTrayIcons); + break; + } update(); } @@ -1237,7 +1276,7 @@ SettingsDialog::SettingsDialog(Data::SyncthingConnection *connection, QWidget *p category = new OptionCategory(this); category->setDisplayName(tr("Tray")); category->assignPages(QList() << new ConnectionOptionPage(connection) << new NotificationsOptionPage << new AppearanceOptionPage - << new IconsOptionPage); + << new IconsOptionPage(IconsOptionPage::Context::UI) << new IconsOptionPage(IconsOptionPage::Context::System)); category->setIcon(QIcon(QStringLiteral(":/icons/hicolor/scalable/app/syncthingtray.svg"))); categories << category; diff --git a/widgets/settings/settingsdialog.h b/widgets/settings/settingsdialog.h index 1021a82..00489ff 100644 --- a/widgets/settings/settingsdialog.h +++ b/widgets/settings/settingsdialog.h @@ -79,10 +79,14 @@ END_DECLARE_OPTION_PAGE DECLARE_UI_FILE_BASED_OPTION_PAGE(AppearanceOptionPage) -BEGIN_DECLARE_UI_FILE_BASED_OPTION_PAGE(IconsOptionPage) +BEGIN_DECLARE_UI_FILE_BASED_OPTION_PAGE_CUSTOM_CTOR(IconsOptionPage) +public: + enum class Context { Combined, UI, System }; + explicit IconsOptionPage(Context context = Context::Combined, QWidget *parentWidget = nullptr); DECLARE_SETUP_WIDGETS private: void update(); +Context m_context; Data::StatusIconSettings m_settings; struct { QtUtilities::ColorButton *colorButtons[3] = {};