Finished work on icon theme stuff.

This commit is contained in:
Martin Rotter 2013-08-03 07:34:41 +02:00
parent 4ee5c83501
commit 5afdb205d8
14 changed files with 127 additions and 94 deletions

@ -202,6 +202,7 @@ set(APP_HEADERS
# GUI headers. # GUI headers.
src/gui/formmain.h src/gui/formmain.h
src/gui/systemtrayicon.h src/gui/systemtrayicon.h
src/gui/themefactory.h
src/gui/formsettings.h src/gui/formsettings.h
src/gui/formwelcome.h src/gui/formwelcome.h
src/gui/formabout.h src/gui/formabout.h
@ -217,6 +218,7 @@ set(APP_HEADERS
src/gui/tabcontent.h src/gui/tabcontent.h
# CORE headers. # CORE headers.
src/core/settings.h
src/core/basenetworkaccessmanager.h src/core/basenetworkaccessmanager.h
src/core/webBrowsernetworkaccessmanager.h src/core/webBrowsernetworkaccessmanager.h
src/core/basewebpage.h src/core/basewebpage.h

@ -45,6 +45,7 @@
#define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/skins") #define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/skins")
#define APP_INFO_PATH QApplication::applicationDirPath() #define APP_INFO_PATH QApplication::applicationDirPath()
#define APP_THEME_PATH QApplication::applicationDirPath() + QString("/themes") #define APP_THEME_PATH QApplication::applicationDirPath() + QString("/themes")
#define APP_THEME_SYSTEM "-"
#define APP_FLAGS_PATH QApplication::applicationDirPath() + QString("/flags") #define APP_FLAGS_PATH QApplication::applicationDirPath() + QString("/flags")
#define APP_ICON_PATH QApplication::applicationDirPath() + QString("/@APP_LOW_NAME@.png") #define APP_ICON_PATH QApplication::applicationDirPath() + QString("/@APP_LOW_NAME@.png")
#define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/@APP_LOW_NAME@_plain.png") #define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/@APP_LOW_NAME@_plain.png")

@ -5,6 +5,8 @@
class Settings : public QSettings { class Settings : public QSettings {
Q_OBJECT
private: private:
static QPointer<Settings> s_instance; static QPointer<Settings> s_instance;

@ -38,10 +38,10 @@ void BaseWebView::createConnections() {
} }
void BaseWebView::setupIcons() { void BaseWebView::setupIcons() {
m_actionReload->setIcon(ThemeFactory::fromTheme("view-refresh")); m_actionReload->setIcon(ThemeFactory::getInstance()->fromTheme("view-refresh"));
m_actionCopyLink->setIcon(ThemeFactory::fromTheme("edit-copy")); m_actionCopyLink->setIcon(ThemeFactory::getInstance()->fromTheme("edit-copy"));
m_actionCopyImage->setIcon(ThemeFactory::fromTheme("insert-image")); m_actionCopyImage->setIcon(ThemeFactory::getInstance()->fromTheme("insert-image"));
m_actionCopyImageUrl->setIcon(ThemeFactory::fromTheme("edit-copy")); m_actionCopyImageUrl->setIcon(ThemeFactory::getInstance()->fromTheme("edit-copy"));
} }
void BaseWebView::initializeActions() { void BaseWebView::initializeActions() {
@ -79,7 +79,7 @@ void BaseWebView::popupContextMenu(const QPoint &pos) {
QMenu image_submenu(tr("Image"), &context_menu); QMenu image_submenu(tr("Image"), &context_menu);
QWebHitTestResult hit_result = page()->mainFrame()->hitTestContent(pos); QWebHitTestResult hit_result = page()->mainFrame()->hitTestContent(pos);
image_submenu.setIcon(ThemeFactory::fromTheme("image-x-generic")); image_submenu.setIcon(ThemeFactory::getInstance()->fromTheme("image-x-generic"));
// Assemble the menu from actions. // Assemble the menu from actions.
context_menu.addAction(m_actionReload); context_menu.addAction(m_actionReload);

@ -11,7 +11,7 @@ FormAbout::FormAbout(QWidget *parent) : QDialog(parent), m_ui(new Ui::FormAbout)
// Set flags and attributes. // Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog); setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog);
setWindowIcon(ThemeFactory::fromTheme("help-about")); setWindowIcon(ThemeFactory::getInstance()->fromTheme("help-about"));
m_ui->m_lblIcon->setPixmap(QPixmap(APP_ICON_PATH)); m_ui->m_lblIcon->setPixmap(QPixmap(APP_ICON_PATH));
// Load information from embedded text files. // Load information from embedded text files.

@ -23,7 +23,8 @@ FormMain::FormMain(QWidget *parent) : QMainWindow(parent), m_ui(new Ui::FormMain
// Prepare main window. // Prepare main window.
prepareMenus(); prepareMenus();
prepareTabs();
m_ui->m_tabWidget->initializeTabs();
// Establish connections. // Establish connections.
createConnections(); createConnections();
@ -57,13 +58,6 @@ QList<QAction*> FormMain::getActions() {
} }
void FormMain::prepareTabs() { void FormMain::prepareTabs() {
// Create widget for "Feeds" page and add it.
WebBrowser *browser = new WebBrowser(m_ui->m_tabWidget);
int index_of_browser = m_ui->m_tabWidget->addTab(static_cast<TabContent*>(browser),
QIcon(),
tr("Feeds"),
TabBar::FeedReader);
m_ui->m_tabWidget->setTabToolTip(index_of_browser, tr("Browser your feeds and messages"));
} }
void FormMain::addEmptyBrowser() { void FormMain::addEmptyBrowser() {
@ -184,12 +178,12 @@ bool FormMain::event(QEvent *event) {
void FormMain::setupIcons() { void FormMain::setupIcons() {
// Setup icons of this main window. // Setup icons of this main window.
m_ui->m_actionSettings->setIcon(ThemeFactory::fromTheme("preferences-system")); m_ui->m_actionSettings->setIcon(ThemeFactory::getInstance()->fromTheme("preferences-system"));
m_ui->m_actionQuit->setIcon(ThemeFactory::fromTheme("application-exit")); m_ui->m_actionQuit->setIcon(ThemeFactory::getInstance()->fromTheme("application-exit"));
m_ui->m_actionAboutGuard->setIcon(ThemeFactory::fromTheme("help-about")); m_ui->m_actionAboutGuard->setIcon(ThemeFactory::getInstance()->fromTheme("help-about"));
m_ui->m_actionImport->setIcon(ThemeFactory::fromTheme("document-import")); m_ui->m_actionImport->setIcon(ThemeFactory::getInstance()->fromTheme("document-import"));
m_ui->m_actionExport->setIcon(ThemeFactory::fromTheme("document-export")); m_ui->m_actionExport->setIcon(ThemeFactory::getInstance()->fromTheme("document-export"));
m_ui->m_actionFullscreen->setIcon(ThemeFactory::fromTheme("view-fullscreen")); m_ui->m_actionFullscreen->setIcon(ThemeFactory::getInstance()->fromTheme("view-fullscreen"));
// Setup icons for underlying components: opened web browsers... // Setup icons for underlying components: opened web browsers...
foreach (WebBrowser *browser, WebBrowser::runningWebBrowsers()) { foreach (WebBrowser *browser, WebBrowser::runningWebBrowsers()) {

@ -21,7 +21,7 @@ FormSettings::FormSettings(QWidget *parent) : QDialog(parent), m_ui(new Ui::Form
// Set flags and attributes. // Set flags and attributes.
setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog); setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog);
setWindowIcon(ThemeFactory::fromTheme("preferences-system")); setWindowIcon(ThemeFactory::getInstance()->fromTheme("preferences-system"));
// Setup behavior. // Setup behavior.
m_ui->m_treeLanguages->setColumnCount(5); m_ui->m_treeLanguages->setColumnCount(5);
@ -290,31 +290,31 @@ void FormSettings::loadInterface() {
} }
// Load settings of icon theme. // Load settings of icon theme.
QString current_theme = ThemeFactory::getCurrentIconTheme(); QString current_theme = ThemeFactory::getInstance()->getCurrentIconTheme();
foreach (QString icon_theme_name, ThemeFactory::getInstalledIconThemes()) { foreach (QString icon_theme_name, ThemeFactory::getInstance()->getInstalledIconThemes()) {
#if defined(Q_OS_LINUX)
if (icon_theme_name == APP_THEME_SYSTEM) { if (icon_theme_name == APP_THEME_SYSTEM) {
#if defined(Q_OS_LINUX)
m_ui->m_cmbIconTheme->addItem(tr("system icon theme (default)"), m_ui->m_cmbIconTheme->addItem(tr("system icon theme (default)"),
icon_theme_name); APP_THEME_SYSTEM);
#else
m_ui->m_cmbIconTheme->addItem(tr("no icon theme"),
APP_THEME_SYSTEM);
#endif
} }
else { else {
#endif
m_ui->m_cmbIconTheme->addItem(icon_theme_name, m_ui->m_cmbIconTheme->addItem(icon_theme_name,
icon_theme_name); icon_theme_name);
#if defined(Q_OS_LINUX)
} }
if (current_theme == APP_THEME_SYSTEM) { }
// Because system icon theme lies at the index 0.
// See ThemeFactory::getInstalledIconThemes() for more info. // Mark active theme.
m_ui->m_cmbIconTheme->setCurrentIndex(0); if (current_theme == APP_THEME_SYSTEM) {
} // Because system icon theme lies at the index 1.
else { m_ui->m_cmbIconTheme->setCurrentIndex(0);
#endif }
m_ui->m_cmbIconTheme->setCurrentText(current_theme); else {
#if defined(Q_OS_LINUX) m_ui->m_cmbIconTheme->setCurrentText(current_theme);
}
#endif
} }
// Load tab settings. // Load tab settings.
@ -349,9 +349,7 @@ void FormSettings::saveInterface() {
// Save selected icon theme. // Save selected icon theme.
QString selected_icon_theme = m_ui->m_cmbIconTheme->itemData(m_ui->m_cmbIconTheme->currentIndex()).toString(); QString selected_icon_theme = m_ui->m_cmbIconTheme->itemData(m_ui->m_cmbIconTheme->currentIndex()).toString();
if (!selected_icon_theme.isEmpty()) { ThemeFactory::getInstance()->setCurrentIconTheme(selected_icon_theme);
ThemeFactory::setCurrentIconTheme(selected_icon_theme);
}
// Save tab settings. // Save tab settings.
Settings::getInstance()->setValue(APP_CFG_GUI, "tab_close_mid_button", Settings::getInstance()->setValue(APP_CFG_GUI, "tab_close_mid_button",

@ -43,7 +43,7 @@ ShortcutCatcher::ShortcutCatcher(QWidget *parent)
// Create clear button. // Create clear button.
m_clearButton = new QToolButton(this); m_clearButton = new QToolButton(this);
m_clearButton->setIcon(ThemeFactory::fromTheme("document-revert")); m_clearButton->setIcon(ThemeFactory::getInstance()->fromTheme("document-revert"));
m_clearButton->setFocusPolicy(Qt::NoFocus); m_clearButton->setFocusPolicy(Qt::NoFocus);
// Clear main shortcut catching button. // Clear main shortcut catching button.

@ -1,5 +1,6 @@
#include "gui/tabwidget.h" #include "gui/tabwidget.h"
#include "gui/tabbar.h" #include "gui/tabbar.h"
#include "gui/webbrowser.h"
TabWidget::TabWidget(QWidget *parent) : QTabWidget(parent) { TabWidget::TabWidget(QWidget *parent) : QTabWidget(parent) {
@ -19,6 +20,16 @@ TabBar *TabWidget::tabBar() {
return static_cast<TabBar*>(QTabWidget::tabBar()); return static_cast<TabBar*>(QTabWidget::tabBar());
} }
void TabWidget::initializeTabs() {
// Create widget for "Feeds" page and add it.
WebBrowser *browser = new WebBrowser(this);
int index_of_browser = addTab(static_cast<TabContent*>(browser),
QIcon(),
tr("Feeds"),
TabBar::FeedReader);
setTabToolTip(index_of_browser, tr("Browse your feeds and messages"));
}
void TabWidget::closeTab(int index) { void TabWidget::closeTab(int index) {
removeTab(index); removeTab(index);
} }

@ -29,6 +29,8 @@ class TabWidget : public QTabWidget {
// Returns tab bar. // Returns tab bar.
TabBar *tabBar(); TabBar *tabBar();
void initializeTabs();
protected: protected:
// Creates necesary connections. // Creates necesary connections.
void createConnections(); void createConnections();

@ -1,6 +1,7 @@
#include <QIcon> #include <QIcon>
#include <QFile> #include <QFile>
#include <QDir> #include <QDir>
#include <QPointer>
#include <QApplication> #include <QApplication>
#include "gui/themefactory.h" #include "gui/themefactory.h"
@ -9,6 +10,7 @@
#include "core/defs.h" #include "core/defs.h"
QPointer<ThemeFactory> ThemeFactory::s_instance;
QEvent::Type ThemeFactoryEvent::m_typeOfEvent = QEvent::None; QEvent::Type ThemeFactoryEvent::m_typeOfEvent = QEvent::None;
// //
@ -34,20 +36,31 @@ QEvent::Type ThemeFactoryEvent::type() {
// ThemeFactory class // ThemeFactory class
// //
ThemeFactory::ThemeFactory() { ThemeFactory::ThemeFactory(QObject *parent)
: QObject(parent), m_currentIconTheme(APP_THEME_SYSTEM) {
}
ThemeFactory::~ThemeFactory() {
qDebug("Destroying ThemeFactory instance.");
}
ThemeFactory *ThemeFactory::getInstance() {
if (s_instance.isNull()) {
s_instance = new ThemeFactory(qApp);
}
return s_instance;
} }
void ThemeFactory::setupSearchPaths() { void ThemeFactory::setupSearchPaths() {
// Add custom icon theme path to existing ones.
QIcon::setThemeSearchPaths(QIcon::themeSearchPaths() << APP_THEME_PATH); QIcon::setThemeSearchPaths(QIcon::themeSearchPaths() << APP_THEME_PATH);
qDebug("Available icon theme paths: %s.", qDebug("Available icon theme paths: %s.",
qPrintable(QIcon::themeSearchPaths().join(", "))); qPrintable(QIcon::themeSearchPaths().join(", ")));
} }
QString ThemeFactory::getCurrentIconTheme() { QString ThemeFactory::getCurrentIconTheme() {
QString current_theme_name = Settings::getInstance()->value(APP_CFG_GUI, return m_currentIconTheme;
"icon_theme",
"mini-kfaenza").toString();
return current_theme_name;
} }
QIcon ThemeFactory::fromTheme(const QString &name, const QIcon &fallback) { QIcon ThemeFactory::fromTheme(const QString &name, const QIcon &fallback) {
@ -62,26 +75,30 @@ void ThemeFactory::setCurrentIconTheme(const QString &theme_name) {
} }
void ThemeFactory::loadCurrentIconTheme(bool notify_widgets) { void ThemeFactory::loadCurrentIconTheme(bool notify_widgets) {
QString theme_name = getCurrentIconTheme();
QStringList installed_themes = getInstalledIconThemes(); QStringList installed_themes = getInstalledIconThemes();
QString theme_name_from_settings = Settings::getInstance()->value(APP_CFG_GUI,
"icon_theme",
"mini-kfaenza").toString();
qDebug("Installed icon themes are: %s.", qDebug("Installed icon themes are: %s.",
qPrintable(installed_themes.join(", "))); qPrintable(installed_themes.join(", ")));
if (!installed_themes.contains(theme_name)) { // User wants to load icon theme, but it's not installed.
qDebug("Icon theme '%s' cannot be loaded because it is not installed.", if (!installed_themes.contains(theme_name_from_settings)) {
qPrintable(theme_name)); qDebug("Icon theme '%s' cannot be loaded because it is not installed. Loading 'default' theme.",
qPrintable(theme_name_from_settings));
QIcon::setThemeName(APP_THEME_SYSTEM);
m_currentIconTheme = APP_THEME_SYSTEM;
} }
// Icon theme is found so it can be installed.
else { else {
qDebug("Loading theme '%s'.", qPrintable(theme_name)); qDebug("Loading theme '%s'.", qPrintable(theme_name_from_settings));
QIcon::setThemeName(theme_name); QIcon::setThemeName(theme_name_from_settings);
m_currentIconTheme = theme_name_from_settings;
} }
// We need to deliver custom event for all widgets // We need to deliver custom event for all widgets
// to make sure they get a chance to setup their icons. // to make sure they get a chance to setup their icons.
// NOTE: Event is delivered even if custom icon theme is not set
// as active, because all widgets need to do initial
// icons initialization based in the event receival.
if (notify_widgets) { if (notify_widgets) {
foreach (QWidget *widget, QtSingleApplication::allWidgets()) { foreach (QWidget *widget, QtSingleApplication::allWidgets()) {
QtSingleApplication::postEvent((QObject*) widget, QtSingleApplication::postEvent((QObject*) widget,
@ -92,11 +109,7 @@ void ThemeFactory::loadCurrentIconTheme(bool notify_widgets) {
QStringList ThemeFactory::getInstalledIconThemes() { QStringList ThemeFactory::getInstalledIconThemes() {
QStringList icon_theme_names; QStringList icon_theme_names;
#if defined(Q_OS_LINUX)
// Add system theme on Linux, it is denoted as empty string.
icon_theme_names << APP_THEME_SYSTEM; icon_theme_names << APP_THEME_SYSTEM;
#endif
// Iterate all directories with icon themes. // Iterate all directories with icon themes.
QStringList icon_themes_paths = QIcon::themeSearchPaths(); QStringList icon_themes_paths = QIcon::themeSearchPaths();

@ -6,35 +6,49 @@
#include <QIcon> #include <QIcon>
class ThemeFactory { class ThemeFactory : public QObject {
private: Q_OBJECT
ThemeFactory();
public: public:
// Adds custom application path to be search for icons. // Singleton getter.
static void setupSearchPaths(); static ThemeFactory *getInstance();
// Returns list of installed themes, this includes:
// a) system-wide themes,
// b) application-wide themes.
static QStringList getInstalledIconThemes();
// Loads name of selected icon theme for the application and activates it.
// NOTE: All existing widgets get a chance to repaint its icons if
// notify_widgets is true.
static void loadCurrentIconTheme(bool notify_widgets);
// Returns name of currently activated theme for the application.
static QString getCurrentIconTheme();
// Sets icon theme with given name as the active one.
static void setCurrentIconTheme(const QString &theme_name);
// Wrapper for QIcon::fromTheme. // Wrapper for QIcon::fromTheme.
// TODO: If icon is not found in user-defined icon theme, // TODO: If icon is not found in user-defined icon theme,
// then it is searched in system-default theme (ThemeFactory::getSystemIconTheme()). // then it is searched in system-default theme (ThemeFactory::getSystemIconTheme()).
// BUG: I tried to do that, but QIcon is apparently bugged. // BUG: I tried to do that, but QIcon is apparently bugged.
static QIcon fromTheme(const QString & name, const QIcon & fallback = QIcon()); QIcon fromTheme(const QString &name, const QIcon &fallback = QIcon());
// Adds custom application path to be search for icons.
void setupSearchPaths();
// Returns list of installed themes, including "default" theme.
// NOTE: "Default" theme is system theme on Linux and "no theme" on windows.
QStringList getInstalledIconThemes();
// Loads name of selected icon theme (from settings) for the application and
// activates it. If that particular theme is not installed, then
// "default" theme is loaded.
// NOTE: All existing widgets get a chance to repaint its icons if
// notify_widgets is true.
void loadCurrentIconTheme(bool notify_widgets);
// Returns name of currently activated theme for the application.
QString getCurrentIconTheme();
// Sets icon theme with given name as the active one and loads it.
void setCurrentIconTheme(const QString &theme_name);
private:
// Constructors and destructors
explicit ThemeFactory(QObject *parent = 0);
virtual ~ThemeFactory();
// Holds name of the current icon theme.
QString m_currentIconTheme;
// Singleton.
static QPointer<ThemeFactory> s_instance;
}; };
class ThemeFactoryEvent : public QEvent { class ThemeFactoryEvent : public QEvent {
@ -43,7 +57,8 @@ class ThemeFactoryEvent : public QEvent {
IconThemeChange = 2000 IconThemeChange = 2000
}; };
ThemeFactoryEvent(); // Constructors.
explicit ThemeFactoryEvent();
virtual ~ThemeFactoryEvent(); virtual ~ThemeFactoryEvent();
static QEvent::Type type(); static QEvent::Type type();

@ -119,10 +119,10 @@ QMenu *WebBrowser::globalMenu() {
} }
void WebBrowser::setupIcons() { void WebBrowser::setupIcons() {
m_actionBack->setIcon(ThemeFactory::fromTheme("go-previous")); m_actionBack->setIcon(ThemeFactory::getInstance()->fromTheme("go-previous"));
m_actionForward->setIcon(ThemeFactory::fromTheme("go-next")); m_actionForward->setIcon(ThemeFactory::getInstance()->fromTheme("go-next"));
m_actionReload->setIcon(ThemeFactory::fromTheme("view-refresh")); m_actionReload->setIcon(ThemeFactory::getInstance()->fromTheme("view-refresh"));
m_actionStop->setIcon(ThemeFactory::fromTheme("process-stop")); m_actionStop->setIcon(ThemeFactory::getInstance()->fromTheme("process-stop"));
m_webView->setupIcons(); m_webView->setupIcons();
} }

@ -63,8 +63,8 @@ int main(int argc, char *argv[]) {
#endif #endif
// Add an extra path for non-system icon themes and set current icon theme. // Add an extra path for non-system icon themes and set current icon theme.
ThemeFactory::setupSearchPaths(); ThemeFactory::getInstance()->setupSearchPaths();
ThemeFactory::loadCurrentIconTheme(false); ThemeFactory::getInstance()->loadCurrentIconTheme(false);
// Load localization and setup locale before any widget is constructed. // Load localization and setup locale before any widget is constructed.
LoadLocalization(); LoadLocalization();
@ -108,11 +108,6 @@ int main(int argc, char *argv[]) {
SystemTrayIcon::getInstance()->show(); SystemTrayIcon::getInstance()->show();
} }
// Load icon theme from settings.
// NOTE: Make sure that this is done after main window and
// other startup widgets are created.
//ThemeFactory::loadCurrentIconTheme();
// Setup single-instance behavior. // Setup single-instance behavior.
QObject::connect(&application, &QtSingleApplication::messageReceived, QObject::connect(&application, &QtSingleApplication::messageReceived,
&window, &FormMain::processExecutionMessage); &window, &FormMain::processExecutionMessage);