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