+
+namespace Beautifier {
+namespace Internal {
+namespace ArtisticStyle {
+
+namespace {
+const char kUseOtherFiles[] = "useOtherFiles";
+const char kUseHomeFile[] = "useHomeFile";
+const char kUseCustomStyle[] = "useCustomStyle";
+const char kCustomStyle[] = "customStyle";
+}
+
+ArtisticStyleSettings::ArtisticStyleSettings() :
+ AbstractSettings(QLatin1String(Constants::ArtisticStyle::SETTINGS_NAME),
+ QLatin1String(".astyle"))
+{
+ setCommand(QLatin1String("astyle"));
+ m_settings.insert(QLatin1String(kUseOtherFiles), QVariant(true));
+ m_settings.insert(QLatin1String(kUseHomeFile), QVariant(false));
+ m_settings.insert(QLatin1String(kUseCustomStyle), QVariant(false));
+ m_settings.insert(QLatin1String(kCustomStyle), QVariant());
+ read();
+}
+
+bool ArtisticStyleSettings::useOtherFiles() const
+{
+ return m_settings.value(QLatin1String(kUseOtherFiles)).toBool();
+}
+
+void ArtisticStyleSettings::setUseOtherFiles(bool useOtherFiles)
+{
+ m_settings.insert(QLatin1String(kUseOtherFiles), QVariant(useOtherFiles));
+}
+
+bool ArtisticStyleSettings::useHomeFile() const
+{
+ return m_settings.value(QLatin1String(kUseHomeFile)).toBool();
+}
+
+void ArtisticStyleSettings::setUseHomeFile(bool useHomeFile)
+{
+ m_settings.insert(QLatin1String(kUseHomeFile), QVariant(useHomeFile));
+}
+
+bool ArtisticStyleSettings::useCustomStyle() const
+{
+ return m_settings.value(QLatin1String(kUseCustomStyle)).toBool();
+}
+
+void ArtisticStyleSettings::setUseCustomStyle(bool useCustomStyle)
+{
+ m_settings.insert(QLatin1String(kUseCustomStyle), QVariant(useCustomStyle));
+}
+
+QString ArtisticStyleSettings::customStyle() const
+{
+ return m_settings.value(QLatin1String(kCustomStyle)).toString();
+}
+
+void ArtisticStyleSettings::setCustomStyle(const QString &customStyle)
+{
+ m_settings.insert(QLatin1String(kCustomStyle), QVariant(customStyle));
+}
+
+QString ArtisticStyleSettings::documentationFilePath() const
+{
+ return Core::ICore::userResourcePath() + QLatin1Char('/')
+ + QLatin1String(Beautifier::Constants::SETTINGS_DIRNAME) + QLatin1Char('/')
+ + QLatin1String(Beautifier::Constants::DOCUMENTATION_DIRNAME) + QLatin1Char('/')
+ + QLatin1String(Constants::ArtisticStyle::SETTINGS_NAME) + QLatin1String(".xml");
+}
+
+void ArtisticStyleSettings::createDocumentationFile() const
+{
+ QFile file(documentationFilePath());
+ const QFileInfo fi(file);
+ if (!fi.exists())
+ fi.dir().mkpath(fi.absolutePath());
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
+ return;
+
+ QProcess process;
+ process.start(command(), QStringList() << QLatin1String("-h"));
+ process.waitForFinished(2000); // show help should be really fast.
+ if (process.error() != QProcess::UnknownError)
+ return;
+
+ QXmlStreamWriter stream(&file);
+ stream.setAutoFormatting(true);
+ stream.writeStartDocument(QLatin1String("1.0"), true);
+ stream.writeComment(QLatin1String("Created ")
+ + QDateTime::currentDateTime().toString(Qt::ISODate));
+ stream.writeStartElement(QLatin1String(Constants::DOCUMENTATION_XMLROOT));
+
+ // astyle writes its output to 'error'...
+ const QStringList lines = QString::fromUtf8(process.readAllStandardError())
+ .split(QLatin1Char('\n'));
+ const int totalLines = lines.count();
+ QStringList keys;
+ QStringList docu;
+ for (int i = 0; i < totalLines; ++i) {
+ const QString &line = lines.at(i).trimmed();
+ if ((line.startsWith(QLatin1String("--")) && !line.startsWith(QLatin1String("---")))
+ || line.startsWith(QLatin1String("OR "))) {
+ QStringList rawKeys = line.split(QLatin1String(" OR "), QString::SkipEmptyParts);
+ foreach (QString k, rawKeys) {
+ k = k.trimmed();
+ k.remove(QLatin1Char('#'));
+ keys << k;
+ if (k.startsWith(QLatin1String("--")))
+ keys << k.right(k.size() - 2);
+ }
+ } else {
+ if (line.isEmpty()) {
+ if (!keys.isEmpty()) {
+ // Write entry
+ stream.writeStartElement(QLatin1String(Constants::DOCUMENTATION_XMLENTRY));
+ stream.writeStartElement(QLatin1String(Constants::DOCUMENTATION_XMLKEYS));
+ foreach (const QString &key, keys)
+ stream.writeTextElement(QLatin1String(Constants::DOCUMENTATION_XMLKEY), key);
+ stream.writeEndElement();
+ const QString text = QLatin1String("")
+ + keys.filter(QRegExp(QLatin1String("^\\-"))).join(QLatin1String(", "))
+ + QLatin1String("
")
+ + Qt::escape(docu.join(QLatin1Char(' ')))
+ + QLatin1String("
");
+ stream.writeTextElement(QLatin1String(Constants::DOCUMENTATION_XMLDOC), text);
+ stream.writeEndElement();
+ }
+ keys.clear();
+ docu.clear();
+ } else if (!keys.isEmpty()) {
+ docu << line;
+ }
+ }
+ }
+
+ stream.writeEndElement();
+ stream.writeEndDocument();
+}
+
+} // namespace ArtisticStyle
+} // namespace Internal
+} // namespace Beautifier
diff --git a/src/plugins/beautifier/artisticstyle/artisticstylesettings.h b/src/plugins/beautifier/artisticstyle/artisticstylesettings.h
new file mode 100644
index 0000000000000000000000000000000000000000..412570c9e4cd5a41da37dde3c1e86833f765028e
--- /dev/null
+++ b/src/plugins/beautifier/artisticstyle/artisticstylesettings.h
@@ -0,0 +1,66 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_ARTISTICSTYLESETTINGS_H
+#define BEAUTIFIER_ARTISTICSTYLESETTINGS_H
+
+#include "../abstractsettings.h"
+
+#include
+
+namespace Beautifier {
+namespace Internal {
+namespace ArtisticStyle {
+
+class ArtisticStyleSettings : public AbstractSettings
+{
+public:
+ ArtisticStyleSettings();
+
+ bool useOtherFiles() const;
+ void setUseOtherFiles(bool useOtherFiles);
+
+ bool useHomeFile() const;
+ void setUseHomeFile(bool useHomeFile);
+
+ bool useCustomStyle() const;
+ void setUseCustomStyle(bool useCustomStyle);
+
+ QString customStyle() const;
+ void setCustomStyle(const QString &customStyle);
+
+ QString documentationFilePath() const QTC_OVERRIDE;
+ void createDocumentationFile() const QTC_OVERRIDE;
+};
+
+} // namespace ArtisticStyle
+} // namespace Internal
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_ARTISTICSTYLESETTINGS_H
diff --git a/src/plugins/beautifier/beautifier.pro b/src/plugins/beautifier/beautifier.pro
new file mode 100644
index 0000000000000000000000000000000000000000..4e0891dc25bae8555de24d3eaf43ee15131c1a3b
--- /dev/null
+++ b/src/plugins/beautifier/beautifier.pro
@@ -0,0 +1,51 @@
+include(../../qtcreatorplugin.pri)
+
+QT += xml
+
+HEADERS += \
+ abstractsettings.h \
+ beautifierabstracttool.h \
+ beautifierconstants.h \
+ beautifierplugin.h \
+ configurationdialog.h \
+ configurationeditor.h \
+ configurationpanel.h \
+ artisticstyle/artisticstyleconstants.h \
+ artisticstyle/artisticstyle.h \
+ artisticstyle/artisticstyleoptionspage.h \
+ artisticstyle/artisticstylesettings.h \
+ clangformat/clangformatconstants.h \
+ clangformat/clangformat.h \
+ clangformat/clangformatoptionspage.h \
+ clangformat/clangformatsettings.h \
+ uncrustify/uncrustifyconstants.h \
+ uncrustify/uncrustify.h \
+ uncrustify/uncrustifyoptionspage.h \
+ uncrustify/uncrustifysettings.h
+
+SOURCES += \
+ abstractsettings.cpp \
+ beautifierplugin.cpp \
+ configurationdialog.cpp \
+ configurationeditor.cpp \
+ configurationpanel.cpp \
+ artisticstyle/artisticstyle.cpp \
+ artisticstyle/artisticstyleoptionspage.cpp \
+ artisticstyle/artisticstylesettings.cpp \
+ clangformat/clangformat.cpp \
+ clangformat/clangformatoptionspage.cpp \
+ clangformat/clangformatsettings.cpp \
+ uncrustify/uncrustify.cpp \
+ uncrustify/uncrustifyoptionspage.cpp \
+ uncrustify/uncrustifysettings.cpp
+
+FORMS += \
+ configurationdialog.ui \
+ configurationpanel.ui \
+ artisticstyle/artisticstyleoptionspage.ui \
+ clangformat/clangformatoptionspage.ui \
+ uncrustify/uncrustifyoptionspage.ui \
+
+RESOURCES += \
+ beautifier.qrc
+
diff --git a/src/plugins/beautifier/beautifier.qbs b/src/plugins/beautifier/beautifier.qbs
new file mode 100644
index 0000000000000000000000000000000000000000..78ef3327ee6b5c763d55752459ad955091211700
--- /dev/null
+++ b/src/plugins/beautifier/beautifier.qbs
@@ -0,0 +1,79 @@
+import qbs.base 1.0
+
+import QtcPlugin
+
+QtcPlugin {
+ name: "Beautifier"
+
+ Depends { name: "Qt.widgets" }
+ Depends { name: "Qt.xml" }
+ Depends { name: "Utils" }
+ Depends { name: "Core" }
+ Depends { name: "CppEditor" }
+ Depends { name: "DiffEditor" }
+ Depends { name: "TextEditor" }
+ Depends { name: "ProjectExplorer" }
+
+ files: [
+ "abstractsettings.h",
+ "abstractsettings.cpp",
+ "beautifier.qrc",
+ "beautifierabstracttool.h",
+ "beautifierconstants.h",
+ "beautifierplugin.cpp",
+ "beautifierplugin.h",
+ "configurationdialog.cpp",
+ "configurationdialog.h",
+ "configurationdialog.ui",
+ "configurationeditor.cpp",
+ "configurationeditor.h",
+ "configurationpanel.cpp",
+ "configurationpanel.h",
+ "configurationpanel.ui"
+ ]
+
+ Group {
+ name: "ArtisticStyle"
+ prefix: "artisticstyle/"
+ files: [
+ "artisticstyle.cpp",
+ "artisticstyle.h",
+ "artisticstyleconstants.h",
+ "artisticstyleoptionspage.cpp",
+ "artisticstyleoptionspage.h",
+ "artisticstyleoptionspage.ui",
+ "artisticstylesettings.cpp",
+ "artisticstylesettings.h"
+ ]
+ }
+
+ Group {
+ name: "ClangFormat"
+ prefix: "clangformat/"
+ files: [
+ "clangformat.cpp",
+ "clangformat.h",
+ "clangformatconstants.h",
+ "clangformatoptionspage.cpp",
+ "clangformatoptionspage.h",
+ "clangformatoptionspage.ui",
+ "clangformatsettings.cpp",
+ "clangformatsettings.h"
+ ]
+ }
+
+ Group {
+ name: "Uncrustify"
+ prefix: "uncrustify/"
+ files: [
+ "uncrustify.cpp",
+ "uncrustify.h",
+ "uncrustifyconstants.h",
+ "uncrustifyoptionspage.cpp",
+ "uncrustifyoptionspage.h",
+ "uncrustifyoptionspage.ui",
+ "uncrustifysettings.cpp",
+ "uncrustifysettings.h"
+ ]
+ }
+}
diff --git a/src/plugins/beautifier/beautifier.qrc b/src/plugins/beautifier/beautifier.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..db98b065bc29e3d47d08a05bb44d3d59b2a36e28
--- /dev/null
+++ b/src/plugins/beautifier/beautifier.qrc
@@ -0,0 +1,5 @@
+
+
+ images/beautifier.png
+
+
diff --git a/src/plugins/beautifier/beautifier_dependencies.pri b/src/plugins/beautifier/beautifier_dependencies.pri
new file mode 100644
index 0000000000000000000000000000000000000000..a759c3632239fad8e765d974c891791b6f2de118
--- /dev/null
+++ b/src/plugins/beautifier/beautifier_dependencies.pri
@@ -0,0 +1,7 @@
+QTC_PLUGIN_NAME = Beautifier
+QTC_LIB_DEPENDS += utils
+QTC_PLUGIN_DEPENDS += coreplugin \
+ cppeditor \
+ diffeditor \
+ projectexplorer \
+ texteditor
diff --git a/src/plugins/beautifier/beautifierabstracttool.h b/src/plugins/beautifier/beautifierabstracttool.h
new file mode 100644
index 0000000000000000000000000000000000000000..0dbd6296cf51b0a1a8d5a5e5e9be9d402971e35b
--- /dev/null
+++ b/src/plugins/beautifier/beautifierabstracttool.h
@@ -0,0 +1,57 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_BEAUTIFIERABSTRACTTOOL_H
+#define BEAUTIFIER_BEAUTIFIERABSTRACTTOOL_H
+
+#include
+#include
+
+namespace Core { class IEditor; }
+
+namespace Beautifier {
+namespace Internal {
+
+class BeautifierAbstractTool : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit BeautifierAbstractTool(QObject *parent = 0) : QObject(parent) {}
+ virtual ~BeautifierAbstractTool() {}
+
+ virtual bool initialize() = 0;
+ virtual void updateActions(Core::IEditor *editor) = 0;
+ virtual QList autoReleaseObjects() = 0;
+};
+
+} // namespace Internal
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_BEAUTIFIERABSTRACTTOOL_H
diff --git a/src/plugins/beautifier/beautifierconstants.h b/src/plugins/beautifier/beautifierconstants.h
new file mode 100644
index 0000000000000000000000000000000000000000..f317a14ddff3a73868039bfdc22910c70e62e68f
--- /dev/null
+++ b/src/plugins/beautifier/beautifierconstants.h
@@ -0,0 +1,56 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_BEAUTIFIERCONSTANTS_H
+#define BEAUTIFIER_BEAUTIFIERCONSTANTS_H
+
+#include
+
+namespace Beautifier {
+namespace Constants {
+
+const char ACTION_ID[] = "Beautifier.Action";
+const char MENU_ID[] = "Beautifier.Menu";
+const char OPTION_CATEGORY[] = "II.Beautifier";
+const char OPTION_TR_CATEGORY[] = QT_TRANSLATE_NOOP("Beautifier", "Beautifier");
+const char OPTION_CATEGORY_ICON[] = ":/categoryicon";
+const char SETTINGS_GROUP[] = "Beautifier";
+const char SETTINGS_DIRNAME[] = "beautifier";
+const char DOCUMENTATION_DIRNAME[] = "documentation";
+const char DOCUMENTATION_XMLROOT[] = "beautifier_documentation";
+const char DOCUMENTATION_XMLENTRY[] = "entry";
+const char DOCUMENTATION_XMLKEYS[] = "keys";
+const char DOCUMENTATION_XMLKEY[] = "key";
+const char DOCUMENTATION_XMLDOC[] = "doc";
+
+} // namespace Constants
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_BEAUTIFIERCONSTANTS_H
+
diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..abf8e16b38e7c1baef7fe5fc2af99b836d7867d8
--- /dev/null
+++ b/src/plugins/beautifier/beautifierplugin.cpp
@@ -0,0 +1,296 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "beautifierplugin.h"
+
+#include "beautifierconstants.h"
+#include "artisticstyle/artisticstyle.h"
+#include "clangformat/clangformat.h"
+#include "uncrustify/uncrustify.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace Beautifier {
+namespace Internal {
+
+BeautifierPlugin::BeautifierPlugin()
+{
+}
+
+BeautifierPlugin::~BeautifierPlugin()
+{
+}
+
+bool BeautifierPlugin::initialize(const QStringList &arguments, QString *errorString)
+{
+ Q_UNUSED(arguments)
+ 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);
+ menu->menu()->setTitle(QLatin1String("Beautifier"));
+ Core::ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu);
+
+ for (int i = 0, total = m_tools.count(); i < total; ++i) {
+ BeautifierAbstractTool *tool = m_tools.at(i);
+ tool->initialize();
+ const QList autoReleasedObjects = tool->autoReleaseObjects();
+ for (int j = 0, total = autoReleasedObjects.count(); j < total; ++j)
+ addAutoReleasedObject(autoReleasedObjects.at(j));
+ }
+
+ // The single shot is needed, otherwise the menu will stay disabled even
+ // when the submenu's actions get enabled later on.
+ QTimer::singleShot(0, this, SLOT(updateActions()));
+ return true;
+}
+
+void BeautifierPlugin::extensionsInitialized()
+{
+ if (const Core::EditorManager *editorManager = Core::EditorManager::instance()) {
+ connect(editorManager, SIGNAL(currentEditorChanged(Core::IEditor *)),
+ this, SLOT(updateActions(Core::IEditor *)));
+ }
+}
+
+ExtensionSystem::IPlugin::ShutdownFlag BeautifierPlugin::aboutToShutdown()
+{
+ return SynchronousShutdown;
+}
+
+void BeautifierPlugin::updateActions(Core::IEditor *editor)
+{
+ for (int i = 0, total = m_tools.count(); i < total; ++i)
+ m_tools.at(i)->updateActions(editor);
+}
+
+QString BeautifierPlugin::format(const QString &text, QStringList command, const QString &fileName)
+{
+ if (command.isEmpty())
+ return QString();
+
+ // Save text to temporary file
+ QFileInfo fi(fileName);
+ Utils::TempFileSaver sourceFile(QLatin1String("qtc_beautifier_XXXXXXXX.") + fi.suffix());
+ sourceFile.setAutoRemove(true);
+ sourceFile.write(text.toUtf8());
+ if (!sourceFile.finalize()) {
+ showError(tr("Couldn't create temporary file %1: %2.")
+ .arg(sourceFile.fileName()).arg(sourceFile.errorString()));
+ return QString();
+ }
+
+ // Format temporary file
+ QProcess process;
+ command.replaceInStrings(QLatin1String("%file"), sourceFile.fileName());
+ process.start(command.takeFirst(), command);
+ if (!process.waitForFinished()) {
+ showError(tr("Failed to call %1 or an error occurred.").arg(process.program()));
+ return QString();
+ }
+ const QByteArray output = process.readAllStandardError();
+ if (!output.isEmpty())
+ showError(process.program() + QLatin1String(": ") + QString::fromLocal8Bit(output));
+
+ // Read text back
+ Utils::FileReader reader;
+ if (!reader.fetch(sourceFile.fileName(), QIODevice::Text)) {
+ showError(tr("Couldn't read file %1: %2.")
+ .arg(sourceFile.fileName()).arg(reader.errorString()));
+ return QString();
+ }
+ return QString::fromUtf8(reader.data());
+}
+
+void BeautifierPlugin::formatCurrentFile(QStringList command)
+{
+ QPlainTextEdit *textEditor = 0;
+ if (TextEditor::BaseTextEditor *editor
+ = qobject_cast(Core::EditorManager::currentEditor()))
+ textEditor = qobject_cast(editor->editorWidget());
+ if (!textEditor)
+ return;
+
+ const QString sourceData = textEditor->toPlainText();
+ if (sourceData.isEmpty())
+ return;
+
+ const QString formattedData = format(sourceData, command,
+ Core::EditorManager::currentDocument()->filePath());
+ if ((sourceData == formattedData) || formattedData.isEmpty())
+ return;
+
+ // Since QTextCursor does not work properly with folded blocks, all blocks must be unfolded.
+ // To restore the current state at the end, keep track of which block is folded.
+ QList foldedBlocks;
+ QTextBlock block = textEditor->document()->firstBlock();
+ while (block.isValid()) {
+ if (const TextEditor::TextBlockUserData *userdata
+ = static_cast(block.userData())) {
+ if (userdata->folded()) {
+ foldedBlocks << block.blockNumber();
+ TextEditor::BaseTextDocumentLayout::doFoldOrUnfold(block, true);
+ }
+ }
+ block = block.next();
+ }
+ textEditor->update();
+
+ // Save the current viewport position of the cursor to ensure the same vertical position after
+ // the formatted text has set to the editor.
+ int absoluteVerticalCursorOffset = textEditor->cursorRect().y();
+
+ // Calculate diff
+ DiffEditor::Differ differ;
+ const QList diff = differ.diff(sourceData, formattedData);
+
+ // Update changed lines and keep track of the cursor position
+ QTextCursor cursor = textEditor->textCursor();
+ int charactersInfrontOfCursor = cursor.position();
+ int newCursorPos = charactersInfrontOfCursor;
+ cursor.beginEditBlock();
+ cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
+ const int diffSize = diff.size();
+ for (int i = 0; i < diffSize; ++i) {
+ const DiffEditor::Diff d = diff.at(i);
+ switch (d.command) {
+ case DiffEditor::Diff::Insert:
+ {
+ // Adjust cursor position if we do work in front of the cursor.
+ if (charactersInfrontOfCursor > 0) {
+ const int size = d.text.size();
+ charactersInfrontOfCursor += size;
+ newCursorPos += size;
+ }
+ // Adjust folded blocks, if a new block is added.
+ if (d.text.contains(QLatin1Char('\n'))) {
+ const int newLineCount = d.text.count(QLatin1Char('\n'));
+ const int number = cursor.blockNumber();
+ const int total = foldedBlocks.size();
+ for (int i = 0; i < total; ++i) {
+ if (foldedBlocks.at(i) > number)
+ foldedBlocks[i] += newLineCount;
+ }
+ }
+ cursor.insertText(d.text);
+ }
+ break;
+ case DiffEditor::Diff::Delete:
+ {
+ // Adjust cursor position if we do work in front of the cursor.
+ if (charactersInfrontOfCursor > 0) {
+ const int size = d.text.size();
+ charactersInfrontOfCursor -= size;
+ newCursorPos -= size;
+ // Cursor was inside the deleted text, so adjust the new cursor position
+ if (charactersInfrontOfCursor < 0)
+ newCursorPos -= charactersInfrontOfCursor;
+ }
+ // Adjust folded blocks, if at least one block is being deleted.
+ if (d.text.contains(QLatin1Char('\n'))) {
+ const int newLineCount = d.text.count(QLatin1Char('\n'));
+ const int number = cursor.blockNumber();
+ for (int i = 0, total = foldedBlocks.size(); i < total; ++i) {
+ if (foldedBlocks.at(i) > number) {
+ foldedBlocks[i] -= newLineCount;
+ if (foldedBlocks[i] < number) {
+ foldedBlocks.removeAt(i);
+ --i;
+ --total;
+ }
+ }
+ }
+ }
+ cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, d.text.size());
+ cursor.removeSelectedText();
+ }
+ break;
+ case DiffEditor::Diff::Equal:
+ // Adjust cursor position
+ charactersInfrontOfCursor -= d.text.size();
+ cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, d.text.size());
+ break;
+ }
+ }
+ cursor.endEditBlock();
+ cursor.setPosition(newCursorPos);
+ textEditor->setTextCursor(cursor);
+
+ // Adjust vertical scrollbar
+ absoluteVerticalCursorOffset = textEditor->cursorRect().y() - absoluteVerticalCursorOffset;
+ const double fontHeight = QFontMetrics(textEditor->document()->defaultFont()).height();
+ textEditor->verticalScrollBar()->setValue(textEditor->verticalScrollBar()->value()
+ + absoluteVerticalCursorOffset / fontHeight);
+ // Restore folded blocks
+ const QTextDocument *doc = textEditor->document();
+ const int total = foldedBlocks.size();
+ for (int i = 0; i < total; ++i) {
+ QTextBlock block = doc->findBlockByNumber(qMax(0, foldedBlocks.at(i)));
+ if (block.isValid())
+ TextEditor::BaseTextDocumentLayout::doFoldOrUnfold(block, false);
+ }
+
+ textEditor->document()->setModified(true);
+}
+
+void BeautifierPlugin::showError(const QString &error)
+{
+ Core::MessageManager::write(tr("ERROR in Beautifier: %1").arg(error.trimmed()));
+}
+
+} // namespace Internal
+} // namespace Beautifier
+
+Q_EXPORT_PLUGIN(Beautifier::Internal::BeautifierPlugin)
diff --git a/src/plugins/beautifier/beautifierplugin.h b/src/plugins/beautifier/beautifierplugin.h
new file mode 100644
index 0000000000000000000000000000000000000000..2e4910e042323780647b17521c6c553d53934872
--- /dev/null
+++ b/src/plugins/beautifier/beautifierplugin.h
@@ -0,0 +1,70 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_BEAUTIFIER_H
+#define BEAUTIFIER_BEAUTIFIER_H
+
+#include
+#include
+
+namespace Core { class IEditor; }
+
+namespace Beautifier {
+namespace Internal {
+
+class BeautifierAbstractTool;
+
+class BeautifierPlugin : public ExtensionSystem::IPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Beautifier.json")
+
+public:
+ BeautifierPlugin();
+ ~BeautifierPlugin();
+ bool initialize(const QStringList &arguments, QString *errorString) QTC_OVERRIDE;
+ void extensionsInitialized() QTC_OVERRIDE;
+ ShutdownFlag aboutToShutdown() QTC_OVERRIDE;
+
+ static QString format(const QString &text, QStringList command, const QString &fileName);
+ static void formatCurrentFile(QStringList command);
+ static void showError(const QString &error);
+
+private slots:
+ void updateActions(Core::IEditor *editor = 0);
+
+private:
+ QList m_tools;
+};
+
+} // namespace Internal
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_BEAUTIFIER_H
+
diff --git a/src/plugins/beautifier/clangformat/clangformat.cpp b/src/plugins/beautifier/clangformat/clangformat.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5c6f929cbb543dfe75883f9e1877c9362587f458
--- /dev/null
+++ b/src/plugins/beautifier/clangformat/clangformat.cpp
@@ -0,0 +1,149 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "clangformat.h"
+
+#include "clangformatconstants.h"
+#include "clangformatoptionspage.h"
+#include "clangformatsettings.h"
+
+#include "../beautifierconstants.h"
+#include "../beautifierplugin.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+namespace Beautifier {
+namespace Internal {
+namespace ClangFormat {
+
+ClangFormat::ClangFormat(QObject *parent) :
+ BeautifierAbstractTool(parent),
+ m_settings(new ClangFormatSettings)
+{
+}
+
+ClangFormat::~ClangFormat()
+{
+ delete m_settings;
+}
+
+bool ClangFormat::initialize()
+{
+ Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::ClangFormat::MENU_ID);
+ menu->menu()->setTitle(QLatin1String("ClangFormat"));
+
+ m_formatFile = new QAction(tr("Format Current File"), this);
+ Core::Command *cmd
+ = Core::ActionManager::registerAction(m_formatFile,
+ Constants::ClangFormat::ACTION_FORMATFILE,
+ Core::Context(Core::Constants::C_GLOBAL));
+ menu->addAction(cmd);
+ connect(m_formatFile, SIGNAL(triggered()), this, SLOT(formatFile()));
+
+ m_formatRange = new QAction(tr("Format Selected Text"), this);
+ cmd = Core::ActionManager::registerAction(m_formatRange,
+ Constants::ClangFormat::ACTION_FORMATSELECTED,
+ Core::Context(Core::Constants::C_GLOBAL));
+ menu->addAction(cmd);
+ connect(m_formatRange, SIGNAL(triggered()), this, SLOT(formatSelectedText()));
+
+ Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu);
+
+ return true;
+}
+
+void ClangFormat::updateActions(Core::IEditor *editor)
+{
+ const bool enabled = (editor && editor->id() == CppEditor::Constants::CPPEDITOR_ID);
+ m_formatFile->setEnabled(enabled);
+ m_formatRange->setEnabled(enabled);
+}
+
+QList ClangFormat::autoReleaseObjects()
+{
+ ClangFormatOptionsPage *optionsPage = new ClangFormatOptionsPage(m_settings, this);
+ return QList() << optionsPage;
+}
+
+void ClangFormat::formatFile()
+{
+ BeautifierPlugin::formatCurrentFile(command());
+}
+
+void ClangFormat::formatSelectedText()
+{
+ TextEditor::BaseTextEditor *editor
+ = qobject_cast(Core::EditorManager::currentEditor());
+ if (!editor)
+ return;
+
+ QTextCursor tc = editor->editorWidget()->textCursor();
+ if (tc.hasSelection()) {
+ const int offset = tc.selectionStart();
+ const int length = tc.selectionEnd() - offset;
+ BeautifierPlugin::formatCurrentFile(command(offset, length));
+ } else if (m_settings->formatEntireFileFallback()) {
+ formatFile();
+ }
+}
+
+QStringList ClangFormat::command(int offset, int length) const
+{
+ QStringList command;
+ command << m_settings->command();
+ command << QLatin1String("-i");
+ if (m_settings->usePredefinedStyle()) {
+ command << QLatin1String("-style=") + m_settings->predefinedStyle();
+ } else {
+ command << QLatin1String("-style={") + m_settings->style(
+ m_settings->customStyle()).remove(QLatin1Char('\n')) + QLatin1String("}");
+ }
+ if (offset != -1) {
+ command << QLatin1String("-offset=") + QString::number(offset);
+ command << QLatin1String("-length=") + QString::number(length);
+ }
+ command << QLatin1String("%file");
+
+ return command;
+}
+
+} // namespace ClangFormat
+} // namespace Internal
+} // namespace Beautifier
diff --git a/src/plugins/beautifier/clangformat/clangformat.h b/src/plugins/beautifier/clangformat/clangformat.h
new file mode 100644
index 0000000000000000000000000000000000000000..6424f0aa383ddf42fcc2ba26d0437117071e4c37
--- /dev/null
+++ b/src/plugins/beautifier/clangformat/clangformat.h
@@ -0,0 +1,71 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_CLANGFORMAT_H
+#define BEAUTIFIER_CLANGFORMAT_H
+
+#include "../beautifierabstracttool.h"
+
+#include
+
+QT_FORWARD_DECLARE_CLASS(QAction)
+
+namespace Beautifier {
+namespace Internal {
+namespace ClangFormat {
+
+class ClangFormatSettings;
+
+class ClangFormat : public BeautifierAbstractTool
+{
+ Q_OBJECT
+
+public:
+ explicit ClangFormat(QObject *parent = 0);
+ virtual ~ClangFormat();
+ bool initialize() QTC_OVERRIDE;
+ void updateActions(Core::IEditor *editor) QTC_OVERRIDE;
+ QList autoReleaseObjects() QTC_OVERRIDE;
+
+private slots:
+ void formatFile();
+ void formatSelectedText();
+
+private:
+ QAction *m_formatFile;
+ QAction *m_formatRange;
+ ClangFormatSettings *m_settings;
+ QStringList command(int offset = -1, int length = -1) const;
+};
+
+} // namespace ClangFormat
+} // namespace Internal
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_CLANGFORMAT_H
diff --git a/src/plugins/beautifier/clangformat/clangformatconstants.h b/src/plugins/beautifier/clangformat/clangformatconstants.h
new file mode 100644
index 0000000000000000000000000000000000000000..844da37b7874ad5b1f52dab0b031a09aa6410eaf
--- /dev/null
+++ b/src/plugins/beautifier/clangformat/clangformatconstants.h
@@ -0,0 +1,47 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_CLANGFORMATCONSTANTS_H
+#define BEAUTIFIER_CLANGFORMATCONSTANTS_H
+
+namespace Beautifier {
+namespace Constants {
+namespace ClangFormat {
+
+const char ACTION_FORMATFILE[] = "ClangFormat.FormatFile";
+const char ACTION_FORMATSELECTED[] = "ClangFormat.FormatSelectedText";
+const char MENU_ID[] = "ClangFormat.Menu";
+const char OPTION_ID[] = "ClangFormat";
+const char SETTINGS_NAME[] = "clangformat";
+
+} // namespace ClangFormat
+} // namespace Constants
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_CLANGFORMATCONSTANTS_H
diff --git a/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp b/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b8ea14477bd66b365f8a2dbd9cd625cbc65933f8
--- /dev/null
+++ b/src/plugins/beautifier/clangformat/clangformatoptionspage.cpp
@@ -0,0 +1,150 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "clangformatoptionspage.h"
+#include "ui_clangformatoptionspage.h"
+
+#include "clangformatconstants.h"
+#include "clangformatsettings.h"
+
+#include "../beautifierconstants.h"
+
+#include
+
+#include
+
+namespace Beautifier {
+namespace Internal {
+namespace ClangFormat {
+
+ClangFormatOptionsPageWidget::ClangFormatOptionsPageWidget(ClangFormatSettings *settings,
+ QWidget *parent)
+ : QWidget(parent)
+ , ui(new Ui::ClangFormatOptionsPage)
+ , m_settings(settings)
+{
+ ui->setupUi(this);
+ ui->options->setEnabled(false);
+ ui->predefinedStyle->addItems(m_settings->predefinedStyles());
+ ui->command->setExpectedKind(Utils::PathChooser::ExistingCommand);
+ ui->command->setPromptDialogTitle(tr("ClangFormat Command"));
+ connect(ui->command, SIGNAL(validChanged(bool)), ui->options, SLOT(setEnabled(bool)));
+ ui->configurations->setSettings(m_settings);
+}
+
+ClangFormatOptionsPageWidget::~ClangFormatOptionsPageWidget()
+{
+ delete ui;
+}
+
+QString ClangFormatOptionsPageWidget::searchKeywords() const
+{
+ QString keywords;
+ const QLatin1Char sep(' ');
+ QTextStream(&keywords) << sep << ui->configuration->title()
+ << sep << ui->commandLabel->text()
+ << sep << ui->options->title()
+ << sep << ui->usePredefinedStyle->text()
+ << sep << ui->useCustomizedStyle->text()
+ << sep << ui->formatEntireFileFallback->text();
+ keywords.remove(QLatin1Char('&'));
+ return keywords;
+}
+
+void ClangFormatOptionsPageWidget::restore()
+{
+ ui->command->setPath(m_settings->command());
+ ui->predefinedStyle->setCurrentText(m_settings->predefinedStyle());
+ ui->formatEntireFileFallback->setChecked(m_settings->formatEntireFileFallback());
+ ui->configurations->setSettings(m_settings);
+ ui->configurations->setCurrentConfiguration(m_settings->customStyle());
+
+ if (m_settings->usePredefinedStyle())
+ ui->usePredefinedStyle->setChecked(true);
+ else
+ ui->useCustomizedStyle->setChecked(true);
+}
+
+void ClangFormatOptionsPageWidget::apply()
+{
+ m_settings->setCommand(ui->command->path());
+ 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();
+}
+
+/* ---------------------------------------------------------------------------------------------- */
+
+ClangFormatOptionsPage::ClangFormatOptionsPage(ClangFormatSettings *settings, QObject *parent) :
+ IOptionsPage(parent),
+ m_widget(0),
+ m_settings(settings),
+ m_searchKeywords()
+{
+ setId(Constants::ClangFormat::OPTION_ID);
+ setDisplayName(tr("ClangFormat"));
+ setCategory(Constants::OPTION_CATEGORY);
+ setDisplayCategory(QCoreApplication::translate("Beautifier", Constants::OPTION_TR_CATEGORY));
+ setCategoryIcon(QLatin1String(Constants::OPTION_CATEGORY_ICON));
+}
+
+QWidget *ClangFormatOptionsPage::widget()
+{
+ m_settings->read();
+
+ if (!m_widget) {
+ m_widget = new ClangFormatOptionsPageWidget(m_settings);
+ if (m_searchKeywords.isEmpty())
+ m_searchKeywords = m_widget->searchKeywords();
+ }
+ m_widget->restore();
+
+ return m_widget;
+}
+
+void ClangFormatOptionsPage::apply()
+{
+ if (m_widget)
+ m_widget->apply();
+}
+
+void ClangFormatOptionsPage::finish()
+{
+}
+
+bool ClangFormatOptionsPage::matches(const QString &searchKeyWord) const
+{
+ return m_searchKeywords.contains(searchKeyWord, Qt::CaseInsensitive);
+}
+
+} // namespace ClangFormat
+} // namespace Internal
+} // namespace Beautifier
diff --git a/src/plugins/beautifier/clangformat/clangformatoptionspage.h b/src/plugins/beautifier/clangformat/clangformatoptionspage.h
new file mode 100644
index 0000000000000000000000000000000000000000..777037a14afa51e2444ba3bb34fe0549d87f9436
--- /dev/null
+++ b/src/plugins/beautifier/clangformat/clangformatoptionspage.h
@@ -0,0 +1,84 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_CLANGFORMATOPTIONSPAGE_H
+#define BEAUTIFIER_CLANGFORMATOPTIONSPAGE_H
+
+#include
+#include
+
+#include
+#include
+
+namespace Beautifier {
+namespace Internal {
+namespace ClangFormat {
+
+class ClangFormatSettings;
+
+namespace Ui { class ClangFormatOptionsPage; }
+
+class ClangFormatOptionsPageWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ClangFormatOptionsPageWidget(ClangFormatSettings *settings, QWidget *parent = 0);
+ virtual ~ClangFormatOptionsPageWidget();
+ QString searchKeywords() const;
+ void restore();
+ void apply();
+
+private:
+ Ui::ClangFormatOptionsPage *ui;
+ ClangFormatSettings *m_settings;
+};
+
+class ClangFormatOptionsPage : public Core::IOptionsPage
+{
+ Q_OBJECT
+
+public:
+ explicit ClangFormatOptionsPage(ClangFormatSettings *settings, QObject *parent = 0);
+ QWidget *widget() QTC_OVERRIDE;
+ void apply() QTC_OVERRIDE;
+ void finish() QTC_OVERRIDE;
+ bool matches(const QString &searchKeywords) const QTC_OVERRIDE;
+
+private:
+ QPointer m_widget;
+ ClangFormatSettings *m_settings;
+ QString m_searchKeywords;
+};
+
+} // namespace ClangFormat
+} // namespace Internal
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_CLANGFORMATOPTIONSPAGE_H
diff --git a/src/plugins/beautifier/clangformat/clangformatoptionspage.ui b/src/plugins/beautifier/clangformat/clangformatoptionspage.ui
new file mode 100644
index 0000000000000000000000000000000000000000..7a06b29e30a13b0b4b5499edb406f042f483c029
--- /dev/null
+++ b/src/plugins/beautifier/clangformat/clangformatoptionspage.ui
@@ -0,0 +1,132 @@
+
+
+ Beautifier::Internal::ClangFormat::ClangFormatOptionsPage
+
+
+
+ 0
+ 0
+ 817
+ 631
+
+
+
+ Form
+
+
+ -
+
+
+ Configuration
+
+
+
-
+
+
+ ClangFormat command:
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ Options
+
+
+
+ QFormLayout::AllNonFixedFieldsGrow
+
+
-
+
+
+ Use Predefined Style:
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+ -
+
+
+ Use Customized Style:
+
+
+ true
+
+
+
+ -
+
+
+ -
+
+
+ Format entire file if no text was selected. (For action "Format Selected Text")
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ Utils::PathChooser
+ QWidget
+
+ 1
+
+
+ Beautifier::Internal::ConfigurationPanel
+ QWidget
+ beautifier/configurationpanel.h
+ 1
+
+
+
+
+
+ usePredefinedStyle
+ toggled(bool)
+ predefinedStyle
+ setEnabled(bool)
+
+
+ 67
+ 108
+
+
+ 240
+ 113
+
+
+
+
+
diff --git a/src/plugins/beautifier/clangformat/clangformatsettings.cpp b/src/plugins/beautifier/clangformat/clangformatsettings.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..795411a5b21d31e0fe16fe5ad68f3f2f6cd295c0
--- /dev/null
+++ b/src/plugins/beautifier/clangformat/clangformatsettings.cpp
@@ -0,0 +1,236 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "clangformatsettings.h"
+
+#include "clangformatconstants.h"
+
+#include "../beautifierconstants.h"
+
+#include
+#include
+
+#include
+
+namespace Beautifier {
+namespace Internal {
+namespace ClangFormat {
+
+namespace {
+const char kUsePredefinedStyle[] = "usePredefinedStyle";
+const char kPredefinedStyle[] = "predefinedStyle";
+const char kCustomStyle[] = "customStyle";
+const char kFormatEntireFileFallback[] = "formatEntireFileFallback";
+}
+
+ClangFormatSettings::ClangFormatSettings() :
+ AbstractSettings(QLatin1String(Constants::ClangFormat::SETTINGS_NAME),
+ QLatin1String(".clang-format"))
+
+{
+ setCommand(QLatin1String("clang-format"));
+ m_settings.insert(QLatin1String(kUsePredefinedStyle), QVariant(true));
+ m_settings.insert(QLatin1String(kPredefinedStyle), QLatin1String("LLVM"));
+ m_settings.insert(QLatin1String(kCustomStyle), QVariant());
+ m_settings.insert(QLatin1String(kFormatEntireFileFallback), QVariant(true));
+ read();
+}
+
+QString ClangFormatSettings::documentationFilePath() const
+{
+ return Core::ICore::userResourcePath() + QLatin1Char('/')
+ + QLatin1String(Beautifier::Constants::SETTINGS_DIRNAME) + QLatin1Char('/')
+ + QLatin1String(Beautifier::Constants::DOCUMENTATION_DIRNAME) + QLatin1Char('/')
+ + QLatin1String(Constants::ClangFormat::SETTINGS_NAME) + QLatin1String(".xml");
+}
+
+void ClangFormatSettings::createDocumentationFile() const
+{
+ QFile file(documentationFilePath());
+ const QFileInfo fi(file);
+ if (!fi.exists())
+ fi.dir().mkpath(fi.absolutePath());
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
+ return;
+
+ QXmlStreamWriter stream(&file);
+ stream.setAutoFormatting(true);
+ stream.writeStartDocument(QLatin1String("1.0"), true);
+ stream.writeComment(QLatin1String("Created ")
+ + QDateTime::currentDateTime().toString(Qt::ISODate));
+ stream.writeStartElement(QLatin1String(Constants::DOCUMENTATION_XMLROOT));
+
+ const QStringList lines = QStringList()
+ << QLatin1String("BasedOnStyle {string: LLVM, Google, Chromium, Mozilla, WebKit}")
+ << QLatin1String("AccessModifierOffset {int}")
+ << QLatin1String("AlignEscapedNewlinesLeft {bool}")
+ << QLatin1String("AlignTrailingComments {bool}")
+ << QLatin1String("AllowAllParametersOfDeclarationOnNextLine {bool}")
+ << QLatin1String("AllowShortFunctionsOnASingleLine {bool}")
+ << QLatin1String("AllowShortIfStatementsOnASingleLine {bool}")
+ << QLatin1String("AllowShortLoopsOnASingleLine {bool}")
+ << QLatin1String("AlwaysBreakBeforeMultilineStrings {bool}")
+ << QLatin1String("AlwaysBreakTemplateDeclarations {bool}")
+ << QLatin1String("BinPackParameters {bool}")
+ << QLatin1String("BreakBeforeBinaryOperators {bool}")
+ << QLatin1String("BreakBeforeBraces {BraceBreakingStyle: BS_Attach, BS_Linux, BS_Stroustrup, BS_Allman, BS_GNU}")
+ << QLatin1String("BreakBeforeTernaryOperators {bool}")
+ << QLatin1String("BreakConstructorInitializersBeforeComma {bool}")
+ << QLatin1String("ColumnLimit {unsigned}")
+ << QLatin1String("CommentPragmas {string}")
+ << QLatin1String("ConstructorInitializerAllOnOneLineOrOnePerLine {bool}")
+ << QLatin1String("ConstructorInitializerIndentWidth {unsigned}")
+ << QLatin1String("ContinuationIndentWidth {unsigned}")
+ << QLatin1String("Cpp11BracedListStyle {bool}")
+ << QLatin1String("IndentCaseLabels {bool}")
+ << QLatin1String("IndentFunctionDeclarationAfterType {bool}")
+ << QLatin1String("IndentWidth {unsigned}")
+ << QLatin1String("Language {LanguageKind: LK_None, LK_Cpp, LK_JavaScript, LK_Proto}")
+ << QLatin1String("MaxEmptyLinesToKeep {unsigned}")
+ << QLatin1String("NamespaceIndentation {NamespaceIndentationKind: NI_None, NI_Inner, NI_All}")
+ << QLatin1String("ObjCSpaceAfterProperty {bool}")
+ << QLatin1String("ObjCSpaceBeforeProtocolList {bool}")
+ << QLatin1String("PenaltyBreakBeforeFirstCallParameter {unsigned}")
+ << QLatin1String("PenaltyBreakComment {unsigned}")
+ << QLatin1String("PenaltyBreakFirstLessLess {unsigned}")
+ << QLatin1String("PenaltyBreakString {unsigned}")
+ << QLatin1String("PenaltyExcessCharacter {unsigned}")
+ << QLatin1String("PenaltyReturnTypeOnItsOwnLine {unsigned}")
+ << QLatin1String("PointerBindsToType {bool}")
+ << QLatin1String("SpaceBeforeAssignmentOperators {bool}")
+ << QLatin1String("SpaceBeforeParens {SpaceBeforeParensOptions: SBPO_Never, SBPO_ControlStatements, SBPO_Always}")
+ << QLatin1String("SpaceInEmptyParentheses {bool}")
+ << QLatin1String("SpacesBeforeTrailingComments {unsigned}")
+ << QLatin1String("SpacesInAngles {bool}")
+ << QLatin1String("SpacesInCStyleCastParentheses {bool}")
+ << QLatin1String("SpacesInContainerLiterals {bool}")
+ << QLatin1String("SpacesInParentheses {bool}")
+ << QLatin1String("Standard {LanguageStandard: LS_Cpp03, LS_Cpp11, LS_Auto}")
+ << QLatin1String("TabWidth {unsigned}")
+ << QLatin1String("UseTab {UseTabStyle: UT_Never, UT_ForIndentation, UT_Always}");
+
+ const int totalLines = lines.count();
+ for (int i = 0; i < totalLines; ++i) {
+ const QString& line = lines.at(i);
+ const int firstSpace = line.indexOf(QLatin1Char(' '));
+ const QString keyword = line.left(firstSpace);
+ const QString options = line.right(line.size() - firstSpace).trimmed();
+ const QString text = QLatin1String("") + keyword
+ + QLatin1String(" ") + options
+ + QLatin1String("
") + tr("Yet no description available.")
+ + QLatin1String("
");
+ stream.writeStartElement(QLatin1String(Constants::DOCUMENTATION_XMLENTRY));
+ stream.writeTextElement(QLatin1String(Constants::DOCUMENTATION_XMLKEY), keyword);
+ stream.writeTextElement(QLatin1String(Constants::DOCUMENTATION_XMLDOC), text);
+ stream.writeEndElement();
+ }
+
+ stream.writeEndElement();
+ stream.writeEndDocument();
+}
+
+QStringList ClangFormatSettings::completerWords()
+{
+ QStringList words;
+ words << QLatin1String("LLVM")
+ << QLatin1String("Google")
+ << QLatin1String("Chromium")
+ << QLatin1String("Mozilla")
+ << QLatin1String("WebKit")
+ << QLatin1String("BS_Attach")
+ << QLatin1String("BS_Linux")
+ << QLatin1String("BS_Stroustrup")
+ << QLatin1String("BS_Allman")
+ << QLatin1String("NI_None")
+ << QLatin1String("NI_Inner")
+ << QLatin1String("NI_All")
+ << QLatin1String("LS_Cpp03")
+ << QLatin1String("LS_Cpp11")
+ << QLatin1String("LS_Auto")
+ << QLatin1String("UT_Never")
+ << QLatin1String("UT_ForIndentation")
+ << QLatin1String("UT_Always");
+ return words;
+}
+
+bool ClangFormatSettings::usePredefinedStyle() const
+{
+ return m_settings.value(QLatin1String(kUsePredefinedStyle)).toBool();
+}
+
+void ClangFormatSettings::setUsePredefinedStyle(bool usePredefinedStyle)
+{
+ m_settings.insert(QLatin1String(kUsePredefinedStyle), QVariant(usePredefinedStyle));
+}
+
+QString ClangFormatSettings::predefinedStyle() const
+{
+ return m_settings.value(QLatin1String(kPredefinedStyle)).toString();
+}
+
+void ClangFormatSettings::setPredefinedStyle(const QString &predefinedStyle)
+{
+ const QStringList test = predefinedStyles();
+ if (test.contains(predefinedStyle))
+ m_settings.insert(QLatin1String(kPredefinedStyle), QVariant(predefinedStyle));
+}
+
+QString ClangFormatSettings::customStyle() const
+{
+ return m_settings.value(QLatin1String(kCustomStyle)).toString();
+}
+
+void ClangFormatSettings::setCustomStyle(const QString &customStyle)
+{
+ m_settings.insert(QLatin1String(kCustomStyle), QVariant(customStyle));
+}
+
+bool ClangFormatSettings::formatEntireFileFallback() const
+{
+ return m_settings.value(QLatin1String(kFormatEntireFileFallback)).toBool();
+}
+
+void ClangFormatSettings::setFormatEntireFileFallback(bool formatEntireFileFallback)
+{
+ m_settings.insert(QLatin1String(kFormatEntireFileFallback), QVariant(formatEntireFileFallback));
+}
+
+QStringList ClangFormatSettings::predefinedStyles() const
+{
+ return QStringList() << QLatin1String("LLVM")
+ << QLatin1String("Google")
+ << QLatin1String("Chromium")
+ << QLatin1String("Mozilla")
+ << QLatin1String("WebKit")
+ << QLatin1String("File");
+}
+
+} // namespace ClangFormat
+} // namespace Internal
+} // namespace Beautifier
diff --git a/src/plugins/beautifier/clangformat/clangformatsettings.h b/src/plugins/beautifier/clangformat/clangformatsettings.h
new file mode 100644
index 0000000000000000000000000000000000000000..39931d131cdb704132f7fd04b1da6d5ca4fadc6f
--- /dev/null
+++ b/src/plugins/beautifier/clangformat/clangformatsettings.h
@@ -0,0 +1,71 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_CLANGFORMATSETTINGS_H
+#define BEAUTIFIER_CLANGFORMATSETTINGS_H
+
+#include "../abstractsettings.h"
+
+#include
+
+namespace Beautifier {
+namespace Internal {
+namespace ClangFormat {
+
+class ClangFormatSettings : public AbstractSettings
+{
+ Q_DECLARE_TR_FUNCTIONS(ClangFormatSettings)
+
+public:
+ explicit ClangFormatSettings();
+
+ QString documentationFilePath() const QTC_OVERRIDE;
+ void createDocumentationFile() const QTC_OVERRIDE;
+ QStringList completerWords() QTC_OVERRIDE;
+
+ bool usePredefinedStyle() const;
+ void setUsePredefinedStyle(bool usePredefinedStyle);
+
+ QString predefinedStyle() const;
+ void setPredefinedStyle(const QString &predefinedStyle);
+
+ QString customStyle() const;
+ void setCustomStyle(const QString &customStyle);
+
+ bool formatEntireFileFallback() const;
+ void setFormatEntireFileFallback(bool formatEntireFileFallback);
+
+ QStringList predefinedStyles() const;
+};
+
+} // namespace ClangFormat
+} // namespace Internal
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_CLANGFORMATSETTINGS_H
diff --git a/src/plugins/beautifier/configurationdialog.cpp b/src/plugins/beautifier/configurationdialog.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e0e9e538f6d5d3ed01bdd30d3a96f43d9bc3f9a3
--- /dev/null
+++ b/src/plugins/beautifier/configurationdialog.cpp
@@ -0,0 +1,155 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "configurationdialog.h"
+#include "ui_configurationdialog.h"
+
+#include "abstractsettings.h"
+
+#include
+#include
+
+#include
+#include
+
+namespace Beautifier {
+namespace Internal {
+
+ConfigurationDialog::ConfigurationDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::ConfigurationDialog),
+ m_settings(0)
+{
+ ui->setupUi(this);
+
+ // Filter out characters which are not allowed in a file name
+ QRegExpValidator *fileNameValidator = new QRegExpValidator(ui->name);
+ fileNameValidator->setRegExp(QRegExp(QLatin1String("^[^\\/\\\\\\?\\>\\<\\*\\%\\:\\\"\\']*$")));
+ ui->name->setValidator(fileNameValidator);
+
+ updateDocumentation();
+ connect(ui->name, SIGNAL(textChanged(QString)), this, SLOT(updateOkButton()));
+ updateOkButton(); // force initial test.
+ connect(ui->editor, SIGNAL(documentationChanged(QString,QString)),
+ this, SLOT(updateDocumentation(QString,QString)));
+
+ // Set palette and font according to settings
+ const TextEditor::FontSettings fs = TextEditor::TextEditorSettings::instance()->fontSettings();
+ const QTextCharFormat tf = fs.toTextCharFormat(TextEditor::C_TEXT);
+ const QTextCharFormat selectionFormat = fs.toTextCharFormat(TextEditor::C_SELECTION);
+
+ QPalette pal;
+ pal.setColor(QPalette::Base, tf.background().color());
+ pal.setColor(QPalette::Text, tf.foreground().color());
+ pal.setColor(QPalette::Foreground, tf.foreground().color());
+ if (selectionFormat.background().style() != Qt::NoBrush)
+ pal.setColor(QPalette::Highlight, selectionFormat.background().color());
+ pal.setBrush(QPalette::HighlightedText, selectionFormat.foreground());
+ ui->documentation->setPalette(pal);
+ ui->editor->setPalette(pal);
+
+ ui->documentation->setFont(tf.font());
+ ui->editor->setFont(tf.font());
+
+ // Set style sheet for documentation browser
+ const QTextCharFormat tfOption = fs.toTextCharFormat(TextEditor::C_FIELD);
+ const QTextCharFormat tfParam = fs.toTextCharFormat(TextEditor::C_STRING);
+
+ const QString css = QString::fromLatin1("span.param {color: %1; background-color: %2;} "
+ "span.option {color: %3; background-color: %4;} "
+ "p { text-align: justify; } ")
+ .arg(tfParam.foreground().color().name())
+ .arg(tfParam.background().style() == Qt::NoBrush
+ ? QString() : tfParam.background().color().name())
+ .arg(tfOption.foreground().color().name())
+ .arg(tfOption.background().style() == Qt::NoBrush
+ ? QString() : tfOption.background().color().name())
+ ;
+ ui->documentation->document()->setDefaultStyleSheet(css);
+}
+
+ConfigurationDialog::~ConfigurationDialog()
+{
+ delete ui;
+}
+
+void ConfigurationDialog::setSettings(AbstractSettings *settings)
+{
+ m_settings = settings;
+ ui->editor->setSettings(m_settings);
+}
+
+void ConfigurationDialog::clear()
+{
+ ui->name->clear();
+ ui->editor->clear();
+ m_currentKey.clear();
+ updateOkButton();
+}
+
+QString ConfigurationDialog::key() const
+{
+ return ui->name->text().simplified();
+}
+
+void ConfigurationDialog::setKey(const QString &key)
+{
+ m_currentKey = key;
+ ui->name->setText(m_currentKey);
+ if (m_settings)
+ ui->editor->setPlainText(m_settings->style(m_currentKey));
+ else
+ ui->editor->clear();
+}
+
+QString ConfigurationDialog::value() const
+{
+ return ui->editor->toPlainText();
+}
+
+void ConfigurationDialog::updateOkButton()
+{
+ const QString key = ui->name->text().simplified();
+ bool exists = false;
+ if (m_settings && key != m_currentKey)
+ exists = m_settings->styleExists(key);
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!(key.isEmpty() || exists));
+}
+
+void ConfigurationDialog::updateDocumentation(const QString &word, const QString &docu)
+{
+ if (word.isEmpty())
+ ui->documentationHeader->setText(tr("Documentation"));
+ else
+ ui->documentationHeader->setText(tr("Documentation for '%1'").arg(word));
+ ui->documentation->setHtml(docu);
+}
+
+} // namespace Internal
+} // namespace Beautifier
diff --git a/src/plugins/beautifier/configurationdialog.h b/src/plugins/beautifier/configurationdialog.h
new file mode 100644
index 0000000000000000000000000000000000000000..6a924689f5d08956e4574bc7414fa952f12b339f
--- /dev/null
+++ b/src/plugins/beautifier/configurationdialog.h
@@ -0,0 +1,71 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_CONFIGURATIONDIALOG_H
+#define BEAUTIFIER_CONFIGURATIONDIALOG_H
+
+#include
+#include
+
+namespace Beautifier {
+namespace Internal {
+
+class AbstractSettings;
+
+namespace Ui { class ConfigurationDialog; }
+
+class ConfigurationDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit ConfigurationDialog(QWidget *parent = 0);
+ ~ConfigurationDialog();
+ void setSettings(AbstractSettings *settings);
+
+ void clear();
+ QString key() const;
+ void setKey(const QString &key);
+ QString value() const;
+
+private slots:
+ void updateOkButton();
+ void updateDocumentation(const QString &word = QString(), const QString &docu = QString());
+
+private:
+ Ui::ConfigurationDialog *ui;
+ AbstractSettings *m_settings;
+ QString m_currentKey;
+};
+
+
+} // namespace Internal
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_CONFIGURATIONDIALOG_H
diff --git a/src/plugins/beautifier/configurationdialog.ui b/src/plugins/beautifier/configurationdialog.ui
new file mode 100644
index 0000000000000000000000000000000000000000..58df158f835ac7490cdeb1d849a456cec9d718a0
--- /dev/null
+++ b/src/plugins/beautifier/configurationdialog.ui
@@ -0,0 +1,118 @@
+
+
+ Beautifier::Internal::ConfigurationDialog
+
+
+
+ 0
+ 0
+ 640
+ 512
+
+
+
+ -
+
+
+ Name
+
+
+
-
+
+
+
+
+
+ -
+
+
+ Value
+
+
+
-
+
+
+ Qt::Vertical
+
+
+ false
+
+
+
+
+
-
+
+
+ Documentation
+
+
+
+ -
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+ Beautifier::Internal::ConfigurationEditor
+ QPlainTextEdit
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ Beautifier::Internal::ConfigurationDialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ Beautifier::Internal::ConfigurationDialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/src/plugins/beautifier/configurationeditor.cpp b/src/plugins/beautifier/configurationeditor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0fdbeaa38845c29ae7f64089b8c0241b904bab85
--- /dev/null
+++ b/src/plugins/beautifier/configurationeditor.cpp
@@ -0,0 +1,267 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "configurationeditor.h"
+
+#include "abstractsettings.h"
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+namespace Beautifier {
+namespace Internal {
+
+ConfigurationSyntaxHighlighter::ConfigurationSyntaxHighlighter(QTextDocument *parent) :
+ QSyntaxHighlighter(parent)
+{
+ const TextEditor::FontSettings fs = TextEditor::TextEditorSettings::instance()->fontSettings();
+ m_formatKeyword = fs.toTextCharFormat(TextEditor::C_FIELD);
+ m_formatComment = fs.toTextCharFormat(TextEditor::C_COMMENT);
+
+ m_expressionComment.setPattern(QLatin1String("#[^\\n]*"));
+ m_expressionComment.setMinimal(false);
+}
+
+void ConfigurationSyntaxHighlighter::setKeywords(const QStringList &keywords)
+{
+ if (keywords.isEmpty())
+ return;
+
+ QStringList pattern;
+ for (int i = 0, total = keywords.count(); i < total; ++i)
+ pattern << QRegExp::escape(keywords.at(i));
+
+ m_expressionKeyword.setPattern(QLatin1String("(?:\\s|^)(") + pattern.join(QLatin1Char('|'))
+ + QLatin1String(")(?=\\s|\\:|\\=|\\,|$)"));
+}
+
+void ConfigurationSyntaxHighlighter::setCommentExpression(const QRegExp &rx)
+{
+ m_expressionComment = rx;
+}
+
+void ConfigurationSyntaxHighlighter::highlightBlock(const QString &text)
+{
+ int pos = 0;
+ if (!m_expressionKeyword.isEmpty()) {
+ while ((pos = m_expressionKeyword.indexIn(text, pos)) != -1) {
+ const int length = m_expressionKeyword.matchedLength();
+ setFormat(pos, length, m_formatKeyword);
+ pos += length;
+ }
+ }
+
+ if (!m_expressionComment.isEmpty()) {
+ pos = 0;
+ while ((pos = m_expressionComment.indexIn(text, pos)) != -1) {
+ const int length = m_expressionComment.matchedLength();
+ setFormat(pos, length, m_formatComment);
+ pos += length;
+ }
+ }
+}
+
+ConfigurationEditor::ConfigurationEditor(QWidget *parent)
+ : QPlainTextEdit(parent)
+ , m_settings(0)
+ , m_completer(new QCompleter(this))
+ , m_model(new QStringListModel(QStringList(), m_completer))
+ , m_highlighter(new ConfigurationSyntaxHighlighter(document()))
+{
+ m_completer->setModel(m_model);
+ m_completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
+ m_completer->setWrapAround(false);
+ m_completer->setWidget(this);
+ m_completer->setCompletionMode(QCompleter::PopupCompletion);
+ m_completer->setCaseSensitivity(Qt::CaseInsensitive);
+ m_completer->popup()->installEventFilter(this);
+
+ connect(m_completer, SIGNAL(activated(QString)), this, SLOT(insertCompleterText(QString)));
+ connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateDocumentation()));
+}
+
+void ConfigurationEditor::setSettings(AbstractSettings *settings)
+{
+ QTC_CHECK(settings);
+ m_settings = settings;
+
+ QStringList keywords = m_settings->options();
+ m_highlighter->setKeywords(keywords);
+ keywords << m_settings->completerWords();
+ keywords.sort(Qt::CaseInsensitive);
+ m_model->setStringList(keywords);
+}
+
+void ConfigurationEditor::setCommentExpression(const QRegExp &rx)
+{
+ m_highlighter->setCommentExpression(rx);
+}
+
+// Workaround for handling "ESC" right when popup is shown.
+bool ConfigurationEditor::eventFilter(QObject *object, QEvent *event)
+{
+ if (event->type() == QEvent::ShortcutOverride) {
+ QKeyEvent *key = static_cast(event);
+ if (key->key() == Qt::Key_Escape) {
+ event->accept();
+ m_completer->popup()->hide();
+ return true;
+ }
+ }
+ return QObject::eventFilter(object, event);
+}
+
+void ConfigurationEditor::keyPressEvent(QKeyEvent *event)
+{
+ const int key = event->key();
+
+ if (key == Qt::Key_Escape) {
+ event->ignore();
+ return;
+ }
+
+ if (m_completer->popup()->isVisible()) {
+ switch (key) {
+ case Qt::Key_Backtab:
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ case Qt::Key_Tab:
+ event->ignore();
+ return;
+ default:
+ break;
+ }
+ }
+
+ const bool isShortcut = ((event->modifiers() & Qt::ControlModifier) && key == Qt::Key_Space);
+ if (!isShortcut)
+ QPlainTextEdit::keyPressEvent(event);
+
+ const int cursorPosition = textCursor().position();
+ QTextCursor cursor = cursorForTextUnderCursor();
+ const QString prefix = cursor.selectedText();
+
+ if (!isShortcut && (prefix.length() < 2 || cursorPosition != cursor.position())) {
+ m_completer->popup()->hide();
+ return;
+ }
+
+ if (prefix != m_completer->completionPrefix()) {
+ m_completer->setCompletionPrefix(prefix);
+ m_completer->popup()->setCurrentIndex(m_completer->completionModel()->index(0, 0));
+ }
+
+ if (m_completer->completionCount() == 1 && prefix == m_completer->currentCompletion()) {
+ m_completer->popup()->hide();
+ return;
+ }
+
+ QRect popupRect = cursorRect();
+ popupRect.setWidth(m_completer->popup()->sizeHintForColumn(0)
+ + m_completer->popup()->verticalScrollBar()->sizeHint().width());
+ m_completer->complete(popupRect);
+}
+
+// Hack because '-' and '=' are treated as End/StartOfWord
+QTextCursor ConfigurationEditor::cursorForTextUnderCursor(QTextCursor tc) const
+{
+ if (tc.isNull())
+ tc = textCursor();
+
+ tc.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
+ QChar ch = document()->characterAt(tc.position() - 1);
+ while (!(ch.isNull() || ch.isSpace() || ch == QLatin1Char(':') || ch == QLatin1Char(','))) {
+ tc.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor);
+ ch = document()->characterAt(tc.position() - 1);
+ }
+ tc.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+ ch = document()->characterAt(tc.position());
+ while (!(ch.isNull() || ch.isSpace() || ch == QLatin1Char(':') || ch == QLatin1Char(','))) {
+ tc.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
+ ch = document()->characterAt(tc.position());
+ }
+ return tc;
+}
+
+void ConfigurationEditor::insertCompleterText(const QString &text)
+{
+ QTextCursor tc = textCursor();
+ // Replace entire word to get case sensitivity right.
+ tc.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor,
+ m_completer->completionPrefix().length());
+ tc.insertText(text);
+ setTextCursor(tc);
+}
+
+void ConfigurationEditor::updateDocumentation()
+{
+ QTC_CHECK(m_settings);
+ QTextCursor cursor = textCursor();
+
+ QString word = cursorForTextUnderCursor(cursor).selectedText();
+ if (word == m_lastDocumentation)
+ return;
+
+ QString doc = m_settings->documentation(word);
+ if (!doc.isEmpty()) {
+ m_lastDocumentation = word;
+ emit documentationChanged(word, doc);
+ return;
+ }
+
+ // If the documentation was empty, then try to use the line's first word or the first word
+ // in front of a colon for providing a documentation.
+ cursor.movePosition(QTextCursor::PreviousWord);
+ cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);
+ const int pos = cursor.selectedText().lastIndexOf(QLatin1Char(','));
+ if (-1 != pos) {
+ cursor.setPosition(cursor.position() + pos);
+ cursor.movePosition(QTextCursor::NextWord);
+ }
+ word = cursorForTextUnderCursor(cursor).selectedText();
+
+ if (word == m_lastDocumentation)
+ return;
+
+ doc = m_settings->documentation(word);
+ if (doc.isEmpty())
+ return;
+
+ m_lastDocumentation = word;
+ emit documentationChanged(word, doc);
+}
+
+} // namespace Internal
+} // namespace Beautifier
diff --git a/src/plugins/beautifier/configurationeditor.h b/src/plugins/beautifier/configurationeditor.h
new file mode 100644
index 0000000000000000000000000000000000000000..4319fd6653d4c52727c1370d48128674122fe154
--- /dev/null
+++ b/src/plugins/beautifier/configurationeditor.h
@@ -0,0 +1,106 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_CONFIGURATIONEDITOR_H
+#define BEAUTIFIER_CONFIGURATIONEDITOR_H
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+QT_BEGIN_NAMESPACE
+class QCompleter;
+class QRegExp;
+class QStringListModel;
+class QTextDocument;
+QT_END_NAMESPACE
+
+namespace Beautifier {
+namespace Internal {
+
+class AbstractSettings;
+
+class ConfigurationSyntaxHighlighter : public QSyntaxHighlighter
+{
+ Q_OBJECT
+
+public:
+ explicit ConfigurationSyntaxHighlighter(QTextDocument *parent);
+ void setKeywords(const QStringList &keywords);
+ void setCommentExpression(const QRegExp &rx);
+
+protected:
+ void highlightBlock(const QString &text) QTC_OVERRIDE;
+
+private:
+ QRegExp m_expressionKeyword;
+ QRegExp m_expressionComment;
+ QTextCharFormat m_formatKeyword;
+ QTextCharFormat m_formatComment;
+};
+
+class ConfigurationEditor : public QPlainTextEdit
+{
+ Q_OBJECT
+
+public:
+ explicit ConfigurationEditor(QWidget *parent = 0);
+ void setSettings(AbstractSettings *settings);
+ void setCommentExpression(const QRegExp &rx);
+
+protected:
+ bool eventFilter(QObject *object, QEvent *event) QTC_OVERRIDE;
+ void keyPressEvent(QKeyEvent *event) QTC_OVERRIDE;
+
+private slots:
+ void insertCompleterText(const QString &text);
+ void updateDocumentation();
+
+signals:
+ void documentationChanged(const QString &word, const QString &documentation);
+
+private:
+ QTextCursor cursorForTextUnderCursor(QTextCursor tc = QTextCursor()) const;
+
+ AbstractSettings *m_settings;
+ QCompleter *m_completer;
+ QStringListModel *m_model;
+ ConfigurationSyntaxHighlighter *m_highlighter;
+ QString m_lastDocumentation;
+};
+
+} // namespace Internal
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_CONFIGURATIONEDITOR_H
diff --git a/src/plugins/beautifier/configurationpanel.cpp b/src/plugins/beautifier/configurationpanel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..01d246d9f9b7fd76391c233254cf1a9b5e2e80cc
--- /dev/null
+++ b/src/plugins/beautifier/configurationpanel.cpp
@@ -0,0 +1,131 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "configurationpanel.h"
+#include "ui_configurationpanel.h"
+
+#include "abstractsettings.h"
+#include "configurationdialog.h"
+
+#include
+
+namespace Beautifier {
+namespace Internal {
+
+ConfigurationPanel::ConfigurationPanel(QWidget *parent) :
+ QWidget(parent),
+ ui(new Ui::ConfigurationPanel),
+ m_settings(0)
+{
+ ui->setupUi(this);
+ connect(ui->add, SIGNAL(clicked()), this, SLOT(add()));
+ connect(ui->edit, SIGNAL(clicked()), this, SLOT(edit()));
+ connect(ui->remove, SIGNAL(clicked()), this, SLOT(remove()));
+ connect(ui->configurations, SIGNAL(currentIndexChanged(int)), this, SLOT(updateButtons()));
+}
+
+ConfigurationPanel::~ConfigurationPanel()
+{
+ delete ui;
+}
+
+void ConfigurationPanel::setSettings(AbstractSettings *settings)
+{
+ m_settings = settings;
+ populateConfigurations();
+}
+
+void ConfigurationPanel::setCurrentConfiguration(const QString &text)
+{
+ ui->configurations->setCurrentText(text);
+}
+
+QString ConfigurationPanel::currentConfiguration() const
+{
+ return ui->configurations->currentText();
+}
+
+void ConfigurationPanel::remove()
+{
+ m_settings->removeStyle(ui->configurations->currentText());
+ populateConfigurations();
+}
+
+void ConfigurationPanel::add()
+{
+ ConfigurationDialog dialog;
+ dialog.setWindowTitle(tr("Add Configuration"));
+ dialog.setSettings(m_settings);
+ if (QDialog::Accepted == dialog.exec()) {
+ const QString key = dialog.key();
+ m_settings->setStyle(key, dialog.value());
+ populateConfigurations(key);
+ }
+}
+
+void ConfigurationPanel::edit()
+{
+ const QString key = ui->configurations->currentText();
+ ConfigurationDialog dialog;
+ dialog.setWindowTitle(tr("Edit Configuration"));
+ dialog.setSettings(m_settings);
+ dialog.setKey(key);
+ if (QDialog::Accepted == dialog.exec()) {
+ const QString newKey = dialog.key();
+ if (newKey == key) {
+ m_settings->setStyle(key, dialog.value());
+ } else {
+ m_settings->replaceStyle(key, newKey, dialog.value());
+ ui->configurations->setItemText(ui->configurations->currentIndex(), newKey);
+ }
+ }
+}
+
+void ConfigurationPanel::populateConfigurations(const QString &key)
+{
+ ui->configurations->blockSignals(true);
+ const QString currentText = (!key.isEmpty()) ? key : ui->configurations->currentText();
+ ui->configurations->clear();
+ ui->configurations->addItems(m_settings->styles());
+ ui->configurations->setCurrentText(currentText);
+ updateButtons();
+ ui->configurations->blockSignals(false);
+}
+
+void ConfigurationPanel::updateButtons()
+{
+ const bool enabled
+ = ((ui->configurations->count() > 0)
+ && !m_settings->styleIsReadOnly(ui->configurations->currentText()));
+ ui->remove->setEnabled(enabled);
+ ui->edit->setEnabled(enabled);
+}
+
+} // namespace Internal
+} // namespace Beautifier
diff --git a/src/plugins/beautifier/configurationpanel.h b/src/plugins/beautifier/configurationpanel.h
new file mode 100644
index 0000000000000000000000000000000000000000..dd9625640b9f001a679fef4c66132e9c511f36b4
--- /dev/null
+++ b/src/plugins/beautifier/configurationpanel.h
@@ -0,0 +1,70 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_CONFIGURATIONPANEL_H
+#define BEAUTIFIER_CONFIGURATIONPANEL_H
+
+#include
+
+namespace Beautifier {
+namespace Internal {
+
+class AbstractSettings;
+class ConfigurationDialog;
+
+namespace Ui { class ConfigurationPanel; }
+
+class ConfigurationPanel : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit ConfigurationPanel(QWidget *parent = 0);
+ ~ConfigurationPanel();
+
+ void setSettings(AbstractSettings *settings);
+ void setCurrentConfiguration(const QString &text);
+ QString currentConfiguration() const;
+
+private slots:
+ void remove();
+ void add();
+ void edit();
+ void updateButtons();
+
+private:
+ Ui::ConfigurationPanel *ui;
+ AbstractSettings *m_settings;
+ void populateConfigurations(const QString &key = QString());
+};
+
+} // namespace Internal
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_CONFIGURATIONPANEL_H
diff --git a/src/plugins/beautifier/configurationpanel.ui b/src/plugins/beautifier/configurationpanel.ui
new file mode 100644
index 0000000000000000000000000000000000000000..73d35bc09fc1280347995972113663cd67ac4c32
--- /dev/null
+++ b/src/plugins/beautifier/configurationpanel.ui
@@ -0,0 +1,57 @@
+
+
+ Beautifier::Internal::ConfigurationPanel
+
+
+
+ 0
+ 0
+ 595
+ 23
+
+
+
+ Form
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ -
+
+
+ Edit
+
+
+
+ -
+
+
+ Remove
+
+
+
+ -
+
+
+ Add
+
+
+
+
+
+
+
+
diff --git a/src/plugins/beautifier/images/beautifier.png b/src/plugins/beautifier/images/beautifier.png
new file mode 100644
index 0000000000000000000000000000000000000000..65cf56ae8efc5942e182b9e76e843399eeaf7758
Binary files /dev/null and b/src/plugins/beautifier/images/beautifier.png differ
diff --git a/src/plugins/beautifier/uncrustify/uncrustify.cpp b/src/plugins/beautifier/uncrustify/uncrustify.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..02774261c72760775486c6c8945192736bbe4d2d
--- /dev/null
+++ b/src/plugins/beautifier/uncrustify/uncrustify.cpp
@@ -0,0 +1,146 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "uncrustify.h"
+
+#include "uncrustifyconstants.h"
+#include "uncrustifyoptionspage.h"
+#include "uncrustifysettings.h"
+
+#include "../beautifierconstants.h"
+#include "../beautifierplugin.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+namespace Beautifier {
+namespace Internal {
+namespace Uncrustify {
+
+Uncrustify::Uncrustify(QObject *parent) :
+ BeautifierAbstractTool(parent),
+ m_settings(new UncrustifySettings)
+{
+}
+
+Uncrustify::~Uncrustify()
+{
+ delete m_settings;
+}
+
+bool Uncrustify::initialize()
+{
+ Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::Uncrustify::MENU_ID);
+ menu->menu()->setTitle(QLatin1String("Uncrustify"));
+
+ m_formatFile = new QAction(tr("Format Current File"), this);
+ Core::Command *cmd
+ = Core::ActionManager::registerAction(m_formatFile,
+ Constants::Uncrustify::ACTION_FORMATFILE,
+ Core::Context(Core::Constants::C_GLOBAL));
+ menu->addAction(cmd);
+ connect(m_formatFile, SIGNAL(triggered()), this, SLOT(formatFile()));
+
+ Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu);
+
+ return true;
+}
+
+void Uncrustify::updateActions(Core::IEditor *editor)
+{
+ m_formatFile->setEnabled(editor && editor->id() == CppEditor::Constants::CPPEDITOR_ID);
+}
+
+QList Uncrustify::autoReleaseObjects()
+{
+ UncrustifyOptionsPage *optionsPage = new UncrustifyOptionsPage(m_settings, this);
+ return QList() << optionsPage;
+}
+
+void Uncrustify::formatFile()
+{
+ QString cfgFileName;
+
+ if (m_settings->useOtherFiles()) {
+ if (const ProjectExplorer::Project *project
+ = ProjectExplorer::ProjectExplorerPlugin::currentProject()) {
+ const QStringList files = project->files(ProjectExplorer::Project::AllFiles);
+ for (int i = 0, total = files.size(); i < total; ++i) {
+ const QString &file = files.at(i);
+ if (!file.endsWith(QLatin1String("cfg")))
+ continue;
+ const QFileInfo fi(file);
+ if (fi.isReadable() && fi.fileName() == QLatin1String("uncrustify.cfg")) {
+ cfgFileName = file;
+ break;
+ }
+ }
+ }
+ }
+
+ if (cfgFileName.isEmpty() && m_settings->useHomeFile()) {
+ const QString file = QDir::home().filePath(QLatin1String("uncrustify.cfg"));
+ if (QFile::exists(file))
+ cfgFileName = file;
+ }
+
+ if (m_settings->useCustomStyle())
+ cfgFileName = m_settings->styleFileName(m_settings->customStyle());
+
+ if (cfgFileName.isEmpty()) {
+ BeautifierPlugin::showError(tr("Could not get configuration file for uncrustify."));
+ } else {
+ BeautifierPlugin::formatCurrentFile(QStringList()
+ << m_settings->command()
+ << QLatin1String("-l")
+ << QLatin1String("cpp")
+ << QLatin1String("-L")
+ << QLatin1String("1-2")
+ << QLatin1String("--no-backup")
+ << QLatin1String("-c")
+ << cfgFileName
+ << QLatin1String("%file"));
+ }
+}
+
+} // namespace Uncrustify
+} // namespace Internal
+} // namespace Beautifier
diff --git a/src/plugins/beautifier/uncrustify/uncrustify.h b/src/plugins/beautifier/uncrustify/uncrustify.h
new file mode 100644
index 0000000000000000000000000000000000000000..7397380d0bc3ff839ee588f5a6fc72e5fa657fdf
--- /dev/null
+++ b/src/plugins/beautifier/uncrustify/uncrustify.h
@@ -0,0 +1,68 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_UNCRUSTIFY_H
+#define BEAUTIFIER_UNCRUSTIFY_H
+
+#include "../beautifierabstracttool.h"
+
+#include
+
+QT_FORWARD_DECLARE_CLASS(QAction)
+
+namespace Beautifier {
+namespace Internal {
+namespace Uncrustify {
+
+class UncrustifySettings;
+
+class Uncrustify : public BeautifierAbstractTool
+{
+ Q_OBJECT
+
+public:
+ explicit Uncrustify(QObject *parent = 0);
+ virtual ~Uncrustify();
+ bool initialize() QTC_OVERRIDE;
+ void updateActions(Core::IEditor *editor) QTC_OVERRIDE;
+ QList autoReleaseObjects() QTC_OVERRIDE;
+
+private slots:
+ void formatFile();
+
+private:
+ QAction *m_formatFile;
+ UncrustifySettings *m_settings;
+};
+
+} // namespace Uncrustify
+} // namespace Internal
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_UNCRUSTIFY_H
diff --git a/src/plugins/beautifier/uncrustify/uncrustifyconstants.h b/src/plugins/beautifier/uncrustify/uncrustifyconstants.h
new file mode 100644
index 0000000000000000000000000000000000000000..6a09f2138ff8eb406090ad03250cc5cc652ea8d2
--- /dev/null
+++ b/src/plugins/beautifier/uncrustify/uncrustifyconstants.h
@@ -0,0 +1,46 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_UNCRUSTIFYCONSTANTS_H
+#define BEAUTIFIER_UNCRUSTIFYCONSTANTS_H
+
+namespace Beautifier {
+namespace Constants {
+namespace Uncrustify {
+
+const char ACTION_FORMATFILE[] = "Uncrustify.FormatFile";
+const char MENU_ID[] = "Uncrustify.Menu";
+const char OPTION_ID[] = "Uncrustify";
+const char SETTINGS_NAME[] = "uncrustify";
+
+} // namespace Uncrustify
+} // namespace Constants
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_UNCRUSTIFYCONSTANTS_H
diff --git a/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..77e25902987354783228333e279bf3031880c46c
--- /dev/null
+++ b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.cpp
@@ -0,0 +1,143 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "uncrustifyoptionspage.h"
+#include "ui_uncrustifyoptionspage.h"
+
+#include "uncrustifyconstants.h"
+#include "uncrustifysettings.h"
+
+#include "../beautifierconstants.h"
+
+#include
+
+#include
+
+namespace Beautifier {
+namespace Internal {
+namespace Uncrustify {
+
+UncrustifyOptionsPageWidget::UncrustifyOptionsPageWidget(UncrustifySettings *settings,
+ QWidget *parent)
+ : QWidget(parent)
+ , ui(new Ui::UncrustifyOptionsPage)
+ , m_settings(settings)
+{
+ ui->setupUi(this);
+ ui->command->setExpectedKind(Utils::PathChooser::ExistingCommand);
+ ui->command->setPromptDialogTitle(tr("Uncrustify Command"));
+ connect(ui->command, SIGNAL(validChanged(bool)), ui->options, SLOT(setEnabled(bool)));
+ ui->configurations->setSettings(m_settings);
+}
+
+UncrustifyOptionsPageWidget::~UncrustifyOptionsPageWidget()
+{
+ delete ui;
+}
+
+QString UncrustifyOptionsPageWidget::searchKeywords() const
+{
+ QString keywords;
+ const QLatin1Char sep(' ');
+ QTextStream(&keywords) << sep << ui->configuration->title()
+ << sep << ui->commandLabel->text()
+ << sep << ui->options->title()
+ << sep << ui->useOtherFiles->text()
+ << sep << ui->useHomeFile->text()
+ << sep << ui->useCustomStyle->text();
+ keywords.remove(QLatin1Char('&'));
+ return keywords;
+}
+
+void UncrustifyOptionsPageWidget::restore()
+{
+ ui->command->setPath(m_settings->command());
+ ui->useOtherFiles->setChecked(m_settings->useOtherFiles());
+ ui->useHomeFile->setChecked(m_settings->useHomeFile());
+ ui->useCustomStyle->setChecked(m_settings->useCustomStyle());
+ ui->configurations->setCurrentConfiguration(m_settings->customStyle());
+}
+
+void UncrustifyOptionsPageWidget::apply()
+{
+ m_settings->setCommand(ui->command->path());
+ 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();
+}
+
+/* ---------------------------------------------------------------------------------------------- */
+
+UncrustifyOptionsPage::UncrustifyOptionsPage(UncrustifySettings *settings, QObject *parent) :
+ IOptionsPage(parent),
+ m_widget(0),
+ m_settings(settings),
+ m_searchKeywords()
+{
+ setId(Constants::Uncrustify::OPTION_ID);
+ setDisplayName(tr("Uncrustify"));
+ setCategory(Constants::OPTION_CATEGORY);
+ setDisplayCategory(QCoreApplication::translate("Beautifier", Constants::OPTION_TR_CATEGORY));
+ setCategoryIcon(QLatin1String(Constants::OPTION_CATEGORY_ICON));
+}
+
+QWidget *UncrustifyOptionsPage::widget()
+{
+ m_settings->read();
+
+ if (!m_widget) {
+ m_widget = new UncrustifyOptionsPageWidget(m_settings);
+ if (m_searchKeywords.isEmpty())
+ m_searchKeywords = m_widget->searchKeywords();
+ }
+ m_widget->restore();
+
+ return m_widget;
+}
+
+void UncrustifyOptionsPage::apply()
+{
+ if (m_widget)
+ m_widget->apply();
+}
+
+void UncrustifyOptionsPage::finish()
+{
+}
+
+bool UncrustifyOptionsPage::matches(const QString &searchKeyWord) const
+{
+ return m_searchKeywords.contains(searchKeyWord, Qt::CaseInsensitive);
+}
+
+} // namespace Uncrustify
+} // namespace Internal
+} // namespace Beautifier
diff --git a/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.h b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.h
new file mode 100644
index 0000000000000000000000000000000000000000..125862c0e9fe629dd0153abdc98a9ee2e354cc08
--- /dev/null
+++ b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.h
@@ -0,0 +1,85 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_UNCRUSTIFYOPTIONSPAGE_H
+#define BEAUTIFIER_UNCRUSTIFYOPTIONSPAGE_H
+
+#include
+#include
+
+#include
+#include
+
+namespace Beautifier {
+namespace Internal {
+namespace Uncrustify {
+
+class UncrustifySettings;
+
+namespace Ui { class UncrustifyOptionsPage; }
+
+class UncrustifyOptionsPageWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit UncrustifyOptionsPageWidget(UncrustifySettings *settings, QWidget *parent = 0);
+ virtual ~UncrustifyOptionsPageWidget();
+ QString searchKeywords() const;
+ void restore();
+ void apply();
+
+private:
+ Ui::UncrustifyOptionsPage *ui;
+ UncrustifySettings *m_settings;
+};
+
+class UncrustifyOptionsPage : public Core::IOptionsPage
+{
+ Q_OBJECT
+
+public:
+ explicit UncrustifyOptionsPage(UncrustifySettings *settings, QObject *parent = 0);
+ QWidget *widget() QTC_OVERRIDE;
+ void apply() QTC_OVERRIDE;
+ void finish() QTC_OVERRIDE;
+ bool matches(const QString &searchKeywords) const QTC_OVERRIDE;
+
+private:
+ QPointer m_widget;
+ UncrustifySettings *m_settings;
+ QString m_searchKeywords;
+};
+
+} // namespace Uncrustify
+} // namespace Internal
+} // namespace Beautifier
+
+
+#endif // BEAUTIFIER_UNCRUSTIFYOPTIONSPAGE_H
diff --git a/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.ui b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.ui
new file mode 100644
index 0000000000000000000000000000000000000000..6dbc77a7102ac48b09521835a323513abb0128f5
--- /dev/null
+++ b/src/plugins/beautifier/uncrustify/uncrustifyoptionspage.ui
@@ -0,0 +1,104 @@
+
+
+ Beautifier::Internal::Uncrustify::UncrustifyOptionsPage
+
+
+
+ 0
+ 0
+ 817
+ 631
+
+
+
+ Form
+
+
+ -
+
+
+ Configuration
+
+
+
-
+
+
+ Uncrustify command:
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+ Options
+
+
+
-
+
+
+ Use file uncrustify.cfg defined in project files
+
+
+
+ -
+
+
+ Use $HOME/uncrustify.cfg
+
+
+
+ -
+
+
-
+
+
+ Use selfdefined style:
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ Utils::PathChooser
+ QWidget
+
+ 1
+
+
+ Beautifier::Internal::ConfigurationPanel
+ QWidget
+ beautifier/configurationpanel.h
+ 1
+
+
+
+
+
diff --git a/src/plugins/beautifier/uncrustify/uncrustifysettings.cpp b/src/plugins/beautifier/uncrustify/uncrustifysettings.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..705c0c922f530fb60825a664b24b01a825e2fda6
--- /dev/null
+++ b/src/plugins/beautifier/uncrustify/uncrustifysettings.cpp
@@ -0,0 +1,172 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "uncrustifysettings.h"
+
+#include "uncrustifyconstants.h"
+
+#include "../beautifierconstants.h"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+namespace Beautifier {
+namespace Internal {
+namespace Uncrustify {
+
+namespace {
+const QString kUseOtherFiles = QLatin1String("useOtherFiles");
+const QString kUseHomeFile = QLatin1String("useHomeFile");
+const QString kUseCustomStyle = QLatin1String("useCustomStyle");
+const QString kCustomStyle = QLatin1String("customStyle");
+}
+
+UncrustifySettings::UncrustifySettings() :
+ AbstractSettings(QLatin1String(Constants::Uncrustify::SETTINGS_NAME), QLatin1String(".cfg"))
+{
+ setCommand(QLatin1String("uncrustify"));
+ m_settings.insert(kUseOtherFiles, QVariant(true));
+ m_settings.insert(kUseHomeFile, QVariant(false));
+ m_settings.insert(kUseCustomStyle, QVariant(false));
+ m_settings.insert(kCustomStyle, QVariant());
+ read();
+}
+
+bool UncrustifySettings::useOtherFiles() const
+{
+ return m_settings.value(kUseOtherFiles).toBool();
+}
+
+void UncrustifySettings::setUseOtherFiles(bool useOtherFiles)
+{
+ m_settings.insert(kUseOtherFiles, QVariant(useOtherFiles));
+}
+
+bool UncrustifySettings::useHomeFile() const
+{
+ return m_settings.value(kUseHomeFile).toBool();
+}
+
+void UncrustifySettings::setUseHomeFile(bool useHomeFile)
+{
+ m_settings.insert(kUseHomeFile, QVariant(useHomeFile));
+}
+
+bool UncrustifySettings::useCustomStyle() const
+{
+ return m_settings.value(kUseCustomStyle).toBool();
+}
+
+void UncrustifySettings::setUseCustomStyle(bool useCustomStyle)
+{
+ m_settings.insert(kUseCustomStyle, QVariant(useCustomStyle));
+}
+
+QString UncrustifySettings::customStyle() const
+{
+ return m_settings.value(kCustomStyle).toString();
+}
+
+void UncrustifySettings::setCustomStyle(const QString &customStyle)
+{
+ m_settings.insert(kCustomStyle, QVariant(customStyle));
+}
+
+QString UncrustifySettings::documentationFilePath() const
+{
+ return Core::ICore::userResourcePath() + QLatin1Char('/')
+ + QLatin1String(Beautifier::Constants::SETTINGS_DIRNAME) + QLatin1Char('/')
+ + QLatin1String(Beautifier::Constants::DOCUMENTATION_DIRNAME) + QLatin1Char('/')
+ + QLatin1String(Constants::Uncrustify::SETTINGS_NAME) + QLatin1String(".xml");
+}
+
+void UncrustifySettings::createDocumentationFile() const
+{
+ QFile file(documentationFilePath());
+ const QFileInfo fi(file);
+ if (!fi.exists())
+ fi.dir().mkpath(fi.absolutePath());
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text))
+ return;
+
+ QProcess process;
+ process.start(command(), QStringList() << QLatin1String("--show-config"));
+ process.waitForFinished(2000); // show config should be really fast.
+ if (process.error() != QProcess::UnknownError)
+ return;
+
+ QXmlStreamWriter stream(&file);
+ stream.setAutoFormatting(true);
+ stream.writeStartDocument(QLatin1String("1.0"), true);
+ stream.writeComment(QLatin1String("Created ")
+ + QDateTime::currentDateTime().toString(Qt::ISODate));
+ stream.writeStartElement(QLatin1String(Constants::DOCUMENTATION_XMLROOT));
+
+ const QStringList lines = QString::fromUtf8(process.readAll()).split(QLatin1Char('\n'));
+ const int totalLines = lines.count();
+ for (int i = 0; i < totalLines; ++i) {
+ const QString &line = lines.at(i);
+ if (line.startsWith(QLatin1Char('#')) || line.trimmed().isEmpty())
+ continue;
+
+ const int firstSpace = line.indexOf(QLatin1Char(' '));
+ const QString keyword = line.left(firstSpace);
+ const QString options = line.right(line.size() - firstSpace).trimmed();
+ QStringList docu;
+ while (++i < totalLines) {
+ const QString &subline = lines.at(i);
+ if (line.startsWith(QLatin1Char('#')) || subline.trimmed().isEmpty()) {
+ //TODO As soon as Qt 4 support is dropped, use toHtmlEscaped().
+ const QString text = QLatin1String("") + keyword
+ + QLatin1String(" ") + options
+ + QLatin1String("
") + Qt::escape(docu.join(QLatin1Char(' ')))
+ + QLatin1String("
");
+ stream.writeStartElement(QLatin1String(Constants::DOCUMENTATION_XMLENTRY));
+ stream.writeTextElement(QLatin1String(Constants::DOCUMENTATION_XMLKEY), keyword);
+ stream.writeTextElement(QLatin1String(Constants::DOCUMENTATION_XMLDOC), text);
+ stream.writeEndElement();
+ break;
+ } else {
+ docu << subline;
+ }
+ }
+ }
+
+ stream.writeEndElement();
+ stream.writeEndDocument();
+}
+
+} // namespace Uncrustify
+} // namespace Internal
+} // namespace Beautifier
diff --git a/src/plugins/beautifier/uncrustify/uncrustifysettings.h b/src/plugins/beautifier/uncrustify/uncrustifysettings.h
new file mode 100644
index 0000000000000000000000000000000000000000..3398a64e1a93f58ca407b6ffaa20a34af1c68fc4
--- /dev/null
+++ b/src/plugins/beautifier/uncrustify/uncrustifysettings.h
@@ -0,0 +1,66 @@
+/**************************************************************************
+**
+** Copyright (c) 2014 Lorenz Haas
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef BEAUTIFIER_UNCRUSTIFYSETTINGS_H
+#define BEAUTIFIER_UNCRUSTIFYSETTINGS_H
+
+#include "../abstractsettings.h"
+
+#include
+
+namespace Beautifier {
+namespace Internal {
+namespace Uncrustify {
+
+class UncrustifySettings : public AbstractSettings
+{
+public:
+ UncrustifySettings();
+
+ bool useOtherFiles() const;
+ void setUseOtherFiles(bool useOtherFiles);
+
+ bool useHomeFile() const;
+ void setUseHomeFile(bool useHomeFile);
+
+ bool useCustomStyle() const;
+ void setUseCustomStyle(bool useCustomStyle);
+
+ QString customStyle() const;
+ void setCustomStyle(const QString &customStyle);
+
+ QString documentationFilePath() const QTC_OVERRIDE;
+ void createDocumentationFile() const QTC_OVERRIDE;
+};
+
+} // namespace Uncrustify
+} // namespace Internal
+} // namespace Beautifier
+
+#endif // BEAUTIFIER_UNCRUSTIFYSETTINGS_H
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 4b4587e2721fc8e533f75b9853d21868d73af2de..987cb24b3adf6582b63867ded380f6248861c8dd 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -48,7 +48,8 @@ SUBDIRS = \
qnx \
clearcase \
baremetal \
- ios
+ ios \
+ beautifier
# prefer qmake variable set on command line over env var
isEmpty(LLVM_INSTALL_DIR):LLVM_INSTALL_DIR=$$(LLVM_INSTALL_DIR)
diff --git a/src/plugins/plugins.qbs b/src/plugins/plugins.qbs
index 757ec3200f94ec0a4f5c477a73881bdd00c9bfa2..7f621efd7a5d78de0a7fbbb6703b17b630df7b08 100644
--- a/src/plugins/plugins.qbs
+++ b/src/plugins/plugins.qbs
@@ -9,6 +9,7 @@ Project {
"autotoolsprojectmanager/autotoolsprojectmanager.qbs",
"baremetal/baremetal.qbs",
"bazaar/bazaar.qbs",
+ "beautifier/beautifier.qbs",
"bineditor/bineditor.qbs",
"bookmarks/bookmarks.qbs",
"clangcodemodel/clangcodemodel.qbs",