forked from qt-creator/qt-creator
integrate qmlformat and improve formatter settings UX
- Add reformat action to trigger full document formatting via qmlformat - Integrate reformat action into context menu and qmljstools menu - Remove custom formatter command from preferences, default to qmlformat when LSP formatting fails - Group tabSettings and other options under 'Built-In Formatter Settings' for clarity - Move formatter selection to Code Style page with a new radio button for selection - Ensure preview updates according to the selected formatter - Populate qmlformat configuration widget automatically for Qt's built-in code style option by running qmlformat --write-defaults. - TabSettings is a data structure being considered by the text editor while rewriting the formatted data. Overwrite tabSettings with the values in the .qmlformat.ini. - fix the issue of builtin formatter being not respecting the current codestyle's tab settings. Task-number: QTCREATORBUG-26602 Change-Id: I2ec1b4a69712eedfafab358aaabb25c6b43ffa8e Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
This commit is contained in:
@@ -19,11 +19,12 @@
|
||||
|
||||
#include <projectexplorer/projectmanager.h>
|
||||
|
||||
#include <qmljs/parser/qmljsast_p.h>
|
||||
#include <qmljstools/qmljsindenter.h>
|
||||
#include <qmljstools/qmljsmodelmanager.h>
|
||||
#include <qmljstools/qmljsqtstylecodeformatter.h>
|
||||
|
||||
#include <qmljs/parser/qmljsast_p.h>
|
||||
#include <texteditor/tabsettings.h>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/infobar.h>
|
||||
@@ -466,6 +467,7 @@ QmlJSEditorDocumentPrivate::QmlJSEditorDocumentPrivate(QmlJSEditorDocument *pare
|
||||
: q(parent)
|
||||
, m_semanticHighlighter(new SemanticHighlighter(parent))
|
||||
, m_outlineModel(new QmlOutlineModel(parent))
|
||||
, m_tabSettings(parent->TextDocument::tabSettings())
|
||||
{
|
||||
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
|
||||
|
||||
@@ -838,5 +840,17 @@ void QmlJSEditorDocument::setSourcesWithCapabilities(
|
||||
d->setSourcesWithCapabilities(cap);
|
||||
}
|
||||
|
||||
TextEditor::TabSettings QmlJSEditorDocument::tabSettings() const
|
||||
{
|
||||
return d->m_tabSettings;
|
||||
}
|
||||
|
||||
void QmlJSEditorDocument::setTabSettings(const TextEditor::TabSettings &tabSettings)
|
||||
{
|
||||
if (tabSettings != d->m_tabSettings) {
|
||||
d->m_tabSettings = tabSettings;
|
||||
emit tabSettingsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
} // QmlJSEditor
|
||||
|
@@ -40,6 +40,8 @@ public:
|
||||
|
||||
void setSourcesWithCapabilities(const LanguageServerProtocol::ServerCapabilities &cap);
|
||||
|
||||
virtual TextEditor::TabSettings tabSettings() const override;
|
||||
void setTabSettings(const TextEditor::TabSettings &tabSettings);
|
||||
signals:
|
||||
void updateCodeWarnings(QmlJS::Document::Ptr doc);
|
||||
void semanticInfoUpdated(const QmlJSTools::SemanticInfo &semanticInfo);
|
||||
|
@@ -6,6 +6,8 @@
|
||||
#include <languageserverprotocol/servercapabilities.h>
|
||||
#include <qmljs/qmljsdocument.h>
|
||||
#include <qmljstools/qmljssemanticinfo.h>
|
||||
#include <texteditor/tabsettings.h>
|
||||
#include <texteditor/textdocument.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QTextLayout>
|
||||
@@ -83,6 +85,7 @@ public:
|
||||
QmllsStatus::Source::EmbeddedCodeModel,
|
||||
QmllsStatus::Source::EmbeddedCodeModel,
|
||||
{}};
|
||||
TextEditor::TabSettings m_tabSettings;
|
||||
};
|
||||
|
||||
} // Internal
|
||||
|
@@ -16,6 +16,8 @@
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
#include <qmljs/qmljsreformatter.h>
|
||||
|
||||
#include <qmljstools/qmlformatsettings.h>
|
||||
#include <qmljstools/qmljscodestylesettings.h>
|
||||
#include <qmljstools/qmljstoolsconstants.h>
|
||||
#include <qmljstools/qmljstoolssettings.h>
|
||||
|
||||
@@ -25,6 +27,7 @@
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/messagemanager.h>
|
||||
|
||||
#include <extensionsystem/iplugin.h>
|
||||
|
||||
@@ -42,6 +45,7 @@
|
||||
#include <texteditor/texteditor.h>
|
||||
#include <texteditor/texteditorconstants.h>
|
||||
|
||||
#include <utils/filepath.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/macroexpander.h>
|
||||
#include <utils/mimeconstants.h>
|
||||
@@ -54,6 +58,7 @@
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Core;
|
||||
using namespace Utils;
|
||||
using namespace QmlJSTools;
|
||||
|
||||
namespace QmlJSEditor::Internal {
|
||||
|
||||
@@ -70,7 +75,7 @@ public:
|
||||
Command *addToolAction(QAction *a, Context &context, Id id,
|
||||
ActionContainer *c1, const QString &keySequence);
|
||||
|
||||
void reformatFile();
|
||||
FormatResult reformatFile();
|
||||
|
||||
QmlJS::JsonSchemaManager *jsonManager() { return &m_jsonManager;}
|
||||
QmlJSQuickFixAssistProvider *quickFixAssistProvider() { return &m_quickFixAssistProvider; }
|
||||
@@ -140,11 +145,15 @@ QmlJSEditorPluginPrivate::QmlJSEditorPluginPrivate()
|
||||
connect(semanticScan, &QAction::triggered, this, &QmlJSEditorPluginPrivate::runSemanticScan);
|
||||
qmlToolsMenu->addAction(cmd);
|
||||
|
||||
m_reformatFileAction = new QAction(Tr::tr("Reformat File"), this);
|
||||
cmd = ActionManager::registerAction(m_reformatFileAction,
|
||||
Id("QmlJSEditor.ReformatFile"),
|
||||
context);
|
||||
connect(m_reformatFileAction, &QAction::triggered, this, &QmlJSEditorPluginPrivate::reformatFile);
|
||||
|
||||
m_reformatFileAction = ActionBuilder(this, TextEditor::Constants::REFORMAT_FILE)
|
||||
.setContext(context)
|
||||
.addOnTriggered([this] { reformatFile(); })
|
||||
.setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+Shift+;")))
|
||||
.setText(Tr::tr("Reformat Document"))
|
||||
.addToContainer(Core::Constants::M_EDIT_ADVANCED, Core::Constants::G_EDIT_FORMAT)
|
||||
.contextAction();
|
||||
cmd = ActionManager::command(TextEditor::Constants::REFORMAT_FILE);
|
||||
qmlToolsMenu->addAction(cmd);
|
||||
|
||||
QAction *inspectElementAction = new QAction(Tr::tr("Inspect API for Element Under Cursor"), this);
|
||||
@@ -171,6 +180,9 @@ QmlJSEditorPluginPrivate::QmlJSEditorPluginPrivate()
|
||||
cmd = ActionManager::command(TextEditor::Constants::AUTO_INDENT_SELECTION);
|
||||
contextMenu->addAction(cmd);
|
||||
|
||||
cmd = ActionManager::command(TextEditor::Constants::REFORMAT_FILE);
|
||||
contextMenu->addAction(cmd);
|
||||
|
||||
cmd = ActionManager::command(TextEditor::Constants::UN_COMMENT_SELECTION);
|
||||
contextMenu->addAction(cmd);
|
||||
|
||||
@@ -188,35 +200,56 @@ QmlJS::JsonSchemaManager *jsonManager()
|
||||
return dd->jsonManager();
|
||||
}
|
||||
|
||||
static void reformatByQmlFormat(QPointer<QmlJSEditorDocument> document)
|
||||
static void overrideTabSettings(QPointer<QmlJSEditorDocument> document)
|
||||
{
|
||||
QString formatCommand = settings().formatCommand();
|
||||
if (formatCommand.isEmpty())
|
||||
formatCommand = settings().defaultFormatCommand();
|
||||
const auto exe = FilePath::fromUserInput(globalMacroExpander()->expand(formatCommand));
|
||||
const QString args = globalMacroExpander()->expand(
|
||||
settings().formatCommandOptions());
|
||||
const CommandLine commandLine(exe, args, CommandLine::Raw);
|
||||
// Search .qmlformat.ini and read the tab settings from it
|
||||
if (!document)
|
||||
return;
|
||||
|
||||
TextEditor::TabSettings tabSettings = document->tabSettings();
|
||||
QSettings settings(
|
||||
QmlJSTools::QmlFormatSettings::currentQmlFormatIniFile(document->filePath()).toUrlishString(),
|
||||
QSettings::IniFormat);
|
||||
|
||||
if (settings.contains("IndentWidth"))
|
||||
tabSettings.m_indentSize = settings.value("IndentWidth").toInt();
|
||||
if (settings.contains("UseTabs"))
|
||||
tabSettings.m_tabPolicy = settings.value("UseTabs").toBool()
|
||||
? TextEditor::TabSettings::TabPolicy::TabsOnlyTabPolicy
|
||||
: TextEditor::TabSettings::TabPolicy::SpacesOnlyTabPolicy;
|
||||
document->setTabSettings(tabSettings);
|
||||
}
|
||||
|
||||
static FormatResult reformatByQmlFormat(QPointer<QmlJSEditorDocument> document)
|
||||
{
|
||||
const FilePath &qmlformatPath = QmlFormatSettings::instance().latestQmlFormatPath();
|
||||
if (!qmlformatPath.isExecutableFile()) {
|
||||
Core::MessageManager::writeSilently(
|
||||
Tr::tr("QmlFormat not found."));
|
||||
return FormatResult::Failed;
|
||||
}
|
||||
const CommandLine commandLine(qmlformatPath, {});
|
||||
TextEditor::Command command;
|
||||
command.setExecutable(commandLine.executable());
|
||||
command.setProcessing(TextEditor::Command::FileProcessing);
|
||||
command.addOptions(commandLine.splitArguments());
|
||||
command.addOption("--inplace");
|
||||
command.addOption("%file");
|
||||
|
||||
if (!command.isValid())
|
||||
return;
|
||||
|
||||
return FormatResult::Failed;
|
||||
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForDocument(document);
|
||||
if (editors.isEmpty())
|
||||
return;
|
||||
return FormatResult::Failed;
|
||||
IEditor *currentEditor = EditorManager::currentEditor();
|
||||
IEditor *editor = editors.contains(currentEditor) ? currentEditor : editors.first();
|
||||
if (auto widget = TextEditor::TextEditorWidget::fromEditor(editor))
|
||||
if (auto widget = TextEditor::TextEditorWidget::fromEditor(editor)) {
|
||||
TextEditor::formatEditor(widget, command);
|
||||
return FormatResult::Success;
|
||||
}
|
||||
return FormatResult::Failed;
|
||||
}
|
||||
|
||||
static void reformatByBuiltInFormatter(QPointer<QmlJSEditorDocument> document)
|
||||
static FormatResult reformatByBuiltInFormatter(QPointer<QmlJSEditorDocument> document)
|
||||
{
|
||||
QmlJS::Document::Ptr documentPtr = document->semanticInfo().document;
|
||||
QmlJS::Snapshot snapshot = QmlJS::ModelManagerInterface::instance()->snapshot();
|
||||
@@ -224,7 +257,7 @@ static void reformatByBuiltInFormatter(QPointer<QmlJSEditorDocument> document)
|
||||
if (document->isSemanticInfoOutdated()) {
|
||||
QmlJS::Document::MutablePtr latestDocument;
|
||||
|
||||
const Utils::FilePath fileName = document->filePath();
|
||||
const FilePath fileName = document->filePath();
|
||||
latestDocument = snapshot.documentFromSource(
|
||||
QString::fromUtf8(document->contents()),
|
||||
fileName,
|
||||
@@ -235,14 +268,16 @@ static void reformatByBuiltInFormatter(QPointer<QmlJSEditorDocument> document)
|
||||
}
|
||||
|
||||
if (!documentPtr->isParsedCorrectly())
|
||||
return;
|
||||
return FormatResult::Failed;
|
||||
|
||||
TextEditor::TabSettings tabSettings = document->tabSettings();
|
||||
QmlJSTools::QmlJSCodeStylePreferences *codeStyle
|
||||
= QmlJSTools::QmlJSToolsSettings::globalCodeStyle();
|
||||
TextEditor::TabSettings tabSettings = codeStyle->currentTabSettings();
|
||||
const QString newText = QmlJS::reformat(
|
||||
documentPtr,
|
||||
tabSettings.m_indentSize,
|
||||
tabSettings.m_tabSize,
|
||||
QmlJSTools::QmlJSToolsSettings::globalCodeStyle()->currentCodeStyleSettings().lineLength);
|
||||
codeStyle->currentCodeStyleSettings().lineLength);
|
||||
auto ed = qobject_cast<TextEditor::BaseTextEditor *>(EditorManager::currentEditor());
|
||||
if (ed) {
|
||||
TextEditor::updateEditorText(ed->editorWidget(), newText);
|
||||
@@ -252,45 +287,98 @@ static void reformatByBuiltInFormatter(QPointer<QmlJSEditorDocument> document)
|
||||
tc.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
|
||||
tc.insertText(newText);
|
||||
}
|
||||
return FormatResult::Success;
|
||||
}
|
||||
|
||||
static bool reformatUsingLanguageServer(QPointer<QmlJSEditorDocument> document)
|
||||
static FormatResult reformatUsingLanguageServer(QPointer<QmlJSEditorDocument> document)
|
||||
{
|
||||
if (!document)
|
||||
return false;
|
||||
return FormatResult::Failed;
|
||||
|
||||
if (!document->formatter())
|
||||
return false;
|
||||
return FormatResult::Failed;
|
||||
|
||||
TextEditor::BaseTextEditor *editor = qobject_cast<TextEditor::BaseTextEditor *>(
|
||||
EditorManager::currentEditor());
|
||||
if (!editor)
|
||||
return false;
|
||||
return FormatResult::Failed;
|
||||
|
||||
TextEditor::TextEditorWidget *editorWidget = editor->editorWidget();
|
||||
if (!editorWidget)
|
||||
return false;
|
||||
return FormatResult::Failed;
|
||||
|
||||
overrideTabSettings(document);
|
||||
document->setFormatterMode(TextEditor::Formatter::FormatMode::FullDocument);
|
||||
editorWidget->autoFormat();
|
||||
|
||||
return true;
|
||||
return FormatResult::Success;
|
||||
}
|
||||
|
||||
void QmlJSEditorPluginPrivate::reformatFile()
|
||||
static FormatResult reformatByCustomFormatter(
|
||||
QPointer<QmlJSEditorDocument> document, const QmlJSTools::QmlJSCodeStyleSettings &settings)
|
||||
{
|
||||
if (!m_currentDocument)
|
||||
return;
|
||||
|
||||
if (reformatUsingLanguageServer(m_currentDocument))
|
||||
return;
|
||||
|
||||
if (settings().useCustomFormatCommand()) {
|
||||
reformatByQmlFormat(m_currentDocument);
|
||||
return;
|
||||
const FilePath &formatter = settings.customFormatterPath;
|
||||
const QStringList &args = settings.customFormatterArguments.split(" ", Qt::SkipEmptyParts);
|
||||
if (!formatter.isExecutableFile()) {
|
||||
MessageManager::writeSilently(
|
||||
Tr::tr("Custom Formatter path not found."));
|
||||
return FormatResult::Failed;
|
||||
}
|
||||
const CommandLine commandLine(formatter, args);
|
||||
TextEditor::Command command;
|
||||
command.setExecutable(commandLine.executable());
|
||||
command.setProcessing(TextEditor::Command::FileProcessing);
|
||||
command.addOptions(commandLine.splitArguments());
|
||||
command.addOption("--inplace");
|
||||
command.addOption("%file");
|
||||
if (!command.isValid())
|
||||
return FormatResult::Failed;
|
||||
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForDocument(document);
|
||||
if (editors.isEmpty())
|
||||
return FormatResult::Failed;
|
||||
IEditor *currentEditor = EditorManager::currentEditor();
|
||||
IEditor *editor = editors.contains(currentEditor) ? currentEditor : editors.first();
|
||||
if (auto widget = TextEditor::TextEditorWidget::fromEditor(editor)) {
|
||||
TextEditor::formatEditor(widget, command);
|
||||
return FormatResult::Success;
|
||||
}
|
||||
return FormatResult::Failed;
|
||||
}
|
||||
|
||||
reformatByBuiltInFormatter(m_currentDocument);
|
||||
FormatResult QmlJSEditorPluginPrivate::reformatFile()
|
||||
{
|
||||
if (!m_currentDocument) {
|
||||
MessageManager::writeSilently(Tr::tr("Error: No current document to format."));
|
||||
return FormatResult::Failed;
|
||||
}
|
||||
|
||||
const QmlJSCodeStyleSettings settings
|
||||
= QmlJSToolsSettings::globalCodeStyle()->currentCodeStyleSettings();
|
||||
|
||||
const auto tryReformat = [this](auto formatterFunction) {
|
||||
const FormatResult result = formatterFunction(m_currentDocument);
|
||||
if (result != FormatResult::Success) {
|
||||
MessageManager::writeSilently(
|
||||
Tr::tr("Error: Formatting failed with the selected formatter."));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
switch (settings.formatter) {
|
||||
case QmlJSCodeStyleSettings::Formatter::QmlFormat:
|
||||
return tryReformat([](auto doc) {
|
||||
return reformatUsingLanguageServer(doc) == FormatResult::Success
|
||||
? FormatResult::Success
|
||||
: reformatByQmlFormat(doc);
|
||||
});
|
||||
|
||||
case QmlJSCodeStyleSettings::Formatter::Custom:
|
||||
return tryReformat(
|
||||
[&settings](auto doc) { return reformatByCustomFormatter(doc, settings); });
|
||||
|
||||
case QmlJSCodeStyleSettings::Formatter::Builtin:
|
||||
default:
|
||||
return tryReformat([](auto doc) { return reformatByBuiltInFormatter(doc); });
|
||||
}
|
||||
}
|
||||
|
||||
Command *QmlJSEditorPluginPrivate::addToolAction(QAction *a,
|
||||
|
@@ -16,4 +16,9 @@ void setupQmlJSEditor();
|
||||
void inspectElement();
|
||||
void showContextPane();
|
||||
|
||||
enum class FormatResult {
|
||||
Success,
|
||||
Failed
|
||||
};
|
||||
|
||||
} // QmlJSEditor::Internal
|
||||
|
@@ -63,15 +63,10 @@ const char QML_CONTEXTPANE_KEY[] = "QmlJSEditor.ContextPaneEnabled";
|
||||
const char QML_CONTEXTPANEPIN_KEY[] = "QmlJSEditor.ContextPanePinned";
|
||||
const char FOLD_AUX_DATA[] = "QmlJSEditor.FoldAuxData";
|
||||
const char UIQML_OPEN_MODE[] = "QmlJSEditor.openUiQmlMode";
|
||||
const char FORMAT_COMMAND[] = "QmlJSEditor.formatCommand";
|
||||
const char FORMAT_COMMAND_OPTIONS[] = "QmlJSEditor.formatCommandOptions";
|
||||
const char CUSTOM_COMMAND[] = "QmlJSEditor.useCustomFormatCommand";
|
||||
const char CUSTOM_ANALYZER[] = "QmlJSEditor.useCustomAnalyzer";
|
||||
const char DISABLED_MESSAGES[] = "QmlJSEditor.disabledMessages";
|
||||
const char DISABLED_MESSAGES_NONQUICKUI[] = "QmlJSEditor.disabledMessagesNonQuickUI";
|
||||
const char QDS_COMMAND[] = "QmlJSEditor.qdsCommand";
|
||||
const char DEFAULT_CUSTOM_FORMAT_COMMAND[]
|
||||
= "%{CurrentDocument:Project:QT_HOST_BINS}/qmlformat%{HostOs:ExecutableSuffix}";
|
||||
const char SETTINGS_PAGE[] = "C.QmlJsEditing";
|
||||
|
||||
QmlJsEditingSettings &settings()
|
||||
@@ -142,19 +137,6 @@ QmlJsEditingSettings::QmlJsEditingSettings()
|
||||
uiQmlOpenMode.addOption({Tr::tr("Qt Design Studio"), {}, Core::Constants::MODE_DESIGN});
|
||||
uiQmlOpenMode.addOption({Tr::tr("Qt Creator"), {}, Core::Constants::MODE_EDIT});
|
||||
|
||||
useCustomFormatCommand.setSettingsKey(group, CUSTOM_COMMAND);
|
||||
useCustomFormatCommand.setLabelText(
|
||||
Tr::tr("Use custom command instead of built-in formatter"));
|
||||
|
||||
formatCommand.setSettingsKey(group, FORMAT_COMMAND);
|
||||
formatCommand.setDisplayStyle(StringAspect::LineEditDisplay);
|
||||
formatCommand.setPlaceHolderText(defaultFormatCommand());
|
||||
formatCommand.setLabelText(Tr::tr("Command:"));
|
||||
|
||||
formatCommandOptions.setSettingsKey(group, FORMAT_COMMAND_OPTIONS);
|
||||
formatCommandOptions.setDisplayStyle(StringAspect::LineEditDisplay);
|
||||
formatCommandOptions.setLabelText(Tr::tr("Arguments:"));
|
||||
|
||||
useCustomAnalyzer.setSettingsKey(group, CUSTOM_ANALYZER);
|
||||
useCustomAnalyzer.setLabelText(Tr::tr("Use customized static analyzer"));
|
||||
|
||||
@@ -174,15 +156,6 @@ QmlJsEditingSettings::QmlJsEditingSettings()
|
||||
qdsCommand.setVisible(false);
|
||||
|
||||
readSettings();
|
||||
|
||||
autoFormatOnlyCurrentProject.setEnabler(&autoFormatOnSave);
|
||||
formatCommand.setEnabler(&useCustomFormatCommand);
|
||||
formatCommandOptions.setEnabler(&useCustomFormatCommand);
|
||||
}
|
||||
|
||||
QString QmlJsEditingSettings::defaultFormatCommand() const
|
||||
{
|
||||
return DEFAULT_CUSTOM_FORMAT_COMMAND;
|
||||
}
|
||||
|
||||
FilePath QmlJsEditingSettings::defaultQdsCommand() const
|
||||
@@ -285,15 +258,10 @@ public:
|
||||
Column {
|
||||
Group {
|
||||
bindTo(&formattingGroup),
|
||||
title(Tr::tr("Automatic Formatting on File Save")),
|
||||
title(Tr::tr("Formatting")),
|
||||
Column {
|
||||
s.autoFormatOnSave,
|
||||
s.autoFormatOnlyCurrentProject,
|
||||
s.useCustomFormatCommand,
|
||||
Form {
|
||||
s.formatCommand, br,
|
||||
s.formatCommandOptions
|
||||
}
|
||||
},
|
||||
},
|
||||
Group {
|
||||
|
@@ -20,7 +20,6 @@ class QmlJsEditingSettings final : public Utils::AspectContainer
|
||||
public:
|
||||
QmlJsEditingSettings();
|
||||
|
||||
QString defaultFormatCommand() const;
|
||||
Utils::FilePath defaultQdsCommand() const;
|
||||
|
||||
Utils::BoolAspect enableContextPane{this};
|
||||
@@ -28,11 +27,8 @@ public:
|
||||
Utils::BoolAspect autoFormatOnSave{this};
|
||||
Utils::BoolAspect autoFormatOnlyCurrentProject{this};
|
||||
Utils::BoolAspect foldAuxData{this};
|
||||
Utils::BoolAspect useCustomFormatCommand{this};
|
||||
Utils::BoolAspect useCustomAnalyzer{this};
|
||||
Utils::SelectionAspect uiQmlOpenMode{this};
|
||||
Utils::StringAspect formatCommand{this};
|
||||
Utils::StringAspect formatCommandOptions{this};
|
||||
Utils::IntegersAspect disabledMessages{this};
|
||||
Utils::IntegersAspect disabledMessagesForNonQuickUi{this};
|
||||
Utils::FilePathAspect qdsCommand{this};
|
||||
|
@@ -7,8 +7,10 @@ add_qtc_plugin(QmlJSTools
|
||||
qmljsbundleprovider.cpp qmljsbundleprovider.h
|
||||
qmljscodestylepreferenceswidget.cpp qmljscodestylepreferenceswidget.h
|
||||
qmljscodestylesettings.cpp qmljscodestylesettings.h
|
||||
qmljscodestylesettingswidget.cpp qmljscodestylesettingswidget.h
|
||||
qmljscodestylesettingspage.cpp qmljscodestylesettingspage.h
|
||||
qmljscustomformatterwidget.cpp qmljscustomformatterwidget.h
|
||||
qmlformatsettingswidget.cpp qmlformatsettingswidget.h
|
||||
qmljsformatterselectionwidget.cpp qmljsformatterselectionwidget.h
|
||||
qmljsfunctionfilter.cpp qmljsfunctionfilter.h
|
||||
qmljsindenter.cpp qmljsindenter.h
|
||||
qmljsmodelmanager.cpp qmljsmodelmanager.h
|
||||
|
98
src/plugins/qmljstools/qmlformatsettingswidget.cpp
Normal file
98
src/plugins/qmljstools/qmlformatsettingswidget.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
// 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 "qmlformatsettingswidget.h"
|
||||
#include "qmljsformatterselectionwidget.h"
|
||||
#include "qmlformatsettings.h"
|
||||
#include "qmljstoolstr.h"
|
||||
|
||||
#include <texteditor/snippets/snippeteditor.h>
|
||||
#include <utils/layoutbuilder.h>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace QmlJSTools {
|
||||
|
||||
QmlFormatSettingsWidget::QmlFormatSettingsWidget(
|
||||
QWidget *parent, FormatterSelectionWidget *selection)
|
||||
: QmlCodeStyleWidgetBase(parent)
|
||||
, m_qmlformatConfigTextEdit(std::make_unique<TextEditor::SnippetEditorWidget>())
|
||||
, m_formatterSelectionWidget(selection)
|
||||
{
|
||||
QSizePolicy sp(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
sp.setHorizontalStretch(1);
|
||||
m_qmlformatConfigTextEdit->setSizePolicy(sp);
|
||||
|
||||
using namespace Layouting;
|
||||
// clang-format off
|
||||
Column {
|
||||
Group {
|
||||
title(Tr::tr("Global qmlformat Configuration")),
|
||||
Column {
|
||||
m_qmlformatConfigTextEdit.get(),
|
||||
},
|
||||
},
|
||||
noMargin
|
||||
}.attachTo(this);
|
||||
// clang-format on
|
||||
|
||||
connect(
|
||||
m_qmlformatConfigTextEdit.get(),
|
||||
&TextEditor::SnippetEditorWidget::textChanged,
|
||||
this,
|
||||
&QmlFormatSettingsWidget::slotSettingsChanged);
|
||||
}
|
||||
|
||||
void QmlFormatSettingsWidget::setCodeStyleSettings(const QmlJSCodeStyleSettings &s)
|
||||
{
|
||||
QSignalBlocker blocker(this);
|
||||
if (s.qmlformatIniContent != m_qmlformatConfigTextEdit->toPlainText())
|
||||
m_qmlformatConfigTextEdit->setPlainText(s.qmlformatIniContent);
|
||||
}
|
||||
|
||||
void QmlFormatSettingsWidget::setPreferences(QmlJSCodeStylePreferences *preferences)
|
||||
{
|
||||
if (m_preferences == preferences)
|
||||
return; // nothing changes
|
||||
|
||||
slotCurrentPreferencesChanged(preferences);
|
||||
|
||||
// cleanup old
|
||||
if (m_preferences) {
|
||||
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, nullptr);
|
||||
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
|
||||
this, &QmlFormatSettingsWidget::slotCurrentPreferencesChanged);
|
||||
}
|
||||
m_preferences = preferences;
|
||||
// fillup new
|
||||
if (m_preferences) {
|
||||
setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
|
||||
connect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, [this] {
|
||||
this->setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
|
||||
});
|
||||
connect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
|
||||
this, &QmlFormatSettingsWidget::slotCurrentPreferencesChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void QmlFormatSettingsWidget::slotCurrentPreferencesChanged(
|
||||
TextEditor::ICodeStylePreferences *preferences)
|
||||
{
|
||||
auto *current = dynamic_cast<QmlJSCodeStylePreferences *>(
|
||||
preferences ? preferences->currentPreferences() : nullptr);
|
||||
const bool enableWidgets = current && !current->isReadOnly() && m_formatterSelectionWidget
|
||||
&& m_formatterSelectionWidget->selection().value()
|
||||
== QmlCodeStyleWidgetBase::QmlFormat;
|
||||
setEnabled(enableWidgets);
|
||||
}
|
||||
|
||||
void QmlFormatSettingsWidget::slotSettingsChanged()
|
||||
{
|
||||
QmlJSCodeStyleSettings settings = m_preferences ? m_preferences->currentCodeStyleSettings()
|
||||
: QmlJSCodeStyleSettings::currentGlobalCodeStyle();
|
||||
settings.qmlformatIniContent = m_qmlformatConfigTextEdit->toPlainText();
|
||||
QmlFormatSettings::instance().globalQmlFormatIniFile().writeFileContents(settings.qmlformatIniContent.toUtf8());
|
||||
emit settingsChanged(settings);
|
||||
}
|
||||
|
||||
} // namespace QmlJSTools
|
34
src/plugins/qmljstools/qmlformatsettingswidget.h
Normal file
34
src/plugins/qmljstools/qmlformatsettingswidget.h
Normal file
@@ -0,0 +1,34 @@
|
||||
// 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 "qmljsformatterselectionwidget.h"
|
||||
#include "qmljscodestylesettings.h"
|
||||
|
||||
#include <texteditor/snippets/snippeteditor.h>
|
||||
|
||||
#include <memory>
|
||||
#include <QWidget>
|
||||
|
||||
namespace QmlJSTools {
|
||||
class FormatterSelectionWidget;
|
||||
|
||||
class QmlFormatSettingsWidget : public QmlCodeStyleWidgetBase
|
||||
{
|
||||
public:
|
||||
explicit QmlFormatSettingsWidget(
|
||||
QWidget *parent = nullptr,
|
||||
FormatterSelectionWidget *selection = nullptr);
|
||||
void setCodeStyleSettings(const QmlJSCodeStyleSettings &s) override;
|
||||
void setPreferences(QmlJSCodeStylePreferences *preferences) override;
|
||||
void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences* preferences) override;
|
||||
|
||||
private:
|
||||
void slotSettingsChanged();
|
||||
std::unique_ptr<TextEditor::SnippetEditorWidget> m_qmlformatConfigTextEdit;
|
||||
FormatterSelectionWidget *m_formatterSelectionWidget = nullptr;
|
||||
QmlJSCodeStylePreferences *m_preferences = nullptr;
|
||||
};
|
||||
|
||||
} // namespace QmlJSTools
|
@@ -4,23 +4,58 @@
|
||||
#include "qmljscodestylepreferenceswidget.h"
|
||||
|
||||
#include "qmljscodestylesettings.h"
|
||||
#include "qmljscodestylesettingswidget.h"
|
||||
#include "qmljsformatterselectionwidget.h"
|
||||
#include "qmljstoolstr.h"
|
||||
|
||||
#include <texteditor/simplecodestylepreferenceswidget.h>
|
||||
#include <texteditor/texteditor.h>
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <utils/aspects.h>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
using namespace TextEditor;
|
||||
namespace QmlJSTools {
|
||||
|
||||
QmlJSCodeStylePreferencesWidget::QmlJSCodeStylePreferencesWidget(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
BuiltinFormatterSettingsWidget::BuiltinFormatterSettingsWidget(QWidget *parent, FormatterSelectionWidget *selection)
|
||||
: QmlCodeStyleWidgetBase(parent)
|
||||
, m_tabSettingsWidget(new TextEditor::TabSettingsWidget)
|
||||
, m_formatterSelectionWidget(selection)
|
||||
{
|
||||
m_codeStyleSettingsWidget = new QmlJSCodeStyleSettingsWidget(this);
|
||||
auto layout = new QVBoxLayout(this);
|
||||
layout->addWidget(m_codeStyleSettingsWidget);
|
||||
layout->setContentsMargins(QMargins());
|
||||
m_lineLength.setRange(0, 999);
|
||||
m_tabSettingsWidget->setParent(this);
|
||||
|
||||
using namespace Layouting;
|
||||
Column {
|
||||
Group {
|
||||
title(Tr::tr("Builtin Formatter Settings")),
|
||||
Column {
|
||||
m_tabSettingsWidget,
|
||||
Group {
|
||||
title(Tr::tr("Other Settings")),
|
||||
Form {
|
||||
Tr::tr("Line Length:"), m_lineLength, br
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.attachTo(this);
|
||||
|
||||
connect(
|
||||
&m_lineLength,
|
||||
&Utils::IntegerAspect::changed,
|
||||
this,
|
||||
&BuiltinFormatterSettingsWidget::slotSettingsChanged);
|
||||
}
|
||||
|
||||
void QmlJSCodeStylePreferencesWidget::setPreferences(QmlJSCodeStylePreferences *preferences)
|
||||
void BuiltinFormatterSettingsWidget::setCodeStyleSettings(const QmlJSCodeStyleSettings &settings)
|
||||
{
|
||||
QSignalBlocker blocker(this);
|
||||
m_lineLength.setValue(settings.lineLength);
|
||||
}
|
||||
|
||||
void BuiltinFormatterSettingsWidget::setPreferences(QmlJSCodeStylePreferences *preferences)
|
||||
{
|
||||
if (m_preferences == preferences)
|
||||
return; // nothing changes
|
||||
@@ -31,41 +66,58 @@ void QmlJSCodeStylePreferencesWidget::setPreferences(QmlJSCodeStylePreferences *
|
||||
if (m_preferences) {
|
||||
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, nullptr);
|
||||
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
|
||||
this, &QmlJSCodeStylePreferencesWidget::slotCurrentPreferencesChanged);
|
||||
disconnect(m_codeStyleSettingsWidget, &QmlJSCodeStyleSettingsWidget::settingsChanged,
|
||||
this, &QmlJSCodeStylePreferencesWidget::slotSettingsChanged);
|
||||
this, &BuiltinFormatterSettingsWidget::slotCurrentPreferencesChanged);
|
||||
disconnect(m_preferences, &ICodeStylePreferences::currentTabSettingsChanged,
|
||||
m_tabSettingsWidget, &TabSettingsWidget::setTabSettings);
|
||||
disconnect(m_tabSettingsWidget, &TabSettingsWidget::settingsChanged,
|
||||
this, &BuiltinFormatterSettingsWidget::slotTabSettingsChanged);
|
||||
}
|
||||
m_preferences = preferences;
|
||||
// fillup new
|
||||
if (m_preferences) {
|
||||
m_codeStyleSettingsWidget->setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
|
||||
|
||||
setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
|
||||
connect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, [this] {
|
||||
m_codeStyleSettingsWidget->setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
|
||||
setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
|
||||
});
|
||||
connect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
|
||||
this, &QmlJSCodeStylePreferencesWidget::slotCurrentPreferencesChanged);
|
||||
connect(m_codeStyleSettingsWidget, &QmlJSCodeStyleSettingsWidget::settingsChanged,
|
||||
this, &QmlJSCodeStylePreferencesWidget::slotSettingsChanged);
|
||||
this, &BuiltinFormatterSettingsWidget::slotCurrentPreferencesChanged);
|
||||
m_tabSettingsWidget->setTabSettings(m_preferences->currentTabSettings());
|
||||
connect(m_preferences, &ICodeStylePreferences::currentTabSettingsChanged,
|
||||
m_tabSettingsWidget, &TabSettingsWidget::setTabSettings);
|
||||
connect(m_tabSettingsWidget, &TabSettingsWidget::settingsChanged,
|
||||
this, &BuiltinFormatterSettingsWidget::slotTabSettingsChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void QmlJSCodeStylePreferencesWidget::slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences *preferences)
|
||||
void BuiltinFormatterSettingsWidget::slotCurrentPreferencesChanged(
|
||||
TextEditor::ICodeStylePreferences *preferences)
|
||||
{
|
||||
m_codeStyleSettingsWidget->setEnabled(preferences && preferences->currentPreferences() &&
|
||||
!preferences->currentPreferences()->isReadOnly());
|
||||
QmlJSCodeStylePreferences *current = dynamic_cast<QmlJSCodeStylePreferences *>(
|
||||
preferences ? preferences->currentPreferences() : nullptr);
|
||||
const bool enableWidgets = current && !current->isReadOnly() && m_formatterSelectionWidget
|
||||
&& m_formatterSelectionWidget->selection().value()
|
||||
== QmlCodeStyleWidgetBase::Builtin;
|
||||
setEnabled(enableWidgets);
|
||||
}
|
||||
|
||||
void QmlJSCodeStylePreferencesWidget::slotSettingsChanged(const QmlJSCodeStyleSettings &settings)
|
||||
void BuiltinFormatterSettingsWidget::slotSettingsChanged()
|
||||
{
|
||||
QmlJSCodeStyleSettings settings = m_preferences ? m_preferences->currentCodeStyleSettings()
|
||||
: QmlJSCodeStyleSettings::currentGlobalCodeStyle();
|
||||
settings.lineLength = m_lineLength.value();
|
||||
emit settingsChanged(settings);
|
||||
}
|
||||
|
||||
void BuiltinFormatterSettingsWidget::slotTabSettingsChanged(const TextEditor::TabSettings &settings)
|
||||
{
|
||||
if (!m_preferences)
|
||||
return;
|
||||
|
||||
QmlJSCodeStylePreferences *current = dynamic_cast<QmlJSCodeStylePreferences*>(m_preferences->currentPreferences());
|
||||
ICodeStylePreferences *current = m_preferences->currentPreferences();
|
||||
if (!current)
|
||||
return;
|
||||
|
||||
current->setCodeStyleSettings(settings);
|
||||
current->setTabSettings(settings);
|
||||
}
|
||||
|
||||
} // namespace QmlJSTools
|
||||
|
@@ -3,30 +3,35 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "qmljstools_global.h"
|
||||
|
||||
#include "qmljscodestylesettings.h"
|
||||
#include "qmljsformatterselectionwidget.h"
|
||||
|
||||
#include <texteditor/tabsettingswidget.h>
|
||||
#include <utils/aspects.h>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSpinBox;
|
||||
QT_END_NAMESPACE
|
||||
namespace QmlJSTools {
|
||||
class QmlJSCodeStyleSettingsWidget;
|
||||
|
||||
class QMLJSTOOLS_EXPORT QmlJSCodeStylePreferencesWidget : public QWidget
|
||||
class BuiltinFormatterSettingsWidget : public QmlCodeStyleWidgetBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QmlJSCodeStylePreferencesWidget(QWidget *parent = nullptr);
|
||||
|
||||
void setPreferences(QmlJSCodeStylePreferences *tabPreferences);
|
||||
explicit BuiltinFormatterSettingsWidget(QWidget *parent, FormatterSelectionWidget *selection);
|
||||
void setCodeStyleSettings(const QmlJSCodeStyleSettings &settings) override;
|
||||
void setPreferences(QmlJSCodeStylePreferences *tabPreferences) override;
|
||||
void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences* preferences) override;
|
||||
|
||||
private:
|
||||
void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences* preferences);
|
||||
void slotSettingsChanged(const QmlJSCodeStyleSettings &settings);
|
||||
void slotSettingsChanged();
|
||||
void slotTabSettingsChanged(const TextEditor::TabSettings &settings);
|
||||
|
||||
QmlJSCodeStyleSettingsWidget *m_codeStyleSettingsWidget;
|
||||
Utils::IntegerAspect m_lineLength;
|
||||
TextEditor::TabSettingsWidget *m_tabSettingsWidget;
|
||||
QmlJSCodeStylePreferences *m_preferences = nullptr;
|
||||
FormatterSelectionWidget *m_formatterSelectionWidget;
|
||||
};
|
||||
|
||||
} // namespace QmlJSTools
|
||||
|
@@ -18,9 +18,12 @@
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
static const char lineLengthKey[] = "LineLength";
|
||||
static const char qmlformatIniContentKey[] = "QmlFormatIniContent";
|
||||
static const char formatterKey[] = "Formatter";
|
||||
static const char customFormatterPathKey[] = "CustomFormatterPath";
|
||||
static const char customFormatterArgumentsKey[] = "CustomFormatterArguments";
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
namespace QmlJSTools {
|
||||
|
||||
// QmlJSCodeStyleSettings
|
||||
@@ -30,18 +33,28 @@ QmlJSCodeStyleSettings::QmlJSCodeStyleSettings() = default;
|
||||
Store QmlJSCodeStyleSettings::toMap() const
|
||||
{
|
||||
return {
|
||||
{lineLengthKey, lineLength}
|
||||
{formatterKey, formatter},
|
||||
{lineLengthKey, lineLength},
|
||||
{qmlformatIniContentKey, qmlformatIniContent},
|
||||
{customFormatterPathKey, customFormatterPath.toUrlishString()},
|
||||
{customFormatterArgumentsKey, customFormatterArguments}
|
||||
};
|
||||
}
|
||||
|
||||
void QmlJSCodeStyleSettings::fromMap(const Store &map)
|
||||
{
|
||||
lineLength = map.value(lineLengthKey, lineLength).toInt();
|
||||
qmlformatIniContent = map.value(qmlformatIniContentKey, qmlformatIniContent).toString();
|
||||
formatter = static_cast<Formatter>(map.value(formatterKey, formatter).toInt());
|
||||
customFormatterPath = Utils::FilePath::fromString(map.value(customFormatterPathKey).toString());
|
||||
customFormatterArguments = map.value(customFormatterArgumentsKey).toString();
|
||||
}
|
||||
|
||||
bool QmlJSCodeStyleSettings::equals(const QmlJSCodeStyleSettings &rhs) const
|
||||
{
|
||||
return lineLength == rhs.lineLength;
|
||||
return lineLength == rhs.lineLength && qmlformatIniContent == rhs.qmlformatIniContent
|
||||
&& formatter == rhs.formatter && customFormatterPath == rhs.customFormatterPath
|
||||
&& customFormatterArguments == rhs.customFormatterArguments;
|
||||
}
|
||||
|
||||
QmlJSCodeStyleSettings QmlJSCodeStyleSettings::currentGlobalCodeStyle()
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <texteditor/icodestylepreferences.h>
|
||||
|
||||
#include <utils/filepath.h>
|
||||
#include <utils/store.h>
|
||||
|
||||
namespace TextEditor { class TabSettings; }
|
||||
@@ -19,7 +20,17 @@ class QMLJSTOOLS_EXPORT QmlJSCodeStyleSettings
|
||||
public:
|
||||
QmlJSCodeStyleSettings();
|
||||
|
||||
enum Formatter {
|
||||
Builtin,
|
||||
QmlFormat,
|
||||
Custom
|
||||
};
|
||||
|
||||
int lineLength = 80;
|
||||
QString qmlformatIniContent;
|
||||
Formatter formatter = Builtin;
|
||||
Utils::FilePath customFormatterPath;
|
||||
QString customFormatterArguments;
|
||||
|
||||
Utils::Store toMap() const;
|
||||
void fromMap(const Utils::Store &map);
|
||||
|
@@ -3,64 +3,112 @@
|
||||
|
||||
#include "qmljscodestylesettingspage.h"
|
||||
|
||||
#include "qmlformatsettings.h"
|
||||
#include "qmlformatsettingswidget.h"
|
||||
#include "qmljscodestylepreferenceswidget.h"
|
||||
#include "qmljscodestylesettings.h"
|
||||
#include "qmljscustomformatterwidget.h"
|
||||
#include "qmljsformatterselectionwidget.h"
|
||||
#include "qmljsqtstylecodeformatter.h"
|
||||
#include "qmljstoolsconstants.h"
|
||||
#include "qmljstoolssettings.h"
|
||||
#include "qmljstoolstr.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/messagemanager.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <qmljseditor/qmljseditorconstants.h>
|
||||
#include <texteditor/codestyleeditor.h>
|
||||
#include <texteditor/command.h>
|
||||
#include <texteditor/displaysettings.h>
|
||||
#include <texteditor/fontsettings.h>
|
||||
#include <texteditor/formattexteditor.h>
|
||||
#include <texteditor/icodestylepreferencesfactory.h>
|
||||
#include <texteditor/simplecodestylepreferenceswidget.h>
|
||||
#include <texteditor/snippets/snippeteditor.h>
|
||||
#include <texteditor/snippets/snippetprovider.h>
|
||||
#include <texteditor/tabsettings.h>
|
||||
#include <texteditor/texteditorsettings.h>
|
||||
#include <utils/commandline.h>
|
||||
#include <utils/filepath.h>
|
||||
#include <utils/layoutbuilder.h>
|
||||
#include <qmljseditor/qmljseditorconstants.h>
|
||||
|
||||
#include <QTextStream>
|
||||
#include <QVBoxLayout>
|
||||
#include <QStandardPaths>
|
||||
|
||||
using namespace TextEditor;
|
||||
|
||||
using namespace QmlJSTools;
|
||||
namespace QmlJSTools::Internal {
|
||||
|
||||
constexpr int BuiltinFormatterIndex = QmlCodeStyleWidgetBase::Builtin;
|
||||
constexpr int QmlFormatIndex = QmlCodeStyleWidgetBase::QmlFormat;
|
||||
constexpr int CustomFormatterIndex = QmlCodeStyleWidgetBase::Custom;
|
||||
|
||||
// QmlJSCodeStylePreferencesWidget
|
||||
|
||||
QmlJSCodeStylePreferencesWidget::QmlJSCodeStylePreferencesWidget(
|
||||
const QString &previewText, QWidget *parent)
|
||||
: TextEditor::CodeStyleEditorWidget(parent)
|
||||
, m_formatterSelectionWidget(new FormatterSelectionWidget(this))
|
||||
, m_formatterSettingsStack(new QStackedWidget(this))
|
||||
{
|
||||
m_tabPreferencesWidget = new SimpleCodeStylePreferencesWidget;
|
||||
m_codeStylePreferencesWidget = new QmlJSTools::QmlJSCodeStylePreferencesWidget;
|
||||
m_previewTextEdit = new SnippetEditorWidget;
|
||||
m_formatterSettingsStack->insertWidget(BuiltinFormatterIndex, new BuiltinFormatterSettingsWidget(this, m_formatterSelectionWidget));
|
||||
m_formatterSettingsStack->insertWidget(QmlFormatIndex, new QmlFormatSettingsWidget(this, m_formatterSelectionWidget));
|
||||
m_formatterSettingsStack->insertWidget(CustomFormatterIndex, new CustomFormatterWidget(this, m_formatterSelectionWidget));
|
||||
|
||||
for (const auto &formatterWidget :
|
||||
m_formatterSettingsStack->findChildren<QmlCodeStyleWidgetBase *>()) {
|
||||
connect(
|
||||
formatterWidget,
|
||||
&QmlCodeStyleWidgetBase::settingsChanged,
|
||||
this,
|
||||
&QmlJSCodeStylePreferencesWidget::slotSettingsChanged);
|
||||
}
|
||||
|
||||
const int index = m_formatterSelectionWidget->selection().value();
|
||||
m_formatterSettingsStack->setCurrentIndex(index);
|
||||
|
||||
m_previewTextEdit = new SnippetEditorWidget(this);
|
||||
m_previewTextEdit->setPlainText(previewText);
|
||||
QSizePolicy sp(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
||||
sp.setHorizontalStretch(1);
|
||||
m_previewTextEdit->setSizePolicy(sp);
|
||||
|
||||
decorateEditor(TextEditorSettings::fontSettings());
|
||||
|
||||
connect(
|
||||
TextEditorSettings::instance(),
|
||||
&TextEditorSettings::fontSettingsChanged,
|
||||
this,
|
||||
&QmlJSCodeStylePreferencesWidget::decorateEditor);
|
||||
|
||||
connect(
|
||||
m_formatterSelectionWidget,
|
||||
&FormatterSelectionWidget::settingsChanged,
|
||||
[this](const QmlJSCodeStyleSettings &settings) {
|
||||
int index = m_formatterSelectionWidget->selection().volatileValue();
|
||||
if (index < 0 || index >= static_cast<int>(m_formatterSettingsStack->count()))
|
||||
return;
|
||||
|
||||
m_formatterSettingsStack->setCurrentIndex(index);
|
||||
if (auto *current = dynamic_cast<QmlCodeStyleWidgetBase *>(
|
||||
m_formatterSettingsStack->widget(index))) {
|
||||
current->slotCurrentPreferencesChanged(m_preferences);
|
||||
}
|
||||
slotSettingsChanged(settings);
|
||||
});
|
||||
|
||||
using namespace Layouting;
|
||||
Row {
|
||||
Column {
|
||||
m_tabPreferencesWidget,
|
||||
m_codeStylePreferencesWidget,
|
||||
st,
|
||||
m_formatterSelectionWidget, br,
|
||||
m_formatterSettingsStack,
|
||||
st
|
||||
},
|
||||
m_previewTextEdit,
|
||||
noMargin
|
||||
}.attachTo(this);
|
||||
|
||||
connect(TextEditorSettings::instance(), &TextEditorSettings::fontSettingsChanged,
|
||||
this, &QmlJSCodeStylePreferencesWidget::decorateEditor);
|
||||
|
||||
setVisualizeWhitespace(true);
|
||||
|
||||
updatePreview();
|
||||
@@ -69,14 +117,20 @@ QmlJSCodeStylePreferencesWidget::QmlJSCodeStylePreferencesWidget(
|
||||
void QmlJSCodeStylePreferencesWidget::setPreferences(QmlJSCodeStylePreferences *preferences)
|
||||
{
|
||||
m_preferences = preferences;
|
||||
m_tabPreferencesWidget->setPreferences(preferences);
|
||||
m_codeStylePreferencesWidget->setPreferences(preferences);
|
||||
m_formatterSelectionWidget->setPreferences(preferences);
|
||||
for (const auto &formatterWidget :
|
||||
m_formatterSettingsStack->findChildren<QmlCodeStyleWidgetBase *>()) {
|
||||
formatterWidget->setPreferences(preferences);
|
||||
}
|
||||
if (m_preferences)
|
||||
{
|
||||
connect(m_preferences, &ICodeStylePreferences::currentTabSettingsChanged,
|
||||
this, &QmlJSCodeStylePreferencesWidget::slotSettingsChanged);
|
||||
this, &QmlJSCodeStylePreferencesWidget::updatePreview);
|
||||
connect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged,
|
||||
this, &QmlJSCodeStylePreferencesWidget::slotSettingsChanged);
|
||||
[this]{
|
||||
m_formatterSettingsStack->setCurrentIndex(m_formatterSelectionWidget->selection().value());
|
||||
updatePreview();
|
||||
});
|
||||
}
|
||||
updatePreview();
|
||||
}
|
||||
@@ -95,12 +149,36 @@ void QmlJSCodeStylePreferencesWidget::setVisualizeWhitespace(bool on)
|
||||
m_previewTextEdit->setDisplaySettings(displaySettings);
|
||||
}
|
||||
|
||||
void QmlJSCodeStylePreferencesWidget::slotSettingsChanged()
|
||||
void QmlJSCodeStylePreferencesWidget::slotSettingsChanged(const QmlJSCodeStyleSettings &settings)
|
||||
{
|
||||
if (!m_preferences)
|
||||
return;
|
||||
|
||||
QmlJSCodeStylePreferences *current = dynamic_cast<QmlJSCodeStylePreferences*>(m_preferences->currentPreferences());
|
||||
if (!current)
|
||||
return;
|
||||
|
||||
current->setCodeStyleSettings(settings);
|
||||
|
||||
updatePreview();
|
||||
}
|
||||
|
||||
void QmlJSCodeStylePreferencesWidget::updatePreview()
|
||||
{
|
||||
switch (m_formatterSelectionWidget->selection().value()) {
|
||||
case QmlCodeStyleWidgetBase::Builtin:
|
||||
builtInFormatterPreview();
|
||||
break;
|
||||
case QmlCodeStyleWidgetBase::QmlFormat:
|
||||
qmlformatPreview();
|
||||
break;
|
||||
case QmlCodeStyleWidgetBase::Custom:
|
||||
customFormatterPreview();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QmlJSCodeStylePreferencesWidget::builtInFormatterPreview()
|
||||
{
|
||||
QTextDocument *doc = m_previewTextEdit->document();
|
||||
|
||||
@@ -121,6 +199,63 @@ void QmlJSCodeStylePreferencesWidget::updatePreview()
|
||||
tc.endEditBlock();
|
||||
}
|
||||
|
||||
void QmlJSCodeStylePreferencesWidget::qmlformatPreview()
|
||||
{
|
||||
using namespace Core;
|
||||
const Utils::FilePath &qmlFormatPath = QmlFormatSettings::instance().latestQmlFormatPath();
|
||||
if (qmlFormatPath.isEmpty()) {
|
||||
MessageManager::writeSilently("QmlFormat not found.");
|
||||
return;
|
||||
}
|
||||
const Utils::CommandLine commandLine(qmlFormatPath);
|
||||
TextEditor::Command command;
|
||||
command.setExecutable(commandLine.executable());
|
||||
command.setProcessing(TextEditor::Command::FileProcessing);
|
||||
command.addOptions(commandLine.splitArguments());
|
||||
command.addOption("--inplace");
|
||||
command.addOption("%file");
|
||||
if (!command.isValid())
|
||||
return;
|
||||
TextEditor::TabSettings tabSettings;
|
||||
QSettings settings(
|
||||
QmlJSTools::QmlFormatSettings::globalQmlFormatIniFile().toUrlishString(),
|
||||
QSettings::IniFormat);
|
||||
if (settings.contains("IndentWidth"))
|
||||
tabSettings.m_indentSize = settings.value("IndentWidth").toInt();
|
||||
if (settings.contains("UseTabs"))
|
||||
tabSettings.m_tabPolicy = settings.value("UseTabs").toBool()
|
||||
? TextEditor::TabSettings::TabPolicy::TabsOnlyTabPolicy
|
||||
: TextEditor::TabSettings::TabPolicy::SpacesOnlyTabPolicy;
|
||||
QString dummyFilePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/dummy.qml";
|
||||
m_previewTextEdit->textDocument()->setFilePath(Utils::FilePath::fromString(dummyFilePath));
|
||||
m_previewTextEdit->textDocument()->setTabSettings(tabSettings);
|
||||
TextEditor::formatEditor(m_previewTextEdit, command);
|
||||
}
|
||||
|
||||
void QmlJSCodeStylePreferencesWidget::customFormatterPreview()
|
||||
{
|
||||
Utils::FilePath path = m_preferences->currentCodeStyleSettings().customFormatterPath;
|
||||
QStringList args = m_preferences->currentCodeStyleSettings()
|
||||
.customFormatterArguments.split(" ", Qt::SkipEmptyParts);
|
||||
if (path.isEmpty()) {
|
||||
Core::MessageManager::writeSilently("Custom formatter not found.");
|
||||
return;
|
||||
}
|
||||
const Utils::CommandLine commandLine(path, args);
|
||||
TextEditor::Command command;
|
||||
command.setExecutable(commandLine.executable());
|
||||
command.setProcessing(TextEditor::Command::FileProcessing);
|
||||
command.addOptions(commandLine.splitArguments());
|
||||
command.addOption("--inplace");
|
||||
command.addOption("%file");
|
||||
if (!command.isValid())
|
||||
return;
|
||||
|
||||
QString dummyFilePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/dummy.qml";
|
||||
m_previewTextEdit->textDocument()->setFilePath(Utils::FilePath::fromString(dummyFilePath));
|
||||
TextEditor::formatEditor(m_previewTextEdit, command);
|
||||
}
|
||||
|
||||
// QmlJSCodeStyleSettingsPageWidget
|
||||
|
||||
class QmlJSCodeStyleSettingsPageWidget : public Core::IOptionsPageWidget
|
||||
|
@@ -4,10 +4,13 @@
|
||||
#pragma once
|
||||
|
||||
#include "qmljscodestylesettings.h"
|
||||
#include "qmljsformatterselectionwidget.h"
|
||||
|
||||
#include <coreplugin/dialogs/ioptionspage.h>
|
||||
#include <texteditor/codestyleeditor.h>
|
||||
|
||||
#include <QStackedWidget>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QString;
|
||||
class QWidget;
|
||||
@@ -15,14 +18,10 @@ QT_END_NAMESPACE
|
||||
|
||||
namespace TextEditor {
|
||||
class FontSettings;
|
||||
class SimpleCodeStylePreferencesWidget;
|
||||
class SnippetEditorWidget;
|
||||
}
|
||||
|
||||
namespace QmlJSTools {
|
||||
class QmlJSCodeStylePreferencesWidget;
|
||||
class QmlJSCodeStyleSettings;
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class QmlJSCodeStylePreferencesWidget : public TextEditor::CodeStyleEditorWidget
|
||||
@@ -37,16 +36,19 @@ public:
|
||||
private:
|
||||
void decorateEditor(const TextEditor::FontSettings &fontSettings);
|
||||
void setVisualizeWhitespace(bool on);
|
||||
void slotSettingsChanged();
|
||||
void slotSettingsChanged(const QmlJSCodeStyleSettings &);
|
||||
void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences *preferences);
|
||||
void updatePreview();
|
||||
void builtInFormatterPreview();
|
||||
void qmlformatPreview();
|
||||
void customFormatterPreview();
|
||||
|
||||
QmlJSCodeStylePreferences *m_preferences = nullptr;
|
||||
TextEditor::SimpleCodeStylePreferencesWidget *m_tabPreferencesWidget;
|
||||
QmlJSTools::QmlJSCodeStylePreferencesWidget *m_codeStylePreferencesWidget;
|
||||
FormatterSelectionWidget *m_formatterSelectionWidget;
|
||||
QStackedWidget *m_formatterSettingsStack;
|
||||
TextEditor::SnippetEditorWidget *m_previewTextEdit;
|
||||
QmlJSCodeStylePreferences *m_preferences = nullptr;
|
||||
};
|
||||
|
||||
|
||||
class QmlJSCodeStyleSettingsPage : public Core::IOptionsPage
|
||||
{
|
||||
public:
|
||||
|
@@ -1,59 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qmljscodestylesettingswidget.h"
|
||||
#include "qmljscodestylesettings.h"
|
||||
#include "qmljstoolstr.h"
|
||||
|
||||
#include <utils/layoutbuilder.h>
|
||||
|
||||
#include <QSpinBox>
|
||||
#include <QTextStream>
|
||||
|
||||
namespace QmlJSTools {
|
||||
|
||||
QmlJSCodeStyleSettingsWidget::QmlJSCodeStyleSettingsWidget(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
m_lineLengthSpinBox = new QSpinBox;
|
||||
m_lineLengthSpinBox->setMinimum(0);
|
||||
m_lineLengthSpinBox->setMaximum(999);
|
||||
|
||||
using namespace Layouting;
|
||||
// clang-format off
|
||||
Column {
|
||||
Group {
|
||||
title(Tr::tr("Other")),
|
||||
Form {
|
||||
Tr::tr("&Line length:"), m_lineLengthSpinBox, br,
|
||||
}
|
||||
},
|
||||
noMargin
|
||||
}.attachTo(this);
|
||||
// clang-format on
|
||||
|
||||
connect(m_lineLengthSpinBox, &QSpinBox::valueChanged,
|
||||
this, &QmlJSCodeStyleSettingsWidget::slotSettingsChanged);
|
||||
}
|
||||
|
||||
void QmlJSCodeStyleSettingsWidget::setCodeStyleSettings(const QmlJSCodeStyleSettings &settings)
|
||||
{
|
||||
QSignalBlocker blocker(this);
|
||||
m_lineLengthSpinBox->setValue(settings.lineLength);
|
||||
}
|
||||
|
||||
QmlJSCodeStyleSettings QmlJSCodeStyleSettingsWidget::codeStyleSettings() const
|
||||
{
|
||||
QmlJSCodeStyleSettings set;
|
||||
|
||||
set.lineLength = m_lineLengthSpinBox->value();
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
void QmlJSCodeStyleSettingsWidget::slotSettingsChanged()
|
||||
{
|
||||
emit settingsChanged(codeStyleSettings());
|
||||
}
|
||||
|
||||
} // namespace TextEditor
|
@@ -1,44 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "qmljstools_global.h"
|
||||
|
||||
#include <QGroupBox>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QSpinBox;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace QmlJSTools {
|
||||
class QmlJSCodeStyleSettings;
|
||||
|
||||
class QMLJSTOOLS_EXPORT QmlJSCodeStyleSettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum CodingStyleLink {
|
||||
CppLink,
|
||||
QtQuickLink
|
||||
};
|
||||
|
||||
explicit QmlJSCodeStyleSettingsWidget(QWidget *parent = nullptr);
|
||||
|
||||
QmlJSCodeStyleSettings codeStyleSettings() const;
|
||||
|
||||
void setCodingStyleWarningVisible(bool visible);
|
||||
void setCodeStyleSettings(const QmlJSCodeStyleSettings &settings);
|
||||
|
||||
signals:
|
||||
void settingsChanged(const QmlJSCodeStyleSettings &);
|
||||
|
||||
private:
|
||||
void slotSettingsChanged();
|
||||
void codingStyleLinkActivated(const QString &linkString);
|
||||
|
||||
QSpinBox *m_lineLengthSpinBox;
|
||||
};
|
||||
|
||||
} // namespace QmlJSTools
|
117
src/plugins/qmljstools/qmljscustomformatterwidget.cpp
Normal file
117
src/plugins/qmljstools/qmljscustomformatterwidget.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
// 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 "qmljscustomformatterwidget.h"
|
||||
#include "qmlformatsettings.h"
|
||||
#include "qmljsformatterselectionwidget.h"
|
||||
#include "qmljstoolstr.h"
|
||||
|
||||
#include <utils/layoutbuilder.h>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace QmlJSTools {
|
||||
|
||||
CustomFormatterWidget::CustomFormatterWidget(QWidget *parent, FormatterSelectionWidget *selection)
|
||||
: QmlCodeStyleWidgetBase(parent)
|
||||
, m_formatterSelectionWidget(selection)
|
||||
{
|
||||
|
||||
m_customFormatterPath.setParent(this);
|
||||
m_customFormatterArguments.setParent(this);
|
||||
|
||||
m_customFormatterPath.setPlaceHolderText(
|
||||
QmlFormatSettings::instance().latestQmlFormatPath().toUrlishString());
|
||||
m_customFormatterPath.setLabelText(Tr::tr("Command:"));
|
||||
|
||||
m_customFormatterArguments.setLabelText(Tr::tr("Arguments:"));
|
||||
m_customFormatterArguments.setDisplayStyle(Utils::StringAspect::LineEditDisplay);
|
||||
|
||||
using namespace Layouting;
|
||||
// clang-format off
|
||||
Column {
|
||||
Group {
|
||||
title(Tr::tr("Custom Formatter Configuration")),
|
||||
Column {
|
||||
m_customFormatterPath, br,
|
||||
m_customFormatterArguments, br,
|
||||
st
|
||||
},
|
||||
},
|
||||
noMargin,
|
||||
}.attachTo(this);
|
||||
|
||||
// clang-format on
|
||||
connect(
|
||||
&m_customFormatterPath,
|
||||
&Utils::BaseAspect::changed,
|
||||
this,
|
||||
&CustomFormatterWidget::slotSettingsChanged);
|
||||
connect(
|
||||
&m_customFormatterArguments,
|
||||
&Utils::BaseAspect::changed,
|
||||
this,
|
||||
&CustomFormatterWidget::slotSettingsChanged);
|
||||
}
|
||||
|
||||
void CustomFormatterWidget::setCodeStyleSettings(const QmlJSCodeStyleSettings& s)
|
||||
{
|
||||
QSignalBlocker blocker(this);
|
||||
if (s.customFormatterPath != m_customFormatterPath.expandedValue()) {
|
||||
m_customFormatterPath.setValue(s.customFormatterPath);
|
||||
}
|
||||
if (s.customFormatterArguments != m_customFormatterArguments.value()) {
|
||||
m_customFormatterArguments.setValue(s.customFormatterArguments);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomFormatterWidget::setPreferences(QmlJSCodeStylePreferences *preferences)
|
||||
{
|
||||
if (m_preferences == preferences)
|
||||
return; // nothing changes
|
||||
|
||||
slotCurrentPreferencesChanged(preferences);
|
||||
|
||||
// cleanup old
|
||||
if (m_preferences) {
|
||||
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, nullptr);
|
||||
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
|
||||
this, &CustomFormatterWidget::slotCurrentPreferencesChanged);
|
||||
}
|
||||
m_preferences = preferences;
|
||||
// fillup new
|
||||
if (m_preferences) {
|
||||
setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
|
||||
connect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, [this] {
|
||||
this->setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
|
||||
});
|
||||
connect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
|
||||
this, &CustomFormatterWidget::slotCurrentPreferencesChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomFormatterWidget::slotCurrentPreferencesChanged(
|
||||
TextEditor::ICodeStylePreferences *preferences)
|
||||
{
|
||||
QmlJSCodeStylePreferences *current = dynamic_cast<QmlJSCodeStylePreferences *>(
|
||||
preferences ? preferences->currentPreferences() : nullptr);
|
||||
const bool enableWidgets = current && !current->isReadOnly() && m_formatterSelectionWidget
|
||||
&& m_formatterSelectionWidget->selection().value()
|
||||
== QmlCodeStyleWidgetBase::Custom;
|
||||
setEnabled(enableWidgets);
|
||||
}
|
||||
|
||||
void CustomFormatterWidget::slotSettingsChanged()
|
||||
{
|
||||
QmlJSCodeStyleSettings settings = m_preferences ? m_preferences->currentCodeStyleSettings()
|
||||
: QmlJSCodeStyleSettings::currentGlobalCodeStyle();
|
||||
if (m_customFormatterPath.value().isEmpty()) {
|
||||
m_customFormatterPath.setValue(
|
||||
QmlFormatSettings::instance().latestQmlFormatPath().toUrlishString());
|
||||
}
|
||||
settings.customFormatterPath = m_customFormatterPath.expandedValue();
|
||||
settings.customFormatterArguments = m_customFormatterArguments.value();
|
||||
emit settingsChanged(settings);
|
||||
}
|
||||
|
||||
} // namespace QmlJSTools
|
27
src/plugins/qmljstools/qmljscustomformatterwidget.h
Normal file
27
src/plugins/qmljstools/qmljscustomformatterwidget.h
Normal file
@@ -0,0 +1,27 @@
|
||||
// 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 "qmljscodestylesettings.h"
|
||||
#include "qmljsformatterselectionwidget.h"
|
||||
|
||||
#include <utils/aspects.h>
|
||||
namespace QmlJSTools {
|
||||
class CustomFormatterWidget : public QmlCodeStyleWidgetBase
|
||||
{
|
||||
public:
|
||||
explicit CustomFormatterWidget(QWidget *parent, FormatterSelectionWidget *selection = nullptr);
|
||||
void setCodeStyleSettings(const QmlJSCodeStyleSettings &s) override;
|
||||
void setPreferences(QmlJSCodeStylePreferences *preferences) override;
|
||||
void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences* preferences) override;
|
||||
|
||||
private:
|
||||
void slotSettingsChanged();
|
||||
Utils::FilePathAspect m_customFormatterPath;
|
||||
Utils::StringAspect m_customFormatterArguments;
|
||||
FormatterSelectionWidget *m_formatterSelectionWidget = nullptr;
|
||||
QmlJSCodeStylePreferences *m_preferences = nullptr;
|
||||
};
|
||||
|
||||
} // namespace QmlJSTools
|
89
src/plugins/qmljstools/qmljsformatterselectionwidget.cpp
Normal file
89
src/plugins/qmljstools/qmljsformatterselectionwidget.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
// 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 "qmljsformatterselectionwidget.h"
|
||||
#include "qmljstoolstr.h"
|
||||
#include <utils/layoutbuilder.h>
|
||||
|
||||
namespace QmlJSTools {
|
||||
|
||||
QmlCodeStyleWidgetBase::QmlCodeStyleWidgetBase(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
FormatterSelectionWidget::FormatterSelectionWidget(QWidget *parent)
|
||||
: QmlCodeStyleWidgetBase(parent)
|
||||
{
|
||||
using namespace Utils;
|
||||
m_formatterSelection.setDefaultValue(Builtin);
|
||||
m_formatterSelection.setDisplayStyle(SelectionAspect::DisplayStyle::RadioButtons);
|
||||
m_formatterSelection.addOption(Tr::tr("Built-In Formatter [Deprecated]") );
|
||||
m_formatterSelection.addOption(Tr::tr("QmlFormat [LSP]"));
|
||||
m_formatterSelection.addOption(Tr::tr("Custom Formatter [Must be qmlformat compatible]"));
|
||||
m_formatterSelection.setLabelText(Tr::tr("Formatter"));
|
||||
|
||||
connect(&m_formatterSelection, &SelectionAspect::changed,
|
||||
this, &FormatterSelectionWidget::slotSettingsChanged);
|
||||
|
||||
using namespace Layouting;
|
||||
Column {
|
||||
Group {
|
||||
title(Tr::tr("Formatter Selection")),
|
||||
Column {
|
||||
m_formatterSelection, br
|
||||
}
|
||||
}
|
||||
}.attachTo(this);
|
||||
}
|
||||
|
||||
void FormatterSelectionWidget::setCodeStyleSettings(const QmlJSCodeStyleSettings &s)
|
||||
{
|
||||
if (s.formatter != m_formatterSelection.value())
|
||||
m_formatterSelection.setValue(s.formatter);
|
||||
}
|
||||
|
||||
void FormatterSelectionWidget::setPreferences(QmlJSCodeStylePreferences *preferences)
|
||||
{
|
||||
if (m_preferences == preferences)
|
||||
return; // nothing changes
|
||||
|
||||
slotCurrentPreferencesChanged(preferences);
|
||||
|
||||
// cleanup old
|
||||
if (m_preferences) {
|
||||
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, nullptr);
|
||||
disconnect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
|
||||
this, &FormatterSelectionWidget::slotCurrentPreferencesChanged);
|
||||
}
|
||||
m_preferences = preferences;
|
||||
// fillup new
|
||||
if (m_preferences) {
|
||||
setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
|
||||
connect(m_preferences, &QmlJSCodeStylePreferences::currentValueChanged, this, [this] {
|
||||
setCodeStyleSettings(m_preferences->currentCodeStyleSettings());
|
||||
});
|
||||
connect(m_preferences, &QmlJSCodeStylePreferences::currentPreferencesChanged,
|
||||
this, &FormatterSelectionWidget::slotCurrentPreferencesChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void FormatterSelectionWidget::slotCurrentPreferencesChanged(
|
||||
TextEditor::ICodeStylePreferences *preferences)
|
||||
{
|
||||
QmlJSCodeStylePreferences *current = dynamic_cast<QmlJSCodeStylePreferences *>(
|
||||
preferences ? preferences->currentPreferences() : nullptr);
|
||||
const bool enableWidgets = current && !current->isReadOnly();
|
||||
setEnabled(enableWidgets);
|
||||
}
|
||||
|
||||
void FormatterSelectionWidget::slotSettingsChanged()
|
||||
{
|
||||
QmlJSCodeStyleSettings settings = m_preferences
|
||||
? m_preferences->currentCodeStyleSettings()
|
||||
: QmlJSCodeStyleSettings::currentGlobalCodeStyle();
|
||||
settings.formatter = static_cast<QmlJSCodeStyleSettings::Formatter>(m_formatterSelection.value());
|
||||
emit settingsChanged(settings);
|
||||
}
|
||||
|
||||
} // namespace QmlJSTools
|
51
src/plugins/qmljstools/qmljsformatterselectionwidget.h
Normal file
51
src/plugins/qmljstools/qmljsformatterselectionwidget.h
Normal file
@@ -0,0 +1,51 @@
|
||||
// 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 "qmljscodestylesettings.h"
|
||||
|
||||
#include <utils/aspects.h>
|
||||
|
||||
namespace QmlJSTools {
|
||||
class QmlJSCodeStyleSettings;
|
||||
|
||||
class QmlCodeStyleWidgetBase : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QmlCodeStyleWidgetBase(QWidget *parent = nullptr);
|
||||
virtual ~QmlCodeStyleWidgetBase() = default;
|
||||
enum Formatter {
|
||||
Builtin,
|
||||
QmlFormat,
|
||||
Custom,
|
||||
Count
|
||||
};
|
||||
virtual void setCodeStyleSettings(const QmlJSCodeStyleSettings &s) = 0;
|
||||
virtual void setPreferences(QmlJSCodeStylePreferences *preferences) = 0;
|
||||
virtual void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences *preferences) = 0;
|
||||
|
||||
signals:
|
||||
void settingsChanged(const QmlJSCodeStyleSettings &);
|
||||
};
|
||||
class FormatterSelectionWidget : public QmlCodeStyleWidgetBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FormatterSelectionWidget(QWidget *parent);
|
||||
|
||||
const Utils::SelectionAspect &selection() const { return m_formatterSelection; }
|
||||
Utils::SelectionAspect &selection() { return m_formatterSelection; }
|
||||
|
||||
void setCodeStyleSettings(const QmlJSCodeStyleSettings &s) override;
|
||||
void setPreferences(QmlJSCodeStylePreferences *preferences) override;
|
||||
void slotCurrentPreferencesChanged(TextEditor::ICodeStylePreferences *preferences) override;
|
||||
|
||||
private:
|
||||
void slotSettingsChanged();
|
||||
Utils::SelectionAspect m_formatterSelection;
|
||||
QmlJSCodeStylePreferences *m_preferences = nullptr;
|
||||
};
|
||||
|
||||
} // namespace QmlJSTools
|
@@ -25,8 +25,6 @@ QtcPlugin {
|
||||
"qmljscodestylesettings.h",
|
||||
"qmljscodestylesettingspage.cpp",
|
||||
"qmljscodestylesettingspage.h",
|
||||
"qmljscodestylesettingswidget.cpp",
|
||||
"qmljscodestylesettingswidget.h",
|
||||
"qmljsfunctionfilter.cpp",
|
||||
"qmljsfunctionfilter.h",
|
||||
"qmljsindenter.cpp",
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include "qmljsindenter.h"
|
||||
#include "qmljstoolsconstants.h"
|
||||
#include "qmljstoolssettings.h"
|
||||
#include "qmlformatsettings.h"
|
||||
#include "qmljstoolstr.h"
|
||||
|
||||
#include <projectexplorer/project.h>
|
||||
@@ -20,6 +21,7 @@
|
||||
#include <texteditor/texteditorsettings.h>
|
||||
|
||||
#include <utils/id.h>
|
||||
#include <utils/filepath.h>
|
||||
#include <utils/mimeconstants.h>
|
||||
#include <utils/mimeutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -166,9 +168,22 @@ QmlJSToolsSettings::QmlJSToolsSettings()
|
||||
qtTabSettings.m_indentSize = 4;
|
||||
qtTabSettings.m_continuationAlignBehavior = TabSettings::ContinuationAlignWithIndent;
|
||||
qtCodeStyle->setTabSettings(qtTabSettings);
|
||||
QmlJSCodeStyleSettings qtQmlJSSetings;
|
||||
qtQmlJSSetings.lineLength = 80;
|
||||
qtCodeStyle->setCodeStyleSettings(qtQmlJSSetings);
|
||||
|
||||
connect(&QmlFormatSettings::instance(), &QmlFormatSettings::qmlformatIniCreated, [](Utils::FilePath qmlformatIniPath) {
|
||||
QmlJSCodeStyleSettings s;
|
||||
s.lineLength = 80;
|
||||
Utils::expected_str<QByteArray> fileContents = qmlformatIniPath.fileContents();
|
||||
if (fileContents)
|
||||
s.qmlformatIniContent = QString::fromUtf8(*qmlformatIniPath.fileContents());
|
||||
auto builtInCodeStyles = TextEditorSettings::codeStylePool(
|
||||
QmlJSTools::Constants::QML_JS_SETTINGS_ID)
|
||||
->builtInCodeStyles();
|
||||
for (auto codeStyle : builtInCodeStyles) {
|
||||
if (auto qtCodeStyle = dynamic_cast<QmlJSCodeStylePreferences *>(codeStyle))
|
||||
qtCodeStyle->setCodeStyleSettings(s);
|
||||
}
|
||||
});
|
||||
|
||||
pool->addCodeStyle(qtCodeStyle);
|
||||
|
||||
// default delegate for global preferences
|
||||
|
@@ -138,6 +138,7 @@ const char UNFOLD_RECURSIVELY[] = "TextEditor.UnfoldRecursively";
|
||||
const char UNFOLD_ALL[] = "TextEditor.UnFoldAll";
|
||||
const char AUTO_INDENT_SELECTION[] = "TextEditor.AutoIndentSelection";
|
||||
const char AUTO_FORMAT_SELECTION[] = "TextEditor.AutoFormatSelection";
|
||||
const char REFORMAT_FILE[] = "TextEditor.ReformatFile";
|
||||
const char INCREASE_FONT_SIZE[] = "TextEditor.IncreaseFontSize";
|
||||
const char DECREASE_FONT_SIZE[] = "TextEditor.DecreaseFontSize";
|
||||
const char RESET_FONT_SIZE[] = "TextEditor.ResetFontSize";
|
||||
|
Reference in New Issue
Block a user