# # # delete "src/view/DiffView.cpp" # # delete "src/view/DiffView.h" # # patch "NEWS" # from [d2ec16781fc257bb5cfb89fb4bd7cb50b9f66437] # to [0cc9be68e25d416c17409b19f0b78b5b41295d16] # # patch "guitone.pro" # from [6e0032b0838ba92246f8267d9d164d6f5485f049] # to [3fd3843b740f3d8859e4647497bbe315d23707ea] # # patch "res/forms/file_diff.ui" # from [9999a04c668f9a40b1a9b20f7ecd0812e8dc7cd5] # to [80ef8d2f2e9421f0fb8a026b00159e6e6e15df61] # # patch "res/forms/revision_diff.ui" # from [56845d2399bd6d4a4e6936b65311cb63a599ba99] # to [b4c9054581ea1f9e5cd89d2556fb30c858f3bd37] # # patch "src/model/ContentDiff.cpp" # from [0b958f4c87f39c1e0999157571d10ac0b497c4ef] # to [f4859a00a655790b3b3772b986ca45c940a9b3de] # # patch "src/model/ContentDiff.h" # from [29385c626e7cc410d08fd00c874afd82f6979fd1] # to [05f150811f860b606483142aca7c3597b367a7c8] # # patch "src/view/dialogs/DatabaseDialogManager.cpp" # from [ee1d232681bf6a8d303e61213d1dab5f2a981526] # to [b4353b273d52faae3b84744adaeb69b3219919a8] # # patch "src/view/dialogs/FileDiff.cpp" # from [436201edbe3071b7d9e8e8ed24310c7879f2a6a5] # to [d2f5ff9152be8a3ccc332dcf9ca71a8e56aa5535] # # patch "src/view/dialogs/RevisionDiff.cpp" # from [78ccc5ca62f2765c0b90507e1282aa2cae3bdffe] # to [1361bc56009d31b862f27759fae0d02a36c0d78b] # # patch "src/view/dialogs/RevisionDiff.h" # from [7cc3c51d118f521ccd84f63e5f82b73ba93479b9] # to [8f6e3ad38608c0c958525a95b42e4998c29876ea] # # patch "src/view/dialogs/WorkspaceDialogManager.cpp" # from [8e528b1a18e3d119b4b5ce771fa53b2be84711a9] # to [9b2ce3991dc8eb8ba04599131783829dac1972f8] # ============================================================ --- NEWS d2ec16781fc257bb5cfb89fb4bd7cb50b9f66437 +++ NEWS 0cc9be68e25d416c17409b19f0b78b5b41295d16 @@ -9,6 +9,8 @@ - new: add, drop and edit file attributes directly in the workspace view! - new: its now possible to actually copy the public key data to the clipboard in the key management dialog + - new: possibility to display a file diff from the revision diff dialog + - improved: input field in the select revision dialog now acts on ENTER - bugfix: the workspace is now properly updated after a commit - change: the proper monotone version is now solely determined by looking at the output of interface version. An upper limit has been introduced for that ============================================================ --- guitone.pro 6e0032b0838ba92246f8267d9d164d6f5485f049 +++ guitone.pro 3fd3843b740f3d8859e4647497bbe315d23707ea @@ -24,7 +24,6 @@ HEADERS = src/view/TreeView.h \ src/view/InventoryView.h \ src/view/InventoryViewDelegate.h \ src/view/AttributesView.h \ - src/view/DiffView.h \ src/view/DiffStatusView.h \ src/view/MenuBar.h \ src/view/DatabaseMenuBar.h \ @@ -96,7 +95,6 @@ SOURCES += src/view/TreeView.cpp \ src/view/InventoryView.cpp \ src/view/InventoryViewDelegate.cpp \ src/view/AttributesView.cpp \ - src/view/DiffView.cpp \ src/view/DiffStatusView.cpp \ src/view/MenuBar.cpp \ src/view/DatabaseMenuBar.cpp \ ============================================================ --- res/forms/file_diff.ui 9999a04c668f9a40b1a9b20f7ecd0812e8dc7cd5 +++ res/forms/file_diff.ui 80ef8d2f2e9421f0fb8a026b00159e6e6e15df61 @@ -16,30 +16,19 @@ :/icons/guitone.png - - 9 - - - 6 - - - 0 - - - 6 - - - 0 - - - 6 - - + + + false + + + false + + @@ -52,20 +41,8 @@ Show - - 9 - - - 6 - - - 0 - - - 6 - @@ -110,12 +87,6 @@ - - 0 - - - 6 - @@ -161,15 +132,15 @@ + TreeView + QTreeView +
TreeView.h
+
+ DiffStatusView QWidget
../DiffStatusView.h
- - DiffView - QTreeView -
../DiffView.h
-
============================================================ --- res/forms/revision_diff.ui 56845d2399bd6d4a4e6936b65311cb63a599ba99 +++ res/forms/revision_diff.ui b4c9054581ea1f9e5cd89d2556fb30c858f3bd37 @@ -13,32 +13,24 @@ :/icons/guitone.png - - 9 - - - 6 - - - 0 - - - 6 - - + - - 0 - - - 6 - + + + false + + + Show detailed differences + + + + Qt::Horizontal @@ -69,9 +61,9 @@ - DiffView + TreeView QTreeView -
../DiffView.h
+
TreeView.h
============================================================ --- src/model/ContentDiff.cpp 0b958f4c87f39c1e0999157571d10ac0b497c4ef +++ src/model/ContentDiff.cpp f4859a00a655790b3b3772b986ca45c940a9b3de @@ -100,27 +100,32 @@ void ContentDiff::processTaskResult(cons // flatten the data for the current view FileDiffs fileDiffs = diffParser->getAllDiffs(); - QMapIterator i(fileDiffs); + QMapIterator i(fileDiffs); while (i.hasNext()) { i.next(); - ListLine * fileLine = new ListLine(ListLine::FileLine); - lines.append(fileLine); + QString fileName = i.key(); + Diff * diff = i.value(); - Diff * diff = (Diff*)i.value(); + ListLine * fileLine = new ListLine(fileName, diff->hunks.size()); + lines.append(fileLine); if (diff->is_binary) { - fileLine->secondColumn = tr("%1 (binary)").arg(i.key()); + fileLine->isBinary = true; continue; } - fileLine->secondColumn = - tr("%1 (%2 hunks)").arg(i.key()).arg(diff->hunks.size()); - for (int j=0, k=diff->hunks.size(); jhunks.at(j); + + // The oldLineNumber is only raised for kept and old lines + // in the following loop. + // This way people should be able to navigate in the original + // file and see the the changes even better. + int oldLineNumber = hunk->leftStart; + for (int m=0, n=hunk->lines.size(); mlines.at(m); @@ -129,17 +134,19 @@ void ContentDiff::processTaskResult(cons if (line->state == DiffLine::Unchanged) { - hunkLine->firstColumn = QString::number(hunk->leftStart + m); + oldLineNumber++; + hunkLine->lineMarker = QString::number(oldLineNumber); } else if (line->state == DiffLine::Added) { - hunkLine->firstColumn = QString("+"); + hunkLine->lineMarker = QString("+"); } else { - hunkLine->firstColumn = QString("-"); + oldLineNumber++; + hunkLine->lineMarker = QString("-"); } - hunkLine->secondColumn = line->content; + hunkLine->lineContent = line->content; } if (j < k-1) @@ -172,8 +179,8 @@ QVariant ContentDiff::data(const QModelI { switch (col) { - case 0: return QVariant(line->firstColumn); - case 1: return QVariant(line->secondColumn); + case 0: return QVariant(line->firstCol()); + case 1: return QVariant(line->secondCol()); } I(false); @@ -206,12 +213,12 @@ QVariant ContentDiff::data(const QModelI { if (line->type != ListLine::HunkLine) return QVariant(); - if (line->firstColumn.compare("-") == 0) + if (line->lineMarker.compare("-") == 0) { return QVariant(QBrush(Qt::red)); } - if (line->firstColumn.compare("+") == 0) + if (line->lineMarker.compare("+") == 0) { return QVariant(QBrush(Qt::green)); } ============================================================ --- src/model/ContentDiff.h 29385c626e7cc410d08fd00c874afd82f6979fd1 +++ src/model/ContentDiff.h 05f150811f860b606483142aca7c3597b367a7c8 @@ -32,22 +32,55 @@ struct ListLine enum Type { FileLine, HunkSep, HunkLine }; Type type; - QString firstColumn; - QString secondColumn; + QString fileName; + int hunkCount; + bool isBinary; + QString lineMarker; + QString lineContent; + ListLine * parent; QList lines; - ListLine() : type(HunkLine), parent(0) {} - ListLine(Type t) : type(t), parent(0) + ListLine(Type t) : type(t), parent(0) {} + ListLine(const QString & file, int count) + : type(FileLine), fileName(file), hunkCount(count), + isBinary(false), parent(0) {} + + ~ListLine() { - if (type == HunkSep) firstColumn = "..."; + qDeleteAll(lines); + lines.clear(); } - inline ~ListLine() + + QString firstCol() const { - qDeleteAll(lines); - lines.clear(); + switch (type) + { + case HunkSep: return QString("..."); + case FileLine: return QString(); + case HunkLine: return lineMarker; + default: I(false); + } } + QString secondCol() const + { + switch (type) + { + case HunkSep: return QString(); + case FileLine: return isBinary + ? QObject::tr("%1 (binary)").arg(fileName) + : QObject::tr("%1 (%2 hunks)").arg(fileName).arg(hunkCount); + case HunkLine: return lineContent; + default: I(false); + } + } + + bool isFileLineAndDiffable() + { + return type == FileLine && !isBinary; + } + void addChild(ListLine * l) { lines.append(l); l->parent = this; } }; ============================================================ --- src/view/dialogs/DatabaseDialogManager.cpp ee1d232681bf6a8d303e61213d1dab5f2a981526 +++ src/view/dialogs/DatabaseDialogManager.cpp b4353b273d52faae3b84744adaeb69b3219919a8 @@ -115,7 +115,7 @@ void DatabaseDialogManager::showFileHist { if (!fileHistory) { - fileHistory = new FileHistory(parentWidget(), databaseFile); + fileHistory = new FileHistory(parentWidget(), databaseFile); connect( fileHistory, SIGNAL(fileDiff(const QString &, const QString &, const QString &)), @@ -161,6 +161,11 @@ void DatabaseDialogManager::showRevision if (!revisionDiff) { revisionDiff = new RevisionDiff(parentWidget()); + + connect( + revisionDiff, SIGNAL(fileDiff(const QString &, const QString &, const QString &)), + this, SLOT(showFileDiff(const QString &, const QString &, const QString &)) + ); } revisionDiff->forDatabase(databaseFile, file, base, target); ============================================================ --- src/view/dialogs/FileDiff.cpp 436201edbe3071b7d9e8e8ed24310c7879f2a6a5 +++ src/view/dialogs/FileDiff.cpp d2f5ff9152be8a3ccc332dcf9ca71a8e56aa5535 @@ -35,7 +35,7 @@ FileDiff::FileDiff(QWidget * parent) : D connect( firstRevision, SIGNAL(toggled(bool)), - this, SLOT(versionToggled(bool)) + this, SLOT(versionToggled()) ); connect( secondRevision, SIGNAL(toggled(bool)), @@ -43,7 +43,7 @@ FileDiff::FileDiff(QWidget * parent) : D ); connect( bothRevisions, SIGNAL(toggled(bool)), - this, SLOT(versionToggled(bool)) + this, SLOT(versionToggled()) ); connect( ============================================================ --- src/view/dialogs/RevisionDiff.cpp 78ccc5ca62f2765c0b90507e1282aa2cae3bdffe +++ src/view/dialogs/RevisionDiff.cpp 1361bc56009d31b862f27759fae0d02a36c0d78b @@ -32,8 +32,25 @@ RevisionDiff::RevisionDiff(QWidget * par // arrow width is approx. 10px diffView->setIndentation(10); + connect( + diffView, SIGNAL(clicked(const QModelIndex &)), + this, SLOT(enableDisableFileDiff(const QModelIndex &)) + ); + + connect( + diffView, SIGNAL(doubleClicked(const QModelIndex &)), + this, SLOT(triggerFileDiff(const QModelIndex &)) + ); + + connect( + showFileDiff, SIGNAL(clicked()), + this, SLOT(triggerFileDiff()) + ); + diffModel = new ContentDiff(this); diffView->setModel(diffModel); + + showFileDiff->setEnabled(false); } RevisionDiff::~RevisionDiff() @@ -44,6 +61,9 @@ void RevisionDiff::forDatabase(const Dat void RevisionDiff::forDatabase(const DatabaseFile & db, const QString & filePath, const QString & base, const QString & target) { + baseRevision = base; + targetRevision = target; + QString left = base.left(12).append("..."); QString right = target.left(12).append("..."); @@ -62,6 +82,9 @@ void RevisionDiff::forWorkspace(const Wo void RevisionDiff::forWorkspace(const WorkspacePath & ws, const QString & filePath, const QString & base, const QString & target) { + baseRevision = base; + targetRevision = target; + QString left = tr("base revision"); QString right = tr("workspace revision"); @@ -87,3 +110,33 @@ void RevisionDiff::forWorkspace(const Wo diffModel->readWorkspaceDiff(ws, filePath, base, target); } +void RevisionDiff::enableDisableFileDiff(const QModelIndex & index) +{ + ListLine * line = static_cast(index.internalPointer()); + if (line->isFileLineAndDiffable()) + { + fileName = line->fileName; + showFileDiff->setEnabled(true); + } + else + { + showFileDiff->setEnabled(false); + } +} + +void RevisionDiff::triggerFileDiff(const QModelIndex & index) +{ + ListLine * line = static_cast(index.internalPointer()); + if (line->isFileLineAndDiffable()) + { + fileName = line->fileName; + triggerFileDiff(); + } +} + +void RevisionDiff::triggerFileDiff() +{ + I(!fileName.isEmpty()); + emit fileDiff(fileName, baseRevision, targetRevision); +} + ============================================================ --- src/view/dialogs/RevisionDiff.h 7cc3c51d118f521ccd84f63e5f82b73ba93479b9 +++ src/view/dialogs/RevisionDiff.h 8f6e3ad38608c0c958525a95b42e4998c29876ea @@ -35,8 +35,19 @@ public: void forDatabase(const DatabaseFile &, const QString &, const QString &, const QString &); void forWorkspace(const WorkspacePath &, const QString &, const QString &, const QString &); +signals: + void fileDiff(const QString &, const QString &, const QString &); + private: ContentDiff * diffModel; + QString fileName; + QString baseRevision; + QString targetRevision; + +private slots: + void enableDisableFileDiff(const QModelIndex &); + void triggerFileDiff(const QModelIndex &); + void triggerFileDiff(); }; #endif ============================================================ --- src/view/dialogs/WorkspaceDialogManager.cpp 8e528b1a18e3d119b4b5ce771fa53b2be84711a9 +++ src/view/dialogs/WorkspaceDialogManager.cpp 9b2ce3991dc8eb8ba04599131783829dac1972f8 @@ -96,6 +96,11 @@ void WorkspaceDialogManager::showRevisio if (!revisionDiff) { revisionDiff = new RevisionDiff(parentWidget()); + + connect( + revisionDiff, SIGNAL(fileDiff(const QString &, const QString &, const QString &)), + this, SLOT(showFileDiff(const QString &, const QString &, const QString &)) + ); } revisionDiff->forWorkspace(workspacePath, file, base, target);