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:
00033 KateUndo (uint type, uint line, uint col, uint len, const QString &text);
00034 ~KateUndo ();
00035
00036 public:
00037
00038
00039
00040 bool isValid();
00041
00042
00043 bool merge(KateUndo* u);
00044
00045 void undo (KateDocument *doc);
00046 void redo (KateDocument *doc);
00047
00048
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
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