Blender  V3.3
interface_undo.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2020 Blender Foundation. All rights reserved. */
3 
10 #include <string.h>
11 
12 #include "BLI_listbase.h"
13 
14 #include "DNA_listBase.h"
15 
16 #include "MEM_guardedalloc.h"
17 
18 #include "interface_intern.h"
19 
20 /* -------------------------------------------------------------------- */
24 typedef struct uiUndoStack_Text_State {
27  char text[0];
29 
30 typedef struct uiUndoStack_Text {
34 
35 static const char *ui_textedit_undo_impl(uiUndoStack_Text *stack, int *r_cursor_index)
36 {
37  /* Don't undo if no data has been pushed yet. */
38  if (stack->current == NULL) {
39  return NULL;
40  }
41 
42  /* Travel backwards in the stack and copy information to the caller. */
43  if (stack->current->prev != NULL) {
44  stack->current = stack->current->prev;
45 
46  *r_cursor_index = stack->current->cursor_index;
47  return stack->current->text;
48  }
49  return NULL;
50 }
51 
52 static const char *ui_textedit_redo_impl(uiUndoStack_Text *stack, int *r_cursor_index)
53 {
54  /* Don't redo if no data has been pushed yet. */
55  if (stack->current == NULL) {
56  return NULL;
57  }
58 
59  /* Only redo if new data has not been entered since the last undo. */
60  if (stack->current->next) {
61  stack->current = stack->current->next;
62 
63  *r_cursor_index = stack->current->cursor_index;
64  return stack->current->text;
65  }
66  return NULL;
67 }
68 
69 const char *ui_textedit_undo(uiUndoStack_Text *stack, int direction, int *r_cursor_index)
70 {
71  BLI_assert(ELEM(direction, -1, 1));
72  if (direction < 0) {
73  return ui_textedit_undo_impl(stack, r_cursor_index);
74  }
75  return ui_textedit_redo_impl(stack, r_cursor_index);
76 }
77 
78 void ui_textedit_undo_push(uiUndoStack_Text *stack, const char *text, int cursor_index)
79 {
80  /* Clear all redo actions from the current state. */
81  if (stack->current != NULL) {
82  while (stack->current->next) {
84  BLI_remlink(&stack->states, state);
86  }
87  }
88 
89  /* Create the new state. */
90  const int text_size = strlen(text) + 1;
91  stack->current = MEM_mallocN(sizeof(uiUndoStack_Text_State) + text_size, __func__);
92  stack->current->cursor_index = cursor_index;
93  memcpy(stack->current->text, text, text_size);
94  BLI_addtail(&stack->states, stack->current);
95 }
96 
98 {
99  uiUndoStack_Text *stack = MEM_mallocN(sizeof(uiUndoStack_Text), __func__);
100  stack->current = NULL;
101  BLI_listbase_clear(&stack->states);
102 
103  return stack;
104 }
105 
107 {
108  BLI_freelistN(&stack->states);
109  MEM_freeN(stack);
110 }
111 
#define BLI_assert(a)
Definition: BLI_assert.h:46
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
#define ELEM(...)
These structs are the foundation for all linked lists in the library system.
Read Guarded memory(de)allocation.
static const char * ui_textedit_redo_impl(uiUndoStack_Text *stack, int *r_cursor_index)
struct uiUndoStack_Text uiUndoStack_Text
static const char * ui_textedit_undo_impl(uiUndoStack_Text *stack, int *r_cursor_index)
const char * ui_textedit_undo(uiUndoStack_Text *stack, int direction, int *r_cursor_index)
struct uiUndoStack_Text_State uiUndoStack_Text_State
uiUndoStack_Text * ui_textedit_undo_stack_create(void)
void ui_textedit_undo_stack_destroy(uiUndoStack_Text *stack)
void ui_textedit_undo_push(uiUndoStack_Text *stack, const char *text, int cursor_index)
const int state
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
struct uiUndoStack_Text_State * next
struct uiUndoStack_Text_State * prev
uiUndoStack_Text_State * current