diff options
author | jkobus <jaroslaw.kobus@digia.com> | 2014-04-17 12:47:38 +0200 |
---|---|---|
committer | Jarek Kobus <jaroslaw.kobus@digia.com> | 2014-05-20 11:56:40 +0200 |
commit | 48aefde7ba3005af2e71ed9a854cfab6fd6dfb9b (patch) | |
tree | cd04d0617f260d99e9a31c62bdbd49ed59ac3c41 /src/plugins/coreplugin | |
parent | ba29d9f9b5d15348c647c5fd363f0772f47f2935 (diff) | |
download | qt-creator-48aefde7ba3005af2e71ed9a854cfab6fd6dfb9b.tar.gz |
Move patch command out of VcsPlugin
It will be needed soon inside DiffEditor plugin.
Move "Patch command" setting out of Version Control | General
into Environment | General | System.
Introduce PatchTool class, which hold the patch command
setting and a method for applying patches (runPatch() - moved
from VcsBasePlugin).
Change-Id: I9de94358ccd5c6e31ac2beefc27305c5111d67bb
Reviewed-by: Jarek Kobus <jaroslaw.kobus@digia.com>
Diffstat (limited to 'src/plugins/coreplugin')
-rw-r--r-- | src/plugins/coreplugin/coreplugin.pro | 6 | ||||
-rw-r--r-- | src/plugins/coreplugin/coreplugin.qbs | 1 | ||||
-rw-r--r-- | src/plugins/coreplugin/generalsettings.cpp | 22 | ||||
-rw-r--r-- | src/plugins/coreplugin/generalsettings.h | 1 | ||||
-rw-r--r-- | src/plugins/coreplugin/generalsettings.ui | 24 | ||||
-rw-r--r-- | src/plugins/coreplugin/patchtool.cpp | 134 | ||||
-rw-r--r-- | src/plugins/coreplugin/patchtool.h | 52 |
7 files changed, 236 insertions, 4 deletions
diff --git a/src/plugins/coreplugin/coreplugin.pro b/src/plugins/coreplugin/coreplugin.pro index d38f93fbe6..f00e51df82 100644 --- a/src/plugins/coreplugin/coreplugin.pro +++ b/src/plugins/coreplugin/coreplugin.pro @@ -97,7 +97,8 @@ SOURCES += mainwindow.cpp \ iversioncontrol.cpp \ dialogs/addtovcsdialog.cpp \ icorelistener.cpp \ - ioutputpane.cpp + ioutputpane.cpp \ + patchtool.cpp HEADERS += mainwindow.h \ editmode.h \ @@ -194,7 +195,8 @@ HEADERS += mainwindow.h \ textdocument.h \ documentmanager.h \ removefiledialog.h \ - dialogs/addtovcsdialog.h + dialogs/addtovcsdialog.h \ + patchtool.h FORMS += dialogs/newdialog.ui \ dialogs/saveitemsdialog.ui \ diff --git a/src/plugins/coreplugin/coreplugin.qbs b/src/plugins/coreplugin/coreplugin.qbs index 5220e3464e..340541f1f9 100644 --- a/src/plugins/coreplugin/coreplugin.qbs +++ b/src/plugins/coreplugin/coreplugin.qbs @@ -75,6 +75,7 @@ QtcPlugin { "outputpane.cpp", "outputpane.h", "outputpanemanager.cpp", "outputpanemanager.h", "outputwindow.cpp", "outputwindow.h", + "patchtool.cpp" "patchtool.h" "plugindialog.cpp", "plugindialog.h", "removefiledialog.cpp", "removefiledialog.h", "removefiledialog.ui", "rightpane.cpp", "rightpane.h", diff --git a/src/plugins/coreplugin/generalsettings.cpp b/src/plugins/coreplugin/generalsettings.cpp index f1f3fe4625..0e8e9c187a 100644 --- a/src/plugins/coreplugin/generalsettings.cpp +++ b/src/plugins/coreplugin/generalsettings.cpp @@ -31,6 +31,8 @@ #include "coreconstants.h" #include "icore.h" #include "infobar.h" +#include "patchtool.h" +#include "vcsmanager.h" #include "editormanager/editormanager.h" #include <utils/checkablemessagebox.h> @@ -38,6 +40,7 @@ #include <utils/hostosinfo.h> #include <utils/stylehelper.h> #include <utils/unixutils.h> +#include <utils/environment.h> #include <QMessageBox> @@ -136,6 +139,12 @@ QWidget *GeneralSettings::widget() m_page->helpExternalFileBrowserButton->hide(); } + const QString patchToolTip = tr("Command used for reverting diff chunks."); + m_page->patchCommandLabel->setToolTip(patchToolTip); + m_page->patchChooser->setToolTip(patchToolTip); + m_page->patchChooser->setExpectedKind(Utils::PathChooser::ExistingCommand); + m_page->patchChooser->setHistoryCompleter(QLatin1String("General.PatchCommand.History")); + m_page->patchChooser->setPath(Core::PatchTool::patchCommand()); m_page->autoSaveCheckBox->setChecked(EditorManager::autoSaveEnabled()); m_page->autoSaveInterval->setValue(EditorManager::autoSaveInterval()); m_page->resetWarningsButton->setEnabled(Core::InfoBar::anyGloballySuppressed() @@ -153,6 +162,11 @@ QWidget *GeneralSettings::widget() this, SLOT(showHelpForFileBrowser())); } } + + updatePath(); + + connect(Core::VcsManager::instance(), SIGNAL(configurationChanged(const IVersionControl*)), + this, SLOT(updatePath())); } return m_widget; } @@ -174,6 +188,7 @@ void GeneralSettings::apply() m_page->externalFileBrowserEdit->text()); } } + Core::PatchTool::setPatchCommand(m_page->patchChooser->path()); EditorManager::setAutoSaveEnabled(m_page->autoSaveCheckBox->isChecked()); EditorManager::setAutoSaveInterval(m_page->autoSaveInterval->value()); } @@ -211,6 +226,13 @@ void GeneralSettings::resetFileBrowser() m_page->externalFileBrowserEdit->setText(UnixUtils::defaultFileBrowser()); } +void GeneralSettings::updatePath() +{ + Utils::Environment env = Utils::Environment::systemEnvironment(); + QStringList toAdd = Core::VcsManager::additionalToolsPath(); + env.appendOrSetPath(toAdd.join(QString(Utils::HostOsInfo::pathListSeparator()))); + m_page->patchChooser->setEnvironment(env); +} void GeneralSettings::variableHelpDialogCreator(const QString &helpText) { diff --git a/src/plugins/coreplugin/generalsettings.h b/src/plugins/coreplugin/generalsettings.h index dd3186df2b..e6d81c4328 100644 --- a/src/plugins/coreplugin/generalsettings.h +++ b/src/plugins/coreplugin/generalsettings.h @@ -60,6 +60,7 @@ private slots: void showHelpForFileBrowser(); void resetFileBrowser(); void resetTerminal(); + void updatePath(); private: void variableHelpDialogCreator(const QString &helpText); diff --git a/src/plugins/coreplugin/generalsettings.ui b/src/plugins/coreplugin/generalsettings.ui index 562fa3d784..33651b785b 100644 --- a/src/plugins/coreplugin/generalsettings.ui +++ b/src/plugins/coreplugin/generalsettings.ui @@ -181,7 +181,17 @@ </property> </widget> </item> - <item row="2" column="0" colspan="4"> + <item row="2" column="0"> + <widget class="QLabel" name="patchCommandLabel"> + <property name="text"> + <string>Patch command:</string> + </property> + </widget> + </item> + <item row="2" column="1" colspan="2"> + <widget class="Utils::PathChooser" name="patchChooser" native="true"/> + </item> + <item row="3" column="0" colspan="4"> <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> <widget class="QLabel" name="modifiedLabel"> @@ -227,7 +237,7 @@ </item> </layout> </item> - <item row="3" column="0" colspan="4"> + <item row="4" column="0" colspan="4"> <layout class="QHBoxLayout" name="horizontalLayout_5"> <item> <widget class="QCheckBox" name="autoSaveCheckBox"> @@ -314,6 +324,16 @@ <extends>QToolButton</extends> <header location="global">utils/qtcolorbutton.h</header> </customwidget> + <customwidget> + <class>Utils::PathChooser</class> + <extends>QWidget</extends> + <header location="global">utils/pathchooser.h</header> + <container>1</container> + <slots> + <signal>editingFinished()</signal> + <signal>browsingFinished()</signal> + </slots> + </customwidget> </customwidgets> <resources> <include location="core.qrc"/> diff --git a/src/plugins/coreplugin/patchtool.cpp b/src/plugins/coreplugin/patchtool.cpp new file mode 100644 index 0000000000..90c38d7102 --- /dev/null +++ b/src/plugins/coreplugin/patchtool.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** 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 "patchtool.h" +#include "messagemanager.h" +#include "icore.h" +#include <utils/synchronousprocess.h> + +#include <QProcess> +#include <QDir> +#include <QApplication> + +static const char settingsGroupC[] = "General"; +static const char legacySettingsGroupC[] = "VCS"; +static const char patchCommandKeyC[] = "PatchCommand"; +static const char patchCommandDefaultC[] = "patch"; + +namespace Core { + +static QString readLegacyCommand() +{ + QSettings *s = Core::ICore::settings(); + + s->beginGroup(QLatin1String(legacySettingsGroupC)); + const bool legacyExists = s->contains(QLatin1String(patchCommandKeyC)); + const QString legacyCommand = s->value(QLatin1String(patchCommandKeyC), QLatin1String(patchCommandDefaultC)).toString(); + if (legacyExists) + s->remove(QLatin1String(patchCommandKeyC)); + s->endGroup(); + + if (legacyExists && legacyCommand != QLatin1String(patchCommandDefaultC)) + PatchTool::setPatchCommand(legacyCommand); + + return legacyCommand; +} + +QString PatchTool::patchCommand() +{ + QSettings *s = Core::ICore::settings(); + + const QString defaultCommand = readLegacyCommand(); // replace it with QLatin1String(patchCommandDefaultC) when dropping legacy stuff + + s->beginGroup(QLatin1String(settingsGroupC)); + const QString command = s->value(QLatin1String(patchCommandKeyC), defaultCommand).toString(); + s->endGroup(); + + return command; +} + +void PatchTool::setPatchCommand(const QString &newCommand) +{ + QSettings *s = Core::ICore::settings(); + s->beginGroup(QLatin1String(settingsGroupC)); + s->setValue(QLatin1String(patchCommandKeyC), newCommand); + s->endGroup(); +} + +bool PatchTool::runPatch(const QByteArray &input, const QString &workingDirectory, + int strip, bool reverse) +{ + const QString patch = patchCommand(); + if (patch.isEmpty()) { + MessageManager::write(QApplication::translate("Core::PatchTool", "There is no patch-command configured in the general \"Environment\" settings.")); + return false; + } + + QProcess patchProcess; + if (!workingDirectory.isEmpty()) + patchProcess.setWorkingDirectory(workingDirectory); + QStringList args(QLatin1String("-p") + QString::number(strip)); + if (reverse) + args << QLatin1String("-R"); + MessageManager::write(QApplication::translate("Core::PatchTool", "Executing in %1: %2 %3"). + arg(QDir::toNativeSeparators(workingDirectory), + QDir::toNativeSeparators(patch), args.join(QLatin1String(" ")))); + patchProcess.start(patch, args); + if (!patchProcess.waitForStarted()) { + MessageManager::write(QApplication::translate("Core::PatchTool", "Unable to launch \"%1\": %2").arg(patch, patchProcess.errorString())); + return false; + } + patchProcess.write(input); + patchProcess.closeWriteChannel(); + QByteArray stdOut; + QByteArray stdErr; + if (!Utils::SynchronousProcess::readDataFromProcess(patchProcess, 30000, &stdOut, &stdErr, true)) { + Utils::SynchronousProcess::stopProcess(patchProcess); + MessageManager::write(QApplication::translate("Core::PatchTool", "A timeout occurred running \"%1\"").arg(patch)); + return false; + + } + if (!stdOut.isEmpty()) + MessageManager::write(QString::fromLocal8Bit(stdOut)); + if (!stdErr.isEmpty()) + MessageManager::write(QString::fromLocal8Bit(stdErr)); + + if (patchProcess.exitStatus() != QProcess::NormalExit) { + MessageManager::write(QApplication::translate("Core::PatchTool", "\"%1\" crashed.").arg(patch)); + return false; + } + if (patchProcess.exitCode() != 0) { + MessageManager::write(QApplication::translate("Core::PatchTool", "\"%1\" failed (exit code %2).").arg(patch).arg(patchProcess.exitCode())); + return false; + } + return true; +} + + +} // namespace Core diff --git a/src/plugins/coreplugin/patchtool.h b/src/plugins/coreplugin/patchtool.h new file mode 100644 index 0000000000..30c3b7bfe9 --- /dev/null +++ b/src/plugins/coreplugin/patchtool.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** 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 CORE_PATCHTOOL_H +#define CORE_PATCHTOOL_H + +#include "coreplugin/core_global.h" + +#include <QString> + +namespace Core { + +class CORE_EXPORT PatchTool +{ +public: + static QString patchCommand(); + static void setPatchCommand(const QString &newCommand); + + // Utility to run the 'patch' command + static bool runPatch(const QByteArray &input, const QString &workingDirectory = QString(), + int strip = 0, bool reverse = false); +}; + +} // namespace Core + +#endif // CORE_PATCHTOOL_H |