26 TextHistory::TextHistory (TextBuffer &buffer)
28 , m_lastSavedRevision (-1)
29 , m_firstHistoryEntryRevision (0)
35 TextHistory::~TextHistory ()
45 void TextHistory::clear ()
48 m_lastSavedRevision = -1;
51 m_historyEntries.
clear ();
55 m_firstHistoryEntryRevision = 0;
58 void TextHistory::setLastSavedRevision ()
64 void TextHistory::wrapLine (
const KTextEditor::Cursor &position)
68 entry.type = Entry::WrapLine;
69 entry.line = position.line ();
70 entry.column = position.column ();
74 void TextHistory::unwrapLine (
int line,
int oldLineLength)
78 entry.type = Entry::UnwrapLine;
81 entry.oldLineLength = oldLineLength;
85 void TextHistory::insertText (
const KTextEditor::Cursor &position,
int length,
int oldLineLength)
89 entry.type = Entry::InsertText;
90 entry.line = position.line ();
91 entry.column = position.column ();
92 entry.length = length;
93 entry.oldLineLength = oldLineLength;
97 void TextHistory::removeText (
const KTextEditor::Range &range,
int oldLineLength)
101 entry.type = Entry::RemoveText;
102 entry.line = range.start().line ();
103 entry.column = range.start().column ();
104 entry.length = range.end().column() - range.start().column();
105 entry.oldLineLength = oldLineLength;
109 void TextHistory::addEntry (
const Entry &entry)
114 Q_ASSERT (!m_historyEntries.
empty ());
120 if ((m_historyEntries.
size () == 1) && !m_historyEntries.
first().referenceCounter) {
124 m_firstHistoryEntryRevision =
revision () + 1;
129 m_historyEntries.
first() = entry;
148 Q_ASSERT (!m_historyEntries.
empty ());
149 Q_ASSERT (revision >= m_firstHistoryEntryRevision);
150 Q_ASSERT (revision < (m_firstHistoryEntryRevision + m_historyEntries.
size()));
155 Entry &entry = m_historyEntries[revision - m_firstHistoryEntryRevision];
156 ++entry.referenceCounter;
164 Q_ASSERT (!m_historyEntries.
empty ());
165 Q_ASSERT (revision >= m_firstHistoryEntryRevision);
166 Q_ASSERT (revision < (m_firstHistoryEntryRevision + m_historyEntries.
size()));
171 Entry &entry = m_historyEntries[revision - m_firstHistoryEntryRevision];
172 Q_ASSERT (entry.referenceCounter);
173 --entry.referenceCounter;
178 if (!entry.referenceCounter) {
182 int unreferencedEdits = 0;
183 for (
int i = 0; i + 1 < m_historyEntries.
size(); ++i) {
184 if (m_historyEntries.
at(i).referenceCounter)
194 if (unreferencedEdits > 0) {
196 m_historyEntries.
erase (m_historyEntries.
begin(), m_historyEntries.
begin() + unreferencedEdits);
199 m_firstHistoryEntryRevision += unreferencedEdits;
204 void TextHistory::Entry::transformCursor (
int &cursorLine,
int &cursorColumn,
bool moveOnInsert)
const
213 if (line > cursorLine)
227 if (cursorLine == line) {
231 if (cursorColumn <= column) {
232 if (cursorColumn < column || !moveOnInsert)
239 cursorColumn = cursorColumn - column;
255 if (cursorLine == line)
256 cursorColumn += oldLineLength;
271 if (cursorLine != line)
275 if (cursorColumn <= column)
276 if (cursorColumn < column || !moveOnInsert)
280 if (cursorColumn <= oldLineLength)
281 cursorColumn += length;
284 else if (cursorColumn < oldLineLength + length)
285 cursorColumn = oldLineLength + length;
296 if (cursorLine != line)
300 if (cursorColumn <= column)
304 if (cursorColumn <= column + length)
305 cursorColumn = column;
307 cursorColumn -= length;
319 void TextHistory::Entry::reverseTransformCursor (
int &cursorLine,
int &cursorColumn,
bool moveOnInsert)
const
332 if (cursorLine <= line)
338 if (cursorLine == line + 1) {
342 cursorColumn = cursorColumn + column;
358 if (cursorLine < line - 1)
364 if (cursorLine == line - 1) {
368 if (cursorColumn <= oldLineLength) {
369 if (cursorColumn < oldLineLength || !moveOnInsert)
373 cursorColumn -= oldLineLength;
389 if (cursorLine != line)
393 if (cursorColumn <= column)
397 if (cursorColumn - length < column)
398 cursorColumn = column;
400 cursorColumn -= length;
411 if (cursorLine != line)
415 if (cursorColumn <= column)
416 if (cursorColumn < column || !moveOnInsert)
420 if (cursorColumn <= oldLineLength)
421 cursorColumn += length;
424 else if (cursorColumn < oldLineLength + length)
425 cursorColumn = oldLineLength + length;
436 void TextHistory::transformCursor (
int& line,
int& column, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision)
441 if (fromRevision == -1)
444 if (toRevision == -1)
450 if (fromRevision == toRevision)
456 Q_ASSERT (!m_historyEntries.
empty ());
457 Q_ASSERT (fromRevision != toRevision);
458 Q_ASSERT (fromRevision >= m_firstHistoryEntryRevision);
459 Q_ASSERT (fromRevision < (m_firstHistoryEntryRevision + m_historyEntries.
size()));
460 Q_ASSERT (toRevision >= m_firstHistoryEntryRevision);
461 Q_ASSERT (toRevision < (m_firstHistoryEntryRevision + m_historyEntries.
size()));
466 bool moveOnInsert = insertBehavior == KTextEditor::MovingCursor::MoveOnInsert;
471 if (toRevision > fromRevision) {
472 for (
int rev = fromRevision - m_firstHistoryEntryRevision + 1; rev <= (toRevision - m_firstHistoryEntryRevision); ++rev) {
473 const Entry &entry = m_historyEntries.
at(rev);
474 entry.transformCursor (line, column, moveOnInsert);
477 for (
int rev = fromRevision - m_firstHistoryEntryRevision; rev >= (toRevision - m_firstHistoryEntryRevision + 1); --rev) {
478 const Entry &entry = m_historyEntries.
at(rev);
479 entry.reverseTransformCursor (line, column, moveOnInsert);
484 void TextHistory::transformRange (KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors, KTextEditor::MovingRange::EmptyBehavior emptyBehavior, qint64 fromRevision, qint64 toRevision)
489 bool invalidateIfEmpty = emptyBehavior == KTextEditor::MovingRange::InvalidateIfEmpty;
490 if (invalidateIfEmpty && range.end() <= range.start()) {
491 range = KTextEditor::Range::invalid();
498 if (fromRevision == -1)
501 if (toRevision == -1)
507 if (fromRevision == toRevision)
513 Q_ASSERT (!m_historyEntries.
empty ());
514 Q_ASSERT (fromRevision != toRevision);
515 Q_ASSERT (fromRevision >= m_firstHistoryEntryRevision);
516 Q_ASSERT (fromRevision < (m_firstHistoryEntryRevision + m_historyEntries.
size()));
517 Q_ASSERT (toRevision >= m_firstHistoryEntryRevision);
518 Q_ASSERT (toRevision < (m_firstHistoryEntryRevision + m_historyEntries.
size()));
525 int startLine = range.start().line(), startColumn = range.start().column(), endLine = range.end().line(), endColumn = range.end().column();
527 bool moveOnInsertStart = !(insertBehaviors & KTextEditor::MovingRange::ExpandLeft);
528 bool moveOnInsertEnd = (insertBehaviors & KTextEditor::MovingRange::ExpandRight);
533 if (toRevision > fromRevision) {
534 for (
int rev = fromRevision - m_firstHistoryEntryRevision + 1; rev <= (toRevision - m_firstHistoryEntryRevision); ++rev) {
535 const Entry &entry = m_historyEntries.
at(rev);
537 entry.transformCursor (startLine, startColumn, moveOnInsertStart);
539 entry.transformCursor (endLine, endColumn, moveOnInsertEnd);
542 if(endLine < startLine || (endLine == startLine && endColumn <= startColumn))
544 if (invalidateIfEmpty) {
545 range = KTextEditor::Range::invalid();
551 endColumn = startColumn;
556 for (
int rev = fromRevision - m_firstHistoryEntryRevision ; rev >= (toRevision - m_firstHistoryEntryRevision + 1); --rev) {
557 const Entry &entry = m_historyEntries.
at(rev);
559 entry.reverseTransformCursor (startLine, startColumn, moveOnInsertStart);
561 entry.reverseTransformCursor (endLine, endColumn, moveOnInsertEnd);
564 if(endLine < startLine || (endLine == startLine && endColumn <= startColumn))
566 if (invalidateIfEmpty) {
567 range = KTextEditor::Range::invalid();
573 endColumn = startColumn;
580 range.start().setLine(startLine);
581 range.start().setColumn(startColumn);
582 range.end().setLine(endLine);
583 range.end().setColumn(endColumn);
void clear()
Clear the complete folding.
void push_back(const T &value)
const T & at(int i) const
iterator erase(iterator pos)
void transformRange(KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors, KTextEditor::MovingRange::EmptyBehavior emptyBehavior, qint64 fromRevision, qint64 toRevision=-1)
Transform a range from one revision to an other.
void unlockRevision(qint64 revision)
Release a revision.
qint64 revision() const
Current revision, just relay the revision of the buffer.
qint64 revision() const
Revision of this buffer.
void transformCursor(int &line, int &column, KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 toRevision=-1)
Transform a cursor from one revision to an other.
void lockRevision(qint64 revision)
Lock a revision, this will keep it around until released again.