Adjust theme icons lookup logic to resemble that of GTK (Qt client) (#2288)

Look for RTL and symbolic icon variants for each icon that we load. The
only exception here is Transmission's own icons, where it doesn't make
sense (the way I see it).
This commit is contained in:
Mike Gelfand 2021-12-09 11:13:04 +03:00 committed by GitHub
parent ab0c49859e
commit eeb82b2fd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 86 additions and 70 deletions

View File

@ -35,6 +35,7 @@
#include "ColumnResizer.h"
#include "DetailsDialog.h"
#include "Formatter.h"
#include "IconCache.h"
#include "Prefs.h"
#include "Session.h"
#include "SqueezeLabel.h"
@ -198,18 +199,6 @@ private:
****
***/
QIcon DetailsDialog::getStockIcon(QString const& freedesktop_name, int fallback) const
{
QIcon icon = QIcon::fromTheme(freedesktop_name);
if (icon.isNull())
{
icon = style()->standardIcon(QStyle::StandardPixmap(fallback), nullptr, this);
}
return icon;
}
DetailsDialog::DetailsDialog(Session& session, Prefs& prefs, TorrentModel const& model, QWidget* parent)
: BaseDialog(parent)
, session_(session)
@ -1449,9 +1438,10 @@ void DetailsDialog::initTrackerTab()
ui_.trackersView->setModel(tracker_filter_.get());
ui_.trackersView->setItemDelegate(tracker_delegate_.get());
ui_.addTrackerButton->setIcon(getStockIcon(QStringLiteral("list-add"), QStyle::SP_DialogOpenButton));
ui_.editTrackerButton->setIcon(getStockIcon(QStringLiteral("document-properties"), QStyle::SP_DesktopIcon));
ui_.removeTrackerButton->setIcon(getStockIcon(QStringLiteral("list-remove"), QStyle::SP_TrashIcon));
auto& icons = IconCache::get();
ui_.addTrackerButton->setIcon(icons.getThemeIcon(QStringLiteral("list-add"), QStyle::SP_DialogOpenButton));
ui_.editTrackerButton->setIcon(icons.getThemeIcon(QStringLiteral("document-properties"), QStyle::SP_DesktopIcon));
ui_.removeTrackerButton->setIcon(icons.getThemeIcon(QStringLiteral("list-remove"), QStyle::SP_TrashIcon));
ui_.showTrackerScrapesCheck->setChecked(prefs_.getBool(Prefs::SHOW_TRACKER_SCRAPES));
ui_.showBackupTrackersCheck->setChecked(prefs_.getBool(Prefs::SHOW_BACKUP_TRACKERS));

View File

@ -55,7 +55,6 @@ private:
void initFilesTab() const;
void initOptionsTab();
QIcon getStockIcon(QString const& freedesktop_name, int fallback) const;
void setEnabled(bool);
private slots:

View File

@ -22,6 +22,7 @@
#include "FilterBarComboBox.h"
#include "FilterBarComboBoxDelegate.h"
#include "Filters.h"
#include "IconCache.h"
#include "Prefs.h"
#include "Torrent.h"
#include "TorrentFilter.h"
@ -53,31 +54,33 @@ FilterBarComboBox* FilterBar::createActivityCombo()
model->appendRow(new QStandardItem); // separator
FilterBarComboBoxDelegate::setSeparator(model, model->index(1, 0));
row = new QStandardItem(QIcon::fromTheme(QStringLiteral("system-run")), tr("Active"));
auto& icons = IconCache::get();
row = new QStandardItem(icons.getThemeIcon(QStringLiteral("system-run")), tr("Active"));
row->setData(FilterMode::SHOW_ACTIVE, ACTIVITY_ROLE);
model->appendRow(row);
row = new QStandardItem(QIcon::fromTheme(QStringLiteral("go-down")), tr("Downloading"));
row = new QStandardItem(icons.getThemeIcon(QStringLiteral("go-down")), tr("Downloading"));
row->setData(FilterMode::SHOW_DOWNLOADING, ACTIVITY_ROLE);
model->appendRow(row);
row = new QStandardItem(QIcon::fromTheme(QStringLiteral("go-up")), tr("Seeding"));
row = new QStandardItem(icons.getThemeIcon(QStringLiteral("go-up")), tr("Seeding"));
row->setData(FilterMode::SHOW_SEEDING, ACTIVITY_ROLE);
model->appendRow(row);
row = new QStandardItem(QIcon::fromTheme(QStringLiteral("media-playback-pause")), tr("Paused"));
row = new QStandardItem(icons.getThemeIcon(QStringLiteral("media-playback-pause")), tr("Paused"));
row->setData(FilterMode::SHOW_PAUSED, ACTIVITY_ROLE);
model->appendRow(row);
row = new QStandardItem(QIcon::fromTheme(QStringLiteral("dialog-ok")), tr("Finished"));
row = new QStandardItem(icons.getThemeIcon(QStringLiteral("dialog-ok")), tr("Finished"));
row->setData(FilterMode::SHOW_FINISHED, ACTIVITY_ROLE);
model->appendRow(row);
row = new QStandardItem(QIcon::fromTheme(QStringLiteral("view-refresh")), tr("Verifying"));
row = new QStandardItem(icons.getThemeIcon(QStringLiteral("view-refresh")), tr("Verifying"));
row->setData(FilterMode::SHOW_VERIFYING, ACTIVITY_ROLE);
model->appendRow(row);
row = new QStandardItem(QIcon::fromTheme(QStringLiteral("process-stop")), tr("Error"));
row = new QStandardItem(icons.getThemeIcon(QStringLiteral("process-stop")), tr("Error"));
row->setData(FilterMode::SHOW_ERROR, ACTIVITY_ROLE);
model->appendRow(row);

View File

@ -13,6 +13,7 @@
#include <shellapi.h>
#endif
#include <QApplication>
#include <QFile>
#include <QFileIconProvider>
#include <QFileInfo>
@ -86,11 +87,11 @@ QIcon IconCache::getMimeTypeIcon(QString const& mime_type_name, bool multifile)
{
QMimeDatabase mime_db;
auto const type = mime_db.mimeTypeForName(mime_type_name);
icon = QIcon::fromTheme(type.iconName());
icon = getThemeIcon(type.iconName());
if (icon.isNull())
{
icon = QIcon::fromTheme(type.genericIconName());
icon = getThemeIcon(type.genericIconName());
}
if (icon.isNull())
@ -125,6 +126,11 @@ QIcon IconCache::getMimeTypeIcon(QString const& mime_type_name, bool multifile)
return icon;
}
QIcon IconCache::getThemeIcon(QString const& name, std::optional<QStyle::StandardPixmap> const& fallback) const
{
return getThemeIcon(name, name + QStringLiteral("-symbolic"), fallback);
}
/***
****
***/
@ -197,12 +203,12 @@ QIcon IconCache::getMimeIcon(QString const& filename) const
auto const type = mime_db.mimeTypeForFile(filename, QMimeDatabase::MatchExtension);
if (icon.isNull())
{
icon = QIcon::fromTheme(type.iconName());
icon = getThemeIcon(type.iconName());
}
if (icon.isNull())
{
icon = QIcon::fromTheme(type.genericIconName());
icon = getThemeIcon(type.genericIconName());
}
if (icon.isNull())
@ -215,3 +221,25 @@ QIcon IconCache::getMimeIcon(QString const& filename) const
}
#endif
QIcon IconCache::getThemeIcon(
QString const& name,
QString const& fallbackName,
std::optional<QStyle::StandardPixmap> const& fallbackPixmap) const
{
static auto const rtlSuffix = qApp->layoutDirection() == Qt::RightToLeft ? QStringLiteral("-rtl") : QString();
auto icon = QIcon::fromTheme(name + rtlSuffix);
if (icon.isNull())
{
icon = getThemeIcon(fallbackName + rtlSuffix);
}
if (icon.isNull() && fallbackPixmap.has_value())
{
icon = qApp->style()->standardIcon(*fallbackPixmap, nullptr);
}
return icon;
}

View File

@ -12,11 +12,13 @@
#include <unordered_set>
#endif
#include <optional>
#include <unordered_map>
#include <QFileIconProvider>
#include <QIcon>
#include <QString>
#include <QStyle>
#include "Utils.h" // std::hash<QString>()
@ -44,6 +46,8 @@ public:
QIcon guessMimeIcon(QString const& filename, QIcon fallback = {}) const;
QIcon getMimeTypeIcon(QString const& mime_type, bool multifile) const;
QIcon getThemeIcon(QString const& name, std::optional<QStyle::StandardPixmap> const& fallback = {}) const;
protected:
IconCache() = default;
@ -61,4 +65,9 @@ private:
mutable std::unordered_map<QString, QIcon> ext_to_icon_;
QIcon getMimeIcon(QString const& filename) const;
#endif
QIcon getThemeIcon(
QString const& name,
QString const& fallbackName,
std::optional<QStyle::StandardPixmap> const& fallbackPixmap) const;
};

View File

@ -30,6 +30,7 @@
#include "FilterBar.h"
#include "Filters.h"
#include "Formatter.h"
#include "IconCache.h"
#include "MainWindow.h"
#include "MakeDialog.h"
#include "OptionsDialog.h"
@ -78,18 +79,6 @@ public:
}
};
QIcon MainWindow::getStockIcon(QString const& name, int fallback) const
{
QIcon icon = QIcon::fromTheme(name);
if (icon.isNull() && fallback >= 0)
{
icon = style()->standardIcon(QStyle::StandardPixmap(fallback), nullptr, this);
}
return icon;
}
QIcon MainWindow::addEmblem(QIcon base_icon, QStringList const& emblem_names) const
{
if (base_icon.isNull())
@ -97,11 +86,12 @@ QIcon MainWindow::addEmblem(QIcon base_icon, QStringList const& emblem_names) co
return base_icon;
}
auto& icons = IconCache::get();
QIcon emblem_icon;
for (QString const& emblem_name : emblem_names)
{
emblem_icon = QIcon::fromTheme(emblem_name);
emblem_icon = icons.getThemeIcon(emblem_name);
if (!emblem_icon.isNull())
{
@ -156,41 +146,43 @@ MainWindow::MainWindow(Session& session, Prefs& prefs, TorrentModel& model, bool
ui_.listView->setStyle(lvp_style_.get());
ui_.listView->setAttribute(Qt::WA_MacShowFocusRect, false);
auto& icons = IconCache::get();
// icons
QIcon const icon_play = getStockIcon(QStringLiteral("media-playback-start"), QStyle::SP_MediaPlay);
QIcon const icon_pause = getStockIcon(QStringLiteral("media-playback-pause"), QStyle::SP_MediaPause);
QIcon const icon_open = getStockIcon(QStringLiteral("document-open"), QStyle::SP_DialogOpenButton);
QIcon const icon_play = icons.getThemeIcon(QStringLiteral("media-playback-start"), QStyle::SP_MediaPlay);
QIcon const icon_pause = icons.getThemeIcon(QStringLiteral("media-playback-pause"), QStyle::SP_MediaPause);
QIcon const icon_open = icons.getThemeIcon(QStringLiteral("document-open"), QStyle::SP_DialogOpenButton);
ui_.action_OpenFile->setIcon(icon_open);
ui_.action_AddURL->setIcon(
addEmblem(icon_open, QStringList() << QStringLiteral("emblem-web") << QStringLiteral("applications-internet")));
ui_.action_New->setIcon(getStockIcon(QStringLiteral("document-new"), QStyle::SP_DesktopIcon));
ui_.action_Properties->setIcon(getStockIcon(QStringLiteral("document-properties"), QStyle::SP_DesktopIcon));
ui_.action_OpenFolder->setIcon(getStockIcon(QStringLiteral("folder-open"), QStyle::SP_DirOpenIcon));
ui_.action_New->setIcon(icons.getThemeIcon(QStringLiteral("document-new"), QStyle::SP_DesktopIcon));
ui_.action_Properties->setIcon(icons.getThemeIcon(QStringLiteral("document-properties"), QStyle::SP_DesktopIcon));
ui_.action_OpenFolder->setIcon(icons.getThemeIcon(QStringLiteral("folder-open"), QStyle::SP_DirOpenIcon));
ui_.action_Start->setIcon(icon_play);
ui_.action_StartNow->setIcon(icon_play);
ui_.action_Announce->setIcon(getStockIcon(QStringLiteral("network-transmit-receive")));
ui_.action_Announce->setIcon(icons.getThemeIcon(QStringLiteral("network-transmit-receive")));
ui_.action_Pause->setIcon(icon_pause);
ui_.action_Remove->setIcon(getStockIcon(QStringLiteral("list-remove"), QStyle::SP_TrashIcon));
ui_.action_Delete->setIcon(getStockIcon(QStringLiteral("edit-delete"), QStyle::SP_TrashIcon));
ui_.action_Remove->setIcon(icons.getThemeIcon(QStringLiteral("list-remove"), QStyle::SP_TrashIcon));
ui_.action_Delete->setIcon(icons.getThemeIcon(QStringLiteral("edit-delete"), QStyle::SP_TrashIcon));
ui_.action_StartAll->setIcon(icon_play);
ui_.action_PauseAll->setIcon(icon_pause);
ui_.action_Quit->setIcon(getStockIcon(QStringLiteral("application-exit")));
ui_.action_SelectAll->setIcon(getStockIcon(QStringLiteral("edit-select-all")));
ui_.action_ReverseSortOrder->setIcon(getStockIcon(QStringLiteral("view-sort-ascending"), QStyle::SP_ArrowDown));
ui_.action_Preferences->setIcon(getStockIcon(QStringLiteral("preferences-system")));
ui_.action_Contents->setIcon(getStockIcon(QStringLiteral("help-contents"), QStyle::SP_DialogHelpButton));
ui_.action_About->setIcon(getStockIcon(QStringLiteral("help-about")));
ui_.action_QueueMoveTop->setIcon(getStockIcon(QStringLiteral("go-top")));
ui_.action_QueueMoveUp->setIcon(getStockIcon(QStringLiteral("go-up"), QStyle::SP_ArrowUp));
ui_.action_QueueMoveDown->setIcon(getStockIcon(QStringLiteral("go-down"), QStyle::SP_ArrowDown));
ui_.action_QueueMoveBottom->setIcon(getStockIcon(QStringLiteral("go-bottom")));
ui_.action_Quit->setIcon(icons.getThemeIcon(QStringLiteral("application-exit")));
ui_.action_SelectAll->setIcon(icons.getThemeIcon(QStringLiteral("edit-select-all")));
ui_.action_ReverseSortOrder->setIcon(icons.getThemeIcon(QStringLiteral("view-sort-ascending"), QStyle::SP_ArrowDown));
ui_.action_Preferences->setIcon(icons.getThemeIcon(QStringLiteral("preferences-system")));
ui_.action_Contents->setIcon(icons.getThemeIcon(QStringLiteral("help-contents"), QStyle::SP_DialogHelpButton));
ui_.action_About->setIcon(icons.getThemeIcon(QStringLiteral("help-about")));
ui_.action_QueueMoveTop->setIcon(icons.getThemeIcon(QStringLiteral("go-top")));
ui_.action_QueueMoveUp->setIcon(icons.getThemeIcon(QStringLiteral("go-up"), QStyle::SP_ArrowUp));
ui_.action_QueueMoveDown->setIcon(icons.getThemeIcon(QStringLiteral("go-down"), QStyle::SP_ArrowDown));
ui_.action_QueueMoveBottom->setIcon(icons.getThemeIcon(QStringLiteral("go-bottom")));
ui_.optionsButton->setIcon(getStockIcon(QStringLiteral("preferences-other")));
ui_.statsModeButton->setIcon(getStockIcon(QStringLiteral("view-statistics")));
ui_.optionsButton->setIcon(icons.getThemeIcon(QStringLiteral("preferences-other")));
ui_.statsModeButton->setIcon(icons.getThemeIcon(QStringLiteral("view-statistics")));
auto make_network_pixmap = [this](QString name, QSize size = { 16, 16 })
auto make_network_pixmap = [this, &icons](QString name, QSize size = { 16, 16 })
{
return getStockIcon(name, QStyle::SP_DriveNetIcon).pixmap(size);
return icons.getThemeIcon(name, QStyle::SP_DriveNetIcon).pixmap(size);
};
pixmap_network_error_ = make_network_pixmap(QStringLiteral("network-error"));
pixmap_network_idle_ = make_network_pixmap(QStringLiteral("network-idle"));

View File

@ -123,7 +123,6 @@ private slots:
void trayActivated(QSystemTrayIcon::ActivationReason);
private:
QIcon getStockIcon(QString const&, int fallback = -1) const;
QIcon addEmblem(QIcon icon, QStringList const& emblem_names) const;
torrent_ids_t getSelectedTorrents(bool withMetadataOnly = false) const;

View File

@ -17,6 +17,7 @@
#include <QStyleOptionProgressBar>
#include "Formatter.h"
#include "IconCache.h"
#include "Torrent.h"
#include "TorrentDelegate.h"
#include "TorrentModel.h"
@ -437,12 +438,7 @@ QIcon& TorrentDelegate::getWarningEmblem() const
if (icon.isNull())
{
icon = QIcon::fromTheme(QStringLiteral("emblem-important"));
}
if (icon.isNull())
{
icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
icon = IconCache::get().getThemeIcon(QStringLiteral("emblem-important"), QStyle::SP_MessageBoxWarning);
}
return icon;