# # # patch "res/forms/dialogs/annotate.ui" # from [afb7bdb74c80f6dd7d1645215548059e1a584706] # to [4284de7e03e359a4f93edafdd2fb074e46e5ef35] # # patch "src/model/Annotate.cpp" # from [bac57aad56435487ef2a0d1c1ab77f24fd89e8f2] # to [58945728c8221cca5248cf30fcd9f97d2dcad4cf] # # patch "src/model/Annotate.h" # from [9bdd4df9225285fd4bcf6aab4ea556774078836f] # to [6b0eda06cab7acc0b94167e919247155dda40cbc] # # patch "src/view/dialogs/AnnotateFile.cpp" # from [7781a16f5c64f4b921e04caeb7a1e9a15ff95d56] # to [692f21e4684bfcf0617b4590475e8227b089b13a] # # patch "src/view/dialogs/AnnotateFile.h" # from [685e5a17947635dbb3d8a90ef57f52ed030ef5de] # to [6d8d61ba66b1f6691a5bf5b56959ccfb0331a016] # # patch "src/view/dialogs/DatabaseDialogManager.cpp" # from [f4db2568e47377dd70644044c39d69a7eb02e179] # to [51cc7d27d32e6996f1b6a22bd30b2ff8f737b349] # # patch "src/view/dialogs/WorkspaceDialogManager.cpp" # from [ef40f0ecdc9c58eed29e5f1eca307d4bd5853d15] # to [b0ef246f9747ea8da66a59c6cd236e99028eca0b] # ============================================================ --- res/forms/dialogs/annotate.ui afb7bdb74c80f6dd7d1645215548059e1a584706 +++ res/forms/dialogs/annotate.ui 4284de7e03e359a4f93edafdd2fb074e46e5ef35 @@ -37,23 +37,7 @@ - - - - 0 - 0 - - - - - 150 - 0 - - - - true - - + ============================================================ --- src/model/Annotate.cpp bac57aad56435487ef2a0d1c1ab77f24fd89e8f2 +++ src/model/Annotate.cpp 58945728c8221cca5248cf30fcd9f97d2dcad4cf @@ -119,6 +119,7 @@ void Annotate::readAnnotation(const Data ); databaseFile = db; + baseRevision = rev; proc->start( QStringList() << "annotate" << "-d" << db << "-r" << rev << "--revs-only" << file @@ -325,3 +326,13 @@ void Annotate::setSelectedRevision(const } } +QString Annotate::getSelectedRevision() const +{ + return selectedRevision; +} + +QString Annotate::getBaseRevision() const +{ + return baseRevision; +} + ============================================================ --- src/model/Annotate.h 9bdd4df9225285fd4bcf6aab4ea556774078836f +++ src/model/Annotate.h 6b0eda06cab7acc0b94167e919247155dda40cbc @@ -68,6 +68,8 @@ public slots: public slots: void readAnnotation(const DatabaseFile &, const QString &, const QString &); void setSelectedRevision(const QString &); + QString getSelectedRevision() const; + QString getBaseRevision() const; signals: void annotationRead(); @@ -75,14 +77,19 @@ private: private: DatabaseFile databaseFile; - QList annotationLines; + MonotoneProcess * proc; Certs * certsModel; + + QList annotationLines; QStack certsToRead; QMap certMap; QMap brushMap, inverseBrushMap; + QBrush highlightBrush; + QString selectedRevision; + QString baseRevision; void readNextCerts(); ============================================================ --- src/view/dialogs/AnnotateFile.cpp 7781a16f5c64f4b921e04caeb7a1e9a15ff95d56 +++ src/view/dialogs/AnnotateFile.cpp 692f21e4684bfcf0617b4590475e8227b089b13a @@ -20,12 +20,20 @@ #include "MonotoneUtil.h" #include +#include AnnotateFile::AnnotateFile(QWidget * parent) : Dialog(parent), annotateModel(0) { setupUi(this); Dialog::init(); + // clear all remembered revisions when the dialog is closed so + // we start with a fresh set of items for the next annotation + connect( + this, SIGNAL(dialogHidden()), + baseRevision, SLOT(clear()) + ); + annotateModel = new Annotate(this); annotationView->setModel(annotateModel); @@ -45,10 +53,25 @@ AnnotateFile::AnnotateFile(QWidget * par ); connect( + annotationView, SIGNAL(contextMenuRequested(const QModelIndexList &, const QPoint &)), + this, SLOT(contextMenuRequested(const QModelIndexList &, const QPoint &)) + ); + + connect( + annotationView, SIGNAL(doubleClicked(const QModelIndex &)), + this, SLOT(doubleClicked(const QModelIndex &)) + ); + + connect( selectRevisionButton, SIGNAL(clicked()), this, SIGNAL(selectRevision()) ); + connect( + baseRevision, SIGNAL(currentIndexChanged(const QString &)), + this, SLOT(setSelectedRevision(const QString &)) + ); + progressWidget->hide(); } @@ -57,21 +80,24 @@ AnnotateFile::~AnnotateFile() if (annotateModel) delete annotateModel; } -void AnnotateFile::forWorkspace(const WorkspacePath & workspace, const QString & file) +void AnnotateFile::read(const DatabaseFile & db, const QString & rev, const QString & file) { - forDatabase( - MonotoneUtil::getDatabaseFile(workspace), - MonotoneUtil::getBaseWorkspaceRevision(workspace), - file - ); -} + if (rev == annotateModel->getBaseRevision() && file == filePath) + { + return; + } -void AnnotateFile::forDatabase(const DatabaseFile & db, const QString & rev, const QString & file) -{ databaseFile = db; filePath = file; - baseRevision->setText(rev); + int pos = baseRevision->findText(rev); + if (pos == -1) + { + baseRevision->insertItem(0, rev); + pos = 0; + } + baseRevision->setCurrentIndex(pos); + setWindowTitle(tr("Annotation of %1").arg(filePath)); annotateModel->readAnnotation(databaseFile, rev, filePath); progressWidget->show(); @@ -79,10 +105,19 @@ void AnnotateFile::setSelectedRevision(c void AnnotateFile::setSelectedRevision(const QString & rev) { - QString newPath = MonotoneUtil::getCorrespondingPath( - databaseFile, baseRevision->text(), filePath, rev - ); + if (rev.isEmpty()) + return; + QString currentBaseRevision = annotateModel->getBaseRevision(); + QString newPath = filePath; + + if (!currentBaseRevision.isEmpty()) + { + newPath = MonotoneUtil::getCorrespondingPath( + databaseFile, currentBaseRevision, filePath, rev + ); + } + if (newPath.isEmpty()) { QMessageBox::information( @@ -95,7 +130,7 @@ void AnnotateFile::setSelectedRevision(c return; } - forDatabase(databaseFile, rev, newPath); + read(databaseFile, rev, newPath); } void AnnotateFile::rowsSelected(const QModelIndexList & indexes) @@ -116,3 +151,59 @@ void AnnotateFile::rowsSelected(const QM annotationView->selectionModel()->clearSelection(); } +void AnnotateFile::contextMenuRequested(const QModelIndexList & indexList, const QPoint & pos) +{ + // FIXME: since we clear the selection in rowsSelected(), indexList is + // always empty, so we can't use that. Beware that there could be a race + // condition where rowsSelected() is executed _after_ contectMenuRequest(), + // thus the annotate model does not have the correct current revision set! + Q_UNUSED(indexList); + QString rev = annotateModel->getSelectedRevision(); + + QStringList parents = MonotoneUtil::resolveSelector(databaseFile, "p:" + rev); + + QMenu menu(this); + QFont activeFont; + activeFont.setBold(true); + + QAction * actSelectRevision = menu.addAction(tr("Select as base revision")); + QAction * actOpenManifest = menu.addAction(tr("View files in this revision")); + + QAction * actFileDiff = 0, * actRevisionDiff = 0; + // FIXME: no support for revisions with multiple parents yet + if (parents.size() == 1) + { + actFileDiff = menu.addAction(tr("Show file differences")); + actRevisionDiff = menu.addAction(tr("Show all revision differences")); + } + + actSelectRevision->setFont(activeFont); + + QAction * act = menu.exec(pos); + if (act == actSelectRevision) + { + setSelectedRevision(rev); + } + else if (act == actOpenManifest) + { + emit revisionManifest(rev); + } + else if (act == actFileDiff) + { + I(parents.size() == 1); + emit fileDiff(filePath, parents.at(0), rev); + } + else if (act == actRevisionDiff) + { + I(parents.size() == 1); + emit revisionDiff(QString(), parents.at(0), rev); + } +} + +void AnnotateFile::doubleClicked(const QModelIndex & index) +{ + if (!index.isValid()) + return; + + setSelectedRevision(index.data(Qt::UserRole).toString()); +} ============================================================ --- src/view/dialogs/AnnotateFile.h 685e5a17947635dbb3d8a90ef57f52ed030ef5de +++ src/view/dialogs/AnnotateFile.h 6d8d61ba66b1f6691a5bf5b56959ccfb0331a016 @@ -33,12 +33,14 @@ public slots: ~AnnotateFile(); public slots: - void forWorkspace(const WorkspacePath &, const QString &); - void forDatabase(const DatabaseFile &, const QString &, const QString &); + void read(const DatabaseFile &, const QString &, const QString &); void setSelectedRevision(const QString &); signals: void selectRevision(); + void revisionManifest(const QString &); + void fileDiff(const QString &, const QString &, const QString &); + void revisionDiff(const QString &, const QString &, const QString &); private: Annotate * annotateModel; @@ -47,6 +49,8 @@ private slots: private slots: void rowsSelected(const QModelIndexList &); + void contextMenuRequested(const QModelIndexList &, const QPoint &); + void doubleClicked(const QModelIndex &); }; #endif ============================================================ --- src/view/dialogs/DatabaseDialogManager.cpp f4db2568e47377dd70644044c39d69a7eb02e179 +++ src/view/dialogs/DatabaseDialogManager.cpp 51cc7d27d32e6996f1b6a22bd30b2ff8f737b349 @@ -303,17 +303,32 @@ void DatabaseDialogManager::showAnnotati annotateFile = new AnnotateFile(parentWidget()); connect( - annotateFile, SIGNAL(selectRevision(const QString &)), - this, SLOT(showSelectRevision(const QString &)) + annotateFile, SIGNAL(selectRevision()), + this, SLOT(showSelectRevision()) ); connect( this, SIGNAL(revisionSelected(const QString &)), annotateFile, SLOT(setSelectedRevision(const QString &)) ); + + connect( + annotateFile, SIGNAL(revisionManifest(const QString &)), + this, SLOT(showRevisionManifest(const QString &)) + ); + + connect( + annotateFile, SIGNAL(revisionDiff(const QString &, const QString &, const QString &)), + this, SLOT(showRevisionDiff(const QString &, const QString &, const QString &)) + ); + + connect( + annotateFile, SIGNAL(fileDiff(const QString &, const QString &, const QString &)), + this, SLOT(showFileDiff(const QString &, const QString &, const QString &)) + ); } - annotateFile->forDatabase(databaseFile, rev, file); + annotateFile->read(databaseFile, rev, file); showDialog(annotateFile); } ============================================================ --- src/view/dialogs/WorkspaceDialogManager.cpp ef40f0ecdc9c58eed29e5f1eca307d4bd5853d15 +++ src/view/dialogs/WorkspaceDialogManager.cpp b0ef246f9747ea8da66a59c6cd236e99028eca0b @@ -164,22 +164,9 @@ void WorkspaceDialogManager::showAnnotat void WorkspaceDialogManager::showAnnotation(const QString & file) { - if (!annotateFile) - { - annotateFile = new AnnotateFile(parentWidget()); - - connect( - annotateFile, SIGNAL(selectRevision()), - this, SLOT(showSelectRevision()) - ); - - connect( - this, SIGNAL(revisionSelected(const QString &)), - annotateFile, SLOT(setSelectedRevision(const QString &)) - ); - } - - annotateFile->forWorkspace(workspacePath, file); - showDialog(annotateFile); + DatabaseDialogManager::showAnnotation( + MonotoneUtil::getBaseWorkspaceRevision(workspacePath), + file + ); }