From 5ec1c36c232b1783b5b3dd7684e05ef8378bcb90 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Fri, 4 Dec 2009 12:58:01 +0100
Subject: [PATCH] Mercurial: Emit version control changed() signals correctly.

Add a QVariant cookie to HgTask to be emitted on successful
execution, wired to IVersionControl.
---
 src/plugins/mercurial/mercurialclient.cpp    | 35 ++++++++++++++------
 src/plugins/mercurial/mercurialclient.h      |  3 ++
 src/plugins/mercurial/mercurialcontrol.cpp   | 16 +++++++++
 src/plugins/mercurial/mercurialcontrol.h     | 10 ++++++
 src/plugins/mercurial/mercurialjobrunner.cpp | 34 +++++++++++++------
 src/plugins/mercurial/mercurialjobrunner.h   | 16 +++++++--
 src/plugins/mercurial/mercurialplugin.cpp    |  1 +
 src/plugins/mercurial/mercurialplugin.h      |  2 +-
 8 files changed, 92 insertions(+), 25 deletions(-)

diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp
index aa54e079259..596a289525e 100644
--- a/src/plugins/mercurial/mercurialclient.cpp
+++ b/src/plugins/mercurial/mercurialclient.cpp
@@ -48,9 +48,9 @@
 #include <QtCore/QtDebug>
 #include <QtCore/QFileInfo>
 #include <QtCore/QByteArray>
+#include <QtCore/QMetaType>
 
-using namespace Mercurial::Internal;
-using namespace Mercurial;
+Q_DECLARE_METATYPE(QVariant)
 
 inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property, const QString &entry)
 {
@@ -60,10 +60,14 @@ inline Core::IEditor* locateEditor(const Core::ICore *core, const char *property
     return 0;
 }
 
+namespace Mercurial {
+namespace Internal  {
+
 MercurialClient::MercurialClient() :
     jobManager(0),
     core(Core::ICore::instance())
 {
+    qRegisterMetaType<QVariant>();
 }
 
 MercurialClient::~MercurialClient()
@@ -227,17 +231,18 @@ void MercurialClient::log(const QFileInfo &fileOrDir)
 
 void MercurialClient::revert(const QFileInfo &fileOrDir, const QString &revision)
 {
-    QStringList args(QLatin1String("revert"));
+    const QString filePath = fileOrDir.absoluteFilePath();
+    const QString workingDir = fileOrDir.isDir() ? filePath : fileOrDir.absolutePath();
 
+    QStringList args(QLatin1String("revert"));    
     if (!revision.isEmpty())
         args << QLatin1String("-r") << revision;
-    if (!fileOrDir.isDir())
-        args.append(fileOrDir.absoluteFilePath());
-    else
-        args.append(QLatin1String("--all"));
+    args.append(fileOrDir.isDir() ? QString(QLatin1String("--all")) : filePath);
 
-    QSharedPointer<HgTask> job(new HgTask(fileOrDir.isDir() ? fileOrDir.absoluteFilePath() :
-                                          fileOrDir.absolutePath(), args, false));
+    // Indicate repository change or file list
+    const QVariant cookie = fileOrDir.isDir() ? QVariant(filePath) : QVariant(QStringList(filePath));
+    QSharedPointer<HgTask> job(new HgTask(workingDir, args, false, cookie));
+    connect(job.data(), SIGNAL(succeeded(QVariant)), this, SIGNAL(changed(QVariant)), Qt::QueuedConnection);
     enqueueJob(job);
 }
 
@@ -310,7 +315,10 @@ void MercurialClient::pull(const QFileInfo &repositoryRoot, const QString &repos
     if (!repository.isEmpty())
         args.append(repository);
 
-    QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, false));
+    const QString path = repositoryRoot.absoluteFilePath();
+
+    QSharedPointer<HgTask> job(new HgTask(path, args, false, QVariant(path)));
+    connect(job.data(), SIGNAL(succeeded(QVariant)), this, SIGNAL(changed(QVariant)), Qt::QueuedConnection);
     enqueueJob(job);
 }
 
@@ -382,7 +390,9 @@ void MercurialClient::update(const QFileInfo &repositoryRoot, const QString &rev
     if (!revision.isEmpty())
         args << revision;
 
-    QSharedPointer<HgTask> job(new HgTask(repositoryRoot.absoluteFilePath(), args, false));
+    const QString path = repositoryRoot.absoluteFilePath();
+    QSharedPointer<HgTask> job(new HgTask(path, args, false, QVariant(path)));
+    connect(job.data(), SIGNAL(succeeded(QVariant)), this, SIGNAL(changed(QVariant)), Qt::QueuedConnection);
     enqueueJob(job);
 }
 
@@ -451,3 +461,6 @@ void MercurialClient::enqueueJob(const QSharedPointer<HgTask> &job)
     }
     jobManager->enqueueJob(job);
 }
+
+} // namespace Internal
+} // namespace Mercurial
diff --git a/src/plugins/mercurial/mercurialclient.h b/src/plugins/mercurial/mercurialclient.h
index bd0c9f8771e..87c5b25c6e8 100644
--- a/src/plugins/mercurial/mercurialclient.h
+++ b/src/plugins/mercurial/mercurialclient.h
@@ -36,6 +36,7 @@
 
 QT_BEGIN_NAMESPACE
 class QFileInfo;
+class QVariant;
 QT_END_NAMESPACE
 
 namespace Core {
@@ -81,6 +82,8 @@ public:
 
 signals:
     void parsedStatus(const QList<QPair<QString, QString> > &statusList);
+    // Passes on changed signals from HgTask to Control.
+    void changed(const QVariant &v);
 
 public slots:
     void view(const QString &source, const QString &id);
diff --git a/src/plugins/mercurial/mercurialcontrol.cpp b/src/plugins/mercurial/mercurialcontrol.cpp
index a2303e02000..8dd3cd94bba 100644
--- a/src/plugins/mercurial/mercurialcontrol.cpp
+++ b/src/plugins/mercurial/mercurialcontrol.cpp
@@ -31,6 +31,8 @@
 #include "mercurialclient.h"
 
 #include <QtCore/QFileInfo>
+#include <QtCore/QVariant>
+#include <QtCore/QStringList>
 
 using namespace Mercurial::Internal;
 
@@ -107,3 +109,17 @@ bool MercurialControl::sccManaged(const QString &filename)
 {
     return mercurialClient->manifestSync(filename);
 }
+
+void MercurialControl::changed(const QVariant &v)
+{
+    switch (v.type()) {
+    case QVariant::String:
+        emit repositoryChanged(v.toString());
+        break;
+    case QVariant::StringList:
+        emit filesChanged(v.toStringList());
+        break;
+    default:
+        break;
+    }
+}
diff --git a/src/plugins/mercurial/mercurialcontrol.h b/src/plugins/mercurial/mercurialcontrol.h
index 2085a27d77d..01c77e47bcf 100644
--- a/src/plugins/mercurial/mercurialcontrol.h
+++ b/src/plugins/mercurial/mercurialcontrol.h
@@ -32,6 +32,10 @@
 
 #include <coreplugin/iversioncontrol.h>
 
+QT_BEGIN_NAMESPACE
+class QVariant;
+QT_END_NAMESPACE
+
 namespace Mercurial {
 namespace Internal {
 
@@ -56,6 +60,12 @@ public:
     bool vcsDelete(const QString &filename);
     bool sccManaged(const QString &filename);
 
+public slots:
+    // To be connected to the HgTask's success signal to emit the repository/
+    // files changed signals according to the variant's type:
+    // String -> repository, StringList -> files
+    void changed(const QVariant&);
+
 signals:
     void enabledChanged(bool);
 
diff --git a/src/plugins/mercurial/mercurialjobrunner.cpp b/src/plugins/mercurial/mercurialjobrunner.cpp
index 3b27594f339..29595a83d96 100644
--- a/src/plugins/mercurial/mercurialjobrunner.cpp
+++ b/src/plugins/mercurial/mercurialjobrunner.cpp
@@ -42,21 +42,34 @@
 using namespace Mercurial::Internal;
 using namespace Mercurial;
 
-HgTask::HgTask(const QString &repositoryRoot, const QStringList &arguments, bool emitRaw)
-        :   m_repositoryRoot(repositoryRoot),
-        arguments(arguments),
-        emitRaw(emitRaw),
-        editor(0)
+HgTask::HgTask(const QString &repositoryRoot,
+               const QStringList &arguments,
+               bool emitRaw,
+               const QVariant &cookie) :
+    m_repositoryRoot(repositoryRoot),
+    arguments(arguments),
+    emitRaw(emitRaw),
+    m_cookie(cookie),
+    editor(0)
+
 {
 }
 
-HgTask::HgTask(const QString &repositoryRoot, const QStringList &arguments, VCSBase::VCSBaseEditor *editor)
-        :   m_repositoryRoot(repositoryRoot),
-        arguments(arguments),
-        emitRaw(false),
-        editor(editor)
+HgTask::HgTask(const QString &repositoryRoot,
+               const QStringList &arguments,
+               VCSBase::VCSBaseEditor *editor,
+               const QVariant &cookie) :
+    m_repositoryRoot(repositoryRoot),
+    arguments(arguments),
+    emitRaw(false),
+    m_cookie(cookie),
+    editor(editor)
+{
+}
 
+void HgTask::emitSucceeded()
 {
+    emit succeeded(m_cookie);
 }
 
 MercurialJobRunner::MercurialJobRunner() :
@@ -206,6 +219,7 @@ void MercurialJobRunner::task(const QSharedPointer<HgTask> &job)
         if (stdOutput.isEmpty())
             stdOutput = hgProcess.readAllStandardError();
         emit output(stdOutput);
+        taskData->emitSucceeded();
     } else {
         emit error(QString::fromLocal8Bit(hgProcess.readAllStandardError()));
     }
diff --git a/src/plugins/mercurial/mercurialjobrunner.h b/src/plugins/mercurial/mercurialjobrunner.h
index bac9c650d57..cdc484d4bfe 100644
--- a/src/plugins/mercurial/mercurialjobrunner.h
+++ b/src/plugins/mercurial/mercurialjobrunner.h
@@ -36,6 +36,7 @@
 #include <QtCore/QWaitCondition>
 #include <QtCore/QStringList>
 #include <QtCore/QSharedPointer>
+#include <QtCore/QVariant>
 #include <QtCore/QString>
 
 namespace VCSBase {
@@ -51,9 +52,13 @@ class HgTask : public QObject
 {
     Q_OBJECT
 public:
-    HgTask(const QString &workingDir, const QStringList &arguments, bool emitRaw=false);
-    HgTask(const QString &workingDir, const QStringList &arguments,
-           VCSBase::VCSBaseEditor *editor);
+    explicit HgTask(const QString &workingDir,
+                    const QStringList &arguments,
+                    bool emitRaw=false,
+                    const QVariant &cookie = QVariant());
+    explicit HgTask(const QString &workingDir, const QStringList &arguments,
+                    VCSBase::VCSBaseEditor *editor,
+                    const QVariant &cookie = QVariant());
 
     bool shouldEmit() { return emitRaw; }
     VCSBase::VCSBaseEditor* displayEditor() { return editor; }
@@ -61,12 +66,17 @@ public:
     QString repositoryRoot() { return m_repositoryRoot; }
 
 signals:
+    void succeeded(const QVariant &cookie); // Use a queued connection
     void rawData(const QByteArray &data);
 
+public slots:
+    void emitSucceeded();
+
 private:
     const QString m_repositoryRoot;
     const QStringList arguments;
     const bool emitRaw;
+    const QVariant m_cookie;
     VCSBase::VCSBaseEditor *editor;
 };
 
diff --git a/src/plugins/mercurial/mercurialplugin.cpp b/src/plugins/mercurial/mercurialplugin.cpp
index 97f8df94376..49963698ec7 100644
--- a/src/plugins/mercurial/mercurialplugin.cpp
+++ b/src/plugins/mercurial/mercurialplugin.cpp
@@ -162,6 +162,7 @@ bool MercurialPlugin::initialize(const QStringList &arguments, QString *error_me
 
     mercurialVC = new MercurialControl(client);
     addAutoReleasedObject(mercurialVC);
+    connect(client, SIGNAL(changed(QVariant)), mercurialVC, SLOT(changed(QVariant)));
 
     static const char *describeSlot = SLOT(view(QString,QString));
     const int editorCount = sizeof(editorParameters)/sizeof(VCSBase::VCSBaseEditorParameters);
diff --git a/src/plugins/mercurial/mercurialplugin.h b/src/plugins/mercurial/mercurialplugin.h
index 84654eb1f9c..fa3318d38ac 100644
--- a/src/plugins/mercurial/mercurialplugin.h
+++ b/src/plugins/mercurial/mercurialplugin.h
@@ -153,7 +153,7 @@ private:
     OptionsPage *optionsPage;
     MercurialClient *client;
 
-    Core::IVersionControl *mercurialVC;
+    MercurialControl *mercurialVC;
     Core::ICore *core;
     Core::ActionManager *actionManager;
     Core::ActionContainer *mercurialContainer;
-- 
GitLab