From 9d4aafebacf4fbd4868ad3ecac5c06a696285390 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 1 Oct 2009 17:50:24 +0200 Subject: [PATCH] VCS/git: Make blame go to current editor line using queued slot/variant cookie magic in command --- src/plugins/git/gitclient.cpp | 14 +++++++++----- src/plugins/git/gitclient.h | 6 ++++-- src/plugins/git/gitcommand.cpp | 10 +++++++++- src/plugins/git/gitcommand.h | 8 +++++++- src/plugins/git/giteditor.cpp | 9 +++++++++ src/plugins/git/giteditor.h | 6 ++++++ 6 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index d413ef75d41..419784887f0 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -310,7 +310,7 @@ void GitClient::blame(const QString &workingDirectory, const QString &fileName, const QString sourceFile = source(workingDirectory, fileName); VCSBase::VCSBaseEditor *editor = createVCSEditor(kind, title, sourceFile, true, "blameFileName", sourceFile); - executeGit(workingDirectory, arguments, editor); + executeGit(workingDirectory, arguments, editor, false, GitCommand::NoReport, lineNumber); } void GitClient::checkoutBranch(const QString &workingDirectory, const QString &branch) @@ -473,13 +473,16 @@ bool GitClient::synchronousShow(const QString &workingDirectory, const QString & // Factory function to create an asynchronous command GitCommand *GitClient::createCommand(const QString &workingDirectory, VCSBase::VCSBaseEditor* editor, - bool outputToWindow) + bool outputToWindow, + int editorLineNumber) { if (Git::Constants::debug) qDebug() << Q_FUNC_INFO << workingDirectory << editor; VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance(); - GitCommand* command = new GitCommand(binary(), workingDirectory, processEnvironment()); + GitCommand* command = new GitCommand(binary(), workingDirectory, processEnvironment(), QVariant(editorLineNumber)); + if (editor) + connect(command, SIGNAL(finished(bool,QVariant)), editor, SLOT(commandFinishedGotoLine(bool,QVariant))); if (outputToWindow) { if (editor) { // assume that the commands output is the important thing connect(command, SIGNAL(outputData(QByteArray)), outputWindow, SLOT(appendDataSilently(QByteArray))); @@ -501,10 +504,11 @@ void GitClient::executeGit(const QString &workingDirectory, const QStringList &arguments, VCSBase::VCSBaseEditor* editor, bool outputToWindow, - GitCommand::TerminationReportMode tm) + GitCommand::TerminationReportMode tm, + int editorLineNumber) { VCSBase::VCSBaseOutputWindow::instance()->appendCommand(formatCommand(QLatin1String(Constants::GIT_BINARY), arguments)); - GitCommand *command = createCommand(workingDirectory, editor, outputToWindow); + GitCommand *command = createCommand(workingDirectory, editor, outputToWindow, editorLineNumber); command->addJob(arguments, m_settings.timeout); command->setTerminationReportMode(tm); command->execute(); diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 26014eee541..341e177f353 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -155,13 +155,15 @@ private: GitCommand *createCommand(const QString &workingDirectory, VCSBase::VCSBaseEditor* editor = 0, - bool outputToWindow = false); + bool outputToWindow = false, + int editorLineNumber = -1); void executeGit(const QString &workingDirectory, const QStringList &arguments, VCSBase::VCSBaseEditor* editor = 0, bool outputToWindow = false, - GitCommand::TerminationReportMode tm = GitCommand::NoReport); + GitCommand::TerminationReportMode tm = GitCommand::NoReport, + int editorLineNumber = -1); bool synchronousGit(const QString &workingDirectory, const QStringList &arguments, diff --git a/src/plugins/git/gitcommand.cpp b/src/plugins/git/gitcommand.cpp index a6aef74f2ff..3f7a97095e6 100644 --- a/src/plugins/git/gitcommand.cpp +++ b/src/plugins/git/gitcommand.cpp @@ -41,6 +41,8 @@ #include #include +Q_DECLARE_METATYPE(QVariant) + namespace Git { namespace Internal { @@ -60,15 +62,20 @@ GitCommand::Job::Job(const QStringList &a, int t) : arguments(a), timeout(t) { + // Finished cookie is emitted via queued slot, needs metatype + static const int qvMetaId = qRegisterMetaType(); + Q_UNUSED(qvMetaId) } GitCommand::GitCommand(const QStringList &binary, const QString &workingDirectory, - const QStringList &environment) : + const QStringList &environment, + const QVariant &cookie) : m_binaryPath(binary.front()), m_basicArguments(binary), m_workingDirectory(workingDirectory), m_environment(environment), + m_cookie(cookie), m_reportTerminationMode(NoReport) { m_basicArguments.pop_front(); @@ -169,6 +176,7 @@ void GitCommand::run() if (!error.isEmpty()) emit errorText(error); + emit finished(ok, m_cookie); // As it is used asynchronously, we need to delete ourselves this->deleteLater(); } diff --git a/src/plugins/git/gitcommand.h b/src/plugins/git/gitcommand.h index c8f9d6dbaa2..7acf167750f 100644 --- a/src/plugins/git/gitcommand.h +++ b/src/plugins/git/gitcommand.h @@ -32,10 +32,13 @@ #include #include +#include namespace Git { namespace Internal { +// Asynchronous command with output signals and a finished +// signal with a magic cookie class GitCommand : public QObject { Q_DISABLE_COPY(GitCommand) @@ -48,7 +51,8 @@ public: explicit GitCommand(const QStringList &binary, const QString &workingDirectory, - const QStringList &environment); + const QStringList &environment, + const QVariant &cookie = QVariant()); void addJob(const QStringList &arguments, int timeout); @@ -68,6 +72,7 @@ private: Q_SIGNALS: void outputData(const QByteArray&); void errorText(const QString&); + void finished(bool ok, const QVariant &cookie); private: struct Job { @@ -81,6 +86,7 @@ private: QStringList m_basicArguments; const QString m_workingDirectory; const QStringList m_environment; + const QVariant m_cookie; QList m_jobs; TerminationReportMode m_reportTerminationMode; diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp index 68d26c57a8e..fe03336035e 100644 --- a/src/plugins/git/giteditor.cpp +++ b/src/plugins/git/giteditor.cpp @@ -184,5 +184,14 @@ void GitEditor::setPlainTextDataFiltered(const QByteArray &a) } } +void GitEditor::commandFinishedGotoLine(bool ok, const QVariant &v) +{ + if (ok && v.type() == QVariant::Int) { + const int line = v.toInt(); + if (line >= 0) + gotoLine(line); + } +} + } // namespace Internal } // namespace Git diff --git a/src/plugins/git/giteditor.h b/src/plugins/git/giteditor.h index 25a647460a9..29e9e75aa19 100644 --- a/src/plugins/git/giteditor.h +++ b/src/plugins/git/giteditor.h @@ -34,6 +34,10 @@ #include +QT_BEGIN_NAMESPACE +class QVariant; +QT_END_NAMESPACE + namespace Git { namespace Internal { @@ -49,6 +53,8 @@ public: public slots: void setPlainTextDataFiltered(const QByteArray &a); + // Matches the signature of the finished signal of GitCommand + void commandFinishedGotoLine(bool ok, const QVariant &v); private: virtual QSet annotationChanges() const;