KDE/kdelibs/kate
Christoph Cullmann
cullmann at kde.org
Mon Jul 12 20:05:03 UTC 2010
SVN commit 1149168 by cullmann:
try to implement reverse transform, if from > to
please test this
and backport to 4.5
CCMAIL: kwrite-devel at kde.org
CCMAIL: kdevelop-devel at barney.cs.uni-potsdam.de
M +2 -1 buffer/katetextblock.cpp
M +168 -5 buffer/katetexthistory.cpp
M +10 -1 buffer/katetexthistory.h
M +5 -0 tests/range_test.cpp
--- trunk/KDE/kdelibs/kate/buffer/katetextblock.cpp #1149167:1149168
@@ -362,6 +362,7 @@
// get text
QString &textOfLine = m_lines[line]->textReadWrite ();
+ int oldLength = textOfLine.size ();
// check if valid column
Q_ASSERT (range.start().column() >= 0);
@@ -378,7 +379,7 @@
/**
* notify the text history
*/
- m_buffer->history().removeText (range);
+ m_buffer->history().removeText (range, oldLength);
/**
* cursor and range handling below
--- trunk/KDE/kdelibs/kate/buffer/katetexthistory.cpp #1149167:1149168
@@ -94,7 +94,7 @@
addEntry (entry);
}
-void TextHistory::removeText (const KTextEditor::Range &range)
+void TextHistory::removeText (const KTextEditor::Range &range, int oldLineLength)
{
// create and add new entry
Entry entry;
@@ -102,6 +102,7 @@
entry.line = range.start().line ();
entry.column = range.start().column ();
entry.length = range.end().column() - range.start().column();
+ entry.oldLineLength = oldLineLength;
addEntry (entry);
}
@@ -315,11 +316,131 @@
}
}
+void TextHistory::Entry::reverseTransformCursor (int &cursorLine, int &cursorColumn, bool moveOnInsert) const
+{
+ /**
+ * handle all history types
+ */
+ switch (type) {
+ /**
+ * Wrap a line
+ */
+ case WrapLine:
+ /**
+ * ignore this line
+ */
+ if (cursorLine <= line)
+ return;
+
+ /**
+ * next line is unwrapped
+ */
+ if (cursorLine == line + 1) {
+ /**
+ * adjust column
+ */
+ cursorColumn = cursorColumn + column;
+ }
+
+ /**
+ * always decrement cursor line
+ */
+ cursorLine -= 1;
+ return;
+
+ /**
+ * Unwrap a line
+ */
+ case UnwrapLine:
+ /**
+ * ignore lines before unwrapped one
+ */
+ if (cursorLine < line - 1)
+ return;
+
+ /**
+ * we unwrap this line, try to adjust cursor column if needed
+ */
+ if (cursorLine == line - 1) {
+ /**
+ * skip cursors with to small columns
+ */
+ if (cursorColumn <= oldLineLength) {
+ if (cursorColumn < oldLineLength || !moveOnInsert)
+ return;
+ }
+
+ cursorColumn -= oldLineLength;
+ }
+
+ /**
+ * increase cursor line
+ */
+ cursorLine += 1;
+ return;
+
+ /**
+ * Insert text
+ */
+ case InsertText:
+ /**
+ * only interesting, if same line
+ */
+ if (cursorLine != line)
+ return;
+
+ // skip cursors with too small column
+ if (cursorColumn <= column)
+ return;
+
+ // patch column of cursor
+ if (cursorColumn - length < column)
+ cursorColumn = column;
+ else
+ cursorColumn -= length;
+
+ return;
+
+ /**
+ * Remove text
+ */
+ case RemoveText:
+ /**
+ * only interesting, if same line
+ */
+ if (cursorLine != line)
+ return;
+
+ // skip cursors with too small column
+ if (cursorColumn <= column)
+ if (cursorColumn < column || !moveOnInsert)
+ return;
+
+ // patch column of cursor
+ if (cursorColumn <= oldLineLength)
+ cursorColumn += length;
+
+ // special handling if cursor behind the real line, e.g. non-wrapping cursor in block selection mode
+ else if (cursorColumn < oldLineLength + length)
+ cursorColumn = oldLineLength + length;
+ return;
+
+ /**
+ * nothing
+ */
+ default:
+ return;
+ }
+}
+
void TextHistory::transformCursor (int& line, int& column, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision)
{
/**
- * -1 special meaning for toRevision
+ * -1 special meaning for from/toRevision
*/
+ if (fromRevision == -1)
+ fromRevision = revision ();
+
if (toRevision == -1)
toRevision = revision ();
@@ -333,7 +454,7 @@
* some invariants must hold
*/
Q_ASSERT (!m_historyEntries.empty ());
- Q_ASSERT (fromRevision < toRevision);
+ Q_ASSERT (fromRevision != toRevision);
Q_ASSERT (fromRevision >= m_firstHistoryEntryRevision);
Q_ASSERT (fromRevision < (m_firstHistoryEntryRevision + m_historyEntries.size()));
Q_ASSERT (toRevision >= m_firstHistoryEntryRevision);
@@ -343,11 +464,22 @@
* transform cursor
*/
bool moveOnInsert = insertBehavior == KTextEditor::MovingCursor::MoveOnInsert;
+
+ /**
+ * forward or reverse transform?
+ */
+ if (toRevision > fromRevision) {
for (int rev = fromRevision - m_firstHistoryEntryRevision + 1; rev <= (toRevision - m_firstHistoryEntryRevision); ++rev) {
const Entry &entry = m_historyEntries[rev];
entry.transformCursor (line, column, moveOnInsert);
}
+ } else {
+ for (int rev = fromRevision - m_firstHistoryEntryRevision; rev >= (toRevision - m_firstHistoryEntryRevision + 1); --rev) {
+ const Entry &entry = m_historyEntries[rev];
+ entry.reverseTransformCursor (line, column, moveOnInsert);
}
+ }
+}
void TextHistory::transformRange (KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors, KTextEditor::MovingRange::EmptyBehavior emptyBehavior, qint64 fromRevision, qint64 toRevision)
{
@@ -361,8 +493,11 @@
}
/**
- * -1 special meaning for toRevision
+ * -1 special meaning for from/toRevision
*/
+ if (fromRevision == -1)
+ fromRevision = revision ();
+
if (toRevision == -1)
toRevision = revision ();
@@ -376,7 +511,7 @@
* some invariants must hold
*/
Q_ASSERT (!m_historyEntries.empty ());
- Q_ASSERT (fromRevision < toRevision);
+ Q_ASSERT (fromRevision != toRevision);
Q_ASSERT (fromRevision >= m_firstHistoryEntryRevision);
Q_ASSERT (fromRevision < (m_firstHistoryEntryRevision + m_historyEntries.size()));
Q_ASSERT (toRevision >= m_firstHistoryEntryRevision);
@@ -391,6 +526,11 @@
bool moveOnInsertStart = !(insertBehaviors & KTextEditor::MovingRange::ExpandLeft);
bool moveOnInsertEnd = (insertBehaviors & KTextEditor::MovingRange::ExpandRight);
+
+ /**
+ * forward or reverse transform?
+ */
+ if (toRevision > fromRevision) {
for (int rev = fromRevision - m_firstHistoryEntryRevision + 1; rev <= (toRevision - m_firstHistoryEntryRevision); ++rev) {
const Entry &entry = m_historyEntries[rev];
@@ -412,7 +552,30 @@
}
}
}
+ } else {
+ for (int rev = fromRevision - m_firstHistoryEntryRevision ; rev >= (toRevision - m_firstHistoryEntryRevision + 1); --rev) {
+ const Entry &entry = m_historyEntries[rev];
+ entry.reverseTransformCursor (startLine, startColumn, moveOnInsertStart);
+
+ entry.reverseTransformCursor (endLine, endColumn, moveOnInsertEnd);
+
+ // got empty?
+ if(endLine < startLine || (endLine == startLine && endColumn <= startColumn))
+ {
+ if (invalidateIfEmpty) {
+ range = KTextEditor::Range::invalid();
+ return;
+ }
+ else{
+ // else normalize them
+ endLine = startLine;
+ endColumn = startColumn;
+ }
+ }
+ }
+ }
+
// now, copy cursors back
range.start().setLine(startLine);
range.start().setColumn(startColumn);
--- trunk/KDE/kdelibs/kate/buffer/katetexthistory.h #1149167:1149168
@@ -101,6 +101,14 @@
void transformCursor (int &line, int &column, bool moveOnInsert) const;
/**
+ * reverse transform cursor for this history entry
+ * @param line line number of the cursor to transform
+ * @param column column number of the cursor to transform
+ * @param moveOnInsert behavior of this cursor on insert of text at it's position
+ */
+ void reverseTransformCursor (int &line, int &column, bool moveOnInsert) const;
+
+ /**
* Types of entries, matching editing primitives of buffer and placeholder
*/
enum Type {
@@ -195,8 +203,9 @@
/**
* Notify about remove text at given range.
* @param range range of text to remove, must be on one line only.
+ * @param oldLineLength text length of the line before this remove
*/
- void removeText (const KTextEditor::Range &range);
+ void removeText (const KTextEditor::Range &range, int oldLineLength);
/**
* Generic function to add a entry to the history. Is used by the above functions for the different editing primitives.
--- trunk/KDE/kdelibs/kate/tests/range_test.cpp #1149167:1149168
@@ -143,4 +143,9 @@
KTextEditor::Range translateTest (0,0,0,0);
doc.transformRange (translateTest, KTextEditor::MovingRange::DoNotExpand, KTextEditor::MovingRange::AllowEmpty, 0);
QCOMPARE(translateTest, KTextEditor::Range(1,0,1,0));
+
+ // test translate reverse
+ KTextEditor::Range reverseTranslateTest (1,0,1,0);
+ doc.transformRange (reverseTranslateTest, KTextEditor::MovingRange::DoNotExpand, KTextEditor::MovingRange::AllowEmpty, -1, 0);
+ QCOMPARE(reverseTranslateTest, KTextEditor::Range(0,0,0,0));
}
More information about the KDevelop-devel
mailing list