kate Library API Documentation

kateundo.cpp

00001 /* This file is part of the KDE libraries
00002    Copyright (C) 2002 John Firebaugh <jfirebaugh@kde.org>
00003    Copyright (C) 2001 Christoph Cullmann <cullmann@kde.org>
00004    Copyright (C) 2001 Joseph Wenninger <jowenn@kde.org>
00005 
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License version 2 as published by the Free Software Foundation.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00018    Boston, MA 02111-1307, USA.
00019 */
00020 
00021 #include "kateundo.h"
00022 
00023 #include "katedocument.h"
00024 #include "kateview.h"
00025 #include "katecursor.h"
00026 
00030  class KateUndo
00031 {
00032   public:
00033     KateUndo (uint type, uint line, uint col, uint len, const QString &text);
00034     ~KateUndo ();
00035 
00036   public:
00037     // Invalid examples: insert / remove 0 length text
00038     // I could probably fix this in KateDocument, but it's more work there
00039     // (and probably better here too)
00040     bool isValid();
00041 
00042     // Saves a bit of memory and potentially many calls when undo/redoing.
00043     bool merge(KateUndo* u);
00044 
00045     void undo (KateDocument *doc);
00046     void redo (KateDocument *doc);
00047 
00048     // The cursor before the action took place
00049     KateTextCursor cursorBefore() const;
00050     KateTextCursor cursorAfter() const;
00051 
00052     inline uint type() const { return m_type; }
00053 
00054     inline uint line () const { return m_line; }
00055     inline uint col () const { return m_col; }
00056     inline uint len() const { return m_len; }
00057 
00058     inline const QString& text() const { return m_text; };
00059 
00060   private:
00061     uint m_type;
00062     uint m_line;
00063     uint m_col;
00064     uint m_len;
00065     QString m_text;
00066 };
00067 
00068 KateUndo::KateUndo (uint type, uint line, uint col, uint len, const QString &text)
00069 : m_type (type),
00070   m_line (line),
00071   m_col (col),
00072   m_len (len),
00073   m_text (text)
00074 {
00075 }
00076 
00077 KateUndo::~KateUndo ()
00078 {
00079 }
00080 
00081 bool KateUndo::isValid()
00082 {
00083   if (m_type == KateUndoGroup::editInsertText || m_type == KateUndoGroup::editRemoveText)
00084     if (len() == 0)
00085       return false;
00086 
00087   return true;
00088 }
00089 
00090 bool KateUndo::merge(KateUndo* u)
00091 {
00092   if (m_type != u->type())
00093     return false;
00094 
00095   if (m_type == KateUndoGroup::editInsertText
00096       && m_line == u->line()
00097       && (m_col + m_len) == u->col())
00098   {
00099     m_text += u->text();
00100     m_len += u->len();
00101     return true;
00102   }
00103   else if (m_type == KateUndoGroup::editRemoveText
00104       && m_line == u->line()
00105       && m_col == (u->col() + u->len()))
00106   {
00107     m_text.prepend(u->text());
00108     m_col = u->col();
00109     m_len += u->len();
00110     return true;
00111   }
00112 
00113   return false;
00114 }
00115 
00116 void KateUndo::undo (KateDocument *doc)
00117 {
00118   if (m_type == KateUndoGroup::editInsertText)
00119   {
00120     doc->editRemoveText (m_line, m_col, m_len);
00121   }
00122   else if (m_type == KateUndoGroup::editRemoveText)
00123   {
00124     doc->editInsertText (m_line, m_col, m_text);
00125   }
00126   else if (m_type == KateUndoGroup::editWrapLine)
00127   {
00128     doc->editUnWrapLine (m_line, (m_text == "1"), m_len);
00129   }
00130   else if (m_type == KateUndoGroup::editUnWrapLine)
00131   {
00132     doc->editWrapLine (m_line, m_col, (m_text == "1"));
00133   }
00134   else if (m_type == KateUndoGroup::editInsertLine)
00135   {
00136     doc->editRemoveLine (m_line);
00137   }
00138   else if (m_type == KateUndoGroup::editRemoveLine)
00139   {
00140     doc->editInsertLine (m_line, m_text);
00141   }
00142   else if (m_type == KateUndoGroup::editMarkLineAutoWrapped)
00143   {
00144     doc->editMarkLineAutoWrapped (m_line, m_col == 0);
00145   }
00146 }
00147 
00148 void KateUndo::redo (KateDocument *doc)
00149 {
00150   if (m_type == KateUndoGroup::editRemoveText)
00151   {
00152     doc->editRemoveText (m_line, m_col, m_len);
00153   }
00154   else if (m_type == KateUndoGroup::editInsertText)
00155   {
00156     doc->editInsertText (m_line, m_col, m_text);
00157   }
00158   else if (m_type == KateUndoGroup::editUnWrapLine)
00159   {
00160     doc->editUnWrapLine (m_line, (m_text == "1"), m_len);
00161   }
00162   else if (m_type == KateUndoGroup::editWrapLine)
00163   {
00164     doc->editWrapLine (m_line, m_col, (m_text == "1"));
00165   }
00166   else if (m_type == KateUndoGroup::editRemoveLine)
00167   {
00168     doc->editRemoveLine (m_line);
00169   }
00170   else if (m_type == KateUndoGroup::editInsertLine)
00171   {
00172     doc->editInsertLine (m_line, m_text);
00173   }
00174   else if (m_type == KateUndoGroup::editMarkLineAutoWrapped)
00175   {
00176     doc->editMarkLineAutoWrapped (m_line, m_col == 1);
00177   }
00178 }
00179 
00180 KateTextCursor KateUndo::cursorBefore() const
00181 {
00182   if (m_type == KateUndoGroup::editInsertLine || m_type == KateUndoGroup::editUnWrapLine)
00183     return KateTextCursor(m_line+1, m_col);
00184   else if (m_type == KateUndoGroup::editRemoveText)
00185     return KateTextCursor(m_line, m_col+m_len);
00186 
00187   return KateTextCursor(m_line, m_col);
00188 }
00189 
00190 KateTextCursor KateUndo::cursorAfter() const
00191 {
00192   if (m_type == KateUndoGroup::editRemoveLine || m_type == KateUndoGroup::editWrapLine)
00193     return KateTextCursor(m_line+1, m_col);
00194   else if (m_type == KateUndoGroup::editInsertText)
00195     return KateTextCursor(m_line, m_col+m_len);
00196 
00197   return KateTextCursor(m_line, m_col);
00198 }
00199 
00200 KateUndoGroup::KateUndoGroup (KateDocument *doc)
00201 : m_doc (doc)
00202 {
00203   m_items.setAutoDelete (true);
00204 }
00205 
00206 KateUndoGroup::~KateUndoGroup ()
00207 {
00208 }
00209 
00210 void KateUndoGroup::undo ()
00211 {
00212   if (m_items.count() == 0)
00213     return;
00214 
00215   m_doc->editStart (false);
00216 
00217   for (KateUndo* u = m_items.last(); u; u = m_items.prev())
00218     u->undo(m_doc);
00219 
00220   if (m_doc->activeView())
00221   {
00222     for (uint z=0; z < m_items.count(); z++)
00223       if (m_items.at(z)->type() != KateUndoGroup::editMarkLineAutoWrapped)
00224       {
00225         m_doc->activeView()->editSetCursor (m_items.at(z)->cursorBefore());
00226         break;
00227       }
00228   }
00229 
00230   m_doc->editEnd ();
00231 }
00232 
00233 void KateUndoGroup::redo ()
00234 {
00235   if (m_items.count() == 0)
00236     return;
00237 
00238   m_doc->editStart (false);
00239 
00240   for (KateUndo* u = m_items.first(); u; u = m_items.next())
00241     u->redo(m_doc);
00242 
00243   if (m_doc->activeView())
00244   {
00245     for (uint z=0; z < m_items.count(); z++)
00246       if (m_items.at(z)->type() != KateUndoGroup::editMarkLineAutoWrapped)
00247       {
00248         m_doc->activeView()->editSetCursor (m_items.at(z)->cursorAfter());
00249         break;
00250       }
00251   }
00252 
00253   m_doc->editEnd ();
00254 }
00255 
00256 void KateUndoGroup::addItem (uint type, uint line, uint col, uint len, const QString &text)
00257 {
00258   addItem(new KateUndo(type, line, col, len, text));
00259 }
00260 
00261 void KateUndoGroup::addItem(KateUndo* u)
00262 {
00263   if (!u->isValid())
00264     delete u;
00265   else if (m_items.last() && m_items.last()->merge(u))
00266     delete u;
00267   else
00268     m_items.append(u);
00269 }
00270 
00271 bool KateUndoGroup::merge(KateUndoGroup* newGroup)
00272 {
00273   if (newGroup->isOnlyType(singleType())) {
00274     // Take all of its items first -> last
00275     KateUndo* u = newGroup->m_items.take(0);
00276     while (u) {
00277       addItem(u);
00278       u = newGroup->m_items.take(0);
00279     }
00280     return true;
00281   }
00282   return false;
00283 }
00284 
00285 uint KateUndoGroup::singleType()
00286 {
00287   uint ret = editInvalid;
00288 
00289   for (KateUndo* u = m_items.first(); u; u = m_items.next()) {
00290     if (ret == editInvalid)
00291       ret = u->type();
00292     else if (ret != u->type())
00293       return editInvalid;
00294   }
00295 
00296   return ret;
00297 }
00298 
00299 bool KateUndoGroup::isOnlyType(uint type)
00300 {
00301   if (type == editInvalid) return false;
00302 
00303   for (KateUndo* u = m_items.first(); u; u = m_items.next())
00304     if (u->type() != type)
00305       return false;
00306 
00307   return true;
00308 }
00309 
00310 // kate: space-indent on; indent-width 2; replace-tabs on;
KDE Logo
This file is part of the documentation for kate Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun May 16 22:07:08 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003