forked from qt-creator/qt-creator
Core: Separate theme settings widget from options page
Change-Id: I6537e592f87969af5c2e53606a704fabec62fedc Reviewed-by: Alessandro Portale <alessandro.portale@digia.com>
This commit is contained in:
committed by
Orgad Shaneh
parent
e871225057
commit
c1a76f8cc1
@@ -17,6 +17,7 @@ SOURCES += corejsextensions.cpp \
|
|||||||
fancytabwidget.cpp \
|
fancytabwidget.cpp \
|
||||||
generalsettings.cpp \
|
generalsettings.cpp \
|
||||||
themesettings.cpp \
|
themesettings.cpp \
|
||||||
|
themesettingswidget.cpp \
|
||||||
id.cpp \
|
id.cpp \
|
||||||
icontext.cpp \
|
icontext.cpp \
|
||||||
jsexpander.cpp \
|
jsexpander.cpp \
|
||||||
@@ -121,6 +122,7 @@ HEADERS += corejsextensions.h \
|
|||||||
fancytabwidget.h \
|
fancytabwidget.h \
|
||||||
generalsettings.h \
|
generalsettings.h \
|
||||||
themesettings.h \
|
themesettings.h \
|
||||||
|
themesettingswidget.h \
|
||||||
id.h \
|
id.h \
|
||||||
jsexpander.h \
|
jsexpander.h \
|
||||||
messagemanager.h \
|
messagemanager.h \
|
||||||
|
|||||||
@@ -98,9 +98,8 @@ QtcPlugin {
|
|||||||
"styleanimator.cpp", "styleanimator.h",
|
"styleanimator.cpp", "styleanimator.h",
|
||||||
"tabpositionindicator.cpp", "tabpositionindicator.h",
|
"tabpositionindicator.cpp", "tabpositionindicator.h",
|
||||||
"textdocument.cpp", "textdocument.h",
|
"textdocument.cpp", "textdocument.h",
|
||||||
"themesettings.cpp",
|
"themesettings.cpp", "themesettings.h", "themesettings.ui",
|
||||||
"themesettings.h",
|
"themesettingswidget.cpp", "themesettingswidget.h",
|
||||||
"themesettings.ui",
|
|
||||||
"toolsettings.cpp", "toolsettings.h",
|
"toolsettings.cpp", "toolsettings.h",
|
||||||
"variablechooser.cpp", "variablechooser.h",
|
"variablechooser.cpp", "variablechooser.h",
|
||||||
"vcsmanager.cpp", "vcsmanager.h",
|
"vcsmanager.cpp", "vcsmanager.h",
|
||||||
|
|||||||
@@ -29,436 +29,44 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "themesettings.h"
|
#include "themesettings.h"
|
||||||
|
#include "themesettingswidget.h"
|
||||||
#include "coreconstants.h"
|
#include "coreconstants.h"
|
||||||
#include "icore.h"
|
|
||||||
#include "editormanager/editormanager_p.h"
|
|
||||||
#include "themeeditor/themesettingstablemodel.h"
|
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QInputDialog>
|
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QSettings>
|
|
||||||
|
|
||||||
#include "ui_themesettings.h"
|
|
||||||
|
|
||||||
using namespace Utils;
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
const char themeNameKey[] = "ThemeName";
|
ThemeSettings::ThemeSettings() :
|
||||||
|
m_widget(0)
|
||||||
static QString customThemesPath()
|
|
||||||
{
|
|
||||||
QString path = Core::ICore::userResourcePath();
|
|
||||||
path.append(QLatin1String("/themes/"));
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
static QString createThemeFileName(const QString &pattern)
|
|
||||||
{
|
|
||||||
const QString stylesPath = customThemesPath();
|
|
||||||
QString baseFileName = stylesPath;
|
|
||||||
baseFileName += pattern;
|
|
||||||
|
|
||||||
// Find an available file name
|
|
||||||
int i = 1;
|
|
||||||
QString fileName;
|
|
||||||
do {
|
|
||||||
fileName = baseFileName.arg((i == 1) ? QString() : QString::number(i));
|
|
||||||
++i;
|
|
||||||
} while (QFile::exists(fileName));
|
|
||||||
|
|
||||||
// Create the base directory when it doesn't exist
|
|
||||||
if (!QFile::exists(stylesPath) && !QDir().mkpath(stylesPath)) {
|
|
||||||
qWarning() << "Failed to create theme directory:" << stylesPath;
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
return fileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct ThemeEntry
|
|
||||||
{
|
|
||||||
ThemeEntry() {}
|
|
||||||
ThemeEntry(const QString &fileName, bool readOnly):
|
|
||||||
m_fileName(fileName),
|
|
||||||
m_readOnly(readOnly)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
QString fileName() const { return m_fileName; }
|
|
||||||
QString name() const;
|
|
||||||
bool readOnly() const { return m_readOnly; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString m_fileName;
|
|
||||||
bool m_readOnly;
|
|
||||||
};
|
|
||||||
|
|
||||||
QString ThemeEntry::name() const
|
|
||||||
{
|
|
||||||
QSettings settings(m_fileName, QSettings::IniFormat);
|
|
||||||
QString n = settings.value(QLatin1String(themeNameKey), QCoreApplication::tr("unnamed")).toString();
|
|
||||||
return m_readOnly ? QCoreApplication::tr("%1 (built-in)").arg(n) : n;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class ThemeListModel : public QAbstractListModel
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ThemeListModel(QObject *parent = 0):
|
|
||||||
QAbstractListModel(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
return parent.isValid() ? 0 : m_themes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant data(const QModelIndex &index, int role) const
|
|
||||||
{
|
|
||||||
if (role == Qt::DisplayRole)
|
|
||||||
return m_themes.at(index.row()).name();
|
|
||||||
return QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeTheme(int index)
|
|
||||||
{
|
|
||||||
beginRemoveRows(QModelIndex(), index, index);
|
|
||||||
m_themes.removeAt(index);
|
|
||||||
endRemoveRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setThemes(const QList<ThemeEntry> &themes)
|
|
||||||
{
|
|
||||||
beginResetModel();
|
|
||||||
m_themes = themes;
|
|
||||||
endResetModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
const ThemeEntry &themeAt(int index) const
|
|
||||||
{
|
|
||||||
return m_themes.at(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QList<ThemeEntry> m_themes;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class ThemeSettingsPrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ThemeSettingsPrivate();
|
|
||||||
~ThemeSettingsPrivate();
|
|
||||||
|
|
||||||
public:
|
|
||||||
ThemeListModel *m_themeListModel;
|
|
||||||
bool m_refreshingThemeList;
|
|
||||||
Ui::ThemeSettings *m_ui;
|
|
||||||
QPointer<QWidget> m_widget;
|
|
||||||
ThemeEntry m_currentTheme;
|
|
||||||
};
|
|
||||||
|
|
||||||
ThemeSettingsPrivate::ThemeSettingsPrivate()
|
|
||||||
: m_themeListModel(new ThemeListModel)
|
|
||||||
, m_refreshingThemeList(false)
|
|
||||||
, m_ui(0)
|
|
||||||
{
|
|
||||||
m_currentTheme = ThemeEntry(creatorTheme()->fileName(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ThemeSettingsPrivate::~ThemeSettingsPrivate()
|
|
||||||
{
|
|
||||||
delete m_themeListModel;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThemeSettings::ThemeSettings()
|
|
||||||
{
|
{
|
||||||
setId(Core::Constants::SETTINGS_ID_ENVIRONMENT);
|
setId(Core::Constants::SETTINGS_ID_ENVIRONMENT);
|
||||||
setDisplayName(tr("Theme"));
|
setDisplayName(tr("Theme"));
|
||||||
setCategory(Core::Constants::SETTINGS_CATEGORY_CORE);
|
setCategory(Core::Constants::SETTINGS_CATEGORY_CORE);
|
||||||
setDisplayCategory(QCoreApplication::translate("Core", Core::Constants::SETTINGS_TR_CATEGORY_CORE));
|
setDisplayCategory(QCoreApplication::translate("Core", Core::Constants::SETTINGS_TR_CATEGORY_CORE));
|
||||||
setCategoryIcon(QLatin1String(Core::Constants::SETTINGS_CATEGORY_CORE_ICON));
|
setCategoryIcon(QLatin1String(Core::Constants::SETTINGS_CATEGORY_CORE_ICON));
|
||||||
|
|
||||||
d = new ThemeSettingsPrivate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ThemeSettings::~ThemeSettings()
|
ThemeSettings::~ThemeSettings()
|
||||||
{
|
{
|
||||||
delete d;
|
delete m_widget;
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::refreshThemeList()
|
|
||||||
{
|
|
||||||
QList<ThemeEntry> themes;
|
|
||||||
|
|
||||||
QString resourcePath = Core::ICore::resourcePath();
|
|
||||||
QDir themeDir(resourcePath + QLatin1String("/themes"));
|
|
||||||
themeDir.setNameFilters(QStringList() << QLatin1String("*.creatortheme"));
|
|
||||||
themeDir.setFilter(QDir::Files);
|
|
||||||
|
|
||||||
int selected = 0;
|
|
||||||
|
|
||||||
QStringList themeList = themeDir.entryList();
|
|
||||||
QString defaultTheme = QFileInfo(defaultThemeFileName()).fileName();
|
|
||||||
if (themeList.removeAll(defaultTheme))
|
|
||||||
themeList.prepend(defaultTheme);
|
|
||||||
foreach (const QString &file, themeList) {
|
|
||||||
const QString fileName = themeDir.absoluteFilePath(file);
|
|
||||||
if (d->m_currentTheme.fileName() == fileName)
|
|
||||||
selected = themes.size();
|
|
||||||
themes.append(ThemeEntry(fileName, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (themes.isEmpty())
|
|
||||||
qWarning() << "Warning: no themes found in path:" << themeDir.path();
|
|
||||||
|
|
||||||
themeDir.setPath(customThemesPath());
|
|
||||||
foreach (const QString &file, themeDir.entryList()) {
|
|
||||||
const QString fileName = themeDir.absoluteFilePath(file);
|
|
||||||
if (d->m_currentTheme.fileName() == fileName)
|
|
||||||
selected = themes.size();
|
|
||||||
themes.append(ThemeEntry(fileName, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
d->m_currentTheme = themes[selected];
|
|
||||||
|
|
||||||
d->m_refreshingThemeList = true;
|
|
||||||
d->m_themeListModel->setThemes(themes);
|
|
||||||
d->m_ui->themeComboBox->setCurrentIndex(selected);
|
|
||||||
d->m_refreshingThemeList = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString ThemeSettings::defaultThemeFileName(const QString &fileName)
|
|
||||||
{
|
|
||||||
QString defaultScheme = Core::ICore::resourcePath();
|
|
||||||
defaultScheme += QLatin1String("/themes/");
|
|
||||||
|
|
||||||
if (!fileName.isEmpty() && QFile::exists(defaultScheme + fileName))
|
|
||||||
defaultScheme += fileName;
|
|
||||||
else
|
|
||||||
defaultScheme += QLatin1String("default.creatortheme");
|
|
||||||
|
|
||||||
return defaultScheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::themeSelected(int index)
|
|
||||||
{
|
|
||||||
bool readOnly = true;
|
|
||||||
if (index != -1) {
|
|
||||||
// Check whether we're switching away from a changed theme
|
|
||||||
if (!d->m_refreshingThemeList)
|
|
||||||
maybeSaveTheme();
|
|
||||||
|
|
||||||
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
|
||||||
readOnly = entry.readOnly();
|
|
||||||
d->m_currentTheme = entry;
|
|
||||||
|
|
||||||
QSettings settings(entry.fileName(), QSettings::IniFormat);
|
|
||||||
Theme theme;
|
|
||||||
theme.readSettings(settings);
|
|
||||||
d->m_ui->editor->initFrom(&theme);
|
|
||||||
}
|
|
||||||
d->m_ui->copyButton->setEnabled(index != -1);
|
|
||||||
d->m_ui->deleteButton->setEnabled(!readOnly);
|
|
||||||
d->m_ui->renameButton->setEnabled(!readOnly);
|
|
||||||
d->m_ui->editor->setReadOnly(readOnly);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *ThemeSettings::widget()
|
QWidget *ThemeSettings::widget()
|
||||||
{
|
{
|
||||||
if (!d->m_widget) {
|
if (!m_widget)
|
||||||
d->m_widget = new QWidget;
|
m_widget = new ThemeSettingsWidget;
|
||||||
d->m_ui = new Ui::ThemeSettings();
|
return m_widget;
|
||||||
d->m_ui->setupUi(d->m_widget);
|
|
||||||
d->m_ui->themeComboBox->setModel(d->m_themeListModel);
|
|
||||||
|
|
||||||
connect(d->m_ui->themeComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
|
||||||
this, &ThemeSettings::themeSelected);
|
|
||||||
connect(d->m_ui->copyButton, &QAbstractButton::clicked, this, &ThemeSettings::copyTheme);
|
|
||||||
connect(d->m_ui->renameButton, &QAbstractButton::clicked, this, &ThemeSettings::renameTheme);
|
|
||||||
connect(d->m_ui->deleteButton, &QAbstractButton::clicked, this, &ThemeSettings::confirmDeleteTheme);
|
|
||||||
|
|
||||||
refreshThemeList();
|
|
||||||
}
|
|
||||||
return d->m_widget;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::confirmDeleteTheme()
|
|
||||||
{
|
|
||||||
const int index = d->m_ui->themeComboBox->currentIndex();
|
|
||||||
if (index == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
|
||||||
if (entry.readOnly())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QMessageBox *messageBox = new QMessageBox(QMessageBox::Warning,
|
|
||||||
tr("Delete Theme"),
|
|
||||||
tr("Are you sure you want to delete the theme '%1' permanently?").arg(entry.name()),
|
|
||||||
QMessageBox::Discard | QMessageBox::Cancel,
|
|
||||||
d->m_ui->deleteButton->window());
|
|
||||||
|
|
||||||
// Change the text and role of the discard button
|
|
||||||
QPushButton *deleteButton = static_cast<QPushButton*>(messageBox->button(QMessageBox::Discard));
|
|
||||||
deleteButton->setText(tr("Delete"));
|
|
||||||
messageBox->addButton(deleteButton, QMessageBox::AcceptRole);
|
|
||||||
messageBox->setDefaultButton(deleteButton);
|
|
||||||
|
|
||||||
connect(deleteButton, &QAbstractButton::clicked, messageBox, &QDialog::accept);
|
|
||||||
connect(messageBox, &QDialog::accepted, this, &ThemeSettings::deleteTheme);
|
|
||||||
messageBox->setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
messageBox->open();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::deleteTheme()
|
|
||||||
{
|
|
||||||
const int index = d->m_ui->themeComboBox->currentIndex();
|
|
||||||
QTC_ASSERT(index != -1, return);
|
|
||||||
|
|
||||||
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
|
||||||
QTC_ASSERT(!entry.readOnly(), return);
|
|
||||||
|
|
||||||
if (QFile::remove(entry.fileName()))
|
|
||||||
d->m_themeListModel->removeTheme(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::copyTheme()
|
|
||||||
{
|
|
||||||
QInputDialog *dialog = new QInputDialog(d->m_ui->copyButton->window());
|
|
||||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
|
||||||
dialog->setInputMode(QInputDialog::TextInput);
|
|
||||||
dialog->setWindowTitle(tr("Copy Theme"));
|
|
||||||
dialog->setLabelText(tr("Theme name:"));
|
|
||||||
|
|
||||||
//TODO
|
|
||||||
//dialog->setTextValue(tr("%1 (copy)").arg(d_ptr->m_value.colorScheme().displayName()));
|
|
||||||
|
|
||||||
connect(dialog, &QInputDialog::textValueSelected, this, &ThemeSettings::copyThemeByName);
|
|
||||||
dialog->open();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::maybeSaveTheme()
|
|
||||||
{
|
|
||||||
if (!d->m_ui->editor->model()->hasChanges())
|
|
||||||
return;
|
|
||||||
|
|
||||||
QMessageBox *messageBox = new QMessageBox(QMessageBox::Warning,
|
|
||||||
tr("Theme Changed"),
|
|
||||||
tr("The theme \"%1\" was modified, do you want to save the changes?")
|
|
||||||
.arg(d->m_currentTheme.name()),
|
|
||||||
QMessageBox::Discard | QMessageBox::Save,
|
|
||||||
d->m_ui->themeComboBox->window());
|
|
||||||
|
|
||||||
// Change the text of the discard button
|
|
||||||
QPushButton *discardButton = static_cast<QPushButton*>(messageBox->button(QMessageBox::Discard));
|
|
||||||
discardButton->setText(tr("Discard"));
|
|
||||||
messageBox->addButton(discardButton, QMessageBox::DestructiveRole);
|
|
||||||
messageBox->setDefaultButton(QMessageBox::Save);
|
|
||||||
|
|
||||||
if (messageBox->exec() == QMessageBox::Save) {
|
|
||||||
Theme newTheme;
|
|
||||||
d->m_ui->editor->model()->toTheme(&newTheme);
|
|
||||||
newTheme.writeSettings(d->m_currentTheme.fileName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::renameTheme()
|
|
||||||
{
|
|
||||||
int index = d->m_ui->themeComboBox->currentIndex();
|
|
||||||
if (index == -1)
|
|
||||||
return;
|
|
||||||
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
|
||||||
|
|
||||||
maybeSaveTheme();
|
|
||||||
|
|
||||||
QInputDialog *dialog = new QInputDialog(d->m_ui->renameButton->window());
|
|
||||||
dialog->setInputMode(QInputDialog::TextInput);
|
|
||||||
dialog->setWindowTitle(tr("Rename Theme"));
|
|
||||||
dialog->setLabelText(tr("Theme name:"));
|
|
||||||
dialog->setTextValue(d->m_ui->editor->model()->m_name);
|
|
||||||
int ret = dialog->exec();
|
|
||||||
QString newName = dialog->textValue();
|
|
||||||
delete dialog;
|
|
||||||
|
|
||||||
if (ret != QDialog::Accepted || newName.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// overwrite file with new name
|
|
||||||
Theme newTheme;
|
|
||||||
d->m_ui->editor->model()->toTheme(&newTheme);
|
|
||||||
newTheme.setName(newName);
|
|
||||||
newTheme.writeSettings(entry.fileName());
|
|
||||||
|
|
||||||
refreshThemeList();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThemeSettings::copyThemeByName(const QString &name)
|
|
||||||
{
|
|
||||||
int index = d->m_ui->themeComboBox->currentIndex();
|
|
||||||
if (index == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
|
||||||
|
|
||||||
QString baseFileName = QFileInfo(entry.fileName()).completeBaseName();
|
|
||||||
baseFileName += QLatin1String("_copy%1.creatortheme");
|
|
||||||
QString fileName = createThemeFileName(baseFileName);
|
|
||||||
|
|
||||||
if (fileName.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Ask about saving any existing modifactions
|
|
||||||
maybeSaveTheme();
|
|
||||||
|
|
||||||
Theme newTheme;
|
|
||||||
d->m_ui->editor->model()->toTheme(&newTheme);
|
|
||||||
newTheme.setName(name);
|
|
||||||
newTheme.writeSettings(fileName);
|
|
||||||
|
|
||||||
d->m_currentTheme = ThemeEntry(fileName, true);
|
|
||||||
|
|
||||||
refreshThemeList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeSettings::apply()
|
void ThemeSettings::apply()
|
||||||
{
|
{
|
||||||
if (!d->m_ui) // wasn't shown, can't be changed
|
if (m_widget)
|
||||||
return;
|
m_widget->apply();
|
||||||
|
|
||||||
{
|
|
||||||
d->m_ui->editor->model()->toTheme(creatorTheme());
|
|
||||||
if (creatorTheme()->flag(Theme::ApplyThemePaletteGlobally))
|
|
||||||
QApplication::setPalette(creatorTheme()->palette(QApplication::palette()));
|
|
||||||
foreach (QWidget *w, QApplication::topLevelWidgets())
|
|
||||||
w->update();
|
|
||||||
}
|
|
||||||
|
|
||||||
// save definition of theme
|
|
||||||
if (!d->m_currentTheme.readOnly()) {
|
|
||||||
Theme newTheme;
|
|
||||||
d->m_ui->editor->model()->toTheme(&newTheme);
|
|
||||||
newTheme.writeSettings(d->m_currentTheme.fileName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// save filename of selected theme in global config
|
|
||||||
QSettings *settings = Core::ICore::settings();
|
|
||||||
settings->setValue(QLatin1String(Core::Constants::SETTINGS_THEME), d->m_currentTheme.fileName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThemeSettings::finish()
|
void ThemeSettings::finish()
|
||||||
{
|
{
|
||||||
delete d->m_widget;
|
delete m_widget;
|
||||||
if (!d->m_ui) // page was never shown
|
m_widget = 0;
|
||||||
return
|
|
||||||
delete d->m_ui;
|
|
||||||
d->m_ui = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class ThemeSettingsPrivate;
|
class ThemeSettingsWidget;
|
||||||
|
|
||||||
class ThemeSettings : public IOptionsPage
|
class ThemeSettings : public IOptionsPage
|
||||||
{
|
{
|
||||||
@@ -50,20 +50,7 @@ public:
|
|||||||
void apply();
|
void apply();
|
||||||
void finish();
|
void finish();
|
||||||
|
|
||||||
static QString defaultThemeFileName(const QString &fileName = QString());
|
ThemeSettingsWidget *m_widget;
|
||||||
|
|
||||||
private slots:
|
|
||||||
void themeSelected(int index);
|
|
||||||
void copyTheme();
|
|
||||||
void renameTheme();
|
|
||||||
void copyThemeByName(const QString &);
|
|
||||||
void confirmDeleteTheme();
|
|
||||||
void deleteTheme();
|
|
||||||
void maybeSaveTheme();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void refreshThemeList();
|
|
||||||
ThemeSettingsPrivate *d;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
438
src/plugins/coreplugin/themesettingswidget.cpp
Normal file
438
src/plugins/coreplugin/themesettingswidget.cpp
Normal file
@@ -0,0 +1,438 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Thorben Kroeger <thorbenkroeger@gmail.com>.
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://www.qt.io/licensing. For further information
|
||||||
|
** use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 or version 3 as published by the Free
|
||||||
|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||||
|
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||||
|
** following information to ensure the GNU Lesser General Public License
|
||||||
|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "themesettingswidget.h"
|
||||||
|
#include "coreconstants.h"
|
||||||
|
#include "icore.h"
|
||||||
|
#include "themeeditor/themesettingstablemodel.h"
|
||||||
|
|
||||||
|
#include <utils/theme/theme.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QSettings>
|
||||||
|
|
||||||
|
#include "ui_themesettings.h"
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
const char themeNameKey[] = "ThemeName";
|
||||||
|
|
||||||
|
static QString customThemesPath()
|
||||||
|
{
|
||||||
|
QString path = Core::ICore::userResourcePath();
|
||||||
|
path.append(QLatin1String("/themes/"));
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString createThemeFileName(const QString &pattern)
|
||||||
|
{
|
||||||
|
const QString stylesPath = customThemesPath();
|
||||||
|
QString baseFileName = stylesPath;
|
||||||
|
baseFileName += pattern;
|
||||||
|
|
||||||
|
// Find an available file name
|
||||||
|
int i = 1;
|
||||||
|
QString fileName;
|
||||||
|
do {
|
||||||
|
fileName = baseFileName.arg((i == 1) ? QString() : QString::number(i));
|
||||||
|
++i;
|
||||||
|
} while (QFile::exists(fileName));
|
||||||
|
|
||||||
|
// Create the base directory when it doesn't exist
|
||||||
|
if (!QFile::exists(stylesPath) && !QDir().mkpath(stylesPath)) {
|
||||||
|
qWarning() << "Failed to create theme directory:" << stylesPath;
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ThemeEntry
|
||||||
|
{
|
||||||
|
ThemeEntry() {}
|
||||||
|
ThemeEntry(const QString &fileName, bool readOnly):
|
||||||
|
m_fileName(fileName),
|
||||||
|
m_readOnly(readOnly)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
QString fileName() const { return m_fileName; }
|
||||||
|
QString name() const;
|
||||||
|
bool readOnly() const { return m_readOnly; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_fileName;
|
||||||
|
bool m_readOnly;
|
||||||
|
};
|
||||||
|
|
||||||
|
QString ThemeEntry::name() const
|
||||||
|
{
|
||||||
|
QSettings settings(m_fileName, QSettings::IniFormat);
|
||||||
|
QString n = settings.value(QLatin1String(themeNameKey), QCoreApplication::tr("unnamed")).toString();
|
||||||
|
return m_readOnly ? QCoreApplication::tr("%1 (built-in)").arg(n) : n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ThemeListModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ThemeListModel(QObject *parent = 0):
|
||||||
|
QAbstractListModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return parent.isValid() ? 0 : m_themes.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
|
return m_themes.at(index.row()).name();
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeTheme(int index)
|
||||||
|
{
|
||||||
|
beginRemoveRows(QModelIndex(), index, index);
|
||||||
|
m_themes.removeAt(index);
|
||||||
|
endRemoveRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setThemes(const QList<ThemeEntry> &themes)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_themes = themes;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ThemeEntry &themeAt(int index) const
|
||||||
|
{
|
||||||
|
return m_themes.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<ThemeEntry> m_themes;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ThemeSettingsPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ThemeSettingsPrivate(QWidget *widget);
|
||||||
|
~ThemeSettingsPrivate();
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThemeListModel *m_themeListModel;
|
||||||
|
bool m_refreshingThemeList;
|
||||||
|
Ui::ThemeSettings *m_ui;
|
||||||
|
ThemeEntry m_currentTheme;
|
||||||
|
};
|
||||||
|
|
||||||
|
ThemeSettingsPrivate::ThemeSettingsPrivate(QWidget *widget)
|
||||||
|
: m_themeListModel(new ThemeListModel)
|
||||||
|
, m_refreshingThemeList(false)
|
||||||
|
, m_ui(new Ui::ThemeSettings)
|
||||||
|
{
|
||||||
|
m_currentTheme = ThemeEntry(creatorTheme()->fileName(), true);
|
||||||
|
m_ui->setupUi(widget);
|
||||||
|
m_ui->themeComboBox->setModel(m_themeListModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeSettingsPrivate::~ThemeSettingsPrivate()
|
||||||
|
{
|
||||||
|
delete m_themeListModel;
|
||||||
|
delete m_ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeSettingsWidget::ThemeSettingsWidget(QWidget *parent) :
|
||||||
|
QWidget(parent)
|
||||||
|
{
|
||||||
|
d = new ThemeSettingsPrivate(this);
|
||||||
|
|
||||||
|
connect(d->m_ui->themeComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||||
|
this, &ThemeSettingsWidget::themeSelected);
|
||||||
|
connect(d->m_ui->copyButton, &QAbstractButton::clicked, this, &ThemeSettingsWidget::copyTheme);
|
||||||
|
connect(d->m_ui->renameButton, &QAbstractButton::clicked, this, &ThemeSettingsWidget::renameTheme);
|
||||||
|
connect(d->m_ui->deleteButton, &QAbstractButton::clicked, this, &ThemeSettingsWidget::confirmDeleteTheme);
|
||||||
|
|
||||||
|
refreshThemeList();
|
||||||
|
}
|
||||||
|
|
||||||
|
ThemeSettingsWidget::~ThemeSettingsWidget()
|
||||||
|
{
|
||||||
|
delete d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::refreshThemeList()
|
||||||
|
{
|
||||||
|
QList<ThemeEntry> themes;
|
||||||
|
|
||||||
|
QString resourcePath = Core::ICore::resourcePath();
|
||||||
|
QDir themeDir(resourcePath + QLatin1String("/themes"));
|
||||||
|
themeDir.setNameFilters(QStringList() << QLatin1String("*.creatortheme"));
|
||||||
|
themeDir.setFilter(QDir::Files);
|
||||||
|
|
||||||
|
int selected = 0;
|
||||||
|
|
||||||
|
QStringList themeList = themeDir.entryList();
|
||||||
|
QString defaultTheme = QFileInfo(defaultThemeFileName()).fileName();
|
||||||
|
if (themeList.removeAll(defaultTheme))
|
||||||
|
themeList.prepend(defaultTheme);
|
||||||
|
foreach (const QString &file, themeList) {
|
||||||
|
const QString fileName = themeDir.absoluteFilePath(file);
|
||||||
|
if (d->m_currentTheme.fileName() == fileName)
|
||||||
|
selected = themes.size();
|
||||||
|
themes.append(ThemeEntry(fileName, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (themes.isEmpty())
|
||||||
|
qWarning() << "Warning: no themes found in path:" << themeDir.path();
|
||||||
|
|
||||||
|
themeDir.setPath(customThemesPath());
|
||||||
|
foreach (const QString &file, themeDir.entryList()) {
|
||||||
|
const QString fileName = themeDir.absoluteFilePath(file);
|
||||||
|
if (d->m_currentTheme.fileName() == fileName)
|
||||||
|
selected = themes.size();
|
||||||
|
themes.append(ThemeEntry(fileName, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
d->m_currentTheme = themes[selected];
|
||||||
|
|
||||||
|
d->m_refreshingThemeList = true;
|
||||||
|
d->m_themeListModel->setThemes(themes);
|
||||||
|
d->m_ui->themeComboBox->setCurrentIndex(selected);
|
||||||
|
d->m_refreshingThemeList = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString ThemeSettingsWidget::defaultThemeFileName(const QString &fileName)
|
||||||
|
{
|
||||||
|
QString defaultScheme = Core::ICore::resourcePath();
|
||||||
|
defaultScheme += QLatin1String("/themes/");
|
||||||
|
|
||||||
|
if (!fileName.isEmpty() && QFile::exists(defaultScheme + fileName))
|
||||||
|
defaultScheme += fileName;
|
||||||
|
else
|
||||||
|
defaultScheme += QLatin1String("default.creatortheme");
|
||||||
|
|
||||||
|
return defaultScheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::themeSelected(int index)
|
||||||
|
{
|
||||||
|
bool readOnly = true;
|
||||||
|
if (index != -1) {
|
||||||
|
// Check whether we're switching away from a changed theme
|
||||||
|
if (!d->m_refreshingThemeList)
|
||||||
|
maybeSaveTheme();
|
||||||
|
|
||||||
|
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
||||||
|
readOnly = entry.readOnly();
|
||||||
|
d->m_currentTheme = entry;
|
||||||
|
|
||||||
|
QSettings settings(entry.fileName(), QSettings::IniFormat);
|
||||||
|
Theme theme;
|
||||||
|
theme.readSettings(settings);
|
||||||
|
d->m_ui->editor->initFrom(&theme);
|
||||||
|
}
|
||||||
|
d->m_ui->copyButton->setEnabled(index != -1);
|
||||||
|
d->m_ui->deleteButton->setEnabled(!readOnly);
|
||||||
|
d->m_ui->renameButton->setEnabled(!readOnly);
|
||||||
|
d->m_ui->editor->setReadOnly(readOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::confirmDeleteTheme()
|
||||||
|
{
|
||||||
|
const int index = d->m_ui->themeComboBox->currentIndex();
|
||||||
|
if (index == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
||||||
|
if (entry.readOnly())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMessageBox *messageBox = new QMessageBox(QMessageBox::Warning,
|
||||||
|
tr("Delete Theme"),
|
||||||
|
tr("Are you sure you want to delete the theme '%1' permanently?").arg(entry.name()),
|
||||||
|
QMessageBox::Discard | QMessageBox::Cancel,
|
||||||
|
d->m_ui->deleteButton->window());
|
||||||
|
|
||||||
|
// Change the text and role of the discard button
|
||||||
|
QPushButton *deleteButton = static_cast<QPushButton*>(messageBox->button(QMessageBox::Discard));
|
||||||
|
deleteButton->setText(tr("Delete"));
|
||||||
|
messageBox->addButton(deleteButton, QMessageBox::AcceptRole);
|
||||||
|
messageBox->setDefaultButton(deleteButton);
|
||||||
|
|
||||||
|
connect(deleteButton, &QAbstractButton::clicked, messageBox, &QDialog::accept);
|
||||||
|
connect(messageBox, &QDialog::accepted, this, &ThemeSettingsWidget::deleteTheme);
|
||||||
|
messageBox->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
messageBox->open();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::deleteTheme()
|
||||||
|
{
|
||||||
|
const int index = d->m_ui->themeComboBox->currentIndex();
|
||||||
|
QTC_ASSERT(index != -1, return);
|
||||||
|
|
||||||
|
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
||||||
|
QTC_ASSERT(!entry.readOnly(), return);
|
||||||
|
|
||||||
|
if (QFile::remove(entry.fileName()))
|
||||||
|
d->m_themeListModel->removeTheme(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::copyTheme()
|
||||||
|
{
|
||||||
|
QInputDialog *dialog = new QInputDialog(d->m_ui->copyButton->window());
|
||||||
|
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||||
|
dialog->setInputMode(QInputDialog::TextInput);
|
||||||
|
dialog->setWindowTitle(tr("Copy Theme"));
|
||||||
|
dialog->setLabelText(tr("Theme name:"));
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
//dialog->setTextValue(tr("%1 (copy)").arg(d_ptr->m_value.colorScheme().displayName()));
|
||||||
|
|
||||||
|
connect(dialog, &QInputDialog::textValueSelected, this, &ThemeSettingsWidget::copyThemeByName);
|
||||||
|
dialog->open();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::maybeSaveTheme()
|
||||||
|
{
|
||||||
|
if (!d->m_ui->editor->model()->hasChanges())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QMessageBox *messageBox = new QMessageBox(QMessageBox::Warning,
|
||||||
|
tr("Theme Changed"),
|
||||||
|
tr("The theme \"%1\" was modified, do you want to save the changes?")
|
||||||
|
.arg(d->m_currentTheme.name()),
|
||||||
|
QMessageBox::Discard | QMessageBox::Save,
|
||||||
|
d->m_ui->themeComboBox->window());
|
||||||
|
|
||||||
|
// Change the text of the discard button
|
||||||
|
QPushButton *discardButton = static_cast<QPushButton*>(messageBox->button(QMessageBox::Discard));
|
||||||
|
discardButton->setText(tr("Discard"));
|
||||||
|
messageBox->addButton(discardButton, QMessageBox::DestructiveRole);
|
||||||
|
messageBox->setDefaultButton(QMessageBox::Save);
|
||||||
|
|
||||||
|
if (messageBox->exec() == QMessageBox::Save) {
|
||||||
|
Theme newTheme;
|
||||||
|
d->m_ui->editor->model()->toTheme(&newTheme);
|
||||||
|
newTheme.writeSettings(d->m_currentTheme.fileName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::renameTheme()
|
||||||
|
{
|
||||||
|
int index = d->m_ui->themeComboBox->currentIndex();
|
||||||
|
if (index == -1)
|
||||||
|
return;
|
||||||
|
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
||||||
|
|
||||||
|
maybeSaveTheme();
|
||||||
|
|
||||||
|
QInputDialog *dialog = new QInputDialog(d->m_ui->renameButton->window());
|
||||||
|
dialog->setInputMode(QInputDialog::TextInput);
|
||||||
|
dialog->setWindowTitle(tr("Rename Theme"));
|
||||||
|
dialog->setLabelText(tr("Theme name:"));
|
||||||
|
dialog->setTextValue(d->m_ui->editor->model()->m_name);
|
||||||
|
int ret = dialog->exec();
|
||||||
|
QString newName = dialog->textValue();
|
||||||
|
delete dialog;
|
||||||
|
|
||||||
|
if (ret != QDialog::Accepted || newName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// overwrite file with new name
|
||||||
|
Theme newTheme;
|
||||||
|
d->m_ui->editor->model()->toTheme(&newTheme);
|
||||||
|
newTheme.setName(newName);
|
||||||
|
newTheme.writeSettings(entry.fileName());
|
||||||
|
|
||||||
|
refreshThemeList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::copyThemeByName(const QString &name)
|
||||||
|
{
|
||||||
|
int index = d->m_ui->themeComboBox->currentIndex();
|
||||||
|
if (index == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const ThemeEntry &entry = d->m_themeListModel->themeAt(index);
|
||||||
|
|
||||||
|
QString baseFileName = QFileInfo(entry.fileName()).completeBaseName();
|
||||||
|
baseFileName += QLatin1String("_copy%1.creatortheme");
|
||||||
|
QString fileName = createThemeFileName(baseFileName);
|
||||||
|
|
||||||
|
if (fileName.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Ask about saving any existing modifactions
|
||||||
|
maybeSaveTheme();
|
||||||
|
|
||||||
|
Theme newTheme;
|
||||||
|
d->m_ui->editor->model()->toTheme(&newTheme);
|
||||||
|
newTheme.setName(name);
|
||||||
|
newTheme.writeSettings(fileName);
|
||||||
|
|
||||||
|
d->m_currentTheme = ThemeEntry(fileName, true);
|
||||||
|
|
||||||
|
refreshThemeList();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThemeSettingsWidget::apply()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
d->m_ui->editor->model()->toTheme(creatorTheme());
|
||||||
|
if (creatorTheme()->flag(Theme::ApplyThemePaletteGlobally))
|
||||||
|
QApplication::setPalette(creatorTheme()->palette(QApplication::palette()));
|
||||||
|
foreach (QWidget *w, QApplication::topLevelWidgets())
|
||||||
|
w->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
// save definition of theme
|
||||||
|
if (!d->m_currentTheme.readOnly()) {
|
||||||
|
Theme newTheme;
|
||||||
|
d->m_ui->editor->model()->toTheme(&newTheme);
|
||||||
|
newTheme.writeSettings(d->m_currentTheme.fileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// save filename of selected theme in global config
|
||||||
|
QSettings *settings = Core::ICore::settings();
|
||||||
|
settings->setValue(QLatin1String(Core::Constants::SETTINGS_THEME), d->m_currentTheme.fileName());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Core
|
||||||
70
src/plugins/coreplugin/themesettingswidget.h
Normal file
70
src/plugins/coreplugin/themesettingswidget.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Thorben Kroeger <thorbenkroeger@gmail.com>.
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Digia. For licensing terms and
|
||||||
|
** conditions see http://www.qt.io/licensing. For further information
|
||||||
|
** use the contact form at http://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU Lesser General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||||
|
** General Public License version 2.1 or version 3 as published by the Free
|
||||||
|
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||||
|
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||||
|
** following information to ensure the GNU Lesser General Public License
|
||||||
|
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||||
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef THEMESETTINGSWIDGET_H
|
||||||
|
#define THEMESETTINGSWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class ThemeSettingsPrivate;
|
||||||
|
|
||||||
|
class ThemeSettingsWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ThemeSettingsWidget(QWidget *parent = 0);
|
||||||
|
~ThemeSettingsWidget();
|
||||||
|
|
||||||
|
static QString defaultThemeFileName(const QString &fileName = QString());
|
||||||
|
|
||||||
|
void apply();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void themeSelected(int index);
|
||||||
|
void copyTheme();
|
||||||
|
void renameTheme();
|
||||||
|
void copyThemeByName(const QString &);
|
||||||
|
void confirmDeleteTheme();
|
||||||
|
void deleteTheme();
|
||||||
|
void maybeSaveTheme();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void refreshThemeList();
|
||||||
|
ThemeSettingsPrivate *d;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Core
|
||||||
|
|
||||||
|
#endif // THEMESETTINGSWIDGET_H
|
||||||
Reference in New Issue
Block a user