1 /* 2 * Copyright (C) 2018-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 * Undoable actions. 24 */ 25 26 #ifndef __UNDO_UNDOABLE_ACTION_H__ 27 #define __UNDO_UNDOABLE_ACTION_H__ 28 29 #include <stdbool.h> 30 31 #include "utils/yaml.h" 32 33 typedef struct AudioClip AudioClip; 34 typedef struct PortConnectionsManager 35 PortConnectionsManager; 36 37 /** 38 * @addtogroup actions 39 * 40 * @{ 41 */ 42 43 #define UNDOABLE_ACTION_SCHEMA_VERSION 1 44 45 /** 46 * Type of UndoableAction. 47 */ 48 typedef enum UndoableActionType 49 { 50 /* ---- Track/Channel ---- */ 51 UA_TRACKLIST_SELECTIONS, 52 53 UA_CHANNEL_SEND, 54 55 /* ---- end ---- */ 56 57 UA_MIXER_SELECTIONS, 58 UA_ARRANGER_SELECTIONS, 59 60 /* ---- connections ---- */ 61 62 UA_MIDI_MAPPING, 63 UA_PORT_CONNECTION, 64 UA_PORT, 65 66 /* ---- end ---- */ 67 68 /* ---- range ---- */ 69 70 UA_RANGE, 71 72 /* ---- end ---- */ 73 74 UA_TRANSPORT, 75 76 } UndoableActionType; 77 78 static const cyaml_strval_t 79 undoable_action_type_strings[] = 80 { 81 { "Tracklist selections", 82 UA_TRACKLIST_SELECTIONS }, 83 { "Channel send", UA_CHANNEL_SEND }, 84 { "Mixer selections", UA_MIXER_SELECTIONS }, 85 { "Arranger selections", UA_ARRANGER_SELECTIONS }, 86 { "MIDI mapping", UA_MIDI_MAPPING }, 87 { "Port connection", UA_PORT_CONNECTION }, 88 { "Port", UA_PORT }, 89 { "Range", UA_RANGE }, 90 { "Transport", UA_TRANSPORT }, 91 }; 92 93 /** 94 * Base struct to be inherited by implementing 95 * undoable actions. 96 */ 97 typedef struct UndoableAction 98 { 99 int schema_version; 100 101 /** Undoable action type. */ 102 UndoableActionType type; 103 104 /** 105 * Index in the stack. 106 * 107 * Used during deserialization. 108 */ 109 int stack_idx; 110 111 /** 112 * Number of actions to perform. 113 * 114 * This is used to group multiple actions into 115 * one logical action (eg, create a group track 116 * and route multiple tracks to it). 117 * 118 * To be set on the last action being performed. 119 */ 120 int num_actions; 121 } UndoableAction; 122 123 static const cyaml_schema_field_t 124 undoable_action_fields_schema[] = 125 { 126 YAML_FIELD_INT (UndoableAction, schema_version), 127 YAML_FIELD_ENUM ( 128 UndoableAction, type, 129 undoable_action_type_strings), 130 YAML_FIELD_INT ( 131 UndoableAction, stack_idx), 132 YAML_FIELD_INT ( 133 UndoableAction, num_actions), 134 135 CYAML_FIELD_END 136 }; 137 138 static const cyaml_schema_value_t 139 undoable_action_schema = 140 { 141 CYAML_VALUE_MAPPING (CYAML_FLAG_POINTER, 142 UndoableAction, undoable_action_fields_schema), 143 }; 144 145 NONNULL 146 void 147 undoable_action_init_loaded ( 148 UndoableAction * self); 149 150 /** 151 * Initializer to be used by implementing actions. 152 */ 153 NONNULL 154 void 155 undoable_action_init ( 156 UndoableAction * self, 157 UndoableActionType type); 158 159 /** 160 * Returns whether the action requires pausing 161 * the engine. 162 */ 163 NONNULL 164 bool 165 undoable_action_needs_pause ( 166 UndoableAction * self); 167 168 /** 169 * Checks whether the action can contain an audio 170 * clip. 171 * 172 * No attempt is made to remove unnused files from 173 * the pool for actions that can't contain audio 174 * clips. 175 */ 176 NONNULL 177 bool 178 undoable_action_can_contain_clip ( 179 UndoableAction * self); 180 181 182 /** 183 * Checks whether the action actually contains or 184 * refers to the given audio clip. 185 */ 186 NONNULL 187 bool 188 undoable_action_contains_clip ( 189 UndoableAction * self, 190 AudioClip * clip); 191 192 /** 193 * Sets the number of actions for this action. 194 * 195 * This should be set on the last action to be 196 * performed. 197 */ 198 NONNULL 199 void 200 undoable_action_set_num_actions ( 201 UndoableAction * self, 202 int num_actions); 203 204 /** 205 * To be used by actions that save/load port 206 * connections. 207 * 208 * @param _do True if doing/performing, false if 209 * undoing. 210 * @param before Pointer to the connections before. 211 * @param after Pointer to the connections after. 212 */ 213 NONNULL_ARGS (1) 214 void 215 undoable_action_save_or_load_port_connections ( 216 UndoableAction * self, 217 bool _do, 218 PortConnectionsManager ** before, 219 PortConnectionsManager ** after); 220 221 /** 222 * Performs the action. 223 * 224 * @note Only to be called by undo manager. 225 * 226 * @return Non-zero if errors occurred. 227 */ 228 NONNULL_ARGS (1) 229 int 230 undoable_action_do ( 231 UndoableAction * self, 232 GError ** error); 233 234 /** 235 * Undoes the action. 236 * 237 * @return Non-zero if errors occurred. 238 */ 239 NONNULL_ARGS (1) 240 int 241 undoable_action_undo ( 242 UndoableAction * self, 243 GError ** error); 244 245 void 246 undoable_action_free ( 247 UndoableAction * self); 248 249 /** 250 * Stringizes the action to be used in Undo/Redo 251 * buttons. 252 * 253 * The string MUST be free'd using g_free(). 254 */ 255 NONNULL 256 char * 257 undoable_action_to_string ( 258 UndoableAction * ua); 259 260 /** 261 * @} 262 */ 263 264 #endif 265