Fixed #81.
This commit is contained in:
parent
e99b66f9eb
commit
7bc8caa6c4
@ -2,6 +2,7 @@
|
||||
—————
|
||||
|
||||
Added:
|
||||
▪ User now can place custom user skins in user "data" folder. (issue #81) See "About" dialog for the exact path.
|
||||
▪ User now can select if DB transactions are enabled or not. (bug #70) By default, DB transactions are now switched OFF, therefore anyone who wants better performance, must turn them ON in app settings.
|
||||
▪ MySQL database backend now requires at least version 5.5, DB encoding is now changed to utf8mb4 character set. (bug #74)
|
||||
▪ Height if message attachment image is now configurable, defaults to 36. (issue #69)
|
||||
|
@ -105,24 +105,21 @@
|
||||
|
||||
#define APP_DB_SQLITE_DRIVER "QSQLITE"
|
||||
#define APP_DB_SQLITE_INIT "db_init_sqlite.sql"
|
||||
#define APP_DB_SQLITE_PATH "data/database/local"
|
||||
#define APP_DB_SQLITE_PATH "database/local"
|
||||
#define APP_DB_SQLITE_FILE "database.db"
|
||||
|
||||
// Keep this in sync with schema versions declared in SQL initialization code.
|
||||
#define APP_DB_SCHEMA_VERSION "7"
|
||||
#define APP_DB_UPDATE_FILE_PATTERN "db_update_%1_%2_%3.sql"
|
||||
#define APP_DB_COMMENT_SPLIT "-- !\n"
|
||||
#define APP_DB_WEB_PATH "data/database/web"
|
||||
#define APP_DB_NAME_PLACEHOLDER "##"
|
||||
|
||||
#define APP_CFG_PATH "data/config"
|
||||
#define APP_CFG_PATH "config"
|
||||
#define APP_CFG_FILE "config.ini"
|
||||
|
||||
#define APP_LOG_PATH "data/log"
|
||||
#define APP_LOG_FILE "log.txt"
|
||||
|
||||
#define APP_QUIT_INSTANCE "-q"
|
||||
#define APP_IS_RUNNING "app_is_running"
|
||||
#define APP_SKIN_USER_FOLDER "skins"
|
||||
#define APP_SKIN_DEFAULT "vergilius"
|
||||
#define APP_SKIN_METADATA_FILE "metadata.xml"
|
||||
#define APP_STYLE_DEFAULT "Fusion"
|
||||
|
@ -51,20 +51,16 @@ FormAbout::~FormAbout() {
|
||||
void FormAbout::loadSettingsAndPaths() {
|
||||
if (qApp->settings()->type() == SettingsProperties::Portable) {
|
||||
m_ui->m_txtPathsSettingsType->setText(tr("FULLY portable"));
|
||||
m_ui->m_txtPathsDatabaseRoot->setText(QDir::toNativeSeparators(qApp->applicationDirPath() +
|
||||
QDir::separator() +
|
||||
QString(APP_DB_SQLITE_PATH)));
|
||||
}
|
||||
else {
|
||||
m_ui->m_txtPathsSettingsType->setText(tr("PARTIALLY portable"));
|
||||
m_ui->m_txtPathsDatabaseRoot->setText(QDir::toNativeSeparators(qApp->homeFolderPath() +
|
||||
QDir::separator() +
|
||||
QString(APP_LOW_H_NAME) +
|
||||
QDir::separator() +
|
||||
QString(APP_DB_SQLITE_PATH)));
|
||||
}
|
||||
|
||||
m_ui->m_txtPathsDatabaseRoot->setText(QDir::toNativeSeparators(qApp->settings()->userSettingsRootFolder() +
|
||||
QDir::separator() +
|
||||
QString(APP_DB_SQLITE_PATH)));
|
||||
m_ui->m_txtPathsSettingsFile->setText(QDir::toNativeSeparators(qApp->settings()->fileName()));
|
||||
m_ui->m_txtPathsSkinsRoot->setText(QDir::toNativeSeparators(qApp->skins()->getUserSkinBaseFolder()));
|
||||
}
|
||||
|
||||
void FormAbout::loadLicenseAndInformation() {
|
||||
|
@ -92,7 +92,7 @@
|
||||
<locale language="English" country="UnitedStates"/>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="m_tabInfo">
|
||||
<attribute name="title">
|
||||
@ -125,7 +125,7 @@
|
||||
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
|
||||
</property>
|
||||
<property name="acceptRichText">
|
||||
@ -159,8 +159,8 @@ p, li { white-space: pre-wrap; }
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>98</width>
|
||||
<height>73</height>
|
||||
<width>685</width>
|
||||
<height>184</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="autoFillBackground">
|
||||
@ -217,7 +217,7 @@ p, li { white-space: pre-wrap; }
|
||||
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
@ -235,8 +235,8 @@ p, li { white-space: pre-wrap; }
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>98</width>
|
||||
<height>73</height>
|
||||
<width>83</width>
|
||||
<height>69</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
@ -287,7 +287,7 @@ p, li { white-space: pre-wrap; }
|
||||
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
@ -333,7 +333,7 @@ p, li { white-space: pre-wrap; }
|
||||
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:10pt; font-weight:400; font-style:normal;">
|
||||
</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html></string>
|
||||
</property>
|
||||
<property name="acceptRichText">
|
||||
@ -389,20 +389,34 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="m_txtPathsDatabaseRoot">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Database root path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="m_txtPathsDatabaseRoot">
|
||||
<item row="3" column="1">
|
||||
<widget class="QLineEdit" name="m_txtPathsSkinsRoot">
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>User skins root path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
@ -416,6 +430,17 @@ p, li { white-space: pre-wrap; }
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>m_tabAbout</tabstop>
|
||||
<tabstop>m_txtPathsSettingsType</tabstop>
|
||||
<tabstop>m_txtPathsSettingsFile</tabstop>
|
||||
<tabstop>m_txtPathsDatabaseRoot</tabstop>
|
||||
<tabstop>m_txtPathsSkinsRoot</tabstop>
|
||||
<tabstop>m_txtInfo</tabstop>
|
||||
<tabstop>m_txtLicenseGnu</tabstop>
|
||||
<tabstop>m_txtChangelog</tabstop>
|
||||
<tabstop>m_txtLicenseBsd</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
|
@ -187,14 +187,7 @@ void DatabaseFactory::finishRestoration() {
|
||||
}
|
||||
|
||||
void DatabaseFactory::sqliteAssemblyDatabaseFilePath() {
|
||||
if (qApp->settings()->type() == SettingsProperties::Portable) {
|
||||
m_sqliteDatabaseFilePath = qApp->applicationDirPath() + QDir::separator() + QString(APP_DB_SQLITE_PATH);
|
||||
}
|
||||
else {
|
||||
m_sqliteDatabaseFilePath = qApp->homeFolderPath() + QDir::separator() +
|
||||
QString(APP_LOW_H_NAME) + QDir::separator() +
|
||||
QString(APP_DB_SQLITE_PATH);
|
||||
}
|
||||
m_sqliteDatabaseFilePath = qApp->settings()->userSettingsRootFolder() + QDir::separator() + QString(APP_DB_SQLITE_PATH);
|
||||
}
|
||||
|
||||
QSqlDatabase DatabaseFactory::sqliteInitializeInMemoryDatabase() {
|
||||
|
@ -275,6 +275,15 @@ Settings::Settings(const QString &file_name, Format format, const SettingsProper
|
||||
Settings::~Settings() {
|
||||
}
|
||||
|
||||
QString Settings::userSettingsRootFolder() const {
|
||||
if (qApp->settings()->type() == SettingsProperties::Portable) {
|
||||
return getAppPathUserFolder();
|
||||
}
|
||||
else {
|
||||
return getHomeUserFolder();
|
||||
}
|
||||
}
|
||||
|
||||
QString Settings::pathName() const {
|
||||
return QFileInfo(fileName()).absolutePath();
|
||||
}
|
||||
@ -309,6 +318,14 @@ void Settings::finishRestoration(const QString &desired_settings_file_path) {
|
||||
}
|
||||
}
|
||||
|
||||
QString Settings::getAppPathUserFolder() {
|
||||
return qApp->applicationDirPath() + QDir::separator() + QSL("data");
|
||||
}
|
||||
|
||||
QString Settings::getHomeUserFolder() {
|
||||
return qApp->homeFolderPath() + QDir::separator() + QString(APP_LOW_H_NAME) + QDir::separator() + QSL("data");
|
||||
}
|
||||
|
||||
Settings *Settings::setupSettings(QObject *parent) {
|
||||
Settings *new_settings;
|
||||
|
||||
@ -338,11 +355,12 @@ SettingsProperties Settings::determineProperties() {
|
||||
|
||||
properties.m_settingsSuffix = QDir::separator() + QString(APP_CFG_PATH) + QDir::separator() + QString(APP_CFG_FILE);
|
||||
|
||||
const QString app_path = qApp->applicationDirPath();
|
||||
const QString home_path = qApp->homeFolderPath() + QDir::separator() + QString(APP_LOW_H_NAME);
|
||||
const QString exe_path = qApp->applicationDirPath();
|
||||
const QString app_path = getAppPathUserFolder();
|
||||
const QString home_path = getHomeUserFolder();
|
||||
const QString home_path_file = home_path + properties.m_settingsSuffix;
|
||||
|
||||
const bool portable_settings_available = IOFactory::isFolderWritable(app_path);
|
||||
const bool portable_settings_available = IOFactory::isFolderWritable(exe_path);
|
||||
const bool non_portable_settings_exist = QFile::exists(home_path_file);
|
||||
|
||||
// We will use PORTABLE settings only and only if it is available and NON-PORTABLE
|
||||
|
@ -312,6 +312,9 @@ class Settings : public QSettings {
|
||||
return m_initializationStatus;
|
||||
}
|
||||
|
||||
// Returns the base folder to which store user data, the "data" folder.
|
||||
QString userSettingsRootFolder() const;
|
||||
|
||||
// Getters/setters for settings values.
|
||||
inline QVariant value(const QString §ion, const QString &key, const QVariant &default_value = QVariant()) const {
|
||||
return QSettings::value(QString("%1/%2").arg(section, key), default_value);
|
||||
@ -342,6 +345,9 @@ class Settings : public QSettings {
|
||||
bool initiateRestoration(const QString &settings_backup_file_path);
|
||||
static void finishRestoration(const QString &desired_settings_file_path);
|
||||
|
||||
static QString getAppPathUserFolder();
|
||||
static QString getHomeUserFolder();
|
||||
|
||||
// Creates settings file in correct location.
|
||||
static Settings *setupSettings(QObject *parent);
|
||||
|
||||
|
@ -65,7 +65,6 @@ void SkinFactory::loadCurrentSkin() {
|
||||
void SkinFactory::loadSkinFromData(const Skin &skin) {
|
||||
if (!skin.m_rawData.isEmpty()) {
|
||||
qApp->setStyleSheet(skin.m_rawData);
|
||||
//qApp->setStyleSheet("QWidget {rgb(39, 43, 48);}");
|
||||
}
|
||||
|
||||
qApp->setStyle(qApp->settings()->value(GROUP(GUI), SETTING(GUI::Style)).toString());
|
||||
@ -75,74 +74,91 @@ void SkinFactory::setCurrentSkinName(const QString &skin_name) {
|
||||
qApp->settings()->setValue(GROUP(GUI), GUI::Skin, skin_name);
|
||||
}
|
||||
|
||||
QString SkinFactory::getUserSkinBaseFolder() const {
|
||||
return qApp->settings()->userSettingsRootFolder() + QDir::separator() + APP_SKIN_USER_FOLDER;
|
||||
}
|
||||
|
||||
QString SkinFactory::selectedSkinName() const {
|
||||
return qApp->settings()->value(GROUP(GUI), SETTING(GUI::Skin)).toString();
|
||||
}
|
||||
|
||||
Skin SkinFactory::skinInfo(const QString &skin_name, bool *ok) const {
|
||||
Skin skin;
|
||||
QFile skin_file(APP_SKIN_PATH + QDir::separator() + skin_name + QDir::separator() + APP_SKIN_METADATA_FILE);
|
||||
QDomDocument dokument;
|
||||
QStringList base_skin_folders;
|
||||
|
||||
if (!skin_file.open(QIODevice::Text | QIODevice::ReadOnly) || !dokument.setContent(&skin_file, true)) {
|
||||
if (ok) {
|
||||
*ok = false;
|
||||
base_skin_folders.append(APP_SKIN_PATH);
|
||||
base_skin_folders.append(getUserSkinBaseFolder());
|
||||
|
||||
while (!base_skin_folders.isEmpty()) {
|
||||
const QString skin_folder = base_skin_folders.takeAt(0) + QDir::separator() + skin_name + QDir::separator();
|
||||
const QString metadata_file = skin_folder + APP_SKIN_METADATA_FILE;
|
||||
|
||||
if (QFile::exists(metadata_file)) {
|
||||
QFile skin_file(metadata_file);
|
||||
|
||||
QDomDocument dokument;
|
||||
|
||||
if (!skin_file.open(QIODevice::Text | QIODevice::ReadOnly) || !dokument.setContent(&skin_file, true)) {
|
||||
if (ok) {
|
||||
*ok = false;
|
||||
}
|
||||
|
||||
return skin;
|
||||
}
|
||||
|
||||
const QDomNode skin_node = dokument.namedItem(QSL("skin"));
|
||||
|
||||
// Obtain visible skin name.
|
||||
skin.m_visibleName = skin_name;
|
||||
|
||||
// Obtain author.
|
||||
skin.m_author = skin_node.namedItem(QSL("author")).namedItem(QSL("name")).toElement().text();
|
||||
|
||||
// Obtain email.
|
||||
skin.m_email = skin_node.namedItem(QSL("author")).namedItem(QSL("email")).toElement().text();
|
||||
|
||||
// Obtain version.
|
||||
skin.m_version = skin_node.attributes().namedItem(QSL("version")).toAttr().value();
|
||||
|
||||
// Obtain other information.
|
||||
skin.m_baseName = skin_name;
|
||||
|
||||
// Free resources.
|
||||
skin_file.close();
|
||||
skin_file.deleteLater();
|
||||
|
||||
// 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.
|
||||
// So if one uses "##/images/border.png" in QSS then it is
|
||||
// replaced by fully absolute path and target file can
|
||||
// be safely loaded.
|
||||
|
||||
skin.m_layoutMarkupWrapper = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_wrapper.html")));
|
||||
skin.m_layoutMarkupWrapper = skin.m_layoutMarkupWrapper.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
|
||||
skin.m_enclosureImageMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_image.html")));
|
||||
skin.m_enclosureImageMarkup = skin.m_enclosureImageMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
|
||||
skin.m_layoutMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_single_message.html")));
|
||||
skin.m_layoutMarkup = skin.m_layoutMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
|
||||
skin.m_enclosureMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_every.html")));
|
||||
skin.m_enclosureMarkup = skin.m_enclosureMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
|
||||
skin.m_rawData = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("theme.css")));
|
||||
skin.m_rawData = skin.m_rawData.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
|
||||
if (ok != nullptr) {
|
||||
*ok = !skin.m_author.isEmpty() && !skin.m_version.isEmpty() &&
|
||||
!skin.m_baseName.isEmpty() && !skin.m_email.isEmpty() &&
|
||||
!skin.m_layoutMarkup.isEmpty();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return skin;
|
||||
}
|
||||
|
||||
const QDomNode skin_node = dokument.namedItem(QSL("skin"));
|
||||
|
||||
// Obtain visible skin name.
|
||||
skin.m_visibleName = skin_name;
|
||||
|
||||
// Obtain author.
|
||||
skin.m_author = skin_node.namedItem(QSL("author")).namedItem(QSL("name")).toElement().text();
|
||||
|
||||
// Obtain email.
|
||||
skin.m_email = skin_node.namedItem(QSL("author")).namedItem(QSL("email")).toElement().text();
|
||||
|
||||
// Obtain version.
|
||||
skin.m_version = skin_node.attributes().namedItem(QSL("version")).toAttr().value();
|
||||
|
||||
// Obtain other information.
|
||||
skin.m_baseName = skin_name;
|
||||
|
||||
// Free resources.
|
||||
skin_file.close();
|
||||
skin_file.deleteLater();
|
||||
|
||||
// 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.
|
||||
// So if one uses "##/images/border.png" in QSS then it is
|
||||
// replaced by fully absolute path and target file can
|
||||
// be safely loaded.
|
||||
|
||||
const QString base_folder = APP_SKIN_PATH + QDir::separator() + skin_name + QDir::separator();
|
||||
|
||||
skin.m_layoutMarkupWrapper = QString::fromUtf8(IOFactory::readTextFile(base_folder + QL1S("html_wrapper.html")));
|
||||
skin.m_layoutMarkupWrapper = skin.m_layoutMarkupWrapper.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
|
||||
skin.m_enclosureImageMarkup = QString::fromUtf8(IOFactory::readTextFile(base_folder + QL1S("html_enclosure_image.html")));
|
||||
skin.m_enclosureImageMarkup = skin.m_enclosureImageMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
|
||||
skin.m_layoutMarkup = QString::fromUtf8(IOFactory::readTextFile(base_folder + QL1S("html_single_message.html")));
|
||||
skin.m_layoutMarkup = skin.m_layoutMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
|
||||
skin.m_enclosureMarkup = QString::fromUtf8(IOFactory::readTextFile(base_folder + QL1S("html_enclosure_every.html")));
|
||||
skin.m_enclosureMarkup = skin.m_enclosureMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
|
||||
skin.m_rawData = QString::fromUtf8(IOFactory::readTextFile(base_folder + QL1S("theme.css")));
|
||||
skin.m_rawData = skin.m_rawData.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
|
||||
if (ok != nullptr) {
|
||||
*ok = !skin.m_author.isEmpty() && !skin.m_version.isEmpty() &&
|
||||
!skin.m_baseName.isEmpty() && !skin.m_email.isEmpty() &&
|
||||
!skin.m_layoutMarkup.isEmpty();
|
||||
}
|
||||
|
||||
return skin;
|
||||
@ -151,10 +167,14 @@ Skin SkinFactory::skinInfo(const QString &skin_name, bool *ok) const {
|
||||
QList<Skin> SkinFactory::installedSkins() const {
|
||||
QList<Skin> skins;
|
||||
bool skin_load_ok;
|
||||
const QStringList skin_directories = QDir(APP_SKIN_PATH).entryList(QDir::Dirs |
|
||||
QDir::NoDotAndDotDot |
|
||||
QDir::NoSymLinks |
|
||||
QDir::Readable);
|
||||
QStringList skin_directories = QDir(APP_SKIN_PATH).entryList(QDir::Dirs |
|
||||
QDir::NoDotAndDotDot |
|
||||
QDir::NoSymLinks |
|
||||
QDir::Readable);
|
||||
skin_directories.append(QDir(getUserSkinBaseFolder()).entryList(QDir::Dirs |
|
||||
QDir::NoDotAndDotDot |
|
||||
QDir::NoSymLinks |
|
||||
QDir::Readable));
|
||||
|
||||
foreach (const QString &base_directory, skin_directories) {
|
||||
const Skin skin_info = skinInfo(base_directory, &skin_load_ok);
|
||||
|
@ -69,7 +69,10 @@ class SkinFactory : public QObject {
|
||||
// Sets the desired skin as the active one if it exists.
|
||||
void setCurrentSkinName(const QString &skin_name);
|
||||
|
||||
QString getUserSkinBaseFolder() const;
|
||||
|
||||
private:
|
||||
|
||||
// Loads the skin from give skin_data.
|
||||
void loadSkinFromData(const Skin &skin);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user