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