[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdelibs/kate/buffer
From:       Christoph Cullmann <cullmann () kde ! org>
Date:       2010-04-24 19:56:32
Message-ID: 20100424195632.D3357AC8A3 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1118458 by cullmann:

cursor and range transformations

 M  +10 -5     katetextblock.cpp  
 M  +200 -31   katetexthistory.cpp  
 M  +33 -7     katetexthistory.h  
 M  +0 -6      katetextrange.cpp  
 M  +1 -1      katetextrange.h  


--- trunk/KDE/kdelibs/kate/buffer/katetextblock.cpp #1118457:1118458
@@ -159,11 +159,6 @@
 
 void TextBlock::unwrapLine (int line, TextBlock *previousBlock)
 {
-  /**
-   * notify the text history in advance
-   */
-  m_buffer->history().unwrapLine (line);
-
   // calc internal line
   line = line - startLine ();
 
@@ -187,6 +182,11 @@
     --m_startLine;
 
     /**
+     * notify the text history in advance
+     */
+    m_buffer->history().unwrapLine (startLine () + line, oldSizeOfPreviousLine);
+
+    /**
      * cursor and range handling below
      */
 
@@ -253,6 +253,11 @@
   m_lines.erase (m_lines.begin () + line);
 
   /**
+   * notify the text history in advance
+   */
+  m_buffer->history().unwrapLine (startLine () + line, oldSizeOfPreviousLine);
+
+  /**
    * cursor and range handling below
    */
 
--- trunk/KDE/kdelibs/kate/buffer/katetexthistory.cpp #1118457:1118458
@@ -36,7 +36,7 @@
 {
 }
 
-qint64 TextHistory::currentRevision () const
+qint64 TextHistory::revision () const
 {
   // just output last revisions of buffer
   return m_buffer.revision ();
@@ -58,7 +58,7 @@
 void TextHistory::setLastSavedRevision ()
 {
   // current revision was succesful saved
-  m_lastSavedRevision = currentRevision ();
+  m_lastSavedRevision = revision ();
 }
 
 void TextHistory::wrapLine (const KTextEditor::Cursor &position)
@@ -71,12 +71,14 @@
   addEntry (entry);
 }
 
-void TextHistory::unwrapLine (int line)
+void TextHistory::unwrapLine (int line, int oldLineLength)
 {
   // create and add new entry
   Entry entry;
   entry.type = Entry::UnwrapLine;
   entry.line = line;
+  entry.column = 0;
+  entry.oldLineLength = oldLineLength;
   addEntry (entry);
 }
 
@@ -118,7 +120,7 @@
     /**
      * remember new revision for first element, it is the revision we get after this \
                change
      */
-    m_firstHistoryEntryRevision = currentRevision () + 1;
+    m_firstHistoryEntryRevision = revision () + 1;
 
     /**
      * remember edit
@@ -137,51 +139,36 @@
   m_historyEntries.push_back (entry);
 }
 
-bool TextHistory::lockRevision (qint64 revision)
+void TextHistory::lockRevision (qint64 revision)
 {
   /**
-   * history should never be empty
+   * some invariants must hold
    */
   Q_ASSERT (!m_historyEntries.empty ());
+  Q_ASSERT (revision >= m_firstHistoryEntryRevision);
+  Q_ASSERT (revision < (m_firstHistoryEntryRevision + m_historyEntries.size()));
 
   /**
-   * is this revision valid at all?
-   */
-  if (revision < m_firstHistoryEntryRevision || revision >= \
                (m_firstHistoryEntryRevision + m_historyEntries.size()))
-    return false;
-
-  /**
    * increment revision reference counter
    */
   Entry &entry = m_historyEntries[revision - m_firstHistoryEntryRevision];
   ++entry.referenceCounter;
-
-  /**
-   * be done
-   */
-  return true;
 }
 
-bool TextHistory::releaseRevision (qint64 revision)
+void TextHistory::unlockRevision (qint64 revision)
 {
-
   /**
-   * history should never be empty
+   * some invariants must hold
    */
   Q_ASSERT (!m_historyEntries.empty ());
+  Q_ASSERT (revision >= m_firstHistoryEntryRevision);
+  Q_ASSERT (revision < (m_firstHistoryEntryRevision + m_historyEntries.size()));
 
   /**
-   * is this revision valid at all?
+   * decrement revision reference counter
    */
-  if (revision < m_firstHistoryEntryRevision || revision >= \
                (m_firstHistoryEntryRevision + m_historyEntries.size()))
-    return false;
-
-  /**
-   * decrement revision reference counter, if possible
-   */
   Entry &entry = m_historyEntries[revision - m_firstHistoryEntryRevision];
-  if (!entry.referenceCounter)
-    return false;
+  Q_ASSERT (entry.referenceCounter);
   --entry.referenceCounter;
 
   /**
@@ -211,11 +198,193 @@
       m_firstHistoryEntryRevision += unreferencedEdits;
     }
   }
+}
 
+void TextHistory::Entry::transformCursor (KTextEditor::Cursor &cursor, bool \
moveOnInsert) const +{
   /**
-   * be done
+   * simple stuff, sort out generic things
    */
-  return true;
+
+  /**
+   * no change, if this change is in line behind cursor
+   */
+  if (line > cursor.line ())
+    return;
+
+  /**
+   * handle all history types
+   */
+  switch (type) {
+    /**
+     * Wrap a line
+     */
+    case WrapLine:
+      /**
+       * we wrap this line
+       */
+      if (cursor.line() == line) {
+        /**
+         * skip cursors with too small column
+         */
+        if (cursor.column() <= column) {
+          if (cursor.column() < column || !moveOnInsert)
+            return;
+        }
+
+        /**
+         * adjust column
+         */
+        cursor.setColumn (cursor.column() - column);
+      }
+
+      /**
+       * always increment cursor line
+       */
+      cursor.setLine (cursor.line() + 1);
+      return;
+
+    /**
+     * Unwrap a line
+     */
+    case UnwrapLine:
+      /**
+       * we unwrap this line, adjust column
+       */
+      if (cursor.line() == line)
+        cursor.setColumn (cursor.column() + oldLineLength);
+
+      /**
+       * decrease cursor line
+       */
+      cursor.setLine (cursor.line() - 1);
+      return;
+
+    /**
+     * Insert text
+     */
+    case InsertText:
+      /**
+       * only interesting, if same line
+       */
+      if (cursor.line() != line)
+        return;
+
+      // skip cursors with too small column
+      if (cursor.column() <= column)
+        if (cursor.column() < column || !moveOnInsert)
+          return;
+
+      // patch column of cursor
+      if (cursor.column() <= oldLineLength)
+        cursor.setColumn (cursor.column () + length);
+
+      // special handling if cursor behind the real line, e.g. non-wrapping cursor \
in block selection mode +      else if (cursor.column() < (oldLineLength + length))
+        cursor.setColumn (oldLineLength + length);
+
+      return;
+
+    /**
+     * Remove text
+     */
+    case RemoveText:
+      /**
+       * only interesting, if same line
+       */
+      if (cursor.line() != line)
+        return;
+
+      // skip cursors with too small column
+      if (cursor.column() <= column)
+          return;
+
+      // patch column of cursor
+      if (cursor.column() <= (column + length))
+        cursor.setColumn (column);
+      else
+        cursor.setColumn (cursor.column () - length);
+
+      return;
+
+    /**
+     * nothing
+     */
+    default:
+      return;
+  }
 }
 
+void TextHistory::transformCursor (KTextEditor::Cursor &cursor, \
KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 \
toRevision) +{
+  /**
+   * -1 special meaning for toRevision
+   */
+  if (toRevision == -1)
+    toRevision = revision ();
+
+  /**
+   * shortcut, same revision
+   */
+  if (fromRevision == toRevision)
+    return;
+
+  /**
+   * some invariants must hold
+   */
+  Q_ASSERT (!m_historyEntries.empty ());
+  Q_ASSERT (fromRevision < toRevision);
+  Q_ASSERT (fromRevision >= m_firstHistoryEntryRevision);
+  Q_ASSERT (fromRevision < (m_firstHistoryEntryRevision + m_historyEntries.size()));
+  Q_ASSERT (toRevision >= m_firstHistoryEntryRevision);
+  Q_ASSERT (toRevision < (m_firstHistoryEntryRevision + m_historyEntries.size()));
+
+  /**
+   * transform cursor
+   */
+  bool moveOnInsert = insertBehavior == KTextEditor::MovingCursor::MoveOnInsert;
+  for (int rev = fromRevision - m_firstHistoryEntryRevision + 1; rev <= (toRevision \
- m_firstHistoryEntryRevision); ++rev) { +    const Entry &entry = \
m_historyEntries[rev]; +    entry.transformCursor (cursor, moveOnInsert);
+  }
 }
+
+void TextHistory::transformRange (KTextEditor::Range &range, \
KTextEditor::MovingRange::InsertBehaviors insertBehaviors, qint64 fromRevision, \
qint64 toRevision) +{
+  /**
+   * -1 special meaning for toRevision
+   */
+  if (toRevision == -1)
+    toRevision = revision ();
+
+  /**
+   * shortcut, same revision
+   */
+  if (fromRevision == toRevision)
+    return;
+
+  /**
+   * some invariants must hold
+   */
+  Q_ASSERT (!m_historyEntries.empty ());
+  Q_ASSERT (fromRevision < toRevision);
+  Q_ASSERT (fromRevision >= m_firstHistoryEntryRevision);
+  Q_ASSERT (fromRevision < (m_firstHistoryEntryRevision + m_historyEntries.size()));
+  Q_ASSERT (toRevision >= m_firstHistoryEntryRevision);
+  Q_ASSERT (toRevision < (m_firstHistoryEntryRevision + m_historyEntries.size()));
+
+  /**
+   * transform cursors
+   */
+  KTextEditor::Cursor &start = range.start ();
+  KTextEditor::Cursor &end = range.end ();
+  bool moveOnInsertStart = !(insertBehaviors & \
KTextEditor::MovingRange::ExpandLeft); +  bool moveOnInsertEnd = (insertBehaviors & \
KTextEditor::MovingRange::ExpandRight); +  for (int rev = fromRevision - \
m_firstHistoryEntryRevision + 1; rev <= (toRevision - m_firstHistoryEntryRevision); \
++rev) { +    const Entry &entry = m_historyEntries[rev];
+    entry.transformCursor (start, moveOnInsertStart);
+    entry.transformCursor (end, moveOnInsertEnd);
+  }
+}
+
+}
--- trunk/KDE/kdelibs/kate/buffer/katetexthistory.h #1118457:1118458
@@ -26,6 +26,8 @@
 #include <ktexteditor/range.h>
 
 #include "katepartprivate_export.h"
+#include "katetextcursor.h"
+#include "katetextrange.h"
 
 namespace Kate {
 
@@ -43,7 +45,7 @@
      * Current revision, just relay the revision of the buffer
      * @return current revision
      */
-    qint64 currentRevision () const;
+    qint64 revision () const;
 
     /**
      * Last revision the buffer got successful saved
@@ -55,17 +57,33 @@
      * Lock a revision, this will keep it around until released again.
      * But all revisions will always be cleared on buffer clear() (and therefor \
                load())
      * @param revision revision to lock
-     * @return sucess of the operation, might fail, if revision is invalid
      */
-    bool lockRevision (qint64 revision);
+    void lockRevision (qint64 revision);
 
     /**
      * Release a revision.
      * @param revision revision to release
-     * @return sucess of the operation, might fail, if revision is invalid or was \
                not locked before
      */
-    bool releaseRevision (qint64 revision);
+    void unlockRevision (qint64 revision);
 
+    /**
+     * Transform a cursor from one revision to an other.
+     * @param cursor cursor to transform
+     * @param insertBehavior behavior of this cursor on insert of text at it's \
position +     * @param fromRevision from this revision we want to transform
+     * @param toRevision to this revision we want to transform, default of -1 is \
current revision +     */
+    void transformCursor (KTextEditor::Cursor &cursor, \
KTextEditor::MovingCursor::InsertBehavior insertBehavior, qint64 fromRevision, qint64 \
toRevision = -1); +
+    /**
+     * Transform a range from one revision to an other.
+     * @param range range to transform
+     * @param insertBehaviors behavior of this range on insert of text at it's \
position +     * @param fromRevision from this revision we want to transform
+     * @param toRevision to this revision we want to transform, default of -1 is \
current revision +     */
+    void transformRange (KTextEditor::Range &range, \
KTextEditor::MovingRange::InsertBehaviors insertBehaviors, qint64 fromRevision, \
qint64 toRevision = -1); +
   private:
     /**
      * Class representing one entry in the editing history.
@@ -73,6 +91,13 @@
     class Entry {
       public:
         /**
+         * transform cursor for this history entry
+         * @param cursor cursor to transform
+         * @param moveOnInsert behavior of this cursor on insert of text at it's \
position +         */
+        void transformCursor (KTextEditor::Cursor &cursor, bool moveOnInsert) const;
+
+        /**
          * Types of entries, matching editing primitives of buffer and placeholder
          */
         enum Type {
@@ -117,7 +142,7 @@
         int length;
 
         /**
-         * old line length (needed for insert)
+         * old line length (needed for unwrap and insert)
          */
         int oldLineLength;
     };
@@ -152,8 +177,9 @@
     /**
      * Notify about unwrap given line.
      * @param line line to unwrap
+     * @param oldLineLength text length of the line in front of this one before this \
                unwrap
      */
-    void unwrapLine (int line);
+    void unwrapLine (int line, int oldLineLength);
 
     /**
      * Notify about insert text at given cursor position.
--- trunk/KDE/kdelibs/kate/buffer/katetextrange.cpp #1118457:1118458
@@ -232,12 +232,6 @@
 void TextRange::setAttribute ( KTextEditor::Attribute::Ptr attribute )
 {
   /**
-   * nothing changes, nop
-   */
-  if (attribute == m_attribute)
-    return;
-
-  /**
    * remember the new attribute
    */
   m_attribute = attribute;
--- trunk/KDE/kdelibs/kate/buffer/katetextrange.h #1118457:1118458
@@ -162,7 +162,7 @@
 
     /**
      * Sets the currently active attribute for this range.
-     * This will trigger update of the relevant view parts, if the attribute \
changed. +     * This will trigger update of the relevant view parts.
      *
      * \param attribute Attribute to assign to this range. If null, simply
      *                  removes the previous Attribute.


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic