diff --git a/src/plugins/coreplugin/iversioncontrol.h b/src/plugins/coreplugin/iversioncontrol.h index 4b3b7c4cc754defb8d1512b7aa9a82f62029c021..13b43a687adfa5b7284cbc2ed7d3fb2f1de221ce 100644 --- a/src/plugins/coreplugin/iversioncontrol.h +++ b/src/plugins/coreplugin/iversioncontrol.h @@ -44,7 +44,8 @@ public: enum Operation { AddOperation, DeleteOperation, OpenOperation, CreateRepositoryOperation, - SnapshotOperations + SnapshotOperations, + AnnotateOperation }; explicit IVersionControl(QObject *parent = 0) : QObject(parent) {} @@ -126,6 +127,11 @@ public: */ virtual bool vcsRemoveSnapshot(const QString &topLevel, const QString &name) = 0; + /*! + * Display annotation for a file and scroll to line + */ + virtual bool vcsAnnotate(const QString &file, int line) = 0; + signals: void repositoryChanged(const QString &repository); void filesChanged(const QStringList &files); diff --git a/src/plugins/cvs/cvscontrol.cpp b/src/plugins/cvs/cvscontrol.cpp index e2c559174b1ee325e8a64879213952c8d3fbef78..33e08c03a057173829455091e5232ddbda86a79c 100644 --- a/src/plugins/cvs/cvscontrol.cpp +++ b/src/plugins/cvs/cvscontrol.cpp @@ -52,6 +52,7 @@ bool CVSControl::supportsOperation(Operation operation) const switch (operation) { case AddOperation: case DeleteOperation: + case AnnotateOperation: break; case OpenOperation: case CreateRepositoryOperation: @@ -105,6 +106,12 @@ bool CVSControl::vcsRemoveSnapshot(const QString &, const QString &) return false; } +bool CVSControl::vcsAnnotate(const QString &file, int line) +{ + m_plugin->vcsAnnotate(file, QString(), line); + return true; +} + bool CVSControl::managesDirectory(const QString &directory) const { return m_plugin->managesDirectory(directory); diff --git a/src/plugins/cvs/cvscontrol.h b/src/plugins/cvs/cvscontrol.h index 74bb1cda882aed66d1ff1c9999d05dc97b6ef904..24483afed331854008d1baafd1fc266cc1f5341e 100644 --- a/src/plugins/cvs/cvscontrol.h +++ b/src/plugins/cvs/cvscontrol.h @@ -57,6 +57,7 @@ public: virtual QStringList vcsSnapshots(const QString &topLevel); virtual bool vcsRestoreSnapshot(const QString &topLevel, const QString &name); virtual bool vcsRemoveSnapshot(const QString &topLevel, const QString &name); + virtual bool vcsAnnotate(const QString &file, int line); void emitRepositoryChanged(const QString &s); void emitFilesChanged(const QStringList &l); diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp index 78df829fcda866250da9ac8660ed4b39c8d1e484..b45deb226f9a970d7b1cbcb8f859b33e5af4194f 100644 --- a/src/plugins/cvs/cvsplugin.cpp +++ b/src/plugins/cvs/cvsplugin.cpp @@ -771,7 +771,7 @@ void CVSPlugin::annotateCurrentFile() annotate(state.currentFileTopLevel(), state.relativeCurrentFile()); } -void CVSPlugin::annotateVersion(const QString &file, const QString &revision, int lineNumber) +void CVSPlugin::vcsAnnotate(const QString &file, const QString &revision, int lineNumber) { const QFileInfo fi(file); annotate(fi.absolutePath(), fi.fileName(), revision, lineNumber); @@ -1072,7 +1072,7 @@ Core::IEditor * CVSPlugin::showOutputInEditor(const QString& title, const QStrin QString s = title; Core::IEditor *editor = Core::EditorManager::instance()->openEditorWithContents(id, &s, output.toLocal8Bit()); connect(editor, SIGNAL(annotateRevisionRequested(QString,QString,int)), - this, SLOT(annotateVersion(QString,QString,int))); + this, SLOT(vcsAnnotate(QString,QString,int))); CVSEditor *e = qobject_cast<CVSEditor*>(editor->widget()); if (!e) return 0; diff --git a/src/plugins/cvs/cvsplugin.h b/src/plugins/cvs/cvsplugin.h index 312a085843502cd82c6e434b8dad8593590dc36d..12a1ee674f3ce431fba3bc572da43731fba4b8b2 100644 --- a/src/plugins/cvs/cvsplugin.h +++ b/src/plugins/cvs/cvsplugin.h @@ -101,6 +101,9 @@ public: static CVSPlugin *cvsPluginInstance(); +public slots: + void vcsAnnotate(const QString &file, const QString &revision /* = QString() */, int lineNumber); + private slots: void addCurrentFile(); void revertCurrentFile(); @@ -111,7 +114,6 @@ private slots: void startCommitCurrentFile(); void filelogCurrentFile(); void annotateCurrentFile(); - void annotateVersion(const QString &file, const QString &revision, int lineNumber); void projectStatus(); void slotDescribe(const QString &source, const QString &changeNr); void updateProject(); diff --git a/src/plugins/git/gitversioncontrol.cpp b/src/plugins/git/gitversioncontrol.cpp index 65308fb17483aae01cdf5455cb3a60cb8901735d..07ff95213432bc45e1d169d28c390808140e89f5 100644 --- a/src/plugins/git/gitversioncontrol.cpp +++ b/src/plugins/git/gitversioncontrol.cpp @@ -81,6 +81,9 @@ bool GitVersionControl::supportsOperation(Operation operation) const case SnapshotOperations: rc = true; break; + case AnnotateOperation: + rc = true; + break; } return rc; } @@ -203,6 +206,13 @@ QString GitVersionControl::findTopLevelForDirectory(const QString &directory) co return GitClient::findRepositoryForDirectory(directory); } +bool GitVersionControl::vcsAnnotate(const QString &file, int line) +{ + const QFileInfo fi(file); + gitClient()->blame(fi.absolutePath(), fi.fileName(), QString(), line); + return true; +} + void GitVersionControl::emitFilesChanged(const QStringList &l) { emit filesChanged(l); diff --git a/src/plugins/git/gitversioncontrol.h b/src/plugins/git/gitversioncontrol.h index 44e65df84db6231654b670162720c8a843e94de2..c53c1f2ab5cf2af5c47871e37c0f4cc35e36f5fe 100644 --- a/src/plugins/git/gitversioncontrol.h +++ b/src/plugins/git/gitversioncontrol.h @@ -59,6 +59,8 @@ public: virtual bool vcsRestoreSnapshot(const QString &topLevel, const QString &name); virtual bool vcsRemoveSnapshot(const QString &topLevel, const QString &name); + virtual bool vcsAnnotate(const QString &file, int line); + void emitFilesChanged(const QStringList &); void emitRepositoryChanged(const QString &); diff --git a/src/plugins/mercurial/mercurialcontrol.cpp b/src/plugins/mercurial/mercurialcontrol.cpp index a0af2093104df5a5e7bb0c2cdcc6ba9ae0cabc19..1b707b9c8b769253c49a02ccc8bd094f8fa90d6a 100644 --- a/src/plugins/mercurial/mercurialcontrol.cpp +++ b/src/plugins/mercurial/mercurialcontrol.cpp @@ -66,6 +66,7 @@ bool MercurialControl::supportsOperation(Operation operation) const case Core::IVersionControl::AddOperation: case Core::IVersionControl::DeleteOperation: case Core::IVersionControl::CreateRepositoryOperation: + case Core::IVersionControl::AnnotateOperation: break; case Core::IVersionControl::OpenOperation: case Core::IVersionControl::SnapshotOperations: @@ -118,6 +119,13 @@ bool MercurialControl::vcsRemoveSnapshot(const QString &, const QString &) return false; } +bool MercurialControl::vcsAnnotate(const QString &file, int line) +{ + const QFileInfo fi(file); + mercurialClient->annotate(fi.absolutePath(), fi.fileName(), QString(), line); + return true; +} + bool MercurialControl::sccManaged(const QString &filename) { const QFileInfo fi(filename); diff --git a/src/plugins/mercurial/mercurialcontrol.h b/src/plugins/mercurial/mercurialcontrol.h index c82401bad89804cc4baa28b6f5851d3e1da83b16..b6ee396b1c726d9c0841b5347d4cd705415ef084 100644 --- a/src/plugins/mercurial/mercurialcontrol.h +++ b/src/plugins/mercurial/mercurialcontrol.h @@ -62,6 +62,7 @@ public: bool vcsRestoreSnapshot(const QString &topLevel, const QString &name); bool vcsRemoveSnapshot(const QString &topLevel, const QString &name); bool sccManaged(const QString &filename); + virtual bool vcsAnnotate(const QString &file, int line); public slots: // To be connected to the HgTask's success signal to emit the repository/ diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp index 287d9bcfe2102f0eebd65792d15a23bccf3bfdce..fe3cbb5a29a8a377d3355a6cceadf2c5b4a9a081 100644 --- a/src/plugins/perforce/perforceplugin.cpp +++ b/src/plugins/perforce/perforceplugin.cpp @@ -723,7 +723,7 @@ void PerforcePlugin::annotate() } } -void PerforcePlugin::annotateVersion(const QString &file, const QString &revision, int lineNumber) +void PerforcePlugin::vcsAnnotate(const QString &file, const QString &revision, int lineNumber) { const QFileInfo fi(file); annotate(fi.absolutePath(), fi.fileName(), revision, lineNumber); @@ -1175,7 +1175,7 @@ Core::IEditor * PerforcePlugin::showOutputInEditor(const QString& title, const Q QString s = title; Core::IEditor *editor = Core::EditorManager::instance()->openEditorWithContents(id, &s, output); connect(editor, SIGNAL(annotateRevisionRequested(QString,QString,int)), - this, SLOT(annotateVersion(QString,QString,int))); + this, SLOT(vcsAnnotate(QString,QString,int))); PerforceEditor *e = qobject_cast<PerforceEditor*>(editor->widget()); if (!e) return 0; diff --git a/src/plugins/perforce/perforceplugin.h b/src/plugins/perforce/perforceplugin.h index 2e62b5d5f9522c3981aba7f4838a88940180a6ad..7c88baef1a9ce09ee31db52d47f1f297c974e75d 100644 --- a/src/plugins/perforce/perforceplugin.h +++ b/src/plugins/perforce/perforceplugin.h @@ -106,6 +106,7 @@ public: public slots: void describe(const QString &source, const QString &n); + void vcsAnnotate(const QString &file, const QString &revision /* = QString() */, int lineNumber); private slots: void openCurrentFile(); @@ -123,7 +124,6 @@ private slots: void describeChange(); void annotateCurrentFile(); void annotate(); - void annotateVersion(const QString &file, const QString &revision, int lineNumber); void filelogCurrentFile(); void filelog(); void logProject(); diff --git a/src/plugins/perforce/perforceversioncontrol.cpp b/src/plugins/perforce/perforceversioncontrol.cpp index 69602d88113d10bab328dfa60a0ff17a9525d572..ecd75e7bfdfb426ad78550086a0cf0ebc7d6ac67 100644 --- a/src/plugins/perforce/perforceversioncontrol.cpp +++ b/src/plugins/perforce/perforceversioncontrol.cpp @@ -54,6 +54,7 @@ bool PerforceVersionControl::supportsOperation(Operation operation) const case AddOperation: case DeleteOperation: case OpenOperation: + case AnnotateOperation: return true; case CreateRepositoryOperation: case SnapshotOperations: @@ -105,6 +106,12 @@ bool PerforceVersionControl::vcsRemoveSnapshot(const QString &, const QString &) return false; } +bool PerforceVersionControl::vcsAnnotate(const QString &file, int line) +{ + m_plugin->vcsAnnotate(file, QString(), line); + return true; +} + bool PerforceVersionControl::managesDirectory(const QString &directory) const { const bool rc = m_plugin->managesDirectory(directory); diff --git a/src/plugins/perforce/perforceversioncontrol.h b/src/plugins/perforce/perforceversioncontrol.h index 063a3be77ce77959ad7baed82b3f54f613eaa59b..5be2ac9826bd6027066e37aad5fd3c754dc08482 100644 --- a/src/plugins/perforce/perforceversioncontrol.h +++ b/src/plugins/perforce/perforceversioncontrol.h @@ -57,6 +57,7 @@ public: virtual QStringList vcsSnapshots(const QString &topLevel); virtual bool vcsRestoreSnapshot(const QString &topLevel, const QString &name); virtual bool vcsRemoveSnapshot(const QString &topLevel, const QString &name); + virtual bool vcsAnnotate(const QString &file, int line); void emitRepositoryChanged(const QString &s); void emitFilesChanged(const QStringList &l); diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index 6b7a446e1f078932b08135f62416b924c10be179..493c5039324601b7bd1ade86d9d9490ca0ef9bd7 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -31,6 +31,8 @@ #include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/coreconstants.h> +#include <coreplugin/vcsmanager.h> +#include <coreplugin/iversioncontrol.h> #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/icore.h> #include <coreplugin/uniqueidmanager.h> @@ -40,6 +42,7 @@ #include <QtCore/QDir> #include <QtCore/QFileInfo> +#include <QtCore/QDebug> #include <QtGui/QApplication> #include <QtGui/QClipboard> #include <QtGui/QKeyEvent> @@ -464,16 +467,21 @@ TaskWindow::TaskWindow() Core::Command *command = core->actionManager()-> registerAction(m_copyAction, Core::Constants::COPY, m_taskWindowContext->context()); m_listview->addAction(command->action()); + connect(m_copyAction, SIGNAL(triggered()), SLOT(copy())); - connect(m_listview->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), - tld, SLOT(currentChanged(const QModelIndex &, const QModelIndex &))); + m_vcsAnnotateAction = new QAction(tr("&Annotate"), this); + command = core->actionManager()-> + registerAction(m_vcsAnnotateAction, QLatin1String("ProjectExplorer.Task.VCS_Annotate"), m_taskWindowContext->context()); + m_listview->addAction(command->action()); + connect(m_vcsAnnotateAction, SIGNAL(triggered()), SLOT(vcsAnnotate())); - connect(m_listview, SIGNAL(activated(const QModelIndex &)), - this, SLOT(showTaskInFile(const QModelIndex &))); - connect(m_listview, SIGNAL(clicked(const QModelIndex &)), - this, SLOT(showTaskInFile(const QModelIndex &))); + connect(m_listview->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), + tld, SLOT(currentChanged(QModelIndex,QModelIndex))); - connect(m_copyAction, SIGNAL(triggered()), SLOT(copy())); + connect(m_listview, SIGNAL(activated(QModelIndex)), + this, SLOT(showTaskInFile(QModelIndex))); + connect(m_listview, SIGNAL(clicked(QModelIndex)), + this, SLOT(showTaskInFile(QModelIndex))); m_filterWarningsButton = createFilterButton(Task::Warning, tr("Show Warnings"), m_model, @@ -563,12 +571,29 @@ void TaskWindow::showTaskInFile(const QModelIndex &index) m_listview->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); } +// Right-click VCS annotate: Find version control and point it to line +void TaskWindow::vcsAnnotate() +{ + const QModelIndex index = m_listview->selectionModel()->currentIndex(); + if (!index.isValid()) + return; + const QString file = index.data(TaskModel::File).toString(); + const int line = index.data(TaskModel::Line).toInt(); + const QFileInfo fi(file); + if (fi.exists()) + if (Core::IVersionControl *vc = Core::ICore::instance()->vcsManager()->findVersionControlForDirectory(fi.absolutePath())) + if (vc->supportsOperation(Core::IVersionControl::AnnotateOperation)) + vc->vcsAnnotate(fi.absoluteFilePath(), line); +} + void TaskWindow::copy() { - QModelIndex index = m_listview->selectionModel()->currentIndex(); - QString file = index.data(TaskModel::File).toString(); - QString line = index.data(TaskModel::Line).toString(); - QString description = index.data(TaskModel::Description).toString(); + const QModelIndex index = m_listview->selectionModel()->currentIndex(); + if (!index.isValid()) + return; + const QString file = index.data(TaskModel::File).toString(); + const QString line = index.data(TaskModel::Line).toString(); + const QString description = index.data(TaskModel::Description).toString(); QString type; switch (index.data(TaskModel::Type).toInt()) { case Task::Error: diff --git a/src/plugins/projectexplorer/taskwindow.h b/src/plugins/projectexplorer/taskwindow.h index 3592591f400bafaf430d02c8687f7fc62dbe56c7..e2f02245933e11c83b25c3723ce04d92307ffa3b 100644 --- a/src/plugins/projectexplorer/taskwindow.h +++ b/src/plugins/projectexplorer/taskwindow.h @@ -119,6 +119,7 @@ signals: private slots: void showTaskInFile(const QModelIndex &index); void copy(); + void vcsAnnotate(); void setShowWarnings(bool); void updateCategoriesMenu(); void filterCategoryTriggered(QAction *action); @@ -132,6 +133,7 @@ private: Internal::TaskView *m_listview; Internal::TaskWindowContext *m_taskWindowContext; QAction *m_copyAction; + QAction *m_vcsAnnotateAction; QToolButton *m_filterWarningsButton; QToolButton *m_categoriesButton; QMenu *m_categoriesMenu; diff --git a/src/plugins/subversion/subversioncontrol.cpp b/src/plugins/subversion/subversioncontrol.cpp index ef6a5677fc7718b8628ed764b61d94f82c600ae3..c58159ff60b358a75dc1d6598944fad29b969cf7 100644 --- a/src/plugins/subversion/subversioncontrol.cpp +++ b/src/plugins/subversion/subversioncontrol.cpp @@ -52,6 +52,7 @@ bool SubversionControl::supportsOperation(Operation operation) const switch (operation) { case AddOperation: case DeleteOperation: + case AnnotateOperation: break; case OpenOperation: case CreateRepositoryOperation: @@ -115,6 +116,13 @@ QString SubversionControl::findTopLevelForDirectory(const QString &directory) co return m_plugin->findTopLevelForDirectory(directory); } +bool SubversionControl::vcsAnnotate(const QString &file, int line) +{ + const QFileInfo fi(file); + m_plugin->vcsAnnotate(fi.absolutePath(), fi.fileName(), QString(), line); + return true; +} + void SubversionControl::emitRepositoryChanged(const QString &s) { emit repositoryChanged(s); diff --git a/src/plugins/subversion/subversioncontrol.h b/src/plugins/subversion/subversioncontrol.h index 43e803ace9b47b1522fbb2d07253739602d65283..132aca4d8ec95b237a31520eac47256989b79642 100644 --- a/src/plugins/subversion/subversioncontrol.h +++ b/src/plugins/subversion/subversioncontrol.h @@ -59,6 +59,8 @@ public: virtual bool vcsRestoreSnapshot(const QString &topLevel, const QString &name); virtual bool vcsRemoveSnapshot(const QString &topLevel, const QString &name); + virtual bool vcsAnnotate(const QString &file, int line); + void emitRepositoryChanged(const QString &); void emitFilesChanged(const QStringList &); diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index ee1a116964158e6e9d8af644a25a5d63ea163308..bcc249ef5f84c624a8e5c32d053a806f3febc64a 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -799,7 +799,7 @@ void SubversionPlugin::annotateCurrentFile() { const VCSBase::VCSBasePluginState state = currentState(); QTC_ASSERT(state.hasFile(), return); - annotate(state.currentFileTopLevel(), state.relativeCurrentFile()); + vcsAnnotate(state.currentFileTopLevel(), state.relativeCurrentFile()); } void SubversionPlugin::annotateVersion(const QString &file, @@ -807,10 +807,10 @@ void SubversionPlugin::annotateVersion(const QString &file, int lineNr) { const QFileInfo fi(file); - annotate(fi.absolutePath(), fi.fileName(), revision, lineNr); + vcsAnnotate(fi.absolutePath(), fi.fileName(), revision, lineNr); } -void SubversionPlugin::annotate(const QString &workingDir, const QString &file, +void SubversionPlugin::vcsAnnotate(const QString &workingDir, const QString &file, const QString &revision /* = QString() */, int lineNumber /* = -1 */) { diff --git a/src/plugins/subversion/subversionplugin.h b/src/plugins/subversion/subversionplugin.h index 9acf0926b2aa6e6550354ba7fb40c4c906b8e7e6..2a9283da2fa0d903a097a0ccca5ecee282fd2b09 100644 --- a/src/plugins/subversion/subversionplugin.h +++ b/src/plugins/subversion/subversionplugin.h @@ -100,6 +100,10 @@ public: static SubversionPlugin *subversionPluginInstance(); +public slots: + void vcsAnnotate(const QString &workingDir, const QString &file, + const QString &revision = QString(), int lineNumber = -1); + private slots: void addCurrentFile(); void revertCurrentFile(); @@ -132,8 +136,6 @@ private: SubversionResponse runSvn(const QString &workingDir, const QStringList &arguments, int timeOut, bool showStdOutInOutputWindow, QTextCodec *outputCodec = 0); - void annotate(const QString &workingDir, const QString &file, - const QString &revision = QString(), int lineNumber = -1); void filelog(const QString &workingDir, const QStringList &file = QStringList(), bool enableAnnotationContextMenu = false);