forked from qt-creator/qt-creator
QmlDesigner: Add support for valueRole in ComboBox
- Add support for valueRole in HelperWidget.ComboBox in order to allow for custom JS arrays that define value and text role - Replace specialized invokables in item filter model which are only available in that particular model with general purpose functionality provided by QML ComboBox - Remove unnecessary functions from item filter model Task-number: QDS-8737 Change-Id: I58bd3fed395961ac4495a0c6e9ff47c9b87e0de2 Reviewed-by: Ali Kianian <ali.kianian@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
committed by
Henning Gründl
parent
6eccd82515
commit
3b8c38c7f0
@@ -10,8 +10,8 @@ StudioControls.ComboBox {
|
|||||||
|
|
||||||
property variant backendValue
|
property variant backendValue
|
||||||
|
|
||||||
labelColor: edit && !colorLogic.errorState ? StudioTheme.Values.themeTextColor
|
labelColor: comboBox.edit && !colorLogic.errorState ? StudioTheme.Values.themeTextColor
|
||||||
: colorLogic.textColor
|
: colorLogic.textColor
|
||||||
property string scope: "Qt"
|
property string scope: "Qt"
|
||||||
|
|
||||||
enum ValueType { String, Integer, Enum }
|
enum ValueType { String, Integer, Enum }
|
||||||
@@ -74,7 +74,6 @@ StudioControls.ComboBox {
|
|||||||
comboBox.backendValue.commitDrop(dropArea.dropData)
|
comboBox.backendValue.commitDrop(dropArea.dropData)
|
||||||
comboBox.hasActiveHoverDrag = false
|
comboBox.hasActiveHoverDrag = false
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExtendedFunctionLogic {
|
ExtendedFunctionLogic {
|
||||||
@@ -102,6 +101,16 @@ StudioControls.ComboBox {
|
|||||||
|
|
||||||
if (comboBox.manualMapping) {
|
if (comboBox.manualMapping) {
|
||||||
comboBox.valueFromBackendChanged()
|
comboBox.valueFromBackendChanged()
|
||||||
|
} else if (comboBox.valueRole && comboBox.textRole !== comboBox.valueRole) {
|
||||||
|
switch (comboBox.valueType) {
|
||||||
|
case ComboBox.ValueType.Enum:
|
||||||
|
comboBox.currentIndex = comboBox.indexOfValue(comboBox.backendValue.enumeration)
|
||||||
|
break
|
||||||
|
case ComboBox.ValueType.String:
|
||||||
|
case ComboBox.ValueType.Integer:
|
||||||
|
default:
|
||||||
|
comboBox.currentIndex = comboBox.indexOfValue(comboBox.backendValue.value)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (comboBox.valueType) {
|
switch (comboBox.valueType) {
|
||||||
case ComboBox.ValueType.String:
|
case ComboBox.ValueType.String:
|
||||||
@@ -147,14 +156,10 @@ StudioControls.ComboBox {
|
|||||||
return
|
return
|
||||||
|
|
||||||
let inputText = comboBox.editText
|
let inputText = comboBox.editText
|
||||||
let inputValue = inputText;
|
let inputValue = inputText
|
||||||
let index = comboBox.find(inputText)
|
let index = comboBox.find(inputText)
|
||||||
if (index !== -1) {
|
if (index !== -1)
|
||||||
let modelIdx = comboBox.model.index(index)
|
inputValue = comboBox.valueRole ? comboBox.valueAt(index) : comboBox.textAt(index)
|
||||||
inputValue = comboBox.valueRole
|
|
||||||
? comboBox.model.data(modelIdx, comboBox.valueRole)
|
|
||||||
: comboBox.textAt(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
comboBox.backendValue.value = inputValue
|
comboBox.backendValue.value = inputValue
|
||||||
|
|
||||||
@@ -175,24 +180,31 @@ StudioControls.ComboBox {
|
|||||||
let inputText = comboBox.currentText
|
let inputText = comboBox.currentText
|
||||||
let inputValue = comboBox.currentValue
|
let inputValue = comboBox.currentValue
|
||||||
let index = comboBox.find(inputText)
|
let index = comboBox.find(inputText)
|
||||||
if (index !== -1) {
|
|
||||||
let modelIdx = comboBox.model.index(index)
|
|
||||||
inputValue = comboBox.model.data(modelIdx, comboBox.valueRole)
|
|
||||||
}
|
|
||||||
comboBox.backendValue.value = inputValue
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (comboBox.valueType) {
|
if (index !== -1)
|
||||||
case ComboBox.ValueType.String:
|
inputValue = comboBox.valueAt(index)
|
||||||
comboBox.backendValue.value = comboBox.currentText
|
|
||||||
break
|
switch (comboBox.valueType) {
|
||||||
case ComboBox.ValueType.Integer:
|
case ComboBox.ValueType.Enum:
|
||||||
comboBox.backendValue.value = comboBox.currentIndex
|
comboBox.backendValue.setEnumeration(comboBox.scope, inputValue)
|
||||||
break
|
break
|
||||||
case ComboBox.ValueType.Enum:
|
case ComboBox.ValueType.String:
|
||||||
default:
|
case ComboBox.ValueType.Integer:
|
||||||
comboBox.backendValue.setEnumeration(comboBox.scope, comboBox.currentText)
|
default:
|
||||||
|
comboBox.backendValue.value = inputValue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (comboBox.valueType) {
|
||||||
|
case ComboBox.ValueType.String:
|
||||||
|
comboBox.backendValue.value = comboBox.currentText
|
||||||
|
break
|
||||||
|
case ComboBox.ValueType.Integer:
|
||||||
|
comboBox.backendValue.value = comboBox.currentIndex
|
||||||
|
break
|
||||||
|
case ComboBox.ValueType.Enum:
|
||||||
|
default:
|
||||||
|
comboBox.backendValue.setEnumeration(comboBox.scope, comboBox.currentText)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -96,7 +96,7 @@ Item {
|
|||||||
tooltip: root.extraButtonToolTip
|
tooltip: root.extraButtonToolTip
|
||||||
onClicked: root.extraButtonClicked(index)
|
onClicked: root.extraButtonClicked(index)
|
||||||
visible: root.extraButtonIcon !== ""
|
visible: root.extraButtonIcon !== ""
|
||||||
enabled: root.model[index]
|
enabled: root.model[index] ?? false
|
||||||
}
|
}
|
||||||
|
|
||||||
IconIndicator {
|
IconIndicator {
|
||||||
|
@@ -42,9 +42,7 @@ StudioControls.ComboBox {
|
|||||||
currentSelectedDataIndex = root.find(root.initialModelData)
|
currentSelectedDataIndex = root.find(root.initialModelData)
|
||||||
} else {
|
} else {
|
||||||
for (let i = 0; i < root.count; ++i) {
|
for (let i = 0; i < root.count; ++i) {
|
||||||
let movingModelIndex = root.model.index(i)
|
if (root.valueAt(i) === root.initialModelData) {
|
||||||
let movingModelValueData = root.model.data(movingModelIndex, root.valueRole)
|
|
||||||
if (movingModelValueData === root.initialModelData) {
|
|
||||||
currentSelectedDataIndex = i
|
currentSelectedDataIndex = i
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@@ -55,14 +53,6 @@ StudioControls.ComboBox {
|
|||||||
root.editText = root.initialModelData
|
root.editText = root.initialModelData
|
||||||
}
|
}
|
||||||
|
|
||||||
function currentData(role = root.valueRole) {
|
|
||||||
if (root.currentIndex !== -1) {
|
|
||||||
let currentModelIndex = root.model.index(root.currentIndex)
|
|
||||||
return root.model.data(currentModelIndex, role)
|
|
||||||
}
|
|
||||||
return root.editText
|
|
||||||
}
|
|
||||||
|
|
||||||
function availableValue() {
|
function availableValue() {
|
||||||
if (root.currentIndex !== -1 && root.currentValue !== "")
|
if (root.currentIndex !== -1 && root.currentValue !== "")
|
||||||
return root.currentValue
|
return root.currentValue
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
#include <model.h>
|
#include <model.h>
|
||||||
#include <nodemetainfo.h>
|
#include <nodemetainfo.h>
|
||||||
#include <qmlmodelnodeproxy.h>
|
#include <qmlmodelnodeproxy.h>
|
||||||
#include "variantproperty.h"
|
#include <variantproperty.h>
|
||||||
|
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
@@ -24,7 +24,7 @@ ItemFilterModel::ItemFilterModel(QObject *parent)
|
|||||||
{
|
{
|
||||||
if (m_roles.empty()) {
|
if (m_roles.empty()) {
|
||||||
m_roles = QAbstractListModel::roleNames();
|
m_roles = QAbstractListModel::roleNames();
|
||||||
QMetaEnum roleEnum = QMetaEnum::fromType<Roles>();
|
const QMetaEnum roleEnum = QMetaEnum::fromType<Roles>();
|
||||||
for (int i = 0; i < roleEnum.keyCount(); i++)
|
for (int i = 0; i < roleEnum.keyCount(); i++)
|
||||||
m_roles.insert(roleEnum.value(i), roleEnum.key(i));
|
m_roles.insert(roleEnum.value(i), roleEnum.key(i));
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,6 @@ ItemFilterModel::ItemFilterModel(QObject *parent)
|
|||||||
|
|
||||||
void ItemFilterModel::setModelNodeBackend(const QVariant &modelNodeBackend)
|
void ItemFilterModel::setModelNodeBackend(const QVariant &modelNodeBackend)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto modelNodeBackendObject = modelNodeBackend.value<QObject*>();
|
auto modelNodeBackendObject = modelNodeBackend.value<QObject*>();
|
||||||
|
|
||||||
const auto backendObjectCasted =
|
const auto backendObjectCasted =
|
||||||
@@ -47,18 +46,22 @@ void ItemFilterModel::setModelNodeBackend(const QVariant &modelNodeBackend)
|
|||||||
|
|
||||||
void ItemFilterModel::setTypeFilter(const QString &filter)
|
void ItemFilterModel::setTypeFilter(const QString &filter)
|
||||||
{
|
{
|
||||||
if (m_typeFilter != filter) {
|
if (m_typeFilter == filter)
|
||||||
m_typeFilter = filter;
|
return;
|
||||||
setupModel();
|
|
||||||
}
|
m_typeFilter = filter;
|
||||||
|
setupModel();
|
||||||
|
emit typeFilterChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemFilterModel::setSelectionOnly(bool value)
|
void ItemFilterModel::setSelectionOnly(bool value)
|
||||||
{
|
{
|
||||||
if (m_selectionOnly != value) {
|
if (m_selectionOnly == value)
|
||||||
m_selectionOnly = value;
|
return;
|
||||||
setupModel();
|
|
||||||
}
|
m_selectionOnly = value;
|
||||||
|
setupModel();
|
||||||
|
emit selectionOnlyChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ItemFilterModel::typeFilter() const
|
QString ItemFilterModel::typeFilter() const
|
||||||
@@ -73,12 +76,7 @@ bool ItemFilterModel::selectionOnly() const
|
|||||||
|
|
||||||
void ItemFilterModel::registerDeclarativeType()
|
void ItemFilterModel::registerDeclarativeType()
|
||||||
{
|
{
|
||||||
qmlRegisterType<ItemFilterModel>("HelperWidgets",2,0,"ItemFilterModel");
|
qmlRegisterType<ItemFilterModel>("HelperWidgets", 2, 0, "ItemFilterModel");
|
||||||
}
|
|
||||||
|
|
||||||
QModelIndex ItemFilterModel::index(int row, int column, const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
return QAbstractListModel::index(row, column, parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ItemFilterModel::rowCount(const QModelIndex &) const
|
int ItemFilterModel::rowCount(const QModelIndex &) const
|
||||||
@@ -91,7 +89,7 @@ QVariant ItemFilterModel::data(const QModelIndex &index, int role) const
|
|||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
ModelNode node = modelNodeForRow(index.row());
|
const ModelNode node = modelNodeForRow(index.row());
|
||||||
|
|
||||||
QVariant value;
|
QVariant value;
|
||||||
switch (role) {
|
switch (role) {
|
||||||
@@ -102,9 +100,8 @@ QVariant ItemFilterModel::data(const QModelIndex &index, int role) const
|
|||||||
value = node.variantProperty("objectName").value();
|
value = node.variantProperty("objectName").value();
|
||||||
break;
|
break;
|
||||||
case IdAndNameRole:
|
case IdAndNameRole:
|
||||||
value = QString("%1 [%2]").arg(
|
value = QString("%1 [%2]").arg(node.variantProperty("objectName").value().toString(),
|
||||||
node.variantProperty("objectName").value().toString()
|
node.id());
|
||||||
,node.id());
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
value = node.id();
|
value = node.id();
|
||||||
@@ -114,12 +111,6 @@ QVariant ItemFilterModel::data(const QModelIndex &index, int role) const
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle model data manipulation here.
|
|
||||||
bool ItemFilterModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
|
||||||
{
|
|
||||||
return QAbstractListModel::setData(index, value, role);
|
|
||||||
}
|
|
||||||
|
|
||||||
QHash<int, QByteArray> ItemFilterModel::roleNames() const
|
QHash<int, QByteArray> ItemFilterModel::roleNames() const
|
||||||
{
|
{
|
||||||
return m_roles;
|
return m_roles;
|
||||||
|
@@ -16,7 +16,7 @@ class ItemFilterModel : public QAbstractListModel
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(QString typeFilter READ typeFilter WRITE setTypeFilter)
|
Q_PROPERTY(QString typeFilter READ typeFilter WRITE setTypeFilter NOTIFY typeFilterChanged)
|
||||||
Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged)
|
Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged)
|
||||||
Q_PROPERTY(QStringList itemModel READ itemModel NOTIFY itemModelChanged)
|
Q_PROPERTY(QStringList itemModel READ itemModel NOTIFY itemModelChanged)
|
||||||
Q_PROPERTY(bool selectionOnly READ selectionOnly WRITE setSelectionOnly NOTIFY selectionOnlyChanged)
|
Q_PROPERTY(bool selectionOnly READ selectionOnly WRITE setSelectionOnly NOTIFY selectionOnlyChanged)
|
||||||
@@ -41,15 +41,13 @@ public:
|
|||||||
|
|
||||||
static void registerDeclarativeType();
|
static void registerDeclarativeType();
|
||||||
|
|
||||||
// Make index accessible for Qml side since it's not accessible by default in QAbstractListModel
|
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
Q_INVOKABLE QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const override;
|
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
Q_INVOKABLE virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
||||||
Q_INVOKABLE virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
|
||||||
Q_INVOKABLE virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
|
|
||||||
|
|
||||||
virtual QHash<int,QByteArray> roleNames() const override;
|
virtual QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void typeFilterChanged();
|
||||||
void modelNodeBackendChanged();
|
void modelNodeBackendChanged();
|
||||||
void itemModelChanged();
|
void itemModelChanged();
|
||||||
void selectionOnlyChanged();
|
void selectionOnlyChanged();
|
||||||
|
Reference in New Issue
Block a user