Removing the ThemeEditor

The Theme editor is a feature which was present but disabled since the
introduction of Themes. It is still unfinished and unlikely to be
finished.

An alternative, cheaper approch could be installing a file watcher
on a theme file, and reloading it on any change. But for that we
would still need proper theme switching during runtime.

Change-Id: Ifd44e8c25c924a8f021618d20ce126648a3558a3
Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@theqtcompany.com>
This commit is contained in:
Alessandro Portale
2016-01-11 17:53:18 +01:00
parent 4255493881
commit 9573ead443
26 changed files with 20 additions and 2087 deletions

View File

@@ -178,91 +178,6 @@ static QColor readColor(const QString &color)
return QColor::fromRgba(rgba); return QColor::fromRgba(rgba);
} }
static QString writeColor(const QColor &color)
{
return QString::number(color.rgba(), 16);
}
// reading, writing of .creatortheme ini file ////////////////////////////////
void Theme::writeSettings(const QString &filename) const
{
QSettings settings(filename, QSettings::IniFormat);
const QMetaObject &m = *metaObject();
{
settings.setValue(QLatin1String("ThemeName"), d->displayName);
settings.setValue(QLatin1String("PreferredStyles"), d->preferredStyles);
}
{
settings.beginGroup(QLatin1String("Palette"));
for (int i = 0, total = d->colors.size(); i < total; ++i) {
const QPair<QColor, QString> var = d->colors[i];
if (var.second.isEmpty())
continue;
settings.setValue(var.second, writeColor(var.first));
}
settings.endGroup();
}
{
settings.beginGroup(QLatin1String("Colors"));
const QMetaEnum e = m.enumerator(m.indexOfEnumerator("Color"));
for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i));
const QPair<QColor, QString> var = d->colors[i];
if (!var.second.isEmpty())
settings.setValue(key, var.second); // named color
else
settings.setValue(key, writeColor(var.first));
}
settings.endGroup();
}
{
settings.beginGroup(QLatin1String("ImageFiles"));
const QMetaEnum e = m.enumerator(m.indexOfEnumerator("ImageFile"));
for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i));
const QString &var = d->imageFiles.at(i);
if (!var.isEmpty())
settings.setValue(key, var);
}
settings.endGroup();
}
{
settings.beginGroup(QLatin1String("Gradients"));
const QMetaEnum e = m.enumerator(m.indexOfEnumerator("Gradient"));
for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i));
QGradientStops stops = gradient(static_cast<Theme::Gradient>(i));
settings.beginWriteArray(key);
int k = 0;
foreach (const QGradientStop stop, stops) {
settings.setArrayIndex(k);
settings.setValue(QLatin1String("pos"), stop.first);
settings.setValue(QLatin1String("color"), writeColor(stop.second));
++k;
}
settings.endArray();
}
settings.endGroup();
}
{
settings.beginGroup(QLatin1String("Flags"));
const QMetaEnum e = m.enumerator(m.indexOfEnumerator("Flag"));
for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i));
settings.setValue(key, flag(static_cast<Theme::Flag>(i)));
}
settings.endGroup();
}
{
settings.beginGroup(QLatin1String("Style"));
const QMetaEnum e = m.enumerator(m.indexOfEnumerator("WidgetStyle"));
settings.setValue(QLatin1String("WidgetStyle"), QLatin1String(e.valueToKey(widgetStyle ())));
settings.endGroup();
}
}
void Theme::readSettings(QSettings &settings) void Theme::readSettings(QSettings &settings)
{ {
d->fileName = settings.fileName(); d->fileName = settings.fileName();

View File

@@ -287,7 +287,6 @@ public:
QVariantHash values() const; QVariantHash values() const;
void writeSettings(const QString &filename) const;
void readSettings(QSettings &settings); void readSettings(QSettings &settings);
static QPalette initialPalette(); static QPalette initialPalette();

View File

@@ -105,14 +105,6 @@ SOURCES += corejsextensions.cpp \
patchtool.cpp \ patchtool.cpp \
windowsupport.cpp \ windowsupport.cpp \
opendocumentstreeview.cpp \ opendocumentstreeview.cpp \
themeeditor/themecolors.cpp \
themeeditor/themecolorstableview.cpp \
themeeditor/colorvariable.cpp \
themeeditor/themeeditorwidget.cpp \
themeeditor/colorrole.cpp \
themeeditor/themesettingstablemodel.cpp \
themeeditor/sectionedtablemodel.cpp \
themeeditor/themesettingsitemdelegate.cpp \
messagebox.cpp \ messagebox.cpp \
iwelcomepage.cpp \ iwelcomepage.cpp \
externaltoolmanager.cpp \ externaltoolmanager.cpp \
@@ -222,14 +214,6 @@ HEADERS += corejsextensions.h \
patchtool.h \ patchtool.h \
windowsupport.h \ windowsupport.h \
opendocumentstreeview.h \ opendocumentstreeview.h \
themeeditor/themecolors.h \
themeeditor/themecolorstableview.h \
themeeditor/colorvariable.h \
themeeditor/themeeditorwidget.h \
themeeditor/colorrole.h \
themeeditor/themesettingstablemodel.h \
themeeditor/sectionedtablemodel.h \
themeeditor/themesettingsitemdelegate.h \
messagebox.h \ messagebox.h \
iwelcomepage.h \ iwelcomepage.h \
systemsettings.h \ systemsettings.h \
@@ -246,7 +230,6 @@ FORMS += dialogs/newdialog.ui \
mimetypemagicdialog.ui \ mimetypemagicdialog.ui \
removefiledialog.ui \ removefiledialog.ui \
dialogs/addtovcsdialog.ui \ dialogs/addtovcsdialog.ui \
themeeditor/themeeditorwidget.ui \
systemsettings.ui systemsettings.ui
RESOURCES += core.qrc \ RESOURCES += core.qrc \

View File

@@ -300,30 +300,6 @@ QtcPlugin {
] ]
} }
Group {
name: "ThemeEditor"
prefix: "themeeditor/"
files: [
"colorrole.cpp",
"colorrole.h",
"colorvariable.cpp",
"colorvariable.h",
"sectionedtablemodel.cpp",
"sectionedtablemodel.h",
"themecolors.cpp",
"themecolors.h",
"themecolorstableview.cpp",
"themecolorstableview.h",
"themeeditorwidget.cpp",
"themeeditorwidget.h",
"themeeditorwidget.ui",
"themesettingsitemdelegate.cpp",
"themesettingsitemdelegate.h",
"themesettingstablemodel.cpp",
"themesettingstablemodel.h",
]
}
Export { Export {
Depends { name: "Aggregation" } Depends { name: "Aggregation" }
Depends { name: "Utils" } Depends { name: "Utils" }

View File

@@ -1,58 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "colorrole.h"
#include "colorvariable.h"
namespace Core {
namespace Internal {
namespace ThemeEditor {
ColorRole::ColorRole(const QString &roleName, QSharedPointer<ColorVariable> colorVariable)
: m_roleName(roleName),
m_roleVariable(colorVariable)
{
m_roleVariable->addReference(this);
}
QSharedPointer<ColorVariable> ColorRole::colorVariable() const
{
return m_roleVariable;
}
void ColorRole::assignColorVariable(ColorVariable::Ptr namedColor)
{
namedColor->addReference(this);
m_roleVariable = namedColor;
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -1,67 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef COLORROLE_H
#define COLORROLE_H
#include <QString>
#include <QColor>
#include <QSharedPointer>
namespace Core {
namespace Internal {
namespace ThemeEditor {
class ColorVariable;
class ThemeColors;
class ColorRole
{
public:
friend class ThemeColors;
typedef QSharedPointer<ColorRole> Ptr;
QString roleName() const { return m_roleName; }
QSharedPointer<ColorVariable> colorVariable() const;
void assignColorVariable(QSharedPointer<ColorVariable> colorVariable);
private:
explicit ColorRole(const QString &roleName, QSharedPointer<ColorVariable> colorVariable);
QString m_roleName;
QString m_roleDescription;
QSharedPointer<ColorVariable> m_roleVariable;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // COLORROLE_H

View File

@@ -1,73 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "colorvariable.h"
#include "colorrole.h"
#include <utils/qtcassert.h>
namespace Core {
namespace Internal {
namespace ThemeEditor {
ColorVariable::ColorVariable(const QColor &color, const QString &name)
: m_variableValue(color)
, m_variableName(name)
{
}
ColorVariable::~ColorVariable()
{
}
void ColorVariable::setColor(const QColor &newColor)
{
m_variableValue = newColor;
}
void ColorVariable::addReference(ColorRole *t)
{
m_references.insert(t);
}
void ColorVariable::removeReference(ColorRole *t)
{
QTC_ASSERT(m_references.contains(t), return);
m_references.remove(t);
}
QSet<ColorRole *> ColorVariable::references() const
{
return m_references;
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -1,77 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef COLORVARIABLE_H
#define COLORVARIABLE_H
#include <QSharedPointer>
#include <QColor>
#include <QString>
#include <QSet>
namespace Core {
namespace Internal {
namespace ThemeEditor {
class ColorRole;
class ThemeColors;
class ColorVariable
{
public:
friend class ThemeColors;
typedef QSharedPointer<ColorVariable> Ptr;
~ColorVariable();
// name of this variable
QString variableName() const { return m_variableName; }
// value of this variable
QColor color() const { return m_variableValue; }
void setColor(const QColor &color);
// which theme colors are referencing this variable?
void addReference(ColorRole *t);
void removeReference(ColorRole *t);
QSet<ColorRole *> references() const;
private:
explicit ColorVariable(const QColor &color, const QString &variableName = QString());
QColor m_variableValue;
QString m_variableName;
QSet<ColorRole *> m_references;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // COLORVARIABLE_H

View File

@@ -1,124 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "sectionedtablemodel.h"
#include <QSize>
namespace Core {
namespace Internal {
namespace ThemeEditor {
SectionedTableModel::SectionedTableModel(QObject *parent) :
QAbstractTableModel(parent)
{
}
int SectionedTableModel::sectionHeader(int row) const
{
int currRow = 0;
int i = 0;
do {
if (row == currRow)
return i;
currRow += sectionRowCount(i) + 1; //account for next header
++i;
} while (i < sectionCount());
return -1;
}
int SectionedTableModel::inSectionBody(int row) const
{
int currRow = 0;
int i = 0;
do {
++currRow;
if (row >= currRow && row < currRow + sectionRowCount(i))
return i;
currRow += sectionRowCount(i);
++i;
} while (i < sectionCount());
return -1;
}
int SectionedTableModel::modelToSectionRow(int row) const
{
int currRow = 0;
for (int i = 0; i < sectionCount(); ++i) {
++currRow;
if (row >= currRow && row < currRow + sectionRowCount(i))
return row-currRow;
currRow += sectionRowCount(i);
}
return row;
}
QSize SectionedTableModel::span(const QModelIndex &index) const
{
if (sectionHeader(index.row()) >= 0 && index.column() == 0)
return QSize(1, columnCount(index));
return QSize(1, 1);
}
int SectionedTableModel::rowCount(const QModelIndex &index) const
{
if (index.isValid())
return 0;
int r = 0;
for (int i = 0; i < sectionCount(); ++i)
r += sectionRowCount(i) + 1;
return r;
}
QVariant SectionedTableModel::data(const QModelIndex &index, int role) const
{
int header = sectionHeader(index.row());
if (header >= 0)
return (index.column() == 0) ? sectionHeaderData(header, role)
: QVariant(QString());
return sectionBodyData(inSectionBody(index.row()),
modelToSectionRow(index.row()),
index.column(),
role);
}
Qt::ItemFlags SectionedTableModel::flags(const QModelIndex &index) const
{
if (int h = sectionHeader(index.row()) >= 0)
return sectionHeaderFlags(h);
return sectionBodyFlags(inSectionBody(index.row()),
modelToSectionRow(index.row()),
index.column());
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -1,69 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef SECTIONEDTABLEMODEL_H
#define SECTIONEDTABLEMODEL_H
#include <QAbstractTableModel>
namespace Core {
namespace Internal {
namespace ThemeEditor {
class SectionedTableModel : public QAbstractTableModel
{
Q_OBJECT
public:
explicit SectionedTableModel(QObject *parent = 0);
virtual int sectionRowCount(int section) const = 0;
virtual QVariant sectionBodyData(int section, int row, int column, int role) const = 0;
virtual QVariant sectionHeaderData(int section, int role) const = 0;
virtual Qt::ItemFlags sectionBodyFlags(int section, int row, int column) const = 0;
virtual Qt::ItemFlags sectionHeaderFlags(int section) const = 0;
virtual int sectionCount() const = 0;
QSize span(const QModelIndex &index) const override;
int inSectionBody(int row) const;
int modelToSectionRow(int row) const;
int sectionHeader(int row) const;
protected:
int rowCount(const QModelIndex &index) const override;
QVariant data(const QModelIndex &index, int role) const override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // SECTIONEDTABLEMODEL_H

View File

@@ -1,76 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "themecolors.h"
#include "colorvariable.h"
#include <utils/qtcassert.h>
namespace Core {
namespace Internal {
namespace ThemeEditor {
QSharedPointer<ColorVariable> ThemeColors::createVariable(const QColor &variableColor, const QString &variableName)
{
ColorVariable::Ptr var(new ColorVariable(variableColor, variableName));
insert(var);
return var;
}
ColorRole::Ptr ThemeColors::createRole(const QString &roleName, QSharedPointer<ColorVariable> colorVariable)
{
ColorRole::Ptr role(new ColorRole(roleName, colorVariable));
insert(role);
return role;
}
void ThemeColors::insert(ColorRole::Ptr color)
{
m_colorRoles.append(color);
}
void ThemeColors::insert(ColorVariable::Ptr color)
{
m_colorVariables.insert(color);
}
QSet<QSharedPointer<ColorVariable> > ThemeColors::colorVariables()
{
return m_colorVariables;
}
void ThemeColors::removeVariable(QSharedPointer<ColorVariable> variable)
{
QTC_ASSERT(m_colorVariables.contains(variable), return);
m_colorVariables.remove(variable);
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -1,71 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef THEMECOLORS_H
#define THEMECOLORS_H
#include "colorrole.h"
#include <QSet>
namespace Core {
namespace Internal {
namespace ThemeEditor {
class ColorVariable;
class ThemeColors
{
public:
typedef QSharedPointer<ThemeColors> Ptr;
int numColorRoles() const { return m_colorRoles.size(); }
ColorRole::Ptr const colorRole(int index) { return m_colorRoles.at(index); }
QSharedPointer<ColorVariable> createVariable(const QColor &variableColor, const QString &variableName = QString());
ColorRole::Ptr createRole(const QString &roleName, QSharedPointer<ColorVariable> colorVariable);
QSet<QSharedPointer<ColorVariable> > colorVariables();
void removeVariable(QSharedPointer<ColorVariable> variable);
private:
void insert(ColorRole::Ptr color);
void insert(QSharedPointer<ColorVariable> color);
QList<ColorRole::Ptr> m_colorRoles;
QSet<QSharedPointer<ColorVariable> > m_colorVariables;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // THEMECOLORS_H

View File

@@ -1,62 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "themecolorstableview.h"
#include "themesettingsitemdelegate.h"
#include "themesettingstablemodel.h"
#include <QMouseEvent>
namespace Core {
namespace Internal {
namespace ThemeEditor {
ThemeColorsTableView::ThemeColorsTableView(QWidget *parent)
: QTreeView(parent)
{
}
void ThemeColorsTableView::mousePressEvent(QMouseEvent *event)
{
if ((editTriggers() & NoEditTriggers) && (event->button() == Qt::LeftButton)) {
QModelIndex index = indexAt(event->pos());
if (model()->flags(index) & Qt::ItemIsEditable && index.column() == 1) {
setCurrentIndex(index);
edit(index);
// TODO: only applies to editing colors
static_cast<ThemeSettingsItemDelegate *>(itemDelegate())->popupMenu();
}
}
QTreeView::mousePressEvent(event);
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -1,55 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef THEMECOLORSTABLEVIEW_H
#define THEMECOLORSTABLEVIEW_H
#include <QTreeView>
namespace Core {
namespace Internal {
namespace ThemeEditor {
class ThemeColorsTableView : public QTreeView
{
Q_OBJECT
public:
ThemeColorsTableView(QWidget *parent = 0);
protected:
void mousePressEvent(QMouseEvent *event);
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // THEMECOLORSTABLEVIEW_H

View File

@@ -1,146 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "themeeditorwidget.h"
#include "ui_themeeditorwidget.h"
#include "colorvariable.h"
#include "colorrole.h"
#include "themecolors.h"
#include "themesettingstablemodel.h"
#include "themesettingsitemdelegate.h"
#include <QAbstractButton>
#include <QAbstractItemModel>
#include <QColorDialog>
#include <QDir>
#include <QFileInfo>
#include <QMetaEnum>
#include <QSortFilterProxyModel>
#include <QTimer>
#include <QSharedPointer>
#include <QWeakPointer>
namespace Core {
namespace Internal {
namespace ThemeEditor {
ThemeEditorWidget::ThemeEditorWidget(QWidget *parent) :
QWidget(parent),
m_ui(new Ui::ThemeEditorWidget),
m_readOnly(false),
m_model(0)
{
m_ui->setupUi(this);
m_proxyModel = new QSortFilterProxyModel(this);
m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
m_proxyModel->setFilterKeyColumn(0);
m_ui->tableView->setModel(m_proxyModel);
ThemeSettingsItemDelegate *cbid = new ThemeSettingsItemDelegate(this);
m_ui->tableView->setItemDelegate(cbid);
connect(m_ui->filter, &QLineEdit::textChanged, m_proxyModel,
static_cast<void (QSortFilterProxyModel:: *)(const QString &)>(&QSortFilterProxyModel::setFilterRegExp));
connect(m_ui->tableView, &QAbstractItemView::doubleClicked, this, &ThemeEditorWidget::changeColor);
}
ThemeEditorWidget::~ThemeEditorWidget()
{
delete m_ui;
}
void ThemeEditorWidget::changeColor(const QModelIndex &index)
{
if (!(m_ui->tableView->editTriggers() & QAbstractItemView::DoubleClicked))
return;
if (m_model->inSectionBody(index.row()) != ThemeSettingsTableModel::SectionColors)
return;
if (index.column() == 1)
return;
int row = m_model->modelToSectionRow(index.row());
ColorRole::Ptr themeColor = m_model->colors()->colorRole(row);
QColor currentColor = themeColor->colorVariable()->color();
// FIXME: 'currentColor' is correct, but QColorDialog won't show
// it as the correct initial color. Why?
QColorDialog dlg(this);
dlg.setOption(QColorDialog::ShowAlphaChannel);
dlg.setCurrentColor(currentColor);
const int customCount = QColorDialog::customCount();
for (int i = 0; i < customCount; ++i)
QColorDialog::setCustomColor(i, Qt::transparent); // invalid
int i = 0;
foreach (ColorVariable::Ptr namedColor, m_model->colors()->colorVariables())
QColorDialog::setCustomColor(i++, namedColor->color().toRgb());
int ret = dlg.exec();
if (ret == QDialog::Accepted) {
themeColor->colorVariable()->setColor(dlg.currentColor());
m_model->markEverythingChanged();
}
}
void ThemeEditorWidget::setReadOnly(bool readOnly)
{
m_readOnly = readOnly;
m_ui->tableView->setEditTriggers(
readOnly ? QAbstractItemView::NoEditTriggers
: QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
m_ui->filter->setEnabled(!readOnly);
}
void ThemeEditorWidget::initFrom(Utils::Theme *theme)
{
if (m_model) {
m_model->setParent(0);
delete m_model;
}
m_model = new ThemeSettingsTableModel(this);
m_model->initFrom(theme);
m_proxyModel->setSourceModel(m_model);
m_ui->tableView->setColumnWidth(0, 400);
m_ui->tableView->setColumnWidth(1, 300);
}
ThemeSettingsTableModel *ThemeEditorWidget::model()
{
return m_model;
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -1,78 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef THEMEEDITORWIDGET_H
#define THEMEEDITORWIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
class QSortFilterProxyModel;
QT_END_NAMESPACE
namespace Utils { class Theme; }
namespace Core {
namespace Internal {
namespace ThemeEditor {
namespace Ui { class ThemeEditorWidget; }
class ThemeSettingsTableModel;
class ThemeEditorWidget : public QWidget
{
Q_OBJECT
public:
explicit ThemeEditorWidget(QWidget *parent = 0);
~ThemeEditorWidget();
void initFrom(Utils::Theme *theme);
ThemeSettingsTableModel *model();
void setReadOnly(bool readOnly);
private slots:
void changeColor(const QModelIndex &index);
private:
Ui::ThemeEditorWidget *m_ui;
bool m_readOnly;
ThemeSettingsTableModel *m_model;
QSortFilterProxyModel *m_proxyModel;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // THEMEEDITORWIDGET_H

View File

@@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Core::Internal::ThemeEditor::ThemeEditorWidget</class>
<widget class="QWidget" name="Core::Internal::ThemeEditor::ThemeEditorWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Theme Editor</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Filter:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="filter"/>
</item>
</layout>
</item>
<item>
<widget class="Core::Internal::ThemeEditor::ThemeColorsTableView" name="tableView"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Core::Internal::ThemeEditor::ThemeColorsTableView</class>
<extends>QTableView</extends>
<header location="global">coreplugin/themeeditor/themecolorstableview.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -1,220 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "themesettingsitemdelegate.h"
#include "colorvariable.h"
#include "themesettingstablemodel.h"
#include <utils/qtcassert.h>
#include <utils/theme/theme.h>
#include <QAbstractProxyModel>
#include <QComboBox>
#include <QEvent>
#include <QInputDialog>
#include <QMetaEnum>
using namespace Utils;
static QAbstractItemModel *sourceModel(QAbstractItemModel *model)
{
if (QAbstractProxyModel *m = qobject_cast<QAbstractProxyModel *>(model))
return m->sourceModel();
return model;
}
static const QAbstractItemModel *sourceModel(const QAbstractItemModel *model)
{
if (const QAbstractProxyModel *m = qobject_cast<const QAbstractProxyModel *>(model))
return m->sourceModel();
return model;
}
static QIcon makeIcon(const QColor &color)
{
QImage img(QSize(24,24), QImage::Format_ARGB32);
img.fill(color.rgba());
QIcon ico = QIcon(QPixmap::fromImage(img));
return ico;
}
namespace Core {
namespace Internal {
namespace ThemeEditor {
ThemeSettingsItemDelegate::ThemeSettingsItemDelegate(QObject *parent)
: QStyledItemDelegate(parent),
m_comboBox(0)
{
}
QWidget *ThemeSettingsItemDelegate::createColorEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
const ThemeSettingsTableModel *model = qobject_cast<const ThemeSettingsTableModel*>(sourceModel(index.model()));
Q_UNUSED(option);
const int row = model->modelToSectionRow(index.row());
QComboBox *cb = new QComboBox(parent);
ColorRole::Ptr colorRole = model->m_colors->colorRole(row);
const bool isUnnamed = colorRole->colorVariable()->variableName().isEmpty();
const QColor currentColor = colorRole->colorVariable()->color();
cb->addItem(makeIcon(currentColor),
isUnnamed ? tr("<Unnamed> (Current)")
: colorRole->colorVariable()->variableName() + tr(" (Current)"));
int k = 1;
foreach (ColorVariable::Ptr namedColor, model->m_colors->colorVariables()) {
if (namedColor->variableName().isEmpty())
continue;
if (colorRole->colorVariable() == namedColor) {
continue;
} else {
cb->addItem(makeIcon(namedColor->color()), namedColor->variableName());
m_actions[k++] = qMakePair(Action_ChooseNamedColor, namedColor);
}
}
if (!isUnnamed) {
cb->addItem(tr("Remove Variable Name"));
m_actions[k++] = qMakePair(Action_MakeUnnamed, QSharedPointer<ColorVariable>(0));
}
cb->addItem(tr("Add Variable Name..."));
m_actions[k++] = qMakePair(Action_CreateNew, QSharedPointer<ColorVariable>(0));
connect(cb, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
this, [this, cb]() {
ThemeSettingsItemDelegate *me = const_cast<ThemeSettingsItemDelegate *>(this);
emit me->commitData(cb);
emit me->closeEditor(cb);
});
m_comboBox = cb;
return cb;
}
QWidget *ThemeSettingsItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
const ThemeSettingsTableModel *model = qobject_cast<const ThemeSettingsTableModel*>(sourceModel(index.model()));
const int section = model->inSectionBody(index.row());
QTC_ASSERT(section >= 0, return 0);
switch (section) {
case ThemeSettingsTableModel::SectionWidgetStyle: {
QComboBox *cb = new QComboBox(parent);
QMetaEnum e = Theme::staticMetaObject.enumerator(Theme::staticMetaObject.indexOfEnumerator("WidgetStyle"));
for (int i = 0, total = e.keyCount(); i < total; ++i)
cb->addItem(QLatin1String(e.key(i)));
cb->setCurrentIndex(model->m_widgetStyle);
connect(cb, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
this, [this, cb]() {
ThemeSettingsItemDelegate *me = const_cast<ThemeSettingsItemDelegate *>(this);
emit me->commitData(cb);
emit me->closeEditor(cb);
});
m_comboBox = cb;
return cb;
}
case ThemeSettingsTableModel::SectionColors:
return createColorEditor(parent, option, index);
case ThemeSettingsTableModel::SectionFlags:
return QStyledItemDelegate::createEditor(parent, option, index);
default:
qWarning("unhandled section");
return 0;
} // switch
}
void ThemeSettingsItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QStyledItemDelegate::setEditorData(editor, index);
}
void ThemeSettingsItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
ThemeSettingsTableModel *themeSettingsModel = qobject_cast<ThemeSettingsTableModel *>(sourceModel(model));
const int row = themeSettingsModel->modelToSectionRow(index.row());
const int section = themeSettingsModel->inSectionBody(index.row());
switch (section) {
case ThemeSettingsTableModel::SectionWidgetStyle:
if (QComboBox *cb = qobject_cast<QComboBox *>(editor))
themeSettingsModel->m_widgetStyle = static_cast<Theme::WidgetStyle>(cb->currentIndex());
return;
case ThemeSettingsTableModel::SectionColors: {
if (QComboBox *cb = qobject_cast<QComboBox *>(editor)) {
ColorRole::Ptr themeColor = themeSettingsModel->m_colors->colorRole(row);
Action act = m_actions[cb->currentIndex()].first;
ColorVariable::Ptr previousVariable = themeColor->colorVariable();
ColorVariable::Ptr newVariable = m_actions[cb->currentIndex()].second;
if (act == Action_NoAction) {
return;
} else if (act == Action_ChooseNamedColor) {
previousVariable->removeReference(themeColor.data());
QTC_ASSERT(newVariable, return);
themeColor->assignColorVariable(newVariable);
} else if (act == Action_MakeUnnamed) {
previousVariable->removeReference(themeColor.data());
if (previousVariable->references().size() == 0)
themeSettingsModel->m_colors->removeVariable(previousVariable);
ColorVariable::Ptr anonymousColor = themeSettingsModel->m_colors->createVariable(previousVariable->color());
themeColor->assignColorVariable(anonymousColor);
} else if (act == Action_CreateNew) {
QString name = QInputDialog::getText(editor, tr("Add Variable Name"), tr("Variable name:"));
if (!name.isEmpty()) {
previousVariable->removeReference(themeColor.data());
// TODO: check for name collision
ColorVariable::Ptr newVariable = themeSettingsModel->m_colors->createVariable(previousVariable->color(), name);
themeColor->assignColorVariable(newVariable);
}
}
}
return;
}
default:
return QStyledItemDelegate::setModelData(editor, model, index);
}
}
void ThemeSettingsItemDelegate::popupMenu()
{
m_comboBox->showPopup();
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -1,78 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef THEMESETTINGSITEMDELEGATE_H
#define THEMESETTINGSITEMDELEGATE_H
#include "themecolors.h"
#include "colorvariable.h"
#include <QStyledItemDelegate>
QT_BEGIN_NAMESPACE
class QComboBox;
QT_END_NAMESPACE
namespace Core {
namespace Internal {
namespace ThemeEditor {
class ThemeSettingsItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
enum Action {
Action_NoAction,
Action_ChooseNamedColor,
Action_MakeUnnamed,
Action_CreateNew
};
public:
ThemeSettingsItemDelegate(QObject *parent);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
void popupMenu();
private:
QWidget *createColorEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
mutable QMap<int, QPair<Action, ColorVariable::Ptr> > m_actions;
mutable QComboBox *m_comboBox;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // THEMESETTINGSITEMDELEGATE_H

View File

@@ -1,284 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "themesettingstablemodel.h"
#include "colorvariable.h"
#include <utils/qtcassert.h>
#include <utils/theme/theme.h>
#include <utils/theme/theme_p.h>
#include <QApplication>
#include <QImage>
#include <QMetaEnum>
#include <QPainter>
#include <QPalette>
using namespace Utils;
namespace Core {
namespace Internal {
namespace ThemeEditor {
ThemeSettingsTableModel::ThemeSettingsTableModel(QObject *parent)
: SectionedTableModel(parent),
m_colors(new ThemeColors),
m_hasChanges(false)
{
}
int ThemeSettingsTableModel::columnCount(const QModelIndex &index) const
{
Q_UNUSED(index);
return 2;
}
int ThemeSettingsTableModel::sectionRowCount(int section) const
{
switch (static_cast<Section>(section)) {
case SectionWidgetStyle: return 1;
case SectionColors: return m_colors->numColorRoles();
case SectionFlags: return m_flags.size();
default: return 0;
}
}
QVariant ThemeSettingsTableModel::sectionBodyData(int section, int row, int column, int role) const
{
auto makeDecoration = [](const QColor &c) -> QImage {
QImage img(QSize(32,32), QImage::Format_ARGB32);
img.fill(Qt::transparent);
QPainter p(&img);
p.fillRect(QRect(4,4,24,24), c);
return img;
};
switch (static_cast<Section>(section)) {
case SectionWidgetStyle: {
if (role != Qt::DisplayRole)
return QVariant();
if (column == 0)
return QLatin1String("WidgetStyle");
else
return m_widgetStyle == Theme::StyleFlat ? QLatin1String("StyleFlat") : QLatin1String("StyleDefault");
}
case SectionColors: {
ColorRole::Ptr colorRole = m_colors->colorRole(row);
if (column == 0 && role == Qt::DecorationRole)
return QVariant::fromValue(makeDecoration(colorRole->colorVariable()->color()));
if (role == Qt::DisplayRole) {
if (column == 0)
return colorRole->roleName();
else
return colorRole->colorVariable()->variableName();
}
return QVariant();
}
case SectionFlags: {
if (column == 0 && role == Qt::DisplayRole)
return m_flags[row].first;
else if (column == 1 && role == Qt::CheckStateRole)
return m_flags[row].second ? Qt::Checked : Qt::Unchecked;
else if (column == 0 && role == Qt::DecorationRole)
return QVariant::fromValue(makeDecoration(Qt::transparent));
return QVariant();
}
default:
return QVariant();
}
}
QVariant ThemeSettingsTableModel::sectionHeaderData(int section, int role) const
{
if (role == Qt::DisplayRole) {
switch (static_cast<Section>(section)) {
case SectionWidgetStyle: return tr("Widget Style");
case SectionColors: return tr("Colors");
case SectionFlags: return tr("Flags");
default: return QString();
}
}
if (role == Qt::FontRole) {
QFont font;
font.setPointSizeF(font.pointSizeF() * 1.25);
font.setBold(true);
return font;
}
if (role == Qt::SizeHintRole)
return QSize(50, 50);
return QVariant();
}
Qt::ItemFlags ThemeSettingsTableModel::sectionBodyFlags(int section, int row, int column) const
{
Q_UNUSED(row);
switch (static_cast<Section>(section)) {
case SectionWidgetStyle:
return (column == 0) ? Qt::ItemIsEnabled
: Qt::ItemIsEnabled | Qt::ItemIsEditable;
case SectionColors:
return (column == 0) ? Qt::ItemIsEnabled
: Qt::ItemIsEnabled | Qt::ItemIsEditable;
case SectionFlags:
return (column == 0) ? Qt::ItemIsEnabled
: Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
default: return Qt::ItemIsEnabled;
}
}
bool ThemeSettingsTableModel::setData(const QModelIndex &idx, const QVariant &value, int role)
{
m_hasChanges = true;
Q_UNUSED(role);
int section = inSectionBody(idx.row());
int row = modelToSectionRow(idx.row());
switch (static_cast<Section>(section)) {
case SectionFlags: {
Qt::CheckState checkState = static_cast<Qt::CheckState>(value.toInt());
bool checked = checkState == Qt::Checked;
m_flags[row].second = checked;
emit dataChanged(idx, idx);
return true;
}
default: {
// don't bother tracking changes, just mark the whole table as changed
markEverythingChanged();
return true;
}
} // switch
}
void ThemeSettingsTableModel::markEverythingChanged()
{
m_hasChanges = true;
QModelIndex i;
emit dataChanged(index(0, 0, i), index(rowCount(i), columnCount(i), i));
}
void ThemeSettingsTableModel::initFrom(Theme *theme)
{
const QMetaObject &metaObject = Theme::staticMetaObject;
// Colors
{
QMetaEnum e = metaObject.enumerator(metaObject.indexOfEnumerator("Color"));
QMap<QString, ColorVariable::Ptr> varLookup;
for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i));
QPair<QColor, QString> c = theme->d->colors[static_cast<Theme::Color>(i)];
if (c.second.isEmpty()) {
ColorVariable::Ptr v = colors()->createVariable(c.first);
colors()->createRole(key, v);
} else if (varLookup.contains(c.second)) {
colors()->createRole(key, varLookup[c.second]);
} else {
ColorVariable::Ptr v = colors()->createVariable(c.first, c.second);
colors()->createRole(key, v);
varLookup[c.second] = v;
}
}
}
// Flags
{
QMetaEnum e = metaObject.enumerator(metaObject.indexOfEnumerator("Flag"));
for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i));
m_flags.append(qMakePair(key, theme->flag(static_cast<Theme::Flag>(i))));
}
}
// ImageFiles
{
QMetaEnum e = metaObject.enumerator(metaObject.indexOfEnumerator("ImageFile"));
for (int i = 0, total = e.keyCount(); i < total; ++i) {
const QString key = QLatin1String(e.key(i));
m_imageFiles.append(qMakePair(key, theme->imageFile(static_cast<Theme::ImageFile>(i), QString())));
}
}
m_widgetStyle = theme->widgetStyle();
m_displayName = theme->d->displayName;
m_preferredStyles = theme->d->preferredStyles;
}
void ThemeSettingsTableModel::toTheme(Theme *t) const
{
ThemePrivate *theme = t->d;
// Colors
{
QMetaEnum e = Theme::staticMetaObject.enumerator(Theme::staticMetaObject.indexOfEnumerator("Color"));
for (int i = 0, total = e.keyCount(); i < total; ++i) {
ColorRole::Ptr role = colors()->colorRole(i);
ColorVariable::Ptr var = role->colorVariable();
theme->colors[i] = qMakePair(var->color(), var->variableName());
}
}
// Flags
{
QTC_ASSERT(theme->flags.size() == m_flags.size(), return);
for (int i = 0; i < theme->flags.size(); ++i)
theme->flags[i] = m_flags[i].second;
}
// ImageFiles
{
const int nImageFiles = theme->imageFiles.size();
for (int i = 0; i < nImageFiles; ++i)
theme->imageFiles[i] = m_imageFiles.at(i).second;
}
theme->widgetStyle = m_widgetStyle;
theme->displayName = m_displayName;
theme->preferredStyles = m_preferredStyles;
}
Qt::ItemFlags ThemeSettingsTableModel::sectionHeaderFlags(int section) const
{
Q_UNUSED(section);
return Qt::ItemIsEnabled;
}
int ThemeSettingsTableModel::sectionCount() const
{
return SectionInvalid;
}
QVariant ThemeSettingsTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (role == Qt::DisplayRole) {
if (orientation == Qt::Horizontal) {
if (section == 0)
return tr("Role");
return tr("Value");
}
}
return QVariant();
}
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core

View File

@@ -1,94 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2015 Thorben Kroeger <thorbenkroeger@gmail.com>.
** Contact: http://www.qt.io/licensing
**
** 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 The Qt Company. For licensing terms and
** conditions see http://www.qt.io/terms-conditions. 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, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#ifndef THEMESETTINGSTABLEMODEL_H
#define THEMESETTINGSTABLEMODEL_H
#include <QAbstractTableModel>
#include "themecolors.h"
#include "sectionedtablemodel.h"
#include <utils/theme/theme.h>
namespace Core {
namespace Internal {
namespace ThemeEditor {
class ThemeSettingsTableModel : public SectionedTableModel
{
Q_OBJECT
public:
friend class ThemeSettingsItemDelegate;
enum Section {
SectionWidgetStyle,
SectionColors,
SectionFlags,
SectionInvalid // end
};
ThemeSettingsTableModel(QObject *parent = 0);
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
int columnCount(const QModelIndex &index) const override;
int sectionRowCount(int section) const override;
QVariant sectionBodyData(int section, int row, int column, int role) const override;
QVariant sectionHeaderData(int section, int role) const override;
Qt::ItemFlags sectionBodyFlags(int section, int row, int column) const override;
Qt::ItemFlags sectionHeaderFlags(int section) const override;
int sectionCount() const override;
ThemeColors::Ptr colors() const { return m_colors; }
bool hasChanges() const { return m_hasChanges; }
void markEverythingChanged();
void initFrom(Utils::Theme *theme);
void toTheme(Utils::Theme *theme) const;
QString m_displayName;
QStringList m_preferredStyles;
public:
ThemeColors::Ptr m_colors;
QList<QPair<QString, bool> > m_flags;
QList<QPair<QString, QString> > m_imageFiles;
Utils::Theme::WidgetStyle m_widgetStyle;
bool m_hasChanges;
};
} // namespace ThemeEditor
} // namespace Internal
} // namespace Core
#endif // THEMESETTINGSTABLEMODEL_H

View File

@@ -45,10 +45,9 @@ static const char themeNameKey[] = "ThemeName";
namespace Core { namespace Core {
namespace Internal { namespace Internal {
ThemeEntry::ThemeEntry(Id id, const QString &filePath, bool readOnly) ThemeEntry::ThemeEntry(Id id, const QString &filePath)
: m_id(id), : m_id(id)
m_filePath(filePath), , m_filePath(filePath)
m_readOnly(readOnly)
{ {
} }
@@ -63,8 +62,6 @@ QString ThemeEntry::displayName() const
QSettings settings(m_filePath, QSettings::IniFormat); QSettings settings(m_filePath, QSettings::IniFormat);
m_displayName = settings.value(QLatin1String(themeNameKey), m_displayName = settings.value(QLatin1String(themeNameKey),
QCoreApplication::tr("unnamed")).toString(); QCoreApplication::tr("unnamed")).toString();
if (false) // TODO: Revert to m_readOnly
m_displayName = QCoreApplication::tr("%1 (built-in)").arg(m_displayName);
} }
return m_displayName; return m_displayName;
} }
@@ -74,11 +71,6 @@ QString ThemeEntry::filePath() const
return m_filePath; return m_filePath;
} }
bool ThemeEntry::readOnly() const
{
return m_readOnly;
}
ThemeSettings::ThemeSettings() ThemeSettings::ThemeSettings()
{ {
setId(Constants::SETTINGS_ID_INTERFACE); setId(Constants::SETTINGS_ID_INTERFACE);
@@ -112,16 +104,16 @@ void ThemeSettings::finish()
m_widget = 0; m_widget = 0;
} }
static void addThemesFromPath(const QString &path, bool readOnly, QList<ThemeEntry> *themes) static void addThemesFromPath(const QString &path, QList<ThemeEntry> *themes)
{ {
static const QLatin1String extension(".creatortheme"); static const QLatin1String extension("*.creatortheme");
QDir themeDir(path); QDir themeDir(path);
themeDir.setNameFilters(QStringList() << QLatin1String("*.creatortheme")); themeDir.setNameFilters(QStringList() << extension);
themeDir.setFilter(QDir::Files); themeDir.setFilter(QDir::Files);
const QStringList themeList = themeDir.entryList(); const QStringList themeList = themeDir.entryList();
foreach (const QString &fileName, themeList) { foreach (const QString &fileName, themeList) {
QString id = QFileInfo(fileName).completeBaseName(); QString id = QFileInfo(fileName).completeBaseName();
themes->append(ThemeEntry(Id::fromString(id), themeDir.absoluteFilePath(fileName), readOnly)); themes->append(ThemeEntry(Id::fromString(id), themeDir.absoluteFilePath(fileName)));
} }
} }
@@ -131,7 +123,7 @@ QList<ThemeEntry> ThemeSettings::availableThemes()
static const QString installThemeDir = ICore::resourcePath() + QLatin1String("/themes"); static const QString installThemeDir = ICore::resourcePath() + QLatin1String("/themes");
static const QString userThemeDir = ICore::userResourcePath() + QLatin1String("/themes"); static const QString userThemeDir = ICore::userResourcePath() + QLatin1String("/themes");
addThemesFromPath(installThemeDir, /*readOnly=*/true, &themes); addThemesFromPath(installThemeDir, &themes);
if (themes.isEmpty()) if (themes.isEmpty())
qWarning() << "Warning: No themes found in installation: " qWarning() << "Warning: No themes found in installation: "
<< QDir::toNativeSeparators(installThemeDir); << QDir::toNativeSeparators(installThemeDir);
@@ -141,7 +133,7 @@ QList<ThemeEntry> ThemeSettings::availableThemes()
ThemeEntry defaultEntry = themes.takeAt(defaultIndex); ThemeEntry defaultEntry = themes.takeAt(defaultIndex);
themes.prepend(defaultEntry); themes.prepend(defaultEntry);
} }
addThemesFromPath(userThemeDir, /*readOnly=*/false, &themes); addThemesFromPath(userThemeDir, &themes);
return themes; return themes;
} }

View File

@@ -44,18 +44,16 @@ class ThemeEntry
{ {
public: public:
ThemeEntry() = default; ThemeEntry() = default;
ThemeEntry(Id id, const QString &filePath, bool readOnly); ThemeEntry(Id id, const QString &filePath);
Id id() const; Id id() const;
QString displayName() const; QString displayName() const;
QString filePath() const; QString filePath() const;
bool readOnly() const;
private: private:
Id m_id; Id m_id;
QString m_filePath; QString m_filePath;
mutable QString m_displayName; mutable QString m_displayName;
bool m_readOnly = true;
}; };
class ThemeSettings : public IOptionsPage class ThemeSettings : public IOptionsPage

View File

@@ -28,27 +28,6 @@
<item> <item>
<widget class="QComboBox" name="themeComboBox"/> <widget class="QComboBox" name="themeComboBox"/>
</item> </item>
<item>
<widget class="QPushButton" name="renameButton">
<property name="text">
<string>Rename...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="copyButton">
<property name="text">
<string>Copy...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteButton">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
@@ -64,26 +43,8 @@
</item> </item>
</layout> </layout>
</item> </item>
<item>
<widget class="Core::Internal::ThemeEditor::ThemeEditorWidget" name="editor" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets>
<customwidget>
<class>Core::Internal::ThemeEditor::ThemeEditorWidget</class>
<extends>QWidget</extends>
<header location="global">coreplugin/themeeditor/themeeditorwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>

View File

@@ -32,7 +32,6 @@
#include "coreconstants.h" #include "coreconstants.h"
#include "icore.h" #include "icore.h"
#include "manhattanstyle.h" #include "manhattanstyle.h"
#include "themeeditor/themesettingstablemodel.h"
#include "themesettings.h" #include "themesettings.h"
#include <utils/algorithm.h> #include <utils/algorithm.h>
@@ -54,33 +53,6 @@ using namespace Utils;
namespace Core { namespace Core {
namespace Internal { namespace Internal {
static QString customThemesPath()
{
return ICore::userResourcePath() + QLatin1String("/themes/");
}
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;
}
class ThemeListModel : public QAbstractListModel class ThemeListModel : public QAbstractListModel
{ {
public: public:
@@ -135,7 +107,6 @@ public:
ThemeListModel *m_themeListModel; ThemeListModel *m_themeListModel;
bool m_refreshingThemeList; bool m_refreshingThemeList;
Ui::ThemeSettings *m_ui; Ui::ThemeSettings *m_ui;
ThemeEntry m_currentTheme;
}; };
ThemeSettingsPrivate::ThemeSettingsPrivate(QWidget *widget) ThemeSettingsPrivate::ThemeSettingsPrivate(QWidget *widget)
@@ -143,13 +114,7 @@ ThemeSettingsPrivate::ThemeSettingsPrivate(QWidget *widget)
, m_refreshingThemeList(false) , m_refreshingThemeList(false)
, m_ui(new Ui::ThemeSettings) , m_ui(new Ui::ThemeSettings)
{ {
m_currentTheme = ThemeEntry(Id::fromString(creatorTheme()->id()), creatorTheme()->filePath(), true);
m_ui->setupUi(widget); m_ui->setupUi(widget);
// TODO: Restore the editor and the buttons after improving the editor
m_ui->editor->hide();
m_ui->copyButton->hide();
m_ui->deleteButton->hide();
m_ui->renameButton->hide();
m_ui->themeComboBox->setModel(m_themeListModel); m_ui->themeComboBox->setModel(m_themeListModel);
} }
@@ -164,12 +129,6 @@ ThemeSettingsWidget::ThemeSettingsWidget(QWidget *parent) :
{ {
d = new ThemeSettingsPrivate(this); 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(); refreshThemeList();
} }
@@ -181,190 +140,26 @@ ThemeSettingsWidget::~ThemeSettingsWidget()
void ThemeSettingsWidget::refreshThemeList() void ThemeSettingsWidget::refreshThemeList()
{ {
const QList<ThemeEntry> themes = ThemeSettings::availableThemes(); const QList<ThemeEntry> themes = ThemeSettings::availableThemes();
const int selected = Utils::indexOf(themes, Utils::equal(&ThemeEntry::id, d->m_currentTheme.id())); const int selected = Utils::indexOf(themes, Utils::equal(&ThemeEntry::id,
Id::fromString(creatorTheme()->id())));
d->m_refreshingThemeList = true; d->m_refreshingThemeList = true;
d->m_themeListModel->setThemes(themes); d->m_themeListModel->setThemes(themes);
if (selected >= 0) { if (selected >= 0)
d->m_currentTheme = themes[selected];
d->m_ui->themeComboBox->setCurrentIndex(selected); d->m_ui->themeComboBox->setCurrentIndex(selected);
}
d->m_refreshingThemeList = false; d->m_refreshingThemeList = false;
} }
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.filePath(), QSettings::IniFormat);
Theme theme(entry.id().toString());
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.displayName()),
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.filePath()))
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.displayName()),
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_currentTheme.id().toString());
d->m_ui->editor->model()->toTheme(&newTheme);
newTheme.writeSettings(d->m_currentTheme.filePath());
}
}
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_displayName);
int ret = dialog->exec();
QString newName = dialog->textValue();
delete dialog;
if (ret != QDialog::Accepted || newName.isEmpty())
return;
// overwrite file with new name
Theme newTheme(entry.id().toString());
d->m_ui->editor->model()->toTheme(&newTheme);
newTheme.setDisplayName(newName);
newTheme.writeSettings(entry.filePath());
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.filePath()).completeBaseName();
baseFileName += QLatin1String("_copy%1.creatortheme");
QString fileName = createThemeFileName(baseFileName);
QString id = QFileInfo(fileName).completeBaseName();
if (fileName.isEmpty() || id.isEmpty())
return;
// Ask about saving any existing modifactions
maybeSaveTheme();
Theme newTheme(fileName);
d->m_ui->editor->model()->toTheme(&newTheme);
newTheme.setDisplayName(name);
newTheme.writeSettings(fileName);
d->m_currentTheme = ThemeEntry(Id::fromString(id), fileName, true);
refreshThemeList();
}
void ThemeSettingsWidget::apply() void ThemeSettingsWidget::apply()
{ {
const QString themeId = d->m_currentTheme.id().toString(); const int index = d->m_ui->themeComboBox->currentIndex();
if (index == -1)
return;
ThemeEntry currentTheme = d->m_themeListModel->themeAt(index);
const QString themeId = currentTheme.id().toString();
Theme *newTheme = new Theme(themeId); Theme *newTheme = new Theme(themeId);
if (d->m_currentTheme.readOnly()) { QSettings themeSettings(currentTheme.filePath(), QSettings::IniFormat);
QSettings themeSettings(d->m_currentTheme.filePath(), QSettings::IniFormat);
newTheme->readSettings(themeSettings); newTheme->readSettings(themeSettings);
} else {
d->m_ui->editor->model()->toTheme(newTheme);
newTheme->writeSettings(d->m_currentTheme.filePath());
}
setCreatorTheme(newTheme); setCreatorTheme(newTheme);
emit ICore::instance()->themeChanged(); emit ICore::instance()->themeChanged();
QPalette pal = newTheme->flag(Theme::ApplyThemePaletteGlobally) ? newTheme->palette() QPalette pal = newTheme->flag(Theme::ApplyThemePaletteGlobally) ? newTheme->palette()

View File

@@ -48,15 +48,6 @@ public:
void apply(); void apply();
private slots:
void themeSelected(int index);
void copyTheme();
void renameTheme();
void copyThemeByName(const QString &);
void confirmDeleteTheme();
void deleteTheme();
void maybeSaveTheme();
private: private:
void refreshThemeList(); void refreshThemeList();
ThemeSettingsPrivate *d; ThemeSettingsPrivate *d;