CuteLogger
Fast and simple logging solution for Qt based applications
timelinecommands.h
1/*
2 * Copyright (c) 2013-2026 Meltytech, LLC
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef COMMANDS_H
19#define COMMANDS_H
20
21#include "docks/timelinedock.h"
22#include "models/markersmodel.h"
23#include "models/multitrackmodel.h"
24#include "undohelper.h"
25
26#include <MltProducer.h>
27#include <MltTransition.h>
28#include <QObject>
29#include <QString>
30#include <QUndoCommand>
31#include <QUuid>
32
33#include <vector>
34
35namespace Timeline {
36
37enum {
38 UndoIdTrimClipIn = 100,
39 UndoIdTrimClipOut,
40 UndoIdFadeIn,
41 UndoIdFadeOut,
42 UndoIdTrimTransitionIn,
43 UndoIdTrimTransitionOut,
44 UndoIdResizeTransition,
45 UndoIdAddTransitionByTrimIn,
46 UndoIdAddTransitionByTrimOut,
47 UndoIdUpdate,
48 UndoIdMoveClip,
49 UndoIdChangeGain,
50};
51
52struct ClipPosition
53{
54 ClipPosition(int track, int clip)
55 {
56 trackIndex = track;
57 clipIndex = clip;
58 }
59
60 bool operator<(const ClipPosition &rhs) const
61 {
62 if (trackIndex == rhs.trackIndex) {
63 return clipIndex < rhs.clipIndex;
64 } else {
65 return trackIndex < rhs.trackIndex;
66 }
67 }
68
69 int trackIndex;
70 int clipIndex;
71};
72
73class AppendCommand : public QUndoCommand
74{
75public:
76 AppendCommand(MultitrackModel &model,
77 int trackIndex,
78 const QString &xml,
79 bool skipProxy = false,
80 bool seek = true,
81 QUndoCommand *parent = 0);
82 void redo();
83 void undo();
84
85private:
86 MultitrackModel &m_model;
87 int m_trackIndex;
88 QString m_xml;
89 UndoHelper m_undoHelper;
90 bool m_skipProxy;
91 bool m_seek;
92 QVector<QUuid> m_uuids;
93};
94
95class InsertCommand : public QUndoCommand
96{
97public:
98 InsertCommand(MultitrackModel &model,
99 MarkersModel &markersModel,
100 int trackIndex,
101 int position,
102 const QString &xml,
103 bool seek = true,
104 QUndoCommand *parent = 0);
105 void redo();
106 void undo();
107
108private:
109 MultitrackModel &m_model;
110 MarkersModel &m_markersModel;
111 int m_trackIndex;
112 int m_position;
113 QString m_xml;
114 QStringList m_oldTracks;
115 UndoHelper m_undoHelper;
116 bool m_seek;
117 bool m_rippleAllTracks;
118 bool m_rippleMarkers;
119 int m_markersShift;
120 QVector<QUuid> m_uuids;
121};
122
123class OverwriteCommand : public QUndoCommand
124{
125public:
126 OverwriteCommand(MultitrackModel &model,
127 int trackIndex,
128 int position,
129 const QString &xml,
130 bool seek = true,
131 QUndoCommand *parent = 0);
132 void redo();
133 void undo();
134
135private:
136 MultitrackModel &m_model;
137 int m_trackIndex;
138 int m_position;
139 QString m_xml;
140 UndoHelper m_undoHelper;
141 bool m_seek;
142 QVector<QUuid> m_uuids;
143};
144
145class LiftCommand : public QUndoCommand
146{
147public:
148 LiftCommand(MultitrackModel &model, int trackIndex, int clipIndex, QUndoCommand *parent = 0);
149 void redo();
150 void undo();
151
152private:
153 MultitrackModel &m_model;
154 int m_trackIndex;
155 int m_clipIndex;
156 UndoHelper m_undoHelper;
157};
158
159class RemoveCommand : public QUndoCommand
160{
161public:
162 RemoveCommand(MultitrackModel &model,
163 MarkersModel &markersModel,
164 int trackIndex,
165 int clipIndex,
166 QUndoCommand *parent = 0);
167 void redo();
168 void undo();
169
170private:
171 MultitrackModel &m_model;
172 MarkersModel &m_markersModel;
173 int m_trackIndex;
174 int m_clipIndex;
175 UndoHelper m_undoHelper;
176 bool m_rippleAllTracks;
177 bool m_rippleMarkers;
178 int m_markerRemoveStart;
179 int m_markerRemoveEnd;
180 QList<Markers::Marker> m_markers;
181};
182
183class GroupCommand : public QUndoCommand
184{
185public:
186 GroupCommand(MultitrackModel &model, QUndoCommand *parent = 0);
187 void addToGroup(int trackIndex, int clipIndex);
188 void redo();
189 void undo();
190
191private:
192 MultitrackModel &m_model;
193 QList<ClipPosition> m_clips;
194 QMap<ClipPosition, int> m_prevGroups;
195};
196
197class UngroupCommand : public QUndoCommand
198{
199public:
200 UngroupCommand(MultitrackModel &model, QUndoCommand *parent = 0);
201 void removeFromGroup(int trackIndex, int clipIndex);
202 void redo();
203 void undo();
204
205private:
206 MultitrackModel &m_model;
207 QMap<ClipPosition, int> m_prevGroups;
208};
209
210class NameTrackCommand : public QUndoCommand
211{
212public:
213 NameTrackCommand(MultitrackModel &model,
214 int trackIndex,
215 const QString &name,
216 QUndoCommand *parent = 0);
217 void redo();
218 void undo();
219
220private:
221 MultitrackModel &m_model;
222 int m_trackIndex;
223 QString m_name;
224 QString m_oldName;
225};
226
227class MergeCommand : public QUndoCommand
228{
229public:
230 MergeCommand(MultitrackModel &model, int trackIndex, int clipIndex, QUndoCommand *parent = 0);
231 void redo();
232 void undo();
233
234private:
235 MultitrackModel &m_model;
236 int m_trackIndex;
237 int m_clipIndex;
238 UndoHelper m_undoHelper;
239};
240
241class MuteTrackCommand : public QUndoCommand
242{
243public:
244 MuteTrackCommand(MultitrackModel &model, int trackIndex, QUndoCommand *parent = 0);
245 void redo();
246 void undo();
247
248private:
249 MultitrackModel &m_model;
250 int m_trackIndex;
251 bool m_oldValue;
252};
253
254class HideTrackCommand : public QUndoCommand
255{
256public:
257 HideTrackCommand(MultitrackModel &model, int trackIndex, QUndoCommand *parent = 0);
258 void redo();
259 void undo();
260
261private:
262 MultitrackModel &m_model;
263 int m_trackIndex;
264 bool m_oldValue;
265};
266
267class CompositeTrackCommand : public QUndoCommand
268{
269public:
270 CompositeTrackCommand(MultitrackModel &model,
271 int trackIndex,
272 bool value,
273 QUndoCommand *parent = 0);
274 void redo();
275 void undo();
276
277private:
278 MultitrackModel &m_model;
279 int m_trackIndex;
280 bool m_value;
281 bool m_oldValue;
282};
283
284class LockTrackCommand : public QUndoCommand
285{
286public:
287 LockTrackCommand(MultitrackModel &model, int trackIndex, bool value, QUndoCommand *parent = 0);
288 void redo();
289 void undo();
290
291private:
292 MultitrackModel &m_model;
293 int m_trackIndex;
294 bool m_value;
295 bool m_oldValue;
296};
297
298class MoveClipCommand : public QUndoCommand
299{
300public:
301 MoveClipCommand(TimelineDock &timeline,
302 int trackDelta,
303 int positionDelta,
304 bool ripple,
305 QUndoCommand *parent = 0);
306 void addClip(int trackIndex, int clipIndex);
307 void redo();
308 void undo();
309
310protected:
311 int id() const { return UndoIdMoveClip; }
312 bool mergeWith(const QUndoCommand *other);
313
314private:
315 void redoMarkers();
316
317 TimelineDock &m_timeline;
318 MultitrackModel &m_model;
319 MarkersModel &m_markersModel;
320
321 struct Info
322 {
323 int trackIndex;
324 int clipIndex;
325 int frame_in;
326 int frame_out;
327 int start;
328 int group;
329 QUuid uuid;
330
331 Info()
332 : trackIndex(-1)
333 , clipIndex(-1)
334 , frame_in(-1)
335 , frame_out(-1)
336 , start(0)
337 , group(-1)
338 {}
339 };
340
341 int m_trackDelta;
342 int m_positionDelta;
343 bool m_ripple;
344 bool m_rippleAllTracks;
345 bool m_rippleMarkers;
346 UndoHelper m_undoHelper;
347 QMultiMap<int, Info> m_clips; // ordered by position
348 bool m_redo;
349 int m_earliestStart;
350 QList<Markers::Marker> m_markers;
351 int m_markersModified;
352};
353
354class TrimCommand : public QUndoCommand
355{
356public:
357 explicit TrimCommand(QUndoCommand *parent = 0)
358 : QUndoCommand(parent)
359 {}
360 void setUndoHelper(UndoHelper *helper) { m_undoHelper.reset(helper); }
361
362protected:
363 QScopedPointer<UndoHelper> m_undoHelper;
364};
365
366class TrimClipInCommand : public TrimCommand
367{
368public:
369 TrimClipInCommand(MultitrackModel &model,
370 MarkersModel &markersModel,
371 int trackIndex,
372 int clipIndex,
373 int delta,
374 bool ripple,
375 bool redo = true,
376 QUndoCommand *parent = 0);
377 void redo();
378 void undo();
379
380protected:
381 int id() const { return UndoIdTrimClipIn; }
382 bool mergeWith(const QUndoCommand *other);
383
384private:
385 MultitrackModel &m_model;
386 MarkersModel &m_markersModel;
387 int m_trackIndex;
388 int m_clipIndex;
389 int m_delta;
390 bool m_ripple;
391 bool m_rippleAllTracks;
392 bool m_rippleMarkers;
393 bool m_redo;
394 int m_markerRemoveStart;
395 int m_markerRemoveEnd;
396 QList<Markers::Marker> m_markers;
397};
398
399class TrimClipOutCommand : public TrimCommand
400{
401public:
402 TrimClipOutCommand(MultitrackModel &model,
403 MarkersModel &markersModel,
404 int trackIndex,
405 int clipIndex,
406 int delta,
407 bool ripple,
408 bool redo = true,
409 QUndoCommand *parent = 0);
410 void redo();
411 void undo();
412
413protected:
414 int id() const { return UndoIdTrimClipOut; }
415 bool mergeWith(const QUndoCommand *other);
416
417private:
418 MultitrackModel &m_model;
419 MarkersModel &m_markersModel;
420 int m_trackIndex;
421 int m_clipIndex;
422 int m_delta;
423 bool m_ripple;
424 bool m_rippleAllTracks;
425 bool m_rippleMarkers;
426 bool m_redo;
427 int m_markerRemoveStart;
428 int m_markerRemoveEnd;
429 QList<Markers::Marker> m_markers;
430};
431
432class SplitCommand : public QUndoCommand
433{
434public:
435 SplitCommand(MultitrackModel &model,
436 const std::vector<int> &trackIndex,
437 const std::vector<int> &clipIndex,
438 int position,
439 QUndoCommand *parent = 0);
440 void redo();
441 void undo();
442
443private:
444 MultitrackModel &m_model;
445 std::vector<int> m_trackIndex;
446 std::vector<int> m_clipIndex;
447 int m_position;
448 UndoHelper m_undoHelper;
449};
450
451class FadeInCommand : public QUndoCommand
452{
453public:
454 FadeInCommand(MultitrackModel &model,
455 int trackIndex,
456 int clipIndex,
457 int duration,
458 QUndoCommand *parent = 0);
459 void redo();
460 void undo();
461
462protected:
463 int id() const { return UndoIdFadeIn; }
464 bool mergeWith(const QUndoCommand *other);
465
466private:
467 MultitrackModel &m_model;
468 int m_trackIndex;
469 int m_clipIndex;
470 int m_duration;
471 int m_previous;
472};
473
474class FadeOutCommand : public QUndoCommand
475{
476public:
477 FadeOutCommand(MultitrackModel &model,
478 int trackIndex,
479 int clipIndex,
480 int duration,
481 QUndoCommand *parent = 0);
482 void redo();
483 void undo();
484
485protected:
486 int id() const { return UndoIdFadeOut; }
487 bool mergeWith(const QUndoCommand *other);
488
489private:
490 MultitrackModel &m_model;
491 int m_trackIndex;
492 int m_clipIndex;
493 int m_duration;
494 int m_previous;
495};
496
497class AddTransitionCommand : public QUndoCommand
498{
499public:
500 AddTransitionCommand(TimelineDock &timeline,
501 int trackIndex,
502 int clipIndex,
503 int position,
504 bool ripple,
505 QUndoCommand *parent = 0);
506 void redo();
507 void undo();
508 int getTransitionIndex() const { return m_transitionIndex; }
509
510private:
511 TimelineDock &m_timeline;
512 MultitrackModel &m_model;
513 MarkersModel &m_markersModel;
514 int m_trackIndex;
515 int m_clipIndex;
516 int m_position;
517 int m_transitionIndex;
518 bool m_ripple;
519 UndoHelper m_undoHelper;
520 bool m_rippleAllTracks;
521 bool m_rippleMarkers;
522 int m_markerOldStart;
523 int m_markerNewStart;
524 QList<Markers::Marker> m_markers;
525};
526
527class TrimTransitionInCommand : public TrimCommand
528{
529public:
530 TrimTransitionInCommand(MultitrackModel &model,
531 int trackIndex,
532 int clipIndex,
533 int delta,
534 bool redo = true,
535 QUndoCommand *parent = 0);
536 void redo();
537 void undo();
538
539protected:
540 int id() const { return UndoIdTrimTransitionIn; }
541 bool mergeWith(const QUndoCommand *other);
542
543private:
544 MultitrackModel &m_model;
545 int m_trackIndex;
546 int m_clipIndex;
547 int m_delta;
548 bool m_notify;
549 bool m_redo;
550};
551
552class TrimTransitionOutCommand : public TrimCommand
553{
554public:
555 TrimTransitionOutCommand(MultitrackModel &model,
556 int trackIndex,
557 int clipIndex,
558 int delta,
559 bool redo = true,
560 QUndoCommand *parent = 0);
561 void redo();
562 void undo();
563
564protected:
565 int id() const { return UndoIdTrimTransitionOut; }
566 bool mergeWith(const QUndoCommand *other);
567
568private:
569 MultitrackModel &m_model;
570 int m_trackIndex;
571 int m_clipIndex;
572 int m_delta;
573 bool m_notify;
574 bool m_redo;
575};
576
577class ResizeTransitionCommand : public TrimCommand
578{
579public:
580 ResizeTransitionCommand(MultitrackModel &model,
581 int trackIndex,
582 int transitionIndex,
583 int delta,
584 bool redo = true,
585 QUndoCommand *parent = 0);
586 void redo();
587 void undo();
588
589protected:
590 int id() const { return UndoIdResizeTransition; }
591 bool mergeWith(const QUndoCommand *other);
592
593private:
594 MultitrackModel &m_model;
595 int m_trackIndex;
596 int m_transitionIndex;
597 int m_delta;
598 bool m_redo;
599};
600
601class AddTransitionByTrimInCommand : public TrimCommand
602{
603public:
604 AddTransitionByTrimInCommand(TimelineDock &timeline,
605 int trackIndex,
606 int clipIndex,
607 int duration,
608 int trimDelta,
609 bool redo = true,
610 QUndoCommand *parent = 0);
611 void redo();
612 void undo();
613
614protected:
615 int id() const { return UndoIdAddTransitionByTrimIn; }
616 bool mergeWith(const QUndoCommand *other);
617
618private:
619 TimelineDock &m_timeline;
620 int m_trackIndex;
621 int m_clipIndex;
622 int m_duration;
623 int m_trimDelta;
624 bool m_notify;
625 bool m_redo;
626};
627
628class RemoveTransitionByTrimInCommand : public TrimCommand
629{
630public:
631 RemoveTransitionByTrimInCommand(MultitrackModel &model,
632 int trackIndex,
633 int clipIndex,
634 int delta,
635 QString xml,
636 bool redo = true,
637 QUndoCommand *parent = 0);
638 void redo();
639 void undo();
640
641private:
642 MultitrackModel &m_model;
643 int m_trackIndex;
644 int m_clipIndex;
645 int m_delta;
646 QString m_xml;
647 bool m_redo;
648};
649
650class RemoveTransitionByTrimOutCommand : public TrimCommand
651{
652public:
653 RemoveTransitionByTrimOutCommand(MultitrackModel &model,
654 int trackIndex,
655 int clipIndex,
656 int delta,
657 QString xml,
658 bool redo = true,
659 QUndoCommand *parent = 0);
660 void redo();
661 void undo();
662
663private:
664 MultitrackModel &m_model;
665 int m_trackIndex;
666 int m_clipIndex;
667 int m_delta;
668 QString m_xml;
669 bool m_redo;
670};
671
672class AddTransitionByTrimOutCommand : public TrimCommand
673{
674public:
675 AddTransitionByTrimOutCommand(MultitrackModel &model,
676 int trackIndex,
677 int clipIndex,
678 int duration,
679 int trimDelta,
680 bool redo = true,
681 QUndoCommand *parent = 0);
682 void redo();
683 void undo();
684
685protected:
686 int id() const { return UndoIdAddTransitionByTrimOut; }
687 bool mergeWith(const QUndoCommand *other);
688
689private:
690 MultitrackModel &m_model;
691 int m_trackIndex;
692 int m_clipIndex;
693 int m_duration;
694 int m_trimDelta;
695 bool m_notify;
696 bool m_redo;
697};
698
699class AddTrackCommand : public QUndoCommand
700{
701public:
702 AddTrackCommand(MultitrackModel &model, bool isVideo, QUndoCommand *parent = 0);
703 void redo();
704 void undo();
705
706private:
707 MultitrackModel &m_model;
708 int m_trackIndex;
709 bool m_isVideo;
710 QUuid m_uuid;
711};
712
713class InsertTrackCommand : public QUndoCommand
714{
715public:
716 InsertTrackCommand(MultitrackModel &model,
717 int trackIndex,
718 TrackType trackType = PlaylistTrackType,
719 QUndoCommand *parent = 0);
720 void redo();
721 void undo();
722
723private:
724 MultitrackModel &m_model;
725 int m_trackIndex;
726 TrackType m_trackType;
727 QUuid m_uuid;
728};
729
730class RemoveTrackCommand : public QUndoCommand
731{
732public:
733 RemoveTrackCommand(MultitrackModel &model, int trackIndex, QUndoCommand *parent = 0);
734 void redo();
735 void undo();
736
737private:
738 MultitrackModel &m_model;
739 int m_trackIndex;
740 TrackType m_trackType;
741 QString m_trackName;
742 UndoHelper m_undoHelper;
743 QScopedPointer<Mlt::Producer> m_filtersProducer;
744 QUuid m_uuid;
745};
746
747class MoveTrackCommand : public QUndoCommand
748{
749public:
750 MoveTrackCommand(MultitrackModel &model,
751 int fromTrackIndex,
752 int toTrackIndex,
753 QUndoCommand *parent = 0);
754 void redo();
755 void undo();
756
757private:
758 MultitrackModel &m_model;
759 int m_fromTrackIndex;
760 int m_toTrackIndex;
761};
762
763class ChangeBlendModeCommand : public QObject, public QUndoCommand
764{
765 Q_OBJECT
766public:
767 ChangeBlendModeCommand(Mlt::Transition &transition,
768 const QString &propertyName,
769 const QString &mode,
770 QUndoCommand *parent = 0);
771 void redo();
772 void undo();
773signals:
774 void modeChanged(QString &mode);
775
776private:
777 Mlt::Transition m_transition;
778 QString m_propertyName;
779 QString m_newMode;
780 QString m_oldMode;
781};
782
783class UpdateCommand : public QUndoCommand
784{
785public:
786 UpdateCommand(TimelineDock &timeline,
787 int trackIndex,
788 int clipIndex,
789 int position,
790 QUndoCommand *parent = 0);
791 void setXmlAfter(const QString &xml);
792 void setPosition(int trackIndex, int clipIndex, int position);
793 void setRippleAllTracks(bool);
794 int trackIndex() const { return m_trackIndex; }
795 int clipIndex() const { return m_clipIndex; }
796 int position() const { return m_position; }
797 void redo();
798 void undo();
799
800private:
801 TimelineDock &m_timeline;
802 int m_trackIndex;
803 int m_clipIndex;
804 int m_position;
805 QString m_xmlAfter;
806 bool m_isFirstRedo;
807 UndoHelper m_undoHelper;
808 bool m_ripple;
809 bool m_rippleAllTracks;
810};
811
812class DetachAudioCommand : public QUndoCommand
813{
814public:
815 DetachAudioCommand(TimelineDock &timeline,
816 int trackIndex,
817 int clipIndex,
818 int position,
819 const QString &xml,
820 QUndoCommand *parent = 0);
821 void redo();
822 void undo();
823
824private:
825 TimelineDock &m_timeline;
826 int m_trackIndex;
827 int m_clipIndex;
828 int m_position;
829 int m_targetTrackIndex;
830 QString m_xml;
831 UndoHelper m_undoHelper;
832 bool m_trackAdded;
833 QUuid m_uuid;
834};
835
836class ReplaceCommand : public QUndoCommand
837{
838public:
839 ReplaceCommand(MultitrackModel &model,
840 int trackIndex,
841 int clipIndex,
842 const QString &xml,
843 QUndoCommand *parent = nullptr);
844 void redo();
845 void undo();
846
847private:
848 MultitrackModel &m_model;
849 int m_trackIndex;
850 int m_clipIndex;
851 QString m_xml;
852 bool m_isFirstRedo;
853 UndoHelper m_undoHelper;
854};
855
856class AlignClipsCommand : public QUndoCommand
857{
858public:
859 AlignClipsCommand(MultitrackModel &model, QUndoCommand *parent = 0);
860 void addAlignment(QUuid uuid, int offset, double speedCompensation);
861 void redo();
862 void undo();
863
864private:
865 MultitrackModel &m_model;
866 UndoHelper m_undoHelper;
867 bool m_redo;
868 struct Alignment
869 {
870 QUuid uuid;
871 int offset;
872 double speed;
873 };
874 QVector<Alignment> m_alignments;
875};
876
877class ApplyFiltersCommand : public QUndoCommand
878{
879public:
880 ApplyFiltersCommand(MultitrackModel &model,
881 const QString &filterProducerXml,
882 QUndoCommand *parent = 0);
883 void addClip(int trackIndex, int clipIndex);
884 void redo();
885 void undo();
886
887private:
888 MultitrackModel &m_model;
889 QString m_xml;
890 QMap<ClipPosition, QString> m_prevFilters;
891};
892
893class ChangeGainCommand : public QUndoCommand
894{
895public:
896 ChangeGainCommand(MultitrackModel &model,
897 int trackIndex,
898 int clipIndex,
899 double gain,
900 QUndoCommand *parent = 0);
901 void redo();
902 void undo();
903
904protected:
905 int id() const { return UndoIdChangeGain; }
906 bool mergeWith(const QUndoCommand *other);
907
908private:
909 MultitrackModel &m_model;
910 int m_trackIndex;
911 int m_clipIndex;
912 double m_gain;
913 double m_previous;
914};
915
916} // namespace Timeline
917
918#endif