Work on skins.
This commit is contained in:
parent
a80270560d
commit
99c011de41
7 changed files with 224 additions and 13 deletions
|
@ -137,10 +137,11 @@ if(${USE_QT_5})
|
||||||
find_package(Qt5WebKitWidgets)
|
find_package(Qt5WebKitWidgets)
|
||||||
find_package(Qt5Widgets)
|
find_package(Qt5Widgets)
|
||||||
find_package(Qt5Xml)
|
find_package(Qt5Xml)
|
||||||
|
find_package(Qt5XmlPatterns)
|
||||||
find_package(Qt5Network)
|
find_package(Qt5Network)
|
||||||
find_package(Qt5LinguistTools)
|
find_package(Qt5LinguistTools)
|
||||||
else(${USE_QT_5})
|
else(${USE_QT_5})
|
||||||
find_package(Qt4 REQUIRED QtCore QtGui QtSql QtNetwork QtWebkit QtXml)
|
find_package(Qt4 REQUIRED QtCore QtGui QtSql QtNetwork QtWebkit QtXml QtXmlPatterns)
|
||||||
include(${QT_USE_FILE})
|
include(${QT_USE_FILE})
|
||||||
endif(${USE_QT_5})
|
endif(${USE_QT_5})
|
||||||
|
|
||||||
|
@ -157,9 +158,9 @@ if(MINGW AND WIN32)
|
||||||
)
|
)
|
||||||
set(APP_SOURCES ${APP_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/resources/executable_properties/rssguard_win.o)
|
set(APP_SOURCES ${APP_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/resources/executable_properties/rssguard_win.o)
|
||||||
|
|
||||||
# MSVC takes care of this automatically no need to use windres.exe
|
# MSVC takes care of this automatically - no need to use windres.exe
|
||||||
# for MSVC compilers.
|
# for MSVC compilers.
|
||||||
elseif(WIN32)
|
elseif(MINGW AND WIN32)
|
||||||
set(APP_SOURCES ${APP_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/resources/executable_properties/rssguard_win.rc)
|
set(APP_SOURCES ${APP_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/resources/executable_properties/rssguard_win.rc)
|
||||||
endif(MINGW AND WIN32)
|
endif(MINGW AND WIN32)
|
||||||
|
|
||||||
|
@ -175,6 +176,7 @@ set(APP_SOURCES
|
||||||
src/gui/formmain.cpp
|
src/gui/formmain.cpp
|
||||||
src/gui/systemtrayicon.cpp
|
src/gui/systemtrayicon.cpp
|
||||||
src/gui/iconthemefactory.cpp
|
src/gui/iconthemefactory.cpp
|
||||||
|
src/gui/skinfactory.cpp
|
||||||
src/gui/formsettings.cpp
|
src/gui/formsettings.cpp
|
||||||
src/gui/formwelcome.cpp
|
src/gui/formwelcome.cpp
|
||||||
src/gui/formabout.cpp
|
src/gui/formabout.cpp
|
||||||
|
@ -218,6 +220,7 @@ set(APP_HEADERS
|
||||||
src/gui/formmain.h
|
src/gui/formmain.h
|
||||||
src/gui/systemtrayicon.h
|
src/gui/systemtrayicon.h
|
||||||
src/gui/iconthemefactory.h
|
src/gui/iconthemefactory.h
|
||||||
|
src/gui/skinfactory.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
|
||||||
|
@ -334,6 +337,7 @@ if(${USE_QT_5})
|
||||||
Sql
|
Sql
|
||||||
Network
|
Network
|
||||||
Xml
|
Xml
|
||||||
|
XmlPatterns
|
||||||
WebKit
|
WebKit
|
||||||
WebKitWidgets
|
WebKitWidgets
|
||||||
)
|
)
|
||||||
|
@ -354,6 +358,7 @@ else(${USE_QT_5})
|
||||||
${QT_QTNETWORK_LIBRARY}
|
${QT_QTNETWORK_LIBRARY}
|
||||||
${QT_QTSQL_LIBRARY}
|
${QT_QTSQL_LIBRARY}
|
||||||
${QT_QTXML_LIBRARY}
|
${QT_QTXML_LIBRARY}
|
||||||
|
${QT_QTXMLPATTERNS_LIBRARY}
|
||||||
${QT_QTMAIN_LIBRARY}
|
${QT_QTMAIN_LIBRARY}
|
||||||
${QT_QTWEBKIT_LIBRARY}
|
${QT_QTWEBKIT_LIBRARY}
|
||||||
)
|
)
|
||||||
|
|
|
@ -122,7 +122,7 @@ void FormMain::cleanupResources() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FormMain::event(QEvent *event) {
|
bool FormMain::event(QEvent *event) {
|
||||||
if (event->type() == ThemeFactoryEvent::type()) {
|
if (event->type() == IconThemeFactoryEvent::type()) {
|
||||||
// Handle the change of icon theme.
|
// Handle the change of icon theme.
|
||||||
setupIcons();
|
setupIcons();
|
||||||
event->accept();
|
event->accept();
|
||||||
|
|
|
@ -11,20 +11,20 @@
|
||||||
|
|
||||||
|
|
||||||
QPointer<IconThemeFactory> IconThemeFactory::s_instance;
|
QPointer<IconThemeFactory> IconThemeFactory::s_instance;
|
||||||
QEvent::Type ThemeFactoryEvent::m_typeOfEvent = QEvent::None;
|
QEvent::Type IconThemeFactoryEvent::m_typeOfEvent = QEvent::None;
|
||||||
|
|
||||||
//
|
//
|
||||||
// ThemeFactoryEvent class
|
// ThemeFactoryEvent class
|
||||||
//
|
//
|
||||||
|
|
||||||
ThemeFactoryEvent::ThemeFactoryEvent() : QEvent(ThemeFactoryEvent::type()) {
|
IconThemeFactoryEvent::IconThemeFactoryEvent() : QEvent(IconThemeFactoryEvent::type()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeFactoryEvent::~ThemeFactoryEvent() {
|
IconThemeFactoryEvent::~IconThemeFactoryEvent() {
|
||||||
qDebug("Destroying IconThemeFactoryEvent.");
|
qDebug("Destroying IconThemeFactoryEvent.");
|
||||||
}
|
}
|
||||||
|
|
||||||
QEvent::Type ThemeFactoryEvent::type() {
|
QEvent::Type IconThemeFactoryEvent::type() {
|
||||||
if (m_typeOfEvent == QEvent::None) {
|
if (m_typeOfEvent == QEvent::None) {
|
||||||
m_typeOfEvent = static_cast<QEvent::Type>(QEvent::registerEventType(2000));
|
m_typeOfEvent = static_cast<QEvent::Type>(QEvent::registerEventType(2000));
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ void IconThemeFactory::loadCurrentIconTheme(bool notify_widgets) {
|
||||||
if (notify_widgets) {
|
if (notify_widgets) {
|
||||||
foreach (QWidget *widget, QtSingleApplication::allWidgets()) {
|
foreach (QWidget *widget, QtSingleApplication::allWidgets()) {
|
||||||
QtSingleApplication::postEvent((QObject*) widget,
|
QtSingleApplication::postEvent((QObject*) widget,
|
||||||
new ThemeFactoryEvent());
|
new IconThemeFactoryEvent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,15 +54,15 @@ class IconThemeFactory : public QObject {
|
||||||
static QPointer<IconThemeFactory> s_instance;
|
static QPointer<IconThemeFactory> s_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ThemeFactoryEvent : public QEvent {
|
class IconThemeFactoryEvent : public QEvent {
|
||||||
public:
|
public:
|
||||||
enum Type {
|
enum Type {
|
||||||
IconThemeChange = 2000
|
IconThemeChange = 2000
|
||||||
};
|
};
|
||||||
|
|
||||||
// Constructors.
|
// Constructors.
|
||||||
explicit ThemeFactoryEvent();
|
explicit IconThemeFactoryEvent();
|
||||||
virtual ~ThemeFactoryEvent();
|
virtual ~IconThemeFactoryEvent();
|
||||||
|
|
||||||
static QEvent::Type type();
|
static QEvent::Type type();
|
||||||
|
|
||||||
|
|
149
src/gui/skinfactory.cpp
Normal file
149
src/gui/skinfactory.cpp
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDomDocument>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QXmlQuery>
|
||||||
|
#include <QStyleFactory>
|
||||||
|
|
||||||
|
#include "core/defs.h"
|
||||||
|
#include "core/settings.h"
|
||||||
|
#include "gui/skinfactory.h"
|
||||||
|
|
||||||
|
|
||||||
|
QPointer<SkinFactory> SkinFactory::s_instance;
|
||||||
|
|
||||||
|
SkinFactory::SkinFactory(QObject *parent)
|
||||||
|
: QObject(parent), m_currentSkin(APP_THEME_SYSTEM) {
|
||||||
|
}
|
||||||
|
|
||||||
|
SkinFactory::~SkinFactory() {
|
||||||
|
qDebug("Destroying SkinFactory instance.");
|
||||||
|
}
|
||||||
|
|
||||||
|
SkinFactory *SkinFactory::getInstance() {
|
||||||
|
if (s_instance.isNull()) {
|
||||||
|
s_instance = new SkinFactory(qApp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkinFactory::loadCurrentSkin() {
|
||||||
|
QString skin_name_from_settings = Settings::getInstance()->value(APP_CFG_GUI,
|
||||||
|
"skin",
|
||||||
|
"base/plain.xml").toString();
|
||||||
|
bool loaded = false;
|
||||||
|
Skin skin_data = getSkinInfo(skin_name_from_settings, &loaded);
|
||||||
|
|
||||||
|
if (loaded) {
|
||||||
|
loadSkinFromData(skin_data.m_rawData, skin_name_from_settings);
|
||||||
|
|
||||||
|
foreach (QString style, skin_data.m_stylesName.split("\n")) {
|
||||||
|
if (qApp->setStyle(style) != 0) {
|
||||||
|
qDebug("Style '%s' loaded.", qPrintable(style));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentSkin = skin_name_from_settings;
|
||||||
|
|
||||||
|
qDebug("Skin '%s' loaded.", qPrintable(skin_name_from_settings));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qDebug("Skin '%s' not loaded because style name is not specified or skin raw data is missing.",
|
||||||
|
qPrintable(skin_name_from_settings));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SkinFactory::loadSkinFromData(QString skin_data, const QString &skin_path) {
|
||||||
|
QStringList skin_parts = skin_path.split('/', QString::SkipEmptyParts);
|
||||||
|
|
||||||
|
// Skin does not contain leading folder name or the actual skin file name.
|
||||||
|
if (skin_parts.size() != 2) {
|
||||||
|
qDebug("Loading of sking %s failed because skin name does not contain "
|
||||||
|
"base folder name or the actual skin name.",
|
||||||
|
qPrintable(skin_path));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qDebug("Loading skin '%s'.", qPrintable(skin_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create needed variables and create QFile object representing skin contents.
|
||||||
|
QString skin_folder = skin_parts.at(0);
|
||||||
|
|
||||||
|
// Here we use "/" instead of QDir::separator() because CSS2.1 url field
|
||||||
|
// accepts '/' as path elements separator.
|
||||||
|
//
|
||||||
|
// "##" is placeholder for the actual path to skin file. This is needed for using
|
||||||
|
// images within the QSS file.
|
||||||
|
QString parsed_data = skin_data.replace("##",
|
||||||
|
APP_SKIN_PATH + "/" + skin_folder + "/images");
|
||||||
|
qApp->setStyleSheet(parsed_data);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SkinFactory::setCurrentSkinName(const QString &skin_name) {
|
||||||
|
Settings::getInstance()->setValue(APP_CFG_GUI, "skin", skin_name);
|
||||||
|
loadCurrentSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SkinFactory::getCurrentSkinName() {
|
||||||
|
return m_currentSkin;
|
||||||
|
}
|
||||||
|
|
||||||
|
Skin SkinFactory::getSkinInfo(const QString &skin_name, bool *ok) {
|
||||||
|
Skin skin;
|
||||||
|
QXmlQuery query;
|
||||||
|
QFile skin_file(APP_SKIN_PATH + QDir::separator() + skin_name);
|
||||||
|
|
||||||
|
if (!skin_file.open(QIODevice::ReadOnly) ||!query.setFocus(&skin_file)) {
|
||||||
|
if (ok) {
|
||||||
|
*ok = false;
|
||||||
|
}
|
||||||
|
return skin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtain skin raw data.
|
||||||
|
query.setQuery("string(skin/data)");
|
||||||
|
query.evaluateTo(&skin.m_rawData);
|
||||||
|
|
||||||
|
// Obtain style name.
|
||||||
|
query.setQuery("string(/skin/style)");
|
||||||
|
query.evaluateTo(&skin.m_stylesName);
|
||||||
|
skin.m_stylesName = skin.m_stylesName.remove("\n");
|
||||||
|
|
||||||
|
// Obtain author.
|
||||||
|
query.setQuery("string(/skin/author/name)");
|
||||||
|
query.evaluateTo(&skin.m_author);
|
||||||
|
skin.m_author = skin.m_author.remove("\n");
|
||||||
|
|
||||||
|
// Obtain email.
|
||||||
|
query.setQuery("string(/skin/author/email)");
|
||||||
|
query.evaluateTo(&skin.m_email);
|
||||||
|
skin.m_email = skin.m_email.remove("\n");
|
||||||
|
|
||||||
|
// Obtain version.
|
||||||
|
query.setQuery("string(/skin/@version)");
|
||||||
|
query.evaluateTo(&skin.m_version);
|
||||||
|
skin.m_version = skin.m_version.remove("\n");
|
||||||
|
|
||||||
|
// Obtain other information.
|
||||||
|
skin.m_baseName = skin_name;
|
||||||
|
|
||||||
|
// Free resources.
|
||||||
|
skin_file.close();
|
||||||
|
skin_file.deleteLater();
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
*ok = !skin.m_author.isEmpty() && !skin.m_version.isEmpty() &&
|
||||||
|
!skin.m_baseName.isEmpty() && !skin.m_email.isEmpty() &&
|
||||||
|
!skin.m_rawData.isEmpty() && !skin.m_stylesName.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
return skin;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Skin> SkinFactory::getInstalledSkins() {
|
||||||
|
QList<Skin> skins;
|
||||||
|
return skins;
|
||||||
|
}
|
54
src/gui/skinfactory.h
Normal file
54
src/gui/skinfactory.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef SKINFACTORY_H
|
||||||
|
#define SKINFACTORY_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPointer>
|
||||||
|
|
||||||
|
|
||||||
|
struct Skin {
|
||||||
|
QString m_baseName;
|
||||||
|
QString m_stylesName;
|
||||||
|
QString m_author;
|
||||||
|
QString m_email;
|
||||||
|
QString m_version;
|
||||||
|
QString m_rawData;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SkinFactory : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit SkinFactory(QObject *parent = 0);
|
||||||
|
|
||||||
|
bool loadSkinFromData(QString skin_data, const QString &skin_path);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Singleton getter.
|
||||||
|
static SkinFactory *getInstance();
|
||||||
|
|
||||||
|
// Destructor.
|
||||||
|
virtual ~SkinFactory();
|
||||||
|
|
||||||
|
// Loads skin name from settings and sets it as active.
|
||||||
|
void loadCurrentSkin();
|
||||||
|
|
||||||
|
// Return the name of the currently activated skin.
|
||||||
|
// NOTE: Skin name is formatted as "<folder>/<skin>.xml".
|
||||||
|
QString getCurrentSkinName();
|
||||||
|
|
||||||
|
Skin getSkinInfo(const QString &skin_name, bool *ok = NULL);
|
||||||
|
|
||||||
|
QList<Skin> getInstalledSkins();
|
||||||
|
|
||||||
|
// Sets the desired skin as the active one if it exists.
|
||||||
|
void setCurrentSkinName(const QString &skin_name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Holds name of the current skin.
|
||||||
|
QString m_currentSkin;
|
||||||
|
|
||||||
|
// Singleton.
|
||||||
|
static QPointer<SkinFactory> s_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SKINFACTORY_H
|
|
@ -11,6 +11,7 @@
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
#include "core/dynamicshortcuts.h"
|
#include "core/dynamicshortcuts.h"
|
||||||
#include "gui/iconthemefactory.h"
|
#include "gui/iconthemefactory.h"
|
||||||
|
#include "gui/skinfactory.h"
|
||||||
#include "gui/formmain.h"
|
#include "gui/formmain.h"
|
||||||
#include "gui/formwelcome.h"
|
#include "gui/formwelcome.h"
|
||||||
#include "gui/systemtrayicon.h"
|
#include "gui/systemtrayicon.h"
|
||||||
|
@ -66,9 +67,11 @@ int main(int argc, char *argv[]) {
|
||||||
QtSingleApplication::addLibraryPath(APP_PLUGIN_PATH);
|
QtSingleApplication::addLibraryPath(APP_PLUGIN_PATH);
|
||||||
#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
|
||||||
|
// and skin.
|
||||||
IconThemeFactory::getInstance()->setupSearchPaths();
|
IconThemeFactory::getInstance()->setupSearchPaths();
|
||||||
IconThemeFactory::getInstance()->loadCurrentIconTheme(false);
|
IconThemeFactory::getInstance()->loadCurrentIconTheme(false);
|
||||||
|
SkinFactory::getInstance()->loadCurrentSkin();
|
||||||
|
|
||||||
// Load localization and setup locale before any widget is constructed.
|
// Load localization and setup locale before any widget is constructed.
|
||||||
LoadLocalization();
|
LoadLocalization();
|
||||||
|
|
Loading…
Add table
Reference in a new issue