diff --git a/src/plugins/qmljseditor/qmljseditordocument.cpp b/src/plugins/qmljseditor/qmljseditordocument.cpp index 91c0fba3b43..444a5407304 100644 --- a/src/plugins/qmljseditor/qmljseditordocument.cpp +++ b/src/plugins/qmljseditor/qmljseditordocument.cpp @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -741,7 +743,8 @@ void QmlJSEditorDocumentPrivate::setSourcesWithCapabilities( static FilePath qmllsForFile(const FilePath &file, QmlJS::ModelManagerInterface *modelManager) { QmllsSettingsManager *settingsManager = QmllsSettingsManager::instance(); - bool enabled = settingsManager->useQmlls(); + ProjectExplorer::Project *project = ProjectExplorer::ProjectManager::projectForFile(file); + const bool enabled = settingsManager->useQmlls(project); if (!enabled) return {}; if (settingsManager->useLatestQmlls()) diff --git a/src/plugins/qmljseditor/qmljseditorplugin.cpp b/src/plugins/qmljseditor/qmljseditorplugin.cpp index b81eb209b9f..986ab1346c6 100644 --- a/src/plugins/qmljseditor/qmljseditorplugin.cpp +++ b/src/plugins/qmljseditor/qmljseditorplugin.cpp @@ -331,6 +331,7 @@ class QmlJSEditorPlugin final : public ExtensionSystem::IPlugin dd = new QmlJSEditorPluginPrivate; setupQmlJSEditor(); + setupQmlJsEditingProjectPanel(); } void extensionsInitialized() final diff --git a/src/plugins/qmljseditor/qmljseditorsettings.cpp b/src/plugins/qmljseditor/qmljseditorsettings.cpp index 58efdca8657..e5641d8d819 100644 --- a/src/plugins/qmljseditor/qmljseditorsettings.cpp +++ b/src/plugins/qmljseditor/qmljseditorsettings.cpp @@ -8,6 +8,10 @@ #include #include +#include +#include +#include + #include #include #include @@ -41,16 +45,19 @@ using namespace QmlJSEditor::Internal; using namespace QtSupport; using namespace Utils; +using namespace ProjectExplorer; namespace QmlJSEditor::Internal { static Q_LOGGING_CATEGORY(qmllsLog, "qtc.qmlls.settings", QtWarningMsg) +const char SETTINGS_KEY_MAIN[] = "QmlJSEditor"; const char AUTO_FORMAT_ON_SAVE[] = "QmlJSEditor.AutoFormatOnSave"; const char AUTO_FORMAT_ONLY_CURRENT_PROJECT[] = "QmlJSEditor.AutoFormatOnlyCurrentProject"; const char QML_CONTEXTPANE_KEY[] = "QmlJSEditor.ContextPaneEnabled"; const char QML_CONTEXTPANEPIN_KEY[] = "QmlJSEditor.ContextPanePinned"; const char FOLD_AUX_DATA[] = "QmlJSEditor.FoldAuxData"; +const char USE_GLOBAL_SETTINGS[] = "QmlJSEditor.UseGlobalSettings"; const char USE_QMLLS[] = "QmlJSEditor.UseQmlls"; const char USE_LATEST_QMLLS[] = "QmlJSEditor.UseLatestQmlls"; const char IGNORE_MINIMUM_QMLLS_VERSION[] = "QmlJSEditor.IgnoreMinimumQmllsVersion"; @@ -65,6 +72,7 @@ const char DISABLED_MESSAGES[] = "QmlJSEditor.disabledMessages"; const char DISABLED_MESSAGES_NONQUICKUI[] = "QmlJSEditor.disabledMessagesNonQuickUI"; const char DEFAULT_CUSTOM_FORMAT_COMMAND[] = "%{CurrentDocument:Project:QT_HOST_BINS}/qmlformat%{HostOs:ExecutableSuffix}"; +const char SETTINGS_PAGE[] = "C.QmlJsEditing"; QmlJsEditingSettings &settings() { @@ -162,9 +170,15 @@ bool QmllsSettingsManager::useLatestQmlls() const return m_useLatestQmlls; } -bool QmllsSettingsManager::useQmlls() const +bool QmllsSettingsManager::useQmlls(Project* onProject) const { - return m_useQmlls; + // check if disabled via project specific settings + ProjectSettings projectSettings{onProject}; + + const bool result = projectSettings.useGlobalSettings() ? m_useQmlls + : projectSettings.useQmlls(); + + return result; } static QList defaultDisabledMessages() @@ -485,10 +499,98 @@ private: QmlJsEditingSettingsPage::QmlJsEditingSettingsPage() { - setId("C.QmlJsEditing"); + setId(SETTINGS_PAGE); setDisplayName(::QmlJSEditor::Tr::tr("QML/JS Editing")); setCategory(Constants::SETTINGS_CATEGORY_QML); setWidgetCreator([] { return new QmlJsEditingSettingsPageWidget; }); + setSettingsProvider([] { return &settings(); }); } +ProjectSettings::ProjectSettings(Project *project) +{ + setAutoApply(true); + + const Key group = QmlJSEditor::Constants::SETTINGS_CATEGORY_QML; + + useQmlls.setSettingsKey(group, USE_QMLLS); + useQmlls.setDefaultValue(true); + useQmlls.setLabelText(Tr::tr("Turn on")); + useQmlls.setToolTip(Tr::tr("Enable QML Language Server on this project.")); + + useGlobalSettings.setSettingsKey(group, USE_GLOBAL_SETTINGS); + useGlobalSettings.setDefaultValue(true); + + Store map = storeFromVariant(project->namedSettings(SETTINGS_KEY_MAIN)); + fromMap(map); + + useQmlls.addOnChanged(this, [this, project] { save(project); }); + useGlobalSettings.addOnChanged(this, [this, project] { save(project); }); +} + +void ProjectSettings::save(Project *project) +{ + Store map; + toMap(map); + project->setNamedSettings(SETTINGS_KEY_MAIN, variantFromStore(map)); + + emit QmllsSettingsManager::instance()->settingsChanged(); +} + +class QmlJsEditingProjectSettingsWidget final : public ProjectSettingsWidget +{ +public: + explicit QmlJsEditingProjectSettingsWidget(Project *project) + : m_settings{project} + { + setUseGlobalSettingsCheckBoxVisible(true); + setGlobalSettingsId(SETTINGS_PAGE); + setExpanding(true); + + setUseGlobalSettings(m_settings.useGlobalSettings()); + + setEnabled(!m_settings.useGlobalSettings()); + + using namespace Layouting; + // clang-format off + Column { + Group{ + title(Tr::tr("QML Language Server")), + Column{ + &m_settings.useQmlls, + }, + }, + st, + }.attachTo(this); + // clang-format on + + connect( + this, &ProjectSettingsWidget::useGlobalSettingsChanged, this, [this](bool newUseGlobal) { + setEnabled(!newUseGlobal); + m_settings.useGlobalSettings.setValue(newUseGlobal); + }); + } + +private: + ProjectSettings m_settings; +}; + +class QmlJsEditingProjectPanelFactory : public ProjectPanelFactory +{ +public: + QmlJsEditingProjectPanelFactory() + { + setPriority(34); // just before the LanguageClientProjectPanelFactory + setDisplayName(Tr::tr("Qt Quick")); + setCreateWidgetFunction([](Project *project) { + return new QmlJsEditingProjectSettingsWidget(project); + }); + } +}; + +void setupQmlJsEditingProjectPanel() +{ + static QmlJsEditingProjectPanelFactory theQmlJsEditingProjectPanelFactory; +} + + } // QmlJsEditor::Internal diff --git a/src/plugins/qmljseditor/qmljseditorsettings.h b/src/plugins/qmljseditor/qmljseditorsettings.h index 040d6a363ee..a58c755b89e 100644 --- a/src/plugins/qmljseditor/qmljseditorsettings.h +++ b/src/plugins/qmljseditor/qmljseditorsettings.h @@ -5,6 +5,8 @@ #include +#include + #include #include @@ -51,7 +53,7 @@ public: Utils::FilePath latestQmlls(); void setupAutoupdate(); - bool useQmlls() const; + bool useQmlls(ProjectExplorer::Project* project) const; bool useLatestQmlls() const; public slots: @@ -76,4 +78,17 @@ public: QmlJsEditingSettingsPage(); }; +class ProjectSettings : public Utils::AspectContainer +{ +public: + ProjectSettings(ProjectExplorer::Project *project); + + Utils::BoolAspect useQmlls{this}; + Utils::BoolAspect useGlobalSettings{this}; + + void save(ProjectExplorer::Project *project); +}; + +void setupQmlJsEditingProjectPanel(); + } // QmlJSEditor::Internal diff --git a/src/plugins/qmljseditor/qmltaskmanager.cpp b/src/plugins/qmljseditor/qmltaskmanager.cpp index d45c6277b5a..5388b6d5522 100644 --- a/src/plugins/qmljseditor/qmltaskmanager.cpp +++ b/src/plugins/qmljseditor/qmltaskmanager.cpp @@ -120,8 +120,13 @@ static void triggerQmllintCMakeTarget() void QmlTaskManager::updateSemanticMessagesNow() { + // note: this can only be called for the startup project + Project *project = ProjectManager::startupProject(); + if (!project) + return; + // heuristic: qmllint will output meaningful warnings if qmlls is enabled - if (QmllsSettingsManager::instance()->useQmlls()) { + if (QmllsSettingsManager::instance()->useQmlls(project)) { // abort any update that's going on already, and remove old codemodel warnings m_messageCollector.cancel(); removeAllTasks(true);