QmlDesigner: Add tooltips as data type descriptors to Model Editor

Task-number: QDS-11676
Change-Id: I14132ca8f2285de85532b26d3374b5e442f8c746
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Henning Gründl <henning.gruendl@qt.io>
This commit is contained in:
Ali Kianian
2024-03-11 15:11:18 +02:00
parent 7bdf43e8e1
commit 1e92dd4fe4
13 changed files with 154 additions and 97 deletions

View File

@@ -8,6 +8,7 @@ import Qt.labs.platform as PlatformWidgets
import HelperWidgets 2.0 as HelperWidgets
import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
import CollectionDetails
import CollectionEditorBackend
Rectangle {
@@ -231,7 +232,9 @@ Rectangle {
Layout.fillWidth: true
model: root.model.typesList()
model: CollectionDataTypeModel{}
textRole: "display"
tooltipRole: "toolTip"
actionIndicatorVisible: false
}

View File

@@ -11,7 +11,7 @@ ListView {
clip: true
delegate: CollectionItem {
implicitWidth: parent.width
implicitWidth: root.width
onDeleteItem: root.model.removeRow(index)
}
}

View File

@@ -6,6 +6,7 @@ import QtQuick.Layouts
import StudioTheme 1.0 as StudioTheme
import StudioControls 1.0 as StudioControls
import HelperWidgets 2.0 as HelperWidgets
import CollectionDetails
StudioControls.Dialog {
id: root
@@ -91,7 +92,9 @@ StudioControls.Dialog {
property string initialType
model: root.model.typesList()
model: CollectionDataTypeModel{}
textRole: "display"
tooltipRole: "toolTip"
actionIndicatorVisible: false
}
}

View File

@@ -36,6 +36,8 @@ T.ComboBox {
property string preFocusText: ""
property string tooltipRole: ""
signal compressedActivated(int index, int reason)
enum ActivatedReason { EditingFinished, Other }
@@ -153,6 +155,17 @@ T.ComboBox {
font: control.font
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
ToolTipArea {
anchors.fill: parent
text: control.tooltipRole ? (Array.isArray(control.model)
? modelData[control.tooltipRole]
: model[control.tooltipRole])
: ""
enabled: text
onClicked: itemDelegate.clicked()
onDoubleClicked: itemDelegate.doubleClicked()
}
}
highlighted: control.highlightedIndex === index

View File

@@ -836,6 +836,7 @@ extend_qtc_plugin(QmlDesigner
extend_qtc_plugin(QmlDesigner
SOURCES_PREFIX components/collectioneditor
SOURCES
collectiondatatypemodel.cpp collectiondatatypemodel.h
collectiondetails.cpp collectiondetails.h
collectiondetailsmodel.cpp collectiondetailsmodel.h
collectiondetailssortfiltermodel.cpp collectiondetailssortfiltermodel.h

View File

@@ -0,0 +1,87 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "collectiondatatypemodel.h"
#include <QHash>
#include <QtQml/QmlTypeAndRevisionsRegistration>
namespace QmlDesigner {
struct CollectionDataTypeModel::Details
{
CollectionDetails::DataType type;
QString name;
QString description;
};
const QList<CollectionDataTypeModel::Details> CollectionDataTypeModel::m_orderedDetails{
{DataType::String, "String", "Text"},
{DataType::Integer, "Integer", "Whole number"},
{DataType::Real, "Real", "Number with a decimal"},
{DataType::Image, "Image", "Image resource"},
{DataType::Color, "Color", "HEX value"},
{DataType::Url, "Url", "Resource locator"},
{DataType::Boolean, "Boolean", "True/False"},
{DataType::Unknown, "Unknown", "Unknown Data Type"},
};
CollectionDataTypeModel::CollectionDataTypeModel(QObject *parent)
: QAbstractListModel(parent)
{
}
int CollectionDataTypeModel::rowCount([[maybe_unused]] const QModelIndex &parent) const
{
return m_orderedDetails.size();
}
QVariant CollectionDataTypeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return {};
if (role == Qt::DisplayRole)
return m_orderedDetails.at(index.row()).name;
if (role == Qt::ToolTipRole)
return m_orderedDetails.at(index.row()).description;
return {};
}
QString CollectionDataTypeModel::dataTypeToString(DataType dataType)
{
static const QHash<DataType, QString> dataTypeHash = []() -> QHash<DataType, QString> {
QHash<DataType, QString> result;
for (const Details &details : m_orderedDetails)
result.insert(details.type, details.name);
return result;
}();
if (dataTypeHash.contains(dataType))
return dataTypeHash.value(dataType);
return "Unknown";
}
CollectionDetails::DataType CollectionDataTypeModel::dataTypeFromString(const QString &dataType)
{
static const QHash<QString, DataType> stringTypeHash = []() -> QHash<QString, DataType> {
QHash<QString, DataType> result;
for (const Details &details : m_orderedDetails)
result.insert(details.name, details.type);
return result;
}();
if (stringTypeHash.contains(dataType))
return stringTypeHash.value(dataType);
return DataType::Unknown;
}
void CollectionDataTypeModel::registerDeclarativeType()
{
qmlRegisterType<CollectionDataTypeModel>("CollectionDetails", 1, 0, "CollectionDataTypeModel");
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,34 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include "collectiondetails.h"
#include <QAbstractListModel>
#include <QList>
namespace QmlDesigner {
class CollectionDataTypeModel : public QAbstractListModel
{
Q_OBJECT
public:
using DataType = CollectionDetails::DataType;
CollectionDataTypeModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
static Q_INVOKABLE QString dataTypeToString(DataType dataType);
static Q_INVOKABLE DataType dataTypeFromString(const QString &dataType);
static void registerDeclarativeType();
private:
struct Details;
static const QList<Details> m_orderedDetails;
};
} // namespace QmlDesigner

View File

@@ -3,6 +3,7 @@
#include "collectiondetails.h"
#include "collectiondatatypemodel.h"
#include "collectioneditorutils.h"
#include <utils/span.h>
@@ -706,7 +707,7 @@ QJsonObject CollectionDetails::toLocalJson() const
for (const CollectionProperty &property : std::as_const(d->properties)) {
QJsonObject columnObject;
columnObject.insert("name", property.name);
columnObject.insert("type", CollectionEditorUtils::dataTypeToString(property.type));
columnObject.insert("type", CollectionDataTypeModel::dataTypeToString(property.type));
columnsArray.append(columnObject);
}
@@ -941,7 +942,7 @@ CollectionDetails CollectionDetails::fromLocalCollection(const QJsonObject &loca
result.insertColumn(columnName,
-1,
{},
CollectionEditorUtils::dataTypeFromString(
CollectionDataTypeModel::dataTypeFromString(
column.value("type").toString()));
}
}

View File

@@ -3,6 +3,7 @@
#include "collectiondetailsmodel.h"
#include "collectiondatatypemodel.h"
#include "collectioneditorutils.h"
#include "modelnode.h"
@@ -188,7 +189,7 @@ QVariant CollectionDetailsModel::headerData(int section, Qt::Orientation orienta
{
if (orientation == Qt::Horizontal) {
if (role == DataTypeRole)
return CollectionEditorUtils::dataTypeToString(m_currentCollection.typeAt(section));
return CollectionDataTypeModel::dataTypeToString(m_currentCollection.typeAt(section));
else
return m_currentCollection.propertyAt(section);
}
@@ -227,7 +228,7 @@ QString CollectionDetailsModel::propertyType(int column) const
{
QTC_ASSERT(m_currentCollection.hasValidReference(), return {});
return CollectionEditorUtils::dataTypeToString(m_currentCollection.typeAt(column));
return CollectionDataTypeModel::dataTypeToString(m_currentCollection.typeAt(column));
}
bool CollectionDetailsModel::isPropertyAvailable(const QString &name)
@@ -251,7 +252,7 @@ bool CollectionDetailsModel::addColumn(int column, const QString &name, const QS
m_currentCollection.insertColumn(name,
column,
{},
CollectionEditorUtils::dataTypeFromString(propertyType));
CollectionDataTypeModel::dataTypeFromString(propertyType));
endInsertColumns();
return m_currentCollection.containsPropertyName(name);
}
@@ -298,7 +299,7 @@ bool CollectionDetailsModel::setPropertyType(int column, const QString &newValue
QTC_ASSERT(m_currentCollection.hasValidReference(), return false);
bool changed = m_currentCollection.setPropertyType(column,
CollectionEditorUtils::dataTypeFromString(
CollectionDataTypeModel::dataTypeFromString(
newValue));
if (changed) {
emit headerDataChanged(Qt::Horizontal, column, column);
@@ -346,11 +347,6 @@ void CollectionDetailsModel::deselectAll()
selectRow(-1);
}
QStringList CollectionDetailsModel::typesList()
{
return CollectionEditorUtils::dataTypesStringList();
}
void CollectionDetailsModel::loadCollection(const ModelNode &sourceNode, const QString &collection)
{
QString fileName = CollectionEditorUtils::getSourceCollectionPath(sourceNode);

View File

@@ -58,7 +58,6 @@ public:
Q_INVOKABLE bool selectRow(int row);
Q_INVOKABLE void deselectAll();
Q_INVOKABLE QString warningToString(DataTypeWarning::Warning warning) const;
static Q_INVOKABLE QStringList typesList();
void loadCollection(const ModelNode &sourceNode, const QString &collection);
void removeCollection(const ModelNode &sourceNode, const QString &collection);

View File

@@ -31,64 +31,6 @@ namespace {
using CollectionDataVariant = std::variant<QString, bool, double, int, QUrl, QColor>;
class CollectionDataTypeHelper
{
private:
using DataType = QmlDesigner::CollectionDetails::DataType;
friend QString QmlDesigner::CollectionEditorUtils::dataTypeToString(DataType);
friend DataType QmlDesigner::CollectionEditorUtils::dataTypeFromString(const QString &);
friend QStringList QmlDesigner::CollectionEditorUtils::dataTypesStringList();
CollectionDataTypeHelper() = delete;
static QHash<DataType, QString> typeToStringHash()
{
return {
{DataType::Unknown, "Unknown"},
{DataType::String, "String"},
{DataType::Url, "Url"},
{DataType::Real, "Real"},
{DataType::Integer, "Integer"},
{DataType::Boolean, "Boolean"},
{DataType::Image, "Image"},
{DataType::Color, "Color"},
};
}
static QHash<QString, DataType> stringToTypeHash()
{
QHash<QString, DataType> stringTypeHash;
const QHash<DataType, QString> typeStringHash = typeToStringHash();
for (const auto &transferItem : typeStringHash.asKeyValueRange())
stringTypeHash.insert(transferItem.second, transferItem.first);
return stringTypeHash;
}
static QStringList orderedTypeNames()
{
const QList<DataType> orderedtypes{
DataType::String,
DataType::Integer,
DataType::Real,
DataType::Image,
DataType::Color,
DataType::Url,
DataType::Boolean,
DataType::Unknown,
};
QStringList orderedNames;
QHash<DataType, QString> typeStringHash = typeToStringHash();
for (const DataType &type : orderedtypes)
orderedNames.append(typeStringHash.take(type));
Q_ASSERT(typeStringHash.isEmpty());
return orderedNames;
}
};
inline bool operator<(const QColor &a, const QColor &b)
{
return a.name(QColor::HexArgb) < b.name(QColor::HexArgb);
@@ -383,24 +325,6 @@ QJsonObject defaultColorCollection()
return collection.toLocalJson();
}
QString dataTypeToString(CollectionDetails::DataType dataType)
{
static const QHash<DataType, QString> typeStringHash = CollectionDataTypeHelper::typeToStringHash();
return typeStringHash.value(dataType);
}
CollectionDetails::DataType dataTypeFromString(const QString &dataType)
{
static const QHash<QString, DataType> stringTypeHash = CollectionDataTypeHelper::stringToTypeHash();
return stringTypeHash.value(dataType, DataType::Unknown);
}
QStringList dataTypesStringList()
{
static const QStringList typesList = CollectionDataTypeHelper::orderedTypeNames();
return typesList;
}
bool writeToJsonDocument(const Utils::FilePath &path, const QJsonDocument &document, QString *errorString)
{
Core::FileChangeBlocker fileBlocker(path);

View File

@@ -43,10 +43,4 @@ QJsonObject defaultCollection();
QJsonObject defaultColorCollection();
QString dataTypeToString(CollectionDetails::DataType dataType);
CollectionDetails::DataType dataTypeFromString(const QString &dataType);
QStringList dataTypesStringList();
} // namespace QmlDesigner::CollectionEditorUtils

View File

@@ -3,6 +3,7 @@
#include "collectionview.h"
#include "collectiondatatypemodel.h"
#include "collectiondetailsmodel.h"
#include "collectioneditorconstants.h"
#include "collectioneditorutils.h"
@@ -290,6 +291,7 @@ void CollectionView::openCollection(const QString &collectionName)
void CollectionView::registerDeclarativeType()
{
CollectionDetails::registerDeclarativeType();
CollectionDataTypeModel::registerDeclarativeType();
}
void CollectionView::resetDataStoreNode()