1 /* 2 * Copyright (C) 2019-2021 Alexandros Theodotou <alex at zrythm dot org> 3 * 4 * This file is part of Zrythm 5 * 6 * Zrythm is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU Affero General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * Zrythm is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU Affero General Public License for more details. 15 * 16 * You should have received a copy of the GNU Affero General Public License 17 * along with Zrythm. If not, see <https://www.gnu.org/licenses/>. 18 */ 19 20 /** 21 * \file 22 * 23 * Undo manager. 24 */ 25 26 #ifndef __UNDO_UNDO_MANAGER_H__ 27 #define __UNDO_UNDO_MANAGER_H__ 28 29 #include "actions/undo_stack.h" 30 31 #include "zix/sem.h" 32 33 typedef struct AudioClip AudioClip; 34 35 /** 36 * @addtogroup actions 37 * 38 * @{ 39 */ 40 41 #define UNDO_MANAGER_SCHEMA_VERSION 1 42 43 #define UNDO_MANAGER (PROJECT->undo_manager) 44 45 /** 46 * Undo manager. 47 */ 48 typedef struct UndoManager 49 { 50 int schema_version; 51 52 UndoStack * undo_stack; 53 UndoStack * redo_stack; 54 55 /** Semaphore for performing actions. */ 56 ZixSem action_sem; 57 } UndoManager; 58 59 static const cyaml_schema_field_t 60 undo_manager_fields_schema[] = 61 { 62 YAML_FIELD_INT (UndoManager, schema_version), 63 YAML_FIELD_MAPPING_PTR ( 64 UndoManager, undo_stack, 65 undo_stack_fields_schema), 66 YAML_FIELD_MAPPING_PTR ( 67 UndoManager, redo_stack, 68 undo_stack_fields_schema), 69 70 CYAML_FIELD_END 71 }; 72 73 static const cyaml_schema_value_t 74 undo_manager_schema = 75 { 76 YAML_VALUE_PTR ( 77 UndoManager, undo_manager_fields_schema), 78 }; 79 80 /** 81 * Inits the undo manager by populating the 82 * undo/redo stacks. 83 */ 84 NONNULL 85 void 86 undo_manager_init_loaded ( 87 UndoManager * self); 88 89 /** 90 * Inits the undo manager by creating the undo/redo 91 * stacks. 92 */ 93 WARN_UNUSED_RESULT 94 UndoManager * 95 undo_manager_new (void); 96 97 /** 98 * Undo last action. 99 */ 100 NONNULL_ARGS (1) 101 int 102 undo_manager_undo ( 103 UndoManager * self, 104 GError ** error); 105 106 /** 107 * Redo last undone action. 108 */ 109 NONNULL_ARGS (1) 110 int 111 undo_manager_redo ( 112 UndoManager * self, 113 GError ** error); 114 115 /** 116 * Performs the action and pushes it to the undo 117 * stack. 118 * 119 * @return Non-zero if error. 120 */ 121 NONNULL_ARGS (1,2) 122 int 123 undo_manager_perform ( 124 UndoManager * self, 125 UndoableAction * action, 126 GError ** error); 127 128 /** 129 * Second and last argument given must be a 130 * GError **. 131 */ 132 #define UNDO_MANAGER_PERFORM_AND_PROPAGATE_ERR( \ 133 action,err,...) \ 134 { \ 135 g_return_val_if_fail ( \ 136 router_is_processing_thread (ROUTER) \ 137 == false, false); \ 138 UndoableAction * ua = \ 139 action (__VA_ARGS__); \ 140 if (ua) \ 141 { \ 142 int ret = \ 143 undo_manager_perform ( \ 144 UNDO_MANAGER, ua, err); \ 145 if (ret == 0) \ 146 return true; \ 147 } \ 148 return false; \ 149 } 150 151 /** 152 * Returns whether the given clip is used by any 153 * stack. 154 */ 155 NONNULL 156 bool 157 undo_manager_contains_clip ( 158 UndoManager * self, 159 AudioClip * clip); 160 161 /** 162 * Returns the last performed action, or NULL if 163 * the stack is empty. 164 */ 165 NONNULL 166 UndoableAction * 167 undo_manager_get_last_action ( 168 UndoManager * self); 169 170 /** 171 * Clears the undo and redo stacks. 172 */ 173 NONNULL 174 void 175 undo_manager_clear_stacks ( 176 UndoManager * self, 177 bool free); 178 179 NONNULL 180 UndoManager * 181 undo_manager_clone ( 182 const UndoManager * src); 183 184 NONNULL 185 void 186 undo_manager_free ( 187 UndoManager * self); 188 189 /** 190 * @} 191 */ 192 193 #endif 194