Commit 3af36134 authored by Lorenz Haas's avatar Lorenz Haas

Beautifier: Make all tools MIME restrict-able

The newly introduced auto save option is restricted to user definable
MIME types. The underlaying tool's restriction, however, is only if the
current editor is a cpp editor. This patch makes the tools also MIME
types restrict-able. In addition the auto save functionality is now only
applicable if the file matches the auto save MIME types as well as the
MIME types of the chosen tool.

Change-Id: Ic430b4a07341647e6c8e95d2b802a17db1637a36
Reviewed-by: Riitta-Leena Miettinen's avatarLeena Miettinen <riitta-leena.miettinen@qt.io>
parent 069714b8
......@@ -81,10 +81,14 @@
\image beautifier_options.png
\li In the \uicontrol {Artistic Style command},
\li In the \uicontrol Configuration group, specify the path to
the tool executable in the \uicontrol {Artistic Style command},
\uicontrol {Clang Format command}, or
\uicontrol {Uncrustify command} field, specify the path to the tool
executable.
\uicontrol {Uncrustify command} field.
\li In the \uicontrol {Restrict to MIME types} field, define the MIME
types of the files to beautify, separated by semicolons. Leave the
field empty to apply the tool on all files.
\li In the \uicontrol Options group, select the configuration file that
defines the style to use in the source files. If you select several
......
......@@ -29,7 +29,10 @@
#include "beautifierplugin.h"
#include <coreplugin/icore.h>
#include <coreplugin/idocument.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <utils/mimetypes/mimedatabase.h>
#include <QFile>
#include <QFileInfo>
......@@ -38,6 +41,11 @@
namespace Beautifier {
namespace Internal {
namespace {
const char COMMAND[] = "command";
const char SUPPORTED_MIME[] = "supportedMime";
}
AbstractSettings::AbstractSettings(const QString &name, const QString &ending) :
m_ending(ending),
m_styleDir(Core::ICore::userResourcePath() + '/' + Beautifier::Constants::SETTINGS_DIRNAME
......@@ -139,6 +147,46 @@ void AbstractSettings::updateVersion()
// in m_version.
}
QString AbstractSettings::supportedMimeTypesAsString() const
{
return m_supportedMimeTypes.join("; ");
}
void AbstractSettings::setSupportedMimeTypes(const QString &mimes)
{
const QStringList stringTypes = mimes.split(';');
const Utils::MimeDatabase mdb;
QStringList types;
for (const QString &type : stringTypes) {
const Utils::MimeType mime = mdb.mimeTypeForName(type.trimmed());
if (!mime.isValid())
continue;
const QString canonicalName = mime.name();
if (!types.contains(canonicalName))
types << canonicalName;
}
if (m_supportedMimeTypes != types) {
m_supportedMimeTypes = types;
emit supportedMimeTypesChanged();
}
}
bool AbstractSettings::isApplicable(const Core::IDocument *document) const
{
if (!document)
return false;
if (m_supportedMimeTypes.isEmpty())
return true;
const Utils::MimeDatabase mdb;
const Utils::MimeType documentMimeType = mdb.mimeTypeForName(document->mimeType());
return Utils::anyOf(m_supportedMimeTypes, [&documentMimeType](const QString &mime) {
return documentMimeType.inherits(mime);
});
}
QStringList AbstractSettings::options()
{
if (m_options.isEmpty())
......@@ -167,7 +215,8 @@ void AbstractSettings::save()
s->setValue(iSettings.key(), iSettings.value());
++iSettings;
}
s->setValue("command", m_command);
s->setValue(COMMAND, m_command);
s->setValue(SUPPORTED_MIME, supportedMimeTypesAsString());
s->endGroup();
s->endGroup();
......@@ -225,14 +274,19 @@ void AbstractSettings::createDocumentationFile() const
void AbstractSettings::read()
{
// Set default values
setSupportedMimeTypes("text/x-c++src;text/x-c++hdr");
// Read settings, except styles
QSettings *s = Core::ICore::settings();
s->beginGroup(Constants::SETTINGS_GROUP);
s->beginGroup(m_name);
const QStringList keys = s->allKeys();
for (const QString &key : keys) {
if (key == "command")
if (key == COMMAND)
setCommand(s->value(key).toString());
else if (key == SUPPORTED_MIME)
setSupportedMimeTypes(s->value(key).toString());
else if (m_settings.contains(key))
m_settings[key] = s->value(key);
else
......
......@@ -29,16 +29,20 @@
#include <QDir>
#include <QHash>
#include <QMap>
#include <QObject>
#include <QSet>
#include <QString>
#include <QStringList>
#include <QVector>
namespace Core { class IDocument; }
namespace Beautifier {
namespace Internal {
class AbstractSettings
class AbstractSettings : public QObject
{
Q_DECLARE_TR_FUNCTIONS(AbstractSettings)
Q_OBJECT
public:
explicit AbstractSettings(const QString &name, const QString &ending);
......@@ -65,9 +69,16 @@ public:
int version() const;
virtual void updateVersion();
QString supportedMimeTypesAsString() const;
void setSupportedMimeTypes(const QString &mimes);
bool isApplicable(const Core::IDocument *document) const;
QStringList options();
QString documentation(const QString &option) const;
signals:
void supportedMimeTypesChanged();
protected:
QMap<QString, QString> m_styles;
QMap<QString, QVariant> m_settings;
......@@ -85,6 +96,7 @@ private:
QString m_command;
QHash<QString, int> m_options;
QStringList m_docu;
QStringList m_supportedMimeTypes;
};
} // namespace Internal
......
......@@ -38,6 +38,7 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/idocument.h>
#include <cppeditor/cppeditorconstants.h>
......@@ -77,6 +78,9 @@ bool ArtisticStyle::initialize()
Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu);
connect(m_settings, &ArtisticStyleSettings::supportedMimeTypesChanged,
[this](){updateActions(Core::EditorManager::instance()->currentEditor());});
return true;
}
......@@ -87,7 +91,7 @@ QString ArtisticStyle::id() const
void ArtisticStyle::updateActions(Core::IEditor *editor)
{
m_formatFile->setEnabled(editor && editor->document()->id() == CppEditor::Constants::CPPEDITOR_ID);
m_formatFile->setEnabled(editor && m_settings->isApplicable(editor->document()));
}
QList<QObject *> ArtisticStyle::autoReleaseObjects()
......@@ -144,6 +148,11 @@ Command ArtisticStyle::command() const
return cfgFile.isEmpty() ? Command() : command(cfgFile);
}
bool ArtisticStyle::isApplicable(const Core::IDocument *document) const
{
return m_settings->isApplicable(document);
}
Command ArtisticStyle::command(const QString &cfgFile) const
{
Command command;
......
......@@ -50,6 +50,7 @@ public:
void updateActions(Core::IEditor *editor) override;
QList<QObject *> autoReleaseObjects() override;
Command command() const override;
bool isApplicable(const Core::IDocument *document) const override;
private:
void formatFile();
......
......@@ -62,6 +62,7 @@ ArtisticStyleOptionsPageWidget::~ArtisticStyleOptionsPageWidget()
void ArtisticStyleOptionsPageWidget::restore()
{
ui->command->setPath(m_settings->command());
ui->mime->setText(m_settings->supportedMimeTypesAsString());
ui->useOtherFiles->setChecked(m_settings->useOtherFiles());
ui->useHomeFile->setChecked(m_settings->useHomeFile());
ui->useCustomStyle->setChecked(m_settings->useCustomStyle());
......@@ -71,11 +72,15 @@ void ArtisticStyleOptionsPageWidget::restore()
void ArtisticStyleOptionsPageWidget::apply()
{
m_settings->setCommand(ui->command->path());
m_settings->setSupportedMimeTypes(ui->mime->text());
m_settings->setUseOtherFiles(ui->useOtherFiles->isChecked());
m_settings->setUseHomeFile(ui->useHomeFile->isChecked());
m_settings->setUseCustomStyle(ui->useCustomStyle->isChecked());
m_settings->setCustomStyle(ui->configurations->currentConfiguration());
m_settings->save();
// update since not all MIME types are accepted (invalids or duplicates)
ui->mime->setText(m_settings->supportedMimeTypesAsString());
}
ArtisticStyleOptionsPage::ArtisticStyleOptionsPage(ArtisticStyleSettings *settings, QObject *parent) :
......
......@@ -19,17 +19,27 @@
<property name="title">
<string>Configuration</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="commandLabel">
<property name="text">
<string>Artistic Style command:</string>
</property>
</widget>
</item>
<item>
<item row="0" column="1">
<widget class="Utils::PathChooser" name="command" native="true"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mimeLabel">
<property name="text">
<string>Restrict to MIME types:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="mime"/>
</item>
</layout>
</widget>
</item>
......
......@@ -34,7 +34,7 @@ namespace Beautifier {
namespace Internal {
namespace ArtisticStyle {
class ArtisticStyleSettings : public QObject, public AbstractSettings
class ArtisticStyleSettings : public AbstractSettings
{
Q_OBJECT
......
......@@ -30,7 +30,10 @@
#include <QList>
#include <QObject>
namespace Core { class IEditor; }
namespace Core {
class IDocument;
class IEditor;
}
namespace Beautifier {
namespace Internal {
......@@ -54,6 +57,8 @@ public:
* @note The received command may be invalid.
*/
virtual Command command() const = 0;
virtual bool isApplicable(const Core::IDocument *document) const = 0;
};
} // namespace Internal
......
......@@ -171,20 +171,20 @@ QString sourceData(TextEditorWidget *editor, int startPos, int endPos)
: Convenience::textAt(editor->textCursor(), startPos, (endPos - startPos));
}
bool isAutoFormatApplicable(const QString &filePath, const QList<Utils::MimeType> &allowedMimeTypes)
bool isAutoFormatApplicable(const Core::IDocument *document,
const QList<Utils::MimeType> &allowedMimeTypes)
{
if (!document)
return false;
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);
const Utils::MimeType documentMimeType = mdb.mimeTypeForName(document->mimeType());
return Utils::anyOf(allowedMimeTypes, [&documentMimeType](const Utils::MimeType &mime) {
return documentMimeType.inherits(mime.name());
});
}
bool BeautifierPlugin::initialize(const QStringList &arguments, QString *errorString)
......@@ -244,19 +244,16 @@ 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()))
if (!isAutoFormatApplicable(document, 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))
if (!pro || !pro->files(ProjectExplorer::Project::SourceFiles).contains(
document->filePath().toString())) {
return;
}
}
// Find tool to use by id and format file!
......@@ -264,6 +261,8 @@ void BeautifierPlugin::autoFormatOnSave(Core::IDocument *document)
auto tool = std::find_if(m_tools.constBegin(), m_tools.constEnd(),
[&id](const BeautifierAbstractTool *t){return t->id() == id;});
if (tool != m_tools.constEnd()) {
if (!(*tool)->isApplicable(document))
return;
const Command command = (*tool)->command();
if (!command.isValid())
return;
......
......@@ -38,11 +38,13 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/idocument.h>
#include <cppeditor/cppeditorconstants.h>
#include <texteditor/texteditor.h>
#include <utils/algorithm.h>
#include <utils/fileutils.h>
#include <QAction>
#include <QMenu>
......@@ -88,12 +90,15 @@ bool ClangFormat::initialize()
Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu);
connect(m_settings, &ClangFormatSettings::supportedMimeTypesChanged,
[this](){updateActions(Core::EditorManager::instance()->currentEditor());});
return true;
}
void ClangFormat::updateActions(Core::IEditor *editor)
{
const bool enabled = (editor && editor->document()->id() == CppEditor::Constants::CPPEDITOR_ID);
const bool enabled = (editor && m_settings->isApplicable(editor->document()));
m_formatFile->setEnabled(enabled);
m_formatRange->setEnabled(enabled);
}
......@@ -144,6 +149,11 @@ Command ClangFormat::command() const
return command;
}
bool ClangFormat::isApplicable(const Core::IDocument *document) const
{
return m_settings->isApplicable(document);
}
Command ClangFormat::command(int offset, int length) const
{
Command c = command();
......
......@@ -50,6 +50,7 @@ public:
void updateActions(Core::IEditor *editor) override;
QList<QObject *> autoReleaseObjects() override;
Command command() const override;
bool isApplicable(const Core::IDocument *document) const override;
private:
void formatFile();
......
......@@ -62,6 +62,7 @@ ClangFormatOptionsPageWidget::~ClangFormatOptionsPageWidget()
void ClangFormatOptionsPageWidget::restore()
{
ui->command->setPath(m_settings->command());
ui->mime->setText(m_settings->supportedMimeTypesAsString());
const int textIndex = ui->predefinedStyle->findText(m_settings->predefinedStyle());
if (textIndex != -1)
ui->predefinedStyle->setCurrentIndex(textIndex);
......@@ -78,11 +79,15 @@ void ClangFormatOptionsPageWidget::restore()
void ClangFormatOptionsPageWidget::apply()
{
m_settings->setCommand(ui->command->path());
m_settings->setSupportedMimeTypes(ui->mime->text());
m_settings->setUsePredefinedStyle(ui->usePredefinedStyle->isChecked());
m_settings->setPredefinedStyle(ui->predefinedStyle->currentText());
m_settings->setCustomStyle(ui->configurations->currentConfiguration());
m_settings->setFormatEntireFileFallback(ui->formatEntireFileFallback->isChecked());
m_settings->save();
// update since not all MIME types are accepted (invalids or duplicates)
ui->mime->setText(m_settings->supportedMimeTypesAsString());
}
ClangFormatOptionsPage::ClangFormatOptionsPage(ClangFormatSettings *settings, QObject *parent) :
......
......@@ -19,17 +19,27 @@
<property name="title">
<string>Configuration</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="commandLabel">
<property name="text">
<string>Clang Format command:</string>
</property>
</widget>
</item>
<item>
<item row="0" column="1">
<widget class="Utils::PathChooser" name="command" native="true"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mimeLabel">
<property name="text">
<string>Restrict to MIME types:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="mime"/>
</item>
</layout>
</widget>
</item>
......
......@@ -33,7 +33,7 @@ namespace ClangFormat {
class ClangFormatSettings : public AbstractSettings
{
Q_DECLARE_TR_FUNCTIONS(ClangFormatSettings)
Q_OBJECT
public:
explicit ClangFormatSettings();
......
......@@ -38,6 +38,7 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/idocument.h>
#include <cppeditor/cppeditorconstants.h>
......@@ -85,6 +86,9 @@ bool Uncrustify::initialize()
Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu);
connect(m_settings, &UncrustifySettings::supportedMimeTypesChanged,
[this](){updateActions(Core::EditorManager::instance()->currentEditor());});
return true;
}
......@@ -95,7 +99,7 @@ QString Uncrustify::id() const
void Uncrustify::updateActions(Core::IEditor *editor)
{
const bool enabled = (editor && editor->document()->id() == CppEditor::Constants::CPPEDITOR_ID);
const bool enabled = (editor && m_settings->isApplicable(editor->document()));
m_formatFile->setEnabled(enabled);
m_formatRange->setEnabled(enabled);
}
......@@ -179,6 +183,11 @@ Command Uncrustify::command() const
return cfgFile.isEmpty() ? Command() : command(cfgFile, false);
}
bool Uncrustify::isApplicable(const Core::IDocument *document) const
{
return m_settings->isApplicable(document);
}
Command Uncrustify::command(const QString &cfgFile, bool fragment) const
{
Command command;
......
......@@ -50,6 +50,7 @@ public:
void updateActions(Core::IEditor *editor) override;
QList<QObject *> autoReleaseObjects() override;
Command command() const override;
bool isApplicable(const Core::IDocument *document) const override;
private:
void formatFile();
......
......@@ -64,6 +64,7 @@ UncrustifyOptionsPageWidget::~UncrustifyOptionsPageWidget()
void UncrustifyOptionsPageWidget::restore()
{
ui->command->setPath(m_settings->command());
ui->mime->setText(m_settings->supportedMimeTypesAsString());
ui->useOtherFiles->setChecked(m_settings->useOtherFiles());
ui->useHomeFile->setChecked(m_settings->useHomeFile());
ui->useCustomStyle->setChecked(m_settings->useCustomStyle());
......@@ -74,12 +75,16 @@ void UncrustifyOptionsPageWidget::restore()
void UncrustifyOptionsPageWidget::apply()
{
m_settings->setCommand(ui->command->path());
m_settings->setSupportedMimeTypes(ui->mime->text());
m_settings->setUseOtherFiles(ui->useOtherFiles->isChecked());
m_settings->setUseHomeFile(ui->useHomeFile->isChecked());
m_settings->setUseCustomStyle(ui->useCustomStyle->isChecked());
m_settings->setCustomStyle(ui->configurations->currentConfiguration());
m_settings->setFormatEntireFileFallback(ui->formatEntireFileFallback->isChecked());
m_settings->save();
// update since not all MIME types are accepted (invalids or duplicates)
ui->mime->setText(m_settings->supportedMimeTypesAsString());
}
UncrustifyOptionsPage::UncrustifyOptionsPage(UncrustifySettings *settings, QObject *parent) :
......
......@@ -19,17 +19,27 @@
<property name="title">
<string>Configuration</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="commandLabel">
<property name="text">
<string>Uncrustify command:</string>
</property>
</widget>
</item>
<item>
<item row="0" column="1">
<widget class="Utils::PathChooser" name="command" native="true"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="mimeLabel">
<property name="text">
<string>Restrict to MIME types:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="mime"/>
</item>
</layout>
</widget>
</item>
......
......@@ -33,7 +33,7 @@ namespace Beautifier {
namespace Internal {
namespace Uncrustify {
class UncrustifySettings : public QObject, public AbstractSettings
class UncrustifySettings : public AbstractSettings
{
Q_OBJECT
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment