diff options
Diffstat (limited to 'src/plugins/cmakeprojectmanager/cmakeformatter.cpp')
-rw-r--r-- | src/plugins/cmakeprojectmanager/cmakeformatter.cpp | 193 |
1 files changed, 161 insertions, 32 deletions
diff --git a/src/plugins/cmakeprojectmanager/cmakeformatter.cpp b/src/plugins/cmakeprojectmanager/cmakeformatter.cpp index d9aa8b2c84a..dca6d47e203 100644 --- a/src/plugins/cmakeprojectmanager/cmakeformatter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeformatter.cpp @@ -4,7 +4,6 @@ #include "cmakeformatter.h" -#include "cmakeformattersettings.h" #include "cmakeprojectconstants.h" #include "cmakeprojectmanagertr.h" @@ -12,6 +11,7 @@ #include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/command.h> #include <coreplugin/coreconstants.h> +#include <coreplugin/dialogs/ioptionspage.h> #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/ieditor.h> #include <coreplugin/idocument.h> @@ -20,54 +20,183 @@ #include <projectexplorer/projectnodes.h> #include <projectexplorer/projecttree.h> +#include <texteditor/command.h> #include <texteditor/formattexteditor.h> #include <texteditor/texteditor.h> -#include <QAction> -#include <QVersionNumber> +#include <utils/algorithm.h> +#include <utils/genericconstants.h> +#include <utils/layoutbuilder.h> +#include <utils/mimeutils.h> +#include <QMenu> + +using namespace Core; using namespace TextEditor; +using namespace Utils; -namespace CMakeProjectManager { -namespace Internal { +namespace CMakeProjectManager::Internal { -void CMakeFormatter::updateActions(Core::IEditor *editor) +class CMakeFormatterPrivate : public PagedSettings { - const bool enabled = editor && CMakeFormatterSettings::instance()->isApplicable(editor->document()); - m_formatFile->setEnabled(enabled); -} - -void CMakeFormatter::formatFile() +public: + CMakeFormatterPrivate() + { + setSettingsGroups(Constants::CMAKEFORMATTER_SETTINGS_GROUP, + Constants::CMAKEFORMATTER_GENERAL_GROUP); + + setId(Constants::Settings::FORMATTER_ID); + setDisplayName(Tr::tr("Formatter")); + setDisplayCategory("CMake"); + setCategory(Constants::Settings::CATEGORY); + + command.setSettingsKey("autoFormatCommand"); + command.setDefaultValue("cmake-format"); + command.setExpectedKind(PathChooser::ExistingCommand); + + autoFormatOnSave.setSettingsKey("autoFormatOnSave"); + autoFormatOnSave.setLabelText(Tr::tr("Enable auto format on file save")); + + autoFormatOnlyCurrentProject.setSettingsKey("autoFormatOnlyCurrentProject"); + autoFormatOnlyCurrentProject.setDefaultValue(true); + autoFormatOnlyCurrentProject.setLabelText(Tr::tr("Restrict to files contained in the current project")); + + autoFormatMime.setSettingsKey("autoFormatMime"); + autoFormatMime.setDefaultValue("text/x-cmake"); + autoFormatMime.setLabelText(Tr::tr("Restrict to MIME types:")); + + setLayouter([this] { + using namespace Layouting; + return Column { + Row { Tr::tr("CMakeFormat command:"), command }, + Space(10), + Group { + title(Tr::tr("Automatic Formatting on File Save")), + autoFormatOnSave.groupChecker(), + Form { + autoFormatMime, br, + Span(2, autoFormatOnlyCurrentProject) + } + }, + st + }; + }); + + ActionContainer *menu = ActionManager::createMenu(Constants::CMAKEFORMATTER_MENU_ID); + menu->menu()->setTitle(Tr::tr("CMakeFormatter")); + menu->setOnAllDisabledBehavior(ActionContainer::Show); + ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu); + + Core::Command *cmd = ActionManager::registerAction(&formatFile, Constants::CMAKEFORMATTER_ACTION_ID); + connect(&formatFile, &QAction::triggered, this, [this] { + TextEditor::formatCurrentFile(formatCommand()); + }); + + ActionManager::actionContainer(Constants::CMAKEFORMATTER_MENU_ID)->addAction(cmd); + + auto updateActions = [this] { + auto editor = EditorManager::currentEditor(); + formatFile.setEnabled(editor && isApplicable(editor->document())); + }; + + connect(&autoFormatMime, &Utils::StringAspect::changed, + this, updateActions); + connect(EditorManager::instance(), &EditorManager::currentEditorChanged, + this, updateActions); + connect(EditorManager::instance(), &EditorManager::aboutToSave, + this, &CMakeFormatterPrivate::applyIfNecessary); + + readSettings(); + } + + bool isApplicable(const IDocument *document) const; + + void applyIfNecessary(IDocument *document) const; + + TextEditor::Command formatCommand() const + { + TextEditor::Command cmd; + cmd.setExecutable(command()); + cmd.setProcessing(TextEditor::Command::FileProcessing); + cmd.addOption("--in-place"); + cmd.addOption("%file"); + return cmd; + } + + FilePathAspect command{this}; + BoolAspect autoFormatOnSave{this}; + BoolAspect autoFormatOnlyCurrentProject{this}; + StringAspect autoFormatMime{this}; + + QAction formatFile{Tr::tr("Format &Current File")}; +}; + +bool CMakeFormatterPrivate::isApplicable(const IDocument *document) const { - formatCurrentFile(command()); + if (!document) + return false; + + if (autoFormatMime.value().isEmpty()) + return true; + + const QStringList allowedMimeTypes = autoFormatMime.value().split(';'); + const MimeType documentMimeType = Utils::mimeTypeForName(document->mimeType()); + + return anyOf(allowedMimeTypes, [&documentMimeType](const QString &mime) { + return documentMimeType.inherits(mime); + }); } -Command CMakeFormatter::command() const +void CMakeFormatterPrivate::applyIfNecessary(IDocument *document) const { - Command command; - command.setExecutable(CMakeFormatterSettings::instance()->command()); - command.setProcessing(Command::FileProcessing); - command.addOption("--in-place"); - command.addOption("%file"); - return command; + if (!autoFormatOnSave.value()) + return; + + if (!document) + return; + + if (!isApplicable(document)) + return; + + // Check if file is contained in the current project (if wished) + if (autoFormatOnlyCurrentProject.value()) { + const ProjectExplorer::Project *pro = ProjectExplorer::ProjectTree::currentProject(); + if (!pro || pro->files([document](const ProjectExplorer::Node *n) { + return ProjectExplorer::Project::SourceFiles(n) + && n->filePath() == document->filePath(); + }).isEmpty()) { + return; + } + } + + TextEditor::Command command = formatCommand(); + if (!command.isValid()) + return; + + const QList<IEditor *> editors = DocumentModel::editorsForDocument(document); + if (editors.isEmpty()) + return; + + IEditor *currentEditor = EditorManager::currentEditor(); + IEditor *editor = editors.contains(currentEditor) ? currentEditor : editors.first(); + if (auto widget = TextEditorWidget::fromEditor(editor)) + TextEditor::formatEditor(widget, command); } -bool CMakeFormatter::isApplicable(const Core::IDocument *document) const +// CMakeFormatter + +CMakeFormatter::CMakeFormatter() + : d(new CMakeFormatterPrivate) +{} + +CMakeFormatter::~CMakeFormatter() { - return CMakeFormatterSettings::instance()->isApplicable(document); + delete d; } -void CMakeFormatter::initialize() +void CMakeFormatter::applyIfNecessary(IDocument *document) const { - m_formatFile = new QAction(Tr::tr("Format &Current File"), this); - Core::Command *cmd = Core::ActionManager::registerAction(m_formatFile, Constants::CMAKEFORMATTER_ACTION_ID); - connect(m_formatFile, &QAction::triggered, this, &CMakeFormatter::formatFile); - - Core::ActionManager::actionContainer(Constants::CMAKEFORMATTER_MENU_ID)->addAction(cmd); - - connect(CMakeFormatterSettings::instance(), &CMakeFormatterSettings::supportedMimeTypesChanged, - [this] { updateActions(Core::EditorManager::currentEditor()); }); + d->applyIfNecessary(document); } -} // namespace Internal -} // namespace CMakeProjectManager +} // CMakeProjectManager::Internal |