From 5afdb205d841e24ffc65a21d5652b9d94b1280a5 Mon Sep 17 00:00:00 2001 From: Martin Rotter Date: Sat, 3 Aug 2013 07:34:41 +0200 Subject: [PATCH] Finished work on icon theme stuff. --- CMakeLists.txt | 2 ++ src/core/defs.h.in | 1 + src/core/settings.h | 2 ++ src/gui/basewebview.cpp | 10 +++--- src/gui/formabout.cpp | 2 +- src/gui/formmain.cpp | 22 +++++-------- src/gui/formsettings.cpp | 40 ++++++++++++------------ src/gui/shortcutcatcher.cpp | 2 +- src/gui/tabwidget.cpp | 11 +++++++ src/gui/tabwidget.h | 2 ++ src/gui/themefactory.cpp | 49 ++++++++++++++++++----------- src/gui/themefactory.h | 61 +++++++++++++++++++++++-------------- src/gui/webbrowser.cpp | 8 ++--- src/main.cpp | 9 ++---- 14 files changed, 127 insertions(+), 94 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1420b42ba..d7a5e9df3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -202,6 +202,7 @@ set(APP_HEADERS # GUI headers. src/gui/formmain.h src/gui/systemtrayicon.h + src/gui/themefactory.h src/gui/formsettings.h src/gui/formwelcome.h src/gui/formabout.h @@ -217,6 +218,7 @@ set(APP_HEADERS src/gui/tabcontent.h # CORE headers. + src/core/settings.h src/core/basenetworkaccessmanager.h src/core/webBrowsernetworkaccessmanager.h src/core/basewebpage.h diff --git a/src/core/defs.h.in b/src/core/defs.h.in index 7ae0b64f6..216278252 100644 --- a/src/core/defs.h.in +++ b/src/core/defs.h.in @@ -45,6 +45,7 @@ #define APP_SKIN_PATH QApplication::applicationDirPath() + QString("/skins") #define APP_INFO_PATH QApplication::applicationDirPath() #define APP_THEME_PATH QApplication::applicationDirPath() + QString("/themes") +#define APP_THEME_SYSTEM "-" #define APP_FLAGS_PATH QApplication::applicationDirPath() + QString("/flags") #define APP_ICON_PATH QApplication::applicationDirPath() + QString("/@APP_LOW_NAME@.png") #define APP_ICON_PLAIN_PATH QApplication::applicationDirPath() + QString("/@APP_LOW_NAME@_plain.png") diff --git a/src/core/settings.h b/src/core/settings.h index 0da70b661..575d49117 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -5,6 +5,8 @@ class Settings : public QSettings { + Q_OBJECT + private: static QPointer s_instance; diff --git a/src/gui/basewebview.cpp b/src/gui/basewebview.cpp index b6556eb75..ddd88e05f 100644 --- a/src/gui/basewebview.cpp +++ b/src/gui/basewebview.cpp @@ -38,10 +38,10 @@ void BaseWebView::createConnections() { } void BaseWebView::setupIcons() { - m_actionReload->setIcon(ThemeFactory::fromTheme("view-refresh")); - m_actionCopyLink->setIcon(ThemeFactory::fromTheme("edit-copy")); - m_actionCopyImage->setIcon(ThemeFactory::fromTheme("insert-image")); - m_actionCopyImageUrl->setIcon(ThemeFactory::fromTheme("edit-copy")); + m_actionReload->setIcon(ThemeFactory::getInstance()->fromTheme("view-refresh")); + m_actionCopyLink->setIcon(ThemeFactory::getInstance()->fromTheme("edit-copy")); + m_actionCopyImage->setIcon(ThemeFactory::getInstance()->fromTheme("insert-image")); + m_actionCopyImageUrl->setIcon(ThemeFactory::getInstance()->fromTheme("edit-copy")); } void BaseWebView::initializeActions() { @@ -79,7 +79,7 @@ void BaseWebView::popupContextMenu(const QPoint &pos) { QMenu image_submenu(tr("Image"), &context_menu); 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. context_menu.addAction(m_actionReload); diff --git a/src/gui/formabout.cpp b/src/gui/formabout.cpp index 6d78c1921..041794151 100644 --- a/src/gui/formabout.cpp +++ b/src/gui/formabout.cpp @@ -11,7 +11,7 @@ FormAbout::FormAbout(QWidget *parent) : QDialog(parent), m_ui(new Ui::FormAbout) // Set flags and attributes. 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)); // Load information from embedded text files. diff --git a/src/gui/formmain.cpp b/src/gui/formmain.cpp index 09f938332..a62185848 100644 --- a/src/gui/formmain.cpp +++ b/src/gui/formmain.cpp @@ -23,7 +23,8 @@ FormMain::FormMain(QWidget *parent) : QMainWindow(parent), m_ui(new Ui::FormMain // Prepare main window. prepareMenus(); - prepareTabs(); + + m_ui->m_tabWidget->initializeTabs(); // Establish connections. createConnections(); @@ -57,13 +58,6 @@ QList FormMain::getActions() { } 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(browser), - QIcon(), - tr("Feeds"), - TabBar::FeedReader); - m_ui->m_tabWidget->setTabToolTip(index_of_browser, tr("Browser your feeds and messages")); } void FormMain::addEmptyBrowser() { @@ -184,12 +178,12 @@ bool FormMain::event(QEvent *event) { void FormMain::setupIcons() { // Setup icons of this main window. - m_ui->m_actionSettings->setIcon(ThemeFactory::fromTheme("preferences-system")); - m_ui->m_actionQuit->setIcon(ThemeFactory::fromTheme("application-exit")); - m_ui->m_actionAboutGuard->setIcon(ThemeFactory::fromTheme("help-about")); - m_ui->m_actionImport->setIcon(ThemeFactory::fromTheme("document-import")); - m_ui->m_actionExport->setIcon(ThemeFactory::fromTheme("document-export")); - m_ui->m_actionFullscreen->setIcon(ThemeFactory::fromTheme("view-fullscreen")); + m_ui->m_actionSettings->setIcon(ThemeFactory::getInstance()->fromTheme("preferences-system")); + m_ui->m_actionQuit->setIcon(ThemeFactory::getInstance()->fromTheme("application-exit")); + m_ui->m_actionAboutGuard->setIcon(ThemeFactory::getInstance()->fromTheme("help-about")); + m_ui->m_actionImport->setIcon(ThemeFactory::getInstance()->fromTheme("document-import")); + m_ui->m_actionExport->setIcon(ThemeFactory::getInstance()->fromTheme("document-export")); + m_ui->m_actionFullscreen->setIcon(ThemeFactory::getInstance()->fromTheme("view-fullscreen")); // Setup icons for underlying components: opened web browsers... foreach (WebBrowser *browser, WebBrowser::runningWebBrowsers()) { diff --git a/src/gui/formsettings.cpp b/src/gui/formsettings.cpp index c07d8d570..fff2165e5 100644 --- a/src/gui/formsettings.cpp +++ b/src/gui/formsettings.cpp @@ -21,7 +21,7 @@ FormSettings::FormSettings(QWidget *parent) : QDialog(parent), m_ui(new Ui::Form // Set flags and attributes. setWindowFlags(Qt::MSWindowsFixedSizeDialogHint | Qt::Dialog); - setWindowIcon(ThemeFactory::fromTheme("preferences-system")); + setWindowIcon(ThemeFactory::getInstance()->fromTheme("preferences-system")); // Setup behavior. m_ui->m_treeLanguages->setColumnCount(5); @@ -290,31 +290,31 @@ void FormSettings::loadInterface() { } // Load settings of icon theme. - QString current_theme = ThemeFactory::getCurrentIconTheme(); + QString current_theme = ThemeFactory::getInstance()->getCurrentIconTheme(); - foreach (QString icon_theme_name, ThemeFactory::getInstalledIconThemes()) { -#if defined(Q_OS_LINUX) + foreach (QString icon_theme_name, ThemeFactory::getInstance()->getInstalledIconThemes()) { if (icon_theme_name == APP_THEME_SYSTEM) { +#if defined(Q_OS_LINUX) 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 { -#endif m_ui->m_cmbIconTheme->addItem(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. - m_ui->m_cmbIconTheme->setCurrentIndex(0); - } - else { -#endif - m_ui->m_cmbIconTheme->setCurrentText(current_theme); -#if defined(Q_OS_LINUX) - } -#endif + } + + // Mark active theme. + if (current_theme == APP_THEME_SYSTEM) { + // Because system icon theme lies at the index 1. + m_ui->m_cmbIconTheme->setCurrentIndex(0); + } + else { + m_ui->m_cmbIconTheme->setCurrentText(current_theme); } // Load tab settings. @@ -349,9 +349,7 @@ void FormSettings::saveInterface() { // Save selected icon theme. QString selected_icon_theme = m_ui->m_cmbIconTheme->itemData(m_ui->m_cmbIconTheme->currentIndex()).toString(); - if (!selected_icon_theme.isEmpty()) { - ThemeFactory::setCurrentIconTheme(selected_icon_theme); - } + ThemeFactory::getInstance()->setCurrentIconTheme(selected_icon_theme); // Save tab settings. Settings::getInstance()->setValue(APP_CFG_GUI, "tab_close_mid_button", diff --git a/src/gui/shortcutcatcher.cpp b/src/gui/shortcutcatcher.cpp index 3cef2fe25..09ca92689 100644 --- a/src/gui/shortcutcatcher.cpp +++ b/src/gui/shortcutcatcher.cpp @@ -43,7 +43,7 @@ ShortcutCatcher::ShortcutCatcher(QWidget *parent) // Create clear button. 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); // Clear main shortcut catching button. diff --git a/src/gui/tabwidget.cpp b/src/gui/tabwidget.cpp index 3437b3755..64aa98de6 100644 --- a/src/gui/tabwidget.cpp +++ b/src/gui/tabwidget.cpp @@ -1,5 +1,6 @@ #include "gui/tabwidget.h" #include "gui/tabbar.h" +#include "gui/webbrowser.h" TabWidget::TabWidget(QWidget *parent) : QTabWidget(parent) { @@ -19,6 +20,16 @@ TabBar *TabWidget::tabBar() { return static_cast(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(browser), + QIcon(), + tr("Feeds"), + TabBar::FeedReader); + setTabToolTip(index_of_browser, tr("Browse your feeds and messages")); +} + void TabWidget::closeTab(int index) { removeTab(index); } diff --git a/src/gui/tabwidget.h b/src/gui/tabwidget.h index 130ae3fc2..a3b92dfd1 100644 --- a/src/gui/tabwidget.h +++ b/src/gui/tabwidget.h @@ -29,6 +29,8 @@ class TabWidget : public QTabWidget { // Returns tab bar. TabBar *tabBar(); + void initializeTabs(); + protected: // Creates necesary connections. void createConnections(); diff --git a/src/gui/themefactory.cpp b/src/gui/themefactory.cpp index ab7a07613..ce1224e8a 100644 --- a/src/gui/themefactory.cpp +++ b/src/gui/themefactory.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "gui/themefactory.h" @@ -9,6 +10,7 @@ #include "core/defs.h" +QPointer ThemeFactory::s_instance; QEvent::Type ThemeFactoryEvent::m_typeOfEvent = QEvent::None; // @@ -34,20 +36,31 @@ QEvent::Type ThemeFactoryEvent::type() { // 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() { + // Add custom icon theme path to existing ones. QIcon::setThemeSearchPaths(QIcon::themeSearchPaths() << APP_THEME_PATH); qDebug("Available icon theme paths: %s.", qPrintable(QIcon::themeSearchPaths().join(", "))); } QString ThemeFactory::getCurrentIconTheme() { - QString current_theme_name = Settings::getInstance()->value(APP_CFG_GUI, - "icon_theme", - "mini-kfaenza").toString(); - return current_theme_name; + return m_currentIconTheme; } 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) { - QString theme_name = getCurrentIconTheme(); 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.", qPrintable(installed_themes.join(", "))); - if (!installed_themes.contains(theme_name)) { - qDebug("Icon theme '%s' cannot be loaded because it is not installed.", - qPrintable(theme_name)); + // User wants to load icon theme, but it's not installed. + if (!installed_themes.contains(theme_name_from_settings)) { + 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 { - qDebug("Loading theme '%s'.", qPrintable(theme_name)); - QIcon::setThemeName(theme_name); + qDebug("Loading theme '%s'.", qPrintable(theme_name_from_settings)); + QIcon::setThemeName(theme_name_from_settings); + m_currentIconTheme = theme_name_from_settings; } // We need to deliver custom event for all widgets // 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) { foreach (QWidget *widget, QtSingleApplication::allWidgets()) { QtSingleApplication::postEvent((QObject*) widget, @@ -92,11 +109,7 @@ void ThemeFactory::loadCurrentIconTheme(bool notify_widgets) { QStringList ThemeFactory::getInstalledIconThemes() { 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; -#endif // Iterate all directories with icon themes. QStringList icon_themes_paths = QIcon::themeSearchPaths(); diff --git a/src/gui/themefactory.h b/src/gui/themefactory.h index 1534eab04..3e3dcf2ac 100644 --- a/src/gui/themefactory.h +++ b/src/gui/themefactory.h @@ -6,35 +6,49 @@ #include -class ThemeFactory { - private: - ThemeFactory(); +class ThemeFactory : public QObject { + Q_OBJECT public: - // Adds custom application path to be search for icons. - static void setupSearchPaths(); - - // 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); + // Singleton getter. + static ThemeFactory *getInstance(); // Wrapper for QIcon::fromTheme. // TODO: If icon is not found in user-defined icon theme, // then it is searched in system-default theme (ThemeFactory::getSystemIconTheme()). // 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 s_instance; }; class ThemeFactoryEvent : public QEvent { @@ -43,7 +57,8 @@ class ThemeFactoryEvent : public QEvent { IconThemeChange = 2000 }; - ThemeFactoryEvent(); + // Constructors. + explicit ThemeFactoryEvent(); virtual ~ThemeFactoryEvent(); static QEvent::Type type(); diff --git a/src/gui/webbrowser.cpp b/src/gui/webbrowser.cpp index ea1078658..1f74bdc82 100644 --- a/src/gui/webbrowser.cpp +++ b/src/gui/webbrowser.cpp @@ -119,10 +119,10 @@ QMenu *WebBrowser::globalMenu() { } void WebBrowser::setupIcons() { - m_actionBack->setIcon(ThemeFactory::fromTheme("go-previous")); - m_actionForward->setIcon(ThemeFactory::fromTheme("go-next")); - m_actionReload->setIcon(ThemeFactory::fromTheme("view-refresh")); - m_actionStop->setIcon(ThemeFactory::fromTheme("process-stop")); + m_actionBack->setIcon(ThemeFactory::getInstance()->fromTheme("go-previous")); + m_actionForward->setIcon(ThemeFactory::getInstance()->fromTheme("go-next")); + m_actionReload->setIcon(ThemeFactory::getInstance()->fromTheme("view-refresh")); + m_actionStop->setIcon(ThemeFactory::getInstance()->fromTheme("process-stop")); m_webView->setupIcons(); } diff --git a/src/main.cpp b/src/main.cpp index ca6701868..b9c03b722 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -63,8 +63,8 @@ int main(int argc, char *argv[]) { #endif // Add an extra path for non-system icon themes and set current icon theme. - ThemeFactory::setupSearchPaths(); - ThemeFactory::loadCurrentIconTheme(false); + ThemeFactory::getInstance()->setupSearchPaths(); + ThemeFactory::getInstance()->loadCurrentIconTheme(false); // Load localization and setup locale before any widget is constructed. LoadLocalization(); @@ -108,11 +108,6 @@ int main(int argc, char *argv[]) { 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. QObject::connect(&application, &QtSingleApplication::messageReceived, &window, &FormMain::processExecutionMessage);