Add a clone wizard for version control (base classes + git/svn).

Task-number: 244831
This commit is contained in:
Friedemann Kleint
2009-07-17 17:19:23 +02:00
parent b799f32b96
commit 9f14b79cc6
32 changed files with 1890 additions and 112 deletions
+91
View File
@@ -0,0 +1,91 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#include "clonewizard.h"
#include "clonewizardpage.h"
#include "gitplugin.h"
#include "gitclient.h"
#include <vcsbase/checkoutjobs.h>
#include <utils/qtcassert.h>
#include <QtGui/QIcon>
namespace Git {
namespace Internal {
CloneWizard::CloneWizard(QObject *parent) :
VCSBase::BaseCheckoutWizard(parent)
{
}
QIcon CloneWizard::icon() const
{
return QIcon();
}
QString CloneWizard::description() const
{
return tr("Clones a project from a git repository.");
}
QString CloneWizard::name() const
{
return tr("Git Checkout");
}
QWizardPage *CloneWizard::createParameterPage(const QString &path)
{
CloneWizardPage *cwp = new CloneWizardPage;
cwp->setPath(path);
return cwp;
}
QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizard::createJob(const QWizardPage *parameterPage,
QString *checkoutPath)
{
// Collect parameters for the clone command.
const CloneWizardPage *cwp = qobject_cast<const CloneWizardPage *>(parameterPage);
QTC_ASSERT(cwp, return QSharedPointer<VCSBase::AbstractCheckoutJob>())
const GitClient *client = GitPlugin::instance()->gitClient();
QStringList args = client->binary();
const QString workingDirectory = cwp->path();
const QString directory = cwp->directory();
*checkoutPath = workingDirectory + QLatin1Char('/') + directory;
args << QLatin1String("clone") << cwp->repository() << directory;
const QString binary = args.front();
args.pop_front();
VCSBase::AbstractCheckoutJob *job = new VCSBase::ProcessCheckoutJob(binary, args, workingDirectory,
client->processEnvironment());
return QSharedPointer<VCSBase::AbstractCheckoutJob>(job);
}
} // namespace Internal
} // namespace Git
+58
View File
@@ -0,0 +1,58 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#ifndef CLONEWIZARD_H
#define CLONEWIZARD_H
#include <vcsbase/basecheckoutwizard.h>
namespace Git {
namespace Internal {
class CloneWizard : public VCSBase::BaseCheckoutWizard
{
public:
explicit CloneWizard(QObject *parent = 0);
// IWizard
virtual QIcon icon() const;
virtual QString description() const;
virtual QString name() const;
protected:
// BaseCheckoutWizard
virtual QWizardPage *createParameterPage(const QString &path);
virtual QSharedPointer<VCSBase::AbstractCheckoutJob> createJob(const QWizardPage *parameterPage,
QString *checkoutPath);
};
} // namespace Internal
} // namespace Git
#endif // CLONEWIZARD_H
+83
View File
@@ -0,0 +1,83 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#include "clonewizardpage.h"
namespace Git {
namespace Internal {
CloneWizardPage::CloneWizardPage(QWidget *parent) :
VCSBase::BaseCheckoutWizardPage(parent),
m_mainLinePostfix(QLatin1String("/mainline.git")),
m_gitPostFix(QLatin1String(".git")),
m_protocolDelimiter(QLatin1String("://"))
{
setSubTitle(tr("Specify repository URL, checkout directory and path."));
setRepositoryLabel(tr("Clone URL:"));
}
QString CloneWizardPage::directoryFromRepository(const QString &urlIn) const
{
/* Try to figure out a good directory name from something like:
* 'user@host:qt/qt.git', 'http://host/qt/qt.git' 'local repo'
* ------> 'qt' . */
QString url = urlIn.trimmed();
const QChar slash = QLatin1Char('/');
// remove host
const int protocolDelimiterPos = url.indexOf(m_protocolDelimiter); // "://"
const int startRepoSearchPos = protocolDelimiterPos == -1 ? 0 : protocolDelimiterPos + m_protocolDelimiter.size();
int repoPos = url.indexOf(QLatin1Char(':'), startRepoSearchPos);
if (repoPos == -1)
repoPos = url.indexOf(slash, startRepoSearchPos);
if (repoPos != -1)
url.remove(0, repoPos + 1);
// Remove postfixes
if (url.endsWith(m_mainLinePostfix)) {
url.truncate(url.size() - m_mainLinePostfix.size());
} else {
if (url.endsWith(m_gitPostFix)) {
url.truncate(url.size() - m_gitPostFix.size());
}
}
// Check for equal parts, something like "qt/qt" -> "qt"
const int slashPos = url.indexOf(slash);
if (slashPos != -1 && slashPos == (url.size() - 1) / 2) {
if (url.leftRef(slashPos) == url.rightRef(slashPos))
url.truncate(slashPos);
}
// fix invalid characters
const QChar dash = QLatin1Char('-');
url.replace(slash, dash);
url.replace(QLatin1Char('.'), dash);
return url;
}
} // namespace Internal
} // namespace Git
+56
View File
@@ -0,0 +1,56 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#ifndef CLONEWIZARDPAGE_H
#define CLONEWIZARDPAGE_H
#include <vcsbase/basecheckoutwizardpage.h>
namespace Git {
namespace Internal {
class CloneWizardPage : public VCSBase::BaseCheckoutWizardPage
{
Q_OBJECT
public:
CloneWizardPage(QWidget *parent = 0);
protected:
virtual QString directoryFromRepository(const QString &r) const;
private:
const QString m_mainLinePostfix;
const QString m_gitPostFix;
const QString m_protocolDelimiter;
};
} // namespace Internal
} // namespace Git
#endif // CLONEWIZARDPAGE_H
+6 -2
View File
@@ -21,7 +21,9 @@ HEADERS += gitplugin.h \
gitsettings.h \ gitsettings.h \
branchdialog.h \ branchdialog.h \
branchmodel.h \ branchmodel.h \
gitcommand.h gitcommand.h \
clonewizard.h \
clonewizardpage.h
SOURCES += gitplugin.cpp \ SOURCES += gitplugin.cpp \
gitoutputwindow.cpp \ gitoutputwindow.cpp \
gitclient.cpp \ gitclient.cpp \
@@ -36,7 +38,9 @@ SOURCES += gitplugin.cpp \
gitsettings.cpp \ gitsettings.cpp \
branchdialog.cpp \ branchdialog.cpp \
branchmodel.cpp \ branchmodel.cpp \
gitcommand.cpp gitcommand.cpp \
clonewizard.cpp \
clonewizardpage.cpp
FORMS += changeselectiondialog.ui \ FORMS += changeselectiondialog.ui \
settingspage.ui \ settingspage.ui \
gitsubmitpanel.ui \ gitsubmitpanel.ui \
+27 -17
View File
@@ -480,11 +480,7 @@ GitCommand *GitClient::createCommand(const QString &workingDirectory,
GitOutputWindow *outputWindow = m_plugin->outputWindow(); GitOutputWindow *outputWindow = m_plugin->outputWindow();
ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment(); GitCommand* command = new GitCommand(binary(), workingDirectory, processEnvironment());
if (m_settings.adoptPath)
environment.set(QLatin1String("PATH"), m_settings.path);
GitCommand* command = new GitCommand(m_binaryPath, workingDirectory, environment);
if (outputToWindow) { if (outputToWindow) {
if (!editor) { // assume that the commands output is the important thing if (!editor) { // assume that the commands output is the important thing
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(appendDataAndPopup(QByteArray))); connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(appendDataAndPopup(QByteArray)));
@@ -527,6 +523,26 @@ void GitClient::appendAndPopup(const QString &text)
m_plugin->outputWindow()->popup(false); m_plugin->outputWindow()->popup(false);
} }
// Return fixed arguments required to run
QStringList GitClient::binary() const
{
#ifdef Q_OS_WIN
QStringList args;
args << QLatin1String("cmd.exe") << QLatin1String("/c") << m_binaryPath;
return args;
#else
return QStringList(m_binaryPath);
#endif
}
QStringList GitClient::processEnvironment() const
{
ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment();
if (m_settings.adoptPath)
environment.set(QLatin1String("PATH"), m_settings.path);
return environment.toStringList();
}
bool GitClient::synchronousGit(const QString &workingDirectory, bool GitClient::synchronousGit(const QString &workingDirectory,
const QStringList &arguments, const QStringList &arguments,
QByteArray* outputText, QByteArray* outputText,
@@ -541,19 +557,13 @@ bool GitClient::synchronousGit(const QString &workingDirectory,
QProcess process; QProcess process;
process.setWorkingDirectory(workingDirectory); process.setWorkingDirectory(workingDirectory);
process.setEnvironment(processEnvironment());
ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment(); QStringList args = binary();
if (m_settings.adoptPath) const QString executable = args.front();
environment.set(QLatin1String("PATH"), m_settings.path); args.pop_front();
process.setEnvironment(environment.toStringList()); args.append(arguments);
process.start(executable, arguments);
#ifdef Q_OS_WIN
QStringList args;
args << "/c" << m_binaryPath << arguments;
process.start(QLatin1String("cmd.exe"), args);
#else
process.start(m_binaryPath, arguments);
#endif
process.closeWriteChannel(); process.closeWriteChannel();
if (!process.waitForFinished()) { if (!process.waitForFinished()) {
+3
View File
@@ -135,6 +135,9 @@ public:
GitSettings settings() const; GitSettings settings() const;
void setSettings(const GitSettings &s); void setSettings(const GitSettings &s);
QStringList binary() const; // Executable + basic arguments
QStringList processEnvironment() const;
static QString msgNoChangedFiles(); static QString msgNoChangedFiles();
static const char *noColorOption; static const char *noColorOption;
+8 -21
View File
@@ -44,15 +44,6 @@
namespace Git { namespace Git {
namespace Internal { namespace Internal {
// Convert environment to list, default to system one.
static inline QStringList environmentToList(const ProjectExplorer::Environment &environment)
{
const QStringList list = environment.toStringList();
if (!list.empty())
return list;
return ProjectExplorer::Environment::systemEnvironment().toStringList();
}
static QString msgTermination(int exitCode, const QString &binaryPath, const QStringList &args) static QString msgTermination(int exitCode, const QString &binaryPath, const QStringList &args)
{ {
QString cmd = QFileInfo(binaryPath).baseName(); QString cmd = QFileInfo(binaryPath).baseName();
@@ -71,14 +62,16 @@ GitCommand::Job::Job(const QStringList &a, int t) :
{ {
} }
GitCommand::GitCommand(const QString &binaryPath, GitCommand::GitCommand(const QStringList &binary,
const QString &workingDirectory, const QString &workingDirectory,
ProjectExplorer::Environment &environment) : const QStringList &environment) :
m_binaryPath(binaryPath), m_binaryPath(binary.front()),
m_basicArguments(binary),
m_workingDirectory(workingDirectory), m_workingDirectory(workingDirectory),
m_environment(environmentToList(environment)), m_environment(environment),
m_reportTerminationMode(NoReport) m_reportTerminationMode(NoReport)
{ {
m_basicArguments.pop_front();
} }
GitCommand::TerminationReportMode GitCommand::reportTerminationMode() const GitCommand::TerminationReportMode GitCommand::reportTerminationMode() const
@@ -132,13 +125,7 @@ void GitCommand::run()
if (Git::Constants::debug) if (Git::Constants::debug)
qDebug() << "GitCommand::run" << j << '/' << count << m_jobs.at(j).arguments; qDebug() << "GitCommand::run" << j << '/' << count << m_jobs.at(j).arguments;
#ifdef Q_OS_WIN process.start(m_binaryPath, m_basicArguments + m_jobs.at(j).arguments);
QStringList args;
args << "/c" << m_binaryPath << m_jobs.at(j).arguments;
process.start(QLatin1String("cmd.exe"), args);
#else
process.start(m_binaryPath, m_jobs.at(j).arguments);
#endif
if(!process.waitForStarted()) { if(!process.waitForStarted()) {
ok = false; ok = false;
error += QString::fromLatin1("Error: \"%1\" could not be started: %2").arg(m_binaryPath, process.errorString()); error += QString::fromLatin1("Error: \"%1\" could not be started: %2").arg(m_binaryPath, process.errorString());
+4 -4
View File
@@ -30,9 +30,8 @@
#ifndef GITCOMMAND_H #ifndef GITCOMMAND_H
#define GITCOMMAND_H #define GITCOMMAND_H
#include <projectexplorer/environment.h>
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QStringList>
namespace Git { namespace Git {
namespace Internal { namespace Internal {
@@ -47,9 +46,9 @@ public:
ReportStdout, // This assumes UTF8 ReportStdout, // This assumes UTF8
ReportStderr }; ReportStderr };
explicit GitCommand(const QString &binaryPath, explicit GitCommand(const QStringList &binary,
const QString &workingDirectory, const QString &workingDirectory,
ProjectExplorer::Environment &environment); const QStringList &environment);
void addJob(const QStringList &arguments, int timeout); void addJob(const QStringList &arguments, int timeout);
@@ -79,6 +78,7 @@ private:
}; };
const QString m_binaryPath; const QString m_binaryPath;
QStringList m_basicArguments;
const QString m_workingDirectory; const QString m_workingDirectory;
const QStringList m_environment; const QStringList m_environment;
+19 -56
View File
@@ -37,6 +37,7 @@
#include "gitsubmiteditor.h" #include "gitsubmiteditor.h"
#include "gitversioncontrol.h" #include "gitversioncontrol.h"
#include "branchdialog.h" #include "branchdialog.h"
#include "clonewizard.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h> #include <coreplugin/coreconstants.h>
@@ -139,10 +140,6 @@ GitPlugin::GitPlugin() :
m_gitClient(0), m_gitClient(0),
m_outputWindow(0), m_outputWindow(0),
m_changeSelectionDialog(0), m_changeSelectionDialog(0),
m_settingsPage(0),
m_coreListener(0),
m_submitEditorFactory(0),
m_versionControl(0),
m_changeTmpFile(0), m_changeTmpFile(0),
m_submitActionTriggered(false) m_submitActionTriggered(false)
{ {
@@ -151,42 +148,6 @@ GitPlugin::GitPlugin() :
GitPlugin::~GitPlugin() GitPlugin::~GitPlugin()
{ {
if (m_outputWindow) {
removeObject(m_outputWindow);
delete m_outputWindow;
m_outputWindow = 0;
}
if (m_settingsPage) {
removeObject(m_settingsPage);
delete m_settingsPage;
m_settingsPage = 0;
}
if (!m_editorFactories.empty()) {
foreach (Core::IEditorFactory* pf, m_editorFactories)
removeObject(pf);
qDeleteAll(m_editorFactories);
}
if (m_coreListener) {
removeObject(m_coreListener);
delete m_coreListener;
m_coreListener = 0;
}
if (m_submitEditorFactory) {
removeObject(m_submitEditorFactory);
delete m_submitEditorFactory;
m_submitEditorFactory = 0;
}
if (m_versionControl) {
removeObject(m_versionControl);
delete m_versionControl;
m_versionControl = 0;
}
cleanChangeTmpFile(); cleanChangeTmpFile();
delete m_gitClient; delete m_gitClient;
m_instance = 0; m_instance = 0;
@@ -231,33 +192,30 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
m_core = Core::ICore::instance(); m_core = Core::ICore::instance();
m_gitClient = new GitClient(this); m_gitClient = new GitClient(this);
// Create the globalcontext list to register actions accordingly // Create the globalco6664324b12a3339d18251df1cd69a1da06d1e2dcntext list to register actions accordingly
QList<int> globalcontext; QList<int> globalcontext;
globalcontext << m_core->uniqueIDManager()->uniqueIdentifier(Core::Constants::C_GLOBAL); globalcontext << m_core->uniqueIDManager()->uniqueIdentifier(Core::Constants::C_GLOBAL);
// Create the output Window // Create the output Window
m_outputWindow = new GitOutputWindow(); m_outputWindow = new GitOutputWindow();
addObject(m_outputWindow); addAutoReleasedObject(m_outputWindow);
// Create the settings Page // Create the settings Page
m_settingsPage = new SettingsPage(); addAutoReleasedObject(new SettingsPage());
addObject(m_settingsPage);
static const char *describeSlot = SLOT(show(QString,QString)); static const char *describeSlot = SLOT(show(QString,QString));
const int editorCount = sizeof(editorParameters)/sizeof(VCSBase::VCSBaseEditorParameters); const int editorCount = sizeof(editorParameters)/sizeof(VCSBase::VCSBaseEditorParameters);
for (int i = 0; i < editorCount; i++) { for (int i = 0; i < editorCount; i++)
m_editorFactories.push_back(new GitEditorFactory(editorParameters + i, m_gitClient, describeSlot)); addAutoReleasedObject(new GitEditorFactory(editorParameters + i, m_gitClient, describeSlot));
addObject(m_editorFactories.back());
}
m_coreListener = new CoreListener(this); addAutoReleasedObject(new CoreListener(this));
addObject(m_coreListener);
m_submitEditorFactory = new GitSubmitEditorFactory(&submitParameters); addAutoReleasedObject(new GitSubmitEditorFactory(&submitParameters));
addObject(m_submitEditorFactory);
m_versionControl = new GitVersionControl(m_gitClient); GitVersionControl *versionControl = new GitVersionControl(m_gitClient);
addObject(m_versionControl); addAutoReleasedObject(versionControl);
addAutoReleasedObject(new CloneWizard);
//register actions //register actions
Core::ActionManager *actionManager = m_core->actionManager(); Core::ActionManager *actionManager = m_core->actionManager();
@@ -270,8 +228,8 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
gitContainer->menu()->setTitle(tr("&Git")); gitContainer->menu()->setTitle(tr("&Git"));
toolsContainer->addMenu(gitContainer); toolsContainer->addMenu(gitContainer);
if (QAction *ma = gitContainer->menu()->menuAction()) { if (QAction *ma = gitContainer->menu()->menuAction()) {
ma->setEnabled(m_versionControl->isEnabled()); ma->setEnabled(versionControl->isEnabled());
connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool))); connect(versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool)));
} }
Core::Command *command; Core::Command *command;
@@ -888,4 +846,9 @@ void GitPlugin::setSettings(const GitSettings &s)
m_gitClient->setSettings(s); m_gitClient->setSettings(s);
} }
GitClient *GitPlugin::gitClient() const
{
return m_gitClient;
}
Q_EXPORT_PLUGIN(GitPlugin) Q_EXPORT_PLUGIN(GitPlugin)
+2 -6
View File
@@ -96,10 +96,11 @@ public:
GitOutputWindow *outputWindow() const; GitOutputWindow *outputWindow() const;
GitSettings settings() const; GitSettings settings() const;
void setSettings(const GitSettings &s); void setSettings(const GitSettings &s);
GitClient *gitClient() const;
public slots: public slots:
void updateActions(); void updateActions();
bool editorAboutToClose(Core::IEditor *editor); bool editorAboutToClose(Core::IEditor *editor);
@@ -166,11 +167,6 @@ private:
GitClient *m_gitClient; GitClient *m_gitClient;
GitOutputWindow *m_outputWindow; GitOutputWindow *m_outputWindow;
ChangeSelectionDialog *m_changeSelectionDialog; ChangeSelectionDialog *m_changeSelectionDialog;
SettingsPage *m_settingsPage;
QList<Core::IEditorFactory*> m_editorFactories;
CoreListener *m_coreListener;
Core::IEditorFactory *m_submitEditorFactory;
Core::IVersionControl *m_versionControl;
QString m_submitRepository; QString m_submitRepository;
QStringList m_submitOrigCommitFiles; QStringList m_submitOrigCommitFiles;
QStringList m_submitOrigDeleteFiles; QStringList m_submitOrigDeleteFiles;
+88
View File
@@ -0,0 +1,88 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#include "checkoutwizard.h"
#include "checkoutwizardpage.h"
#include "subversionplugin.h"
#include <vcsbase/checkoutjobs.h>
#include <utils/qtcassert.h>
#include <QtGui/QIcon>
namespace Subversion {
namespace Internal {
CheckoutWizard::CheckoutWizard(QObject *parent) :
VCSBase::BaseCheckoutWizard(parent)
{
}
QIcon CheckoutWizard::icon() const
{
return QIcon();
}
QString CheckoutWizard::description() const
{
return tr("Check-out a project from a Subversion repository.");
}
QString CheckoutWizard::name() const
{
return tr("Subversion Checkout");
}
QWizardPage *CheckoutWizard::createParameterPage(const QString &path)
{
CheckoutWizardPage *cwp = new CheckoutWizardPage;
cwp->setPath(path);
return cwp;
}
QSharedPointer<VCSBase::AbstractCheckoutJob> CheckoutWizard::createJob(const QWizardPage *parameterPage,
QString *checkoutPath)
{
// Collect parameters for the checkout command.
const CheckoutWizardPage *cwp = qobject_cast<const CheckoutWizardPage *>(parameterPage);
QTC_ASSERT(cwp, return QSharedPointer<VCSBase::AbstractCheckoutJob>())
const SubversionSettings settings = SubversionPlugin::subversionPluginInstance()->settings();
const QString binary = settings.svnCommand;
const QString directory = cwp->directory();
QStringList args;
args << QLatin1String("checkout") << cwp->repository() << directory;
const QString workingDirectory = cwp->path();
*checkoutPath = workingDirectory + QLatin1Char('/') + directory;
VCSBase::AbstractCheckoutJob *job = new VCSBase::ProcessCheckoutJob(binary, settings.addOptions(args),
workingDirectory);
return QSharedPointer<VCSBase::AbstractCheckoutJob>(job);
}
} // namespace Internal
} // namespace Subversion
+58
View File
@@ -0,0 +1,58 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#ifndef CHECKOUTWIZARD_H
#define CHECKOUTWIZARD_H
#include <vcsbase/basecheckoutwizard.h>
namespace Subversion {
namespace Internal {
class CheckoutWizard : public VCSBase::BaseCheckoutWizard
{
public:
explicit CheckoutWizard(QObject *parent = 0);
// IWizard
virtual QIcon icon() const;
virtual QString description() const;
virtual QString name() const;
protected:
// BaseCheckoutWizard
virtual QWizardPage *createParameterPage(const QString &path);
virtual QSharedPointer<VCSBase::AbstractCheckoutJob> createJob(const QWizardPage *parameterPage,
QString *checkoutPath);
};
} // namespace Internal
} // namespace Subversion
#endif // CHECKOUTWIZARD_H
@@ -0,0 +1,60 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#include "checkoutwizardpage.h"
namespace Subversion {
namespace Internal {
CheckoutWizardPage::CheckoutWizardPage(QWidget *parent) :
VCSBase::BaseCheckoutWizardPage(parent)
{
setSubTitle(tr("Specify repository, checkout directory and path."));
setRepositoryLabel(tr("Repository:"));
}
QString CheckoutWizardPage::directoryFromRepository(const QString &repoIn) const
{
/* Try to figure out a good directory name from something like:
* "svn://<server>/path1/project" -> project */
QString repo = repoIn.trimmed();
const QChar slash = QLatin1Char('/');
// remove host
const int slashPos = repo.lastIndexOf(slash);
if (slashPos != -1)
repo.remove(0, slashPos + 1);
// fix invalid characters
const QChar dash = QLatin1Char('-');
repo.replace(QLatin1Char('.'), QLatin1Char('-'));
return repo;
}
} // namespace Internal
} // namespace Subversion
@@ -0,0 +1,49 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#ifndef CHECKOUTWIZARDPAGE_H
#define CHECKOUTWIZARDPAGE_H
#include <vcsbase/basecheckoutwizardpage.h>
namespace Subversion {
namespace Internal {
class CheckoutWizardPage : public VCSBase::BaseCheckoutWizardPage {
Q_OBJECT
public:
CheckoutWizardPage(QWidget *parent = 0);
protected:
virtual QString directoryFromRepository(const QString &r) const;
};
} // namespace Internal
} // namespace Subversion
#endif // CHECKOUTWIZARDPAGE_H
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Subversion::Internal::CheckoutWizardPage</class>
<widget class="QWizardPage" name="Subversion::Internal::CheckoutWizardPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>464</width>
<height>302</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<property name="subTitle">
<string>Specify path and repository URL.</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="repositoryLabel">
<property name="text">
<string>Clone URL:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="repositoryLineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="checkoutDirectoryLabel">
<property name="text">
<string>Checkout Directory:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="pathLabel">
<property name="text">
<string>Path:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Core::Utils::PathChooser" name="pathChooser"/>
</item>
<item row="1" column="1">
<widget class="Core::Utils::ProjectNameValidatingLineEdit" name="checkoutDirectoryLineEdit"/>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Core::Utils::ProjectNameValidatingLineEdit</class>
<extends>QLineEdit</extends>
<header location="global">utils/projectnamevalidatinglineedit.h</header>
</customwidget>
<customwidget>
<class>Core::Utils::PathChooser</class>
<extends>QWidget</extends>
<header location="global">utils/pathchooser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
+8 -3
View File
@@ -15,7 +15,9 @@ HEADERS += annotationhighlighter.h \
settingspage.h \ settingspage.h \
subversioneditor.h \ subversioneditor.h \
subversionsubmiteditor.h \ subversionsubmiteditor.h \
subversionsettings.h subversionsettings.h \
checkoutwizard.h \
checkoutwizardpage.h
SOURCES += annotationhighlighter.cpp \ SOURCES += annotationhighlighter.cpp \
subversionplugin.cpp \ subversionplugin.cpp \
@@ -24,9 +26,12 @@ SOURCES += annotationhighlighter.cpp \
settingspage.cpp \ settingspage.cpp \
subversioneditor.cpp \ subversioneditor.cpp \
subversionsubmiteditor.cpp \ subversionsubmiteditor.cpp \
subversionsettings.cpp subversionsettings.cpp \
checkoutwizard.cpp \
checkoutwizardpage.cpp
FORMS += settingspage.ui FORMS += settingspage.ui \
checkoutwizardpage.ui
RESOURCES += subversion.qrc RESOURCES += subversion.qrc
@@ -36,6 +36,7 @@
#include "subversionsubmiteditor.h" #include "subversionsubmiteditor.h"
#include "subversionconstants.h" #include "subversionconstants.h"
#include "subversioncontrol.h" #include "subversioncontrol.h"
#include "checkoutwizard.h"
#include <vcsbase/basevcseditorfactory.h> #include <vcsbase/basevcseditorfactory.h>
#include <vcsbase/vcsbaseeditor.h> #include <vcsbase/vcsbaseeditor.h>
@@ -269,6 +270,8 @@ bool SubversionPlugin::initialize(const QStringList &arguments, QString *errorMe
m_subversionOutputWindow = new SubversionOutputWindow(this); m_subversionOutputWindow = new SubversionOutputWindow(this);
addAutoReleasedObject(m_subversionOutputWindow); addAutoReleasedObject(m_subversionOutputWindow);
addAutoReleasedObject(new CheckoutWizard);
//register actions //register actions
Core::ActionManager *ami = core->actionManager(); Core::ActionManager *ami = core->actionManager();
Core::ActionContainer *toolsContainer = ami->actionContainer(M_TOOLS); Core::ActionContainer *toolsContainer = ami->actionContainer(M_TOOLS);
+150
View File
@@ -0,0 +1,150 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#include "basecheckoutwizard.h"
#include "vcsbaseconstants.h"
#include "checkoutwizarddialog.h"
#include "checkoutjobs.h"
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtGui/QMessageBox>
namespace VCSBase {
struct BaseCheckoutWizardPrivate {
BaseCheckoutWizardPrivate() : dialog(0), parameterPage(0) {}
void clear();
Internal::CheckoutWizardDialog *dialog;
QWizardPage *parameterPage;
QString checkoutPath;
};
void BaseCheckoutWizardPrivate::clear()
{
parameterPage = 0;
dialog = 0;
checkoutPath.clear();
}
BaseCheckoutWizard::BaseCheckoutWizard(QObject *parent) :
Core::IWizard(parent),
d(new BaseCheckoutWizardPrivate)
{
}
BaseCheckoutWizard::~BaseCheckoutWizard()
{
delete d;
}
Core::IWizard::Kind BaseCheckoutWizard::kind() const
{
return Core::IWizard::ProjectWizard;
}
QString BaseCheckoutWizard::category() const
{
return QLatin1String(VCSBase::Constants::VCS_WIZARD_CATEGORY);
}
QString BaseCheckoutWizard::trCategory() const
{
return QCoreApplication::translate("VCSBase", VCSBase::Constants::VCS_WIZARD_CATEGORY);
}
QStringList BaseCheckoutWizard::runWizard(const QString &path, QWidget *parent)
{
// Create dialog and launch
d->parameterPage = createParameterPage(path);
Internal::CheckoutWizardDialog dialog(d->parameterPage, parent);
d->dialog = &dialog;
connect(&dialog, SIGNAL(progressPageShown()), this, SLOT(slotProgressPageShown()));
dialog.setWindowTitle(name());
if (dialog.exec() != QDialog::Accepted)
return QStringList();
// Now try to find the project file and open
const QString checkoutPath = d->checkoutPath;
d->clear();
QString errorMessage;
const QString projectFile = openProject(checkoutPath, &errorMessage);
if (projectFile.isEmpty()) {
QMessageBox msgBox(QMessageBox::Warning, tr("Cannot Open Project"),
tr("Failed to open project in '%1'").arg(checkoutPath));
msgBox.setDetailedText(errorMessage);
msgBox.exec();
return QStringList();
}
return QStringList(projectFile);
}
QString BaseCheckoutWizard::openProject(const QString &path, QString *errorMessage)
{
ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
if (!pe) {
*errorMessage = tr("The Project Explorer is not available.");
return QString();
}
// Search the directory for project files
const QDir dir(path);
if (!dir.exists()) {
*errorMessage = tr("'%1' does not exist.").arg(path); // Should not happen
return QString();
}
// Hardcoded: Find *.pro/Cmakefiles
QStringList patterns;
patterns << QLatin1String("*.pro") << QLatin1String("CMakeList.txt");
QFileInfoList projectFiles = dir.entryInfoList(patterns, QDir::Files|QDir::NoDotAndDotDot|QDir::Readable);
if (projectFiles.empty()) {
*errorMessage = tr("No project files could be found (%1).").arg(patterns.join(QLatin1String(", ")));
return QString();
}
// Open!
const QString projectFile = projectFiles.front().absoluteFilePath();
if (!pe->openProject(projectFile)) {
*errorMessage = tr("Unable to open the project '%1'.").arg(projectFile);
return QString();
}
return projectFile;
}
void BaseCheckoutWizard::slotProgressPageShown()
{
const QSharedPointer<AbstractCheckoutJob> job = createJob(d->parameterPage, &(d->checkoutPath));
if (!job.isNull())
d->dialog->start(job);
}
} // namespace VCSBase
+92
View File
@@ -0,0 +1,92 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#ifndef BASECHECKOUTWIZARD_H
#define BASECHECKOUTWIZARD_H
#include "vcsbase_global.h"
#include <coreplugin/dialogs/iwizard.h>
#include <QtCore/QSharedPointer>
QT_BEGIN_NAMESPACE
class QWizardPage;
QT_END_NAMESPACE
namespace VCSBase {
class AbstractCheckoutJob;
struct BaseCheckoutWizardPrivate;
/* A Core::IWizard implementing a wizard for initially checking
* out a project using a version control system.
* Implements all of Core::IWizard with the exception of
* name()/description() and icon().
* Pops up a QWizard consisting of a Parameter Page which is created
* by a virtual factory function and a progress
* page containing a log text. The factory function createJob()
* creates a job with the output connected to the log window,
* returning the path to the checkout.
* On success, the wizard tries to locate a project file
* and open it.
* BaseCheckoutWizardPage is provided as a convenience base class
* for parameter wizard pages. */
class VCSBASE_EXPORT BaseCheckoutWizard : public Core::IWizard
{
Q_OBJECT
public:
explicit BaseCheckoutWizard(QObject *parent = 0);
virtual ~BaseCheckoutWizard();
virtual Kind kind() const;
virtual QString category() const;
virtual QString trCategory() const;
virtual QStringList runWizard(const QString &path, QWidget *parent);
protected:
virtual QWizardPage *createParameterPage(const QString &path) = 0;
virtual QSharedPointer<AbstractCheckoutJob> createJob(const QWizardPage *parameterPage,
QString *checkoutPath) = 0;
private slots:
void slotProgressPageShown();
private:
QString openProject(const QString &path, QString *errorMessage);
BaseCheckoutWizardPrivate *d;
};
} // namespace VCSBase
#endif // BASECHECKOUTWIZARD_H
@@ -0,0 +1,139 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#include "basecheckoutwizardpage.h"
#include "ui_basecheckoutwizardpage.h"
namespace VCSBase {
struct BaseCheckoutWizardPagePrivate {
BaseCheckoutWizardPagePrivate() : m_valid(false), m_directoryEdited(false) {}
Ui::BaseCheckoutWizardPage ui;
bool m_valid;
bool m_directoryEdited;
};
BaseCheckoutWizardPage::BaseCheckoutWizardPage(QWidget *parent) :
QWizardPage(parent),
d(new BaseCheckoutWizardPagePrivate)
{
d->ui.setupUi(this);
d->ui.pathChooser->setExpectedKind(Core::Utils::PathChooser::Directory);
connect(d->ui.pathChooser, SIGNAL(validChanged()), this, SLOT(slotChanged()));
connect(d->ui.checkoutDirectoryLineEdit, SIGNAL(validChanged()),
this, SLOT(slotChanged()));
connect(d->ui.repositoryLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotRepositoryChanged(QString)));
connect(d->ui.checkoutDirectoryLineEdit, SIGNAL(textEdited(QString)), this, SLOT(slotDirectoryEdited()));
}
BaseCheckoutWizardPage::~BaseCheckoutWizardPage()
{
delete d;
}
void BaseCheckoutWizardPage::setRepositoryLabel(const QString &l)
{
d->ui.repositoryLabel->setText(l);
}
QString BaseCheckoutWizardPage::path() const
{
return d->ui.pathChooser->path();
}
void BaseCheckoutWizardPage::setPath(const QString &p)
{
d->ui.pathChooser->setPath(p);
}
QString BaseCheckoutWizardPage::directory() const
{
return d->ui.checkoutDirectoryLineEdit->text();
}
void BaseCheckoutWizardPage::setDirectory(const QString &dir)
{
d->ui.checkoutDirectoryLineEdit->setText(dir);
}
QString BaseCheckoutWizardPage::repository() const
{
return d->ui.repositoryLineEdit->text().trimmed();
}
void BaseCheckoutWizardPage::setRepository(const QString &r)
{
d->ui.repositoryLineEdit->setText(r);
}
void BaseCheckoutWizardPage::slotRepositoryChanged(const QString &repo)
{
/* Try to figure out a good directory name from something like:
* "svn://<server>/path1/project" -> project */
if (d->m_directoryEdited)
return;
d->ui.checkoutDirectoryLineEdit->setText(directoryFromRepository(repo));
}
void BaseCheckoutWizardPage::slotDirectoryEdited()
{
d->m_directoryEdited = true;
}
void BaseCheckoutWizardPage::changeEvent(QEvent *e)
{
QWizardPage::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
d->ui.retranslateUi(this);
break;
default:
break;
}
}
bool BaseCheckoutWizardPage::isComplete() const
{
return d->m_valid;
}
void BaseCheckoutWizardPage::slotChanged()
{
const bool valid = d->ui.pathChooser->isValid()
&& d->ui.checkoutDirectoryLineEdit->isValid()
&& !d->ui.repositoryLineEdit->text().isEmpty();
if (valid != d->m_valid) {
d->m_valid = valid;
emit completeChanged();
}
}
} // namespace VCSBase
@@ -0,0 +1,87 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#ifndef VCSBASE_CHECKOUTWIZARDPAGE_H
#define VCSBASE_CHECKOUTWIZARDPAGE_H
#include "vcsbase_global.h"
#include <QtGui/QWizardPage>
namespace VCSBase {
namespace Ui {
class BaseCheckoutWizardPage;
}
struct BaseCheckoutWizardPagePrivate;
/* Base class for a parameter page of a checkout wizard.
* Let's the user specify the repository, a checkout directory and
* the path. Contains a virtual to derive the checkout directory
* from the repository as it is entered. */
class VCSBASE_EXPORT BaseCheckoutWizardPage : public QWizardPage {
Q_OBJECT
public:
BaseCheckoutWizardPage(QWidget *parent = 0);
~BaseCheckoutWizardPage();
QString path() const;
void setPath(const QString &);
QString directory() const;
void setDirectory(const QString &d);
QString repository() const;
void setRepository(const QString &r);
virtual bool isComplete() const;
protected:
void changeEvent(QEvent *e);
void setRepositoryLabel(const QString &l);
/* Determine a checkout directory name from
* repository URL, that is, "protocol:/project" -> "project". */
virtual QString directoryFromRepository(const QString &r) const = 0;
private slots:
void slotRepositoryChanged(const QString &url);
void slotDirectoryEdited();
void slotChanged();
private:
BaseCheckoutWizardPagePrivate *d;
};
} // namespace VCSBase
#endif // VCSBASE_CHECKOUTWIZARDPAGE_H
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>VCSBase::BaseCheckoutWizardPage</class>
<widget class="QWizardPage" name="VCSBase::BaseCheckoutWizardPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>464</width>
<height>302</height>
</rect>
</property>
<property name="windowTitle">
<string>WizardPage</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="repositoryLabel"/>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="repositoryLineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="checkoutDirectoryLabel">
<property name="text">
<string>Checkout Directory:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="pathLabel">
<property name="text">
<string>Path:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Core::Utils::PathChooser" name="pathChooser"/>
</item>
<item row="1" column="1">
<widget class="Core::Utils::ProjectNameValidatingLineEdit" name="checkoutDirectoryLineEdit"/>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Core::Utils::ProjectNameValidatingLineEdit</class>
<extends>QLineEdit</extends>
<header location="global">utils/projectnamevalidatinglineedit.h</header>
</customwidget>
<customwidget>
<class>Core::Utils::PathChooser</class>
<extends>QWidget</extends>
<header location="global">utils/pathchooser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
+137
View File
@@ -0,0 +1,137 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#include "checkoutjobs.h"
#include <QtCore/QDebug>
enum { debug = 0 };
namespace VCSBase {
AbstractCheckoutJob::AbstractCheckoutJob(QObject *parent) :
QObject(parent)
{
}
struct ProcessCheckoutJobPrivate {
ProcessCheckoutJobPrivate(const QString &binary,
const QStringList &args,
const QString &workingDirectory,
const QStringList &env);
QProcess process;
const QString binary;
const QStringList args;
};
ProcessCheckoutJobPrivate::ProcessCheckoutJobPrivate(const QString &b,
const QStringList &a,
const QString &workingDirectory,
const QStringList &env) :
binary(b),
args(a)
{
if (!workingDirectory.isEmpty())
process.setWorkingDirectory(workingDirectory);
if (!env.empty())
process.setEnvironment(env);
}
ProcessCheckoutJob::ProcessCheckoutJob(const QString &binary,
const QStringList &args,
const QString &workingDirectory,
const QStringList &env,
QObject *parent) :
AbstractCheckoutJob(parent),
d(new ProcessCheckoutJobPrivate(binary, args, workingDirectory, env))
{
if (debug)
qDebug() << "ProcessCheckoutJob" << binary << args << workingDirectory;
connect(&d->process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(slotError(QProcess::ProcessError)));
connect(&d->process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotFinished(int,QProcess::ExitStatus)));
connect(&d->process, SIGNAL(readyReadStandardOutput()), this, SLOT(slotOutput()));
d->process.setProcessChannelMode(QProcess::MergedChannels);
d->process.closeWriteChannel();
}
ProcessCheckoutJob::~ProcessCheckoutJob()
{
delete d;
}
void ProcessCheckoutJob::slotOutput()
{
const QString s = QString::fromLocal8Bit(d->process.readAllStandardOutput());
if (debug)
qDebug() << s;
emit output(s);
}
void ProcessCheckoutJob::slotError(QProcess::ProcessError /* error */)
{
emit failed(d->process.errorString());
}
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) {
emit succeeded();
} 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()
{
d->process.start(d->binary, d->args);
}
void ProcessCheckoutJob::cancel()
{
if (debug)
qDebug() << "ProcessCheckoutJob::start";
emit output(tr("Stopping..."));
d->process.terminate();
if (!d->process.waitForFinished(5000))
d->process.kill();
}
} // namespace VCSBase
+95
View File
@@ -0,0 +1,95 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#ifndef CHECKOUTJOB_H
#define CHECKOUTJOB_H
#include "vcsbase_global.h"
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <QtCore/QProcess>
QT_BEGIN_NAMESPACE
class QStringList;
class QByteArray;
QT_END_NAMESPACE
namespace VCSBase {
struct 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);
};
/* Convenience implementation using a QProcess. */
class VCSBASE_EXPORT ProcessCheckoutJob : public AbstractCheckoutJob
{
Q_OBJECT
public:
explicit ProcessCheckoutJob(const QString &binary,
const QStringList &args,
const QString &workingDirectory = QString(),
const QStringList &env = QStringList(),
QObject *parent = 0);
virtual ~ProcessCheckoutJob();
virtual void start();
virtual void cancel();
private slots:
void slotError(QProcess::ProcessError error);
void slotFinished (int exitCode, QProcess::ExitStatus exitStatus);
void slotOutput();
private:
ProcessCheckoutJobPrivate *d;
};
} // namespace VCSBase
#endif // CHECKOUTJOB_H
@@ -0,0 +1,118 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#include "checkoutprogresswizardpage.h"
#include "checkoutjobs.h"
#include "ui_checkoutprogresswizardpage.h"
#include <utils/qtcassert.h>
#include <QtGui/QApplication>
#include <QtGui/QCursor>
namespace VCSBase {
namespace Internal {
CheckoutProgressWizardPage::CheckoutProgressWizardPage(QWidget *parent) :
QWizardPage(parent),
ui(new Ui::CheckoutProgressWizardPage),
m_state(Idle)
{
ui->setupUi(this);
}
CheckoutProgressWizardPage::~CheckoutProgressWizardPage()
{
if (m_state == Running) // Paranoia!
QApplication::restoreOverrideCursor();
delete ui;
}
void CheckoutProgressWizardPage::start(const QSharedPointer<AbstractCheckoutJob> &job)
{
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()));
QApplication::setOverrideCursor(Qt::WaitCursor);
ui->logPlainTextEdit->clear();
setSubTitle(tr("Checkout started..."));
job->start();
m_state = Running;
}
void CheckoutProgressWizardPage::slotFailed(const QString &why)
{
ui->logPlainTextEdit->appendPlainText(why);
if (m_state == Running) {
m_state = Failed;
QApplication::restoreOverrideCursor();
setSubTitle(tr("Failed."));
emit terminated(false);
}
}
void CheckoutProgressWizardPage::slotSucceeded()
{
if (m_state == Running) {
m_state = Succeeded;
QApplication::restoreOverrideCursor();
setSubTitle(tr("Succeeded."));
emit completeChanged();
emit terminated(true);
}
}
void CheckoutProgressWizardPage::terminate()
{
if (!m_job.isNull())
m_job->cancel();
}
bool CheckoutProgressWizardPage::isComplete() const
{
return m_state == Succeeded;
}
void CheckoutProgressWizardPage::changeEvent(QEvent *e)
{
QWizardPage::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
} // namespace Internal
} // namespace VCSBase
@@ -0,0 +1,84 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#ifndef CHECKOUTPROGRESSWIZARDPAGE_H
#define CHECKOUTPROGRESSWIZARDPAGE_H
#include <QtCore/QSharedPointer>
#include <QtGui/QWizardPage>
namespace VCSBase {
class AbstractCheckoutJob;
namespace Internal {
namespace Ui {
class CheckoutProgressWizardPage;
}
/* Page showing the progress of an initial project
* checkout. Turns complete when the job succeeds. */
class CheckoutProgressWizardPage : public QWizardPage {
Q_OBJECT
Q_DISABLE_COPY(CheckoutProgressWizardPage)
public:
enum State { Idle, Running, Failed, Succeeded };
explicit CheckoutProgressWizardPage(QWidget *parent = 0);
~CheckoutProgressWizardPage();
void start(const QSharedPointer<AbstractCheckoutJob> &job);
virtual bool isComplete() const;
bool isRunning() const{ return m_state == Running; }
void terminate();
signals:
void terminated(bool success);
private slots:
void slotFailed(const QString &);
void slotSucceeded();
protected:
void changeEvent(QEvent *e);
private:
Ui::CheckoutProgressWizardPage *ui;
QSharedPointer<AbstractCheckoutJob> m_job;
State m_state;
};
} // namespace Internal
} // namespace VCSBase
#endif // CHECKOUTPROGRESSWIZARDPAGE_H
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>VCSBase::Internal::CheckoutProgressWizardPage</class>
<widget class="QWizardPage" name="VCSBase::Internal::CheckoutProgressWizardPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>264</width>
<height>200</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPlainTextEdit" name="logPlainTextEdit">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
@@ -0,0 +1,93 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#include "checkoutwizarddialog.h"
#include "basecheckoutwizard.h"
#include "checkoutjobs.h"
#include "checkoutprogresswizardpage.h"
#include <coreplugin/basefilewizard.h>
#include <QtGui/QPushButton>
namespace VCSBase {
namespace Internal {
enum PageId { ParameterPageId, ProgressPageId };
CheckoutWizardDialog::CheckoutWizardDialog(QWizardPage *parameterPage,
QWidget *parent) :
QWizard(parent),
m_progressPage(new CheckoutProgressWizardPage)
{
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setPage(ParameterPageId, parameterPage);
setPage(ProgressPageId, m_progressPage);
connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(slotPageChanged(int)));
connect(m_progressPage, SIGNAL(terminated(bool)), this, SLOT(slotTerminated(bool)));
Core::BaseFileWizard::setupWizard(this);
}
void CheckoutWizardDialog::slotPageChanged(int id)
{
if (id == ProgressPageId)
emit progressPageShown();
}
void CheckoutWizardDialog::slotTerminated(bool success)
{
// Allow to correct parameters
if (!success)
button(QWizard::BackButton)->setEnabled(true);
}
void CheckoutWizardDialog::start(const QSharedPointer<AbstractCheckoutJob> &job)
{
m_progressPage->start(job);
// No "back" available while running.
button(QWizard::BackButton)->setEnabled(false);
}
const QWizardPage *CheckoutWizardDialog::parameterPage() const
{
return page(ParameterPageId);
}
void CheckoutWizardDialog::reject()
{
// First click kills, 2nd closes
if (currentId() == ProgressPageId && m_progressPage->isRunning()) {
m_progressPage->terminate();
} else {
QWizard::reject();
}
}
} // namespace Internal
} // namespace VCSBase
@@ -0,0 +1,69 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#ifndef CHECKOUTWIZARDDIALOG_H
#define CHECKOUTWIZARDDIALOG_H
#include <QtCore/QSharedPointer>
#include <QtGui/QWizard>
namespace VCSBase {
class AbstractCheckoutJob;
namespace Internal {
class CheckoutProgressWizardPage;
/* See BaseCheckoutWizard.
* Overwrites reject() to first kill the checkout
* and then close. */
class CheckoutWizardDialog : public QWizard {
Q_OBJECT
public:
CheckoutWizardDialog(QWizardPage *parameterPage,
QWidget *parent = 0);
void start(const QSharedPointer<AbstractCheckoutJob> &job);
const QWizardPage *parameterPage() const;
signals:
void progressPageShown();
private slots:
void slotPageChanged(int id);
void slotTerminated(bool success);
virtual void reject();
private:
CheckoutProgressWizardPage *m_progressPage;
};
} // namespace Internal
} // namespace VCSBase
#endif // CHECKOUTWIZARDDIALOG_H
+15 -3
View File
@@ -17,7 +17,12 @@ HEADERS += vcsbase_global.h \
submitfilemodel.h \ submitfilemodel.h \
vcsbasesettings.h \ vcsbasesettings.h \
vcsbasesettingspage.h \ vcsbasesettingspage.h \
nicknamedialog.h nicknamedialog.h \
basecheckoutwizard.h \
checkoutwizarddialog.h \
checkoutprogresswizardpage.h \
checkoutjobs.h \
basecheckoutwizardpage.h
SOURCES += vcsbaseplugin.cpp \ SOURCES += vcsbaseplugin.cpp \
baseannotationhighlighter.cpp \ baseannotationhighlighter.cpp \
@@ -31,11 +36,18 @@ SOURCES += vcsbaseplugin.cpp \
submitfilemodel.cpp \ submitfilemodel.cpp \
vcsbasesettings.cpp \ vcsbasesettings.cpp \
vcsbasesettingspage.cpp \ vcsbasesettingspage.cpp \
nicknamedialog.cpp nicknamedialog.cpp \
basecheckoutwizard.cpp \
checkoutwizarddialog.cpp \
checkoutprogresswizardpage.cpp \
checkoutjobs.cpp \
basecheckoutwizardpage.cpp
RESOURCES += vcsbase.qrc RESOURCES += vcsbase.qrc
FORMS += vcsbasesettingspage.ui \ FORMS += vcsbasesettingspage.ui \
nicknamedialog.ui nicknamedialog.ui \
checkoutprogresswizardpage.ui \
basecheckoutwizardpage.ui
OTHER_FILES += VCSBase.pluginspec OTHER_FILES += VCSBase.pluginspec
+2
View File
@@ -38,6 +38,8 @@ namespace Constants {
const char * const VCS_SETTINGS_CATEGORY = QT_TRANSLATE_NOOP("VCSBase", "Version Control"); const char * const VCS_SETTINGS_CATEGORY = QT_TRANSLATE_NOOP("VCSBase", "Version Control");
const char * const VCS_COMMON_SETTINGS_ID = QT_TRANSLATE_NOOP("VCSBase", "Common"); const char * const VCS_COMMON_SETTINGS_ID = QT_TRANSLATE_NOOP("VCSBase", "Common");
const char * const VCS_WIZARD_CATEGORY = QT_TRANSLATE_NOOP("VCSBase", "Version Control");
namespace Internal { namespace Internal {
enum { debug = 0 }; enum { debug = 0 };
} // namespace Internal } // namespace Internal