# # # patch "guitone/guitone.pro" # from [49a24c7330525835a70b169a086f4ea9ee5e3f6d] # to [1d0b76a9f80f37b5c5f122d3439554ca1b3da8eb] # # patch "guitone/src/model/ContentDiff.cpp" # from [1e58b03ad145e7e21ddab17e527ea21ed37aad4c] # to [266e612ce327dd35334a34c59a8fcfbb96090e71] # # patch "guitone/src/model/ContentDiff.h" # from [c520819fe390978f21f38ac1914b7a56f1d009f0] # to [7b893384b27150e421956e5834087d7fe454c041] # # patch "guitone/src/model/GetFile.cpp" # from [0117818744e4fe5b21736b6455f8907891cf5207] # to [5a26992c2a9ce6552ad1792f6b140cbc1fa0cf4c] # # patch "guitone/src/model/GetFile.h" # from [c0eef19054f57b96eeb9bc989be39e972f4c0697] # to [b7d451ce64492ca12ae8097b4bd87f2961b05174] # # patch "guitone/src/util/DiffParser.cpp" # from [a39cfc9afaf8f44745392fffbba460ac876b760b] # to [bbfb38a9a3726e8a216c405c9e5753856d4b1529] # # patch "guitone/src/util/DiffParser.h" # from [d2f98e7daeae0b9a95d9288c577ab703f093e2ed] # to [568c7594ae3f23b95c1834b466fbd44b513f0eed] # ============================================================ --- guitone/guitone.pro 49a24c7330525835a70b169a086f4ea9ee5e3f6d +++ guitone/guitone.pro 1d0b76a9f80f37b5c5f122d3439554ca1b3da8eb @@ -23,6 +23,7 @@ HEADERS += src/view/Guitone.h \ src/model/Select.h \ src/model/Certs.h \ src/model/Graph.h \ + src/model/ContentDiff.h \ src/model/GetFile.h \ src/util/IconProvider.h \ src/util/StanzaParser.h \ @@ -46,6 +47,7 @@ SOURCES += src/view/Guitone.cpp \ src/model/Select.cpp \ src/model/Certs.cpp \ src/model/Graph.cpp \ + src/model/ContentDiff.cpp \ src/model/GetFile.cpp \ src/util/IconProvider.cpp \ src/util/StanzaParser.cpp \ ============================================================ --- guitone/src/model/ContentDiff.cpp 1e58b03ad145e7e21ddab17e527ea21ed37aad4c +++ guitone/src/model/ContentDiff.cpp 266e612ce327dd35334a34c59a8fcfbb96090e71 @@ -63,28 +63,7 @@ bool ContentDiff::readDiff( // reset the view reset(); - Monotone *mtn = Monotone::singleton(); - - // - // read in the original file - // - baseFileName = fileName; - QStringList cmd; - cmd << "get_file_of" << diffFileName; - - QStringList opts; - opts << "r" << leftRevision; - - if (!mtn->executeCommand(cmd, opts)) - { - qWarning("ContentDiff::readDiff: could not execute get_file_of"); - return false; - } - - baseFileContents = mtn->getOutput().split(QRegExp("/[\r\n]+/")); - - QStringList cmd; cmd << "content_diff" << fileName; QStringList opts; @@ -105,188 +84,42 @@ void ContentDiff::parseOutput(AutomateCo // if not we are the caller, omit the parsing if (caller != this) return; - diffParser = new diffParser(AutomateCommand::data); - Diff * diff = diffParser->getDiff(diffFileName); - - if (diff->is_binary) - { - emit parsingError(tr("Binary file %1 can't be diffed.").arg(baseFileName)); - return; - } - - int leftLastHunk = 0, rightLastHunk = 0; + diffParser = new DiffParser(AutomateCommand::data); - for (int i=0, s=diff->hunks.size(); ihunks.at(i); - - // push unrelated left lines - if (hunk->leftStart > 0) - { - pushNewLines(Left, - ContentLine::Unchanged, - baseFileContents.mid(leftLastHunk, hunk->leftStart) - ); - } - - // push unrelated right lines - if (hunk->rightStart > 0) - { - pushNewLines(Right, - ContentLine::Unchanged, - baseFileContents.mid(rightLastHunk, hunk->rightStart) - ); - } - - leftLastHunk = hunk->leftStart + hunk->leftCount; - rightLastHunk = hunk->rightStart + hunk->rightCount; - - int leftLastLine = 0, rightLastLine = 0; - - // now parse each line group in the hunk - for (int j=0, t=hunk->lines.size(); jlines.at(j); - - if (line->state == DiffLines::Removed) - { - if (leftLastLine < line->startPos) - { - int pos = leftLastHunk + leftLastLine; - int count = line->startPos - leftLastLine; - - pushNewLines(Left, - ContentLine::Unchanged, - baseFileContents.mid(pos, count) - ); - } - - // TODO: Take care of line relations - pushNewLines(Left, - ContentLine::Changed, - line->contents); - - leftLastLine = line->startPos + line->changeLen; - continue; - } - - // DiffLines::Added - if (rightLastLine < line->startPos) - { - int pos = rightLastHunk + rightLastLine; - int count = line->startPos - rightLastLine; - - pushNewLines(Right, - ContentLine::Unchanged, - baseFileContents.mid(pos, count) - ); - } - - // TODO: Take care of line relations - pushNewLines(Right, - ContentLine::Changed, - line->contents); - - rightLastLine = line->startPos + line->changeLen; - } - } - - // signal that we've finished (whoever listens to that) emit diffRead(); } -void ContentDiff::pushNewLines(FileVersion version, ContentLine::Marker marker, const QStringList & contents) -{ - for (int i=0, s=contents.size(); i= attributes->size()) return QVariant(); - - Attribute attr = attributes->at(row); - - switch (index.column()) - { - case 0: return QVariant(attr.key); - case 1: return QVariant(attr.value); - case 2: - switch (attr.state) - { - case Attribute::Added: return QVariant(tr("added")); - case Attribute::Dropped: return QVariant(tr("dropped")); - case Attribute::Changed: return QVariant(tr("changed")); - case Attribute::Unchanged: return QVariant(tr("unchanged")); - } - } - - return QVariant(); + return QVariant(); } Qt::ItemFlags ContentDiff::flags(const QModelIndex &index) const { - // TODO: add ItemIsEditable as soon as we can set/drop attributes through - // the automation interface, implement setData() then as well - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + return 0; } QVariant ContentDiff::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) - { - switch (section) - { - case 0: return QVariant(tr("Key")); - case 1: return QVariant(tr("Value")); - case 2: return QVariant(tr("State")); - } - } - return QVariant(); + return QVariant(); } int ContentDiff::rowCount(const QModelIndex& parent) const { - return attributes->size(); + return 0; } QModelIndex ContentDiff::index(int row, int column, const QModelIndex& parent) const { - return hasIndex(row, column, parent) ? createIndex(row, column, 0) : QModelIndex(); + return QModelIndex(); } QModelIndex ContentDiff::parent(const QModelIndex& index) const ============================================================ --- guitone/src/model/ContentDiff.h c520819fe390978f21f38ac1914b7a56f1d009f0 +++ guitone/src/model/ContentDiff.h 7b893384b27150e421956e5834087d7fe454c041 @@ -26,13 +26,6 @@ #include "AutomateCommand.h" #include "../util/DiffParser.h" -struct ContentLine { - QString content; - enum Marker {Changed, Unchanged} marker; -} - -typedef QVector Content; - class ContentDiff : public AutomateCommand { Q_OBJECT @@ -49,7 +42,8 @@ public: int rowCount(const QModelIndex&) const; int columnCount(const QModelIndex&) const; - enum FileVersion { Left, Right } fileVersion; + inline Diff * getDiff(QString fileName) { return diffParser->getDiff(fileName); } + inline FileDiffs getAllDiffs() { return diffParser->getAllDiffs(); } public slots: bool readDiff(QString); @@ -61,13 +55,7 @@ private: private: void parseOutput(AutomateCommand*); - DiffParser * diffParser; - QString baseFileName; - QStringList baseFileContents; - - Content leftFile; - Content rightFile; }; #endif ============================================================ --- guitone/src/model/GetFile.cpp 0117818744e4fe5b21736b6455f8907891cf5207 +++ guitone/src/model/GetFile.cpp 5a26992c2a9ce6552ad1792f6b140cbc1fa0cf4c @@ -20,6 +20,7 @@ #include "GetFile.h" #include "../monotone/Monotone.h" +#include GetFile::GetFile(QObject *parent) : AutomateCommand(parent) @@ -81,6 +82,157 @@ void GetFile::parseOutput(AutomateComman emit fileRead(); } +void GetFile::applyDiff(Diff * diff, FileVersion version) +{ + int curLine = 0; + int leftLastHunk = 0, rightLastHunk = 0; + + for (int i=0, s=diff->hunks.size(); ihunks.at(i); + + // skip unrelated left/right lines + if (version == Left && hunk->leftStart > 0) + { + curLine += hunk->leftStart - leftLastHunk; + } + + if (version == Right && hunk->rightStart > 0) + { + curLine += hunk->rightStart - rightLastHunk; + } + + leftLastHunk = hunk->leftStart + hunk->leftCount; + rightLastHunk = hunk->rightStart + hunk->rightCount; + + int leftLastLine = 0, rightLastLine = 0; + + for (int j=0, t=hunk->lineGroups.size(); jlineGroups.at(j); + + if (version == Left) + { + // skip the added part, this is not used here + if (group->state == DiffLineGroup::Added) continue; + + // skip even more unchanged lines + if (leftLastLine < group->startPos) + { + curLine += group->startPos - leftLastLine; + } + + Q_ASSERT(fileContents.size() >= curLine + group->changeLen); + + // set the following lines to "Removed" + for (int k = curLine, l = k+group->changeLen; kchangeLen; + + leftLastLine = group->startPos + group->changeLen; + continue; + } + + if (version == Right) + { + // each removed line group is followed by an added line group + // we're processing here these two at once + if (group->state == DiffLineGroup::Removed) + { + // skip even more unchanged lines + if (rightLastLine < group->startPos) + { + curLine += group->startPos - rightLastLine; + } + + // remove deleted lines from the right + // don't raise the curLine counter! + fileContents.remove(curLine, group->changeLen); + + // go to the next add part + j += 1; + + // add the new lines accordingly + group = hunk->lineGroups.at(j); + + for (int x=0, y=group->changeLen; xcontents.at(x), ContentLine::Added) + ); + } + curLine += group->changeLen; + + // raise the line count for the other items + for (int x=curLine, y=fileContents.size(); xstate == DiffLineGroup::Removed) + { + // skip even more unchanged lines + if (rightLastLine < group->startPos) + { + curLine += group->startPos - rightLastLine; + } + + // mark deleted lines + for (int k = curLine, l = k+group->changeLen; kchangeLen; + + // go to the next add part + j += 1; + + // add the new lines accordingly + group = hunk->lineGroups.at(j); + + for (int x=0, y=group->contents.size(); xcontents.at(x), ContentLine::Added) + ); + } + curLine += group->changeLen; + + // raise the line count for the other items + for (int x=curLine, y=fileContents.size(); x -1); + Q_ASSERT(rx.indexIn(nextGroup) > -1); QStringList list = rx.capturedTexts(); Q_ASSERT(list.size() >= 2); @@ -111,7 +111,7 @@ void DiffParser::parse(const QString & i else curHunk->rightCount = 1; - curLine = 0; + curGroup = 0; leftLinesCount = 0; rightLinesCount = 0; @@ -147,21 +147,21 @@ void DiffParser::parse(const QString & i // create linked dummy item if (lastChar == ' ') { - DiffLines * lastLine = new DiffLines(); - lastLine->startPos = leftLinesCount; - lastLine->changeLen = 0; - lastLine->state = DiffLines::Removed; + DiffLineGroup * lastGroup = new DiffLineGroup(); + lastGroup->startPos = leftLinesCount; + lastGroup->changeLen = 0; + lastGroup->state = DiffLineGroup::Removed; - curHunk->lines.push_back(lastLine); - curLine = new DiffLines(); - curHunk->lines.push_back(curLine); + curHunk->lineGroups.push_back(lastGroup); + curGroup = new DiffLineGroup(); + curHunk->lineGroups.push_back(curGroup); - curLine->startPos = rightLinesCount; - curLine->changeLen = 1; - curLine->contents.push_back(line.mid(1)); + curGroup->startPos = rightLinesCount; + curGroup->changeLen = 1; + curGroup->contents.push_back(line.mid(1)); - lastLine->friendLines = curLine; - curLine->friendLines = lastLine; + lastGroup->friendGroup = curGroup; + curGroup->friendGroup = lastGroup; leftLinesCount++; continue; @@ -169,26 +169,26 @@ void DiffParser::parse(const QString & i if (lastChar == '+') { - curLine->contents.push_back(line.mid(1)); - curLine->changeLen++; + curGroup->contents.push_back(line.mid(1)); + curGroup->changeLen++; leftLinesCount++; continue; } if (lastChar == '-') { - curLine = new DiffLines(); - curHunk->lines.push_back(curLine); + curGroup = new DiffLineGroup(); + curHunk->lineGroups.push_back(curGroup); - curLine->startPos = rightLinesCount; - curLine->changeLen = 1; - curLine->state = DiffLines::Added; - curLine->contents.push_back(line.mid(1)); + curGroup->startPos = rightLinesCount; + curGroup->changeLen = 1; + curGroup->state = DiffLineGroup::Added; + curGroup->contents.push_back(line.mid(1)); - DiffLines * lastLine = curHunk->lines.last(); - Q_ASSERT(lastLine); - curLine->friendLines = lastLine; - lastLine->friendLines = curLine; + DiffLineGroup * lastGroup = curHunk->lineGroups.last(); + Q_ASSERT(lastGroup); + curGroup->friendGroup = lastGroup; + lastGroup->friendGroup = curGroup; leftLinesCount++; continue; @@ -218,22 +218,22 @@ void DiffParser::parse(const QString & i // create linked dummy item if (nextChar == ' ') { - DiffLines * nextLine = new DiffLines(); - nextLine->startPos = rightLinesCount; - nextLine->changeLen = 0; - nextLine->state = DiffLines::Added; + DiffLineGroup * nextGroup = new DiffLineGroup(); + nextGroup->startPos = rightLinesCount; + nextGroup->changeLen = 0; + nextGroup->state = DiffLineGroup::Added; - curLine = new DiffLines(); - curHunk->lines.push_back(curLine); + curGroup = new DiffLineGroup(); + curHunk->lineGroups.push_back(curGroup); - curHunk->lines.push_back(nextLine); + curHunk->lineGroups.push_back(nextGroup); - curLine->startPos = leftLinesCount; - curLine->changeLen = 1; - curLine->contents.push_back(line.mid(1)); + curGroup->startPos = leftLinesCount; + curGroup->changeLen = 1; + curGroup->contents.push_back(line.mid(1)); - nextLine->friendLines = curLine; - curLine->friendLines = nextLine; + nextGroup->friendGroup = curGroup; + curGroup->friendGroup = nextGroup; rightLinesCount++; continue; @@ -242,8 +242,8 @@ void DiffParser::parse(const QString & i if (nextChar == '+') { // this case is already handled above - curLine->contents.push_back(line.mid(1)); - curLine->changeLen++; + curGroup->contents.push_back(line.mid(1)); + curGroup->changeLen++; rightLinesCount++; continue; } @@ -251,7 +251,7 @@ void DiffParser::parse(const QString & i if (nextChar == '-') { // this case is already handled above - curLine->changeLen++; + curGroup->changeLen++; rightLinesCount++; continue; } ============================================================ --- guitone/src/util/DiffParser.h d2f98e7daeae0b9a95d9288c577ab703f093e2ed +++ guitone/src/util/DiffParser.h 568c7594ae3f23b95c1834b466fbd44b513f0eed @@ -26,18 +26,18 @@ #include #include -struct DiffLines +struct DiffLineGroup { enum State {Added, Removed} state; int startPos; int changeLen; - QVector contents; - DiffLines * friendLines; + QList contents; + DiffLineGroup * friendGroup; }; struct DiffHunk { - QVector lines; + QList lineGroups; int leftStart; int leftCount; int rightStart; @@ -46,20 +46,24 @@ struct Diff struct Diff { - QVector hunks; + QList hunks; bool is_binary; }; +typedef QMap FileDiffs; + class DiffParser : public QObject { Q_OBJECT public: DiffParser(const QString &); ~DiffParser(); - Diff* getDiff(const QString &); + Diff * getDiff(const QString &); + inline FileDiffs getAllDiffs() const { return fileDiffs; } + private: void parse(const QString &); - QMap fileDiffs; + FileDiffs fileDiffs; }; #endif