aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmldesigner/components/propertyeditor
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qmldesigner/components/propertyeditor')
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp13
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.h4
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp178
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/gradientmodel.h15
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/gradientpresetcustomlistmodel.cpp161
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/gradientpresetcustomlistmodel.h62
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/gradientpresetdefaultlistmodel.cpp61
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/gradientpresetdefaultlistmodel.h48
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.cpp206
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.h92
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/gradientpresetlistmodel.cpp113
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/gradientpresetlistmodel.h60
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri18
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp29
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp119
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h7
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp119
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h3
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp284
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h2
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp31
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h9
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp6
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/simplecolorpalette.cpp113
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/simplecolorpalette.h75
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettemodel.cpp146
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettemodel.h77
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettesingleton.cpp185
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettesingleton.h71
29 files changed, 1941 insertions, 366 deletions
diff --git a/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp
index 5d7b1aeaaf..245d604707 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp
@@ -85,6 +85,11 @@ QUrl FileResourcesModel::path() const
return m_path;
}
+QUrl FileResourcesModel::dirPath() const
+{
+ return QUrl::fromLocalFile(m_dirPath.path());
+}
+
void FileResourcesModel::setFilter(const QString &filter)
{
if (m_filter != filter) {
@@ -162,16 +167,14 @@ void FileResourcesModel::setupModel()
m_lock = true;
m_model.clear();
- QDir dir;
-
- dir = QFileInfo(m_path.toLocalFile()).dir();
+ m_dirPath = QFileInfo(m_path.toLocalFile()).dir();
QStringList filterList = m_filter.split(QLatin1Char(' '));
- QDirIterator it(dir.absolutePath(), filterList, QDir::Files, QDirIterator::Subdirectories);
+ QDirIterator it(m_dirPath.absolutePath(), filterList, QDir::Files, QDirIterator::Subdirectories);
while (it.hasNext()) {
QString absolutePath = it.next();
- m_model.append(dir.relativeFilePath(absolutePath));
+ m_model.append(m_dirPath.relativeFilePath(absolutePath));
}
m_lock = false;
diff --git a/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.h b/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.h
index e0d6fc9725..f686631079 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.h
@@ -27,6 +27,7 @@
#include <qmlitemnode.h>
+#include <QDir>
#include <QObject>
#include <QStringList>
#include <QUrl>
@@ -40,6 +41,7 @@ class FileResourcesModel : public QObject
Q_PROPERTY(QString filter READ filter WRITE setFilter)
Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged)
Q_PROPERTY(QUrl path READ path WRITE setPath)
+ Q_PROPERTY(QUrl dirPath READ dirPath)
Q_PROPERTY(QStringList fileModel READ fileModel NOTIFY fileModelChanged)
public:
@@ -51,6 +53,7 @@ public:
void setFileNameStr(const QString &fileName);
void setPath(const QUrl &url);
QUrl path() const;
+ QUrl dirPath() const;
void setFilter(const QString &filter);
QString filter() const;
QStringList fileModel() const;
@@ -71,6 +74,7 @@ private:
private:
QUrl m_fileName;
QUrl m_path;
+ QDir m_dirPath;
QString m_filter;
bool m_lock;
QString m_currentPath;
diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp
index 6bb3153bea..d4b1f47184 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp
@@ -27,6 +27,8 @@
#include "qmlanchorbindingproxy.h"
#include "propertyeditorview.h"
+#include "gradientpresetitem.h"
+#include "gradientpresetcustomlistmodel.h"
#include <exception.h>
#include <nodeproperty.h>
@@ -34,14 +36,14 @@
#include <variantproperty.h>
#include <abstractview.h>
#include <nodemetainfo.h>
-#include <rewritertransaction.h>
+#include <exception.h>
#include <utils/qtcassert.h>
#include <QTimer>
GradientModel::GradientModel(QObject *parent) :
- QAbstractListModel(parent), m_gradientTypeName("Gradient"), m_locked(false)
+ QAbstractListModel(parent)
{
}
@@ -145,18 +147,16 @@ void GradientModel::addGradient()
return;
if (!m_itemNode.modelNode().hasNodeProperty(gradientPropertyName().toUtf8())) {
- try {
+ if (m_gradientTypeName != "Gradient")
+ ensureShapesImport();
+
+ view()->executeInTransaction("GradientModel::addGradient", [this](){
QColor color = m_itemNode.instanceValue("color").value<QColor>();
if (!color.isValid())
color = QColor(Qt::white);
- if (m_gradientTypeName != "Gradient")
- ensureShapesImport();
-
- QmlDesigner::RewriterTransaction transaction = view()->beginRewriterTransaction(QByteArrayLiteral("GradientModel::addGradient"));
-
QmlDesigner::ModelNode gradientNode = createGradientNode();
m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).reparentHere(gradientNode);
@@ -170,16 +170,12 @@ void GradientModel::addGradient()
gradientStopNode.variantProperty("position").setValue(1.0);
gradientStopNode.variantProperty("color").setValue(QColor(Qt::black));
gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode);
-
- } catch (const QmlDesigner::Exception &e) {
- e.showException();
- }
-
+ });
}
setupModel();
if (m_gradientTypeName != "Gradient")
- QTimer::singleShot(100, [this](){ view()->resetPuppet(); }); /*Unfortunately required */
+ resetPuppet(); /*Unfortunately required */
emit hasGradientChanged();
emit gradientTypeChanged();
}
@@ -242,18 +238,18 @@ qreal GradientModel::getPosition(int index) const
void GradientModel::removeStop(int index)
{
if (index < rowCount() - 1 && index != 0) {
- QmlDesigner::RewriterTransaction transaction = view()->beginRewriterTransaction(QByteArrayLiteral("GradientModel::removeStop"));
- QmlDesigner::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode();
- QmlDesigner::QmlObjectNode stop = gradientNode.nodeListProperty("stops").at(index);
- if (stop.isValid()) {
- stop.destroy();
- setupModel();
- }
+ view()->executeInTransaction("GradientModel::removeStop", [this, index](){
+ QmlDesigner::ModelNode gradientNode = m_itemNode.modelNode().nodeProperty(gradientPropertyName().toUtf8()).modelNode();
+ QmlDesigner::QmlObjectNode stop = gradientNode.nodeListProperty("stops").at(index);
+ if (stop.isValid()) {
+ stop.destroy();
+ setupModel();
+ }
+ });
}
qWarning() << Q_FUNC_INFO << "invalid index";
}
-
void GradientModel::deleteGradient()
{
if (!m_itemNode.isValid())
@@ -262,16 +258,7 @@ void GradientModel::deleteGradient()
if (!m_itemNode.modelNode().metaInfo().hasProperty(gradientPropertyName().toUtf8()))
return;
- QmlDesigner::ModelNode modelNode = m_itemNode.modelNode();
-
- if (m_itemNode.isInBaseState()) {
- if (modelNode.hasProperty(gradientPropertyName().toUtf8())) {
- QmlDesigner::RewriterTransaction transaction = view()->beginRewriterTransaction(QByteArrayLiteral("GradientModel::deleteGradient"));
- QmlDesigner::ModelNode gradientNode = modelNode.nodeProperty(gradientPropertyName().toUtf8()).modelNode();
- if (QmlDesigner::QmlObjectNode(gradientNode).isValid())
- QmlDesigner::QmlObjectNode(gradientNode).destroy();
- }
- }
+ deleteGradientNode(true);
emit hasGradientChanged();
emit gradientTypeChanged();
@@ -392,7 +379,11 @@ void GradientModel::ensureShapesImport()
{
if (!hasShapesImport()) {
QmlDesigner::Import timelineImport = QmlDesigner::Import::createLibraryImport("QtQuick.Shapes", "1.0");
- model()->changeImports({timelineImport}, {});
+ try {
+ model()->changeImports({timelineImport}, {});
+ } catch (const QmlDesigner::Exception &) {
+ QTC_ASSERT(false, return);
+ }
}
}
@@ -444,6 +435,11 @@ QmlDesigner::AbstractView *GradientModel::view() const
return m_itemNode.view();
}
+void GradientModel::resetPuppet()
+{
+ QTimer::singleShot(1000, [this]() { view()->resetPuppet(); });
+}
+
QmlDesigner::ModelNode GradientModel::createGradientNode()
{
QByteArray fullTypeName = m_gradientTypeName.toUtf8();
@@ -477,6 +473,23 @@ QmlDesigner::ModelNode GradientModel::createGradientStopNode()
return view()->createModelNode(fullTypeName, majorVersion, minorVersion);
}
+void GradientModel::deleteGradientNode(bool saveTransaction)
+{
+ QmlDesigner::ModelNode modelNode = m_itemNode.modelNode();
+
+ if (m_itemNode.isInBaseState()) {
+ if (modelNode.hasProperty(gradientPropertyName().toUtf8())) {
+ if (saveTransaction)
+ QmlDesigner::RewriterTransaction transaction = view()->beginRewriterTransaction(
+ QByteArrayLiteral("GradientModel::deleteGradient"));
+ QmlDesigner::ModelNode gradientNode
+ = modelNode.nodeProperty(gradientPropertyName().toUtf8()).modelNode();
+ if (QmlDesigner::QmlObjectNode(gradientNode).isValid())
+ QmlDesigner::QmlObjectNode(gradientNode).destroy();
+ }
+ }
+}
+
void GradientModel::setGradientProperty(const QString &propertyName, qreal value)
{
QTC_ASSERT(m_itemNode.isValid(), return);
@@ -494,3 +507,102 @@ void GradientModel::setGradientProperty(const QString &propertyName, qreal value
e.showException();
}
}
+
+void GradientModel::setPresetByID(int presetID)
+{
+ const QGradient gradient(GradientPresetItem::createGradientFromPreset(
+ static_cast<GradientPresetItem::Preset>(presetID)));
+ const QList<QGradientStop> gradientStops = gradient.stops().toList();
+
+ QList<qreal> stopsPositions;
+ QList<QString> stopsColors;
+ for (const QGradientStop &stop : gradientStops) {
+ stopsPositions.append(stop.first);
+ stopsColors.append(stop.second.name());
+ }
+
+ setPresetByStops(stopsPositions, stopsColors, gradientStops.size());
+}
+
+void GradientModel::setPresetByStops(const QList<qreal> &stopsPositions,
+ const QList<QString> &stopsColors,
+ int stopsCount)
+{
+ if (m_locked)
+ return;
+
+ if (!m_itemNode.isValid() || gradientPropertyName().isEmpty())
+ return;
+
+ QmlDesigner::RewriterTransaction transaction = view()->beginRewriterTransaction(
+ QByteArrayLiteral("GradientModel::setCustomPreset"));
+
+ deleteGradientNode(false);
+
+ if (!m_itemNode.modelNode().hasNodeProperty(gradientPropertyName().toUtf8())) {
+ try {
+
+ if (m_gradientTypeName != "Gradient")
+ ensureShapesImport();
+
+ QmlDesigner::ModelNode gradientNode = createGradientNode();
+
+ m_itemNode.modelNode()
+ .nodeProperty(gradientPropertyName().toUtf8())
+ .reparentHere(gradientNode);
+
+ for (int i = 0; i < stopsCount; i++) {
+ QmlDesigner::ModelNode gradientStopNode = createGradientStopNode();
+ gradientStopNode.variantProperty("position").setValue(stopsPositions.at(i));
+ gradientStopNode.variantProperty("color").setValue(stopsColors.at(i));
+ gradientNode.nodeListProperty("stops").reparentHere(gradientStopNode);
+ }
+
+ } catch (const QmlDesigner::Exception &e) {
+ e.showException();
+ }
+ }
+ setupModel();
+
+ if (m_gradientTypeName != "Gradient")
+ resetPuppet(); /*Unfortunately required */
+
+ emit hasGradientChanged();
+ emit gradientTypeChanged();
+}
+
+void GradientModel::savePreset()
+{
+ //preparing qgradient:
+ QGradient currentGradient;
+ QGradientStops currentStops;
+ QGradientStop stop; //double, color
+
+ for (int i = 0; i < rowCount(); i++) {
+ stop.first = getPosition(i);
+ stop.second = getColor(i);
+ currentStops.append(stop);
+ }
+ currentGradient.setStops(currentStops);
+ const GradientPresetItem item(currentGradient, "Custom Gradient");
+
+ //reading the custom gradient file
+ //filling the file with old data + new data
+ const QString filename(GradientPresetCustomListModel::getFilename());
+ QList<GradientPresetItem> items = GradientPresetCustomListModel::storedPresets(filename);
+ items.append(item);
+ GradientPresetCustomListModel::storePresets(filename, items);
+}
+
+void GradientModel::updateGradient()
+{
+ QList<qreal> stops;
+ QList<QString> colors;
+ int stopsCount = rowCount();
+ for (int i = 0; i < stopsCount; i++) {
+ stops.append(getPosition(i));
+ colors.append(getColor(i).name(QColor::HexArgb));
+ }
+
+ setPresetByStops(stops, colors, stopsCount);
+}
diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.h b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.h
index 48514ae688..c54526838e 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.h
@@ -70,6 +70,15 @@ public:
Q_INVOKABLE void setGradientProperty(const QString &propertyName, qreal value);
+ Q_INVOKABLE void setPresetByID(int presetID);
+ Q_INVOKABLE void setPresetByStops(const QList<qreal> &stopsPositions,
+ const QList<QString> &stopsColors,
+ int stopsCount);
+
+ Q_INVOKABLE void savePreset();
+
+ Q_INVOKABLE void updateGradient();
+
signals:
void anchorBackendChanged();
void hasGradientChanged();
@@ -87,17 +96,19 @@ private:
bool locked() const;
QmlDesigner::ModelNode createGradientNode();
QmlDesigner::ModelNode createGradientStopNode();
+ void deleteGradientNode(bool saveTransaction);
private:
QmlDesigner::QmlItemNode m_itemNode;
QString m_gradientPropertyName;
- QString m_gradientTypeName;
- bool m_locked;
+ QString m_gradientTypeName = {"Gradient"};
+ bool m_locked = false;
bool hasShapesImport() const;
void ensureShapesImport();
void setupGradientProperties(const QmlDesigner::ModelNode &gradient);
QmlDesigner::Model *model() const;
QmlDesigner::AbstractView *view() const;
+ void resetPuppet();
};
QML_DECLARE_TYPE(GradientModel)
diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientpresetcustomlistmodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetcustomlistmodel.cpp
new file mode 100644
index 0000000000..a1599a7099
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetcustomlistmodel.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "gradientpresetcustomlistmodel.h"
+#include "gradientpresetitem.h"
+
+#include <coreplugin/icore.h>
+#include <utils/qtcassert.h>
+#include <utils/algorithm.h>
+
+#include <QHash>
+#include <QByteArray>
+#include <QDebug>
+#include <QSettings>
+#include <QFile>
+
+namespace Internal {
+
+static const char settingsKey[] = "GradientPresetCustomList";
+static const char settingsFileName[] = "/GradientPresets.ini";
+
+QString settingsFullFilePath(const QSettings::Scope &scope)
+{
+ if (scope == QSettings::SystemScope)
+ return Core::ICore::installerResourcePath() + settingsFileName;
+
+ return Core::ICore::userResourcePath() + settingsFileName;
+}
+
+} // namespace Internal
+
+GradientPresetCustomListModel::GradientPresetCustomListModel(QObject *parent)
+ : GradientPresetListModel(parent)
+ , m_filename(getFilename())
+{
+ qRegisterMetaTypeStreamOperators<GradientPresetItem>("GradientPresetItem");
+ readPresets();
+}
+
+GradientPresetCustomListModel::~GradientPresetCustomListModel() {}
+
+void GradientPresetCustomListModel::registerDeclarativeType()
+{
+ qmlRegisterType<GradientPresetCustomListModel>("HelperWidgets",
+ 2,
+ 0,
+ "GradientPresetCustomListModel");
+}
+
+QString GradientPresetCustomListModel::getFilename()
+{
+ return Internal::settingsFullFilePath(QSettings::UserScope);
+}
+
+void GradientPresetCustomListModel::storePresets(const QString &filename,
+ const QList<GradientPresetItem> &items)
+{
+ const QList<QVariant> presets
+ = Utils::transform<QList<QVariant>>(items, [](const GradientPresetItem &item) {
+ return QVariant::fromValue(item);
+ });
+
+ QSettings settings(filename, QSettings::IniFormat);
+ settings.clear();
+ settings.setValue(Internal::settingsKey, QVariant::fromValue(presets));
+}
+
+QList<GradientPresetItem> GradientPresetCustomListModel::storedPresets(const QString &filename)
+{
+ const QSettings settings(filename, QSettings::IniFormat);
+ const QVariant presetSettings = settings.value(Internal::settingsKey);
+
+ if (!presetSettings.isValid())
+ return {};
+
+ const QList<QVariant> presets = presetSettings.toList();
+
+ QList<GradientPresetItem> out;
+ for (const QVariant &preset : presets) {
+ if (preset.isValid()) {
+ out.append(preset.value<GradientPresetItem>());
+ }
+ }
+
+ return out;
+}
+
+void GradientPresetCustomListModel::addGradient(const QList<qreal> &stopsPositions,
+ const QList<QString> &stopsColors,
+ int stopsCount)
+{
+ QGradient tempGradient;
+ QGradientStops gradientStops;
+ QGradientStop gradientStop;
+ for (int i = 0; i < stopsCount; i++) {
+ gradientStop.first = stopsPositions.at(i);
+ gradientStop.second = stopsColors.at(i);
+ gradientStops.push_back(gradientStop);
+ }
+
+ tempGradient.setStops(gradientStops);
+
+ addItem(GradientPresetItem(tempGradient));
+}
+
+void GradientPresetCustomListModel::changePresetName(int id, const QString &newName)
+{
+ QTC_ASSERT(id >= 0, return);
+ QTC_ASSERT(id < m_items.size(), return);
+ m_items[id].setPresetName(newName);
+ writePresets();
+}
+
+void GradientPresetCustomListModel::deletePreset(int id)
+{
+ QTC_ASSERT(id >= 0, return);
+ QTC_ASSERT(id < m_items.size(), return);
+ beginResetModel();
+ m_items.removeAt(id);
+ writePresets();
+ endResetModel();
+}
+
+void GradientPresetCustomListModel::writePresets()
+{
+ storePresets(m_filename, m_items);
+}
+
+void GradientPresetCustomListModel::readPresets()
+{
+ const QList<GradientPresetItem> presets = storedPresets(m_filename);
+ beginResetModel();
+ m_items.clear();
+
+ for (const GradientPresetItem &preset : presets) {
+ addItem(preset);
+ }
+ endResetModel();
+}
diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientpresetcustomlistmodel.h b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetcustomlistmodel.h
new file mode 100644
index 0000000000..382b651e3b
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetcustomlistmodel.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "gradientpresetlistmodel.h"
+
+#include <QObject>
+#include <QAbstractListModel>
+#include <QtQml/qqml.h>
+
+class GradientPresetCustomListModel : public GradientPresetListModel
+{
+ Q_OBJECT
+
+public:
+ explicit GradientPresetCustomListModel(QObject *parent = nullptr);
+ ~GradientPresetCustomListModel() override;
+
+ static void registerDeclarativeType();
+
+ static QString getFilename();
+ static void storePresets(const QString &filename, const QList<GradientPresetItem> &items);
+ static QList<GradientPresetItem> storedPresets(const QString &filename);
+
+ Q_INVOKABLE void addGradient(const QList<qreal> &stopsPositions,
+ const QList<QString> &stopsColors,
+ int stopsCount);
+
+ Q_INVOKABLE void changePresetName(int id, const QString &newName);
+ Q_INVOKABLE void deletePreset(int id);
+
+ Q_INVOKABLE void writePresets();
+ Q_INVOKABLE void readPresets();
+
+private:
+ QString m_filename;
+};
+
+QML_DECLARE_TYPE(GradientPresetCustomListModel)
diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientpresetdefaultlistmodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetdefaultlistmodel.cpp
new file mode 100644
index 0000000000..8237390de9
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetdefaultlistmodel.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "gradientpresetdefaultlistmodel.h"
+#include "gradientpresetitem.h"
+
+#include <QHash>
+#include <QByteArray>
+#include <QDebug>
+#include <QFile>
+
+GradientPresetDefaultListModel::GradientPresetDefaultListModel(QObject *parent)
+ : GradientPresetListModel(parent)
+{
+ addAllPresets();
+}
+
+GradientPresetDefaultListModel::~GradientPresetDefaultListModel() {}
+
+void GradientPresetDefaultListModel::registerDeclarativeType()
+{
+ qmlRegisterType<GradientPresetDefaultListModel>("HelperWidgets",
+ 2,
+ 0,
+ "GradientPresetDefaultListModel");
+}
+
+void GradientPresetDefaultListModel::addAllPresets()
+{
+ const QMetaObject &metaObj = QGradient::staticMetaObject;
+ const QMetaEnum metaEnum = metaObj.enumerator(metaObj.indexOfEnumerator("Preset"));
+
+ if (!metaEnum.isValid())
+ return;
+
+ for (int i = 0; i < metaEnum.keyCount(); i++) {
+ addItem(GradientPresetItem(GradientPresetItem::Preset(metaEnum.value(i))));
+ }
+}
diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientpresetdefaultlistmodel.h b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetdefaultlistmodel.h
new file mode 100644
index 0000000000..831135e052
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetdefaultlistmodel.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "gradientpresetlistmodel.h"
+
+#include <QObject>
+#include <QAbstractListModel>
+#include <QtQml/qqml.h>
+
+class GradientPresetDefaultListModel : public GradientPresetListModel
+{
+ Q_OBJECT
+
+public:
+ explicit GradientPresetDefaultListModel(QObject *parent = nullptr);
+ ~GradientPresetDefaultListModel() override;
+
+ static void registerDeclarativeType();
+
+private:
+ void addAllPresets();
+};
+
+QML_DECLARE_TYPE(GradientPresetDefaultListModel)
diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.cpp b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.cpp
new file mode 100644
index 0000000000..9d2454c4e9
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.cpp
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "gradientpresetitem.h"
+
+#include <utils/qtcassert.h>
+#include <utils/algorithm.h>
+
+#include <QVariant>
+#include <QMetaObject>
+#include <QMetaEnum>
+#include <algorithm>
+#include <QDebug>
+
+
+GradientPresetItem::GradientPresetItem()
+ : m_gradientVal(QGradient())
+ , m_gradientID(Preset(0))
+ , m_presetName(QString())
+{}
+
+GradientPresetItem::GradientPresetItem(const QGradient &value, const QString &name)
+ : m_gradientVal(value)
+ , m_gradientID(Preset(0))
+ , m_presetName(name)
+{}
+
+GradientPresetItem::GradientPresetItem(const Preset value)
+ : m_gradientVal(createGradientFromPreset(value))
+ , m_gradientID(value)
+ , m_presetName(getNameByPreset(value))
+{}
+
+GradientPresetItem::~GradientPresetItem() = default;
+
+QVariant GradientPresetItem::getProperty(GradientPresetItem::Property id) const
+{
+ QVariant out;
+
+ switch (id) {
+ case objectNameRole:
+ out.setValue(QString());
+ break;
+ case stopsPosListRole:
+ out.setValue(stopsPosList());
+ break;
+ case stopsColorListRole:
+ out.setValue(stopsColorList());
+ break;
+ case stopListSizeRole:
+ out.setValue(stopListSize());
+ break;
+ case presetNameRole:
+ out.setValue(presetName());
+ break;
+ case presetIDRole:
+ out.setValue(presetID());
+ break;
+ default:
+ qWarning() << "GradientPresetItem Property switch default case";
+ break; //replace with assert before switch?
+ }
+
+ return out;
+}
+
+QGradient GradientPresetItem::gradientVal() const
+{
+ return m_gradientVal;
+}
+
+void GradientPresetItem::setGradient(const QGradient &value)
+{
+ m_gradientVal = value;
+ m_gradientID = Preset(0);
+ m_presetName = QString();
+}
+
+void GradientPresetItem::setGradient(const Preset value)
+{
+ m_gradientID = value;
+ m_gradientVal = createGradientFromPreset(value);
+ m_presetName = getNameByPreset(value);
+}
+
+QList<qreal> GradientPresetItem::stopsPosList() const
+{
+ const QList<QPair<qreal, QColor>> subres = m_gradientVal.stops().toList();
+ const QList<qreal> result = Utils::transform<QList<qreal>>(subres,
+ [](const QPair<qreal, QColor> &item) {
+ return item.first;
+ });
+ return result;
+}
+
+QList<QString> GradientPresetItem::stopsColorList() const
+{
+ const QList<QPair<qreal, QColor>> subres = m_gradientVal.stops().toList();
+ const QList<QString> result
+ = Utils::transform<QList<QString>>(subres, [](const QPair<qreal, QColor> &item) {
+ return item.second.name();
+ });
+ return result;
+}
+
+int GradientPresetItem::stopListSize() const
+{
+ return m_gradientVal.stops().size();
+}
+
+void GradientPresetItem::setPresetName(const QString &value)
+{
+ m_presetName = value;
+}
+
+QString GradientPresetItem::presetName() const
+{
+ return m_presetName;
+}
+
+int GradientPresetItem::presetID() const
+{
+ return static_cast<int>(m_gradientID);
+}
+
+QString GradientPresetItem::getNameByPreset(Preset value)
+{
+ const QMetaObject &metaObj = QGradient::staticMetaObject;
+ const QMetaEnum metaEnum = metaObj.enumerator(metaObj.indexOfEnumerator("Preset"));
+
+ if (!metaEnum.isValid())
+ return QString("Custom");
+
+ QString enumName = QString::fromUtf8(metaEnum.valueToKey(static_cast<int>(value)));
+
+ const QStringList sl = enumName.split(QRegExp("(?=[A-Z])"), QString::SkipEmptyParts);
+
+ enumName.clear();
+ std::for_each(sl.begin(), sl.end(), [&enumName](const QString &s) { enumName += (s + " "); });
+ enumName.chop(1); //let's remove the last empty space
+
+ return (enumName.isEmpty() ? QString("Custom") : enumName);
+}
+
+QGradient GradientPresetItem::createGradientFromPreset(Preset value)
+{
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ return QGradient(value);
+#else
+ Q_UNUSED(value);
+ return {};
+#endif
+}
+
+QDebug &operator<<(QDebug &stream, const GradientPresetItem &gradient)
+{
+ stream << "\"stops:" << gradient.m_gradientVal.stops() << "\"";
+ stream << "\"preset:" << gradient.m_gradientID << "\"";
+ stream << "\"name:" << gradient.m_presetName << "\"";
+ return stream;
+}
+
+QDataStream &operator<<(QDataStream &stream, const GradientPresetItem &gradient)
+{
+ stream << gradient.m_gradientVal.stops();
+
+ stream << static_cast<int>(gradient.m_gradientID);
+ stream << gradient.m_presetName;
+ return stream;
+}
+
+QDataStream &operator>>(QDataStream &stream, GradientPresetItem &gradient)
+{
+ QGradientStops stops;
+ stream >> stops;
+ gradient.m_gradientVal.setStops(stops);
+
+ int gradientID;
+ stream >> gradientID;
+ gradient.m_gradientID = static_cast<GradientPresetItem::Preset>(gradientID);
+
+ stream >> gradient.m_presetName;
+ return stream;
+}
diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.h b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.h
new file mode 100644
index 0000000000..cd0f0017e0
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetitem.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QObject>
+#include <QGradient>
+
+class GradientPresetItem
+{
+ Q_GADGET
+
+ Q_PROPERTY(QList<qreal> stopsPosList READ stopsPosList FINAL)
+ Q_PROPERTY(QList<QString> stopsColorList READ stopsColorList FINAL)
+ Q_PROPERTY(int stopListSize READ stopListSize FINAL)
+ Q_PROPERTY(QString presetName READ presetName FINAL)
+ Q_PROPERTY(int presetID READ presetID FINAL)
+
+public:
+#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
+ using Preset = QGradient::Preset;
+#else
+ enum Preset {};
+#endif
+
+ explicit GradientPresetItem();
+ explicit GradientPresetItem(const QGradient &value, const QString &name = QString());
+ explicit GradientPresetItem(const Preset number);
+ ~GradientPresetItem();
+
+ enum Property {
+ objectNameRole = 0,
+ stopsPosListRole = 1,
+ stopsColorListRole = 2,
+ stopListSizeRole = 3,
+ presetNameRole = 4,
+ presetIDRole = 5
+ };
+
+ QVariant getProperty(Property id) const;
+
+ QGradient gradientVal() const;
+
+ void setGradient(const QGradient &value);
+ void setGradient(const Preset value);
+
+ QList<qreal> stopsPosList() const;
+ QList<QString> stopsColorList() const;
+ int stopListSize() const;
+
+ void setPresetName(const QString &value);
+ QString presetName() const;
+ int presetID() const;
+
+ static QString getNameByPreset(Preset value);
+
+ friend QDebug &operator<<(QDebug &stream, const GradientPresetItem &gradient);
+
+ friend QDataStream &operator<<(QDataStream &stream, const GradientPresetItem &gradient);
+ friend QDataStream &operator>>(QDataStream &stream, GradientPresetItem &gradient);
+
+ static QGradient createGradientFromPreset(Preset value);
+
+private:
+ QGradient m_gradientVal;
+ Preset m_gradientID;
+ QString m_presetName;
+};
+
+Q_DECLARE_METATYPE(GradientPresetItem)
diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientpresetlistmodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetlistmodel.cpp
new file mode 100644
index 0000000000..1ed95f8719
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetlistmodel.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "gradientpresetlistmodel.h"
+#include "gradientpresetitem.h"
+
+#include <QHash>
+#include <QByteArray>
+#include <QDebug>
+#include <QSettings>
+
+GradientPresetListModel::GradientPresetListModel(QObject *parent)
+ : QAbstractListModel(parent)
+{
+ m_roleNames
+ = {{static_cast<int>(GradientPresetItem::Property::objectNameRole), "objectName"},
+ {static_cast<int>(GradientPresetItem::Property::stopsPosListRole), "stopsPosList"},
+ {static_cast<int>(GradientPresetItem::Property::stopsColorListRole), "stopsColorList"},
+ {static_cast<int>(GradientPresetItem::Property::stopListSizeRole), "stopListSize"},
+ {static_cast<int>(GradientPresetItem::Property::presetNameRole), "presetName"},
+ {static_cast<int>(GradientPresetItem::Property::presetIDRole), "presetID"}};
+}
+
+GradientPresetListModel::~GradientPresetListModel()
+{
+ clearItems();
+}
+
+int GradientPresetListModel::rowCount(const QModelIndex & /*parent*/) const
+{
+ return m_items.count();
+}
+
+QVariant GradientPresetListModel::data(const QModelIndex &index, int role) const
+{
+ if (index.isValid() && (index.row() >= 0) && (index.row() < m_items.count())) {
+ if (m_roleNames.contains(role)) {
+ QVariant value = m_items.at(index.row())
+ .getProperty(static_cast<GradientPresetItem::Property>(role));
+
+ if (auto model = qobject_cast<GradientPresetListModel *>(value.value<QObject *>()))
+ return QVariant::fromValue(model);
+
+ return value;
+ }
+
+ qWarning() << Q_FUNC_INFO << "invalid role requested";
+ return QVariant();
+ }
+
+ qWarning() << Q_FUNC_INFO << "invalid index requested";
+ return QVariant();
+}
+
+QHash<int, QByteArray> GradientPresetListModel::roleNames() const
+{
+ return m_roleNames;
+}
+
+void GradientPresetListModel::clearItems()
+{
+ beginResetModel();
+ m_items.clear();
+ endResetModel();
+}
+
+void GradientPresetListModel::addItem(const GradientPresetItem &element)
+{
+ beginResetModel();
+ m_items.append(element);
+ endResetModel();
+}
+
+const QList<GradientPresetItem> &GradientPresetListModel::items() const
+{
+ return m_items;
+}
+
+void GradientPresetListModel::sortItems()
+{
+ auto itemSort = [](const GradientPresetItem &first, const GradientPresetItem &second) {
+ return (static_cast<int>(first.presetID()) < static_cast<int>(second.presetID()));
+ };
+
+ std::sort(m_items.begin(), m_items.end(), itemSort);
+}
+
+void GradientPresetListModel::registerDeclarativeType()
+{
+ qmlRegisterType<GradientPresetListModel>("HelperWidgets", 2, 0, "GradientPresetListModel");
+}
diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientpresetlistmodel.h b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetlistmodel.h
new file mode 100644
index 0000000000..7fce2243dd
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetlistmodel.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QObject>
+#include <QAbstractListModel>
+#include <QtQml/qqml.h>
+
+class GradientPresetItem;
+
+class GradientPresetListModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+ explicit GradientPresetListModel(QObject *parent = nullptr);
+ ~GradientPresetListModel() override;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ QHash<int, QByteArray> roleNames() const override;
+
+ void clearItems();
+ void addItem(const GradientPresetItem &element);
+
+ const QList<GradientPresetItem> &items() const;
+
+ void sortItems();
+
+ static void registerDeclarativeType();
+
+protected:
+ QList<GradientPresetItem> m_items;
+ QHash<int, QByteArray> m_roleNames;
+};
+
+//QML_DECLARE_TYPE(GradientPresetListModel)
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri
index d822fbb70d..b32a744016 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.pri
@@ -11,7 +11,14 @@ SOURCES += propertyeditorview.cpp \
propertyeditorwidget.cpp \
fileresourcesmodel.cpp \
gradientmodel.cpp \
- qmlmodelnodeproxy.cpp
+ qmlmodelnodeproxy.cpp \
+ gradientpresetitem.cpp \
+ gradientpresetlistmodel.cpp \
+ gradientpresetdefaultlistmodel.cpp \
+ gradientpresetcustomlistmodel.cpp \
+ simplecolorpalette.cpp \
+ simplecolorpalettemodel.cpp \
+ simplecolorpalettesingleton.cpp
HEADERS += propertyeditorview.h \
qmlanchorbindingproxy.h \
@@ -24,6 +31,13 @@ HEADERS += propertyeditorview.h \
propertyeditorwidget.h \
fileresourcesmodel.h \
gradientmodel.h \
- qmlmodelnodeproxy.h
+ qmlmodelnodeproxy.h \
+ gradientpresetitem.h \
+ gradientpresetlistmodel.h \
+ gradientpresetdefaultlistmodel.h \
+ gradientpresetcustomlistmodel.h \
+ simplecolorpalette.h \
+ simplecolorpalettemodel.h \
+ simplecolorpalettesingleton.h
QT += qml quick
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp
index dc8243e1c8..8fdab5a821 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp
@@ -152,22 +152,14 @@ void PropertyEditorContextObject::toogleExportAlias()
PropertyName modelNodeId = selectedNode.id().toUtf8();
ModelNode rootModelNode = rewriterView->rootModelNode();
- try {
- RewriterTransaction transaction =
- rewriterView->beginRewriterTransaction(QByteArrayLiteral("PropertyEditorContextObject:toogleExportAlias"));
-
+ rewriterView->executeInTransaction("PropertyEditorContextObject:toogleExportAlias", [&objectNode, &rootModelNode, modelNodeId](){
if (!objectNode.isAliasExported())
objectNode.ensureAliasExport();
else
if (rootModelNode.hasProperty(modelNodeId))
rootModelNode.removeProperty(modelNodeId);
-
- transaction.commit();
- } catch (RewritingException &exception) { //better safe than sorry! There always might be cases where we fail
- exception.showException();
- }
+ });
}
-
}
void PropertyEditorContextObject::changeTypeName(const QString &typeName)
@@ -181,11 +173,8 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName)
QTC_ASSERT(!rewriterView->selectedModelNodes().isEmpty(), return);
- ModelNode selectedNode = rewriterView->selectedModelNodes().constFirst();
-
- try {
- RewriterTransaction transaction =
- rewriterView->beginRewriterTransaction(QByteArrayLiteral("PropertyEditorContextObject:changeTypeName"));
+ rewriterView->executeInTransaction("PropertyEditorContextObject:changeTypeName", [this, rewriterView, typeName](){
+ ModelNode selectedNode = rewriterView->selectedModelNodes().constFirst();
NodeMetaInfo metaInfo = m_model->metaInfo(typeName.toLatin1());
if (!metaInfo.isValid()) {
@@ -193,16 +182,10 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName)
return;
}
if (selectedNode.isRootNode())
- rewriterView->changeRootNodeType(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion());
+ rewriterView->changeRootNodeType(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion());
else
selectedNode.changeType(metaInfo.typeName(), metaInfo.majorVersion(), metaInfo.minorVersion());
-
- transaction.commit();
- } catch (RewritingException &exception) { //better safe than sorry! There always might be cases where we fail
- exception.showException();
- }
-
-
+ });
}
void PropertyEditorContextObject::insertKeyframe(const QString &propertyName)
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
index 284b6948ee..12f12ed2bc 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
@@ -40,6 +40,7 @@
#include <coreplugin/icore.h>
#include <qmljs/qmljssimplereader.h>
+#include <utils/qtcassert.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h>
@@ -281,13 +282,17 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
setupLayoutAttachedProperties(qmlObjectNode, propertyEditor);
+ // model node
+ m_backendModelNode.setup(qmlObjectNode.modelNode());
+ context()->setContextProperty(QLatin1String("modelNodeBackend"), &m_backendModelNode);
+
// className
auto valueObject = qobject_cast<PropertyEditorValue*>(variantToQObject(m_backendValuesPropertyMap.value(QLatin1String("className"))));
if (!valueObject)
valueObject = new PropertyEditorValue(&m_backendValuesPropertyMap);
valueObject->setName("className");
valueObject->setModelNode(qmlObjectNode.modelNode());
- valueObject->setValue(qmlObjectNode.modelNode().simplifiedTypeName());
+ valueObject->setValue(m_backendModelNode.simplifiedTypeName());
QObject::connect(valueObject, &PropertyEditorValue::valueChanged, &backendValuesPropertyMap(), &DesignerPropertyMap::valueChanged);
m_backendValuesPropertyMap.insert(QLatin1String("className"), QVariant::fromValue(valueObject));
@@ -296,7 +301,7 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
if (!valueObject)
valueObject = new PropertyEditorValue(&m_backendValuesPropertyMap);
valueObject->setName("id");
- valueObject->setValue(qmlObjectNode.id());
+ valueObject->setValue(m_backendModelNode.nodeId());
QObject::connect(valueObject, &PropertyEditorValue::valueChanged, &backendValuesPropertyMap(), &DesignerPropertyMap::valueChanged);
m_backendValuesPropertyMap.insert(QLatin1String("id"), QVariant::fromValue(valueObject));
@@ -310,10 +315,6 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
qCInfo(propertyEditorBenchmark) << "anchors:" << time.elapsed();
- // model node
- m_backendModelNode.setup(qmlObjectNode.modelNode());
- context()->setContextProperty(QLatin1String("modelNodeBackend"), &m_backendModelNode);
-
qCInfo(propertyEditorBenchmark) << "context:" << time.elapsed();
contextObject()->setSpecificsUrl(qmlSpecificsFile);
@@ -402,23 +403,49 @@ QString PropertyEditorQmlBackend::propertyEditorResourcesPath() {
QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
const NodeMetaInfo &superType,
- const QmlObjectNode &objectNode)
+ const QmlObjectNode &node)
{
if (!templateConfiguration() || !templateConfiguration()->isValid())
return QString();
+ const auto nodes = templateConfiguration()->children();
+
+ QStringList sectorTypes;
+
+ for (const QmlJS::SimpleReaderNode::Ptr &node : nodes) {
+ if (node->propertyNames().contains("separateSection"))
+ sectorTypes.append(variantToStringList(node->property("typeNames")));
+ }
+
QStringList imports = variantToStringList(templateConfiguration()->property(QStringLiteral("imports")));
QString qmlTemplate = imports.join(QLatin1Char('\n')) + QLatin1Char('\n');
- qmlTemplate += QStringLiteral("Section {\n");
- qmlTemplate += QStringLiteral("caption: \"%1\"\n").arg(objectNode.modelNode().simplifiedTypeName());
- qmlTemplate += QStringLiteral("SectionLayout {\n");
+
+ qmlTemplate += "Column {\n";
+ qmlTemplate += "anchors.left: parent.left\n";
+ qmlTemplate += "anchors.right: parent.right\n";
QList<PropertyName> orderedList = type.propertyNames();
- Utils::sort(orderedList);
+ Utils::sort(orderedList, [type, &sectorTypes](const PropertyName &left, const PropertyName &right){
+ const QString typeNameLeft = QString::fromLatin1(type.propertyTypeName(left));
+ const QString typeNameRight = QString::fromLatin1(type.propertyTypeName(right));
+ if (typeNameLeft == typeNameRight)
+ return left > right;
+
+ if (sectorTypes.contains(typeNameLeft)) {
+ if (sectorTypes.contains(typeNameRight))
+ return left > right;
+ return true;
+ } else if (sectorTypes.contains(typeNameRight)) {
+ return false;
+ }
+ return left > right;
+ });
bool emptyTemplate = true;
+ bool sectionStarted = false;
+
foreach (const PropertyName &name, orderedList) {
if (name.startsWith("__"))
@@ -429,18 +456,38 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
TypeName typeName = type.propertyTypeName(name);
//alias resolution only possible with instance
- if (typeName == "alias" && objectNode.isValid())
- typeName = objectNode.instanceType(name);
+ if (typeName == "alias" && node.isValid())
+ typeName = node.instanceType(name);
+
+ auto nodes = templateConfiguration()->children();
if (!superType.hasProperty(name) && type.propertyIsWritable(name) && !name.contains(".")) {
- foreach (const QmlJS::SimpleReaderNode::Ptr &node, templateConfiguration()->children())
+
+ foreach (const QmlJS::SimpleReaderNode::Ptr &node, nodes)
if (variantToStringList(node->property(QStringLiteral("typeNames"))).contains(QString::fromLatin1(typeName))) {
const QString fileName = propertyTemplatesPath() + node->property(QStringLiteral("sourceFile")).toString();
QFile file(fileName);
if (file.open(QIODevice::ReadOnly)) {
QString source = QString::fromUtf8(file.readAll());
file.close();
+ const bool section = node->propertyNames().contains("separateSection");
+ if (section) {
+ qmlTemplate += "Section {\n";
+ qmlTemplate += "anchors.left: parent.left\n";
+ qmlTemplate += "anchors.right: parent.right\n";
+ qmlTemplate += QString("caption: \"%1\"\n").arg(QString::fromUtf8(properName));
+ } else if (!sectionStarted) {
+ qmlTemplate += QStringLiteral("Section {\n");
+ qmlTemplate += QStringLiteral("caption: \"%1\"\n").arg(QString::fromUtf8(type.simplifiedTypeName()));
+ qmlTemplate += "anchors.left: parent.left\n";
+ qmlTemplate += "anchors.right: parent.right\n";
+ qmlTemplate += QStringLiteral("SectionLayout {\n");
+ sectionStarted = true;
+ }
+
qmlTemplate += source.arg(QString::fromUtf8(name)).arg(QString::fromUtf8(properName));
+ if (section)
+ qmlTemplate += "}\n";
emptyTemplate = false;
} else {
qWarning().nospace() << "template definition source file not found:" << fileName;
@@ -448,8 +495,12 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &type,
}
}
}
- qmlTemplate += QStringLiteral("}\n"); //Section
- qmlTemplate += QStringLiteral("}\n"); //SectionLayout
+ if (sectionStarted) {
+ qmlTemplate += QStringLiteral("}\n"); //Section
+ qmlTemplate += QStringLiteral("}\n"); //SectionLayout
+ }
+
+ qmlTemplate += "}\n";
if (emptyTemplate)
return QString();
@@ -469,6 +520,36 @@ TypeName PropertyEditorQmlBackend::fixTypeNameForPanes(const TypeName &typeName)
return fixedTypeName;
}
+static NodeMetaInfo findCommonSuperClass(const NodeMetaInfo &first, const NodeMetaInfo &second)
+{
+ for (const NodeMetaInfo &info : first.superClasses()) {
+ if (second.isSubclassOf(info.typeName()))
+ return info;
+ }
+ return first;
+}
+
+NodeMetaInfo PropertyEditorQmlBackend::findCommonAncestor(const ModelNode &node)
+{
+ if (!node.isValid())
+ return {};
+
+ QTC_ASSERT(node.metaInfo().isValid(), return {});
+
+ AbstractView *view = node.view();
+
+ if (view->selectedModelNodes().count() > 1) {
+ NodeMetaInfo commonClass = node.metaInfo();
+ for (const ModelNode &currentNode : view->selectedModelNodes()) {
+ if (currentNode.metaInfo().isValid() && !currentNode.isSubclassOf(commonClass.typeName(), -1, -1))
+ commonClass = findCommonSuperClass(currentNode.metaInfo(), commonClass);
+ }
+ return commonClass;
+ }
+
+ return node.metaInfo();
+}
+
TypeName PropertyEditorQmlBackend::qmlFileName(const NodeMetaInfo &nodeInfo)
{
const TypeName fixedTypeName = fixTypeNameForPanes(nodeInfo.typeName());
@@ -526,10 +607,10 @@ void PropertyEditorQmlBackend::setValueforLayoutAttachedProperties(const QmlObje
setValue(qmlObjectNode, name, properDefaultLayoutAttachedProperties(qmlObjectNode, propertyName));
}
-QUrl PropertyEditorQmlBackend::getQmlUrlForModelNode(const ModelNode &modelNode, TypeName &className)
+QUrl PropertyEditorQmlBackend::getQmlUrlForMetaInfo(const NodeMetaInfo &metaInfo, TypeName &className)
{
- if (modelNode.isValid()) {
- foreach (const NodeMetaInfo &info, modelNode.metaInfo().classHierarchy()) {
+ if (metaInfo.isValid()) {
+ foreach (const NodeMetaInfo &info, metaInfo.classHierarchy()) {
QUrl fileUrl = fileToUrl(locateQmlFile(info, QString::fromUtf8(qmlFileName(info))));
if (fileUrl.isValid()) {
className = info.typeName();
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h
index a0012a1cc1..51279a1fc6 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h
@@ -68,11 +68,10 @@ public:
PropertyEditorValue *propertyValueForName(const QString &propertyName);
static QString propertyEditorResourcesPath();
- static QString templateGeneration(const NodeMetaInfo &type, const NodeMetaInfo &superType,
- const QmlObjectNode &objectNode);
+ static QString templateGeneration(const NodeMetaInfo &type, const NodeMetaInfo &superType, const QmlObjectNode &node);
static QUrl getQmlFileUrl(const TypeName &relativeTypeName, const NodeMetaInfo &info = NodeMetaInfo());
- static QUrl getQmlUrlForModelNode(const ModelNode &modelNode, TypeName &className);
+ static QUrl getQmlUrlForMetaInfo(const NodeMetaInfo &modelNode, TypeName &className);
static bool checkIfUrlExists(const QUrl &url);
@@ -83,6 +82,8 @@ public:
void setupLayoutAttachedProperties(const QmlObjectNode &qmlObjectNode, PropertyEditorView *propertyEditor);
+ static NodeMetaInfo findCommonAncestor(const ModelNode &node);
+
private:
void createPropertyEditorValue(const QmlObjectNode &qmlObjectNode,
const PropertyName &name, const QVariant &value,
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp
index 0467355bf4..9dd0a2da24 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp
@@ -213,20 +213,13 @@ void PropertyEditorView::changeValue(const QString &name)
castedValue = QVariant(newColor);
}
- try {
- if (!value->value().isValid()) { //reset
- qmlObjectNode.removeProperty(propertyName);
- } else {
- if (castedValue.isValid() && !castedValue.isNull()) {
- m_locked = true;
- qmlObjectNode.setVariantProperty(propertyName, castedValue);
- m_locked = false;
- }
+ if (!value->value().isValid()) { //reset
+ removePropertyFromModel(propertyName);
+ } else {
+ if (castedValue.isValid() && !castedValue.isNull()) {
+ commitVariantValueToModel(propertyName, castedValue);
}
}
- catch (const RewritingException &e) {
- e.showException();
- }
}
void PropertyEditorView::changeExpression(const QString &propertyName)
@@ -242,9 +235,7 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
if (!m_selectedNode.isValid())
return;
- RewriterTransaction transaction = beginRewriterTransaction(QByteArrayLiteral("PropertyEditorView::changeExpression"));
-
- try {
+ executeInTransaction("PropertyEditorView::changeExpression", [this, name](){
PropertyName underscoreName(name);
underscoreName.replace('.', '_');
@@ -260,7 +251,6 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(name) == "QColor") {
if (QColor(value->expression().remove('"')).isValid()) {
qmlObjectNode.setVariantProperty(name, QColor(value->expression().remove('"')));
- transaction.commit(); //committing in the try block
return;
}
} else if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(name) == "bool") {
@@ -270,7 +260,6 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
qmlObjectNode.setVariantProperty(name, true);
else
qmlObjectNode.setVariantProperty(name, false);
- transaction.commit(); //committing in the try block
return;
}
} else if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(name) == "int") {
@@ -278,7 +267,6 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
int intValue = value->expression().toInt(&ok);
if (ok) {
qmlObjectNode.setVariantProperty(name, intValue);
- transaction.commit(); //committing in the try block
return;
}
} else if (qmlObjectNode.modelNode().metaInfo().propertyTypeName(name) == "qreal") {
@@ -286,7 +274,6 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
qreal realValue = value->expression().toDouble(&ok);
if (ok) {
qmlObjectNode.setVariantProperty(name, realValue);
- transaction.commit(); //committing in the try block
return;
}
}
@@ -298,12 +285,7 @@ void PropertyEditorView::changeExpression(const QString &propertyName)
if (qmlObjectNode.expression(name) != value->expression() || !qmlObjectNode.propertyAffectedByCurrentState(name))
qmlObjectNode.setBindingProperty(name, value->expression());
- transaction.commit(); //committing in the try block
- }
-
- catch (const RewritingException &e) {
- e.showException();
- }
+ }); /* end of transaction */
}
void PropertyEditorView::exportPopertyAsAlias(const QString &name)
@@ -317,9 +299,7 @@ void PropertyEditorView::exportPopertyAsAlias(const QString &name)
if (!m_selectedNode.isValid())
return;
- RewriterTransaction transaction = beginRewriterTransaction(QByteArrayLiteral("PropertyEditorView::exportPopertyAsAlias"));
-
- try {
+ executeInTransaction("PropertyEditorView::exportPopertyAsAlias", [this, name](){
const QString id = m_selectedNode.validId();
QString upperCasePropertyName = name;
upperCasePropertyName.replace(0, 1, upperCasePropertyName.at(0).toUpper());
@@ -333,11 +313,7 @@ void PropertyEditorView::exportPopertyAsAlias(const QString &name)
return;
}
rootModelNode().bindingProperty(propertyName).setDynamicTypeNameAndExpression("alias", id + "." + name);
-
- transaction.commit(); //committing in the try block
- } catch (const RewritingException &e) {
- e.showException();
- }
+ });
}
void PropertyEditorView::removeAliasExport(const QString &name)
@@ -351,9 +327,7 @@ void PropertyEditorView::removeAliasExport(const QString &name)
if (!m_selectedNode.isValid())
return;
- RewriterTransaction transaction = beginRewriterTransaction(QByteArrayLiteral("PropertyEditorView::exportPopertyAsAlias"));
-
- try {
+ executeInTransaction("PropertyEditorView::exportPopertyAsAlias", [this, name](){
const QString id = m_selectedNode.validId();
for (const BindingProperty &property : rootModelNode().bindingProperties())
@@ -361,10 +335,7 @@ void PropertyEditorView::removeAliasExport(const QString &name)
rootModelNode().removeProperty(property.name());
break;
}
- transaction.commit(); //committing in the try block
- } catch (const RewritingException &e) {
- e.showException();
- }
+ });
}
bool PropertyEditorView::locked() const
@@ -446,13 +417,16 @@ void PropertyEditorView::resetView()
void PropertyEditorView::setupQmlBackend()
{
TypeName specificsClassName;
- QUrl qmlFile(PropertyEditorQmlBackend::getQmlUrlForModelNode(m_selectedNode, specificsClassName));
+
+ const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor(m_selectedNode);
+
+ const QUrl qmlFile(PropertyEditorQmlBackend::getQmlUrlForMetaInfo(commonAncestor, specificsClassName));
QUrl qmlSpecificsFile;
TypeName diffClassName;
- if (m_selectedNode.isValid()) {
- diffClassName = m_selectedNode.metaInfo().typeName();
- foreach (const NodeMetaInfo &metaInfo, m_selectedNode.metaInfo().classHierarchy()) {
+ if (commonAncestor.isValid()) {
+ diffClassName = commonAncestor.typeName();
+ foreach (const NodeMetaInfo &metaInfo, commonAncestor.classHierarchy()) {
if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile))
break;
qmlSpecificsFile = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName() + "Specifics", metaInfo);
@@ -465,8 +439,8 @@ void PropertyEditorView::setupQmlBackend()
QString specificQmlData;
- if (m_selectedNode.isValid() && m_selectedNode.metaInfo().isValid() && diffClassName != m_selectedNode.type())
- specificQmlData = PropertyEditorQmlBackend::templateGeneration(m_selectedNode.metaInfo(), model()->metaInfo(diffClassName), m_selectedNode);
+ if (commonAncestor.isValid() && m_selectedNode.metaInfo().isValid() && diffClassName != m_selectedNode.type())
+ specificQmlData = PropertyEditorQmlBackend::templateGeneration(commonAncestor, model()->metaInfo(diffClassName), m_selectedNode);
PropertyEditorQmlBackend *currentQmlBackend = m_qmlBackendHash.value(qmlFile.toString());
@@ -515,14 +489,51 @@ void PropertyEditorView::setupQmlBackend()
}
+void PropertyEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value)
+{
+ m_locked = true;
+ try {
+ RewriterTransaction transaction = beginRewriterTransaction("PropertyEditorView::commitVariantValueToMode");
+
+ for (const ModelNode &node : m_selectedNode.view()->selectedModelNodes()) {
+ if (QmlObjectNode::isValidQmlObjectNode(node))
+ QmlObjectNode(node).setVariantProperty(propertyName, value);
+ }
+ transaction.commit();
+ }
+ catch (const RewritingException &e) {
+ e.showException();
+ }
+ m_locked = false;
+}
+
+void PropertyEditorView::removePropertyFromModel(const PropertyName &propertyName)
+{
+ m_locked = true;
+ try {
+ RewriterTransaction transaction = beginRewriterTransaction("PropertyEditorView::removePropertyFromModel");
+
+ for (const ModelNode &node : m_selectedNode.view()->selectedModelNodes()) {
+ if (QmlObjectNode::isValidQmlObjectNode(node))
+ QmlObjectNode(node).removeProperty(propertyName);
+ }
+
+ transaction.commit();
+ }
+ catch (const RewritingException &e) {
+ e.showException();
+ }
+ m_locked = false;
+}
+
void PropertyEditorView::selectedNodesChanged(const QList<ModelNode> &selectedNodeList,
const QList<ModelNode> &lastSelectedNodeList)
{
Q_UNUSED(lastSelectedNodeList);
- if (selectedNodeList.isEmpty() || selectedNodeList.count() > 1)
+ if (selectedNodeList.isEmpty())
select(ModelNode());
- else if (m_selectedNode != selectedNodeList.constFirst())
+ else
select(selectedNodeList.constFirst());
}
@@ -542,10 +553,11 @@ void PropertyEditorView::modelAttached(Model *model)
m_locked = true;
if (!m_setupCompleted) {
- m_singleShotTimer->setSingleShot(true);
- m_singleShotTimer->setInterval(100);
- connect(m_singleShotTimer, &QTimer::timeout, this, &PropertyEditorView::setupPanes);
- m_singleShotTimer->start();
+ QTimer::singleShot(50, this, [this]{
+ PropertyEditorView::setupPanes();
+ /* workaround for QTBUG-75847 */
+ reloadQml();
+ });
}
m_locked = false;
@@ -648,6 +660,9 @@ void PropertyEditorView::instanceInformationsChanged(const QMultiHash<ModelNode,
if (!m_selectedNode.isValid())
return;
+ if (!m_qmlBackEndForCurrentType)
+ return;
+
m_locked = true;
QList<InformationName> informationNameList = informationChangedHash.values(m_selectedNode);
if (informationNameList.contains(Anchor)
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h
index 85bd8286f5..e7f57cf186 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h
@@ -110,6 +110,9 @@ private: //functions
void delayedResetView();
void setupQmlBackend();
+ void commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value);
+ void removePropertyFromModel(const PropertyName &propertyName);
+
private: //variables
ModelNode m_selectedNode;
QWidget *m_parent;
diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp
index bc6b4376b6..7a38f74f34 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp
@@ -292,9 +292,9 @@ void QmlAnchorBindingProxy::setDefaultRelativeRightTarget()
}
}
-RewriterTransaction QmlAnchorBindingProxy::beginRewriterTransaction(const QByteArray &identifier)
+bool QmlAnchorBindingProxy::executeInTransaction(const QByteArray &identifier, const AbstractView::OperationBlock &lambda)
{
- return m_qmlItemNode.modelNode().view()->beginRewriterTransaction(identifier);
+ return m_qmlItemNode.modelNode().view()->executeInTransaction(identifier, lambda);
}
bool QmlAnchorBindingProxy::hasParent() const
@@ -361,20 +361,11 @@ void QmlAnchorBindingProxy::setTopTarget(const QString &target)
if (!newTarget.isValid())
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setTopTarget"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setTopTarget", [this, newTarget](){
m_topTarget = newTarget;
-
setDefaultRelativeTopTarget();
-
anchorTop();
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit topTargetChanged();
}
@@ -393,18 +384,12 @@ void QmlAnchorBindingProxy::setBottomTarget(const QString &target)
if (!newTarget.isValid())
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setBottomTarget"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setBottomTarget", [this, newTarget](){
m_bottomTarget = newTarget;
setDefaultRelativeBottomTarget();
anchorBottom();
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit bottomTargetChanged();
}
@@ -422,18 +407,11 @@ void QmlAnchorBindingProxy::setLeftTarget(const QString &target)
if (!newTarget.isValid())
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setLeftTarget"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setLeftTarget", [this, newTarget](){
m_leftTarget = newTarget;
setDefaultRelativeLeftTarget();
anchorLeft();
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit leftTargetChanged();
}
@@ -451,18 +429,11 @@ void QmlAnchorBindingProxy::setRightTarget(const QString &target)
if (!newTarget.isValid())
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setRightTarget"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setRightTarget", [this, newTarget](){
m_rightTarget = newTarget;
setDefaultRelativeRightTarget();
anchorRight();
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit rightTargetChanged();
}
@@ -480,17 +451,10 @@ void QmlAnchorBindingProxy::setVerticalTarget(const QString &target)
if (!newTarget.isValid())
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setVerticalTarget"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setVerticalTarget", [this, newTarget](){
m_verticalTarget = newTarget;
anchorVertical();
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit verticalTargetChanged();
}
@@ -508,17 +472,10 @@ void QmlAnchorBindingProxy::setHorizontalTarget(const QString &target)
if (!newTarget.isValid())
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setHorizontalTarget"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setHorizontalTarget", [this, newTarget](){
m_horizontalTarget = newTarget;
- anchorHorizontal();\
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ anchorHorizontal();
+ });
emit horizontalTargetChanged();
}
@@ -531,18 +488,10 @@ void QmlAnchorBindingProxy::setRelativeAnchorTargetTop(QmlAnchorBindingProxy::Re
if (target == m_relativeTopTarget)
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setRelativeAnchorTargetTop"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setRelativeAnchorTargetTop", [this, target](){
m_relativeTopTarget = target;
-
anchorTop();
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit relativeAnchorTargetTopChanged();
}
@@ -555,19 +504,10 @@ void QmlAnchorBindingProxy::setRelativeAnchorTargetBottom(QmlAnchorBindingProxy:
if (target == m_relativeBottomTarget)
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setRelativeAnchorTargetBottom"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setRelativeAnchorTargetBottom", [this, target](){
m_relativeBottomTarget = target;
-
-
anchorBottom();
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit relativeAnchorTargetBottomChanged();
}
@@ -580,18 +520,11 @@ void QmlAnchorBindingProxy::setRelativeAnchorTargetLeft(QmlAnchorBindingProxy::R
if (target == m_relativeLeftTarget)
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setRelativeAnchorTargetLeft"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setRelativeAnchorTargetLeft", [this, target](){
m_relativeLeftTarget = target;
-
anchorLeft();
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit relativeAnchorTargetLeftChanged();
}
@@ -604,18 +537,10 @@ void QmlAnchorBindingProxy::setRelativeAnchorTargetRight(QmlAnchorBindingProxy::
if (target == m_relativeRightTarget)
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setRelativeAnchorTargetRight"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setRelativeAnchorTargetRight", [this, target](){
m_relativeRightTarget = target;
-
anchorRight();
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit relativeAnchorTargetRightChanged();
@@ -629,18 +554,11 @@ void QmlAnchorBindingProxy::setRelativeAnchorTargetVertical(QmlAnchorBindingProx
if (target == m_relativeVerticalTarget)
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setRelativeAnchorTargetVertical"));
+ executeInTransaction("QmlAnchorBindingProxy::setRelativeAnchorTargetVertical", [this, target](){
m_relativeVerticalTarget = target;
-
anchorVertical();
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit relativeAnchorTargetVerticalChanged();
}
@@ -653,18 +571,10 @@ void QmlAnchorBindingProxy::setRelativeAnchorTargetHorizontal(QmlAnchorBindingPr
if (target == m_relativeHorizontalTarget)
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setRelativeAnchorTargetHorizontal"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setRelativeAnchorTargetHorizontal", [this, target](){
m_relativeHorizontalTarget = target;
-
anchorHorizontal();
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit relativeAnchorTargetHorizontalChanged();
}
@@ -709,12 +619,10 @@ int QmlAnchorBindingProxy::indexOfPossibleTargetItem(const QString &targetName)
return possibleTargetItems().indexOf(targetName);
}
-void QmlAnchorBindingProxy::resetLayout() {
-
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::resetLayout"));
+void QmlAnchorBindingProxy::resetLayout()
+{
+ executeInTransaction("QmlAnchorBindingProxy::resetLayout", [this](){
m_qmlItemNode.anchors().removeAnchors();
m_qmlItemNode.anchors().removeMargins();
@@ -722,11 +630,7 @@ void QmlAnchorBindingProxy::resetLayout() {
restoreProperty(modelNode(), "y");
restoreProperty(modelNode(), "width");
restoreProperty(modelNode(), "height");
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit topAnchorChanged();
emit bottomAnchorChanged();
@@ -743,10 +647,7 @@ void QmlAnchorBindingProxy::setBottomAnchor(bool anchor)
if (bottomAnchored() == anchor)
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setBottomAnchor"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setBottomAnchor", [this, anchor](){
if (!anchor) {
removeBottomAnchor();
} else {
@@ -756,10 +657,7 @@ void QmlAnchorBindingProxy::setBottomAnchor(bool anchor)
backupPropertyAndRemove(modelNode(), "height");
}
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit relativeAnchorTargetBottomChanged();
emit bottomAnchorChanged();
@@ -776,10 +674,8 @@ void QmlAnchorBindingProxy::setLeftAnchor(bool anchor)
if (leftAnchored() == anchor)
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setLeftAnchor"));
+ executeInTransaction("QmlAnchorBindingProxy::setLeftAnchor", [this, anchor](){
if (!anchor) {
removeLeftAnchor();
} else {
@@ -791,10 +687,7 @@ void QmlAnchorBindingProxy::setLeftAnchor(bool anchor)
backupPropertyAndRemove(modelNode(), "width");
}
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit relativeAnchorTargetLeftChanged();
emit leftAnchorChanged();
@@ -810,10 +703,7 @@ void QmlAnchorBindingProxy::setRightAnchor(bool anchor)
if (rightAnchored() == anchor)
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setRightAnchor"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setRightAnchor", [this, anchor](){
if (!anchor) {
removeRightAnchor();
} else {
@@ -824,10 +714,7 @@ void QmlAnchorBindingProxy::setRightAnchor(bool anchor)
backupPropertyAndRemove(modelNode(), "width");
}
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit relativeAnchorTargetRightChanged();
emit rightAnchorChanged();
@@ -1026,10 +913,7 @@ void QmlAnchorBindingProxy::setTopAnchor(bool anchor)
if (topAnchored() == anchor)
return;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setTopAnchor"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setTopAnchor", [this, anchor](){
if (!anchor) {
removeTopAnchor();
} else {
@@ -1040,10 +924,7 @@ void QmlAnchorBindingProxy::setTopAnchor(bool anchor)
if (bottomAnchored())
backupPropertyAndRemove(modelNode(), "height");
}
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit relativeAnchorTargetTopChanged();
emit topAnchorChanged();
@@ -1052,70 +933,44 @@ void QmlAnchorBindingProxy::setTopAnchor(bool anchor)
}
void QmlAnchorBindingProxy::removeTopAnchor() {
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::removeTopAnchor"));
-
+ executeInTransaction("QmlAnchorBindingProxy::removeTopAnchor", [this](){
m_qmlItemNode.anchors().removeAnchor(AnchorLineTop);
m_qmlItemNode.anchors().removeMargin(AnchorLineTop);
restoreProperty(modelNode(), "y");
restoreProperty(modelNode(), "height");
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
}
-void QmlAnchorBindingProxy::removeBottomAnchor() {
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::removeBottomAnchor"));
-
+void QmlAnchorBindingProxy::removeBottomAnchor()
+{
+ executeInTransaction("QmlAnchorBindingProxy::removeBottomAnchor", [this](){
m_qmlItemNode.anchors().removeAnchor(AnchorLineBottom);
m_qmlItemNode.anchors().removeMargin(AnchorLineBottom);
-
restoreProperty(modelNode(), "height");
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
}
-void QmlAnchorBindingProxy::removeLeftAnchor() {
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::removeLeftAnchor"));
-
+void QmlAnchorBindingProxy::removeLeftAnchor()
+{
+ executeInTransaction("QmlAnchorBindingProxy::removeLeftAnchor", [this](){
m_qmlItemNode.anchors().removeAnchor(AnchorLineLeft);
m_qmlItemNode.anchors().removeMargin(AnchorLineLeft);
restoreProperty(modelNode(), "x");
restoreProperty(modelNode(), "width");
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
}
-void QmlAnchorBindingProxy::removeRightAnchor() {
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::removeRightAnchor"));
-
+void QmlAnchorBindingProxy::removeRightAnchor()
+{
+ executeInTransaction("QmlAnchorBindingProxy::removeRightAnchor", [this](){
m_qmlItemNode.anchors().removeAnchor(AnchorLineRight);
m_qmlItemNode.anchors().removeMargin(AnchorLineRight);
restoreProperty(modelNode(), "width");
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
}
void QmlAnchorBindingProxy::setVerticalCentered(bool centered)
@@ -1128,10 +983,7 @@ void QmlAnchorBindingProxy::setVerticalCentered(bool centered)
m_locked = true;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setVerticalCentered"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setVerticalCentered", [this, centered](){
if (!centered) {
m_qmlItemNode.anchors().removeAnchor(AnchorLineVerticalCenter);
m_qmlItemNode.anchors().removeMargin(AnchorLineVerticalCenter);
@@ -1141,10 +993,7 @@ void QmlAnchorBindingProxy::setVerticalCentered(bool centered)
anchorVertical();
}
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
m_locked = false;
emit relativeAnchorTargetVerticalChanged();
@@ -1161,10 +1010,7 @@ void QmlAnchorBindingProxy::setHorizontalCentered(bool centered)
m_locked = true;
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::setHorizontalCentered"));
-
+ executeInTransaction("QmlAnchorBindingProxy::setHorizontalCentered", [this, centered](){
if (!centered) {
m_qmlItemNode.anchors().removeAnchor(AnchorLineHorizontalCenter);
m_qmlItemNode.anchors().removeMargin(AnchorLineHorizontalCenter);
@@ -1173,11 +1019,7 @@ void QmlAnchorBindingProxy::setHorizontalCentered(bool centered)
anchorHorizontal();
}
-
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
m_locked = false;
emit relativeAnchorTargetHorizontalChanged();
@@ -1256,12 +1098,7 @@ bool QmlAnchorBindingProxy::horizontalCentered()
void QmlAnchorBindingProxy::fill()
{
-
- try {
- RewriterTransaction transaction = beginRewriterTransaction(
- QByteArrayLiteral("QmlAnchorBindingProxy::fill"));
-
-
+ executeInTransaction("QmlAnchorBindingProxy::fill", [this](){
backupPropertyAndRemove(modelNode(), "x");
backupPropertyAndRemove(modelNode(), "y");
backupPropertyAndRemove(modelNode(), "width");
@@ -1277,10 +1114,7 @@ void QmlAnchorBindingProxy::fill()
m_qmlItemNode.anchors().removeMargin(AnchorLineTop);
m_qmlItemNode.anchors().removeMargin(AnchorLineBottom);
- transaction.commit();
- } catch (const Exception &e) {
- e.showException();
- }
+ });
emit topAnchorChanged();
emit bottomAnchorChanged();
diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h
index cf42ea055a..0bd562add2 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h
@@ -210,7 +210,7 @@ private:
void setDefaultRelativeLeftTarget();
void setDefaultRelativeRightTarget();
- RewriterTransaction beginRewriterTransaction(const QByteArray &identifier);
+ bool executeInTransaction(const QByteArray &identifier, const AbstractView::OperationBlock &lambda);
QmlItemNode targetIdToNode(const QString &id) const;
QString idForNode(const QmlItemNode &qmlItemNode) const;
diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp
index 6f56b055c8..934c284691 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp
@@ -23,6 +23,7 @@
**
****************************************************************************/
+#include "abstractview.h"
#include "qmlmodelnodeproxy.h"
#include <QtQml>
@@ -66,4 +67,34 @@ ModelNode QmlModelNodeProxy::modelNode() const
return m_qmlItemNode.modelNode();
}
+bool QmlModelNodeProxy::multiSelection() const
+{
+ if (!m_qmlItemNode.isValid())
+ return false;
+
+ return m_qmlItemNode.view()->selectedModelNodes().count() > 1;
+}
+
+QString QmlModelNodeProxy::nodeId() const
+{
+ if (!m_qmlItemNode.isValid())
+ return {};
+
+ if (multiSelection())
+ return tr("multiselection");
+
+ return m_qmlItemNode.id();
+}
+
+QString QmlModelNodeProxy::simplifiedTypeName() const
+{
+ if (!m_qmlItemNode.isValid())
+ return {};
+
+ if (multiSelection())
+ return tr("multiselection");
+
+ return m_qmlItemNode.simplifiedTypeName();
+}
+
}
diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h
index 0a73583355..6037f32752 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h
+++ b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h
@@ -35,7 +35,8 @@ class QmlModelNodeProxy : public QObject
{
Q_OBJECT
- Q_PROPERTY(QmlDesigner::ModelNode modelNode READ modelNode NOTIFY modelNodeChanged)
+ Q_PROPERTY(QmlDesigner::ModelNode modelNode READ modelNode NOTIFY modelNodeChanged)
+ Q_PROPERTY(bool multiSelection READ multiSelection NOTIFY modelNodeChanged)
public:
explicit QmlModelNodeProxy(QObject *parent = nullptr);
@@ -51,6 +52,12 @@ public:
ModelNode modelNode() const;
+ bool multiSelection() const;
+
+ QString nodeId() const;
+
+ QString simplifiedTypeName() const;
+
signals:
void modelNodeChanged();
void selectionToBeChanged();
diff --git a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp
index 4e58374759..862d16ba22 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/quick2propertyeditorview.cpp
@@ -28,6 +28,9 @@
#include "propertyeditorvalue.h"
#include "fileresourcesmodel.h"
#include "gradientmodel.h"
+#include "gradientpresetdefaultlistmodel.h"
+#include "gradientpresetcustomlistmodel.h"
+#include "simplecolorpalettemodel.h"
#include "qmlanchorbindingproxy.h"
#include "theme.h"
@@ -48,6 +51,9 @@ void Quick2PropertyEditorView::registerQmlTypes()
PropertyEditorValue::registerDeclarativeTypes();
FileResourcesModel::registerDeclarativeType();
GradientModel::registerDeclarativeType();
+ GradientPresetDefaultListModel::registerDeclarativeType();
+ GradientPresetCustomListModel::registerDeclarativeType();
+ SimpleColorPaletteModel::registerDeclarativeType();
Internal::QmlAnchorBindingProxy::registerDeclarativeType();
}
}
diff --git a/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalette.cpp b/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalette.cpp
new file mode 100644
index 0000000000..c88d83aa0a
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalette.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "simplecolorpalette.h"
+
+#include "designersettings.h"
+
+#include <QDebug>
+
+namespace QmlDesigner {
+
+PaletteColor::PaletteColor()
+ : m_color(QColor())
+ , m_colorCode(QColor().name())
+ , m_isFavorite(false)
+{}
+
+PaletteColor::PaletteColor(const QString &colorCode)
+ : m_color(colorCode)
+ , m_colorCode(colorCode)
+ , m_isFavorite(false)
+{}
+
+PaletteColor::PaletteColor(const QColor &color)
+ : m_color(color)
+ , m_colorCode(color.name(QColor::HexArgb))
+ , m_isFavorite(false)
+{}
+
+QVariant PaletteColor::getProperty(Property id) const
+{
+ QVariant out;
+
+ switch (id) {
+ case objectNameRole:
+ out.setValue(QString());
+ break;
+ case colorRole:
+ out.setValue(color());
+ break;
+ case colorCodeRole:
+ out.setValue(colorCode());
+ break;
+ case isFavoriteRole:
+ out.setValue(isFavorite());
+ break;
+ default:
+ qWarning() << "PaletteColor Property switch default case";
+ break; //replace with assert before switch?
+ }
+
+ return out;
+}
+
+QColor PaletteColor::color() const
+{
+ return m_color;
+}
+
+void PaletteColor::setColor(const QColor &value)
+{
+ m_color = value;
+ m_colorCode = m_color.name(QColor::HexArgb);
+}
+
+QString PaletteColor::colorCode() const
+{
+ return m_colorCode;
+}
+
+bool PaletteColor::isFavorite() const
+{
+ return m_isFavorite;
+}
+
+void PaletteColor::setFavorite(bool favorite)
+{
+ m_isFavorite = favorite;
+}
+
+bool PaletteColor::toggleFavorite()
+{
+ return m_isFavorite = !m_isFavorite;
+}
+
+bool PaletteColor::operator==(const PaletteColor &other) const
+{
+ return (m_color == other.m_color);
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalette.h b/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalette.h
new file mode 100644
index 0000000000..342c9832e7
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalette.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QObject>
+#include <QtQml/qqml.h>
+#include <QColor>
+
+namespace QmlDesigner {
+
+class PaletteColor
+{
+ Q_GADGET
+
+ Q_PROPERTY(QColor color READ color FINAL)
+ Q_PROPERTY(QString colorCode READ colorCode FINAL)
+ Q_PROPERTY(bool isFavorite READ isFavorite FINAL)
+public:
+ PaletteColor();
+ PaletteColor(const QString &colorCode);
+ PaletteColor(const QColor &value);
+ ~PaletteColor() = default;
+
+ enum Property {
+ objectNameRole = 0,
+ colorRole = 1,
+ colorCodeRole = 2,
+ isFavoriteRole = 3
+ };
+
+ QVariant getProperty(Property id) const;
+
+ QColor color() const;
+ void setColor(const QColor &value);
+
+ QString colorCode() const;
+
+ bool isFavorite() const;
+ void setFavorite(bool favorite);
+ bool toggleFavorite();
+
+ bool operator==(const PaletteColor &other) const;
+
+private:
+ QColor m_color;
+ QString m_colorCode;
+ bool m_isFavorite;
+};
+
+} // namespace QmlDesigner
+
+Q_DECLARE_METATYPE(QmlDesigner::PaletteColor)
diff --git a/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettemodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettemodel.cpp
new file mode 100644
index 0000000000..b3207f0006
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettemodel.cpp
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "simplecolorpalettemodel.h"
+#include "simplecolorpalette.h"
+#include "simplecolorpalettesingleton.h"
+
+#include "designersettings.h"
+
+#include <QHash>
+#include <QByteArray>
+#include <QDebug>
+#include <QSettings>
+
+namespace QmlDesigner {
+
+SimpleColorPaletteModel::SimpleColorPaletteModel(QObject *parent)
+ : QAbstractListModel(parent)
+{
+ connect(&SimpleColorPaletteSingleton::getInstance(),
+ &SimpleColorPaletteSingleton::paletteChanged,
+ this,
+ &SimpleColorPaletteModel::setPalette);
+ m_roleNames = {{static_cast<int>(PaletteColor::Property::objectNameRole), "objectName"},
+ {static_cast<int>(PaletteColor::Property::colorRole), "color"},
+ {static_cast<int>(PaletteColor::Property::colorCodeRole), "colorCode"},
+ {static_cast<int>(PaletteColor::Property::isFavoriteRole), "isFavorite"}};
+
+ setPalette();
+}
+
+SimpleColorPaletteModel::~SimpleColorPaletteModel()
+{
+ clearItems();
+}
+
+int SimpleColorPaletteModel::rowCount(const QModelIndex & /*parent*/) const
+{
+ return m_items.count();
+}
+
+QVariant SimpleColorPaletteModel::data(const QModelIndex &index, int role) const
+{
+ if (index.isValid() && (index.row() >= 0) && (index.row() < m_items.count())) {
+ if (m_roleNames.contains(role)) {
+ QVariant value = m_items.at(index.row())
+ .getProperty(static_cast<PaletteColor::Property>(role));
+ if (auto model = qobject_cast<SimpleColorPaletteModel *>(value.value<QObject *>()))
+ return QVariant::fromValue(model);
+
+ return value;
+ }
+
+ qWarning() << Q_FUNC_INFO << "invalid role requested";
+ return QVariant();
+ }
+
+ qWarning() << Q_FUNC_INFO << "invalid index requested";
+ return QVariant();
+}
+
+QHash<int, QByteArray> SimpleColorPaletteModel::roleNames() const
+{
+ return m_roleNames;
+}
+
+void SimpleColorPaletteModel::clearItems()
+{
+ beginResetModel();
+ m_items.clear();
+ endResetModel();
+}
+
+void SimpleColorPaletteModel::addItem(const QString &item)
+{
+ PaletteColor palette(item);
+ addItem(palette);
+}
+
+void SimpleColorPaletteModel::addItem(const PaletteColor &item)
+{
+ SimpleColorPaletteSingleton::getInstance().addItem(item);
+}
+
+const QList<PaletteColor> &SimpleColorPaletteModel::items() const
+{
+ return m_items;
+}
+
+void SimpleColorPaletteModel::sortItems()
+{
+ SimpleColorPaletteSingleton::getInstance().sortItems();
+}
+
+void SimpleColorPaletteModel::registerDeclarativeType()
+{
+ qmlRegisterType<SimpleColorPaletteModel>("HelperWidgets", 2, 0, "SimpleColorPaletteModel");
+}
+
+void SimpleColorPaletteModel::toggleFavorite(int id)
+{
+ SimpleColorPaletteSingleton::getInstance().toggleFavorite(id);
+}
+
+void SimpleColorPaletteModel::setPalette()
+{
+ beginResetModel();
+ m_items = SimpleColorPaletteSingleton::getInstance().getItems();
+ m_favoriteOffset = SimpleColorPaletteSingleton::getInstance().getFavoriteOffset();
+ m_paletteSize = SimpleColorPaletteSingleton::getInstance().getPaletteSize();
+ endResetModel();
+}
+
+bool SimpleColorPaletteModel::read()
+{
+ return SimpleColorPaletteSingleton::getInstance().readPalette();
+}
+
+void SimpleColorPaletteModel::write()
+{
+ SimpleColorPaletteSingleton::getInstance().writePalette();
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettemodel.h b/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettemodel.h
new file mode 100644
index 0000000000..3ed2cc8a31
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettemodel.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QAbstractListModel>
+#include <QtQml/qqml.h>
+#include <QList>
+
+namespace QmlDesigner {
+
+class PaletteColor;
+
+class SimpleColorPaletteModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ explicit SimpleColorPaletteModel(QObject *parent = nullptr);
+ ~SimpleColorPaletteModel() override;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ QHash<int, QByteArray> roleNames() const override;
+
+ void clearItems();
+ Q_INVOKABLE void addItem(const QString &item);
+ void addItem(const PaletteColor &item);
+
+ const QList<PaletteColor> &items() const;
+
+ void sortItems();
+
+ static void registerDeclarativeType();
+
+ Q_INVOKABLE void toggleFavorite(int id);
+
+ bool read();
+ void write();
+
+private slots:
+ void setPalette();
+
+private:
+ void enqueue(const PaletteColor &item);
+
+private:
+ int m_paletteSize;
+ int m_favoriteOffset;
+ QList<PaletteColor> m_items;
+ QHash<int, QByteArray> m_roleNames;
+};
+
+} // namespace QmlDesigner
+
+QML_DECLARE_TYPE(QmlDesigner::SimpleColorPaletteModel)
diff --git a/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettesingleton.cpp b/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettesingleton.cpp
new file mode 100644
index 0000000000..ccea50bbf2
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettesingleton.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "simplecolorpalettesingleton.h"
+#include "simplecolorpalette.h"
+
+#include "designersettings.h"
+
+#include <QDebug>
+#include <QSettings>
+
+namespace QmlDesigner {
+
+SimpleColorPaletteSingleton::SimpleColorPaletteSingleton()
+ : m_items()
+ , m_favoriteOffset(0)
+{
+ if (!readPalette()) {
+ for (int i = 0; i < m_paletteSize; i++)
+ m_items.append(PaletteColor());
+ }
+}
+
+SimpleColorPaletteSingleton &SimpleColorPaletteSingleton::getInstance()
+{
+ static SimpleColorPaletteSingleton singleton;
+
+ return singleton;
+}
+
+void SimpleColorPaletteSingleton::addItem(const PaletteColor &item)
+{
+ if (m_favoriteOffset >= m_paletteSize)
+ return;
+
+ if (item.isFavorite()) {
+ int contains = m_items.indexOf(item);
+ if (contains != -1) {
+ if (m_items.at(contains).isFavorite())
+ return;
+ else
+ m_items.removeAt(contains);
+ }
+ m_items.insert(0, item);
+ m_favoriteOffset++;
+ } else if (m_items.contains(item))
+ return;
+ else
+ m_items.insert(m_favoriteOffset, item);
+
+ while (m_items.size() > m_paletteSize) {
+ m_items.removeLast();
+ }
+
+ writePalette();
+
+ emit paletteChanged();
+}
+
+QList<PaletteColor> SimpleColorPaletteSingleton::getItems() const
+{
+ return m_items;
+}
+
+int SimpleColorPaletteSingleton::getPaletteSize() const
+{
+ return m_paletteSize;
+}
+
+int SimpleColorPaletteSingleton::getFavoriteOffset() const
+{
+ return m_favoriteOffset;
+}
+
+void SimpleColorPaletteSingleton::sortItems()
+{
+ auto itemSort = [](const PaletteColor &first, const PaletteColor &second) {
+ return (static_cast<int>(first.isFavorite()) < static_cast<int>(second.isFavorite()));
+ };
+
+ std::sort(m_items.begin(), m_items.end(), itemSort);
+
+ emit paletteChanged();
+}
+
+void SimpleColorPaletteSingleton::toggleFavorite(int id)
+{
+ bool toggleResult = m_items[id].toggleFavorite();
+
+ if (toggleResult) {
+ m_favoriteOffset++;
+ m_items.move(id, 0);
+ } else {
+ m_favoriteOffset--;
+ m_items.move(id, m_favoriteOffset);
+ }
+
+ if (m_favoriteOffset < 0)
+ m_favoriteOffset = 0;
+ else if (m_favoriteOffset > m_paletteSize)
+ m_favoriteOffset = m_paletteSize;
+
+ emit paletteChanged();
+}
+
+bool SimpleColorPaletteSingleton::readPalette()
+{
+ QList<PaletteColor> proxy;
+ const QStringList stringData = QmlDesigner::DesignerSettings::getValue(
+ QmlDesigner::DesignerSettingsKey::SIMPLE_COLOR_PALETTE_CONTENT)
+ .toStringList();
+
+ int favCounter = 0;
+
+ for (int i = 0; i < stringData.size(); i++) {
+ const QStringList strsep = stringData.at(i).split(";");
+ if (strsep.size() != 2) {
+ continue;
+ }
+ PaletteColor colorItem(strsep.at(0));
+ bool isFav = static_cast<bool>(strsep.at(1).toInt());
+ colorItem.setFavorite(isFav);
+ if (isFav)
+ favCounter++;
+ proxy.append(colorItem);
+ }
+
+ if (proxy.size() == 0) {
+ return false;
+ }
+
+ while (proxy.size() > m_paletteSize) {
+ proxy.removeLast();
+ }
+ while (proxy.size() < m_paletteSize) {
+ proxy.append(PaletteColor());
+ }
+
+ m_items.clear();
+ m_items = proxy;
+ m_favoriteOffset = favCounter;
+
+ return true;
+}
+
+void SimpleColorPaletteSingleton::writePalette()
+{
+ QStringList output;
+ QString subres;
+
+ for (int i = 0; i < m_items.size(); i++) {
+ subres = m_items.at(i).color().name(QColor::HexArgb);
+ subres += ";";
+ subres += QString::number(static_cast<int>(m_items.at(i).isFavorite()));
+ output.push_back(subres);
+ subres.clear();
+ }
+
+ QmlDesigner::DesignerSettings::setValue(
+ QmlDesigner::DesignerSettingsKey::SIMPLE_COLOR_PALETTE_CONTENT, output);
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettesingleton.h b/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettesingleton.h
new file mode 100644
index 0000000000..77ad2b0732
--- /dev/null
+++ b/src/plugins/qmldesigner/components/propertyeditor/simplecolorpalettesingleton.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QObject>
+#include <QAbstractListModel>
+#include <QtQml/qqml.h>
+#include <QList>
+#include <QColor>
+#include <simplecolorpalette.h>
+
+namespace QmlDesigner {
+
+class SimpleColorPaletteSingleton : public QObject
+{
+ Q_OBJECT
+public:
+ static SimpleColorPaletteSingleton &getInstance();
+
+ bool readPalette();
+ void writePalette();
+
+ void addItem(const PaletteColor &item);
+ QList<PaletteColor> getItems() const;
+
+ int getPaletteSize() const;
+ int getFavoriteOffset() const;
+
+ void sortItems();
+
+ void toggleFavorite(int id);
+
+ SimpleColorPaletteSingleton(const SimpleColorPaletteSingleton &) = delete;
+ void operator=(const SimpleColorPaletteSingleton &) = delete;
+
+signals:
+ void paletteChanged();
+
+private:
+ SimpleColorPaletteSingleton();
+
+private:
+ QList<PaletteColor> m_items;
+ const int m_paletteSize = 6;
+ int m_favoriteOffset;
+};
+
+} // namespace QmlDesigner