Beautifier: Add option to automatically format files on save

Change-Id: I72fb3f4b728df7ef3e449c1202df9cbb0279dde4
Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
This commit is contained in:
Lorenz Haas
2015-09-17 21:27:25 +02:00
committed by Lorenz Haas
parent 41cf9d7b33
commit e195c87299
22 changed files with 751 additions and 21 deletions

View File

@@ -129,4 +129,21 @@
file in this case when using Clang, select the file in this case when using Clang, select the
\uicontrol {Format entire file if no text was selected} check box in the \uicontrol {Format entire file if no text was selected} check box in the
\uicontrol {Clang Format} options. \uicontrol {Clang Format} options.
To automatically format files when they are saved, select \uicontrol Tools >
\uicontrol Beautifier > \uicontrol General:
\list 1
\li In the \uicontrol Tool field, select the tool for formatting.
\li In the \uicontrol {Restrict to MIME types} field, specify a
semicolon-separated list of MIME types. One of these types must
match the MIME type of the file that is auto formatted.
An empty list accepts all files.
\li Select the \uicontrol {Restrict to files contained in the current
project} check box to only auto format files in the current project.
\endlist
*/ */

View File

@@ -33,7 +33,6 @@
#include "../beautifierconstants.h" #include "../beautifierconstants.h"
#include "../beautifierplugin.h" #include "../beautifierplugin.h"
#include "../command.h"
#include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
@@ -81,6 +80,11 @@ bool ArtisticStyle::initialize()
return true; return true;
} }
QString ArtisticStyle::id() const
{
return QLatin1String(Constants::ArtisticStyle::DISPLAY_NAME);
}
void ArtisticStyle::updateActions(Core::IEditor *editor) void ArtisticStyle::updateActions(Core::IEditor *editor)
{ {
m_formatFile->setEnabled(editor && editor->document()->id() == CppEditor::Constants::CPPEDITOR_ID); m_formatFile->setEnabled(editor && editor->document()->id() == CppEditor::Constants::CPPEDITOR_ID);
@@ -134,6 +138,12 @@ QString ArtisticStyle::configurationFile() const
return QString(); return QString();
} }
Command ArtisticStyle::command() const
{
const QString cfgFile = configurationFile();
return cfgFile.isEmpty() ? Command() : command(cfgFile);
}
Command ArtisticStyle::command(const QString &cfgFile) const Command ArtisticStyle::command(const QString &cfgFile) const
{ {
Command command; Command command;

View File

@@ -26,7 +26,6 @@
#pragma once #pragma once
#include "../beautifierabstracttool.h" #include "../beautifierabstracttool.h"
#include "../command.h"
QT_FORWARD_DECLARE_CLASS(QAction) QT_FORWARD_DECLARE_CLASS(QAction)
@@ -47,8 +46,10 @@ public:
explicit ArtisticStyle(BeautifierPlugin *parent = nullptr); explicit ArtisticStyle(BeautifierPlugin *parent = nullptr);
virtual ~ArtisticStyle(); virtual ~ArtisticStyle();
bool initialize() override; bool initialize() override;
QString id() const override;
void updateActions(Core::IEditor *editor) override; void updateActions(Core::IEditor *editor) override;
QList<QObject *> autoReleaseObjects() override; QList<QObject *> autoReleaseObjects() override;
Command command() const override;
private: private:
void formatFile(); void formatFile();

View File

@@ -9,6 +9,8 @@ HEADERS += \
configurationdialog.h \ configurationdialog.h \
configurationeditor.h \ configurationeditor.h \
configurationpanel.h \ configurationpanel.h \
generaloptionspage.h \
generalsettings.h \
artisticstyle/artisticstyleconstants.h \ artisticstyle/artisticstyleconstants.h \
artisticstyle/artisticstyle.h \ artisticstyle/artisticstyle.h \
artisticstyle/artisticstyleoptionspage.h \ artisticstyle/artisticstyleoptionspage.h \
@@ -29,6 +31,8 @@ SOURCES += \
configurationdialog.cpp \ configurationdialog.cpp \
configurationeditor.cpp \ configurationeditor.cpp \
configurationpanel.cpp \ configurationpanel.cpp \
generaloptionspage.cpp \
generalsettings.cpp \
artisticstyle/artisticstyle.cpp \ artisticstyle/artisticstyle.cpp \
artisticstyle/artisticstyleoptionspage.cpp \ artisticstyle/artisticstyleoptionspage.cpp \
artisticstyle/artisticstylesettings.cpp \ artisticstyle/artisticstylesettings.cpp \
@@ -42,6 +46,7 @@ SOURCES += \
FORMS += \ FORMS += \
configurationdialog.ui \ configurationdialog.ui \
configurationpanel.ui \ configurationpanel.ui \
generaloptionspage.ui \
artisticstyle/artisticstyleoptionspage.ui \ artisticstyle/artisticstyleoptionspage.ui \
clangformat/clangformatoptionspage.ui \ clangformat/clangformatoptionspage.ui \
uncrustify/uncrustifyoptionspage.ui \ uncrustify/uncrustifyoptionspage.ui \

View File

@@ -30,6 +30,11 @@ QtcPlugin {
"configurationpanel.cpp", "configurationpanel.cpp",
"configurationpanel.h", "configurationpanel.h",
"configurationpanel.ui" "configurationpanel.ui"
"generaloptionspage.cpp",
"generaloptionspage.h",
"generaloptionspage.ui"
"generalsettings.cpp",
"generalsettings.h"
] ]
Group { Group {

View File

@@ -25,6 +25,8 @@
#pragma once #pragma once
#include "command.h"
#include <QList> #include <QList>
#include <QObject> #include <QObject>
@@ -41,9 +43,17 @@ public:
explicit BeautifierAbstractTool(QObject *parent = nullptr) : QObject(parent) {} explicit BeautifierAbstractTool(QObject *parent = nullptr) : QObject(parent) {}
virtual ~BeautifierAbstractTool() {} virtual ~BeautifierAbstractTool() {}
virtual QString id() const = 0;
virtual bool initialize() = 0; virtual bool initialize() = 0;
virtual void updateActions(Core::IEditor *editor) = 0; virtual void updateActions(Core::IEditor *editor) = 0;
virtual QList<QObject *> autoReleaseObjects() = 0; virtual QList<QObject *> autoReleaseObjects() = 0;
/**
* Returns the tool's command to format an entire file.
*
* @note The received command may be invalid.
*/
virtual Command command() const = 0;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -35,6 +35,7 @@ const char MENU_ID[] = "Beautifier.Menu";
const char OPTION_CATEGORY[] = "II.Beautifier"; const char OPTION_CATEGORY[] = "II.Beautifier";
const char OPTION_TR_CATEGORY[] = QT_TRANSLATE_NOOP("Beautifier", "Beautifier"); const char OPTION_TR_CATEGORY[] = QT_TRANSLATE_NOOP("Beautifier", "Beautifier");
const char OPTION_CATEGORY_ICON[] = ":/beautifier/images/beautifier.png"; const char OPTION_CATEGORY_ICON[] = ":/beautifier/images/beautifier.png";
const char OPTION_GENERAL_ID[] = "aaa.General";
const char SETTINGS_GROUP[] = "Beautifier"; const char SETTINGS_GROUP[] = "Beautifier";
const char SETTINGS_DIRNAME[] = "beautifier"; const char SETTINGS_DIRNAME[] = "beautifier";
const char DOCUMENTATION_DIRNAME[] = "documentation"; const char DOCUMENTATION_DIRNAME[] = "documentation";

View File

@@ -26,6 +26,8 @@
#include "beautifierplugin.h" #include "beautifierplugin.h"
#include "beautifierconstants.h" #include "beautifierconstants.h"
#include "generaloptionspage.h"
#include "generalsettings.h"
#include "artisticstyle/artisticstyle.h" #include "artisticstyle/artisticstyle.h"
#include "clangformat/clangformat.h" #include "clangformat/clangformat.h"
@@ -35,14 +37,22 @@
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h> #include <coreplugin/actionmanager/command.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/documentmodel.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h> #include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/messagemanager.h> #include <coreplugin/messagemanager.h>
#include <cppeditor/cppeditorconstants.h>
#include <diffeditor/differ.h> #include <diffeditor/differ.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h>
#include <texteditor/convenience.h> #include <texteditor/convenience.h>
#include <texteditor/textdocument.h> #include <texteditor/textdocument.h>
#include <texteditor/textdocumentlayout.h> #include <texteditor/textdocumentlayout.h>
#include <texteditor/texteditor.h> #include <texteditor/texteditor.h>
#include <texteditor/texteditorconstants.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/runextensions.h> #include <utils/runextensions.h>
#include <utils/synchronousprocess.h> #include <utils/synchronousprocess.h>
@@ -161,37 +171,61 @@ QString sourceData(TextEditorWidget *editor, int startPos, int endPos)
: Convenience::textAt(editor->textCursor(), startPos, (endPos - startPos)); : Convenience::textAt(editor->textCursor(), startPos, (endPos - startPos));
} }
bool isAutoFormatApplicable(const QString &filePath, const QList<Utils::MimeType> &allowedMimeTypes)
{
if (allowedMimeTypes.isEmpty())
return true;
const Utils::MimeDatabase mdb;
const QList<Utils::MimeType> fileMimeTypes = mdb.mimeTypesForFileName(filePath);
auto inheritedByFileMimeTypes = [&fileMimeTypes](const Utils::MimeType &mimeType){
const QString name = mimeType.name();
return Utils::anyOf(fileMimeTypes, [&name](const Utils::MimeType &fileMimeType){
return fileMimeType.inherits(name);
});
};
return Utils::anyOf(allowedMimeTypes, inheritedByFileMimeTypes);
}
bool BeautifierPlugin::initialize(const QStringList &arguments, QString *errorString) bool BeautifierPlugin::initialize(const QStringList &arguments, QString *errorString)
{ {
Q_UNUSED(arguments) Q_UNUSED(arguments)
Q_UNUSED(errorString) Q_UNUSED(errorString)
m_tools << new ArtisticStyle::ArtisticStyle(this);
m_tools << new ClangFormat::ClangFormat(this);
m_tools << new Uncrustify::Uncrustify(this);
Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::MENU_ID); Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::MENU_ID);
menu->menu()->setTitle(QCoreApplication::translate("Beautifier", Constants::OPTION_TR_CATEGORY)); menu->menu()->setTitle(QCoreApplication::translate("Beautifier", Constants::OPTION_TR_CATEGORY));
menu->setOnAllDisabledBehavior(Core::ActionContainer::Show); menu->setOnAllDisabledBehavior(Core::ActionContainer::Show);
Core::ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu); Core::ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu);
m_tools << new ArtisticStyle::ArtisticStyle(this);
m_tools << new ClangFormat::ClangFormat(this);
m_tools << new Uncrustify::Uncrustify(this);
QStringList toolIds;
toolIds.reserve(m_tools.count());
for (BeautifierAbstractTool *tool : m_tools) { for (BeautifierAbstractTool *tool : m_tools) {
toolIds << tool->id();
tool->initialize(); tool->initialize();
const QList<QObject *> autoReleasedObjects = tool->autoReleaseObjects(); const QList<QObject *> autoReleasedObjects = tool->autoReleaseObjects();
for (QObject *object : autoReleasedObjects) for (QObject *object : autoReleasedObjects)
addAutoReleasedObject(object); addAutoReleasedObject(object);
} }
m_generalSettings = new GeneralSettings;
auto settingsPage = new GeneralOptionsPage(m_generalSettings, toolIds, this);
addAutoReleasedObject(settingsPage);
updateActions(); updateActions();
return true; return true;
} }
void BeautifierPlugin::extensionsInitialized() void BeautifierPlugin::extensionsInitialized()
{ {
if (const Core::EditorManager *editorManager = Core::EditorManager::instance()) { const Core::EditorManager *editorManager = Core::EditorManager::instance();
connect(editorManager, &Core::EditorManager::currentEditorChanged, connect(editorManager, &Core::EditorManager::currentEditorChanged,
this, &BeautifierPlugin::updateActions); this, &BeautifierPlugin::updateActions);
} connect(editorManager, &Core::EditorManager::aboutToSave,
this, &BeautifierPlugin::autoFormatOnSave);
} }
ExtensionSystem::IPlugin::ShutdownFlag BeautifierPlugin::aboutToShutdown() ExtensionSystem::IPlugin::ShutdownFlag BeautifierPlugin::aboutToShutdown()
@@ -205,6 +239,42 @@ void BeautifierPlugin::updateActions(Core::IEditor *editor)
tool->updateActions(editor); tool->updateActions(editor);
} }
void BeautifierPlugin::autoFormatOnSave(Core::IDocument *document)
{
if (!m_generalSettings->autoFormatOnSave())
return;
// Check that we are dealing with a cpp editor
if (document->id() != CppEditor::Constants::CPPEDITOR_ID)
return;
const QString filePath = document->filePath().toString();
if (!isAutoFormatApplicable(filePath, m_generalSettings->autoFormatMime()))
return;
// Check if file is contained in the current project (if wished)
if (m_generalSettings->autoFormatOnlyCurrentProject()) {
const ProjectExplorer::Project *pro = ProjectExplorer::ProjectTree::currentProject();
if (!pro || !pro->files(ProjectExplorer::Project::SourceFiles).contains(filePath))
return;
}
// Find tool to use by id and format file!
const QString id = m_generalSettings->autoFormatTool();
auto tool = std::find_if(m_tools.constBegin(), m_tools.constEnd(),
[&id](const BeautifierAbstractTool *t){return t->id() == id;});
if (tool != m_tools.constEnd()) {
const Command command = (*tool)->command();
if (!command.isValid())
return;
const QList<Core::IEditor *> editors = Core::DocumentModel::editorsForDocument(document);
if (editors.isEmpty())
return;
if (TextEditorWidget* widget = qobject_cast<TextEditorWidget *>(editors.first()->widget()))
formatEditor(widget, command);
}
}
void BeautifierPlugin::formatCurrentFile(const Command &command, int startPos, int endPos) void BeautifierPlugin::formatCurrentFile(const Command &command, int startPos, int endPos)
{ {
if (TextEditorWidget *editor = TextEditorWidget::currentTextEditorWidget()) if (TextEditorWidget *editor = TextEditorWidget::currentTextEditorWidget())

View File

@@ -32,13 +32,17 @@
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QPointer> #include <QPointer>
namespace Core { class IEditor; } namespace Core {
namespace TextEditor { class TextEditorWidget; } class IDocument;
class IEditor;
}
namespace TextEditor {class TextEditorWidget;}
namespace Beautifier { namespace Beautifier {
namespace Internal { namespace Internal {
class BeautifierAbstractTool; class BeautifierAbstractTool;
class GeneralSettings;
struct FormatTask struct FormatTask
{ {
@@ -82,12 +86,16 @@ public:
private: private:
void updateActions(Core::IEditor *editor = nullptr); void updateActions(Core::IEditor *editor = nullptr);
QList<BeautifierAbstractTool *> m_tools; QList<BeautifierAbstractTool *> m_tools;
GeneralSettings *m_generalSettings = nullptr;
QHash<QObject*, QMetaObject::Connection> m_autoFormatConnections;
void formatEditor(TextEditor::TextEditorWidget *editor, const Command &command, void formatEditor(TextEditor::TextEditorWidget *editor, const Command &command,
int startPos = -1, int endPos = 0); int startPos = -1, int endPos = 0);
void formatEditorAsync(TextEditor::TextEditorWidget *editor, const Command &command, void formatEditorAsync(TextEditor::TextEditorWidget *editor, const Command &command,
int startPos = -1, int endPos = 0); int startPos = -1, int endPos = 0);
void checkAndApplyTask(const FormatTask &task); void checkAndApplyTask(const FormatTask &task);
void updateEditorText(QPlainTextEdit *editor, const QString &text); void updateEditorText(QPlainTextEdit *editor, const QString &text);
void autoFormatOnSave(Core::IDocument *document);
}; };
} // namespace Internal } // namespace Internal

View File

@@ -63,6 +63,11 @@ ClangFormat::~ClangFormat()
delete m_settings; delete m_settings;
} }
QString ClangFormat::id() const
{
return QLatin1String(Constants::ClangFormat::DISPLAY_NAME);
}
bool ClangFormat::initialize() bool ClangFormat::initialize()
{ {
Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::ClangFormat::MENU_ID); Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::ClangFormat::MENU_ID);
@@ -120,7 +125,7 @@ void ClangFormat::formatSelectedText()
} }
} }
Command ClangFormat::command(int offset, int length) const Command ClangFormat::command() const
{ {
Command command; Command command;
command.setExecutable(m_settings->command()); command.setExecutable(m_settings->command());
@@ -136,14 +141,17 @@ Command ClangFormat::command(int offset, int length) const
command.addOption("-assume-filename=" + path + QDir::separator() + "%filename"); command.addOption("-assume-filename=" + path + QDir::separator() + "%filename");
} }
if (offset != -1) {
command.addOption("-offset=" + QString::number(offset));
command.addOption("-length=" + QString::number(length));
}
return command; return command;
} }
Command ClangFormat::command(int offset, int length) const
{
Command c = command();
c.addOption("-offset=" + QString::number(offset));
c.addOption("-length=" + QString::number(length));
return c;
}
} // namespace ClangFormat } // namespace ClangFormat
} // namespace Internal } // namespace Internal
} // namespace Beautifier } // namespace Beautifier

View File

@@ -26,7 +26,6 @@
#pragma once #pragma once
#include "../beautifierabstracttool.h" #include "../beautifierabstracttool.h"
#include "../command.h"
QT_FORWARD_DECLARE_CLASS(QAction) QT_FORWARD_DECLARE_CLASS(QAction)
@@ -46,9 +45,11 @@ class ClangFormat : public BeautifierAbstractTool
public: public:
explicit ClangFormat(BeautifierPlugin *parent = nullptr); explicit ClangFormat(BeautifierPlugin *parent = nullptr);
virtual ~ClangFormat(); virtual ~ClangFormat();
QString id() const override;
bool initialize() override; bool initialize() override;
void updateActions(Core::IEditor *editor) override; void updateActions(Core::IEditor *editor) override;
QList<QObject *> autoReleaseObjects() override; QList<QObject *> autoReleaseObjects() override;
Command command() const override;
private: private:
void formatFile(); void formatFile();
@@ -57,7 +58,7 @@ private:
QAction *m_formatFile = nullptr; QAction *m_formatFile = nullptr;
QAction *m_formatRange = nullptr; QAction *m_formatRange = nullptr;
ClangFormatSettings *m_settings; ClangFormatSettings *m_settings;
Command command(int offset = -1, int length = -1) const; Command command(int offset, int length) const;
}; };
} // namespace ClangFormat } // namespace ClangFormat

View File

@@ -28,6 +28,11 @@
namespace Beautifier { namespace Beautifier {
namespace Internal { namespace Internal {
bool Command::isValid() const
{
return !m_executable.isEmpty();
}
QString Command::executable() const QString Command::executable() const
{ {
return m_executable; return m_executable;

View File

@@ -39,6 +39,8 @@ public:
PipeProcessing PipeProcessing
}; };
bool isValid() const;
QString executable() const; QString executable() const;
void setExecutable(const QString &executable); void setExecutable(const QString &executable);

View File

@@ -0,0 +1,115 @@
/****************************************************************************
**
** Copyright (C) 2016 Lorenz Haas
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "generaloptionspage.h"
#include "ui_generaloptionspage.h"
#include "beautifierconstants.h"
#include "generalsettings.h"
#include <coreplugin/icore.h>
#include <QTextStream>
namespace Beautifier {
namespace Internal {
GeneralOptionsPageWidget::GeneralOptionsPageWidget(GeneralSettings *settings,
const QStringList &toolIds, QWidget *parent) :
QWidget(parent),
ui(new Ui::GeneralOptionsPage),
m_settings(settings)
{
ui->setupUi(this);
ui->autoFormatTool->addItems(toolIds);
restore();
}
GeneralOptionsPageWidget::~GeneralOptionsPageWidget()
{
delete ui;
}
void GeneralOptionsPageWidget::restore()
{
ui->autoFormat->setChecked(m_settings->autoFormatOnSave());
const int index = ui->autoFormatTool->findText(m_settings->autoFormatTool());
ui->autoFormatTool->setCurrentIndex(qMax(index, 0));
ui->autoFormatMime->setText(m_settings->autoFormatMimeAsString());
ui->autoFormatOnlyCurrentProject->setChecked(m_settings->autoFormatOnlyCurrentProject());
}
void GeneralOptionsPageWidget::apply(bool *autoFormatChanged)
{
if (autoFormatChanged)
*autoFormatChanged = (m_settings->autoFormatOnSave() != ui->autoFormat->isChecked());
m_settings->setAutoFormatOnSave(ui->autoFormat->isChecked());
m_settings->setAutoFormatTool(ui->autoFormatTool->currentText());
m_settings->setAutoFormatMime(ui->autoFormatMime->text());
m_settings->setAutoFormatOnlyCurrentProject(ui->autoFormatOnlyCurrentProject->isChecked());
m_settings->save();
}
GeneralOptionsPage::GeneralOptionsPage(GeneralSettings *settings, const QStringList &toolIds,
QObject *parent) :
IOptionsPage(parent),
m_settings(settings),
m_toolIds(toolIds)
{
setId(Constants::OPTION_GENERAL_ID);
setDisplayName(tr("General"));
setCategory(Constants::OPTION_CATEGORY);
setDisplayCategory(QCoreApplication::translate("Beautifier", Constants::OPTION_TR_CATEGORY));
setCategoryIcon(Constants::OPTION_CATEGORY_ICON);
}
QWidget *GeneralOptionsPage::widget()
{
m_settings->read();
if (!m_widget)
m_widget = new GeneralOptionsPageWidget(m_settings, m_toolIds);
m_widget->restore();
return m_widget;
}
void GeneralOptionsPage::apply()
{
if (m_widget) {
bool autoFormat = false;
m_widget->apply(&autoFormat);
if (autoFormat)
emit autoFormatChanged();
}
}
void GeneralOptionsPage::finish()
{
}
} // namespace Internal
} // namespace Beautifier

View File

@@ -0,0 +1,77 @@
/****************************************************************************
**
** Copyright (C) 2016 Lorenz Haas
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <coreplugin/dialogs/ioptionspage.h>
#include <QPointer>
#include <QWidget>
namespace Beautifier {
namespace Internal {
class GeneralSettings;
namespace Ui { class GeneralOptionsPage; }
class GeneralOptionsPageWidget : public QWidget
{
Q_OBJECT
public:
explicit GeneralOptionsPageWidget(GeneralSettings *settings, const QStringList &toolIds,
QWidget *parent = nullptr);
virtual ~GeneralOptionsPageWidget();
void restore();
void apply(bool *autoFormatChanged);
private:
Ui::GeneralOptionsPage *ui;
GeneralSettings *m_settings;
};
class GeneralOptionsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
explicit GeneralOptionsPage(GeneralSettings *settings, const QStringList &toolIds,
QObject *parent = nullptr);
QWidget *widget() override;
void apply() override;
void finish() override;
signals:
void autoFormatChanged();
private:
QPointer<GeneralOptionsPageWidget> m_widget;
GeneralSettings *m_settings;
QStringList m_toolIds;
};
} // namespace Internal
} // namespace Beautifier

View File

@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Beautifier::Internal::GeneralOptionsPage</class>
<widget class="QWidget" name="Beautifier::Internal::GeneralOptionsPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>817</width>
<height>631</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="formatOnSave">
<property name="enabled">
<bool>true</bool>
</property>
<property name="title">
<string>Automatic formatting on file save</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="autoFormat">
<property name="text">
<string>Enable auto format on file save</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Tool:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="autoFormatTool">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Restrict to MIME types:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="autoFormatMime">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QCheckBox" name="autoFormatOnlyCurrentProject">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Restrict to files contained in the current project</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>autoFormat</sender>
<signal>toggled(bool)</signal>
<receiver>autoFormatTool</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>140</x>
<y>56</y>
</hint>
<hint type="destinationlabel">
<x>262</x>
<y>99</y>
</hint>
</hints>
</connection>
<connection>
<sender>autoFormat</sender>
<signal>toggled(bool)</signal>
<receiver>autoFormatMime</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>292</x>
<y>51</y>
</hint>
<hint type="destinationlabel">
<x>288</x>
<y>106</y>
</hint>
</hints>
</connection>
<connection>
<sender>autoFormat</sender>
<signal>toggled(bool)</signal>
<receiver>label</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>41</x>
<y>55</y>
</hint>
<hint type="destinationlabel">
<x>65</x>
<y>92</y>
</hint>
</hints>
</connection>
<connection>
<sender>autoFormat</sender>
<signal>toggled(bool)</signal>
<receiver>label_2</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>92</x>
<y>47</y>
</hint>
<hint type="destinationlabel">
<x>74</x>
<y>122</y>
</hint>
</hints>
</connection>
<connection>
<sender>autoFormat</sender>
<signal>toggled(bool)</signal>
<receiver>autoFormatOnlyCurrentProject</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>38</x>
<y>50</y>
</hint>
<hint type="destinationlabel">
<x>32</x>
<y>160</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -0,0 +1,140 @@
/****************************************************************************
**
** Copyright (C) 2016 Lorenz Haas
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "generalsettings.h"
#include "beautifierconstants.h"
#include <coreplugin/icore.h>
#include <utils/mimetypes/mimedatabase.h>
namespace Beautifier {
namespace Internal {
namespace {
const char GROUP[] = "General";
const char AUTO_FORMAT_ON_SAVE[] = "autoFormatOnSave";
const char AUTO_FORMAT_TOOL[] = "autoFormatTool";
const char AUTO_FORMAT_MIME[] = "autoFormatMime";
const char AUTO_FORMAT_ONLY_CURRENT_PROJECT[] = "autoFormatOnlyCurrentProject";
}
GeneralSettings::GeneralSettings()
{
read();
}
void GeneralSettings::read()
{
QSettings *s = Core::ICore::settings();
s->beginGroup(Constants::SETTINGS_GROUP);
s->beginGroup(GROUP);
m_autoFormatOnSave = s->value(AUTO_FORMAT_ON_SAVE, false).toBool();
m_autoFormatTool = s->value(AUTO_FORMAT_TOOL, QString()).toString();
setAutoFormatMime(s->value(AUTO_FORMAT_MIME, "text/x-c++src;text/x-c++hdr").toString());
m_autoFormatOnlyCurrentProject = s->value(AUTO_FORMAT_ONLY_CURRENT_PROJECT, true).toBool();
s->endGroup();
s->endGroup();
}
void GeneralSettings::save()
{
QSettings *s = Core::ICore::settings();
s->beginGroup(Constants::SETTINGS_GROUP);
s->beginGroup(GROUP);
s->setValue(AUTO_FORMAT_ON_SAVE, m_autoFormatOnSave);
s->setValue(AUTO_FORMAT_TOOL, m_autoFormatTool);
s->setValue(AUTO_FORMAT_MIME, autoFormatMimeAsString());
s->setValue(AUTO_FORMAT_ONLY_CURRENT_PROJECT, m_autoFormatOnlyCurrentProject);
s->endGroup();
s->endGroup();
}
bool GeneralSettings::autoFormatOnSave() const
{
return m_autoFormatOnSave;
}
void GeneralSettings::setAutoFormatOnSave(bool autoFormatOnSave)
{
m_autoFormatOnSave = autoFormatOnSave;
}
QString GeneralSettings::autoFormatTool() const
{
return m_autoFormatTool;
}
void GeneralSettings::setAutoFormatTool(const QString &autoFormatTool)
{
m_autoFormatTool = autoFormatTool;
}
QList<Utils::MimeType> GeneralSettings::autoFormatMime() const
{
return m_autoFormatMime;
}
QString GeneralSettings::autoFormatMimeAsString() const
{
QStringList types;
types.reserve(m_autoFormatMime.count());
for (auto t : m_autoFormatMime)
types << t.name();
return types.join("; ");
}
void GeneralSettings::setAutoFormatMime(const QList<Utils::MimeType> &autoFormatMime)
{
m_autoFormatMime = autoFormatMime;
}
void GeneralSettings::setAutoFormatMime(const QString &mimeList)
{
const QStringList stringTypes = mimeList.split(';');
QList<Utils::MimeType> types;
types.reserve(stringTypes.count());
const Utils::MimeDatabase mdb;
for (QString t : stringTypes) {
t = t.trimmed();
const Utils::MimeType mime = mdb.mimeTypeForName(t);
if (mime.isValid())
types << mime;
}
setAutoFormatMime(types);
}
bool GeneralSettings::autoFormatOnlyCurrentProject() const
{
return m_autoFormatOnlyCurrentProject;
}
void GeneralSettings::setAutoFormatOnlyCurrentProject(bool autoFormatOnlyCurrentProject)
{
m_autoFormatOnlyCurrentProject = autoFormatOnlyCurrentProject;
}
} // namespace Internal
} // namespace Beautifier

View File

@@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (C) 2016 Lorenz Haas
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <utils/mimetypes/mimetype.h>
namespace Beautifier {
namespace Internal {
class GeneralSettings
{
public:
explicit GeneralSettings();
void read();
void save();
bool autoFormatOnSave() const;
void setAutoFormatOnSave(bool autoFormatOnSave);
QString autoFormatTool() const;
void setAutoFormatTool(const QString &autoFormatTool);
QList<Utils::MimeType> autoFormatMime() const;
QString autoFormatMimeAsString() const;
void setAutoFormatMime(const QList<Utils::MimeType> &autoFormatMime);
void setAutoFormatMime(const QString &mimeList);
bool autoFormatOnlyCurrentProject() const;
void setAutoFormatOnlyCurrentProject(bool autoFormatOnlyCurrentProject);
private:
bool m_autoFormatOnSave = false;
bool m_autoFormatOnlyCurrentProject = true;
QString m_autoFormatTool;
QList<Utils::MimeType> m_autoFormatMime;
};
} // namespace Internal
} // namespace Beautifier

View File

@@ -88,6 +88,11 @@ bool Uncrustify::initialize()
return true; return true;
} }
QString Uncrustify::id() const
{
return QLatin1String(Constants::Uncrustify::DISPLAY_NAME);
}
void Uncrustify::updateActions(Core::IEditor *editor) void Uncrustify::updateActions(Core::IEditor *editor)
{ {
const bool enabled = (editor && editor->document()->id() == CppEditor::Constants::CPPEDITOR_ID); const bool enabled = (editor && editor->document()->id() == CppEditor::Constants::CPPEDITOR_ID);
@@ -168,6 +173,12 @@ QString Uncrustify::configurationFile() const
return QString(); return QString();
} }
Command Uncrustify::command() const
{
const QString cfgFile = configurationFile();
return cfgFile.isEmpty() ? Command() : command(cfgFile, false);
}
Command Uncrustify::command(const QString &cfgFile, bool fragment) const Command Uncrustify::command(const QString &cfgFile, bool fragment) const
{ {
Command command; Command command;

View File

@@ -26,7 +26,6 @@
#pragma once #pragma once
#include "../beautifierabstracttool.h" #include "../beautifierabstracttool.h"
#include "../command.h"
QT_FORWARD_DECLARE_CLASS(QAction) QT_FORWARD_DECLARE_CLASS(QAction)
@@ -47,8 +46,10 @@ public:
explicit Uncrustify(BeautifierPlugin *parent = nullptr); explicit Uncrustify(BeautifierPlugin *parent = nullptr);
virtual ~Uncrustify(); virtual ~Uncrustify();
bool initialize() override; bool initialize() override;
QString id() const override;
void updateActions(Core::IEditor *editor) override; void updateActions(Core::IEditor *editor) override;
QList<QObject *> autoReleaseObjects() override; QList<QObject *> autoReleaseObjects() override;
Command command() const override;
private: private:
void formatFile(); void formatFile();

View File

@@ -1906,6 +1906,7 @@ bool EditorManagerPrivate::saveDocument(IDocument *document)
bool success = false; bool success = false;
bool isReadOnly; bool isReadOnly;
emit m_instance->aboutToSave(document);
// try saving, no matter what isReadOnly tells us // try saving, no matter what isReadOnly tells us
success = DocumentManager::saveDocument(document, QString(), &isReadOnly); success = DocumentManager::saveDocument(document, QString(), &isReadOnly);
@@ -1932,6 +1933,7 @@ bool EditorManagerPrivate::saveDocumentAs(IDocument *document)
if (!document) if (!document)
return false; return false;
emit m_instance->aboutToSave(document);
Utils::MimeDatabase mdb; Utils::MimeDatabase mdb;
const QString filter = Utils::MimeDatabase::allFiltersString(); const QString filter = Utils::MimeDatabase::allFiltersString();
QString selectedFilter; QString selectedFilter;

View File

@@ -183,6 +183,7 @@ signals:
void editorAboutToClose(Core::IEditor *editor); void editorAboutToClose(Core::IEditor *editor);
void editorsClosed(QList<Core::IEditor *> editors); void editorsClosed(QList<Core::IEditor *> editors);
void findOnFileSystemRequest(const QString &path); void findOnFileSystemRequest(const QString &path);
void aboutToSave(IDocument *document);
public slots: public slots:
static void saveDocument(); static void saveDocument();