Skip to content

Commit 4ccd499

Browse files
committed
Refactor icon handling and move most of the code to the resources lib
1 parent a660cef commit 4ccd499

14 files changed

+208
-206
lines changed

src/gui/activitywidget.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -469,10 +469,10 @@ ActivitySettings::ActivitySettings(QWidget *parent)
469469
connect(_activityWidget, &ActivityWidget::newNotification, this, &ActivitySettings::slotShowActivityTab);
470470

471471
_protocolWidget = new ProtocolWidget(this);
472-
_protocolTabId = _tab->addTab(_protocolWidget, Theme::instance()->syncStateIcon(SyncResult::Success), tr("Sync Protocol"));
472+
_protocolTabId = _tab->addTab(_protocolWidget, Resources::getCoreIcon(QStringLiteral("states/ok")), tr("Sync Protocol"));
473473

474474
_issuesWidget = new IssuesWidget(this);
475-
_syncIssueTabId = _tab->addTab(_issuesWidget, Theme::instance()->syncStateIcon(SyncResult::Problem), QString());
475+
_syncIssueTabId = _tab->addTab(_issuesWidget, Resources::getCoreIcon(QStringLiteral("states/error")), QString());
476476
slotShowIssueItemCount(0); // to display the label.
477477
connect(_issuesWidget, &IssuesWidget::issueCountUpdated,
478478
this, &ActivitySettings::slotShowIssueItemCount);

src/gui/folderstatusdelegate.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ void FolderStatusDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
142142
const auto iconVisualRect = QStyle::visualRect(option.direction, option.rect, iconRect.toRect());
143143
spaceImage.paint(painter, iconVisualRect, Qt::AlignCenter, iconState);
144144
// paint the overlay in NormalState, on mac os disabled icons have an alpha channel, drawing semi transparent icons on top of each other...
145-
Theme::instance()->themeIcon(QStringLiteral("states/%1").arg(statusIconName)).paint(painter, iconVisualRect, Qt::AlignCenter, QIcon::Normal);
145+
Resources::getCoreIcon(QStringLiteral("states/%1").arg(statusIconName)).paint(painter, iconVisualRect, Qt::AlignCenter, QIcon::Normal);
146146
}
147147

148148
// only show the warning icon if the sync is running. Otherwise its

src/gui/generalsettings.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ GeneralSettings::GeneralSettings(QWidget *parent)
8686

8787
// OEM themes are not obliged to ship mono icons, so there
8888
// is no point in offering an option
89-
_ui->monoIconsCheckBox->setVisible(Theme::instance()->monoIconsAvailable());
89+
_ui->monoIconsCheckBox->setVisible(Resources::hasMonoTheme());
9090

9191
connect(_ui->ignoredFilesButton, &QAbstractButton::clicked, this, &GeneralSettings::slotIgnoreFilesEditor);
9292
connect(_ui->logSettingsButton, &QPushButton::clicked, this, [] {

src/gui/models/protocolitemmodel.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,11 @@ QVariant ProtocolItemModel::data(const QModelIndex &index, int role) const
8484
|| status == SyncFileItem::FatalError
8585
|| status == SyncFileItem::DetailError
8686
|| status == SyncFileItem::BlacklistedError) {
87-
return Theme::instance()->syncStateIcon(SyncResult::Error);
87+
return Resources::themeIcon(Theme::instance()->syncStateIconName(SyncResult{SyncResult::Error}));
8888
} else if (Progress::isWarningKind(status) || status == SyncFileItem::Excluded) {
89-
return Theme::instance()->syncStateIcon(SyncResult::Problem);
89+
return Resources::themeIcon(Theme::instance()->syncStateIconName(SyncResult{SyncResult::Problem}));
9090
} else {
91-
return Theme::instance()->syncStateIcon(SyncResult::Success);
91+
return Resources::themeIcon(Theme::instance()->syncStateIconName(SyncResult{SyncResult::Success}));
9292
}
9393
}
9494
break;

src/gui/owncloudgui.cpp

+9-8
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,14 @@ ownCloudGui::ownCloudGui(Application *parent)
120120
, _recentActionsMenu(nullptr)
121121
, _app(parent)
122122
{
123-
// for the beginning, set the offline icon until the account was verified
124-
_tray->setIcon(Theme::instance()->syncStateIcon(SyncResult::Status::Offline, true, false));
125-
126123
connect(_tray, &QSystemTrayIcon::activated,
127124
this, &ownCloudGui::slotTrayClicked);
128125

129126
setupActions();
130127
setupContextMenu();
131128

129+
// init systry
130+
slotComputeOverallSyncStatus();
132131
_tray->show();
133132

134133
ProgressDispatcher *pd = ProgressDispatcher::instance();
@@ -238,6 +237,8 @@ void ownCloudGui::slotTrayMessageIfServerUnsupported(Account *account)
238237

239238
void ownCloudGui::slotComputeOverallSyncStatus()
240239
{
240+
auto getIcon = [this](const SyncResult &result) { return Theme::instance()->themeTrayIcon(result, contextMenuVisible()); };
241+
auto getIconFromStatus = [getIcon, this](const SyncResult::Status &status) { return getIcon(SyncResult{status}); };
241242
bool allSignedOut = true;
242243
bool allPaused = true;
243244
bool allDisconnected = true;
@@ -268,7 +269,7 @@ void ownCloudGui::slotComputeOverallSyncStatus()
268269
}
269270

270271
if (!problemAccounts.empty()) {
271-
_tray->setIcon(Theme::instance()->syncStateIcon(SyncResult::Status::Offline, true, contextMenuVisible()));
272+
_tray->setIcon(getIconFromStatus(SyncResult::Status::Offline));
272273
if (allDisconnected) {
273274
setStatusText(tr("Disconnected"));
274275
} else {
@@ -297,12 +298,12 @@ void ownCloudGui::slotComputeOverallSyncStatus()
297298
}
298299

299300
if (allSignedOut) {
300-
_tray->setIcon(Theme::instance()->syncStateIcon(SyncResult::Status::Offline, true, contextMenuVisible()));
301+
_tray->setIcon(getIconFromStatus(SyncResult::Status::Offline));
301302
_tray->setToolTip(tr("Please sign in"));
302303
setStatusText(tr("Signed out"));
303304
return;
304305
} else if (allPaused) {
305-
_tray->setIcon(Theme::instance()->syncStateIcon(SyncResult::Paused, true, contextMenuVisible()));
306+
_tray->setIcon(getIconFromStatus(SyncResult::Paused));
306307
_tray->setToolTip(tr("Account synchronization is disabled"));
307308
setStatusText(tr("Synchronization is paused"));
308309
return;
@@ -313,7 +314,7 @@ void ownCloudGui::slotComputeOverallSyncStatus()
313314

314315
auto trayOverallStatusResult = FolderMan::trayOverallStatus(map);
315316

316-
const QIcon statusIcon = Theme::instance()->syncStateIcon(trayOverallStatusResult.overallStatus(), true, contextMenuVisible());
317+
const QIcon statusIcon = getIcon(trayOverallStatusResult.overallStatus());
317318
_tray->setIcon(statusIcon);
318319

319320
// create the tray blob message, check if we have an defined state
@@ -694,7 +695,7 @@ void ownCloudGui::updateContextMenuNeeded()
694695
void ownCloudGui::slotShowTrayMessage(const QString &title, const QString &msg, const QIcon &icon)
695696
{
696697
// SyncResult::Problem is returns the info icon
697-
_tray->showMessage(title, msg, icon.isNull() ? Theme::instance()->syncStateIcon(SyncResult::Problem) : icon);
698+
_tray->showMessage(title, msg, icon.isNull() ? Resources::getCoreIcon(QStringLiteral("states/error")) : icon);
698699
}
699700

700701
void ownCloudGui::slotShowOptionalTrayMessage(const QString &title, const QString &msg, const QIcon &icon)

src/gui/settingsdialog.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ SettingsDialog::SettingsDialog(ownCloudGui *gui, QWidget *parent)
230230
const auto appNameGui = Theme::instance()->appNameGUI();
231231

232232
for (const auto &[iconName, name, url] : Theme::instance()->urlButtons()) {
233-
auto urlAction = new ToolButtonAction(Theme::instance()->themeUniversalIcon(QStringLiteral("urlIcons/%1").arg(iconName)), name, this);
233+
auto urlAction = new ToolButtonAction(Resources::themeUniversalIcon(QStringLiteral("urlIcons/%1").arg(iconName)), name, this);
234234
urlAction->setCheckable(false);
235235
connect(urlAction, &QAction::triggered, this, [url = url] {
236236
if (!QDesktopServices::openUrl(url)) {

src/libsync/CMakeLists.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,12 @@ set_target_properties(libsync PROPERTIES EXPORT_NAME SyncCore)
8383
target_link_libraries(libsync
8484
PUBLIC
8585
csync
86+
owncloudResources
8687
Qt::Core
8788
Qt::Network
8889
Qt::Widgets
90+
8991
PRIVATE
90-
owncloudResources
9192
Qt::Concurrent
9293
ZLIB::ZLIB
9394
Qt6Keychain::Qt6Keychain

src/libsync/owncloudtheme.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ QColor ownCloudTheme::wizardHeaderTitleColor() const
4141

4242
QIcon ownCloudTheme::wizardHeaderLogo() const
4343
{
44-
return themeUniversalIcon(QStringLiteral("wizard_logo"));
44+
return Resources::themeUniversalIcon(QStringLiteral("wizard_logo"));
4545
}
4646

4747
QIcon ownCloudTheme::aboutIcon() const
4848
{
49-
return themeUniversalIcon(QStringLiteral("oc-image-about"));
49+
return Resources::themeUniversalIcon(QStringLiteral("oc-image-about"));
5050
}
5151
}

src/libsync/theme.cpp

+22-136
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@
3535
#endif
3636

3737
namespace {
38-
QString vanillaThemePath()
38+
QString whiteTheme()
3939
{
40-
return QStringLiteral(":/client/ownCloud/theme");
40+
return QStringLiteral("white");
4141
}
4242

43-
QString brandThemePath()
43+
QString blackTheme()
4444
{
45-
return QStringLiteral(":/client/" APPLICATION_SHORTNAME "/theme");
45+
return QStringLiteral("black");
4646
}
4747

4848
QString darkTheme()
@@ -55,16 +55,6 @@ QString coloredTheme()
5555
return QStringLiteral("colored");
5656
}
5757

58-
QString whiteTheme()
59-
{
60-
return QStringLiteral("white");
61-
}
62-
63-
QString blackTheme()
64-
{
65-
return QStringLiteral("black");
66-
}
67-
6858
constexpr bool isVanilla()
6959
{
7060
return std::string_view(APPLICATION_SHORTNAME) == "ownCloud";
@@ -118,7 +108,7 @@ QString Theme::configFileName() const
118108

119109
QIcon Theme::applicationIcon() const
120110
{
121-
return themeUniversalIcon(applicationIconName() + QStringLiteral("-icon"));
111+
return Resources::themeUniversalIcon(applicationIconName() + QStringLiteral("-icon"));
122112
}
123113

124114
QString Theme::applicationIconName() const
@@ -131,20 +121,25 @@ QIcon Theme::aboutIcon() const
131121
return applicationIcon();
132122
}
133123

134-
bool Theme::allowDarkTheme() const
124+
QIcon Theme::themeTrayIcon(const SyncResult &result, bool sysTrayMenuVisible, Resources::IconType iconType) const
135125
{
136-
return _hasBrandedColored == _hasBrandedDark;
137-
}
126+
auto systrayIconFlavor = [&]() {
127+
QString flavor;
128+
if (_mono) {
129+
flavor = Utility::hasDarkSystray() ? whiteTheme() : blackTheme();
138130

139-
140-
QIcon Theme::themeUniversalIcon(const QString &name, Theme::IconType iconType) const
141-
{
142-
return loadIcon(QStringLiteral("universal"), name, iconType);
143-
}
144-
145-
QIcon Theme::themeTrayIcon(const QString &name, bool sysTrayMenuVisible, IconType iconType) const
146-
{
147-
auto icon = loadIcon(systrayIconFlavor(_mono, sysTrayMenuVisible), name, iconType);
131+
#ifdef Q_OS_MAC
132+
if (sysTrayMenuVisible) {
133+
flavor = QLatin1String("white");
134+
}
135+
#endif
136+
} else {
137+
// we have a dark sys tray and the theme has support for that
138+
flavor = (Utility::hasDarkSystray() && Resources::hasDarkTheme()) ? darkTheme() : coloredTheme();
139+
}
140+
return flavor;
141+
};
142+
auto icon = Resources::loadIcon(systrayIconFlavor(), QStringLiteral("state-%1").arg(syncStateIconName(result)), iconType);
148143
#ifdef Q_OS_MAC
149144
// This defines the icon as a template and enables automatic macOS color handling
150145
// See https://bugreports.qt.io/browse/QTBUG-42109
@@ -153,89 +148,6 @@ QIcon Theme::themeTrayIcon(const QString &name, bool sysTrayMenuVisible, IconTyp
153148
return icon;
154149
}
155150

156-
QIcon Theme::themeIcon(const QString &name, Theme::IconType iconType) const
157-
{
158-
return loadIcon((Resources::isUsingDarkTheme() && allowDarkTheme()) ? darkTheme() : coloredTheme(), name, iconType);
159-
}
160-
/*
161-
* helper to load a icon from either the icon theme the desktop provides or from
162-
* the apps Qt resources.
163-
*/
164-
QIcon Theme::loadIcon(const QString &flavor, const QString &name, IconType iconType) const
165-
{
166-
// prevent recusion
167-
const bool useCoreIcon = (iconType == IconType::VanillaIcon) || isVanilla();
168-
const QString path = useCoreIcon ? vanillaThemePath() : brandThemePath();
169-
const QString key = name + QLatin1Char(',') + flavor;
170-
QIcon &cached = _iconCache[key]; // Take reference, this will also "set" the cache entry
171-
if (cached.isNull()) {
172-
if (isVanilla() && QIcon::hasThemeIcon(name)) {
173-
// use from theme
174-
return cached = QIcon::fromTheme(name);
175-
}
176-
const QString svg = QStringLiteral("%1/%2/%3.svg").arg(path, flavor, name);
177-
if (QFile::exists(svg)) {
178-
return cached = QIcon(svg);
179-
}
180-
181-
const QString png = QStringLiteral("%1/%2/%3.png").arg(path, flavor, name);
182-
if (QFile::exists(png)) {
183-
return cached = QIcon(png);
184-
}
185-
186-
const QList<int> sizes {16, 22, 32, 48, 64, 128, 256, 512, 1024};
187-
QString previousIcon;
188-
for (int size : sizes) {
189-
QString pixmapName = QStringLiteral("%1/%2/%3-%4.png").arg(path, flavor, name, QString::number(size));
190-
if (QFile::exists(pixmapName)) {
191-
previousIcon = pixmapName;
192-
cached.addFile(pixmapName, { size, size });
193-
} else if (size >= 128) {
194-
if (!previousIcon.isEmpty()) {
195-
qWarning() << "Upscaling:" << previousIcon << "to" << size;
196-
cached.addPixmap(QPixmap(previousIcon).scaled({ size, size }, Qt::KeepAspectRatio, Qt::SmoothTransformation));
197-
}
198-
}
199-
}
200-
}
201-
if (cached.isNull()) {
202-
if (!useCoreIcon && iconType == IconType::BrandedIconWithFallbackToVanillaIcon) {
203-
return loadIcon(flavor, name, IconType::VanillaIcon);
204-
}
205-
qWarning() << "Failed to locate the icon" << name;
206-
}
207-
return cached;
208-
}
209-
210-
bool Theme::hasTheme(IconType type, const QString &theme) const
211-
{
212-
const auto key = qMakePair(type != IconType::VanillaIcon, theme);
213-
auto it = _themeCache.constFind(key);
214-
if (it == _themeCache.cend()) {
215-
return _themeCache[key] = QFileInfo(QStringLiteral("%1/%2/").arg(type == IconType::VanillaIcon ? vanillaThemePath() : brandThemePath(), theme)).isDir();
216-
}
217-
return it.value();
218-
}
219-
220-
QString Theme::systrayIconFlavor(bool mono, bool sysTrayMenuVisible) const
221-
{
222-
Q_UNUSED(sysTrayMenuVisible)
223-
QString flavor;
224-
if (mono) {
225-
flavor = Utility::hasDarkSystray() ? whiteTheme() : blackTheme();
226-
227-
#ifdef Q_OS_MAC
228-
if (sysTrayMenuVisible) {
229-
flavor = QLatin1String("white");
230-
}
231-
#endif
232-
} else {
233-
// we have a dark sys tray and the theme has support for that
234-
flavor = (Utility::hasDarkSystray() && allowDarkTheme()) ? darkTheme() : coloredTheme();
235-
}
236-
return flavor;
237-
}
238-
239151
Theme::Theme()
240152
: QObject(nullptr)
241153
{
@@ -305,13 +217,6 @@ bool Theme::systrayUseMonoIcons() const
305217
return _mono;
306218
}
307219

308-
bool Theme::monoIconsAvailable() const
309-
{
310-
// mono icons are only supported in vanilla and if a customer provides them
311-
// no fallback to vanilla
312-
return hasTheme(IconType::BrandedIcon, systrayIconFlavor(true));
313-
}
314-
315220
QUrl Theme::updateCheckUrl() const
316221
{
317222
return QUrl(QStringLiteral(APPLICATION_UPDATE_URL));
@@ -445,25 +350,6 @@ QString Theme::syncStateIconName(const SyncResult &result) const
445350
Q_UNREACHABLE();
446351
}
447352

448-
QIcon Theme::syncStateIcon(SyncResult::Status status, bool sysTray, bool sysTrayMenuVisible) const
449-
{
450-
return syncStateIcon(SyncResult{status}, sysTray, sysTrayMenuVisible);
451-
}
452-
453-
QIcon Theme::syncStateIcon(const SyncResult &result, bool sysTray, bool sysTrayMenuVisible) const
454-
{
455-
return syncStateIcon(QStringLiteral("state-%1").arg(syncStateIconName(result)), sysTray, sysTrayMenuVisible);
456-
}
457-
458-
QIcon Theme::syncStateIcon(const QString &iconName, bool sysTray, bool sysTrayMenuVisible) const
459-
{
460-
if (sysTray) {
461-
return themeTrayIcon(iconName, sysTrayMenuVisible);
462-
} else {
463-
return themeIcon(iconName);
464-
}
465-
}
466-
467353
QColor Theme::wizardHeaderTitleColor() const
468354
{
469355
return qApp->palette().text().color();

0 commit comments

Comments
 (0)