diff --git a/src/plugins/bazaar/clonewizard.cpp b/src/plugins/bazaar/clonewizard.cpp index 6809cfb84ab..76947850f06 100644 --- a/src/plugins/bazaar/clonewizard.cpp +++ b/src/plugins/bazaar/clonewizard.cpp @@ -35,7 +35,7 @@ #include "bazaarsettings.h" #include -#include +#include #include #include @@ -77,13 +77,13 @@ QList CloneWizard::createParameterPages(const QString &path) return wizardPageList; } -QSharedPointer CloneWizard::createJob(const QList ¶meterPages, - QString *checkoutPath) +VcsBase::Command *CloneWizard::createCommand(const QList ¶meterPages, + QString *checkoutPath) { const CloneWizardPage *page = qobject_cast(parameterPages.front()); if (!page) - return QSharedPointer(); + return 0; const BazaarSettings &settings = BazaarPlugin::instance()->settings(); *checkoutPath = page->path() + QLatin1Char('/') + page->directory(); @@ -111,7 +111,8 @@ QSharedPointer CloneWizard::createJob(const QList< args << client->vcsCommandString(BazaarClient::CloneCommand) << extraOptions << page->repository() << page->directory(); - VcsBase::ProcessCheckoutJob *job = new VcsBase::ProcessCheckoutJob; - job->addStep(settings.binaryPath(), args, page->path()); - return QSharedPointer(job); + VcsBase::Command *command = new VcsBase::Command(settings.binaryPath(), page->path(), + client->processEnvironment()); + command->addJob(args, -1); + return command; } diff --git a/src/plugins/bazaar/clonewizard.h b/src/plugins/bazaar/clonewizard.h index 06d5f9c1ac9..4dd23652046 100644 --- a/src/plugins/bazaar/clonewizard.h +++ b/src/plugins/bazaar/clonewizard.h @@ -50,8 +50,8 @@ public: protected: QList createParameterPages(const QString &path); - QSharedPointer createJob(const QList ¶meterPages, - QString *checkoutPath); + VcsBase::Command *createCommand(const QList ¶meterPages, + QString *checkoutPath); private: const QIcon m_icon; diff --git a/src/plugins/cvs/checkoutwizard.cpp b/src/plugins/cvs/checkoutwizard.cpp index 0fa3882847a..3572a5c1006 100644 --- a/src/plugins/cvs/checkoutwizard.cpp +++ b/src/plugins/cvs/checkoutwizard.cpp @@ -32,7 +32,7 @@ #include "cvsplugin.h" #include -#include +#include #include #include #include @@ -75,13 +75,13 @@ QList CheckoutWizard::createParameterPages(const QString &path) return rc; } -QSharedPointer CheckoutWizard::createJob(const QList ¶meterPages, - QString *checkoutPath) +VcsBase::Command *CheckoutWizard::createCommand(const QList ¶meterPages, + QString *checkoutPath) { // Collect parameters for the checkout command. // CVS does not allow for checking out into a different directory. const CheckoutWizardPage *cwp = qobject_cast(parameterPages.front()); - QTC_ASSERT(cwp, return QSharedPointer()); + QTC_ASSERT(cwp, return 0); const CvsSettings settings = CvsPlugin::instance()->settings(); const QString binary = settings.cvsBinaryPath; QStringList args; @@ -90,9 +90,10 @@ QSharedPointer CheckoutWizard::createJob(const QLi const QString workingDirectory = cwp->path(); *checkoutPath = workingDirectory + QLatin1Char('/') + repository; - VcsBase::ProcessCheckoutJob *job = new VcsBase::ProcessCheckoutJob; - job->addStep(binary, settings.addOptions(args), workingDirectory); - return QSharedPointer(job); + VcsBase::Command *command = new VcsBase::Command(binary, workingDirectory, + QProcessEnvironment::systemEnvironment()); + command->addJob(settings.addOptions(args), -1); + return command; } } // namespace Internal diff --git a/src/plugins/cvs/checkoutwizard.h b/src/plugins/cvs/checkoutwizard.h index 28068c1e1f4..1ab5d36054f 100644 --- a/src/plugins/cvs/checkoutwizard.h +++ b/src/plugins/cvs/checkoutwizard.h @@ -49,8 +49,8 @@ public: protected: // BaseCheckoutWizard QList createParameterPages(const QString &path); - QSharedPointer createJob(const QList ¶meterPage, - QString *checkoutPath); + VcsBase::Command *createCommand(const QList ¶meterPage, + QString *checkoutPath); }; } // namespace Internal diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp index 7ed99b96e35..2f452695221 100644 --- a/src/plugins/cvs/cvsplugin.cpp +++ b/src/plugins/cvs/cvsplugin.cpp @@ -225,6 +225,7 @@ bool CvsPlugin::initialize(const QStringList &arguments, QString *errorMessage) using namespace Core::Constants; using namespace ExtensionSystem; + using Core::Command; initializeVcs(new CvsControl(this)); diff --git a/src/plugins/git/clonewizard.cpp b/src/plugins/git/clonewizard.cpp index d3f99c68c29..b84ce3bda57 100644 --- a/src/plugins/git/clonewizard.cpp +++ b/src/plugins/git/clonewizard.cpp @@ -33,7 +33,6 @@ #include "gitplugin.h" #include "gitversioncontrol.h" -#include #include #include #include @@ -76,8 +75,8 @@ QList CloneWizard::createParameterPages(const QString &path) return rc; } -QSharedPointer CloneWizard::createJob(const QList ¶meterPages, - QString *checkoutPath) +VcsBase::Command *CloneWizard::createCommand(const QList ¶meterPages, + QString *checkoutPath) { // Collect parameters for the clone command. const CloneWizardPage *cwp = 0; @@ -87,7 +86,7 @@ QSharedPointer CloneWizard::createJob(const QList< break; } - QTC_ASSERT(cwp, return QSharedPointer()); + QTC_ASSERT(cwp, return 0); return cwp->createCheckoutJob(checkoutPath); } diff --git a/src/plugins/git/clonewizard.h b/src/plugins/git/clonewizard.h index f0c5af8adf8..16c6f3f3189 100644 --- a/src/plugins/git/clonewizard.h +++ b/src/plugins/git/clonewizard.h @@ -49,8 +49,8 @@ public: protected: // BaseCheckoutWizard QList createParameterPages(const QString &path); - QSharedPointer createJob(const QList ¶meterPages, - QString *checkoutPath); + VcsBase::Command *createCommand(const QList ¶meterPages, + QString *checkoutPath); }; } // namespace Internal diff --git a/src/plugins/git/clonewizardpage.cpp b/src/plugins/git/clonewizardpage.cpp index 1ea045141eb..926a5d01d3b 100644 --- a/src/plugins/git/clonewizardpage.cpp +++ b/src/plugins/git/clonewizardpage.cpp @@ -31,7 +31,7 @@ #include "gitplugin.h" #include "gitclient.h" -#include +#include namespace Git { @@ -112,25 +112,24 @@ QString CloneWizardPage::directoryFromRepository(const QString &urlIn) const return url; } -QSharedPointer CloneWizardPage::createCheckoutJob(QString *checkoutPath) const +VcsBase::Command *CloneWizardPage::createCheckoutJob(QString *checkoutPath) const { const Internal::GitClient *client = Internal::GitPlugin::instance()->gitClient(); const QString workingDirectory = path(); const QString checkoutDir = directory(); *checkoutPath = workingDirectory + QLatin1Char('/') + checkoutDir; - const QString binary = client->gitBinaryPath(); - - VcsBase::ProcessCheckoutJob *job = new VcsBase::ProcessCheckoutJob; - const QProcessEnvironment env = client->processEnvironment(); const QString checkoutBranch = branch(); QStringList args(QLatin1String("clone")); if (!checkoutBranch.isEmpty()) args << QLatin1String("--branch") << checkoutBranch; args << repository() << checkoutDir; - job->addStep(binary, args, workingDirectory, env); - return QSharedPointer(job); + VcsBase::Command *command = new VcsBase::Command(client->gitBinaryPath(), workingDirectory, + client->processEnvironment()); + command->addFlags(VcsBase::VcsBasePlugin::MergeOutputChannels); + command->addJob(args, -1); + return command; } QStringList CloneWizardPage::branches(const QString &repository, int *current) diff --git a/src/plugins/git/clonewizardpage.h b/src/plugins/git/clonewizardpage.h index 1b7eb1ef2b8..ab69df8090c 100644 --- a/src/plugins/git/clonewizardpage.h +++ b/src/plugins/git/clonewizardpage.h @@ -35,7 +35,7 @@ #include namespace VcsBase { - class AbstractCheckoutJob; + class Command; } namespace Git { @@ -50,7 +50,7 @@ public: explicit CloneWizardPage(QWidget *parent = 0); ~CloneWizardPage(); - QSharedPointer createCheckoutJob(QString *checkoutPath) const; + VcsBase::Command *createCheckoutJob(QString *checkoutPath) const; protected: QString directoryFromRepository(const QString &r) const; diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index c4ec0671ef6..b5ca2b083e1 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -33,7 +33,6 @@ #include "gitsettings.h" #include -#include #include #include @@ -52,8 +51,9 @@ namespace Core { } namespace VcsBase { - class VcsBaseEditorWidget; + class Command; class SubmitFileModel; + class VcsBaseEditorWidget; } namespace Utils { diff --git a/src/plugins/git/gitorious/gitoriousclonewizard.cpp b/src/plugins/git/gitorious/gitoriousclonewizard.cpp index baa7cdb4638..57c9af726e2 100644 --- a/src/plugins/git/gitorious/gitoriousclonewizard.cpp +++ b/src/plugins/git/gitorious/gitoriousclonewizard.cpp @@ -36,7 +36,6 @@ #include "../gitplugin.h" #include -#include #include #include #include @@ -109,11 +108,11 @@ QList GitoriousCloneWizard::createParameterPages(const QString &pa return rc; } -QSharedPointer GitoriousCloneWizard::createJob(const QList ¶meterPages, - QString *checkoutPath) +VcsBase::Command *GitoriousCloneWizard::createCommand(const QList ¶meterPages, + QString *checkoutPath) { const Git::CloneWizardPage *cwp = qobject_cast(parameterPages.back()); - QTC_ASSERT(cwp, return QSharedPointer()); + QTC_ASSERT(cwp, return 0); return cwp->createCheckoutJob(checkoutPath); } diff --git a/src/plugins/git/gitorious/gitoriousclonewizard.h b/src/plugins/git/gitorious/gitoriousclonewizard.h index 6f7b9418a44..352078749fc 100644 --- a/src/plugins/git/gitorious/gitoriousclonewizard.h +++ b/src/plugins/git/gitorious/gitoriousclonewizard.h @@ -51,8 +51,8 @@ public: protected: // BaseCheckoutWizard QList createParameterPages(const QString &path); - QSharedPointer createJob(const QList ¶meterPages, - QString *checkoutPath); + VcsBase::Command *createCommand(const QList ¶meterPages, + QString *checkoutPath); }; } // namespace Internal diff --git a/src/plugins/mercurial/clonewizard.cpp b/src/plugins/mercurial/clonewizard.cpp index ff777a72b50..53cd84901e7 100644 --- a/src/plugins/mercurial/clonewizard.cpp +++ b/src/plugins/mercurial/clonewizard.cpp @@ -33,7 +33,7 @@ #include "mercurialsettings.h" #include -#include +#include #include #include @@ -74,13 +74,13 @@ QList CloneWizard::createParameterPages(const QString &path) return wizardPageList; } -QSharedPointer CloneWizard::createJob(const QList ¶meterPages, - QString *checkoutPath) +Command *CloneWizard::createCommand(const QList ¶meterPages, + QString *checkoutPath) { const CloneWizardPage *page = qobject_cast(parameterPages.front()); if (!page) - return QSharedPointer(); + return 0; const MercurialSettings &settings = MercurialPlugin::settings(); @@ -90,7 +90,8 @@ QSharedPointer CloneWizard::createJob(const QListrepository() << directory; *checkoutPath = path + QLatin1Char('/') + directory; - ProcessCheckoutJob *job = new ProcessCheckoutJob; - job->addStep(settings.binaryPath(), args, path); - return QSharedPointer(job); + VcsBase::Command *command = new VcsBase::Command(settings.binaryPath(), path, + QProcessEnvironment::systemEnvironment()); + command->addJob(args, -1); + return command; } diff --git a/src/plugins/mercurial/clonewizard.h b/src/plugins/mercurial/clonewizard.h index a0e1f77d052..f8d37d37e85 100644 --- a/src/plugins/mercurial/clonewizard.h +++ b/src/plugins/mercurial/clonewizard.h @@ -49,8 +49,8 @@ public: protected: QList createParameterPages(const QString &path); - QSharedPointer createJob(const QList ¶meterPages, - QString *checkoutPath); + VcsBase::Command *createCommand(const QList ¶meterPages, + QString *checkoutPath); private: const QIcon m_icon; diff --git a/src/plugins/subversion/checkoutwizard.cpp b/src/plugins/subversion/checkoutwizard.cpp index 81c801af1b2..20a7ca6eac9 100644 --- a/src/plugins/subversion/checkoutwizard.cpp +++ b/src/plugins/subversion/checkoutwizard.cpp @@ -32,7 +32,7 @@ #include "subversionplugin.h" #include -#include +#include #include #include #include @@ -75,12 +75,12 @@ QList CheckoutWizard::createParameterPages(const QString &path) return rc; } -QSharedPointer CheckoutWizard::createJob(const QList ¶meterPages, - QString *checkoutPath) +VcsBase::Command *CheckoutWizard::createCommand(const QList ¶meterPages, + QString *checkoutPath) { // Collect parameters for the checkout command. const CheckoutWizardPage *cwp = qobject_cast(parameterPages.front()); - QTC_ASSERT(cwp, return QSharedPointer()); + QTC_ASSERT(cwp, return 0); const SubversionSettings settings = SubversionPlugin::instance()->settings(); const QString binary = settings.binaryPath(); const QString directory = cwp->directory(); @@ -93,9 +93,10 @@ QSharedPointer CheckoutWizard::createJob(const QLi const QString pwd = settings.stringValue(SubversionSettings::passwordKey); args = SubversionPlugin::addAuthenticationOptions(args, user, pwd); } - VcsBase::ProcessCheckoutJob *job = new VcsBase::ProcessCheckoutJob; - job->addStep(binary, args, workingDirectory); - return QSharedPointer(job); + VcsBase::Command *command = new VcsBase::Command(binary, workingDirectory, + QProcessEnvironment::systemEnvironment()); + command->addJob(args, -1); + return command; } } // namespace Internal diff --git a/src/plugins/subversion/checkoutwizard.h b/src/plugins/subversion/checkoutwizard.h index 7bd41dac095..0a4d8fd4ab2 100644 --- a/src/plugins/subversion/checkoutwizard.h +++ b/src/plugins/subversion/checkoutwizard.h @@ -49,8 +49,8 @@ public: protected: // BaseCheckoutWizard QList createParameterPages(const QString &path); - QSharedPointer createJob(const QList ¶meterPage, - QString *checkoutPath); + VcsBase::Command *createCommand(const QList ¶meterPage, + QString *checkoutPath); }; } // namespace Internal diff --git a/src/plugins/vcsbase/basecheckoutwizard.cpp b/src/plugins/vcsbase/basecheckoutwizard.cpp index 7999c6ea998..05cbce2410b 100644 --- a/src/plugins/vcsbase/basecheckoutwizard.cpp +++ b/src/plugins/vcsbase/basecheckoutwizard.cpp @@ -29,7 +29,6 @@ #include "basecheckoutwizard.h" #include "checkoutwizarddialog.h" -#include "checkoutjobs.h" #include @@ -215,8 +214,8 @@ QString BaseCheckoutWizard::openProject(const QString &path, QString *errorMessa void BaseCheckoutWizard::slotProgressPageShown() { - const QSharedPointer job = createJob(d->parameterPages, &(d->checkoutPath)); - d->dialog->start(job); + Command *command = createCommand(d->parameterPages, &(d->checkoutPath)); + d->dialog->start(command); } } // namespace VcsBase diff --git a/src/plugins/vcsbase/basecheckoutwizard.h b/src/plugins/vcsbase/basecheckoutwizard.h index 4ca72d6ff2a..8bc15810376 100644 --- a/src/plugins/vcsbase/basecheckoutwizard.h +++ b/src/plugins/vcsbase/basecheckoutwizard.h @@ -45,7 +45,7 @@ namespace Internal { class BaseCheckoutWizardPrivate; } -class AbstractCheckoutJob; +class Command; class VCSBASE_EXPORT BaseCheckoutWizard : public Core::IWizard { @@ -73,8 +73,8 @@ public: protected: virtual QList createParameterPages(const QString &path) = 0; - virtual QSharedPointer createJob(const QList ¶meterPages, - QString *checkoutPath) = 0; + virtual Command *createCommand(const QList ¶meterPages, + QString *checkoutPath) = 0; public slots: void setId(const QString &id); diff --git a/src/plugins/vcsbase/checkoutjobs.cpp b/src/plugins/vcsbase/checkoutjobs.cpp deleted file mode 100644 index fae3367cdea..00000000000 --- a/src/plugins/vcsbase/checkoutjobs.cpp +++ /dev/null @@ -1,215 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 "checkoutjobs.h" - -#include "vcsbaseplugin.h" -#include "vcsbaseoutputwindow.h" - -#include -#include -#include -#include -#include -#include - -enum { debug = 0 }; - -/*! - \class VcsBase::AbstractCheckoutJob - - \brief The AbstractCheckoutJob class is an abstract base class for a job - creating an initial project checkout. - - It should be something that runs in the background producing log messages. - - \sa VcsBase::BaseCheckoutWizard -*/ - -namespace VcsBase { - -namespace Internal { - -// Use a terminal-less process to suppress SSH prompts. -static inline QSharedPointer createProcess() -{ - unsigned flags = 0; - if (VcsBasePlugin::isSshPromptConfigured()) - flags = Utils::SynchronousProcess::UnixTerminalDisabled; - return Utils::SynchronousProcess::createProcess(flags); -} - -class ProcessCheckoutJobStep -{ -public: - ProcessCheckoutJobStep() {} - explicit ProcessCheckoutJobStep(const QString &bin, - const QStringList &args, - const QString &workingDir, - QProcessEnvironment env) : - binary(bin), arguments(args), workingDirectory(workingDir), environment(env) {} - - QString binary; - QStringList arguments; - QString workingDirectory; - QProcessEnvironment environment; -}; - -class ProcessCheckoutJobPrivate -{ -public: - ProcessCheckoutJobPrivate(); - - QSharedPointer process; - QQueue stepQueue; - QString binary; -}; - -ProcessCheckoutJobPrivate::ProcessCheckoutJobPrivate() : - process(createProcess()) -{ -} - -} // namespace Internal - -AbstractCheckoutJob::AbstractCheckoutJob(QObject *parent) : - QObject(parent) -{ -} - -/*! - \class VcsBase::ProcessCheckoutJob - - \brief The ProcessCheckoutJob class is a convenience implementation of a - VcsBase::AbstractCheckoutJob using a QProcess. -*/ - -ProcessCheckoutJob::ProcessCheckoutJob(QObject *parent) : - AbstractCheckoutJob(parent), - d(new Internal::ProcessCheckoutJobPrivate) -{ - connect(d->process.data(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(slotError(QProcess::ProcessError))); - connect(d->process.data(), SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotFinished(int,QProcess::ExitStatus))); - connect(d->process.data(), SIGNAL(readyReadStandardOutput()), this, SLOT(slotOutput())); - d->process->setProcessChannelMode(QProcess::MergedChannels); - d->process->closeWriteChannel(); -} - -ProcessCheckoutJob::~ProcessCheckoutJob() -{ - delete d; -} - -void ProcessCheckoutJob::addStep(const QString &binary, - const QStringList &args, - const QString &workingDirectory, - const QProcessEnvironment &env) -{ - if (debug) - qDebug() << "ProcessCheckoutJob::addStep" << binary << args << workingDirectory; - d->stepQueue.enqueue(Internal::ProcessCheckoutJobStep(binary, args, workingDirectory, env)); -} - -void ProcessCheckoutJob::slotOutput() -{ - const QString s = Utils::SynchronousProcess::normalizeNewlines( - QString::fromLocal8Bit(d->process->readAllStandardOutput())); - if (debug) - qDebug() << s; - emit output(s.trimmed()); -} - -void ProcessCheckoutJob::slotError(QProcess::ProcessError error) -{ - switch (error) { - case QProcess::FailedToStart: - emit failed(tr("Unable to start %1: %2"). - arg(QDir::toNativeSeparators(d->binary), d->process->errorString())); - break; - default: - emit failed(d->process->errorString()); - break; - } -} - -void ProcessCheckoutJob::slotFinished (int exitCode, QProcess::ExitStatus exitStatus) -{ - if (debug) - qDebug() << "finished" << exitCode << exitStatus; - - switch (exitStatus) { - case QProcess::NormalExit: - emit output(tr("The process terminated with exit code %1.").arg(exitCode)); - if (exitCode == 0) - slotNext(); - else - emit failed(tr("The process returned exit code %1.").arg(exitCode)); - break; - case QProcess::CrashExit: - emit failed(tr("The process terminated in an abnormal way.")); - break; - } -} - -void ProcessCheckoutJob::start() -{ - QTC_ASSERT(!d->stepQueue.empty(), return); - slotNext(); -} - -void ProcessCheckoutJob::slotNext() -{ - if (d->stepQueue.isEmpty()) { - emit succeeded(); - return; - } - // Launch next - const Internal::ProcessCheckoutJobStep step = d->stepQueue.dequeue(); - d->process->setWorkingDirectory(step.workingDirectory); - - // Set up SSH correctly. - QProcessEnvironment processEnv = step.environment; - VcsBasePlugin::setProcessEnvironment(&processEnv, false); - d->process->setProcessEnvironment(processEnv); - - d->binary = step.binary; - emit output(VcsBaseOutputWindow::msgExecutionLogEntry(step.workingDirectory, d->binary, step.arguments)); - d->process->start(d->binary, step.arguments); -} - -void ProcessCheckoutJob::cancel() -{ - if (debug) - qDebug() << "ProcessCheckoutJob::start"; - - emit output(tr("Stopping...")); - Utils::SynchronousProcess::stopProcess(*d->process); -} - -} // namespace VcsBase diff --git a/src/plugins/vcsbase/checkoutjobs.h b/src/plugins/vcsbase/checkoutjobs.h deleted file mode 100644 index ce4c9a01129..00000000000 --- a/src/plugins/vcsbase/checkoutjobs.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 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 CHECKOUTJOB_H -#define CHECKOUTJOB_H - -#include "vcsbase_global.h" - -#include -#include -#include - -QT_FORWARD_DECLARE_CLASS(QStringList) - -namespace VcsBase { - -namespace Internal { class ProcessCheckoutJobPrivate; } - -/* Abstract base class for a job creating an initial project checkout. - * It should be something that runs in the background producing log - * messages. */ - -class VCSBASE_EXPORT AbstractCheckoutJob : public QObject -{ - Q_OBJECT - -public: - virtual void start() = 0; - virtual void cancel() = 0; - -protected: - explicit AbstractCheckoutJob(QObject *parent = 0); - -signals: - void succeeded(); - void failed(const QString &why); - void output(const QString &what); -}; - -class VCSBASE_EXPORT ProcessCheckoutJob : public AbstractCheckoutJob -{ - Q_OBJECT - -public: - explicit ProcessCheckoutJob(QObject *parent = 0); - ~ProcessCheckoutJob(); - - void addStep(const QString &binary, - const QStringList &args, - const QString &workingDirectory = QString(), - const QProcessEnvironment &env = QProcessEnvironment::systemEnvironment()); - - void start(); - void cancel(); - -private slots: - void slotError(QProcess::ProcessError error); - void slotFinished (int exitCode, QProcess::ExitStatus exitStatus); - void slotOutput(); - void slotNext(); - -private: - Internal::ProcessCheckoutJobPrivate *const d; -}; - -} // namespace VcsBase - -#endif // CHECKOUTJOB_H diff --git a/src/plugins/vcsbase/checkoutprogresswizardpage.cpp b/src/plugins/vcsbase/checkoutprogresswizardpage.cpp index 2c9bf4e35b9..a891348dfba 100644 --- a/src/plugins/vcsbase/checkoutprogresswizardpage.cpp +++ b/src/plugins/vcsbase/checkoutprogresswizardpage.cpp @@ -28,8 +28,9 @@ ****************************************************************************/ #include "checkoutprogresswizardpage.h" -#include "checkoutjobs.h" #include "ui_checkoutprogresswizardpage.h" +#include "command.h" +#include "vcsbaseplugin.h" #include @@ -65,60 +66,67 @@ CheckoutProgressWizardPage::~CheckoutProgressWizardPage() delete ui; } -void CheckoutProgressWizardPage::start(const QSharedPointer &job) +void CheckoutProgressWizardPage::start(Command *command) { - if (job.isNull()) { + if (!command) { ui->logPlainTextEdit->setPlainText(tr("No job running, please abort.")); return; } QTC_ASSERT(m_state != Running, return); - m_job = job; - connect(job.data(), SIGNAL(output(QString)), ui->logPlainTextEdit, SLOT(appendPlainText(QString))); - connect(job.data(), SIGNAL(failed(QString)), this, SLOT(slotFailed(QString))); - connect(job.data(), SIGNAL(succeeded()), this, SLOT(slotSucceeded())); + m_command = command; + command->setProgressiveOutput(true); + connect(command, SIGNAL(output(QString)), this, SLOT(slotOutput(QString))); + connect(command, SIGNAL(finished(bool,int,QVariant)), this, SLOT(slotFinished(bool,int,QVariant))); QApplication::setOverrideCursor(Qt::WaitCursor); ui->logPlainTextEdit->clear(); ui->statusLabel->setText(tr("Checkout started...")); ui->statusLabel->setPalette(QPalette()); m_state = Running; - // Note: Process jobs can emit failed() right from - // the start() method on Windows. - job->start(); + command->execute(); } -void CheckoutProgressWizardPage::slotFailed(const QString &why) +void CheckoutProgressWizardPage::slotFinished(bool ok, int exitCode, const QVariant &) { - ui->logPlainTextEdit->appendPlainText(why); - if (m_state == Running) { - m_state = Failed; - QApplication::restoreOverrideCursor(); - ui->statusLabel->setText(tr("Failed.")); - QPalette palette = ui->statusLabel->palette(); - palette.setColor(QPalette::Active, QPalette::Text, Qt::red); - ui->statusLabel->setPalette(palette); - emit terminated(false); + if (ok && exitCode == 0) { + if (m_state == Running) { + m_state = Succeeded; + QApplication::restoreOverrideCursor(); + ui->statusLabel->setText(tr("Succeeded.")); + QPalette palette = ui->statusLabel->palette(); + palette.setColor(QPalette::Active, QPalette::Text, Qt::green); + ui->statusLabel->setPalette(palette); + emit completeChanged(); + emit terminated(true); + } + } else { + ui->logPlainTextEdit->appendPlainText(m_error); + if (m_state == Running) { + m_state = Failed; + QApplication::restoreOverrideCursor(); + ui->statusLabel->setText(tr("Failed.")); + QPalette palette = ui->statusLabel->palette(); + palette.setColor(QPalette::Active, QPalette::Text, Qt::red); + ui->statusLabel->setPalette(palette); + emit terminated(false); + } } } -void CheckoutProgressWizardPage::slotSucceeded() +void CheckoutProgressWizardPage::slotOutput(const QString &text) { - if (m_state == Running) { - m_state = Succeeded; - QApplication::restoreOverrideCursor(); - ui->statusLabel->setText(tr("Succeeded.")); - QPalette palette = ui->statusLabel->palette(); - palette.setColor(QPalette::Active, QPalette::Text, Qt::green); - ui->statusLabel->setPalette(palette); - emit completeChanged(); - emit terminated(true); - } + ui->logPlainTextEdit->appendPlainText(text.trimmed()); +} + +void CheckoutProgressWizardPage::slotError(const QString &text) +{ + m_error.append(text); } void CheckoutProgressWizardPage::terminate() { - if (!m_job.isNull()) - m_job->cancel(); + if (m_command) + m_command->terminate(); } bool CheckoutProgressWizardPage::isComplete() const diff --git a/src/plugins/vcsbase/checkoutprogresswizardpage.h b/src/plugins/vcsbase/checkoutprogresswizardpage.h index 87136507ed6..7d317e6a182 100644 --- a/src/plugins/vcsbase/checkoutprogresswizardpage.h +++ b/src/plugins/vcsbase/checkoutprogresswizardpage.h @@ -34,7 +34,7 @@ #include namespace VcsBase { -class AbstractCheckoutJob; +class Command; namespace Internal { @@ -50,7 +50,7 @@ public: explicit CheckoutProgressWizardPage(QWidget *parent = 0); ~CheckoutProgressWizardPage(); - void start(const QSharedPointer &job); + void start(Command *command); virtual bool isComplete() const; bool isRunning() const{ return m_state == Running; } @@ -61,12 +61,15 @@ signals: void terminated(bool success); private slots: - void slotFailed(const QString &); - void slotSucceeded(); + void slotFinished(bool ok, int exitCode, const QVariant &cookie); + void slotOutput(const QString &text); + void slotError(const QString &text); private: Ui::CheckoutProgressWizardPage *ui; - QSharedPointer m_job; + + Command *m_command; + QString m_error; State m_state; }; diff --git a/src/plugins/vcsbase/checkoutwizarddialog.cpp b/src/plugins/vcsbase/checkoutwizarddialog.cpp index fecf506c31a..a57096faada 100644 --- a/src/plugins/vcsbase/checkoutwizarddialog.cpp +++ b/src/plugins/vcsbase/checkoutwizarddialog.cpp @@ -29,7 +29,6 @@ #include "checkoutwizarddialog.h" #include "basecheckoutwizard.h" -#include "checkoutjobs.h" #include "checkoutprogresswizardpage.h" #include @@ -75,11 +74,11 @@ void CheckoutWizardDialog::slotTerminated(bool success) button(QWizard::BackButton)->setEnabled(true); } -void CheckoutWizardDialog::start(const QSharedPointer &job) +void CheckoutWizardDialog::start(Command *command) { // No "back" available while running. button(QWizard::BackButton)->setEnabled(false); - m_progressPage->start(job); + m_progressPage->start(command); } void CheckoutWizardDialog::reject() diff --git a/src/plugins/vcsbase/checkoutwizarddialog.h b/src/plugins/vcsbase/checkoutwizarddialog.h index 18181e25c75..7ef0a60389e 100644 --- a/src/plugins/vcsbase/checkoutwizarddialog.h +++ b/src/plugins/vcsbase/checkoutwizarddialog.h @@ -35,7 +35,7 @@ #include namespace VcsBase { -class AbstractCheckoutJob; +class Command; namespace Internal { class CheckoutProgressWizardPage; @@ -48,7 +48,7 @@ public: explicit CheckoutWizardDialog(const QList ¶meterPages, QWidget *parent = 0); - void start(const QSharedPointer &job); + void start(VcsBase::Command *command); signals: void progressPageShown(); diff --git a/src/plugins/vcsbase/command.cpp b/src/plugins/vcsbase/command.cpp index 97532a93316..e05e1328a83 100644 --- a/src/plugins/vcsbase/command.cpp +++ b/src/plugins/vcsbase/command.cpp @@ -99,6 +99,8 @@ public: QTextCodec *m_codec; const QString m_sshPasswordPrompt; ProgressParser *m_progressParser; + VcsBase::VcsBaseOutputWindow *m_outputWindow; + bool m_progressiveOutput; QList m_jobs; @@ -117,6 +119,8 @@ CommandPrivate::CommandPrivate(const QString &binary, m_codec(0), m_sshPasswordPrompt(VcsBasePlugin::sshPrompt()), m_progressParser(0), + m_outputWindow(VcsBase::VcsBaseOutputWindow::instance()), + m_progressiveOutput(false), m_lastExecSuccess(false), m_lastExecExitCode(-1) { @@ -258,9 +262,11 @@ void Command::run(QFutureInterface &future) } if (!future.isCanceled()) { - emit output(stdOut); - if (!stdErr.isEmpty()) - emit errorText(stdErr); + if (!d->m_progressiveOutput) { + emit output(stdOut); + if (!stdErr.isEmpty()) + emit errorText(stdErr); + } emit finished(d->m_lastExecSuccess, d->m_lastExecExitCode, cookie()); if (d->m_lastExecSuccess) @@ -313,8 +319,6 @@ Utils::SynchronousProcessResponse Command::runVcs(const QStringList &arguments, return response; } - VcsBase::VcsBaseOutputWindow *outputWindow = VcsBase::VcsBaseOutputWindow::instance(); - if (!(d->m_flags & VcsBasePlugin::SuppressCommandLogging)) emit outputProxy.appendCommand(d->m_workingDirectory, d->m_binaryPath, arguments); @@ -372,16 +376,19 @@ Utils::SynchronousProcessResponse Command::runVcs(const QStringList &arguments, // connect stderr to the output window if desired if (d->m_flags & VcsBasePlugin::MergeOutputChannels) { process.setProcessChannelMode(QProcess::MergedChannels); - } else if (!(d->m_flags & VcsBasePlugin::SuppressStdErrInLogWindow)) { + } else if (d->m_progressiveOutput + || !(d->m_flags & VcsBasePlugin::SuppressStdErrInLogWindow)) { process.setStdErrBufferedSignalsEnabled(true); - connect(&process, SIGNAL(stdErrBuffered(QString,bool)), outputWindow, SLOT(appendError(QString))); + connect(&process, SIGNAL(stdErrBuffered(QString,bool)), + this, SLOT(bufferedError(QString))); } // connect stdout to the output window if desired - process.setStdOutBufferedSignalsEnabled(true); - connect(&process, SIGNAL(stdOutBuffered(QString,bool)), this, SLOT(bufferedOutput(QString))); - if (d->m_flags & VcsBasePlugin::ShowStdOutInLogWindow) - connect(&process, SIGNAL(stdOutBuffered(QString,bool)), outputWindow, SLOT(append(QString))); + if (d->m_progressParser || d->m_progressiveOutput + || (d->m_flags & VcsBasePlugin::ShowStdOutInLogWindow)) { + process.setStdOutBufferedSignalsEnabled(true); + connect(&process, SIGNAL(stdOutBuffered(QString,bool)), this, SLOT(bufferedOutput(QString))); + } process.setTimeOutMessageBoxEnabled(true); @@ -519,6 +526,18 @@ void Command::bufferedOutput(const QString &text) { if (d->m_progressParser) d->m_progressParser->parseProgress(text); + if (d->m_flags & VcsBasePlugin::ShowStdOutInLogWindow) + d->m_outputWindow->append(text); + if (d->m_progressiveOutput) + emit output(text); +} + +void Command::bufferedError(const QString &text) +{ + if (!(d->m_flags & VcsBasePlugin::SuppressStdErrInLogWindow)) + d->m_outputWindow->appendError(text); + if (d->m_progressiveOutput) + emit errorText(text); } const QVariant &Command::cookie() const @@ -548,6 +567,11 @@ void Command::setProgressParser(ProgressParser *parser) d->m_progressParser = parser; } +void Command::setProgressiveOutput(bool progressive) +{ + d->m_progressiveOutput = progressive; +} + ProgressParser::ProgressParser() : m_future(0), m_futureMutex(new QMutex) diff --git a/src/plugins/vcsbase/command.h b/src/plugins/vcsbase/command.h index e0164dd7f47..dd41f91dcf0 100644 --- a/src/plugins/vcsbase/command.h +++ b/src/plugins/vcsbase/command.h @@ -101,6 +101,7 @@ public: void setCodec(QTextCodec *codec); void setProgressParser(ProgressParser *parser); + void setProgressiveOutput(bool progressive); Utils::SynchronousProcessResponse runVcs(const QStringList &arguments, int timeoutMS); // Make sure to not pass through the event loop at all: @@ -113,6 +114,7 @@ private: private slots: void bufferedOutput(const QString &text); + void bufferedError(const QString &text); signals: void output(const QString &); diff --git a/src/plugins/vcsbase/vcsbase.pro b/src/plugins/vcsbase/vcsbase.pro index 3faed8be6b0..807d501d17a 100644 --- a/src/plugins/vcsbase/vcsbase.pro +++ b/src/plugins/vcsbase/vcsbase.pro @@ -20,7 +20,6 @@ HEADERS += vcsbase_global.h \ basecheckoutwizard.h \ checkoutwizarddialog.h \ checkoutprogresswizardpage.h \ - checkoutjobs.h \ basecheckoutwizardpage.h \ vcsbaseoutputwindow.h \ cleandialog.h \ @@ -50,7 +49,6 @@ SOURCES += vcsplugin.cpp \ basecheckoutwizard.cpp \ checkoutwizarddialog.cpp \ checkoutprogresswizardpage.cpp \ - checkoutjobs.cpp \ basecheckoutwizardpage.cpp \ vcsbaseoutputwindow.cpp \ cleandialog.cpp \ diff --git a/src/plugins/vcsbase/vcsbase.qbs b/src/plugins/vcsbase/vcsbase.qbs index a3b1e11ca6f..c901d3d9a18 100644 --- a/src/plugins/vcsbase/vcsbase.qbs +++ b/src/plugins/vcsbase/vcsbase.qbs @@ -25,8 +25,6 @@ QtcPlugin { "basevcseditorfactory.h", "basevcssubmiteditorfactory.cpp", "basevcssubmiteditorfactory.h", - "checkoutjobs.cpp", - "checkoutjobs.h", "checkoutprogresswizardpage.cpp", "checkoutprogresswizardpage.h", "checkoutprogresswizardpage.ui", diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h index 569e893f2c1..91d90d1e332 100644 --- a/src/plugins/vcsbase/vcsbaseclient.h +++ b/src/plugins/vcsbase/vcsbaseclient.h @@ -118,6 +118,7 @@ public: virtual QString findTopLevelForFile(const QFileInfo &file) const = 0; virtual VcsBaseClientSettings *settings() const; + virtual QProcessEnvironment processEnvironment() const; signals: void parsedStatus(const QList &statusList); @@ -175,8 +176,6 @@ protected: const char *registerDynamicProperty, const QString &dynamicPropertyValue) const; - virtual QProcessEnvironment processEnvironment() const; - enum JobOutputBindMode { NoOutputBind, VcsWindowOutputBind