Work on skins.
This commit is contained in:
parent
99c011de41
commit
d995782668
10 changed files with 238 additions and 32 deletions
|
@ -72,6 +72,13 @@
|
|||
<translation>Hypertextový odkaz</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CornerButton</name>
|
||||
<message>
|
||||
<source>Open new tab</source>
|
||||
<translation>Otevřít nový panel</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>FormAbout</name>
|
||||
<message>
|
||||
|
@ -210,7 +217,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Language</source>
|
||||
<translation>Lokalizacce</translation>
|
||||
<translation>Lokalizace</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Proxy</source>
|
||||
|
@ -424,6 +431,15 @@
|
|||
<source>no icon theme</source>
|
||||
<translation>žádné téma ikon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Some keyboard shortcuts are not unique.
|
||||
</source>
|
||||
<translation>Některé klávesové zkrátky jsou duplicitní.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot save settings</source>
|
||||
<translation>Nastavení nelze uložit</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>FormWelcome</name>
|
||||
|
@ -468,6 +484,13 @@
|
|||
<translation>rotter.martinos@gmail.com</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SkinFactory</name>
|
||||
<message>
|
||||
<source>default system skin</source>
|
||||
<translation>výchozí systémový vzhled</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TabWidget</name>
|
||||
<message>
|
||||
|
|
|
@ -72,6 +72,13 @@
|
|||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>CornerButton</name>
|
||||
<message>
|
||||
<source>Open new tab</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>FormAbout</name>
|
||||
<message>
|
||||
|
@ -418,6 +425,15 @@
|
|||
<source>no icon theme</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Some keyboard shortcuts are not unique.
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Cannot save settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>FormWelcome</name>
|
||||
|
@ -462,6 +478,13 @@
|
|||
<translation>rotter.martinos@gmail.com</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SkinFactory</name>
|
||||
<message>
|
||||
<source>default system skin</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TabWidget</name>
|
||||
<message>
|
||||
|
|
|
@ -19,6 +19,25 @@ DynamicShortcutsWidget::~DynamicShortcutsWidget() {
|
|||
delete m_layout;
|
||||
}
|
||||
|
||||
bool DynamicShortcutsWidget::areShortcutsUnique() {
|
||||
QList<QKeySequence> all_shortcuts;
|
||||
|
||||
// Obtain all shortcuts.
|
||||
foreach (ActionBinding binding, m_actionBindings) {
|
||||
QKeySequence new_shortcut = binding.second->shortcut();
|
||||
|
||||
if (all_shortcuts.contains(new_shortcut)) {
|
||||
// Problem, two identical shortcuts found.
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
all_shortcuts.append(binding.second->shortcut());
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DynamicShortcutsWidget::updateShortcuts() {
|
||||
foreach (ActionBinding binding, m_actionBindings) {
|
||||
binding.first->setShortcut(binding.second->shortcut());
|
||||
|
|
|
@ -23,6 +23,10 @@ class DynamicShortcutsWidget : public QWidget {
|
|||
// and stored back to settings when application quits.
|
||||
void updateShortcuts();
|
||||
|
||||
// Returns true if all shortcuts are unique,
|
||||
// otherwise false.
|
||||
bool areShortcutsUnique();
|
||||
|
||||
// Populates this widget with shortcut widgets for given actions.
|
||||
// NOTE: This gets initial shortcut for each action from its properties, NOT from
|
||||
// the application settings, so shortcuts from settings need to be
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "gui/formsettings.h"
|
||||
#include "gui/iconthemefactory.h"
|
||||
#include "gui/skinfactory.h"
|
||||
#include "gui/systemtrayicon.h"
|
||||
#include "gui/formmain.h"
|
||||
#include "gui/webbrowser.h"
|
||||
|
@ -28,17 +29,31 @@ FormSettings::FormSettings(QWidget *parent) : QDialog(parent), m_ui(new Ui::Form
|
|||
m_ui->m_treeLanguages->setHeaderHidden(false);
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
// Setup languages.
|
||||
m_ui->m_treeLanguages->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeLanguages->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeLanguages->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeLanguages->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeLanguages->header()->setSectionResizeMode(4, QHeaderView::ResizeToContents);
|
||||
|
||||
// Setup skins.
|
||||
m_ui->m_treeSkins->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeSkins->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeSkins->header()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeSkins->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
|
||||
#else
|
||||
// Setup languages.
|
||||
m_ui->m_treeLanguages->header()->setResizeMode(0, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeLanguages->header()->setResizeMode(1, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeLanguages->header()->setResizeMode(2, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeLanguages->header()->setResizeMode(3, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeLanguages->header()->setResizeMode(4, QHeaderView::ResizeToContents);
|
||||
|
||||
// Setup skins.
|
||||
m_ui->m_treeSkins->header()->setResizeMode(0, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeSkins->header()->setResizeMode(1, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeSkins->header()->setResizeMode(2, QHeaderView::ResizeToContents);
|
||||
m_ui->m_treeSkins->header()->setResizeMode(3, QHeaderView::ResizeToContents);
|
||||
#endif
|
||||
|
||||
m_ui->m_treeLanguages->setHeaderLabels(QStringList()
|
||||
|
@ -48,8 +63,15 @@ FormSettings::FormSettings(QWidget *parent) : QDialog(parent), m_ui(new Ui::Form
|
|||
<< tr("Author")
|
||||
<< tr("Email"));
|
||||
|
||||
m_ui->m_treeSkins->setHeaderLabels(QStringList()
|
||||
<< tr("Name")
|
||||
<< tr("Version")
|
||||
<< tr("Author")
|
||||
<< tr("Email"));
|
||||
|
||||
// Establish needed connections.
|
||||
connect(this, SIGNAL(accepted()), this, SLOT(saveSettings()));
|
||||
connect(m_ui->m_buttonBox, SIGNAL(accepted()),
|
||||
this, SLOT(saveSettings()));
|
||||
connect(m_ui->m_cmbProxyType, SIGNAL(currentIndexChanged(int)),
|
||||
this, SLOT(onProxyTypeChanged(int)));
|
||||
connect(m_ui->m_checkShowPassword, SIGNAL(stateChanged(int)),
|
||||
|
@ -88,7 +110,31 @@ void FormSettings::displayProxyPassword(int state) {
|
|||
}
|
||||
}
|
||||
|
||||
bool FormSettings::doSaveCheck() {
|
||||
bool everything_ok = true;
|
||||
QString resulting_information;
|
||||
|
||||
everything_ok &= m_ui->m_shortcuts->areShortcutsUnique();
|
||||
|
||||
if (!m_ui->m_shortcuts->areShortcutsUnique()) {
|
||||
resulting_information = resulting_information.append(tr("Some keyboard shortcuts are not unique.\n"));
|
||||
}
|
||||
|
||||
if (!everything_ok) {
|
||||
QMessageBox::warning(this,
|
||||
tr("Cannot save settings"),
|
||||
resulting_information);
|
||||
}
|
||||
|
||||
return everything_ok;
|
||||
}
|
||||
|
||||
void FormSettings::saveSettings() {
|
||||
// Make sure everything is saveable.
|
||||
if (!doSaveCheck()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save all settings.
|
||||
saveGeneral();
|
||||
saveShortcuts();
|
||||
|
@ -98,6 +144,8 @@ void FormSettings::saveSettings() {
|
|||
saveLanguage();
|
||||
|
||||
Settings::getInstance()->checkSettings();
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
void FormSettings::onProxyTypeChanged(int index) {
|
||||
|
@ -349,6 +397,26 @@ void FormSettings::loadInterface() {
|
|||
m_ui->m_cmbIconTheme->setCurrentIndex(theme_index);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Load skin.
|
||||
QList<Skin> installed_skins = SkinFactory::getInstance()->getInstalledSkins();
|
||||
QString active_skin = SkinFactory::getInstance()->getCurrentSkinName();
|
||||
|
||||
foreach (Skin skin, installed_skins) {
|
||||
QTreeWidgetItem *new_item = new QTreeWidgetItem(QStringList() <<
|
||||
skin.m_visibleName <<
|
||||
skin.m_version <<
|
||||
skin.m_author <<
|
||||
skin.m_email);
|
||||
new_item->setData(0, Qt::UserRole, QVariant::fromValue(skin));
|
||||
|
||||
// Add this skin and mark it as active if its active now.
|
||||
m_ui->m_treeSkins->addTopLevelItem(new_item);
|
||||
|
||||
if (skin.m_baseName == active_skin) {
|
||||
m_ui->m_treeSkins->setCurrentItem(new_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load tab settings.
|
||||
|
@ -387,6 +455,10 @@ void FormSettings::saveInterface() {
|
|||
QString selected_icon_theme = m_ui->m_cmbIconTheme->itemData(m_ui->m_cmbIconTheme->currentIndex()).toString();
|
||||
IconThemeFactory::getInstance()->setCurrentIconTheme(selected_icon_theme);
|
||||
|
||||
// Save and activate new skin.
|
||||
Skin active_skin = m_ui->m_treeSkins->currentItem()->data(0, Qt::UserRole).value<Skin>();
|
||||
SkinFactory::getInstance()->setCurrentSkinName(active_skin.m_baseName);
|
||||
|
||||
// Save tab settings.
|
||||
settings->setValue(APP_CFG_GUI, "tab_close_mid_button",
|
||||
m_ui->m_checkCloseTabsMiddleClick->isChecked());
|
||||
|
|
|
@ -22,6 +22,9 @@ class FormSettings : public QDialog {
|
|||
explicit FormSettings(QWidget *parent = 0);
|
||||
virtual ~FormSettings();
|
||||
|
||||
protected:
|
||||
bool doSaveCheck();
|
||||
|
||||
protected slots:
|
||||
// Saves settings into global configuration.
|
||||
void saveSettings();
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>680</width>
|
||||
<width>829</width>
|
||||
<height>414</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -17,7 +17,7 @@
|
|||
<item row="0" column="1">
|
||||
<widget class="QStackedWidget" name="m_stackedSettings">
|
||||
<property name="currentIndex">
|
||||
<number>4</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="m_pageGeneral">
|
||||
<layout class="QFormLayout" name="formLayout_5">
|
||||
|
@ -69,8 +69,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>100</width>
|
||||
<height>30</height>
|
||||
<width>585</width>
|
||||
<height>368</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
|
@ -142,8 +142,29 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="m_cmbSkin"/>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QTreeWidget" name="m_treeSkins">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="itemsExpandable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="expandsOnDoubleClick">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string notr="true">1</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
|
@ -528,9 +549,15 @@
|
|||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QListWidget" name="m_listSettings">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>220</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<width>220</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
|
@ -586,22 +613,6 @@
|
|||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>m_buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>FormSettings</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>257</x>
|
||||
<y>404</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>m_buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
|
|
|
@ -34,10 +34,15 @@ void SkinFactory::loadCurrentSkin() {
|
|||
bool loaded = false;
|
||||
Skin skin_data = getSkinInfo(skin_name_from_settings, &loaded);
|
||||
|
||||
if (loaded) {
|
||||
if (skin_name_from_settings == APP_THEME_SYSTEM) {
|
||||
qApp->setStyleSheet(QString());
|
||||
qApp->setStyle(NULL);
|
||||
qDebug("System default skin loaded.");
|
||||
}
|
||||
else if (loaded) {
|
||||
loadSkinFromData(skin_data.m_rawData, skin_name_from_settings);
|
||||
|
||||
foreach (QString style, skin_data.m_stylesName.split("\n")) {
|
||||
foreach (QString style, skin_data.m_stylesNames) {
|
||||
if (qApp->setStyle(style) != 0) {
|
||||
qDebug("Style '%s' loaded.", qPrintable(style));
|
||||
break;
|
||||
|
@ -96,21 +101,27 @@ Skin SkinFactory::getSkinInfo(const QString &skin_name, bool *ok) {
|
|||
QXmlQuery query;
|
||||
QFile skin_file(APP_SKIN_PATH + QDir::separator() + skin_name);
|
||||
|
||||
if (!skin_file.open(QIODevice::ReadOnly) ||!query.setFocus(&skin_file)) {
|
||||
if (!skin_file.open(QIODevice::ReadOnly) || !query.setFocus(&skin_file)) {
|
||||
if (ok) {
|
||||
*ok = false;
|
||||
}
|
||||
return skin;
|
||||
}
|
||||
|
||||
// Obtain visible skin name.
|
||||
query.setQuery("string(skin/name)");
|
||||
query.evaluateTo(&skin.m_visibleName);
|
||||
skin.m_visibleName = skin.m_visibleName.remove("\n");
|
||||
|
||||
// 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");
|
||||
QString styles;
|
||||
query.evaluateTo(&styles);
|
||||
skin.m_stylesNames = styles.remove("\n").split(",");
|
||||
|
||||
// Obtain author.
|
||||
query.setQuery("string(/skin/author/name)");
|
||||
|
@ -137,7 +148,7 @@ Skin SkinFactory::getSkinInfo(const QString &skin_name, bool *ok) {
|
|||
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();
|
||||
!skin.m_rawData.isEmpty() && !skin.m_stylesNames.isEmpty();
|
||||
}
|
||||
|
||||
return skin;
|
||||
|
@ -145,5 +156,36 @@ Skin SkinFactory::getSkinInfo(const QString &skin_name, bool *ok) {
|
|||
|
||||
QList<Skin> SkinFactory::getInstalledSkins() {
|
||||
QList<Skin> skins;
|
||||
|
||||
Skin default_skin;
|
||||
default_skin.m_author = "-";
|
||||
default_skin.m_baseName = APP_THEME_SYSTEM;
|
||||
default_skin.m_email = "-";
|
||||
default_skin.m_version = "-";
|
||||
default_skin.m_visibleName = tr("default system skin");
|
||||
skins.append(default_skin);
|
||||
|
||||
bool skin_load_ok;
|
||||
QStringList skin_directories = QDir(APP_SKIN_PATH).entryList(QDir::Dirs |
|
||||
QDir::NoDotAndDotDot |
|
||||
QDir::NoSymLinks |
|
||||
QDir::Readable);
|
||||
|
||||
foreach (QString base_directory, skin_directories) {
|
||||
// Check skins installed in this base directory.
|
||||
QStringList skin_files = QDir(APP_SKIN_PATH + QDir::separator() + base_directory).entryList(QStringList() << "*.xml",
|
||||
QDir::Files | QDir::Readable | QDir::NoDotAndDotDot | QDir::NoSymLinks);
|
||||
|
||||
foreach (QString skin_file, skin_files) {
|
||||
// Check if skin file is valid and add it if it is valid.
|
||||
Skin skin_info = getSkinInfo(base_directory + QDir::separator() + skin_file,
|
||||
&skin_load_ok);
|
||||
|
||||
if (skin_load_ok) {
|
||||
skins.append(skin_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return skins;
|
||||
}
|
||||
|
|
|
@ -3,23 +3,31 @@
|
|||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QStringList>
|
||||
#include <QMetaType>
|
||||
|
||||
|
||||
struct Skin {
|
||||
QString m_baseName;
|
||||
QString m_stylesName;
|
||||
QString m_visibleName;
|
||||
QStringList m_stylesNames;
|
||||
QString m_author;
|
||||
QString m_email;
|
||||
QString m_version;
|
||||
QString m_rawData;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(Skin)
|
||||
|
||||
class SkinFactory : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
explicit SkinFactory(QObject *parent = 0);
|
||||
|
||||
// Loads the skin from give skin_data.
|
||||
// NOTE: Extra relative path escaping is done for loading of
|
||||
// external resources.
|
||||
bool loadSkinFromData(QString skin_data, const QString &skin_path);
|
||||
|
||||
public:
|
||||
|
|
|
@ -72,6 +72,7 @@ int main(int argc, char *argv[]) {
|
|||
IconThemeFactory::getInstance()->setupSearchPaths();
|
||||
IconThemeFactory::getInstance()->loadCurrentIconTheme(false);
|
||||
SkinFactory::getInstance()->loadCurrentSkin();
|
||||
SkinFactory::getInstance()->getInstalledSkins();
|
||||
|
||||
// Load localization and setup locale before any widget is constructed.
|
||||
LoadLocalization();
|
||||
|
|
Loading…
Add table
Reference in a new issue