ListModelEditor: Prevent adding qml keywords as a property name

Qml keywords shouldn't be used a property name for the list elements.
Also the user can't add an existing property name.

Fixes: QDS-15121
Change-Id: I3886ddfffe4013f8a92c53e1a126e46c40ebccde
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
Ali Kianian
2025-04-11 15:53:52 +03:00
parent 1186c495f8
commit 97e0a25271
5 changed files with 128 additions and 7 deletions

View File

@@ -496,6 +496,7 @@ extend_qtc_plugin(QmlDesigner
SOURCES
listmodeleditordialog.cpp listmodeleditordialog.h
listmodeleditormodel.cpp listmodeleditormodel.h
listmodeleditorpropertydialog.cpp listmodeleditorpropertydialog.h
)
extend_qtc_plugin(QmlDesigner

View File

@@ -2,10 +2,12 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "listmodeleditordialog.h"
#include "listmodeleditormodel.h"
#include <theme.h>
#include "listmodeleditormodel.h"
#include "listmodeleditorpropertydialog.h"
#include <qmldesignericons.h>
#include <theme.h>
#include <coreplugin/icore.h>
#include <utils/algorithm.h>
@@ -123,10 +125,14 @@ void ListModelEditorDialog::addRowBelow()
void ListModelEditorDialog::openColumnDialog()
{
bool ok;
QString columnName = QInputDialog::getText(
this, tr("Add Property"), tr("Property name:"), QLineEdit::Normal, "", &ok);
if (ok && !columnName.isEmpty())
ListModelEditorPropertyDialog propertyDialog{m_model->propertyNames()};
int result = propertyDialog.exec();
if (result != QDialog::Accepted)
return;
const QString columnName = propertyDialog.propertyName();
if (!columnName.isEmpty())
m_model->addColumn(columnName);
}

View File

@@ -7,8 +7,8 @@
QT_BEGIN_NAMESPACE
class QAbstractItemModel;
class QTableView;
class QModelIndex;
class QTableView;
QT_END_NAMESPACE
namespace Ui {

View File

@@ -0,0 +1,78 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "listmodeleditorpropertydialog.h"
#include <modelutils.h>
#include <theme.h>
#include <QDialogButtonBox>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QRegularExpressionValidator>
#include <QSpacerItem>
namespace QmlDesigner {
ListModelEditorPropertyDialog::ListModelEditorPropertyDialog(const PropertyNameList &existingProperties)
: QDialog()
, m_existingProperties(existingProperties)
, m_lineEdit(new QLineEdit(this))
, m_errorLabel(new QLabel(this))
{
static const QRegularExpression propertyNameRegex{R"(^[a-z_]{1}\w+$)"};
QLabel *propertyLabel = new QLabel(tr("Property name:"), this);
m_lineEdit->setValidator(new QRegularExpressionValidator(propertyNameRegex, this));
connect(m_lineEdit,
&QLineEdit::textChanged,
this,
&ListModelEditorPropertyDialog::secondaryValidation);
QDialogButtonBox *dialogButtons = new QDialogButtonBox(this);
m_okButton = dialogButtons->addButton(QDialogButtonBox::Ok);
dialogButtons->addButton(QDialogButtonBox::Cancel);
connect(dialogButtons, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(dialogButtons, &QDialogButtonBox::rejected, this, &QDialog::reject);
m_errorLabel->setStyleSheet(
QString("color: %1").arg(Theme::getColor(Theme::DSwarningColor).name()));
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
dialogLayout->addWidget(propertyLabel);
dialogLayout->addWidget(m_lineEdit);
dialogLayout->addWidget(m_errorLabel);
dialogLayout->addSpacerItem(
new QSpacerItem{1, 10, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding});
dialogLayout->addWidget(dialogButtons);
setWindowTitle(tr("Add property"));
setError({});
}
QString ListModelEditorPropertyDialog::propertyName() const
{
return m_lineEdit->text();
}
void ListModelEditorPropertyDialog::secondaryValidation(const QString &text)
{
if (ModelUtils::isQmlKeyword(text))
setError(tr("`%1` is a QML keyword and can't be used as a property name.").arg(text));
else if (m_existingProperties.contains(text.toUtf8()))
setError(tr("`%1` already exists in the property list.").arg(text));
else
setError({});
}
void ListModelEditorPropertyDialog::setError(const QString &errorString)
{
const bool hasError = !errorString.isEmpty();
const bool nameIsEmpty = propertyName().isEmpty();
m_errorLabel->setText(errorString);
m_okButton->setEnabled(!hasError && !nameIsEmpty);
}
} // namespace QmlDesigner

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#pragma once
#include <nodeinstanceglobal.h>
#include <QDialog>
QT_BEGIN_NAMESPACE
class QLabel;
class QLineEdit;
class QPushButton;
QT_END_NAMESPACE
namespace QmlDesigner {
class ListModelEditorPropertyDialog : public QDialog
{
Q_OBJECT
public:
ListModelEditorPropertyDialog(const PropertyNameList &existingProperties);
QString propertyName() const;
private:
void secondaryValidation(const QString &text);
void setError(const QString &errorString);
const PropertyNameList m_existingProperties;
QLineEdit *m_lineEdit = nullptr;
QLabel *m_errorLabel = nullptr;
QPushButton *m_okButton = nullptr;
};
} // namespace QmlDesigner