diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index fcea12a3096..227e7067dac 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -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 diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.cpp b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.cpp index bbbda2e095f..6dc786919c2 100644 --- a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.cpp +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.cpp @@ -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 +#include "listmodeleditormodel.h" +#include "listmodeleditorpropertydialog.h" + #include +#include #include #include @@ -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); } diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.h b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.h index d881c45b871..62a525413d6 100644 --- a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.h +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditordialog.h @@ -7,8 +7,8 @@ QT_BEGIN_NAMESPACE class QAbstractItemModel; -class QTableView; class QModelIndex; +class QTableView; QT_END_NAMESPACE namespace Ui { diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditorpropertydialog.cpp b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditorpropertydialog.cpp new file mode 100644 index 00000000000..0c91041f8fb --- /dev/null +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditorpropertydialog.cpp @@ -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 +#include + +#include +#include +#include +#include +#include +#include +#include + +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 diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditorpropertydialog.h b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditorpropertydialog.h new file mode 100644 index 00000000000..71bea6bc978 --- /dev/null +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditorpropertydialog.h @@ -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 + +#include + +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