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  * Action for a group of ArrangerObject's.
24  */
25 
26 #ifndef __UNDO_ARRANGER_SELECTIONS_ACTION_H__
27 #define __UNDO_ARRANGER_SELECTIONS_ACTION_H__
28 
29 #include <stdbool.h>
30 #include <stdint.h>
31 
32 #include "actions/undoable_action.h"
33 #include "audio/audio_function.h"
34 #include "audio/automation_function.h"
35 #include "audio/midi_function.h"
36 #include "audio/position.h"
37 #include "audio/quantize_options.h"
38 #include "gui/backend/audio_selections.h"
39 #include "gui/backend/automation_selections.h"
40 #include "gui/backend/chord_selections.h"
41 #include "gui/backend/midi_arranger_selections.h"
42 #include "gui/backend/timeline_selections.h"
43 
44 typedef struct ArrangerSelections ArrangerSelections;
45 typedef struct ArrangerObject ArrangerObject;
46 typedef struct Position Position;
47 typedef struct QuantizeOptions QuantizeOptions;
48 
49 /**
50  * @addtogroup actions
51  *
52  * @{
53  */
54 
55 typedef enum ArrangerSelectionsActionType
56 {
57   AS_ACTION_AUTOMATION_FILL,
58   AS_ACTION_CREATE,
59   AS_ACTION_DELETE,
60   AS_ACTION_DUPLICATE,
61   AS_ACTION_EDIT,
62   AS_ACTION_LINK,
63   AS_ACTION_MERGE,
64   AS_ACTION_MOVE,
65   AS_ACTION_QUANTIZE,
66   AS_ACTION_RECORD,
67   AS_ACTION_RESIZE,
68   AS_ACTION_SPLIT,
69 } ArrangerSelectionsActionType;
70 
71 static const cyaml_strval_t
72 arranger_selections_action_type_strings[] =
73 {
74   { "Automation fill", AS_ACTION_AUTOMATION_FILL },
75   { "Create",          AS_ACTION_CREATE },
76   { "Delete",          AS_ACTION_DELETE },
77   { "Duplicate",       AS_ACTION_DUPLICATE },
78   { "Edit",            AS_ACTION_EDIT },
79   { "Link",            AS_ACTION_LINK },
80   { "Merge",           AS_ACTION_MERGE },
81   { "Move",            AS_ACTION_MOVE },
82   { "Quantize",        AS_ACTION_QUANTIZE },
83   { "Record",          AS_ACTION_RECORD },
84   { "Resize",          AS_ACTION_RESIZE },
85   { "Split",           AS_ACTION_SPLIT },
86 };
87 
88 /**
89  * Type used when the action is a RESIZE action.
90  */
91 typedef enum ArrangerSelectionsActionResizeType
92 {
93   ARRANGER_SELECTIONS_ACTION_RESIZE_L,
94   ARRANGER_SELECTIONS_ACTION_RESIZE_R,
95   ARRANGER_SELECTIONS_ACTION_RESIZE_L_LOOP,
96   ARRANGER_SELECTIONS_ACTION_RESIZE_R_LOOP,
97   ARRANGER_SELECTIONS_ACTION_RESIZE_L_FADE,
98   ARRANGER_SELECTIONS_ACTION_RESIZE_R_FADE,
99   ARRANGER_SELECTIONS_ACTION_STRETCH_L,
100   ARRANGER_SELECTIONS_ACTION_STRETCH_R,
101 } ArrangerSelectionsActionResizeType;
102 
103 static const cyaml_strval_t
104 arranger_selections_action_resize_type_strings[] =
105 {
106   { "Resize L",
107     ARRANGER_SELECTIONS_ACTION_RESIZE_L },
108   { "Resize R",
109     ARRANGER_SELECTIONS_ACTION_RESIZE_R },
110   { "Resize L (loop)",
111     ARRANGER_SELECTIONS_ACTION_RESIZE_L_LOOP },
112   { "Resize R (loop)",
113     ARRANGER_SELECTIONS_ACTION_RESIZE_R_LOOP },
114   { "Resize L (fade)",
115     ARRANGER_SELECTIONS_ACTION_RESIZE_L_FADE },
116   { "Resize R (fade)",
117     ARRANGER_SELECTIONS_ACTION_RESIZE_R_FADE },
118   { "Stretch L",
119     ARRANGER_SELECTIONS_ACTION_STRETCH_L },
120   { "Stretch R",
121     ARRANGER_SELECTIONS_ACTION_STRETCH_R },
122 };
123 
124 /**
125  * Type used when the action is an EDIT action.
126  */
127 typedef enum ArrangerSelectionsActionEditType
128 {
129   /** Edit the name of the ArrangerObject's in the
130    * selection. */
131   ARRANGER_SELECTIONS_ACTION_EDIT_NAME,
132 
133   /**
134    * Edit a Position of the ArrangerObject's in
135    * the selection.
136    *
137    * This will just set all of the positions on the
138    * object.
139    */
140   ARRANGER_SELECTIONS_ACTION_EDIT_POS,
141 
142   /**
143    * Edit a primitive (int, etc) member of
144    * ArrangerObject's in the selection.
145    *
146    * This will simply set all relevant primitive
147    * values in an ArrangerObject when doing/undoing.
148    */
149   ARRANGER_SELECTIONS_ACTION_EDIT_PRIMITIVE,
150 
151   /** For editing the MusicalScale inside
152    * ScaleObject's. */
153   ARRANGER_SELECTIONS_ACTION_EDIT_SCALE,
154 
155   /** Editing fade positions or curve options. */
156   ARRANGER_SELECTIONS_ACTION_EDIT_FADES,
157 
158   /** Change mute status. */
159   ARRANGER_SELECTIONS_ACTION_EDIT_MUTE,
160 
161   /** For ramping MidiNote velocities or
162    * AutomationPoint values.
163    * (this is handled by EDIT_PRIMITIVE) */
164   //ARRANGER_SELECTIONS_ACTION_EDIT_RAMP,
165 
166   /** MIDI function. */
167   ARRANGER_SELECTIONS_ACTION_EDIT_EDITOR_FUNCTION,
168 } ArrangerSelectionsActionEditType;
169 
170 static const cyaml_strval_t
171 arranger_selections_action_edit_type_strings[] =
172 {
173   { "Name",
174     ARRANGER_SELECTIONS_ACTION_EDIT_NAME },
175   { "Pos",
176     ARRANGER_SELECTIONS_ACTION_EDIT_POS },
177   { "Primitive",
178     ARRANGER_SELECTIONS_ACTION_EDIT_PRIMITIVE },
179   { "Scale",
180     ARRANGER_SELECTIONS_ACTION_EDIT_SCALE },
181   { "Fades",
182     ARRANGER_SELECTIONS_ACTION_EDIT_FADES },
183   { "Mute",
184     ARRANGER_SELECTIONS_ACTION_EDIT_MUTE },
185   { "Editor function",
186     ARRANGER_SELECTIONS_ACTION_EDIT_EDITOR_FUNCTION },
187 };
188 
189 /**
190  * The action.
191  */
192 typedef struct ArrangerSelectionsAction
193 {
194   UndoableAction       parent_instance;
195 
196   /** Action type. */
197   ArrangerSelectionsActionType type;
198 
199   /** A clone of the ArrangerSelections before the
200    * change. */
201   ArrangerSelections * sel;
202 
203   /**
204    * A clone of the ArrangerSelections after the
205    * change (used in the EDIT action and
206    * quantize).
207    */
208   ArrangerSelections * sel_after;
209 
210   /** Type of edit action, if an Edit action. */
211   ArrangerSelectionsActionEditType edit_type;
212 
213   ArrangerSelectionsActionResizeType resize_type;
214 
215   /** Ticks diff. */
216   double               ticks;
217   /** Tracks moved. */
218   int                  delta_tracks;
219   /** Lanes moved. */
220   int                  delta_lanes;
221   /** Chords moved (up/down in the Chord editor). */
222   int                  delta_chords;
223   /** Delta of MidiNote pitch. */
224   int                  delta_pitch;
225   /** Delta of MidiNote velocity. */
226   int                  delta_vel;
227   /**
228    * Difference in a normalized amount, such as
229    * automation point normalized value.
230    */
231   double               delta_normalized_amount;
232 
233   /** String, when changing a string. */
234   char *               str;
235 
236   /** Position, when changing a Position. */
237   Position             pos;
238 
239   /** Used when splitting - these are the split
240    * ArrangerObject's. */
241   ArrangerObject *     r1[800];
242   ArrangerObject *     r2[800];
243 
244   /** Number of split objects inside r1 and r2
245    * each. */
246   int                  num_split_objs;
247 
248   /**
249    * If this is 1, the first "do" call does
250    * nothing in some cases.
251    *
252    * Set internally and either used or ignored.
253    */
254   int                  first_run;
255 
256   /** QuantizeOptions clone, if quantizing. */
257   QuantizeOptions *    opts;
258 
259   /* --- below for serialization only --- */
260   ChordSelections *    chord_sel;
261   ChordSelections *    chord_sel_after;
262   TimelineSelections * tl_sel;
263   TimelineSelections * tl_sel_after;
264   MidiArrangerSelections * ma_sel;
265   MidiArrangerSelections * ma_sel_after;
266   AutomationSelections * automation_sel;
267   AutomationSelections * automation_sel_after;
268   AudioSelections *      audio_sel;
269   AudioSelections *      audio_sel_after;
270 
271   /* arranger objects that can be split */
272   ZRegion *            region_r1[800];
273   ZRegion *            region_r2[800];
274   MidiNote *           mn_r1[800];
275   MidiNote *           mn_r2[800];
276 
277   /** Used for automation autofill action. */
278   ZRegion *            region_before;
279   ZRegion *            region_after;
280 
281 } ArrangerSelectionsAction;
282 
283 static const cyaml_schema_field_t
284   arranger_selections_action_fields_schema[] =
285 {
286   YAML_FIELD_MAPPING_EMBEDDED (
287     ArrangerSelectionsAction, parent_instance,
288     undoable_action_fields_schema),
289   YAML_FIELD_ENUM (
290     ArrangerSelectionsAction, type,
291     arranger_selections_action_type_strings),
292   YAML_FIELD_ENUM (
293     ArrangerSelectionsAction, edit_type,
294     arranger_selections_action_edit_type_strings),
295   YAML_FIELD_ENUM (
296     ArrangerSelectionsAction, resize_type,
297     arranger_selections_action_resize_type_strings),
298   YAML_FIELD_FLOAT (
299     ArrangerSelectionsAction, ticks),
300   YAML_FIELD_INT (
301     ArrangerSelectionsAction, delta_tracks),
302   YAML_FIELD_INT (
303     ArrangerSelectionsAction, delta_lanes),
304   YAML_FIELD_INT (
305     ArrangerSelectionsAction, delta_chords),
306   YAML_FIELD_INT (
307     ArrangerSelectionsAction, delta_pitch),
308   YAML_FIELD_INT (
309     ArrangerSelectionsAction, delta_vel),
310   YAML_FIELD_FLOAT (
311     ArrangerSelectionsAction,
312     delta_normalized_amount),
313   YAML_FIELD_STRING_PTR_OPTIONAL (
314     ArrangerSelectionsAction, str),
315   YAML_FIELD_MAPPING_EMBEDDED (
316     ArrangerSelectionsAction, pos,
317     position_fields_schema),
318   YAML_FIELD_MAPPING_PTR_OPTIONAL (
319     ArrangerSelectionsAction, opts,
320     quantize_options_fields_schema),
321   CYAML_FIELD_MAPPING_PTR (
322     "chord_sel",
323     CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
324     ArrangerSelectionsAction, chord_sel,
325     chord_selections_fields_schema),
326   CYAML_FIELD_MAPPING_PTR (
327     "tl_sel",
328     CYAML_FLAG_POINTER | CYAML_FLAG_OPTIONAL,
329     ArrangerSelectionsAction, tl_sel,
330     timeline_selections_fields_schema),
331   YAML_FIELD_MAPPING_PTR_OPTIONAL (
332     ArrangerSelectionsAction, ma_sel,
333     midi_arranger_selections_fields_schema),
334   YAML_FIELD_MAPPING_PTR_OPTIONAL (
335     ArrangerSelectionsAction, automation_sel,
336     automation_selections_fields_schema),
337   YAML_FIELD_MAPPING_PTR_OPTIONAL (
338     ArrangerSelectionsAction, audio_sel,
339     audio_selections_fields_schema),
340   YAML_FIELD_MAPPING_PTR_OPTIONAL (
341     ArrangerSelectionsAction, chord_sel_after,
342     chord_selections_fields_schema),
343   YAML_FIELD_MAPPING_PTR_OPTIONAL (
344     ArrangerSelectionsAction, tl_sel_after,
345     timeline_selections_fields_schema),
346   YAML_FIELD_MAPPING_PTR_OPTIONAL (
347     ArrangerSelectionsAction, ma_sel_after,
348     midi_arranger_selections_fields_schema),
349   YAML_FIELD_MAPPING_PTR_OPTIONAL (
350     ArrangerSelectionsAction, automation_sel_after,
351     automation_selections_fields_schema),
352   YAML_FIELD_MAPPING_PTR_OPTIONAL (
353     ArrangerSelectionsAction, audio_sel_after,
354     audio_selections_fields_schema),
355   YAML_FIELD_MAPPING_PTR_OPTIONAL (
356     ArrangerSelectionsAction, region_before,
357     region_fields_schema),
358   YAML_FIELD_MAPPING_PTR_OPTIONAL (
359     ArrangerSelectionsAction, region_after,
360     region_fields_schema),
361   CYAML_FIELD_SEQUENCE_COUNT (
362     "region_r1", CYAML_FLAG_DEFAULT,
363     ArrangerSelectionsAction, region_r1,
364     num_split_objs,
365     &region_schema, 0, CYAML_UNLIMITED),
366   CYAML_FIELD_SEQUENCE_COUNT (
367     "region_r2", CYAML_FLAG_DEFAULT,
368     ArrangerSelectionsAction, region_r2,
369     num_split_objs,
370     &region_schema, 0, CYAML_UNLIMITED),
371   CYAML_FIELD_SEQUENCE_COUNT (
372     "mn_r1", CYAML_FLAG_DEFAULT,
373     ArrangerSelectionsAction, mn_r1,
374     num_split_objs,
375     &midi_note_schema, 0, CYAML_UNLIMITED),
376   CYAML_FIELD_SEQUENCE_COUNT (
377     "mn_r2", CYAML_FLAG_DEFAULT,
378     ArrangerSelectionsAction, mn_r2,
379     num_split_objs,
380     &midi_note_schema, 0, CYAML_UNLIMITED),
381 
382   CYAML_FIELD_END
383 };
384 
385 static const cyaml_schema_value_t
386   arranger_selections_action_schema =
387 {
388   YAML_VALUE_PTR_NULLABLE (
389     ArrangerSelectionsAction,
390     arranger_selections_action_fields_schema),
391 };
392 
393 void
394 arranger_selections_action_init_loaded (
395   ArrangerSelectionsAction * self);
396 
397 /**
398  * Creates a new action for creating/deleting
399  * objects.
400  *
401  * @param create 1 to create 0 to delte.
402  */
403 WARN_UNUSED_RESULT
404 UndoableAction *
405 arranger_selections_action_new_create_or_delete (
406   ArrangerSelections * sel,
407   const bool           create,
408   GError **            error);
409 
410 #define \
411 arranger_selections_action_new_create(sel,error) \
412   arranger_selections_action_new_create_or_delete ( \
413     (ArrangerSelections *) sel, true, error)
414 
415 #define \
416 arranger_selections_action_new_delete(sel,error) \
417   arranger_selections_action_new_create_or_delete ( \
418     (ArrangerSelections *) sel, false, error)
419 
420 WARN_UNUSED_RESULT
421 UndoableAction *
422 arranger_selections_action_new_record (
423   ArrangerSelections * sel_before,
424   ArrangerSelections * sel_after,
425   const bool           already_recorded,
426   GError **            error);
427 
428 /**
429  * Creates a new action for moving or duplicating
430  * objects.
431  *
432  * @param move True to move, false to duplicate.
433  * @param already_moved If this is true, the first
434  *   DO will do nothing.
435  * @param delta_normalized_amount Difference in a
436  *   normalized amount, such as automation point
437  *   normalized value.
438  */
439 WARN_UNUSED_RESULT
440 UndoableAction *
441 arranger_selections_action_new_move_or_duplicate (
442   ArrangerSelections * sel,
443   const bool           move,
444   const double         ticks,
445   const int            delta_chords,
446   const int            delta_pitch,
447   const int            delta_tracks,
448   const int            delta_lanes,
449   const double         delta_normalized_amount,
450   const bool           already_moved,
451   GError **            error);
452 
453 #define \
454 arranger_selections_action_new_move( \
455   sel,ticks,chords,pitch,tracks,lanes,norm_amt, \
456   already_moved,error) \
457   arranger_selections_action_new_move_or_duplicate ( \
458     (ArrangerSelections *) sel, 1, ticks, chords, \
459     pitch, tracks, lanes, norm_amt, already_moved, \
460     error)
461 #define \
462 arranger_selections_action_new_duplicate( \
463   sel,ticks,chords,pitch,tracks,lanes,norm_amt, \
464   already_moved,error) \
465   arranger_selections_action_new_move_or_duplicate ( \
466     (ArrangerSelections *) sel, 0, ticks, chords, \
467     pitch, tracks, lanes, norm_amt, already_moved, \
468     error)
469 
470 #define \
471 arranger_selections_action_new_move_timeline( \
472   sel,ticks,delta_tracks,delta_lanes, \
473   already_moved,error) \
474   arranger_selections_action_new_move ( \
475     sel, ticks, 0, 0, delta_tracks, delta_lanes, \
476     0, already_moved, error)
477 #define \
478 arranger_selections_action_new_duplicate_timeline( \
479   sel,ticks,delta_tracks,delta_lanes, \
480   already_moved,error) \
481   arranger_selections_action_new_duplicate ( \
482     sel, ticks, 0, 0, delta_tracks, delta_lanes, \
483     0, already_moved, error)
484 
485 #define \
486 arranger_selections_action_new_move_midi( \
487   sel,ticks,delta_pitch, already_moved,error) \
488   arranger_selections_action_new_move ( \
489     sel, ticks, 0, delta_pitch, 0, 0, \
490     0, already_moved, error)
491 #define \
492 arranger_selections_action_new_duplicate_midi( \
493   sel,ticks,delta_pitch,already_moved,error) \
494   arranger_selections_action_new_duplicate ( \
495     sel, ticks, 0, delta_pitch, 0, 0, \
496     0, already_moved, error)
497 #define \
498 arranger_selections_action_new_move_chord( \
499   sel,ticks,delta_chords, already_moved,error) \
500   arranger_selections_action_new_move ( \
501     sel, ticks, delta_chords, 0, 0, 0, \
502     0, already_moved, error)
503 #define \
504 arranger_selections_action_new_duplicate_chord( \
505   sel,ticks,delta_chords, already_moved,error) \
506   arranger_selections_action_new_duplicate ( \
507     sel, ticks, delta_chords, 0, 0, 0, \
508     0, already_moved, error)
509 
510 #define \
511 arranger_selections_action_new_move_automation( \
512   sel,ticks,norm_amt,already_moved,error) \
513   arranger_selections_action_new_move ( \
514     sel, ticks, 0, 0, 0, 0, norm_amt, \
515     already_moved, error)
516 #define \
517 arranger_selections_action_new_duplicate_automation( \
518   sel,ticks,norm_amt,already_moved,error) \
519   arranger_selections_action_new_duplicate ( \
520     sel, ticks, 0, 0, 0, 0, norm_amt, \
521     already_moved, error)
522 
523 /**
524  * Creates a new action for linking regions.
525  *
526  * @param already_moved If this is true, the first
527  *   DO will do nothing.
528  * @param sel_before Original selections.
529  * @param sel_after Selections after duplication.
530  */
531 WARN_UNUSED_RESULT
532 UndoableAction *
533 arranger_selections_action_new_link (
534   ArrangerSelections * sel_before,
535   ArrangerSelections * sel_after,
536   const double         ticks,
537   const int            delta_tracks,
538   const int            delta_lanes,
539   const bool           already_moved,
540   GError **            error);
541 
542 /**
543  * Creates a new action for editing properties
544  * of an object.
545  *
546  * @param sel_before The selections before the
547  *   change.
548  * @param sel_after The selections after the
549  *   change.
550  * @param type Indication of which field has changed.
551  */
552 WARN_UNUSED_RESULT
553 UndoableAction *
554 arranger_selections_action_new_edit (
555   ArrangerSelections *             sel_before,
556   ArrangerSelections *             sel_after,
557   ArrangerSelectionsActionEditType type,
558   bool                             already_edited,
559   GError **                        error);
560 
561 /**
562  * Wrapper over
563  * arranger_selections_action_new_edit() for MIDI
564  * functions.
565  */
566 WARN_UNUSED_RESULT
567 UndoableAction *
568 arranger_selections_action_new_edit_midi_function (
569   ArrangerSelections * sel_before,
570   MidiFunctionType     midi_func_type,
571   GError **            error);
572 
573 /**
574  * Wrapper over
575  * arranger_selections_action_new_edit() for
576  * automation functions.
577  */
578 WARN_UNUSED_RESULT
579 UndoableAction *
580 arranger_selections_action_new_edit_automation_function (
581   ArrangerSelections *   sel_before,
582   AutomationFunctionType automation_func_type,
583   GError **              error);
584 
585 /**
586  * Wrapper over
587  * arranger_selections_action_new_edit() for
588  * automation functions.
589  */
590 WARN_UNUSED_RESULT
591 UndoableAction *
592 arranger_selections_action_new_edit_audio_function (
593   ArrangerSelections * sel_before,
594   AudioFunctionType    audio_func_type,
595   const char *         uri,
596   GError **            error);
597 
598 /**
599  * Creates a new action for automation autofill.
600  *
601  * @param region_before The region before the
602  *   change.
603  * @param region_after The region after the
604  *   change.
605  * @param already_changed Whether the change was
606  *   already made.
607  */
608 WARN_UNUSED_RESULT
609 UndoableAction *
610 arranger_selections_action_new_automation_fill (
611   ZRegion * region_before,
612   ZRegion * region_after,
613   bool      already_changed,
614   GError ** error);
615 
616 /**
617  * Creates a new action for splitting
618  * ArrangerObject's.
619  *
620  * @param pos Global position to split at.
621  */
622 WARN_UNUSED_RESULT
623 UndoableAction *
624 arranger_selections_action_new_split (
625   ArrangerSelections * sel,
626   const Position *     pos,
627   GError **            error);
628 
629 /**
630  * Creates a new action for merging
631  * ArrangerObject's.
632  */
633 WARN_UNUSED_RESULT
634 UndoableAction *
635 arranger_selections_action_new_merge (
636   ArrangerSelections * sel,
637   GError **            error);
638 
639 /**
640  * Creates a new action for resizing
641  * ArrangerObject's.
642  *
643  * @param ticks How many ticks to add to the resizing
644  *   edge.
645  */
646 WARN_UNUSED_RESULT
647 UndoableAction *
648 arranger_selections_action_new_resize (
649   ArrangerSelections *               sel,
650   ArrangerSelectionsActionResizeType type,
651   const double                       ticks,
652   const bool                         already_resized,
653   GError **                          error);
654 
655 /**
656  * Creates a new action fro quantizing
657  * ArrangerObject's.
658  *
659  * @param opts Quantize options.
660  */
661 WARN_UNUSED_RESULT
662 UndoableAction *
663 arranger_selections_action_new_quantize (
664   ArrangerSelections * sel,
665   QuantizeOptions *    opts,
666   GError **            error);
667 
668 NONNULL
669 ArrangerSelectionsAction *
670 arranger_selections_action_clone (
671   const ArrangerSelectionsAction * src);
672 
673 bool
674 arranger_selections_action_perform_create_or_delete (
675   ArrangerSelections * sel,
676   const bool           create,
677   GError **            error);
678 
679 #define \
680 arranger_selections_action_perform_create( \
681   sel,error) \
682   arranger_selections_action_perform_create_or_delete ( \
683     (ArrangerSelections *) sel, true, error)
684 
685 #define \
686 arranger_selections_action_perform_delete( \
687   sel,error) \
688   arranger_selections_action_perform_create_or_delete ( \
689     (ArrangerSelections *) sel, false, error)
690 
691 bool
692 arranger_selections_action_perform_record (
693   ArrangerSelections * sel_before,
694   ArrangerSelections * sel_after,
695   const bool           already_recorded,
696   GError **            error);
697 
698 bool
699 arranger_selections_action_perform_move_or_duplicate (
700   ArrangerSelections * sel,
701   const bool           move,
702   const double         ticks,
703   const int            delta_chords,
704   const int            delta_pitch,
705   const int            delta_tracks,
706   const int            delta_lanes,
707   const double         delta_normalized_amount,
708   const bool           already_moved,
709   GError **            error);
710 
711 #define \
712 arranger_selections_action_perform_move( \
713   sel,ticks,chords,pitch,tracks,lanes,norm_amt, \
714   already_moved,error) \
715   arranger_selections_action_perform_move_or_duplicate ( \
716     (ArrangerSelections *) sel, 1, ticks, chords, \
717     pitch, tracks, lanes, norm_amt, already_moved, \
718     error)
719 #define \
720 arranger_selections_action_perform_duplicate( \
721   sel,ticks,chords,pitch,tracks,lanes,norm_amt, \
722   already_moved,error) \
723   arranger_selections_action_perform_move_or_duplicate ( \
724     (ArrangerSelections *) sel, 0, ticks, chords, \
725     pitch, tracks, lanes, norm_amt, already_moved, \
726     error)
727 
728 #define \
729 arranger_selections_action_perform_move_timeline( \
730   sel,ticks,delta_tracks,delta_lanes, \
731   already_moved,error) \
732   arranger_selections_action_perform_move ( \
733     sel, ticks, 0, 0, delta_tracks, delta_lanes, \
734     0, already_moved, error)
735 #define \
736 arranger_selections_action_perform_duplicate_timeline( \
737   sel,ticks,delta_tracks,delta_lanes, \
738   already_moved,error) \
739   arranger_selections_action_perform_duplicate ( \
740     sel, ticks, 0, 0, delta_tracks, delta_lanes, \
741     0, already_moved, error)
742 
743 #define \
744 arranger_selections_action_perform_move_midi( \
745   sel,ticks,delta_pitch, already_moved,error) \
746   arranger_selections_action_perform_move ( \
747     sel, ticks, 0, delta_pitch, 0, 0, \
748     0, already_moved, error)
749 #define \
750 arranger_selections_action_perform_duplicate_midi( \
751   sel,ticks,delta_pitch,already_moved,error) \
752   arranger_selections_action_perform_duplicate ( \
753     sel, ticks, 0, delta_pitch, 0, 0, \
754     0, already_moved, error)
755 #define \
756 arranger_selections_action_perform_move_chord( \
757   sel,ticks,delta_chords, already_moved,error) \
758   arranger_selections_action_perform_move ( \
759     sel, ticks, delta_chords, 0, 0, 0, \
760     0, already_moved, error)
761 #define \
762 arranger_selections_action_perform_duplicate_chord( \
763   sel,ticks,delta_chords, already_moved,error) \
764   arranger_selections_action_perform_duplicate ( \
765     sel, ticks, delta_chords, 0, 0, 0, \
766     0, already_moved, error)
767 
768 #define \
769 arranger_selections_action_perform_move_automation( \
770   sel,ticks,norm_amt,already_moved,error) \
771   arranger_selections_action_perform_move ( \
772     sel, ticks, 0, 0, 0, 0, norm_amt, \
773     already_moved, error)
774 #define \
775 arranger_selections_action_perform_duplicate_automation( \
776   sel,ticks,norm_amt,already_moved,error) \
777   arranger_selections_action_perform_duplicate ( \
778     sel, ticks, 0, 0, 0, 0, norm_amt, \
779     already_moved, error)
780 
781 bool
782 arranger_selections_action_perform_link (
783   ArrangerSelections * sel_before,
784   ArrangerSelections * sel_after,
785   const double         ticks,
786   const int            delta_tracks,
787   const int            delta_lanes,
788   const bool           already_moved,
789   GError **            error);
790 
791 bool
792 arranger_selections_action_perform_edit (
793   ArrangerSelections *             sel_before,
794   ArrangerSelections *             sel_after,
795   ArrangerSelectionsActionEditType type,
796   bool                             already_edited,
797   GError **                        error);
798 
799 bool
800 arranger_selections_action_perform_edit_midi_function (
801   ArrangerSelections * sel_before,
802   MidiFunctionType     midi_func_type,
803   GError **            error);
804 
805 bool
806 arranger_selections_action_perform_edit_automation_function (
807   ArrangerSelections *   sel_before,
808   AutomationFunctionType automation_func_type,
809   GError **              error);
810 
811 bool
812 arranger_selections_action_perform_edit_audio_function (
813   ArrangerSelections * sel_before,
814   AudioFunctionType    audio_func_type,
815   const char *         uri,
816   GError **            error);
817 
818 bool
819 arranger_selections_action_perform_automation_fill (
820   ZRegion * region_before,
821   ZRegion * region_after,
822   bool      already_changed,
823   GError ** error);
824 
825 bool
826 arranger_selections_action_perform_split (
827   ArrangerSelections * sel,
828   const Position *     pos,
829   GError **            error);
830 
831 bool
832 arranger_selections_action_perform_merge (
833   ArrangerSelections * sel,
834   GError **            error);
835 
836 bool
837 arranger_selections_action_perform_resize (
838   ArrangerSelections *               sel,
839   ArrangerSelectionsActionResizeType type,
840   const double                       ticks,
841   const bool                         already_resized,
842   GError **                          error);
843 
844 bool
845 arranger_selections_action_perform_quantize (
846   ArrangerSelections * sel,
847   QuantizeOptions *    opts,
848   GError **            error);
849 
850 int
851 arranger_selections_action_do (
852   ArrangerSelectionsAction * self,
853   GError **                  error);
854 
855 int
856 arranger_selections_action_undo (
857   ArrangerSelectionsAction * self,
858   GError **                  error);
859 
860 char *
861 arranger_selections_action_stringize (
862   ArrangerSelectionsAction * self);
863 
864 bool
865 arranger_selections_action_contains_clip (
866   ArrangerSelectionsAction * self,
867   AudioClip *                clip);
868 
869 void
870 arranger_selections_action_free (
871   ArrangerSelectionsAction * self);
872 
873 /**
874  * @}
875  */
876 
877 #endif
878