QmlDesigner: Create data type warnings for CollectionDetailsModel

Task-number: QDS-11079
Change-Id: I8cb5167d71ff96d01313bc559401e16f0925afbb
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Ali Kianian <ali.kianian@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
Shrief Gabr
2023-12-14 13:52:48 +02:00
parent 4d042e5b7d
commit 6b6f74ccad
5 changed files with 72 additions and 9 deletions

View File

@@ -4,6 +4,7 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import CollectionDetails 1.0 as CollectionDetails
import HelperWidgets 2.0 as HelperWidgets import HelperWidgets 2.0 as HelperWidgets
import StudioTheme 1.0 as StudioTheme import StudioTheme 1.0 as StudioTheme
import StudioControls 1.0 as StudioControls import StudioControls 1.0 as StudioControls
@@ -207,13 +208,23 @@ Rectangle {
id: itemCell id: itemCell
implicitWidth: 100 implicitWidth: 100
implicitHeight: itemText.height implicitHeight: itemText.height
border.color: dataTypeWarning !== CollectionDetails.Warning.None ?
StudioTheme.Values.themeWarning : StudioTheme.Values.themeControlBackgroundInteraction
border.width: 1 border.width: 1
HelperWidgets.ToolTipArea {
anchors.fill: parent
text: root.model.warningToString(dataTypeWarning)
enabled: dataTypeWarning !== CollectionDetails.Warning.None && text !== ""
hoverEnabled: true
acceptedButtons: Qt.NoButton
}
Text { Text {
id: itemText id: itemText
text: display ? display : "" text: display
color: StudioTheme.Values.themePlaceholderTextColorInteraction
width: parent.width width: parent.width
leftPadding: 5 leftPadding: 5
topPadding: 3 topPadding: 3
@@ -239,7 +250,6 @@ Rectangle {
PropertyChanges { PropertyChanges {
target: itemCell target: itemCell
color: StudioTheme.Values.themeControlBackground color: StudioTheme.Values.themeControlBackground
border.color: StudioTheme.Values.themeControlBackgroundInteraction
} }
PropertyChanges { PropertyChanges {

View File

@@ -22,6 +22,10 @@ struct CollectionProperty
DataType type; DataType type;
}; };
const QMap<DataTypeWarning::Warning, QString> DataTypeWarning::dataTypeWarnings = {
{DataTypeWarning::CellDataTypeMismatch, "Cell and column data types do not match."}
};
class CollectionDetails::Private class CollectionDetails::Private
{ {
using SourceFormat = CollectionEditor::SourceFormat; using SourceFormat = CollectionEditor::SourceFormat;
@@ -345,6 +349,13 @@ CollectionDetails::DataType CollectionDetails::typeAt(int row, int column) const
return {}; return {};
} }
DataTypeWarning::Warning CollectionDetails::cellWarningCheck(int row, int column) const
{
if (typeAt(column) != typeAt(row, column) && !d->elements.at(row).isEmpty())
return DataTypeWarning::Warning::CellDataTypeMismatch;
return DataTypeWarning::Warning::None;
}
bool CollectionDetails::containsPropertyName(const QString &propertyName) bool CollectionDetails::containsPropertyName(const QString &propertyName)
{ {
if (!isValid()) if (!isValid())
@@ -394,6 +405,9 @@ void CollectionDetails::registerDeclarativeType()
typedef CollectionDetails::DataType DataType; typedef CollectionDetails::DataType DataType;
qRegisterMetaType<DataType>("DataType"); qRegisterMetaType<DataType>("DataType");
qmlRegisterUncreatableType<CollectionDetails>("CollectionDetails", 1, 0, "DataType", "Enum type"); qmlRegisterUncreatableType<CollectionDetails>("CollectionDetails", 1, 0, "DataType", "Enum type");
qRegisterMetaType<DataTypeWarning::Warning>("Warning");
qmlRegisterUncreatableType<DataTypeWarning>("CollectionDetails", 1, 0, "Warning", "Enum type");
} }
CollectionDetails &CollectionDetails::operator=(const CollectionDetails &other) CollectionDetails &CollectionDetails::operator=(const CollectionDetails &other)

View File

@@ -35,6 +35,26 @@ struct CollectionReference
struct CollectionProperty; struct CollectionProperty;
struct DataTypeWarning {
Q_GADGET
public:
enum Warning { None, CellDataTypeMismatch };
Q_ENUM(Warning)
Warning warning = None;
DataTypeWarning(Warning warning)
: warning(warning)
{}
static QString getDataTypeWarningString(Warning warning) {
return dataTypeWarnings.value(warning);
}
private:
static const QMap<Warning, QString> dataTypeWarnings;
};
class CollectionDetails class CollectionDetails
{ {
Q_GADGET Q_GADGET
@@ -71,6 +91,7 @@ public:
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; DataType typeAt(int row, int column) const;
DataTypeWarning::Warning cellWarningCheck(int row, int column) const;
bool containsPropertyName(const QString &propertyName); bool containsPropertyName(const QString &propertyName);
bool isValid() const; bool isValid() const;

View File

@@ -102,6 +102,7 @@ QHash<int, QByteArray> CollectionDetailsModel::roleNames() const
roles.insert(SelectedRole, "itemSelected"); roles.insert(SelectedRole, "itemSelected");
roles.insert(DataTypeRole, "dataType"); roles.insert(DataTypeRole, "dataType");
roles.insert(ColumnDataTypeRole, "columnType"); roles.insert(ColumnDataTypeRole, "columnType");
roles.insert(DataTypeWarningRole, "dataTypeWarning");
} }
return roles; return roles;
} }
@@ -133,6 +134,9 @@ QVariant CollectionDetailsModel::data(const QModelIndex &index, int role) const
if (role == Qt::EditRole) if (role == Qt::EditRole)
return m_currentCollection.data(index.row(), index.column()); return m_currentCollection.data(index.row(), index.column());
if (role == DataTypeWarningRole )
return QVariant::fromValue(m_currentCollection.cellWarningCheck(index.row(), index.column()));
return m_currentCollection.data(index.row(), index.column()).toString(); return m_currentCollection.data(index.row(), index.column()).toString();
} }
@@ -142,11 +146,19 @@ bool CollectionDetailsModel::setData(const QModelIndex &index, const QVariant &v
return {}; return {};
if (role == Qt::EditRole) { if (role == Qt::EditRole) {
DataTypeWarning::Warning prevWarning = m_currentCollection.cellWarningCheck(index.row(), index.column());
bool changed = m_currentCollection.setPropertyValue(index.row(), index.column(), value); bool changed = m_currentCollection.setPropertyValue(index.row(), index.column(), value);
if (changed) { if (changed) {
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole}); QList<int> roles = {Qt::DisplayRole, Qt::EditRole};
return true;
if (prevWarning != m_currentCollection.cellWarningCheck(index.row(), index.column()))
roles << DataTypeWarningRole;
emit dataChanged(index, index, roles);
} }
return true;
} }
return false; return false;
@@ -326,7 +338,8 @@ bool CollectionDetailsModel::setPropertyType(int column, const QString &newValue
newValue)); newValue));
if (changed) { if (changed) {
emit headerDataChanged(Qt::Horizontal, column, column); emit headerDataChanged(Qt::Horizontal, column, column);
emit dataChanged(index(0, column), index(rowCount() - 1, column), {Qt::DisplayRole, DataTypeRole}); emit dataChanged(index(0, column), index(rowCount() - 1, column),
{Qt::DisplayRole, DataTypeRole, DataTypeWarningRole});
} }
return changed; return changed;
@@ -623,4 +636,10 @@ bool CollectionDetailsModel::saveCollectionFromString(const QString &path, const
return false; return false;
} }
QString CollectionDetailsModel::warningToString(DataTypeWarning::Warning warning) const
{
return DataTypeWarning::getDataTypeWarningString(warning);
}
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -22,8 +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, ColumnDataTypeRole }; enum DataRoles { SelectedRole = Qt::UserRole + 1, DataTypeRole, ColumnDataTypeRole, DataTypeWarningRole };
explicit CollectionDetailsModel(QObject *parent = nullptr); explicit CollectionDetailsModel(QObject *parent = nullptr);
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
@@ -58,7 +57,7 @@ public:
Q_INVOKABLE bool setPropertyType(int column, const QString &newValue); Q_INVOKABLE bool setPropertyType(int column, const QString &newValue);
Q_INVOKABLE bool selectRow(int row); Q_INVOKABLE bool selectRow(int row);
Q_INVOKABLE void deselectAll(); Q_INVOKABLE void deselectAll();
Q_INVOKABLE QString warningToString(DataTypeWarning::Warning warning) const;
static Q_INVOKABLE QStringList typesList(); static Q_INVOKABLE QStringList typesList();
void loadCollection(const ModelNode &sourceNode, const QString &collection); void loadCollection(const ModelNode &sourceNode, const QString &collection);