diff --git a/src/plugins/beautifier/abstractsettings.cpp b/src/plugins/beautifier/abstractsettings.cpp index e7a3810032c..774478edafa 100644 --- a/src/plugins/beautifier/abstractsettings.cpp +++ b/src/plugins/beautifier/abstractsettings.cpp @@ -44,7 +44,8 @@ namespace Beautifier { namespace Internal { AbstractSettings::AbstractSettings(const QString &name, const QString &ending) - : m_name(name) + : m_version(0) + , m_name(name) , m_ending(ending) , m_styleDir(Core::ICore::userResourcePath() + QLatin1Char('/') + QLatin1String(Beautifier::Constants::SETTINGS_DIRNAME) + QLatin1Char('/') @@ -135,6 +136,18 @@ void AbstractSettings::setCommand(const QString &command) return; m_command = command; + updateVersion(); +} + +int AbstractSettings::version() const +{ + return m_version; +} + +void AbstractSettings::updateVersion() +{ + // If a beautifier needs to know the current tool's version, reimplement and store the version + // in m_version. } QStringList AbstractSettings::options() diff --git a/src/plugins/beautifier/abstractsettings.h b/src/plugins/beautifier/abstractsettings.h index 031ccd26f3a..c859c61a75d 100644 --- a/src/plugins/beautifier/abstractsettings.h +++ b/src/plugins/beautifier/abstractsettings.h @@ -67,6 +67,8 @@ public: QString command() const; void setCommand(const QString &command); + int version() const; + virtual void updateVersion(); QStringList options(); QString documentation(const QString &option) const; @@ -74,6 +76,7 @@ public: protected: QMap m_styles; QMap m_settings; + int m_version; void readDocumentation(); diff --git a/src/plugins/beautifier/artisticstyle/artisticstyle.cpp b/src/plugins/beautifier/artisticstyle/artisticstyle.cpp index b9b4d0bb4f8..9ba0abd8d1c 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstyle.cpp +++ b/src/plugins/beautifier/artisticstyle/artisticstyle.cpp @@ -27,6 +27,8 @@ ** ****************************************************************************/ +// Tested with version 2.01, 2.02, 2.02.1, 2.03 and 2.04 + #include "artisticstyle.h" #include "artisticstyleconstants.h" @@ -35,6 +37,7 @@ #include "../beautifierconstants.h" #include "../beautifierplugin.h" +#include "../command.h" #include #include @@ -136,11 +139,19 @@ void ArtisticStyle::formatFile() BeautifierPlugin::showError(BeautifierPlugin::msgCannotGetConfigurationFile( QLatin1String(Constants::ArtisticStyle::DISPLAY_NAME))); } else { - BeautifierPlugin::formatCurrentFile(QStringList() - << m_settings->command() - << QLatin1String("-q") - << QLatin1String("--options=") + cfgFileName - << QLatin1String("%file")); + Command command; + command.setExecutable(m_settings->command()); + command.addOption(QLatin1String("-q")); + command.addOption(QLatin1String("--options=") + cfgFileName); + + if (m_settings->version() > ArtisticStyleSettings::Version_2_03) { + command.setProcessing(Command::PipeProcessing); + command.setPipeAddsNewline(true); + } else { + command.addOption(QLatin1String("%file")); + } + + BeautifierPlugin::formatCurrentFile(command); } } diff --git a/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp b/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp index f10e16d459c..c3ca0851984 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp +++ b/src/plugins/beautifier/artisticstyle/artisticstylesettings.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include // Qt::escape() in Qt 4 #include @@ -57,6 +58,8 @@ ArtisticStyleSettings::ArtisticStyleSettings() : AbstractSettings(QLatin1String(Constants::ArtisticStyle::SETTINGS_NAME), QLatin1String(".astyle")) { + connect(&m_versionWatcher, SIGNAL(finished()), this, SLOT(helperSetVersion())); + setCommand(QLatin1String("astyle")); m_settings.insert(QLatin1String(kUseOtherFiles), QVariant(true)); m_settings.insert(QLatin1String(kUseHomeFile), QVariant(false)); @@ -65,6 +68,40 @@ ArtisticStyleSettings::ArtisticStyleSettings() : read(); } +void ArtisticStyleSettings::updateVersion() +{ + if (m_versionFuture.isRunning()) + m_versionFuture.cancel(); + + m_versionFuture = QtConcurrent::run(this, &ArtisticStyleSettings::helperUpdateVersion); + m_versionWatcher.setFuture(m_versionFuture); +} + +int ArtisticStyleSettings::helperUpdateVersion() const +{ + QProcess process; + process.start(command(), QStringList() << QLatin1String("--version")); + if (!process.waitForFinished()) { + process.kill(); + return 0; + } + + // The version in Artistic Style is printed like "Artistic Style Version 2.04" + const QString version = QString::fromUtf8(process.readAllStandardError()).trimmed(); + const QRegExp rx(QLatin1String("([2-9]{1})\\.([0-9]{2})(\\.[1-9]{1})?$")); + if (rx.indexIn(version) != -1) { + const int major = rx.cap(1).toInt() * 100; + const int minor = rx.cap(2).toInt(); + return major + minor; + } + return 0; +} + +void ArtisticStyleSettings::helperSetVersion() +{ + m_version = m_versionWatcher.result(); +} + bool ArtisticStyleSettings::useOtherFiles() const { return m_settings.value(QLatin1String(kUseOtherFiles)).toBool(); diff --git a/src/plugins/beautifier/artisticstyle/artisticstylesettings.h b/src/plugins/beautifier/artisticstyle/artisticstylesettings.h index 412570c9e4c..b820c261ac8 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstylesettings.h +++ b/src/plugins/beautifier/artisticstyle/artisticstylesettings.h @@ -34,15 +34,26 @@ #include +#include +#include + namespace Beautifier { namespace Internal { namespace ArtisticStyle { -class ArtisticStyleSettings : public AbstractSettings +class ArtisticStyleSettings : public QObject, public AbstractSettings { + Q_OBJECT + public: + enum ArtisticStyleVersion { + Version_2_03 = 203 + }; + ArtisticStyleSettings(); + void updateVersion() QTC_OVERRIDE; + bool useOtherFiles() const; void setUseOtherFiles(bool useOtherFiles); @@ -57,6 +68,14 @@ public: QString documentationFilePath() const QTC_OVERRIDE; void createDocumentationFile() const QTC_OVERRIDE; + +private slots: + void helperSetVersion(); + +private: + QFuture m_versionFuture; + QFutureWatcher m_versionWatcher; + int helperUpdateVersion() const; }; } // namespace ArtisticStyle diff --git a/src/plugins/beautifier/beautifier.pro b/src/plugins/beautifier/beautifier.pro index 4e0891dc25b..1cb7463ba18 100644 --- a/src/plugins/beautifier/beautifier.pro +++ b/src/plugins/beautifier/beautifier.pro @@ -7,6 +7,7 @@ HEADERS += \ beautifierabstracttool.h \ beautifierconstants.h \ beautifierplugin.h \ + command.h \ configurationdialog.h \ configurationeditor.h \ configurationpanel.h \ @@ -26,6 +27,7 @@ HEADERS += \ SOURCES += \ abstractsettings.cpp \ beautifierplugin.cpp \ + command.cpp \ configurationdialog.cpp \ configurationeditor.cpp \ configurationpanel.cpp \ diff --git a/src/plugins/beautifier/beautifier.qbs b/src/plugins/beautifier/beautifier.qbs index 685f996e95d..d22464eb6a6 100644 --- a/src/plugins/beautifier/beautifier.qbs +++ b/src/plugins/beautifier/beautifier.qbs @@ -22,6 +22,8 @@ QtcPlugin { "beautifierconstants.h", "beautifierplugin.cpp", "beautifierplugin.h", + "command.cpp", + "command.h", "configurationdialog.cpp", "configurationdialog.h", "configurationdialog.ui", diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp index 211623ad409..c5883050287 100644 --- a/src/plugins/beautifier/beautifierplugin.cpp +++ b/src/plugins/beautifier/beautifierplugin.cpp @@ -30,6 +30,8 @@ #include "beautifierplugin.h" #include "beautifierconstants.h" +#include "command.h" + #include "artisticstyle/artisticstyle.h" #include "clangformat/clangformat.h" #include "uncrustify/uncrustify.h" @@ -116,47 +118,83 @@ void BeautifierPlugin::updateActions(Core::IEditor *editor) m_tools.at(i)->updateActions(editor); } -QString BeautifierPlugin::format(const QString &text, QStringList command, const QString &fileName) +QString BeautifierPlugin::format(const QString &text, const Command &command, const QString &fileName) { - if (command.isEmpty()) + const QString executable = command.executable(); + if (executable.isEmpty()) return QString(); - // Save text to temporary file - QFileInfo fi(fileName); - Utils::TempFileSaver sourceFile(fi.absolutePath() + QLatin1String("/qtc_beautifier_XXXXXXXX.") - + fi.suffix()); - sourceFile.setAutoRemove(true); - sourceFile.write(text.toUtf8()); - if (!sourceFile.finalize()) { - showError(tr("Cannot create temporary file \"%1\": %2.") - .arg(sourceFile.fileName()).arg(sourceFile.errorString())); - return QString(); + switch (command.processing()) { + case Command::FileProcessing: { + // Save text to temporary file + QFileInfo fi(fileName); + Utils::TempFileSaver sourceFile(QDir::tempPath() + QLatin1String("/qtc_beautifier_XXXXXXXX.") + + fi.suffix()); + sourceFile.setAutoRemove(true); + sourceFile.write(text.toUtf8()); + if (!sourceFile.finalize()) { + showError(tr("Cannot create temporary file \"%1\": %2.") + .arg(sourceFile.fileName()).arg(sourceFile.errorString())); + return QString(); + } + + // Format temporary file + QProcess process; + QStringList options = command.options(); + options.replaceInStrings(QLatin1String("%file"), sourceFile.fileName()); + process.start(executable, options); + if (!process.waitForFinished()) { + showError(tr("Cannot call %1 or some other error occurred.").arg(executable)); + return QString(); + } + const QByteArray output = process.readAllStandardError(); + if (!output.isEmpty()) + showError(executable + QLatin1String(": ") + QString::fromUtf8(output)); + + // Read text back + Utils::FileReader reader; + if (!reader.fetch(sourceFile.fileName(), QIODevice::Text)) { + showError(tr("Cannot read file \"%1\": %2.") + .arg(sourceFile.fileName()).arg(reader.errorString())); + return QString(); + } + return QString::fromUtf8(reader.data()); + } break; + + case Command::PipeProcessing: { + QProcess process; + QStringList options = command.options(); + options.replaceInStrings(QLatin1String("%file"), fileName); + process.start(executable, options); + if (!process.waitForStarted()) { + showError(tr("Cannot call %1 or some other error occurred.").arg(executable)); + return QString(); + } + process.write(text.toUtf8()); + process.closeWriteChannel(); + if (!process.waitForFinished()) { + showError(tr("Cannot call %1 or some other error occurred.").arg(executable)); + return QString(); + } + const QByteArray error = process.readAllStandardError(); + if (!error.isEmpty()) { + showError(executable + QLatin1String(": ") + QString::fromUtf8(error)); + return QString(); + } + + if (command.pipeAddsNewline()) { + QString formatted = QString::fromUtf8(process.readAllStandardOutput()); + formatted.remove(QRegExp(QLatin1String("(\\r\\n|\\n)$"))); + return formatted; + } + return QString::fromUtf8(process.readAllStandardOutput()); + } } - // Format temporary file - QProcess process; - command.replaceInStrings(QLatin1String("%file"), sourceFile.fileName()); - const QString processProgram = command.takeFirst(); - process.start(processProgram, command); - if (!process.waitForFinished()) { - showError(tr("Cannot call %1 or some other error occurred.").arg(processProgram)); - return QString(); - } - const QByteArray output = process.readAllStandardError(); - if (!output.isEmpty()) - showError(processProgram + QLatin1String(": ") + QString::fromLocal8Bit(output)); - - // Read text back - Utils::FileReader reader; - if (!reader.fetch(sourceFile.fileName(), QIODevice::Text)) { - showError(tr("Cannot read file \"%1\": %2.") - .arg(sourceFile.fileName()).arg(reader.errorString())); - return QString(); - } - return QString::fromUtf8(reader.data()); + return QString(); } -void BeautifierPlugin::formatCurrentFile(QStringList command) +void BeautifierPlugin::formatCurrentFile(const Command &command) { QPlainTextEdit *textEditor = 0; if (TextEditor::BaseTextEditor *editor diff --git a/src/plugins/beautifier/beautifierplugin.h b/src/plugins/beautifier/beautifierplugin.h index e1b0da5e278..42f5733988b 100644 --- a/src/plugins/beautifier/beautifierplugin.h +++ b/src/plugins/beautifier/beautifierplugin.h @@ -39,6 +39,7 @@ namespace Beautifier { namespace Internal { class BeautifierAbstractTool; +class Command; class BeautifierPlugin : public ExtensionSystem::IPlugin { @@ -52,8 +53,8 @@ public: 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 QString format(const QString &text, const Command &command, const QString &fileName); + static void formatCurrentFile(const Command &command); static void showError(const QString &error); static QString msgCannotGetConfigurationFile(const QString &command); diff --git a/src/plugins/beautifier/clangformat/clangformat.cpp b/src/plugins/beautifier/clangformat/clangformat.cpp index 17b4385a839..8a1cabc1480 100644 --- a/src/plugins/beautifier/clangformat/clangformat.cpp +++ b/src/plugins/beautifier/clangformat/clangformat.cpp @@ -27,6 +27,8 @@ ** ****************************************************************************/ +// Tested with version 3.3, 3.4 and 3.4.1 + #include "clangformat.h" #include "clangformatconstants.h" @@ -125,22 +127,24 @@ void ClangFormat::formatSelectedText() } } -QStringList ClangFormat::command(int offset, int length) const +Command ClangFormat::command(int offset, int length) const { - QStringList command; - command << m_settings->command(); - command << QLatin1String("-i"); + Command command; + command.setExecutable(m_settings->command()); + command.setProcessing(Command::PipeProcessing); + if (m_settings->usePredefinedStyle()) { - command << QLatin1String("-style=") + m_settings->predefinedStyle(); + command.addOption(QLatin1String("-style=") + m_settings->predefinedStyle()); } else { - command << QLatin1String("-style={") + m_settings->style( - m_settings->customStyle()).remove(QLatin1Char('\n')) + QLatin1String("}"); + command.addOption(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.addOption(QLatin1String("-offset=") + QString::number(offset)); + command.addOption(QLatin1String("-length=") + QString::number(length)); } - command << QLatin1String("%file"); return command; } diff --git a/src/plugins/beautifier/clangformat/clangformat.h b/src/plugins/beautifier/clangformat/clangformat.h index 6424f0aa383..6806cd7d08c 100644 --- a/src/plugins/beautifier/clangformat/clangformat.h +++ b/src/plugins/beautifier/clangformat/clangformat.h @@ -31,6 +31,7 @@ #define BEAUTIFIER_CLANGFORMAT_H #include "../beautifierabstracttool.h" +#include "../command.h" #include @@ -61,7 +62,7 @@ private: QAction *m_formatFile; QAction *m_formatRange; ClangFormatSettings *m_settings; - QStringList command(int offset = -1, int length = -1) const; + Command command(int offset = -1, int length = -1) const; }; } // namespace ClangFormat diff --git a/src/plugins/beautifier/command.cpp b/src/plugins/beautifier/command.cpp new file mode 100644 index 00000000000..834f469a58c --- /dev/null +++ b/src/plugins/beautifier/command.cpp @@ -0,0 +1,82 @@ +/************************************************************************** +** +** 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 "command.h" + +namespace Beautifier { +namespace Internal { + +Command::Command() + : m_processing(FileProcessing) + , m_pipeAddsNewline(false) +{ +} + +QString Command::executable() const +{ + return m_executable; +} + +void Command::setExecutable(const QString &executable) +{ + m_executable = executable; +} + +QStringList Command::options() const +{ + return m_options; +} + +void Command::addOption(const QString &option) +{ + m_options << option; +} + +Command::Processing Command::processing() const +{ + return m_processing; +} + +void Command::setProcessing(const Processing &processing) +{ + m_processing = processing; +} + +bool Command::pipeAddsNewline() const +{ + return m_pipeAddsNewline; +} + +void Command::setPipeAddsNewline(bool pipeAddsNewline) +{ + m_pipeAddsNewline = pipeAddsNewline; +} + +} // namespace Internal +} // namespace Beautifier diff --git a/src/plugins/beautifier/command.h b/src/plugins/beautifier/command.h new file mode 100644 index 00000000000..e6774f38fae --- /dev/null +++ b/src/plugins/beautifier/command.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_COMMAND_H +#define BEAUTIFIER_COMMAND_H + +#include +#include + +namespace Beautifier { +namespace Internal { + +class Command +{ +public: + enum Processing { + FileProcessing, + PipeProcessing + }; + + Command(); + + QString executable() const; + void setExecutable(const QString &executable); + + QStringList options() const; + void addOption(const QString &option); + + Processing processing() const; + void setProcessing(const Processing &processing); + + bool pipeAddsNewline() const; + void setPipeAddsNewline(bool pipeAddsNewline); + +private: + QString m_executable; + QStringList m_options; + Processing m_processing; + bool m_pipeAddsNewline; +}; + +} // namespace Internal +} // namespace Beautifier + +#endif // BEAUTIFIER_COMMAND_H diff --git a/src/plugins/beautifier/uncrustify/uncrustify.cpp b/src/plugins/beautifier/uncrustify/uncrustify.cpp index d4f5fa3d78d..1db39853b27 100644 --- a/src/plugins/beautifier/uncrustify/uncrustify.cpp +++ b/src/plugins/beautifier/uncrustify/uncrustify.cpp @@ -27,6 +27,8 @@ ** ****************************************************************************/ +// Tested with version 0.59 and 0.60 + #include "uncrustify.h" #include "uncrustifyconstants.h" @@ -35,6 +37,7 @@ #include "../beautifierconstants.h" #include "../beautifierplugin.h" +#include "../command.h" #include #include @@ -130,16 +133,16 @@ void Uncrustify::formatFile() BeautifierPlugin::showError(BeautifierPlugin::msgCannotGetConfigurationFile( QLatin1String(Constants::Uncrustify::DISPLAY_NAME))); } else { - BeautifierPlugin::formatCurrentFile(QStringList() - << m_settings->command() - << QLatin1String("-l") - << QLatin1String("cpp") - << QLatin1String("-L") - << QLatin1String("1-2") - << QLatin1String("--no-backup") - << QLatin1String("-c") - << cfgFileName - << QLatin1String("%file")); + Command command; + command.setExecutable(m_settings->command()); + command.setProcessing(Command::PipeProcessing); + command.addOption(QLatin1String("-l")); + command.addOption(QLatin1String("cpp")); + command.addOption(QLatin1String("-L")); + command.addOption(QLatin1String("1-2")); + command.addOption(QLatin1String("-c")); + command.addOption(cfgFileName); + BeautifierPlugin::formatCurrentFile(command); } }