1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //  $Id: undo.h,v 1.6.2.5 2009/05/24 21:43:44 terminator356 Exp $
5 //
6 //  (C) Copyright 1999/2000 Werner Schweer (ws@seh.de)
7 //
8 //  This program is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU General Public License
10 //  as published by the Free Software Foundation; version 2 of
11 //  the License, or (at your option) any later version.
12 //
13 //  This program is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 //  GNU General Public License for more details.
17 //
18 //  You should have received a copy of the GNU General Public License
19 //  along with this program; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 //
22 //=========================================================
23 
24 #ifndef __UNDO_H__
25 #define __UNDO_H__
26 
27 #include <list>
28 
29 #include <QString>
30 
31 #include "event.h"
32 #include "route.h"
33 #include "sig.h"
34 #include "pos.h"
35 #include <stdint.h>
36 
37 namespace MusECore {
38 
39 // Forward declarations:
40 class Marker;
41 class MidiPort;
42 class MidiInstrument;
43 class Track;
44 class Part;
45 class CtrlListList;
46 class CtrlList;
47 struct CtrlVal;
48 
49 extern std::list<QString> temporaryWavFiles; //!< Used for storing all tmp-files, for cleanup on shutdown
50 //---------------------------------------------------------
51 //   UndoOp
52 //---------------------------------------------------------
53 
54 struct UndoOp {
55       enum UndoType {
56             AddRoute, DeleteRoute,
57             AddTrack, DeleteTrack,
58             AddPart,  DeletePart,  MovePart, ModifyPartStart, ModifyPartLength, ModifyPartName, SelectPart,
59             AddEvent, DeleteEvent, ModifyEvent, SelectEvent,
60             AddAudioCtrlVal, DeleteAudioCtrlVal, ModifyAudioCtrlVal, ModifyAudioCtrlValList,
61             // Add, delete and modify operate directly on the list.
62             // setTempo does only if master is set, otherwise it operates on the static tempo value.
63             AddTempo, DeleteTempo, ModifyTempo, SetTempo, SetStaticTempo, SetGlobalTempo, EnableMasterTrack,
64             AddSig,   DeleteSig,   ModifySig,
65             AddKey,   DeleteKey,   ModifyKey,
66             ModifyTrackName, ModifyTrackChannel,
67             SetTrackRecord, SetTrackMute, SetTrackSolo, SetTrackRecMonitor, SetTrackOff,
68             MoveTrack,
69             ModifyClip,
70             AddMarker, DeleteMarker, ModifyMarker,
71             // This one is provided separately for optimizing repeated adjustments. It is 'combo breaker' -aware.
72             SetMarkerPos,
73             //// For wholesale changes to the list. Preferred if multiple additions or deletions are required.
74             //ModifyMarkerList,
75             ModifySongLen, // a = new len, b = old len
76             SetInstrument,
77             DoNothing,
78             ModifyMidiDivision,
79 
80             // These operations cannot be undone. They are 'one time' operations, removed after execution.
81             EnableAllAudioControllers,
82             GlobalSelectAllEvents,
83             NormalizeMidiDivision
84             };
85       UndoType type;
86 
87       union {
88             //U() { memset( this, 0, sizeof( U ) ); }
89             struct {
90                   int a;
91                   int b;
92                   int c;
93                   int d;
94                   int e;
95                   };
96             struct {
97                   const Part* part;
98                   unsigned old_partlen_or_pos; // FIXME FINDMICHJETZT XTicks!!
99                   unsigned new_partlen_or_pos;
100                   unsigned old_partlen;
101                   unsigned new_partlen;
102                   int64_t events_offset;
103                   Pos::TType events_offset_time_type;
104                   };
105             struct {
106                   int channel;
107                   int ctrl;
108                   int oVal;
109                   int nVal;
110                   };
111             struct {
112                   int startframe; //!< Start frame of changed data
113                   int endframe;   //!< End frame of changed data
114                   QString* tmpwavfile; //!< The file with the changed data
115                   };
116             struct {
117                   Marker* oldMarker;
118                   Marker* newMarker;
119                 };
120             struct {
121                   const Track* _propertyTrack;
122                   int _oldPropValue;
123                   int _newPropValue;
124                 };
125             struct {
126                   CtrlListList* _ctrlListList;
127                   CtrlList* _eraseCtrlList;
128                   CtrlList* _addCtrlList;
129                 };
130             struct {
131                   int _audioCtrlID;
132                   int _audioCtrlFrame;
133                   int _audioNewCtrlFrame;
134                   double _audioCtrlVal;
135                   double _audioNewCtrlVal;
136                 };
137             struct {
138                   MidiPort* _midiPort;
139                   MidiInstrument* _oldMidiInstrument;
140                   MidiInstrument* _newMidiInstrument;
141                 };
142             };
143 
144       QString* _oldName;
145       QString* _newName;
146       Event oEvent;
147       Event nEvent;
148       bool selected;
149       bool selected_old;
150       bool doCtrls;
151       bool doClones;
152       const Track* track;
153       const Track* oldTrack;
154       int trackno;
155       Route routeFrom;
156       Route routeTo;
157 
158       // If _noUndo is set, the operation cannot be undone. It is a 'one time' operation, removed after execution.
159       // It allows mixed undoable and non-undoable operations in one list, all executed in one RT cycle.
160       bool _noUndo;
161 
162       const char* typeName();
163       void dump();
164 
165       UndoOp();
166       // NOTE: In these constructors, if noUndo is set, the operation cannot be undone. It is a 'one time' operation, removed after execution.
167       //       It allows mixed undoable and non-undoable operations in one list, all executed in one RT cycle.
168       UndoOp(UndoType type, int a, int b, int c=0, bool noUndo = false);
169       UndoOp(UndoType type, int n, const Track* track, bool noUndo = false);
170       UndoOp(UndoType type, const Part* part, bool noUndo = false);
171       UndoOp(UndoType type, const Part* part, const QString& old_name, const QString& new_name, bool noUndo = false);
172       UndoOp(UndoType type, const Part* part, bool selected, bool selected_old, bool noUndo = false);
173       UndoOp(UndoType type, const Part* part, unsigned int old_len_or_pos, unsigned int new_len_or_pos, Pos::TType new_time_type = Pos::TICKS,
174              const Track* oTrack = 0, const Track* nTrack = 0, bool noUndo = false);
175       UndoOp(UndoType type, const Part* part, unsigned int old_pos, unsigned int new_pos,
176              unsigned int old_len, unsigned int new_len, int64_t events_offset,
177              Pos::TType new_time_type = Pos::TICKS, bool noUndo = false);
178       UndoOp(UndoType type, const Part* part, unsigned int old_len, unsigned int new_len, int64_t events_offset,
179              Pos::TType new_time_type = Pos::TICKS, bool noUndo = false);
180       UndoOp(UndoType type, const Event& nev, const Event& oev, const Part* part, bool doCtrls, bool doClones, bool noUndo = false);
181       UndoOp(UndoType type, const Event& nev, const Part* part, bool, bool, bool noUndo = false);
182       UndoOp(UndoType type, const Event& changedEvent, const QString& changeData, int startframe, int endframe, bool noUndo = false);
183       UndoOp(UndoType type, const Marker& oldMarker, const Marker& newMarker, bool noUndo = false);
184       UndoOp(UndoType type, const Marker& marker, bool noUndo = false);
185       UndoOp(UndoType type, const Marker& marker, unsigned int new_pos, Pos::TType new_time_type, bool noUndo = false);
186       // Takes ownership of the old list (deletes it).
187       //UndoOp(UndoType type, MarkerList** oldMarkerList, MarkerList* newMarkerList, bool noUndo = false);
188 
189       UndoOp(UndoType type, const Track* track, const QString& old_name, const QString& new_name, bool noUndo = false);
190       UndoOp(UndoType type, const Track* track, int old_chan, int new_chan, bool noUndo = false);
191       //UndoOp(UndoType type, const Track* track, int ctrlID, int frame, bool noUndo = false); // Same as above.
192       UndoOp(UndoType type, const Track* track, int ctrlID, int oldFrame, int newFrame, double oldValue, double newValue, bool noUndo = false);
193       UndoOp(UndoType type, const Track* track, int ctrlID, int frame, double value, bool noUndo = false);
194       UndoOp(UndoType type, const Track* track, bool value, bool noUndo = false);
195       UndoOp(UndoType type, CtrlListList* ctrl_ll, CtrlList* eraseCtrlList, CtrlList* addCtrlList, bool noUndo = false);
196       UndoOp(UndoType type, int tick, const MusECore::TimeSignature old_sig, const MusECore::TimeSignature new_sig, bool noUndo = false);
197       UndoOp(UndoType type, const Route& route_from, const Route& route_to, bool noUndo = false);
198       UndoOp(UndoType type, MidiPort* mp, MidiInstrument* instr, bool noUndo = false);
199       UndoOp(UndoType type);
200 };
201 
202 class Undo : public std::list<UndoOp> {
203    public:
Undo()204       Undo() : std::list<UndoOp>() { combobreaker=false; }
Undo(const Undo & other)205       Undo(const Undo& other) : std::list<UndoOp>(other) { this->combobreaker=other.combobreaker; }
206       Undo& operator=(const Undo& other) { std::list<UndoOp>::operator=(other); this->combobreaker=other.combobreaker; return *this;}
207 
208       bool empty() const;
209 
210 
211       /** if set, forbid merging (below).
212        *  Defaults to false */
213       bool combobreaker;
214 
215       /** is possible, merges itself and other by appending
216        *  all contents of other at this->end().
217        *  returns true if merged, false otherwise.
218        *  in case of success, the caller has to ensure that
219        *  other is deleted from the UndoList. */
220       bool merge_combo(const Undo& other);
221 
222       void push_front(const UndoOp& op);
223       void push_back(const UndoOp& op);
224       void insert(iterator position, const_iterator first, const_iterator last);
225       void insert(iterator position, const UndoOp& op);
226       void insert (iterator position, size_type n, const UndoOp& op);
227 };
228 
229 typedef Undo::iterator iUndoOp;
230 typedef Undo::reverse_iterator riUndoOp;
231 typedef Undo::const_iterator ciUndoOp;
232 typedef Undo::const_reverse_iterator criUndoOp;
233 
234 class UndoList : public std::list<Undo> {
235    protected:
236       bool isUndo;
237    public:
238       void clearDelete();
UndoList(bool _isUndo)239       UndoList(bool _isUndo) : std::list<Undo>() { isUndo=_isUndo; }
240 };
241 
242 typedef UndoList::iterator iUndo;
243 typedef UndoList::reverse_iterator riUndo;
244 
245 } // namespace MusECore
246 
247 #endif // __UNDO_H__
248