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.