forked from qt-creator/qt-creator
QmlDesigner: Add edit delegate to the CollectionDetailsView
Delegates are added for the Color, Bool, Number, ad String types. The default delegate is string delegate. Task-number: QDS-10989 Change-Id: I7dbaf5451d8be778691e72e18bd3124a754e47b7 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -0,0 +1,154 @@
|
|||||||
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import CollectionDetails 1.0 as CollectionDetails
|
||||||
|
import HelperWidgets 2.0 as HelperWidgets
|
||||||
|
import StudioControls 1.0 as StudioControls
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
required property var columnType
|
||||||
|
|
||||||
|
property var __modifier : textEditor
|
||||||
|
|
||||||
|
width: itemColumn.width
|
||||||
|
height: itemColumn.height
|
||||||
|
|
||||||
|
TableView.onCommit: edit = __modifier.editValue
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (edit && edit !== "")
|
||||||
|
root.__modifier.editValue = edit
|
||||||
|
}
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (root.activeFocus)
|
||||||
|
root.__modifier.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
id: modifierFocusConnection
|
||||||
|
target: root.__modifier
|
||||||
|
function onActiveFocusChanged() {
|
||||||
|
if (!modifierFocusConnection.target.activeFocus)
|
||||||
|
TableView.commit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: itemColumn
|
||||||
|
|
||||||
|
StudioControls.TextField {
|
||||||
|
id: textEditor
|
||||||
|
|
||||||
|
property alias editValue: textEditor.text
|
||||||
|
|
||||||
|
actionIndicator.visible: false
|
||||||
|
translationIndicatorVisible: false
|
||||||
|
enabled: visible
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.RealSpinBox {
|
||||||
|
id: numberEditor
|
||||||
|
|
||||||
|
property alias editValue: numberEditor.realValue
|
||||||
|
|
||||||
|
actionIndicator.visible: false
|
||||||
|
enabled: visible
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
realFrom: -9e9
|
||||||
|
realTo: 9e9
|
||||||
|
realStepSize: 1.0
|
||||||
|
decimals: 6
|
||||||
|
}
|
||||||
|
|
||||||
|
StudioControls.CheckBox {
|
||||||
|
id: boolEditor
|
||||||
|
|
||||||
|
property alias editValue: boolEditor.checked
|
||||||
|
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
enabled: visible
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
HelperWidgets.ColorPicker {
|
||||||
|
id: colorEditor
|
||||||
|
|
||||||
|
property alias editValue: colorEditor.color
|
||||||
|
|
||||||
|
width: 100
|
||||||
|
enabled: visible
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "default"
|
||||||
|
when: columnType !== CollectionDetails.DataType.Boolean
|
||||||
|
&& columnType !== CollectionDetails.DataType.Color
|
||||||
|
&& columnType !== CollectionDetails.DataType.Number
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
__modifier: textEditor
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: textEditor
|
||||||
|
visible: true
|
||||||
|
focus: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "number"
|
||||||
|
when: columnType === CollectionDetails.DataType.Number
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
__modifier: numberEditor
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: numberEditor
|
||||||
|
visible: true
|
||||||
|
focus: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "bool"
|
||||||
|
when: columnType === CollectionDetails.DataType.Boolean
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
__modifier: boolEditor
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: boolEditor
|
||||||
|
visible: true
|
||||||
|
focus: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "color"
|
||||||
|
when: columnType === CollectionDetails.DataType.Color
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: root
|
||||||
|
__modifier: colorEditor
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: colorEditor
|
||||||
|
visible: true
|
||||||
|
focus: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -201,6 +201,13 @@ Rectangle {
|
|||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TableView.editDelegate: CollectionDetailsEditDelegate {
|
||||||
|
anchors {
|
||||||
|
top: itemText.top
|
||||||
|
left: itemText.left
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
name: "default"
|
name: "default"
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "collectiondetails.h"
|
#include "collectiondetails.h"
|
||||||
|
|
||||||
#include <utils/span.h>
|
#include <utils/span.h>
|
||||||
|
#include <qqml.h>
|
||||||
|
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
@@ -220,6 +221,21 @@ bool CollectionDetails::removeElements(int row, int count)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CollectionDetails::setPropertyValue(int row, int column, const QVariant &value)
|
||||||
|
{
|
||||||
|
if (!d->isValidRowId(row) || !d->isValidColumnId(column))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QJsonObject &element = d->elements[row];
|
||||||
|
QVariant currentValue = data(row, column);
|
||||||
|
|
||||||
|
if (value == currentValue)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
element.insert(d->properties.at(column).name, QJsonValue::fromVariant(value));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CollectionDetails::setPropertyName(int column, const QString &value)
|
bool CollectionDetails::setPropertyName(int column, const QString &value)
|
||||||
{
|
{
|
||||||
if (!d->isValidColumnId(column))
|
if (!d->isValidColumnId(column))
|
||||||
@@ -316,6 +332,20 @@ CollectionDetails::DataType CollectionDetails::typeAt(int column) const
|
|||||||
return d->properties.at(column).type;
|
return d->properties.at(column).type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CollectionDetails::DataType CollectionDetails::typeAt(int row, int column) const
|
||||||
|
{
|
||||||
|
if (!d->isValidRowId(row) || !d->isValidColumnId(column))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
const QString &propertyName = d->properties.at(column).name;
|
||||||
|
const QJsonObject &element = d->elements.at(row);
|
||||||
|
|
||||||
|
if (element.contains(propertyName))
|
||||||
|
return collectionDataTypeFromJsonValue(element.value(propertyName));
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
bool CollectionDetails::containsPropertyName(const QString &propertyName)
|
bool CollectionDetails::containsPropertyName(const QString &propertyName)
|
||||||
{
|
{
|
||||||
if (!isValid())
|
if (!isValid())
|
||||||
@@ -360,6 +390,13 @@ void CollectionDetails::swap(CollectionDetails &other)
|
|||||||
d.swap(other.d);
|
d.swap(other.d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CollectionDetails::registerDeclarativeType()
|
||||||
|
{
|
||||||
|
typedef CollectionDetails::DataType DataType;
|
||||||
|
qRegisterMetaType<DataType>("DataType");
|
||||||
|
qmlRegisterUncreatableType<CollectionDetails>("CollectionDetails", 1, 0, "DataType", "Enum type");
|
||||||
|
}
|
||||||
|
|
||||||
CollectionDetails &CollectionDetails::operator=(const CollectionDetails &other)
|
CollectionDetails &CollectionDetails::operator=(const CollectionDetails &other)
|
||||||
{
|
{
|
||||||
CollectionDetails value(other);
|
CollectionDetails value(other);
|
||||||
|
|||||||
@@ -37,8 +37,11 @@ struct CollectionProperty;
|
|||||||
|
|
||||||
class CollectionDetails
|
class CollectionDetails
|
||||||
{
|
{
|
||||||
|
Q_GADGET
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class DataType { Unknown, String, Url, Number, Boolean, Image, Color };
|
enum class DataType { Unknown, String, Url, Number, Boolean, Image, Color };
|
||||||
|
Q_ENUM(DataType)
|
||||||
|
|
||||||
explicit CollectionDetails();
|
explicit CollectionDetails();
|
||||||
CollectionDetails(const CollectionReference &reference);
|
CollectionDetails(const CollectionReference &reference);
|
||||||
@@ -57,6 +60,7 @@ public:
|
|||||||
void insertElementAt(std::optional<QJsonObject> object, int row = -1);
|
void insertElementAt(std::optional<QJsonObject> object, int row = -1);
|
||||||
void insertEmptyElements(int row = 0, int count = 1);
|
void insertEmptyElements(int row = 0, int count = 1);
|
||||||
bool removeElements(int row, int count = 1);
|
bool removeElements(int row, int count = 1);
|
||||||
|
bool setPropertyValue(int row, int column, const QVariant &value);
|
||||||
|
|
||||||
bool setPropertyName(int column, const QString &value);
|
bool setPropertyName(int column, const QString &value);
|
||||||
bool forcePropertyType(int column, DataType type, bool force = false);
|
bool forcePropertyType(int column, DataType type, bool force = false);
|
||||||
@@ -66,6 +70,7 @@ public:
|
|||||||
QVariant data(int row, int column) const;
|
QVariant data(int row, int column) const;
|
||||||
QString propertyAt(int column) const;
|
QString propertyAt(int column) const;
|
||||||
DataType typeAt(int column) const;
|
DataType typeAt(int column) const;
|
||||||
|
DataType typeAt(int row, int column) const;
|
||||||
bool containsPropertyName(const QString &propertyName);
|
bool containsPropertyName(const QString &propertyName);
|
||||||
|
|
||||||
bool isValid() const;
|
bool isValid() const;
|
||||||
@@ -80,6 +85,8 @@ public:
|
|||||||
QJsonArray getJsonCollection() const;
|
QJsonArray getJsonCollection() const;
|
||||||
QString getCsvCollection() const;
|
QString getCsvCollection() const;
|
||||||
|
|
||||||
|
static void registerDeclarativeType();
|
||||||
|
|
||||||
CollectionDetails &operator=(const CollectionDetails &other);
|
CollectionDetails &operator=(const CollectionDetails &other);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ QHash<int, QByteArray> CollectionDetailsModel::roleNames() const
|
|||||||
roles.insert(QAbstractTableModel::roleNames());
|
roles.insert(QAbstractTableModel::roleNames());
|
||||||
roles.insert(SelectedRole, "itemSelected");
|
roles.insert(SelectedRole, "itemSelected");
|
||||||
roles.insert(DataTypeRole, "dataType");
|
roles.insert(DataTypeRole, "dataType");
|
||||||
|
roles.insert(ColumnDataTypeRole, "columnType");
|
||||||
}
|
}
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
@@ -122,11 +123,31 @@ QVariant CollectionDetailsModel::data(const QModelIndex &index, int role) const
|
|||||||
if (role == SelectedRole)
|
if (role == SelectedRole)
|
||||||
return (index.column() == m_selectedColumn || index.row() == m_selectedRow);
|
return (index.column() == m_selectedColumn || index.row() == m_selectedRow);
|
||||||
|
|
||||||
return m_currentCollection.data(index.row(), index.column());
|
if (role == DataTypeRole)
|
||||||
|
return QVariant::fromValue(m_currentCollection.typeAt(index.row(), index.column()));
|
||||||
|
|
||||||
|
if (role == ColumnDataTypeRole)
|
||||||
|
return QVariant::fromValue(m_currentCollection.typeAt(index.column()));
|
||||||
|
|
||||||
|
if (role == Qt::EditRole)
|
||||||
|
return m_currentCollection.data(index.row(), index.column());
|
||||||
|
|
||||||
|
return m_currentCollection.data(index.row(), index.column()).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CollectionDetailsModel::setData(const QModelIndex &, const QVariant &, int)
|
bool CollectionDetailsModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
{
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
if (role == Qt::EditRole) {
|
||||||
|
bool changed = m_currentCollection.setPropertyValue(index.row(), index.column(), value);
|
||||||
|
if (changed) {
|
||||||
|
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +210,7 @@ Qt::ItemFlags CollectionDetailsModel::flags(const QModelIndex &index) const
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return {Qt::ItemIsSelectable | Qt::ItemIsEnabled};
|
return {Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable};
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant CollectionDetailsModel::headerData(int section, Qt::Orientation orientation, int role) const
|
QVariant CollectionDetailsModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class CollectionDetailsModel : public QAbstractTableModel
|
|||||||
Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
|
Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum DataRoles { SelectedRole = Qt::UserRole + 1, DataTypeRole };
|
enum DataRoles { SelectedRole = Qt::UserRole + 1, DataTypeRole, ColumnDataTypeRole };
|
||||||
|
|
||||||
explicit CollectionDetailsModel(QObject *parent = nullptr);
|
explicit CollectionDetailsModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
|||||||
@@ -153,6 +153,11 @@ void CollectionView::addResource(const QUrl &url, const QString &name, const QSt
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CollectionView::registerDeclarativeType()
|
||||||
|
{
|
||||||
|
CollectionDetails::registerDeclarativeType();
|
||||||
|
}
|
||||||
|
|
||||||
void CollectionView::refreshModel()
|
void CollectionView::refreshModel()
|
||||||
{
|
{
|
||||||
if (!model())
|
if (!model())
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ public:
|
|||||||
|
|
||||||
void addResource(const QUrl &url, const QString &name, const QString &type);
|
void addResource(const QUrl &url, const QString &name, const QString &type);
|
||||||
|
|
||||||
|
static void registerDeclarativeType();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void refreshModel();
|
void refreshModel();
|
||||||
NodeMetaInfo jsonCollectionMetaInfo() const;
|
NodeMetaInfo jsonCollectionMetaInfo() const;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "qmldesignerplugin.h"
|
#include "qmldesignerplugin.h"
|
||||||
#include "qmldesignertr.h"
|
#include "qmldesignertr.h"
|
||||||
|
|
||||||
|
#include "collectioneditor/collectionview.h"
|
||||||
#include "coreplugin/iwizardfactory.h"
|
#include "coreplugin/iwizardfactory.h"
|
||||||
#include "designmodecontext.h"
|
#include "designmodecontext.h"
|
||||||
#include "designmodewidget.h"
|
#include "designmodewidget.h"
|
||||||
@@ -282,6 +283,7 @@ bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *e
|
|||||||
|
|
||||||
//TODO Move registering those types out of the property editor, since they are used also in the states editor
|
//TODO Move registering those types out of the property editor, since they are used also in the states editor
|
||||||
Quick2PropertyEditorView::registerQmlTypes();
|
Quick2PropertyEditorView::registerQmlTypes();
|
||||||
|
CollectionView::registerDeclarativeType();
|
||||||
|
|
||||||
if (checkEnterpriseLicense())
|
if (checkEnterpriseLicense())
|
||||||
Core::IWizardFactory::registerFeatureProvider(new EnterpriseFeatureProvider);
|
Core::IWizardFactory::registerFeatureProvider(new EnterpriseFeatureProvider);
|
||||||
|
|||||||
Reference in New Issue
Block a user