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