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.
This commit is contained in:
Martchus 2019-07-31 20:16:43 +02:00
parent 59e0f93c1c
commit 353f1e2463
13 changed files with 130 additions and 30 deletions

View File

@ -67,7 +67,7 @@ void SyncthingFileItemActionStaticData::initialize()
}
// use default icon settings
IconManager::instance().applySettings(StatusIconSettings());
IconManager::instance().applySettings();
m_initialized = true;
}

View File

@ -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)
{

View File

@ -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();

View File

@ -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

View File

@ -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()) {

View File

@ -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;

View File

@ -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();

View File

@ -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;
}
}
}

View File

@ -10,6 +10,12 @@
<normaloff>.</normaloff>.</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="contextLabel"/>
</item>
<item>
<widget class="QCheckBox" name="contextCheckBox"/>
</item>
<item>
<widget class="QGroupBox" name="statusIconsGroupBox">
<property name="title">
@ -128,5 +134,22 @@
</layout>
</widget>
<resources/>
<connections/>
<connections>
<connection>
<sender>contextCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>statusIconsGroupBox</receiver>
<slot>setDisabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>224</x>
<y>39</y>
</hint>
<hint type="destinationlabel">
<x>224</x>
<y>115</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -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);

View File

@ -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;

View File

@ -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<OptionPage *>() << 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;

View File

@ -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] = {};