ReactOS 0.4.16-dev-1067-ge98bba2
undo.c File Reference
#include "editor.h"
Include dependency graph for undo.c:

Go to the source code of this file.

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (richedit)
 
static void destroy_undo_item (struct undo_item *undo)
 
static void empty_redo_stack (ME_TextEditor *editor)
 
void ME_EmptyUndoStack (ME_TextEditor *editor)
 
static struct undo_itemadd_undo (ME_TextEditor *editor, enum undo_type type)
 
BOOL add_undo_insert_run (ME_TextEditor *editor, int pos, const WCHAR *str, int len, int flags, ME_Style *style)
 
BOOL add_undo_set_para_fmt (ME_TextEditor *editor, const ME_Paragraph *para)
 
BOOL add_undo_set_char_fmt (ME_TextEditor *editor, int pos, int len, const CHARFORMAT2W *fmt)
 
BOOL add_undo_join_paras (ME_TextEditor *editor, int pos)
 
BOOL add_undo_split_para (ME_TextEditor *editor, const ME_Paragraph *para, ME_String *eol_str, const ME_Cell *cell)
 
BOOL add_undo_delete_run (ME_TextEditor *editor, int pos, int len)
 
void ME_CommitUndo (ME_TextEditor *editor)
 
void ME_ContinueCoalescingTransaction (ME_TextEditor *editor)
 
void ME_CommitCoalescingUndo (ME_TextEditor *editor)
 
static void ME_PlayUndoItem (ME_TextEditor *editor, struct undo_item *undo)
 
BOOL ME_Undo (ME_TextEditor *editor)
 
BOOL ME_Redo (ME_TextEditor *editor)
 

Function Documentation

◆ add_undo()

static struct undo_item * add_undo ( ME_TextEditor editor,
enum undo_type  type 
)
static

Definition at line 72 of file undo.c.

73{
74 struct undo_item *undo, *item;
75 struct list *head;
76
77 if (editor->nUndoMode == umIgnore) return NULL;
78 if (editor->nUndoLimit == 0) return NULL;
79
80 undo = heap_alloc( sizeof(*undo) );
81 if (!undo) return NULL;
82 undo->type = type;
83
84 if (editor->nUndoMode == umAddToUndo || editor->nUndoMode == umAddBackToUndo)
85 {
86
87 head = list_head( &editor->undo_stack );
88 if (head)
89 {
90 item = LIST_ENTRY( head, struct undo_item, entry );
93 }
94
95 if (editor->nUndoMode == umAddToUndo)
96 TRACE("Pushing id=%d to undo stack, deleting redo stack\n", type);
97 else
98 TRACE("Pushing id=%d to undo stack\n", type);
99
100 list_add_head( &editor->undo_stack, &undo->entry );
101
103 editor->nUndoStackSize++;
104
105 if (editor->nUndoStackSize > editor->nUndoLimit)
106 {
107 struct undo_item *cursor2;
108 /* remove oldest undo from stack */
109 LIST_FOR_EACH_ENTRY_SAFE_REV( item, cursor2, &editor->undo_stack, struct undo_item, entry )
110 {
111 BOOL done = (item->type == undo_end_transaction);
112 list_remove( &item->entry );
114 if (done) break;
115 }
116 editor->nUndoStackSize--;
117 }
118
119 /* any new operation (not redo) clears the redo stack */
120 if (editor->nUndoMode == umAddToUndo) empty_redo_stack( editor );
121 }
122 else if (editor->nUndoMode == umAddToRedo)
123 {
124 TRACE("Pushing id=%d to redo stack\n", type);
125 list_add_head( &editor->redo_stack, &undo->entry );
126 }
127
128 return undo;
129}
struct outqueuenode * head
Definition: adnsresfilter.c:66
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
Definition: list.h:37
#define NULL
Definition: types.h:112
@ umAddBackToUndo
Definition: editstr.h:283
@ umAddToUndo
Definition: editstr.h:280
@ umAddToRedo
Definition: editstr.h:281
@ umIgnore
Definition: editstr.h:282
@ undo_end_transaction
Definition: editstr.h:294
@ undo_potential_end_transaction
Definition: editstr.h:295
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
uint32_t entry
Definition: isohybrid.c:63
static ATOM item
Definition: dde.c:856
#define LIST_FOR_EACH_ENTRY_SAFE_REV(cursor, cursor2, list, type, field)
Definition: list.h:228
#define TRACE(s)
Definition: solgame.cpp:4
Definition: list.h:15
struct list redo_stack
Definition: editstr.h:405
int nUndoStackSize
Definition: editstr.h:406
ME_UndoMode nUndoMode
Definition: editstr.h:408
struct list undo_stack
Definition: editstr.h:404
struct list entry
Definition: editstr.h:342
enum undo_type type
Definition: editstr.h:343
#define LIST_ENTRY(type)
Definition: queue.h:175
static void empty_redo_stack(ME_TextEditor *editor)
Definition: undo.c:43
static void destroy_undo_item(struct undo_item *undo)
Definition: undo.c:25

Referenced by add_undo_delete_run(), add_undo_insert_run(), add_undo_join_paras(), add_undo_set_char_fmt(), add_undo_set_para_fmt(), add_undo_split_para(), ME_CommitCoalescingUndo(), ME_CommitUndo(), ME_Redo(), and ME_Undo().

◆ add_undo_delete_run()

BOOL add_undo_delete_run ( ME_TextEditor editor,
int  pos,
int  len 
)

Definition at line 204 of file undo.c.

205{
206 struct undo_item *undo = add_undo( editor, undo_delete_run );
207 if (!undo) return FALSE;
208
209 undo->u.delete_run.pos = pos;
210 undo->u.delete_run.len = len;
211
212 return TRUE;
213}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ undo_delete_run
Definition: editstr.h:289
GLenum GLsizei len
Definition: glext.h:6722
struct delete_run_item delete_run
Definition: editstr.h:347
union undo_item::@569 u
static struct undo_item * add_undo(ME_TextEditor *editor, enum undo_type type)
Definition: undo.c:72

Referenced by run_insert().

◆ add_undo_insert_run()

BOOL add_undo_insert_run ( ME_TextEditor editor,
int  pos,
const WCHAR str,
int  len,
int  flags,
ME_Style style 
)

Definition at line 131 of file undo.c.

132{
133 struct undo_item *undo = add_undo( editor, undo_insert_run );
134 if (!undo) return FALSE;
135
136 undo->u.insert_run.str = heap_alloc( (len + 1) * sizeof(WCHAR) );
137 if (!undo->u.insert_run.str)
138 {
139 ME_EmptyUndoStack( editor );
140 return FALSE;
141 }
142 memcpy( undo->u.insert_run.str, str, len * sizeof(WCHAR) );
143 undo->u.insert_run.str[len] = 0;
144 undo->u.insert_run.pos = pos;
145 undo->u.insert_run.len = len;
146 undo->u.insert_run.flags = flags;
147 undo->u.insert_run.style = style;
149 return TRUE;
150}
Arabic default style
Definition: afstyles.h:94
void ME_AddRefStyle(ME_Style *item) DECLSPEC_HIDDEN
Definition: style.c:454
@ undo_insert_run
Definition: editstr.h:288
GLbitfield flags
Definition: glext.h:7161
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
const WCHAR * str
struct insert_run_item insert_run
Definition: editstr.h:346
void ME_EmptyUndoStack(ME_TextEditor *editor)
Definition: undo.c:53
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ME_InternalDeleteText().

◆ add_undo_join_paras()

BOOL add_undo_join_paras ( ME_TextEditor editor,
int  pos 
)

Definition at line 176 of file undo.c.

177{
178 struct undo_item *undo = add_undo( editor, undo_join_paras );
179 if (!undo) return FALSE;
180
181 undo->u.join_paras.pos = pos;
182 return TRUE;
183}
@ undo_join_paras
Definition: editstr.h:290
struct join_paras_item join_paras
Definition: editstr.h:348

Referenced by para_split().

◆ add_undo_set_char_fmt()

BOOL add_undo_set_char_fmt ( ME_TextEditor editor,
int  pos,
int  len,
const CHARFORMAT2W fmt 
)

Definition at line 164 of file undo.c.

165{
166 struct undo_item *undo = add_undo( editor, undo_set_char_fmt );
167 if (!undo) return FALSE;
168
169 undo->u.set_char_fmt.pos = pos;
170 undo->u.set_char_fmt.len = len;
171 undo->u.set_char_fmt.fmt = *fmt;
172
173 return TRUE;
174}
@ undo_set_char_fmt
Definition: editstr.h:293
Definition: dsound.c:943
struct set_char_fmt_item set_char_fmt
Definition: editstr.h:351

Referenced by ME_SetCharFormat().

◆ add_undo_set_para_fmt()

BOOL add_undo_set_para_fmt ( ME_TextEditor editor,
const ME_Paragraph para 
)

Definition at line 152 of file undo.c.

153{
154 struct undo_item *undo = add_undo( editor, undo_set_para_fmt );
155 if (!undo) return FALSE;
156
157 undo->u.set_para_fmt.pos = para->nCharOfs;
158 undo->u.set_para_fmt.fmt = para->fmt;
159 undo->u.set_para_fmt.border = para->border;
160
161 return TRUE;
162}
@ undo_set_para_fmt
Definition: editstr.h:292
ME_BorderRect border
Definition: editstr.h:207
PARAFORMAT2 fmt
Definition: editstr.h:203
struct set_para_fmt_item set_para_fmt
Definition: editstr.h:350

Referenced by ME_PlayUndoItem(), para_join(), and para_set_fmt().

◆ add_undo_split_para()

BOOL add_undo_split_para ( ME_TextEditor editor,
const ME_Paragraph para,
ME_String eol_str,
const ME_Cell cell 
)

Definition at line 185 of file undo.c.

186{
187 struct undo_item *undo = add_undo( editor, undo_split_para );
188 if (!undo) return FALSE;
189
190 undo->u.split_para.pos = para->nCharOfs - eol_str->nLen;
191 undo->u.split_para.eol_str = eol_str;
192 undo->u.split_para.fmt = para->fmt;
193 undo->u.split_para.border = para->border;
194 undo->u.split_para.flags = para->prev_para->member.para.nFlags & ~MEPF_CELL;
195
196 if (cell)
197 {
198 undo->u.split_para.cell_border = cell->border;
199 undo->u.split_para.cell_right_boundary = cell->nRightBoundary;
200 }
201 return TRUE;
202}
@ undo_split_para
Definition: editstr.h:291
int nRightBoundary
Definition: editstr.h:223
ME_BorderRect border
Definition: editstr.h:224
struct tagME_DisplayItem * prev_para
Definition: editstr.h:216
int nLen
Definition: editstr.h:56
struct split_para_item split_para
Definition: editstr.h:349

Referenced by para_join().

◆ destroy_undo_item()

static void destroy_undo_item ( struct undo_item undo)
static

Definition at line 25 of file undo.c.

26{
27 switch( undo->type )
28 {
29 case undo_insert_run:
30 heap_free( undo->u.insert_run.str );
31 ME_ReleaseStyle( undo->u.insert_run.style );
32 break;
33 case undo_split_para:
34 ME_DestroyString( undo->u.split_para.eol_str );
35 break;
36 default:
37 break;
38 }
39
40 heap_free( undo );
41}
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
void ME_ReleaseStyle(ME_Style *item) DECLSPEC_HIDDEN
Definition: style.c:462
void ME_DestroyString(ME_String *s) DECLSPEC_HIDDEN
Definition: string.c:96

Referenced by add_undo(), empty_redo_stack(), ME_ContinueCoalescingTransaction(), ME_EmptyUndoStack(), ME_Redo(), and ME_Undo().

◆ empty_redo_stack()

static void empty_redo_stack ( ME_TextEditor editor)
static

Definition at line 43 of file undo.c.

44{
45 struct undo_item *cursor, *cursor2;
46 LIST_FOR_EACH_ENTRY_SAFE( cursor, cursor2, &editor->redo_stack, struct undo_item, entry )
47 {
48 list_remove( &cursor->entry );
50 }
51}
const char cursor[]
Definition: icontest.c:13
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204

Referenced by add_undo(), and ME_EmptyUndoStack().

◆ ME_CommitCoalescingUndo()

void ME_CommitCoalescingUndo ( ME_TextEditor editor)

Commits preceding changes into a undo transaction that can be expanded.

This function allows the transaction to be reopened with ME_ContinueCoalescingTransaction in order to continue the transaction. If an undo item is added to the undo stack as a result of a change without the transaction being reopened, then the transaction will be ended, and the changes will become a part of the next transaction.

This is used to allow typed characters to be grouped together since each typed character results in a single event, and each event adding undo items must be committed. Using this function as opposed to ME_CommitUndo allows multiple events to be grouped, and undone together.

Definition at line 301 of file undo.c.

302{
303 struct undo_item *item;
304 struct list *head;
305
306 if (editor->nUndoMode == umIgnore)
307 return;
308
309 assert(editor->nUndoMode == umAddToUndo);
310
311 head = list_head( &editor->undo_stack );
312 if (!head) return;
313
314 /* no need to commit empty transactions */
315 item = LIST_ENTRY( head, struct undo_item, entry );
316 if (item->type == undo_end_transaction ||
318 return;
319
321}
#define assert(x)
Definition: debug.h:53

Referenced by handle_enter(), handle_wm_char(), and ME_KeyDown().

◆ ME_CommitUndo()

void ME_CommitUndo ( ME_TextEditor editor)

Commits preceding changes into a transaction that can be undone together.

This should be called after all the changes occur associated with an event so that the group of changes can be undone atomically as a transaction.

This will have no effect the undo mode is set to ignore changes, or if no changes preceded calling this function before the last time it was called.

This can also be used to conclude a coalescing transaction (used for grouping typed characters).

Definition at line 227 of file undo.c.

228{
229 struct undo_item *item;
230 struct list *head;
231
232 if (editor->nUndoMode == umIgnore)
233 return;
234
235 assert(editor->nUndoMode == umAddToUndo);
236
237 /* no transactions, no need to commit */
238 head = list_head( &editor->undo_stack );
239 if (!head) return;
240
241 /* no need to commit empty transactions */
242 item = LIST_ENTRY( head, struct undo_item, entry );
243 if (item->type == undo_end_transaction) return;
244
246 {
248 return;
249 }
250
252}

Referenced by editor_copy_or_cut(), editor_handle_message(), handle_EM_SETCHARFORMAT(), handle_enter(), handle_wm_char(), IRichEditOle_fnInsertObject(), ME_KeyDown(), ME_ReplaceSel(), ME_StreamIn(), and paste_emf().

◆ ME_ContinueCoalescingTransaction()

void ME_ContinueCoalescingTransaction ( ME_TextEditor editor)

Groups subsequent changes with previous ones for an undo if coalescing.

Has no effect if the previous changes were followed by a ME_CommitUndo. This function will only have an affect if the previous changes were followed by a call to ME_CommitCoalescingUndo, which allows the transaction to be continued.

This allows multiple consecutively typed characters to be grouped together to be undone by a single undo operation.

Definition at line 265 of file undo.c.

266{
267 struct undo_item *item;
268 struct list *head;
269
270 if (editor->nUndoMode == umIgnore)
271 return;
272
273 assert(editor->nUndoMode == umAddToUndo);
274
275 head = list_head( &editor->undo_stack );
276 if (!head) return;
277
278 item = LIST_ENTRY( head, struct undo_item, entry );
280 {
281 list_remove( &item->entry );
282 editor->nUndoStackSize--;
284 }
285}

Referenced by handle_enter(), handle_wm_char(), and ME_KeyDown().

◆ ME_EmptyUndoStack()

void ME_EmptyUndoStack ( ME_TextEditor editor)

Definition at line 53 of file undo.c.

54{
55 struct undo_item *cursor, *cursor2;
56 if (editor->nUndoMode == umIgnore)
57 return;
58
59 TRACE("Emptying undo stack\n");
60
61 editor->nUndoStackSize = 0;
62
63 LIST_FOR_EACH_ENTRY_SAFE( cursor, cursor2, &editor->undo_stack, struct undo_item, entry )
64 {
65 list_remove( &cursor->entry );
67 }
68
69 empty_redo_stack( editor );
70}

Referenced by add_undo_insert_run(), editor_handle_message(), fnTextSrv_TxSetText(), ME_DestroyEditor(), ME_ReplaceSel(), and ME_StreamIn().

◆ ME_PlayUndoItem()

static void ME_PlayUndoItem ( ME_TextEditor editor,
struct undo_item undo 
)
static

Definition at line 323 of file undo.c.

324{
325
326 if (editor->nUndoMode == umIgnore)
327 return;
328 TRACE("Playing undo/redo item, id=%d\n", undo->type);
329
330 switch(undo->type)
331 {
334 assert(0);
336 {
337 ME_Cursor tmp;
338 cursor_from_char_ofs( editor, undo->u.set_para_fmt.pos, &tmp );
339 add_undo_set_para_fmt( editor, tmp.para );
340 tmp.para->fmt = undo->u.set_para_fmt.fmt;
341 tmp.para->border = undo->u.set_para_fmt.border;
342 para_mark_rewrap( editor, tmp.para );
343 break;
344 }
346 {
348 cursor_from_char_ofs( editor, undo->u.set_char_fmt.pos, &start );
349 end = start;
350 ME_MoveCursorChars(editor, &end, undo->u.set_char_fmt.len, FALSE);
351 ME_SetCharFormat(editor, &start, &end, &undo->u.set_char_fmt.fmt);
352 break;
353 }
354 case undo_insert_run:
355 {
356 ME_Cursor tmp;
357 cursor_from_char_ofs( editor, undo->u.insert_run.pos, &tmp );
358 run_insert( editor, &tmp, undo->u.insert_run.style,
359 undo->u.insert_run.str, undo->u.insert_run.len,
360 undo->u.insert_run.flags );
361 break;
362 }
363 case undo_delete_run:
364 {
365 ME_Cursor tmp;
366 cursor_from_char_ofs( editor, undo->u.delete_run.pos, &tmp );
367 ME_InternalDeleteText(editor, &tmp, undo->u.delete_run.len, TRUE);
368 break;
369 }
370 case undo_join_paras:
371 {
372 ME_Cursor tmp;
373 cursor_from_char_ofs( editor, undo->u.join_paras.pos, &tmp );
374 para_join( editor, tmp.para, TRUE );
375 break;
376 }
377 case undo_split_para:
378 {
379 ME_Cursor tmp;
380 ME_Paragraph *this_para, *new_para;
381 BOOL bFixRowStart;
382 int paraFlags = undo->u.split_para.flags & (MEPF_ROWSTART|MEPF_CELL|MEPF_ROWEND);
383
384 cursor_from_char_ofs( editor, undo->u.split_para.pos, &tmp );
385 if (tmp.nOffset) run_split( editor, &tmp );
386 this_para = tmp.para;
387 bFixRowStart = this_para->nFlags & MEPF_ROWSTART;
388 if (bFixRowStart)
389 {
390 /* Re-insert the paragraph before the table, making sure the nFlag value
391 * is correct. */
392 this_para->nFlags &= ~MEPF_ROWSTART;
393 }
394 new_para = para_split( editor, tmp.run, tmp.run->style,
395 undo->u.split_para.eol_str->szData, undo->u.split_para.eol_str->nLen, paraFlags );
396 if (bFixRowStart)
397 new_para->nFlags |= MEPF_ROWSTART;
398 new_para->fmt = undo->u.split_para.fmt;
399 new_para->border = undo->u.split_para.border;
400 if (paraFlags)
401 {
402 para_cell( new_para )->nRightBoundary = undo->u.split_para.cell_right_boundary;
403 para_cell( new_para )->border = undo->u.split_para.cell_border;
404 }
405 break;
406 }
407 }
408}
int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop)
Definition: caret.c:678
BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, int nChars, BOOL bForce)
Definition: caret.c:339
ME_Paragraph * para_join(ME_TextEditor *editor, ME_Paragraph *para, BOOL use_first_fmt) DECLSPEC_HIDDEN
Definition: para.c:683
ME_Cell * para_cell(ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:127
void cursor_from_char_ofs(ME_TextEditor *editor, int char_ofs, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: run.c:240
void para_mark_rewrap(ME_TextEditor *editor, ME_Paragraph *para) DECLSPEC_HIDDEN
Definition: para.c:26
ME_Paragraph * para_split(ME_TextEditor *editor, ME_Run *run, ME_Style *style, const WCHAR *eol_str, int eol_len, int paraFlags) DECLSPEC_HIDDEN
Definition: para.c:540
ME_Run * run_split(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN
Definition: run.c:305
ME_Run * run_insert(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style, const WCHAR *str, int len, int flags) DECLSPEC_HIDDEN
Definition: run.c:375
void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *pFmt) DECLSPEC_HIDDEN
Definition: run.c:777
#define MEPF_CELL
Definition: editstr.h:142
#define MEPF_ROWSTART
Definition: editstr.h:143
#define MEPF_ROWEND
Definition: editstr.h:144
GLuint start
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
ME_Paragraph * para
Definition: editstr.h:274
int nOffset
Definition: editstr.h:276
ME_Run * run
Definition: editstr.h:275
ME_Style * style
Definition: editstr.h:159
BOOL add_undo_set_para_fmt(ME_TextEditor *editor, const ME_Paragraph *para)
Definition: undo.c:152

Referenced by ME_Redo(), and ME_Undo().

◆ ME_Redo()

BOOL ME_Redo ( ME_TextEditor editor)

Definition at line 448 of file undo.c.

449{
450 ME_UndoMode nMode = editor->nUndoMode;
451 struct list *head;
452 struct undo_item *undo, *cursor2;
453
454 assert(nMode == umAddToUndo || nMode == umIgnore);
455
456 if (editor->nUndoMode == umIgnore) return FALSE;
457
458 head = list_head( &editor->redo_stack );
459 if (!head) return FALSE;
460
461 /* watch out for uncommitted transactions ! */
462 undo = LIST_ENTRY( head, struct undo_item, entry );
463 assert( undo->type == undo_end_transaction );
464
465 editor->nUndoMode = umAddBackToUndo;
466 list_remove( &undo->entry );
467 destroy_undo_item( undo );
468
469 LIST_FOR_EACH_ENTRY_SAFE( undo, cursor2, &editor->redo_stack, struct undo_item, entry )
470 {
471 if (undo->type == undo_end_transaction) break;
472 ME_PlayUndoItem( editor, undo );
473 list_remove( &undo->entry );
474 destroy_undo_item( undo );
475 }
478 editor->nUndoMode = nMode;
479 ME_UpdateRepaint(editor, FALSE);
480 return TRUE;
481}
void table_move_from_row_start(ME_TextEditor *editor) DECLSPEC_HIDDEN
Definition: table.c:531
void ME_UpdateRepaint(ME_TextEditor *editor, BOOL update_now) DECLSPEC_HIDDEN
Definition: paint.c:129
ME_UndoMode
Definition: editstr.h:279
static void ME_PlayUndoItem(ME_TextEditor *editor, struct undo_item *undo)
Definition: undo.c:323

Referenced by editor_handle_message(), and ME_KeyDown().

◆ ME_Undo()

BOOL ME_Undo ( ME_TextEditor editor)

Definition at line 410 of file undo.c.

411{
412 ME_UndoMode nMode = editor->nUndoMode;
413 struct list *head;
414 struct undo_item *undo, *cursor2;
415
416 if (editor->nUndoMode == umIgnore) return FALSE;
417 assert(nMode == umAddToUndo || nMode == umIgnore);
418
419 head = list_head( &editor->undo_stack );
420 if (!head) return FALSE;
421
422 /* watch out for uncommitted transactions ! */
423 undo = LIST_ENTRY( head, struct undo_item, entry );
426
427 editor->nUndoMode = umAddToRedo;
428
429 list_remove( &undo->entry );
430 destroy_undo_item( undo );
431
432 LIST_FOR_EACH_ENTRY_SAFE( undo, cursor2, &editor->undo_stack, struct undo_item, entry )
433 {
434 if (undo->type == undo_end_transaction) break;
435 ME_PlayUndoItem( editor, undo );
436 list_remove( &undo->entry );
437 destroy_undo_item( undo );
438 }
439
442 editor->nUndoStackSize--;
443 editor->nUndoMode = nMode;
444 ME_UpdateRepaint(editor, FALSE);
445 return TRUE;
446}

Referenced by editor_handle_message(), and ME_KeyDown().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( richedit  )