diff options
14 files changed, 180 insertions, 4 deletions
diff --git a/doc/src/projects/creator-only/creator-projects-custom-wizards-json.qdoc b/doc/src/projects/creator-only/creator-projects-custom-wizards-json.qdoc index 80fcdaa832..3d29edd0c8 100644 --- a/doc/src/projects/creator-only/creator-projects-custom-wizards-json.qdoc +++ b/doc/src/projects/creator-only/creator-projects-custom-wizards-json.qdoc @@ -683,6 +683,11 @@ \li \c trIncompleteMessage is shown when the field's \c isComplete was evaluated to \c false. + \li \c persistenceKey makes the user choice persistent. The value is + taken to be a settings key. If the user changes the default + value of the widget, the user-provided value is stored and will + become the new default value the next time the wizard is run. + \li \c data specifies settings for the widget: \list diff --git a/share/qtcreator/templates/wizards/autotest/wizard.json b/share/qtcreator/templates/wizards/autotest/wizard.json index 6744a14a8c..e35f9cd980 100644 --- a/share/qtcreator/templates/wizards/autotest/wizard.json +++ b/share/qtcreator/templates/wizards/autotest/wizard.json @@ -171,6 +171,7 @@ "name": "BuildSystem", "trDisplayName": "Build system:", "type": "ComboBox", + "persistenceKey": "BuildSystemType", "data": { "index": 0, diff --git a/share/qtcreator/templates/wizards/projects/consoleapp/wizard.json b/share/qtcreator/templates/wizards/projects/consoleapp/wizard.json index b500c9edf4..aa64d12bed 100644 --- a/share/qtcreator/templates/wizards/projects/consoleapp/wizard.json +++ b/share/qtcreator/templates/wizards/projects/consoleapp/wizard.json @@ -39,6 +39,7 @@ "name": "BuildSystem", "trDisplayName": "Build system:", "type": "ComboBox", + "persistenceKey": "BuildSystemType", "data": { "index": 0, diff --git a/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json b/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json index 512ffdfe66..0b12fd67e1 100644 --- a/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json +++ b/share/qtcreator/templates/wizards/projects/cpplibrary/wizard.json @@ -54,6 +54,7 @@ "name": "BuildSystem", "trDisplayName": "Build system:", "type": "ComboBox", + "persistenceKey": "BuildSystemType", "data": { "index": 0, diff --git a/share/qtcreator/templates/wizards/projects/plainc/wizard.json b/share/qtcreator/templates/wizards/projects/plainc/wizard.json index 66514cb9a7..205e02c379 100644 --- a/share/qtcreator/templates/wizards/projects/plainc/wizard.json +++ b/share/qtcreator/templates/wizards/projects/plainc/wizard.json @@ -36,6 +36,7 @@ "name": "BuildSystem", "trDisplayName": "Build system:", "type": "ComboBox", + "persistenceKey": "BuildSystemType", "data": { "index": 0, diff --git a/share/qtcreator/templates/wizards/projects/plaincpp/wizard.json b/share/qtcreator/templates/wizards/projects/plaincpp/wizard.json index f5fbffaa84..496f2f41c1 100644 --- a/share/qtcreator/templates/wizards/projects/plaincpp/wizard.json +++ b/share/qtcreator/templates/wizards/projects/plaincpp/wizard.json @@ -36,6 +36,7 @@ "name": "BuildSystem", "trDisplayName": "Build system:", "type": "ComboBox", + "persistenceKey": "BuildSystemType", "data": { "index": 0, diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json index 412aa3f8f8..04fa9bbb7d 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/empty/wizard.json @@ -44,6 +44,7 @@ "name": "BuildSystem", "trDisplayName": "Build system:", "type": "ComboBox", + "persistenceKey": "BuildSystemType", "data": { "index": 0, @@ -79,6 +80,7 @@ "name": "QtVersion", "trDisplayName": "Minimal required Qt version:", "type": "ComboBox", + "persistenceKey": "QtQuick.minimumQtVersion", "data": { "index": 1, @@ -163,6 +165,7 @@ "name": "UseVirtualKeyboard", "trDisplayName": "Use Qt Virtual Keyboard", "type": "CheckBox", + "persistenceKey": "QtQuick.UseVirtualKeyboard.%{UseVirtualKeyboardByDefault}", "data": { "checked": "%{UseVirtualKeyboardByDefault}" diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json index adfa7def75..1fa633f83d 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/scroll/wizard.json @@ -46,6 +46,7 @@ "name": "BuildSystem", "trDisplayName": "Build system:", "type": "ComboBox", + "persistenceKey": "BuildSystemType", "data": { "index": 0, @@ -81,6 +82,7 @@ "name": "QtVersion", "trDisplayName": "Minimal required Qt version:", "type": "ComboBox", + "persistenceKey": "QtQuick.minimumQtVersion", "data": { "index": 1, @@ -214,6 +216,7 @@ "name": "UseVirtualKeyboard", "trDisplayName": "Use Qt Virtual Keyboard", "type": "CheckBox", + "persistenceKey": "QtQuick.UseVirtualKeyboard.%{UseVirtualKeyboardByDefault}", "data": { "checked": "%{UseVirtualKeyboardByDefault}" diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json index a4593f8eb1..59ea4db313 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/stack/wizard.json @@ -46,6 +46,7 @@ "name": "BuildSystem", "trDisplayName": "Build system:", "type": "ComboBox", + "persistenceKey": "BuildSystemType", "data": { "index": 0, @@ -81,6 +82,7 @@ "name": "QtVersion", "trDisplayName": "Minimal required Qt version:", "type": "ComboBox", + "persistenceKey": "QtQuick.minimumQtVersion", "data": { "index": 1, @@ -232,6 +234,7 @@ "name": "UseVirtualKeyboard", "trDisplayName": "Use Qt Virtual Keyboard", "type": "CheckBox", + "persistenceKey": "QtQuick.UseVirtualKeyboard.%{UseVirtualKeyboardByDefault}", "data": { "checked": "%{UseVirtualKeyboardByDefault}" diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json index 9f47b864e1..b2e90419b4 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/swipe/wizard.json @@ -46,6 +46,7 @@ "name": "BuildSystem", "trDisplayName": "Build system:", "type": "ComboBox", + "persistenceKey": "BuildSystemType", "data": { "index": 0, @@ -81,6 +82,7 @@ "name": "QtVersion", "trDisplayName": "Minimal required Qt version:", "type": "ComboBox", + "persistenceKey": "QtQuick.minimumQtVersion", "data": { "index": 1, @@ -232,6 +234,7 @@ "name": "UseVirtualKeyboard", "trDisplayName": "Use Qt Virtual Keyboard", "type": "CheckBox", + "persistenceKey": "QtQuick.UseVirtualKeyboard.%{UseVirtualKeyboardByDefault}", "data": { "checked": "%{UseVirtualKeyboardByDefault}" diff --git a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json index 971ef3f88f..055299f94d 100644 --- a/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtwidgetsapplication/wizard.json @@ -42,6 +42,7 @@ "name": "BuildSystem", "trDisplayName": "Build system:", "type": "ComboBox", + "persistenceKey": "BuildSystemType", "data": { "index": 0, diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp index 749c660e01..432a22fec1 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp @@ -29,6 +29,7 @@ #include "jsonwizard.h" #include "jsonwizardfactory.h" +#include <coreplugin/icore.h> #include <utils/algorithm.h> #include <utils/fancylineedit.h> #include <utils/qtcassert.h> @@ -57,6 +58,7 @@ const char NAME_KEY[] = "name"; const char DISPLAY_NAME_KEY[] = "trDisplayName"; const char TOOLTIP_KEY[] = "trToolTip"; const char MANDATORY_KEY[] = "mandatory"; +const char PERSISTENCE_KEY_KEY[] = "persistenceKey"; const char VISIBLE_KEY[] = "visible"; const char ENABLED_KEY[] = "enabled"; const char SPAN_KEY[] = "span"; @@ -153,6 +155,21 @@ QString JsonFieldPage::Field::type() return d->m_type; } +void JsonFieldPage::Field::setHasUserChanges() +{ + d->m_hasUserChanges = true; +} + +void JsonFieldPage::Field::fromSettings(const QVariant &value) +{ + Q_UNUSED(value); +} + +QVariant JsonFieldPage::Field::toSettings() const +{ + return {}; +} + JsonFieldPage::Field *JsonFieldPage::Field::parse(const QVariant &input, QString *errorMessage) { if (input.type() != QVariant::Map) { @@ -192,6 +209,7 @@ JsonFieldPage::Field *JsonFieldPage::Field::parse(const QVariant &input, QString data->setHasSpan(consumeValue(tmp, SPAN_KEY, false).toBool()); data->setIsCompleteExpando(consumeValue(tmp, IS_COMPLETE_KEY, true), consumeValue(tmp, IS_COMPLETE_MESSAGE_KEY).toString()); + data->setPersistenceKey(consumeValue(tmp, PERSISTENCE_KEY_KEY).toString()); QVariant dataVal = consumeValue(tmp, DATA_KEY); if (!data->parseData(dataVal, errorMessage)) { @@ -295,6 +313,11 @@ QString JsonFieldPage::Field::toolTip() return d->m_toolTip; } +QString JsonFieldPage::Field::persistenceKey() const +{ + return d->m_persistenceKey; +} + bool JsonFieldPage::Field::isMandatory() { return d->m_isMandatory; @@ -305,6 +328,11 @@ bool JsonFieldPage::Field::hasSpan() return d->m_hasSpan; } +bool JsonFieldPage::Field::hasUserChanges() const +{ + return d->m_hasUserChanges; +} + QVariant JsonFieldPage::value(const QString &key) { QVariant v = property(key.toUtf8()); @@ -353,6 +381,11 @@ void JsonFieldPage::Field::setIsCompleteExpando(const QVariant &v, const QString d->m_isCompleteExpandoMessage = m; } +void JsonFieldPage::Field::setPersistenceKey(const QString &key) +{ + d->m_persistenceKey = key; +} + // -------------------------------------------------------------------- // LabelFieldData: // -------------------------------------------------------------------- @@ -494,6 +527,7 @@ QWidget *LineEditField::createWidget(const QString &displayName, JsonFieldPage * w->setHistoryCompleter(m_historyId, m_restoreLastHistoryItem); w->setEchoMode(m_isPassword ? QLineEdit::Password : QLineEdit::Normal); + QObject::connect(w, &FancyLineEdit::textEdited, [this] { setHasUserChanges(); }); return w; } @@ -551,6 +585,16 @@ void LineEditField::initializeData(MacroExpander *expander) m_isValidating = false; } +void LineEditField::fromSettings(const QVariant &value) +{ + m_defaultText = value.toString(); +} + +QVariant LineEditField::toSettings() const +{ + return qobject_cast<FancyLineEdit *>(widget())->text(); +} + // -------------------------------------------------------------------- // TextEditFieldData: // -------------------------------------------------------------------- @@ -585,6 +629,10 @@ QWidget *TextEditField::createWidget(const QString &displayName, JsonFieldPage * Q_UNUSED(page) auto w = new QTextEdit; w->setAcceptRichText(m_acceptRichText); + QObject::connect(w, &QTextEdit::textChanged, [this, w] { + if (w->toPlainText() != m_defaultText) + setHasUserChanges(); + }); return w; } @@ -622,6 +670,16 @@ void TextEditField::initializeData(MacroExpander *expander) w->setPlainText(expander->expand(m_defaultText)); } +void TextEditField::fromSettings(const QVariant &value) +{ + m_defaultText = value.toString(); +} + +QVariant TextEditField::toSettings() const +{ + return qobject_cast<QTextEdit *>(widget())->toPlainText(); +} + // -------------------------------------------------------------------- // PathChooserFieldData: // -------------------------------------------------------------------- @@ -678,6 +736,10 @@ QWidget *PathChooserField::createWidget(const QString &displayName, JsonFieldPag auto w = new PathChooser; if (!m_historyId.isEmpty()) w->setHistoryCompleter(m_historyId); + QObject::connect(w, &PathChooser::pathChanged, [this, w] { + if (w->path() != m_path) + setHasUserChanges(); + }); return w; } @@ -720,6 +782,16 @@ void PathChooserField::initializeData(MacroExpander *expander) w->setPath(m_currentPath); } +void PathChooserField::fromSettings(const QVariant &value) +{ + m_path = value.toString(); +} + +QVariant PathChooserField::toSettings() const +{ + return qobject_cast<PathChooser *>(widget())->path(); +} + // -------------------------------------------------------------------- // CheckBoxFieldData: // -------------------------------------------------------------------- @@ -770,6 +842,7 @@ void CheckBoxField::setup(JsonFieldPage *page, const QString &name) QObject::connect(w, &QCheckBox::stateChanged, page, [this, page]() { m_isModified = true; + setHasUserChanges(); emit page->completeChanged(); }); } @@ -795,6 +868,16 @@ void CheckBoxField::initializeData(MacroExpander *expander) w->setChecked(JsonWizard::boolFromVariant(m_checkedExpression, expander)); } +void CheckBoxField::fromSettings(const QVariant &value) +{ + m_checkedExpression = value; +} + +QVariant CheckBoxField::toSettings() const +{ + return qobject_cast<QCheckBox *>(widget())->isChecked(); +} + // -------------------------------------------------------------------- // ListFieldData: // -------------------------------------------------------------------- @@ -958,7 +1041,7 @@ QStandardItemModel *ListField::itemModel() return m_itemModel; } -QItemSelectionModel *ListField::selectionModel() +QItemSelectionModel *ListField::selectionModel() const { return m_selectionModel; } @@ -991,6 +1074,22 @@ void ListField::updateIndex() } } +void ListField::fromSettings(const QVariant &value) +{ + for (decltype(m_itemList)::size_type i = 0; i < m_itemList.size(); ++i) { + if (m_itemList.at(i)->data(ValueRole) == value) { + m_index = int(i); + break; + } + } +} + +QVariant ListField::toSettings() const +{ + const int idx = selectionModel()->currentIndex().row(); + return idx >= 0 ? m_itemList.at(idx)->data(ValueRole) : QVariant(); +} + void ComboBoxField::setup(JsonFieldPage *page, const QString &name) { auto w = qobject_cast<QComboBox*>(widget()); @@ -1030,7 +1129,10 @@ void ComboBoxField::setup(JsonFieldPage *page, const QString &name) QWidget *ComboBoxField::createWidget(const QString & /*displayName*/, JsonFieldPage * /*page*/) { - return new QComboBox; + const auto comboBox = new QComboBox; + QObject::connect(comboBox, QOverload<int>::of(&QComboBox::activated), + [this] { setHasUserChanges(); }); + return comboBox; } void ComboBoxField::initializeData(MacroExpander *expander) @@ -1068,7 +1170,10 @@ void IconListField::setup(JsonFieldPage *page, const QString &name) QWidget *IconListField::createWidget(const QString & /*displayName*/, JsonFieldPage * /*page*/) { - return new QListView; + const auto listView = new QListView; + QObject::connect(listView->selectionModel(), &QItemSelectionModel::currentChanged, + [this] { setHasUserChanges(); }); + return listView; } void IconListField::initializeData(MacroExpander *expander) @@ -1131,6 +1236,13 @@ bool JsonFieldPage::setup(const QVariant &data) if (!f) continue; f->createWidget(this); + if (!f->persistenceKey().isEmpty()) { + f->setPersistenceKey(m_expander->expand(f->persistenceKey())); + const QVariant value = Core::ICore::settings() + ->value(fullSettingsKey(f->persistenceKey())); + if (value.isValid()) + f->fromSettings(value); + } m_fields.append(f); } return true; @@ -1172,6 +1284,17 @@ void JsonFieldPage::cleanupPage() f->cleanup(m_expander); } +bool JsonFieldPage::validatePage() +{ + for (Field * const f : qAsConst(m_fields)) + if (!f->persistenceKey().isEmpty() && f->hasUserChanges()) { + const QVariant value = f->toSettings(); + if (value.isValid()) + Core::ICore::settings()->setValue(fullSettingsKey(f->persistenceKey()), value); + } + return true; +} + void JsonFieldPage::showError(const QString &m) const { m_errorLabel->setText(m); @@ -1199,4 +1322,9 @@ JsonFieldPage::Field *JsonFieldPage::createFieldData(const QString &type) return nullptr; } +QString JsonFieldPage::fullSettingsKey(const QString &fieldKey) +{ + return "Wizards/" + fieldKey; +} + } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h index 16da75c4ad..5ef115cfbf 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.h @@ -83,8 +83,10 @@ public: QString name(); QString displayName(); QString toolTip(); + QString persistenceKey() const; bool isMandatory(); bool hasSpan(); + bool hasUserChanges() const; protected: QWidget *widget() const; @@ -95,8 +97,12 @@ public: { Q_UNUSED(page); Q_UNUSED(name) } QString type(); + void setHasUserChanges(); private: + virtual void fromSettings(const QVariant &value); + virtual QVariant toSettings() const; + void setTexts(const QString &n, const QString &dn, const QString &tt); void setIsMandatory(bool b); void setHasSpan(bool b); @@ -104,6 +110,7 @@ public: void setVisibleExpression(const QVariant &v); void setEnabledExpression(const QVariant &v); void setIsCompleteExpando(const QVariant &v, const QString &m); + void setPersistenceKey(const QString &key); friend class JsonFieldPage; @@ -121,6 +128,7 @@ public: bool isComplete() const override; void initializePage() override; void cleanupPage() override; + bool validatePage() override; QFormLayout *layout() const { return m_formLayout; } @@ -135,6 +143,7 @@ private: static QHash<QString, FieldFactory> m_factories; static Field *createFieldData(const QString &type); + static QString fullSettingsKey(const QString &fieldKey); QFormLayout *m_formLayout; QLabel *m_errorLabel; diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h index 44ab872802..62db37aff6 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h @@ -57,11 +57,13 @@ public: QString m_toolTip; bool m_isMandatory = false; bool m_hasSpan = false; + bool m_hasUserChanges = false; QVariant m_visibleExpression; QVariant m_enabledExpression; QVariant m_isCompleteExpando; QString m_isCompleteExpandoMessage; + QString m_persistenceKey; QLabel *m_label = nullptr; QWidget *m_widget = nullptr; @@ -106,6 +108,9 @@ private: bool validate(Utils::MacroExpander *expander, QString *message) override; void initializeData(Utils::MacroExpander *expander) override; + void fromSettings(const QVariant &value) override; + QVariant toSettings() const override; + bool m_isModified = false; bool m_isValidating = false; bool m_restoreLastHistoryItem = false; @@ -130,6 +135,9 @@ private: bool validate(Utils::MacroExpander *expander, QString *message) override; void initializeData(Utils::MacroExpander *expander) override; + void fromSettings(const QVariant &value) override; + QVariant toSettings() const override; + QString m_defaultText; bool m_acceptRichText = false; QString m_disabledText; @@ -150,6 +158,9 @@ private: bool validate(Utils::MacroExpander *expander, QString *message) override; void initializeData(Utils::MacroExpander *expander) override; + void fromSettings(const QVariant &value) override; + QVariant toSettings() const override; + QString m_path; QString m_basePath; QString m_historyId; @@ -172,6 +183,8 @@ private: bool validate(Utils::MacroExpander *expander, QString *message) override; void initializeData(Utils::MacroExpander *expander) override; + void fromSettings(const QVariant &value) override; + QVariant toSettings() const override; QString m_checkedValue; QString m_uncheckedValue; @@ -200,7 +213,7 @@ public: bool validate(Utils::MacroExpander *expander, QString *message) override; void initializeData(Utils::MacroExpander *expander) override; QStandardItemModel *itemModel(); - QItemSelectionModel *selectionModel(); + QItemSelectionModel *selectionModel() const; void setSelectionModel(QItemSelectionModel *selectionModel); QSize maxIconSize(); @@ -208,6 +221,9 @@ private: void addPossibleIconSize(const QIcon &icon); void updateIndex(); + void fromSettings(const QVariant &value) override; + QVariant toSettings() const override; + std::vector<std::unique_ptr<QStandardItem>> m_itemList; QStandardItemModel *m_itemModel = nullptr; QItemSelectionModel *m_selectionModel = nullptr; |