00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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:
00041 KateUndo (KateUndoGroup::UndoType type, uint line, uint col, uint len, const QString &text);
00042
00046 ~KateUndo ();
00047
00048 public:
00055 bool isValid();
00056
00063 bool merge(KateUndo* u);
00064
00069 void undo (KateDocument *doc);
00070
00075 void redo (KateDocument *doc);
00076
00080 KateTextCursor cursorBefore() const;
00081
00085 KateTextCursor cursorAfter() const;
00086
00091 inline KateUndoGroup::UndoType type() const { return m_type; }
00092
00097 inline uint line () const { return m_line; }
00098
00103 inline uint col () const { return m_col; }
00104
00109 inline uint len() const { return m_len; }
00110
00115 inline const QString& text() const { return m_text; };
00116
00117 private:
00121 KateUndoGroup::UndoType m_type;
00122
00126 uint m_line;
00127
00131 uint m_col;
00132
00136 uint m_len;
00137
00141 QString m_text;
00142 };
00143
00144 KateUndo::KateUndo (KateUndoGroup::UndoType type, uint line, uint col, uint len, const QString &text)
00145 : m_type (type),
00146 m_line (line),
00147 m_col (col),
00148 m_len (len),
00149 m_text (text)
00150 {
00151 }
00152
00153 KateUndo::~KateUndo ()
00154 {
00155 }
00156
00157 bool KateUndo::isValid()
00158 {
00159 if (m_type == KateUndoGroup::editInsertText || m_type == KateUndoGroup::editRemoveText)
00160 if (len() == 0)
00161 return false;
00162
00163 return true;
00164 }
00165
00166 bool KateUndo::merge(KateUndo* u)
00167 {
00168 if (m_type != u->type())
00169 return false;
00170
00171 if (m_type == KateUndoGroup::editInsertText
00172 && m_line == u->line()
00173 && (m_col + m_len) == u->col())
00174 {
00175 m_text += u->text();
00176 m_len += u->len();
00177 return true;
00178 }
00179 else if (m_type == KateUndoGroup::editRemoveText
00180 && m_line == u->line()
00181 && m_col == (u->col() + u->len()))
00182 {
00183 m_text.prepend(u->text());
00184 m_col = u->col();
00185 m_len += u->len();
00186 return true;
00187 }
00188
00189 return false;
00190 }
00191
00192 void KateUndo::undo (KateDocument *doc)
00193 {
00194 if (m_type == KateUndoGroup::editInsertText)
00195 {
00196 doc->editRemoveText (m_line, m_col, m_len);
00197 }
00198 else if (m_type == KateUndoGroup::editRemoveText)
00199 {
00200 doc->editInsertText (m_line, m_col, m_text);
00201 }
00202 else if (m_type == KateUndoGroup::editWrapLine)
00203 {
00204 doc->editUnWrapLine (m_line, (m_text == "1"), m_len);
00205 }
00206 else if (m_type == KateUndoGroup::editUnWrapLine)
00207 {
00208 doc->editWrapLine (m_line, m_col, (m_text == "1"));
00209 }
00210 else if (m_type == KateUndoGroup::editInsertLine)
00211 {
00212 doc->editRemoveLine (m_line);
00213 }
00214 else if (m_type == KateUndoGroup::editRemoveLine)
00215 {
00216 doc->editInsertLine (m_line, m_text);
00217 }
00218 else if (m_type == KateUndoGroup::editMarkLineAutoWrapped)
00219 {
00220 doc->editMarkLineAutoWrapped (m_line, m_col == 0);
00221 }
00222 }
00223
00224 void KateUndo::redo (KateDocument *doc)
00225 {
00226 if (m_type == KateUndoGroup::editRemoveText)
00227 {
00228 doc->editRemoveText (m_line, m_col, m_len);
00229 }
00230 else if (m_type == KateUndoGroup::editInsertText)
00231 {
00232 doc->editInsertText (m_line, m_col, m_text);
00233 }
00234 else if (m_type == KateUndoGroup::editUnWrapLine)
00235 {
00236 doc->editUnWrapLine (m_line, (m_text == "1"), m_len);
00237 }
00238 else if (m_type == KateUndoGroup::editWrapLine)
00239 {
00240 doc->editWrapLine (m_line, m_col, (m_text == "1"));
00241 }
00242 else if (m_type == KateUndoGroup::editRemoveLine)
00243 {
00244 doc->editRemoveLine (m_line);
00245 }
00246 else if (m_type == KateUndoGroup::editInsertLine)
00247 {
00248 doc->editInsertLine (m_line, m_text);
00249 }
00250 else if (m_type == KateUndoGroup::editMarkLineAutoWrapped)
00251 {
00252 doc->editMarkLineAutoWrapped (m_line, m_col == 1);
00253 }
00254 }
00255
00256 KateTextCursor KateUndo::cursorBefore() const
00257 {
00258 if (m_type == KateUndoGroup::editInsertLine || m_type == KateUndoGroup::editUnWrapLine)
00259 return KateTextCursor(m_line+1, m_col);
00260 else if (m_type == KateUndoGroup::editRemoveText)
00261 return KateTextCursor(m_line, m_col+m_len);
00262
00263 return KateTextCursor(m_line, m_col);
00264 }
00265
00266 KateTextCursor KateUndo::cursorAfter() const
00267 {
00268 if (m_type == KateUndoGroup::editRemoveLine || m_type == KateUndoGroup::editWrapLine)
00269 return KateTextCursor(m_line+1, m_col);
00270 else if (m_type == KateUndoGroup::editInsertText)
00271 return KateTextCursor(m_line, m_col+m_len);
00272
00273 return KateTextCursor(m_line, m_col);
00274 }
00275
00276 KateUndoGroup::KateUndoGroup (KateDocument *doc)
00277 : m_doc (doc),m_safePoint(false)
00278 {
00279 m_items.setAutoDelete (true);
00280 }
00281
00282 KateUndoGroup::~KateUndoGroup ()
00283 {
00284 }
00285
00286 void KateUndoGroup::undo ()
00287 {
00288 if (m_items.count() == 0)
00289 return;
00290
00291 m_doc->editStart (false);
00292
00293 for (KateUndo* u = m_items.last(); u; u = m_items.prev())
00294 u->undo(m_doc);
00295
00296 if (m_doc->activeView())
00297 {
00298 for (uint z=0; z < m_items.count(); z++)
00299 if (m_items.at(z)->type() != KateUndoGroup::editMarkLineAutoWrapped)
00300 {
00301 m_doc->activeView()->editSetCursor (m_items.at(z)->cursorBefore());
00302 break;
00303 }
00304 }
00305
00306 m_doc->editEnd ();
00307 }
00308
00309 void KateUndoGroup::redo ()
00310 {
00311 if (m_items.count() == 0)
00312 return;
00313
00314 m_doc->editStart (false);
00315
00316 for (KateUndo* u = m_items.first(); u; u = m_items.next())
00317 u->redo(m_doc);
00318
00319 if (m_doc->activeView())
00320 {
00321 for (uint z=0; z < m_items.count(); z++)
00322 if (m_items.at(z)->type() != KateUndoGroup::editMarkLineAutoWrapped)
00323 {
00324 m_doc->activeView()->editSetCursor (m_items.at(z)->cursorAfter());
00325 break;
00326 }
00327 }
00328
00329 m_doc->editEnd ();
00330 }
00331
00332 void KateUndoGroup::addItem (KateUndoGroup::UndoType type, uint line, uint col, uint len, const QString &text)
00333 {
00334 addItem(new KateUndo(type, line, col, len, text));
00335 }
00336
00337 void KateUndoGroup::addItem(KateUndo* u)
00338 {
00339 if (!u->isValid())
00340 delete u;
00341 else if (m_items.last() && m_items.last()->merge(u))
00342 delete u;
00343 else
00344 m_items.append(u);
00345 }
00346
00347 bool KateUndoGroup::merge(KateUndoGroup* newGroup,bool complex)
00348 {
00349 if (m_safePoint) return false;
00350 if (newGroup->isOnlyType(singleType()) || complex) {
00351
00352 KateUndo* u = newGroup->m_items.take(0);
00353 while (u) {
00354 addItem(u);
00355 u = newGroup->m_items.take(0);
00356 }
00357 if (newGroup->m_safePoint) safePoint();
00358 return true;
00359 }
00360 return false;
00361 }
00362
00363 void KateUndoGroup::safePoint (bool safePoint) {
00364 m_safePoint=safePoint;
00365 }
00366
00367 KateUndoGroup::UndoType KateUndoGroup::singleType()
00368 {
00369 KateUndoGroup::UndoType ret = editInvalid;
00370
00371 for (KateUndo* u = m_items.first(); u; u = m_items.next()) {
00372 if (ret == editInvalid)
00373 ret = u->type();
00374 else if (ret != u->type())
00375 return editInvalid;
00376 }
00377
00378 return ret;
00379 }
00380
00381 bool KateUndoGroup::isOnlyType(KateUndoGroup::UndoType type)
00382 {
00383 if (type == editInvalid) return false;
00384
00385 for (KateUndo* u = m_items.first(); u; u = m_items.next())
00386 if (u->type() != type)
00387 return false;
00388
00389 return true;
00390 }
00391
00392