mirror of
https://github.com/martinrotter/rssguard.git
synced 2025-01-31 01:24:49 +01:00
Work on skins.
This commit is contained in:
parent
a80270560d
commit
99c011de41
@ -137,10 +137,11 @@ if(${USE_QT_5})
|
||||
find_package(Qt5WebKitWidgets)
|
||||
find_package(Qt5Widgets)
|
||||
find_package(Qt5Xml)
|
||||
find_package(Qt5XmlPatterns)
|
||||
find_package(Qt5Network)
|
||||
find_package(Qt5LinguistTools)
|
||||
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})
|
||||
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)
|
||||
|
||||
# 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.
|
||||
elseif(WIN32)
|
||||
elseif(MINGW AND WIN32)
|
||||
set(APP_SOURCES ${APP_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/resources/executable_properties/rssguard_win.rc)
|
||||
endif(MINGW AND WIN32)
|
||||
|
||||
@ -175,6 +176,7 @@ set(APP_SOURCES
|
||||
src/gui/formmain.cpp
|
||||
src/gui/systemtrayicon.cpp
|
||||
src/gui/iconthemefactory.cpp
|
||||
src/gui/skinfactory.cpp
|
||||
src/gui/formsettings.cpp
|
||||
src/gui/formwelcome.cpp
|
||||
src/gui/formabout.cpp
|
||||
@ -218,6 +220,7 @@ set(APP_HEADERS
|
||||
src/gui/formmain.h
|
||||
src/gui/systemtrayicon.h
|
||||
src/gui/iconthemefactory.h
|
||||
src/gui/skinfactory.h
|
||||
src/gui/formsettings.h
|
||||
src/gui/formwelcome.h
|
||||
src/gui/formabout.h
|
||||
@ -334,6 +337,7 @@ if(${USE_QT_5})
|
||||
Sql
|
||||
Network
|
||||
Xml
|
||||
XmlPatterns
|
||||
WebKit
|
||||
WebKitWidgets
|
||||
)
|
||||
@ -354,6 +358,7 @@ else(${USE_QT_5})
|
||||
${QT_QTNETWORK_LIBRARY}
|
||||
${QT_QTSQL_LIBRARY}
|
||||
${QT_QTXML_LIBRARY}
|
||||
${QT_QTXMLPATTERNS_LIBRARY}
|
||||
${QT_QTMAIN_LIBRARY}
|
||||
${QT_QTWEBKIT_LIBRARY}
|
||||
)
|
||||
|
@ -122,7 +122,7 @@ void FormMain::cleanupResources() {
|
||||
}
|
||||
|
||||
bool FormMain::event(QEvent *event) {
|
||||
if (event->type() == ThemeFactoryEvent::type()) {
|
||||
if (event->type() == IconThemeFactoryEvent::type()) {
|
||||
// Handle the change of icon theme.
|
||||
setupIcons();
|
||||
event->accept();
|
||||
|
@ -11,20 +11,20 @@
|
||||
|
||||
|
||||
QPointer<IconThemeFactory> IconThemeFactory::s_instance;
|
||||
QEvent::Type ThemeFactoryEvent::m_typeOfEvent = QEvent::None;
|
||||
QEvent::Type IconThemeFactoryEvent::m_typeOfEvent = QEvent::None;
|
||||
|
||||
//
|
||||
// ThemeFactoryEvent class
|
||||
//
|
||||
|
||||
ThemeFactoryEvent::ThemeFactoryEvent() : QEvent(ThemeFactoryEvent::type()) {
|
||||
IconThemeFactoryEvent::IconThemeFactoryEvent() : QEvent(IconThemeFactoryEvent::type()) {
|
||||
}
|
||||
|
||||
ThemeFactoryEvent::~ThemeFactoryEvent() {
|
||||
IconThemeFactoryEvent::~IconThemeFactoryEvent() {
|
||||
qDebug("Destroying IconThemeFactoryEvent.");
|
||||
}
|
||||
|
||||
QEvent::Type ThemeFactoryEvent::type() {
|
||||
QEvent::Type IconThemeFactoryEvent::type() {
|
||||
if (m_typeOfEvent == QEvent::None) {
|
||||
m_typeOfEvent = static_cast<QEvent::Type>(QEvent::registerEventType(2000));
|
||||
}
|
||||
@ -109,7 +109,7 @@ void IconThemeFactory::loadCurrentIconTheme(bool notify_widgets) {
|
||||
if (notify_widgets) {
|
||||
foreach (QWidget *widget, QtSingleApplication::allWidgets()) {
|
||||
QtSingleApplication::postEvent((QObject*) widget,
|
||||
new ThemeFactoryEvent());
|
||||
new IconThemeFactoryEvent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,15 +54,15 @@ class IconThemeFactory : public QObject {
|
||||
static QPointer<IconThemeFactory> s_instance;
|
||||
};
|
||||
|
||||
class ThemeFactoryEvent : public QEvent {
|
||||
class IconThemeFactoryEvent : public QEvent {
|
||||
public:
|
||||
enum Type {
|
||||
IconThemeChange = 2000
|
||||
};
|
||||
|
||||
// Constructors.
|
||||
explicit ThemeFactoryEvent();
|
||||
virtual ~ThemeFactoryEvent();
|
||||
explicit IconThemeFactoryEvent();
|
||||
virtual ~IconThemeFactoryEvent();
|
||||
|
||||
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/dynamicshortcuts.h"
|
||||
#include "gui/iconthemefactory.h"
|
||||
#include "gui/skinfactory.h"
|
||||
#include "gui/formmain.h"
|
||||
#include "gui/formwelcome.h"
|
||||
#include "gui/systemtrayicon.h"
|
||||
@ -66,9 +67,11 @@ int main(int argc, char *argv[]) {
|
||||
QtSingleApplication::addLibraryPath(APP_PLUGIN_PATH);
|
||||
#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()->loadCurrentIconTheme(false);
|
||||
SkinFactory::getInstance()->loadCurrentSkin();
|
||||
|
||||
// Load localization and setup locale before any widget is constructed.
|
||||
LoadLocalization();
|
||||
|
Loading…
x
Reference in New Issue
Block a user