Commit 746bea8e authored by Christian Kamm's avatar Christian Kamm
Browse files

Make flip in ChangeSet move two different-length strings around.

Instead of just flipping same-length strings.
Also fix an incorrect replace position adjustment.
parent 36913baf
...@@ -70,12 +70,12 @@ bool ChangeSet::hasOverlap(int pos, int length) ...@@ -70,12 +70,12 @@ bool ChangeSet::hasOverlap(int pos, int length)
switch (cmd.type) { switch (cmd.type) {
case EditOp::Replace: case EditOp::Replace:
if (overlaps(pos, length, cmd.pos1, cmd.length)) if (overlaps(pos, length, cmd.pos1, cmd.length1))
return true; return true;
break; break;
case EditOp::Move: case EditOp::Move:
if (overlaps(pos, length, cmd.pos1, cmd.length)) if (overlaps(pos, length, cmd.pos1, cmd.length1))
return true; return true;
if (cmd.pos2 > pos && cmd.pos2 < pos + length) if (cmd.pos2 > pos && cmd.pos2 < pos + length)
return true; return true;
...@@ -87,19 +87,19 @@ bool ChangeSet::hasOverlap(int pos, int length) ...@@ -87,19 +87,19 @@ bool ChangeSet::hasOverlap(int pos, int length)
break; break;
case EditOp::Remove: case EditOp::Remove:
if (overlaps(pos, length, cmd.pos1, cmd.length)) if (overlaps(pos, length, cmd.pos1, cmd.length1))
return true; return true;
break; break;
case EditOp::Flip: case EditOp::Flip:
if (overlaps(pos, length, cmd.pos1, cmd.length)) if (overlaps(pos, length, cmd.pos1, cmd.length1))
return true; return true;
if (overlaps(pos, length, cmd.pos2, cmd.length)) if (overlaps(pos, length, cmd.pos2, cmd.length2))
return true; return true;
break; break;
case EditOp::Copy: case EditOp::Copy:
if (overlaps(pos, length, cmd.pos1, cmd.length)) if (overlaps(pos, length, cmd.pos1, cmd.length1))
return true; return true;
if (cmd.pos2 > pos && cmd.pos2 < pos + length) if (cmd.pos2 > pos && cmd.pos2 < pos + length)
return true; return true;
...@@ -138,7 +138,7 @@ bool ChangeSet::replace(int pos, int length, const QString &replacement) ...@@ -138,7 +138,7 @@ bool ChangeSet::replace(int pos, int length, const QString &replacement)
EditOp cmd(EditOp::Replace); EditOp cmd(EditOp::Replace);
cmd.pos1 = pos; cmd.pos1 = pos;
cmd.length = length; cmd.length1 = length;
cmd.text = replacement; cmd.text = replacement;
m_operationList += cmd; m_operationList += cmd;
...@@ -154,7 +154,7 @@ bool ChangeSet::move(int pos, int length, int to) ...@@ -154,7 +154,7 @@ bool ChangeSet::move(int pos, int length, int to)
EditOp cmd(EditOp::Move); EditOp cmd(EditOp::Move);
cmd.pos1 = pos; cmd.pos1 = pos;
cmd.length = length; cmd.length1 = length;
cmd.pos2 = to; cmd.pos2 = to;
m_operationList += cmd; m_operationList += cmd;
...@@ -181,23 +181,24 @@ bool ChangeSet::remove(int pos, int length) ...@@ -181,23 +181,24 @@ bool ChangeSet::remove(int pos, int length)
EditOp cmd(EditOp::Remove); EditOp cmd(EditOp::Remove);
cmd.pos1 = pos; cmd.pos1 = pos;
cmd.length = length; cmd.length1 = length;
m_operationList += cmd; m_operationList += cmd;
return !m_error; return !m_error;
} }
bool ChangeSet::flip(int pos1, int length, int pos2) bool ChangeSet::flip(int pos1, int length1, int pos2, int length2)
{ {
if (hasOverlap(pos1, length) if (hasOverlap(pos1, length1)
|| hasOverlap(pos2, length) || hasOverlap(pos2, length2)
|| overlaps(pos1, length, pos2, length)) || overlaps(pos1, length1, pos2, length2))
m_error = true; m_error = true;
EditOp cmd(EditOp::Flip); EditOp cmd(EditOp::Flip);
cmd.pos1 = pos1; cmd.pos1 = pos1;
cmd.length = length; cmd.length1 = length1;
cmd.pos2 = pos2; cmd.pos2 = pos2;
cmd.length2 = length2;
m_operationList += cmd; m_operationList += cmd;
return !m_error; return !m_error;
...@@ -212,7 +213,7 @@ bool ChangeSet::copy(int pos, int length, int to) ...@@ -212,7 +213,7 @@ bool ChangeSet::copy(int pos, int length, int to)
EditOp cmd(EditOp::Copy); EditOp cmd(EditOp::Copy);
cmd.pos1 = pos; cmd.pos1 = pos;
cmd.length = length; cmd.length1 = length;
cmd.pos2 = to; cmd.pos2 = to;
m_operationList += cmd; m_operationList += cmd;
...@@ -223,21 +224,22 @@ void ChangeSet::doReplace(const EditOp &replace, QList<EditOp> *replaceList) ...@@ -223,21 +224,22 @@ void ChangeSet::doReplace(const EditOp &replace, QList<EditOp> *replaceList)
{ {
Q_ASSERT(replace.type == EditOp::Replace); Q_ASSERT(replace.type == EditOp::Replace);
int diff = replace.text.size() - replace.length;
{ {
QMutableListIterator<EditOp> i(*replaceList); QMutableListIterator<EditOp> i(*replaceList);
while (i.hasNext()) { while (i.hasNext()) {
EditOp &c = i.next(); EditOp &c = i.next();
if (replace.pos1 <= c.pos1) if (replace.pos1 <= c.pos1)
c.pos1 += diff; c.pos1 += replace.text.size();
if (replace.pos1 < c.pos1)
c.pos1 -= replace.length1;
} }
} }
if (m_string) { if (m_string) {
m_string->replace(replace.pos1, replace.length, replace.text); m_string->replace(replace.pos1, replace.length1, replace.text);
} else if (m_cursor) { } else if (m_cursor) {
m_cursor->setPosition(replace.pos1); m_cursor->setPosition(replace.pos1);
m_cursor->setPosition(replace.pos1 + replace.length, QTextCursor::KeepAnchor); m_cursor->setPosition(replace.pos1 + replace.length1, QTextCursor::KeepAnchor);
m_cursor->insertText(replace.text); m_cursor->insertText(replace.text);
} }
} }
...@@ -254,11 +256,11 @@ void ChangeSet::convertToReplace(const EditOp &op, QList<EditOp> *replaceList) ...@@ -254,11 +256,11 @@ void ChangeSet::convertToReplace(const EditOp &op, QList<EditOp> *replaceList)
case EditOp::Move: case EditOp::Move:
replace1.pos1 = op.pos1; replace1.pos1 = op.pos1;
replace1.length = op.length; replace1.length1 = op.length1;
replaceList->append(replace1); replaceList->append(replace1);
replace2.pos1 = op.pos2; replace2.pos1 = op.pos2;
replace2.text = textAt(op.pos1, op.length); replace2.text = textAt(op.pos1, op.length1);
replaceList->append(replace2); replaceList->append(replace2);
break; break;
...@@ -270,25 +272,25 @@ void ChangeSet::convertToReplace(const EditOp &op, QList<EditOp> *replaceList) ...@@ -270,25 +272,25 @@ void ChangeSet::convertToReplace(const EditOp &op, QList<EditOp> *replaceList)
case EditOp::Remove: case EditOp::Remove:
replace1.pos1 = op.pos1; replace1.pos1 = op.pos1;
replace1.length = op.length; replace1.length1 = op.length1;
replaceList->append(replace1); replaceList->append(replace1);
break; break;
case EditOp::Flip: case EditOp::Flip:
replace1.pos1 = op.pos1; replace1.pos1 = op.pos1;
replace1.length = op.length; replace1.length1 = op.length1;
replace1.text = textAt(op.pos2, op.length); replace1.text = textAt(op.pos2, op.length2);
replaceList->append(replace1); replaceList->append(replace1);
replace2.pos1 = op.pos2; replace2.pos1 = op.pos2;
replace2.length = op.length; replace2.length1 = op.length2;
replace2.text = textAt(op.pos1, op.length); replace2.text = textAt(op.pos1, op.length1);
replaceList->append(replace2); replaceList->append(replace2);
break; break;
case EditOp::Copy: case EditOp::Copy:
replace1.pos1 = op.pos2; replace1.pos1 = op.pos2;
replace1.text = textAt(op.pos1, op.length); replace1.text = textAt(op.pos1, op.length1);
replaceList->append(replace1); replaceList->append(replace1);
break; break;
......
...@@ -66,13 +66,14 @@ public: ...@@ -66,13 +66,14 @@ public:
Copy Copy
}; };
EditOp(): type(Unset), pos1(0), pos2(0), length(0) {} EditOp(): type(Unset), pos1(0), pos2(0), length1(0), length2(0) {}
EditOp(Type t): type(t), pos1(0), pos2(0), length(0) {} EditOp(Type t): type(t), pos1(0), pos2(0), length1(0), length2(0) {}
Type type; Type type;
int pos1; int pos1;
int pos2; int pos2;
int length; int length1;
int length2;
QString text; QString text;
}; };
...@@ -89,7 +90,7 @@ public: ...@@ -89,7 +90,7 @@ public:
bool move(int pos, int length, int to); bool move(int pos, int length, int to);
bool insert(int pos, const QString &text); bool insert(int pos, const QString &text);
bool remove(int pos, int length); bool remove(int pos, int length);
bool flip(int pos1, int length, int pos2); bool flip(int pos1, int length1, int pos2, int length2);
bool copy(int pos, int length, int to); bool copy(int pos, int length, int to);
bool hadErrors(); bool hadErrors();
......
...@@ -204,60 +204,74 @@ void tst_ChangeSet::singleFlip() ...@@ -204,60 +204,74 @@ void tst_ChangeSet::singleFlip()
{ {
Utils::ChangeSet cs; Utils::ChangeSet cs;
QString test("abcdef"); QString test("abcdef");
QVERIFY(cs.flip(0, 2, 4)); QVERIFY(cs.flip(0, 2, 3, 3));
cs.apply(&test); cs.apply(&test);
QCOMPARE(test, QLatin1String("efcdab")); QCOMPARE(test, QLatin1String("defcab"));
} }
{ {
Utils::ChangeSet cs; Utils::ChangeSet cs;
QString test("abcdef"); QString test("abcdef");
QVERIFY(cs.flip(1, 2, 3)); QVERIFY(cs.flip(1, 2, 3, 1));
cs.apply(&test); cs.apply(&test);
QCOMPARE(test, QLatin1String("adebcf")); QCOMPARE(test, QLatin1String("adbcef"));
} }
{ {
Utils::ChangeSet cs; Utils::ChangeSet cs;
QString test("abcdef"); QString test("abcdef");
QVERIFY(cs.flip(3, 0, 4)); QVERIFY(cs.flip(3, 0, 4, 0));
cs.apply(&test); cs.apply(&test);
QCOMPARE(test, QLatin1String("abcdef")); QCOMPARE(test, QLatin1String("abcdef"));
} }
{ {
Utils::ChangeSet cs; Utils::ChangeSet cs;
QString test("abcdef"); QString test("abcdef");
QVERIFY(cs.flip(0, 6, 6)); QVERIFY(cs.flip(3, 0, 4, 1));
cs.apply(&test);
QCOMPARE(test, QLatin1String("abcedf"));
}
{
Utils::ChangeSet cs;
QString test("abcdef");
QVERIFY(cs.flip(0, 6, 6, 6));
cs.apply(&test); cs.apply(&test);
QCOMPARE(test, QLatin1String("abcdef")); QCOMPARE(test, QLatin1String("abcdef"));
} }
{ {
Utils::ChangeSet cs; Utils::ChangeSet cs;
QString test("abcdef"); QString test("abcdef");
QVERIFY(cs.flip(0, 6, 7)); QVERIFY(cs.flip(0, 6, 7, 3));
cs.apply(&test); cs.apply(&test);
// ### maybe this should expand the string or error? // ### maybe this should expand the string or error?
QCOMPARE(test, QLatin1String("")); QCOMPARE(test, QLatin1String(""));
} }
{ {
Utils::ChangeSet cs; Utils::ChangeSet cs;
QCOMPARE(cs.flip(0, 3, 1), false); QCOMPARE(cs.flip(0, 3, 1, 3), false);
} }
{ {
Utils::ChangeSet cs; Utils::ChangeSet cs;
QCOMPARE(cs.flip(0, 3, 2), false); QCOMPARE(cs.flip(0, 3, 2, 3), false);
} }
{ {
Utils::ChangeSet cs; Utils::ChangeSet cs;
QVERIFY(cs.flip(3, 3, 0)); QVERIFY(cs.flip(0, 3, 0, 0));
QString test("abcdef"); QString test("abcdef");
cs.apply(&test); cs.apply(&test);
QCOMPARE(test, QLatin1String("defabc")); QCOMPARE(test, QLatin1String("abcdef"));
} }
{ {
Utils::ChangeSet cs; Utils::ChangeSet cs;
QVERIFY(cs.flip(0, 3, 3)); QVERIFY(cs.flip(0, 0, 0, 3));
QString test("abcdef"); QString test("abcdef");
cs.apply(&test); cs.apply(&test);
QCOMPARE(test, QLatin1String("defabc")); QCOMPARE(test, QLatin1String("abcdef"));
}
{
Utils::ChangeSet cs;
QVERIFY(cs.flip(0, 3, 3, 0));
QString test("abcdef");
cs.apply(&test);
QCOMPARE(test, QLatin1String("abcdef"));
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment