Commit b0e1fdbf authored by Friedemann Kleint's avatar Friedemann Kleint

Mercurial: Save resources, polishing.

Start the jobrunner on demand, save options only if changed,
give it the structure used elsewhere in the VCS plugins. Remove
last traces of the cmd /c hack.
parent d570b05b
......@@ -76,15 +76,15 @@ QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizard::createJob(const QList<
if (!page)
return QSharedPointer<VCSBase::AbstractCheckoutJob>();
MercurialSettings *settings = MercurialPlugin::instance()->settings();
const MercurialSettings &settings = MercurialPlugin::instance()->settings();
QStringList args = settings->standardArguments();
QStringList args = settings.standardArguments();
QString path = page->path();
QString directory = page->directory();
args << QLatin1String("clone") << page->repository() << directory;
*checkoutPath = path + QLatin1Char('/') + directory;
return QSharedPointer<VCSBase::AbstractCheckoutJob>(new VCSBase::ProcessCheckoutJob(settings->binary(),
return QSharedPointer<VCSBase::AbstractCheckoutJob>(new VCSBase::ProcessCheckoutJob(settings.binary(),
args, path));
}
......@@ -60,11 +60,10 @@ inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property
return 0;
}
MercurialClient::MercurialClient()
: core(Core::ICore::instance())
MercurialClient::MercurialClient() :
jobManager(0),
core(Core::ICore::instance())
{
jobManager = new MercurialJobRunner();
jobManager->start();
}
MercurialClient::~MercurialClient()
......@@ -118,9 +117,9 @@ bool MercurialClient::executeHgSynchronously(const QFileInfo &file, const QStrin
QProcess hgProcess;
hgProcess.setWorkingDirectory(file.isDir() ? file.absoluteFilePath() : file.absolutePath());
const MercurialSettings *settings = MercurialPlugin::instance()->settings();
const QString binary = settings->binary();
const QStringList arguments = MercurialPlugin::instance()->standardArguments() + args;
const MercurialSettings &settings = MercurialPlugin::instance()->settings();
const QString binary = settings.binary();
const QStringList arguments = settings.standardArguments() + args;
VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance();
outputWindow->appendCommand(MercurialJobRunner::msgExecute(binary, arguments));
......@@ -134,9 +133,9 @@ bool MercurialClient::executeHgSynchronously(const QFileInfo &file, const QStrin
hgProcess.closeWriteChannel();
if (!hgProcess.waitForFinished(settings->timeout())) {
if (!hgProcess.waitForFinished(settings.timeoutMilliSeconds())) {
hgProcess.terminate();
outputWindow->appendError(MercurialJobRunner::msgTimeout(settings->timeout()));
outputWindow->appendError(MercurialJobRunner::msgTimeout(settings.timeoutSeconds()));
return false;
}
......@@ -170,7 +169,7 @@ void MercurialClient::annotate(const QFileInfo &file)
"annotate", file.absoluteFilePath());
QSharedPointer<HgTask> job(new HgTask(file.absolutePath(), args, editor));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::diff(const QFileInfo &fileOrDir)
......@@ -198,7 +197,7 @@ void MercurialClient::diff(const QFileInfo &fileOrDir)
"diff", id);
QSharedPointer<HgTask> job(new HgTask(workingPath, args, editor));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::log(const QFileInfo &fileOrDir)
......@@ -223,7 +222,7 @@ void MercurialClient::log(const QFileInfo &fileOrDir)
"log", id);
QSharedPointer<HgTask> job(new HgTask(workingDir, args, editor));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::revert(const QFileInfo &fileOrDir, const QString &revision)
......@@ -239,7 +238,7 @@ void MercurialClient::revert(const QFileInfo &fileOrDir, const QString &revision
QSharedPointer<HgTask> job(new HgTask(fileOrDir.isDir() ? fileOrDir.absoluteFilePath() :
fileOrDir.absolutePath(), args, false));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::status(const QFileInfo &fileOrDir)
......@@ -250,7 +249,7 @@ void MercurialClient::status(const QFileInfo &fileOrDir)
QSharedPointer<HgTask> job(new HgTask(fileOrDir.isDir() ? fileOrDir.absoluteFilePath() :
fileOrDir.absolutePath(), args, false));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::statusWithSignal(const QFileInfo &repositoryRoot)
......@@ -261,7 +260,7 @@ void MercurialClient::statusWithSignal(const QFileInfo &repositoryRoot)
connect(job.data(), SIGNAL(rawData(QByteArray)),
this, SLOT(statusParser(QByteArray)));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::statusParser(const QByteArray &data)
......@@ -302,7 +301,7 @@ void MercurialClient::import(const QFileInfo &repositoryRoot, const QStringList
args += files;
QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, false));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::pull(const QFileInfo &repositoryRoot, const QString &repository)
......@@ -312,7 +311,7 @@ void MercurialClient::pull(const QFileInfo &repositoryRoot, const QString &repos
args.append(repository);
QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, false));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::push(const QFileInfo &repositoryRoot, const QString &repository)
......@@ -322,7 +321,7 @@ void MercurialClient::push(const QFileInfo &repositoryRoot, const QString &repos
args.append(repository);
QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, false));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::incoming(const QFileInfo &repositoryRoot, const QString &repository)
......@@ -341,7 +340,7 @@ void MercurialClient::incoming(const QFileInfo &repositoryRoot, const QString &r
true, "incoming", id);
QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, editor));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::outgoing(const QFileInfo &repositoryRoot)
......@@ -358,7 +357,7 @@ void MercurialClient::outgoing(const QFileInfo &repositoryRoot)
"outgoing", id);
QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, editor));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::view(const QString &source, const QString &id)
......@@ -374,7 +373,7 @@ void MercurialClient::view(const QString &source, const QString &id)
true, "view", id);
QSharedPointer<HgTask> job(new HgTask(source, args, editor));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::update(const QFileInfo &repositoryRoot, const QString &revision)
......@@ -384,7 +383,7 @@ void MercurialClient::update(const QFileInfo &repositoryRoot, const QString &rev
args << revision;
QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, false));
jobManager->enqueueJob(job);
enqueueJob(job);
}
void MercurialClient::commit(const QFileInfo &repositoryRoot, const QStringList &files,
......@@ -395,7 +394,7 @@ void MercurialClient::commit(const QFileInfo &repositoryRoot, const QStringList
args << QLatin1String("-u") << committerInfo;
args << QLatin1String("-l") << commitMessageFile << files;
QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, false));
jobManager->enqueueJob(job);
enqueueJob(job);
}
QString MercurialClient::findTopLevelForFile(const QFileInfo &file)
......@@ -443,3 +442,12 @@ VCSBase::VCSBaseEditor *MercurialClient::createVCSEditor(const QString &kind, QS
core->editorManager()->activateEditor(outputEditor);
return baseEditor;
}
void MercurialClient::enqueueJob(const QSharedPointer<HgTask> &job)
{
if (!jobManager) {
jobManager = new MercurialJobRunner();
jobManager->start();
}
jobManager->enqueueJob(job);
}
......@@ -32,6 +32,7 @@
#include <QtCore/QObject>
#include <QtCore/QPair>
#include <QtCore/QSharedPointer>
QT_BEGIN_NAMESPACE
class QFileInfo;
......@@ -49,6 +50,7 @@ namespace Mercurial {
namespace Internal {
class MercurialJobRunner;
class HgTask;
class MercurialClient : public QObject
{
......@@ -90,6 +92,7 @@ private slots:
private:
bool executeHgSynchronously(const QFileInfo &file, const QStringList &args,
QByteArray *output=0) const;
void enqueueJob(const QSharedPointer<HgTask> &);
MercurialJobRunner *jobManager;
Core::ICore *core;
......
......@@ -97,10 +97,10 @@ void MercurialJobRunner::restart()
void MercurialJobRunner::getSettings()
{
const MercurialSettings *settings = MercurialPlugin::instance()->settings();
binary = settings->binary();
timeout = settings->timeout();
standardArguments = settings->standardArguments();
const MercurialSettings &settings = MercurialPlugin::instance()->settings();
binary = settings.binary();
timeout = settings.timeoutMilliSeconds();
standardArguments = settings.standardArguments();
}
void MercurialJobRunner::enqueueJob(const QSharedPointer<HgTask> &job)
......@@ -142,9 +142,9 @@ QString MercurialJobRunner::msgStartFailed(const QString &binary, const QString
return tr("Unable to start mercurial process '%1': %2").arg(binary, why);
}
QString MercurialJobRunner::msgTimeout(int timeoutMS)
QString MercurialJobRunner::msgTimeout(int timeoutSeconds)
{
return tr("Timed out after %1ms waiting for mercurial process to finish.").arg(timeoutMS);
return tr("Timed out after %1s waiting for mercurial process to finish.").arg(timeoutSeconds);
}
void MercurialJobRunner::task(const QSharedPointer<HgTask> &job)
......@@ -192,7 +192,7 @@ void MercurialJobRunner::task(const QSharedPointer<HgTask> &job)
if (!hgProcess.waitForFinished(timeout)) {
hgProcess.terminate();
emit error(msgTimeout(timeout));
emit error(msgTimeout(timeout / 1000));
return;
}
......
......@@ -83,7 +83,7 @@ public:
static QString msgExecute(const QString &binary, const QStringList &args);
static QString msgStartFailed(const QString &binary, const QString &why);
static QString msgTimeout(int timeoutMS);
static QString msgTimeout(int timeoutSeconds);
protected:
void run();
......
......@@ -121,8 +121,7 @@ static inline const VCSBase::VCSBaseEditorParameters *findType(int ie)
MercurialPlugin *MercurialPlugin::m_instance = 0;
MercurialPlugin::MercurialPlugin()
: mercurialSettings(new MercurialSettings),
MercurialPlugin::MercurialPlugin() :
optionsPage(0),
client(0),
mercurialVC(0),
......@@ -139,11 +138,6 @@ MercurialPlugin::~MercurialPlugin()
client = 0;
}
if (mercurialSettings) {
delete mercurialSettings;
mercurialSettings = 0;
}
deleteCommitLog();
m_instance = 0;
......@@ -161,6 +155,7 @@ bool MercurialPlugin::initialize(const QStringList &arguments, QString *error_me
optionsPage = new OptionsPage();
addAutoReleasedObject(optionsPage);
mercurialSettings.readSettings(core->settings());
client = new MercurialClient();
connect(optionsPage, SIGNAL(settingsChanged()), client, SLOT(settingsChanged()));
......@@ -194,14 +189,21 @@ void MercurialPlugin::extensionsInitialized()
this, SLOT(currentProjectChanged(ProjectExplorer::Project *)));
}
MercurialSettings *MercurialPlugin::settings()
const MercurialSettings &MercurialPlugin::settings() const
{
return mercurialSettings;
}
void MercurialPlugin::setSettings(const MercurialSettings &settings)
{
if (settings != mercurialSettings) {
mercurialSettings = settings;
}
}
QStringList MercurialPlugin::standardArguments() const
{
return mercurialSettings->standardArguments();
return mercurialSettings.standardArguments();
}
void MercurialPlugin::createMenu()
......@@ -530,8 +532,8 @@ void MercurialPlugin::showCommitWidget(const QList<QPair<QString, QString> > &st
QString branch = client->branchQuerySync(currentProjectRoot());
commitEditor->setFields(currentProjectRoot(), branch, mercurialSettings->userName(),
mercurialSettings->email(), status);
commitEditor->setFields(currentProjectRoot(), branch, mercurialSettings.userName(),
mercurialSettings.email(), status);
commitEditor->registerActions(editorUndo, editorRedo, editorCommit, editorDiff);
connect(commitEditor, SIGNAL(diffSelectedFiles(const QStringList &)),
......@@ -564,11 +566,11 @@ bool MercurialPlugin::closeEditor(Core::IEditor *editor)
if (!editorFile || !commitEditor)
return true;
bool dummyPrompt = settings()->prompt();
bool dummyPrompt = mercurialSettings.prompt();
const VCSBase::VCSBaseSubmitEditor::PromptSubmitResult response =
commitEditor->promptSubmit(tr("Close commit editor"), tr("Do you want to commit the changes?"),
tr("Message check failed. Do you want to proceed?"),
&dummyPrompt, settings()->prompt());
&dummyPrompt, mercurialSettings.prompt());
switch (response) {
case VCSBase::VCSBaseSubmitEditor::SubmitCanceled:
......
......@@ -30,6 +30,8 @@
#ifndef MERCURIALPLUGIN_H
#define MERCURIALPLUGIN_H
#include "mercurialsettings.h"
#include <extensionsystem/iplugin.h>
#include <coreplugin/icorelistener.h>
......@@ -85,7 +87,8 @@ public:
bool closeEditor(Core::IEditor *editor);
QStringList standardArguments() const;
MercurialSettings *settings();
const MercurialSettings &settings() const;
void setSettings(const MercurialSettings &settings);
private slots:
// File menu action Slots
......@@ -146,7 +149,7 @@ private:
//Variables
static MercurialPlugin *m_instance;
MercurialSettings *mercurialSettings;
MercurialSettings mercurialSettings;
OptionsPage *optionsPage;
MercurialClient *client;
......
......@@ -30,40 +30,53 @@
#include "mercurialsettings.h"
#include "constants.h"
#include <coreplugin/icore.h>
#include <QtCore/QSettings>
using namespace Mercurial::Internal;
MercurialSettings::MercurialSettings()
enum { timeOutDefaultSeconds = 30 };
MercurialSettings::MercurialSettings() :
m_binary(QLatin1String(Constants::MERCURIALDEFAULT)),
m_logCount(0),
m_timeoutSeconds(timeOutDefaultSeconds),
m_prompt(true)
{
readSettings();
}
QString MercurialSettings::binary() const
{
return bin;
return m_binary;
}
QString MercurialSettings::application() const
void MercurialSettings::setBinary(const QString &b)
{
return app;
m_binary = b;
}
QStringList MercurialSettings::standardArguments() const
{
return standardArgs;
return m_standardArguments;
}
QString MercurialSettings::userName() const
{
return user;
return m_user;
}
void MercurialSettings::setUserName(const QString &u)
{
m_user = u;
}
QString MercurialSettings::email() const
{
return mail;
return m_mail;
}
void MercurialSettings::setEmail(const QString &m)
{
m_mail = m;
}
int MercurialSettings::logCount() const
......@@ -71,16 +84,26 @@ int MercurialSettings::logCount() const
return m_logCount;
}
int MercurialSettings::timeout() const
void MercurialSettings::setLogCount(int l)
{
m_logCount = l;
}
int MercurialSettings::timeoutMilliSeconds() const
{
//return timeout is in Ms
return m_timeout * 1000;
return m_timeoutSeconds * 1000;
}
int MercurialSettings::timeoutSeconds() const
{
//return timeout in seconds (as the user specifies on the options page
return m_timeout;
return m_timeoutSeconds;
}
void MercurialSettings::setTimeoutSeconds(int s)
{
m_timeoutSeconds = s;
}
bool MercurialSettings::prompt() const
......@@ -88,50 +111,39 @@ bool MercurialSettings::prompt() const
return m_prompt;
}
void MercurialSettings::writeSettings(const QString &application, const QString &userName,
const QString &email, int logCount, int timeout, bool prompt)
{
QSettings *settings = Core::ICore::instance()->settings();
if (settings) {
settings->beginGroup(QLatin1String("Mercurial"));
settings->setValue(QLatin1String(Constants::MERCURIALPATH), application);
settings->setValue(QLatin1String(Constants::MERCURIALUSERNAME), userName);
settings->setValue(QLatin1String(Constants::MERCURIALEMAIL), email);
settings->setValue(QLatin1String(Constants::MERCURIALLOGCOUNT), logCount);
settings->setValue(QLatin1String(Constants::MERCURIALTIMEOUT), timeout);
settings->setValue(QLatin1String(Constants::MERCURIALPROMPTSUBMIT), prompt);
settings->endGroup();
}
app = application;
user = userName;
mail = email;
m_logCount = logCount;
m_timeout = timeout;
m_prompt = prompt;
setBinAndArgs();
}
void MercurialSettings::readSettings()
{
QSettings *settings = Core::ICore::instance()->settings();
if (settings) {
settings->beginGroup(QLatin1String("Mercurial"));
app = settings->value(QLatin1String(Constants::MERCURIALPATH),
QLatin1String(Constants::MERCURIALDEFAULT)).toString();
user = settings->value(QLatin1String(Constants::MERCURIALUSERNAME), QString()).toString();
mail = settings->value(QLatin1String(Constants::MERCURIALEMAIL), QString()).toString();
m_logCount = settings->value(QLatin1String(Constants::MERCURIALLOGCOUNT), 0).toInt();
m_timeout = settings->value(QLatin1String(Constants::MERCURIALTIMEOUT), 30).toInt();
m_prompt = settings->value(QLatin1String(Constants::MERCURIALPROMPTSUBMIT), true).toBool();
settings->endGroup();
}
setBinAndArgs();
}
void MercurialSettings::setBinAndArgs()
{
standardArgs.clear();
bin = app;
void MercurialSettings::setPrompt(bool b)
{
m_prompt = b;
}
void MercurialSettings::writeSettings(QSettings *settings) const
{
settings->beginGroup(QLatin1String("Mercurial"));
settings->setValue(QLatin1String(Constants::MERCURIALPATH), m_binary);
settings->setValue(QLatin1String(Constants::MERCURIALUSERNAME), m_user);
settings->setValue(QLatin1String(Constants::MERCURIALEMAIL), m_mail);
settings->setValue(QLatin1String(Constants::MERCURIALLOGCOUNT), m_logCount);
settings->setValue(QLatin1String(Constants::MERCURIALTIMEOUT), m_timeoutSeconds);
settings->setValue(QLatin1String(Constants::MERCURIALPROMPTSUBMIT), m_prompt);
settings->endGroup();
}
void MercurialSettings::readSettings(const QSettings *settings)
{
const QString keyRoot = QLatin1String("Mercurial/");
m_binary = settings->value(keyRoot + QLatin1String(Constants::MERCURIALPATH),
QLatin1String(Constants::MERCURIALDEFAULT)).toString();
m_user = settings->value(keyRoot + QLatin1String(Constants::MERCURIALUSERNAME), QString()).toString();
m_mail = settings->value(keyRoot + QLatin1String(Constants::MERCURIALEMAIL), QString()).toString();
m_logCount = settings->value(keyRoot + QLatin1String(Constants::MERCURIALLOGCOUNT), 0).toInt();
m_timeoutSeconds = settings->value(keyRoot + QLatin1String(Constants::MERCURIALTIMEOUT), timeOutDefaultSeconds).toInt();
m_prompt = settings->value(keyRoot + QLatin1String(Constants::MERCURIALPROMPTSUBMIT), true).toBool();
}
bool MercurialSettings::equals(const MercurialSettings &rhs) const
{
return m_binary == rhs.m_binary && m_standardArguments == rhs.m_standardArguments
&& m_user == rhs.m_user && m_mail == rhs.m_mail
&& m_logCount == rhs.m_logCount && m_timeoutSeconds == rhs.m_timeoutSeconds
&& m_prompt == rhs.m_prompt;
}
......@@ -33,6 +33,10 @@
#include <QtCore/QString>
#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE
class QSettings;
QT_END_NAMESPACE
namespace Mercurial {
namespace Internal {
......@@ -42,32 +46,50 @@ public:
MercurialSettings();
QString binary() const;
QString application() const;
void setBinary(const QString &);
// Calculated.
QStringList standardArguments() const;
QString userName() const;
void setUserName(const QString &);
QString email() const;
void setEmail(const QString &);
int logCount() const;
int timeout() const;
void setLogCount(int l);
int timeoutMilliSeconds() const;
int timeoutSeconds() const;
void setTimeoutSeconds(int s);
bool prompt() const;
void writeSettings(const QString &application, const QString &userName,
const QString &email, int logCount, int timeout, bool prompt);
void setPrompt(bool b);
void writeSettings(QSettings *settings) const;
void readSettings(const QSettings *settings);
bool equals(const MercurialSettings &rhs) const;
private:
void readSettings();
void setBinAndArgs();
QString bin; // used because windows requires cmd.exe to run the mercurial binary
// in this case the actual mercurial binary will be part of the standard args
QString app; // this is teh actual mercurial executable
QStringList standardArgs;
QString user;
QString mail;
QString m_binary;
QStringList m_standardArguments;
QString m_user;
QString m_mail;
int m_logCount;
int m_timeout;
int m_timeoutSeconds;
bool m_prompt;
};
inline bool operator==(const MercurialSettings &s1, const MercurialSettings &s2)
{ return s1.equals(s2); }
inline bool operator!=(const MercurialSettings &s1, const MercurialSettings &s2)
{ return !s1.equals(s2); }
} //namespace Internal
} //namespace Mercurial
......
......@@ -31,6 +31,7 @@
#include "mercurialsettings.h"
#include "mercurialplugin.h"
#include <coreplugin/icore.h>
#include <utils/pathchooser.h>
#include <vcsbase/vcsbaseconstants.h>
......@@ -45,24 +46,26 @@ OptionsPageWidget::OptionsPageWidget(QWidget *parent) :
m_ui.commandChooser->setPromptDialogTitle(tr("Mercurial Command"));
}
void OptionsPageWidget::updateOptions()