diff options
-rw-r--r-- | muse2/muse/audio.cpp | 2 | ||||
-rw-r--r-- | muse2/muse/audio.h | 9 | ||||
-rw-r--r-- | muse2/muse/seqmsg.cpp | 39 | ||||
-rw-r--r-- | muse2/muse/song.cpp | 34 | ||||
-rw-r--r-- | muse2/muse/song.h | 14 | ||||
-rw-r--r-- | muse2/muse/undo.cpp | 85 | ||||
-rw-r--r-- | muse2/muse/undo.h | 2 |
7 files changed, 97 insertions, 88 deletions
diff --git a/muse2/muse/audio.cpp b/muse2/muse/audio.cpp index 4eabe8ac..f7caa6a0 100644 --- a/muse2/muse/audio.cpp +++ b/muse2/muse/audio.cpp @@ -83,7 +83,7 @@ const char* seqMsgList[] = { "SEQM_ADD_TEMPO", "SEQM_SET_TEMPO", "SEQM_REMOVE_TEMPO", "SEQM_ADD_SIG", "SEQM_REMOVE_SIG", "SEQM_ADD_KEY", "SEQM_REMOVE_KEY", "SEQM_SET_GLOBAL_TEMPO", - "SEQM_UNDO", "SEQM_REDO", + "SEQM_REVERT_OPERATION_GROUP", "SEQM_EXECUTE_OPERATION_GROUP", "SEQM_RESET_DEVICES", "SEQM_INIT_DEVICES", "SEQM_PANIC", "SEQM_MIDI_LOCAL_OFF", "SEQM_PLAY_MIDI_EVENT", diff --git a/muse2/muse/audio.h b/muse2/muse/audio.h index 4b81bb2a..044760ac 100644 --- a/muse2/muse/audio.h +++ b/muse2/muse/audio.h @@ -52,6 +52,7 @@ class Part; class PluginI; class SynthI; class Track; +class Undo; //--------------------------------------------------------- // AudioMsgId @@ -67,7 +68,7 @@ enum { SEQM_ADD_TEMPO, SEQM_SET_TEMPO, SEQM_REMOVE_TEMPO, SEQM_ADD_SIG, SEQM_REMOVE_SIG, SEQM_ADD_KEY, SEQM_REMOVE_KEY, SEQM_SET_GLOBAL_TEMPO, - SEQM_UNDO, SEQM_REDO, + SEQM_REVERT_OPERATION_GROUP, SEQM_EXECUTE_OPERATION_GROUP, SEQM_RESET_DEVICES, SEQM_INIT_DEVICES, SEQM_PANIC, SEQM_MIDI_LOCAL_OFF, SEQM_PLAY_MIDI_EVENT, @@ -121,6 +122,7 @@ struct AudioMsg : public ThreadMsg { // this should be an union char port, channel, ctrl; int a, b, c; Pos pos; + Undo* operations; }; class AudioOutput; @@ -221,6 +223,9 @@ class Audio { void msgSeek(const Pos&); void msgPlay(bool val); + void msgExecuteOperationGroup(Undo&); // calls exe1, then calls exe2 in audio context, then calls exe3 + void msgRevertOperationGroup(Undo&); // similar. + void msgRemoveTrack(Track*, bool u = true); void msgRemoveTracks(); void msgMoveTrack(int idx1, int dx2, bool u = true); @@ -252,8 +257,6 @@ class Audio { void msgSetPrefader(AudioTrack*, int); void msgSetChannels(AudioTrack*, int); void msgSetRecord(AudioTrack*, bool); - void msgUndo(); - void msgRedo(); void msgLocalOff(); void msgInitMidiDevices(bool force = true); void msgResetMidiDevices(); diff --git a/muse2/muse/seqmsg.cpp b/muse2/muse/seqmsg.cpp index 4a51e7ce..3b914fda 100644 --- a/muse2/muse/seqmsg.cpp +++ b/muse2/muse/seqmsg.cpp @@ -606,26 +606,37 @@ void Audio::msgSeek(const Pos& pos) } //--------------------------------------------------------- -// msgUndo +// msgExecuteOperationGroup //--------------------------------------------------------- -void Audio::msgUndo() - { - AudioMsg msg; - msg.id = SEQM_UNDO; - sendMsg(&msg); - } +void Audio::msgExecuteOperationGroup(Undo& operations) +{ + MusEGlobal::song->executeOperationGroup1(operations); + + AudioMsg msg; + msg.id = SEQM_EXECUTE_OPERATION_GROUP; + msg.operations=&operations; + sendMsg(&msg); + + MusEGlobal::song->executeOperationGroup3(operations); +} //--------------------------------------------------------- -// msgRedo +// msgRevertOperationGroup //--------------------------------------------------------- -void Audio::msgRedo() - { - AudioMsg msg; - msg.id = SEQM_REDO; - sendMsg(&msg); - } +void Audio::msgRevertOperationGroup(Undo& operations) +{ + MusEGlobal::song->revertOperationGroup1(operations); + + + AudioMsg msg; + msg.id = SEQM_REVERT_OPERATION_GROUP; + msg.operations=&operations; + sendMsg(&msg); + + MusEGlobal::song->revertOperationGroup3(operations); +} //--------------------------------------------------------- // msgPlay diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 3cf1960d..e18dfc01 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -1756,10 +1756,16 @@ void Song::endMsgCmd() void Song::undo() { updateFlags = 0; - if (doUndo1()) + + Undo& opGroup = undoList->back(); + + if (opGroup.empty()) return; - MusEGlobal::audio->msgUndo(); - doUndo3(); + + MusEGlobal::audio->msgRevertOperationGroup(opGroup); + + undoList->pop_back(); + MusEGlobal::redoAction->setEnabled(true); MusEGlobal::undoAction->setEnabled(!undoList->empty()); setUndoRedoText(); @@ -1768,6 +1774,7 @@ void Song::undo() MusEGlobal::audio->msgUpdateSoloStates(); emit songChanged(updateFlags); + emit sigDirty(); } //--------------------------------------------------------- @@ -1777,10 +1784,16 @@ void Song::undo() void Song::redo() { updateFlags = 0; - if (doRedo1()) + + Undo& opGroup = redoList->back(); + + if (opGroup.empty()) return; - MusEGlobal::audio->msgRedo(); - doRedo3(); + + MusEGlobal::audio->msgExecuteOperationGroup(opGroup); + + redoList->pop_back(); + MusEGlobal::undoAction->setEnabled(true); MusEGlobal::redoAction->setEnabled(!redoList->empty()); setUndoRedoText(); @@ -1789,6 +1802,7 @@ void Song::redo() MusEGlobal::audio->msgUpdateSoloStates(); emit songChanged(updateFlags); + emit sigDirty(); } //--------------------------------------------------------- @@ -1802,11 +1816,11 @@ void Song::processMsg(AudioMsg* msg) case SEQM_UPDATE_SOLO_STATES: updateSoloStates(); break; - case SEQM_UNDO: - doUndo2(); + case SEQM_EXECUTE_OPERATION_GROUP: + executeOperationGroup2(*msg->operations); break; - case SEQM_REDO: - doRedo2(); + case SEQM_REVERT_OPERATION_GROUP: + revertOperationGroup2(*msg->operations); break; case SEQM_MOVE_TRACK: if (msg->a > msg->b) { diff --git a/muse2/muse/song.h b/muse2/muse/song.h index bc1aa9a1..c62f1c08 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -356,7 +356,7 @@ class Song : public QObject { void updateSoloStates(); //----------------------------------------- - // undo, redo + // undo, redo, operation groups //----------------------------------------- void startUndo(); @@ -364,12 +364,12 @@ class Song : public QObject { void undoOp(UndoOp::UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe); - bool doUndo1(); - void doUndo2(); - void doUndo3(); - bool doRedo1(); - void doRedo2(); - void doRedo3(); + void executeOperationGroup1(Undo& operations); + void executeOperationGroup2(Undo& operations); + void executeOperationGroup3(Undo& operations); + void revertOperationGroup1(Undo& operations); + void revertOperationGroup2(Undo& operations); + void revertOperationGroup3(Undo& operations); void addUndo(UndoOp i); void setUndoRedoText(); diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp index fdb24dad..6d22d440 100644 --- a/muse2/muse/undo.cpp +++ b/muse2/muse/undo.cpp @@ -211,9 +211,9 @@ void UndoList::clearDelete() void Song::startUndo() { redoList->clearDelete(); // redo must be invalidated when a new undo is started - MusEGlobal::redoAction->setEnabled(false); + MusEGlobal::redoAction->setEnabled(false); setUndoRedoText(); - + undoList->push_back(Undo()); updateFlags = 0; undoMode = true; @@ -355,23 +355,19 @@ bool Song::applyOperationGroup(Undo& group, bool doUndo) if (!group.empty()) { prepareOperationGroup(group); - //this is a HACK! but it works :) (added by flo93) - redoList->push_back(group); - redo(); - if (!doUndo) - { - undoList->pop_back(); - MusEGlobal::undoAction->setEnabled(!undoList->empty()); - setUndoRedoText(); - } - else - { - redoList->clearDelete(); // redo must be invalidated when a new undo is started - MusEGlobal::redoAction->setEnabled(false); - setUndoRedoText(); - } + if (doUndo) + startUndo(); + + MusEGlobal::audio->msgExecuteOperationGroup(group); + + // append all elements from "group" to the end of undoList->back(). + Undo& curUndo = undoList->back(); + curUndo.insert(curUndo.end(), group.begin(), group.end()); + if (doUndo) + endUndo(0); + return doUndo; } else @@ -381,14 +377,13 @@ bool Song::applyOperationGroup(Undo& group, bool doUndo) //--------------------------------------------------------- -// doUndo2 +// revertOperationGroup2 // real time part //--------------------------------------------------------- -void Song::doUndo2() +void Song::revertOperationGroup2(Undo& operations) { - Undo& u = undoList->back(); - for (riUndoOp i = u.rbegin(); i != u.rend(); ++i) { + for (riUndoOp i = operations.rbegin(); i != operations.rend(); ++i) { Track* editable_track = const_cast<Track*>(i->track); // uncomment if needed Track* editable_property_track = const_cast<Track*>(i->_propertyTrack); Part* editable_part = const_cast<Part*>(i->part); @@ -503,13 +498,12 @@ void Song::doUndo2() } //--------------------------------------------------------- -// Song::doRedo2 +// Song::executeOperationGroup2 //--------------------------------------------------------- -void Song::doRedo2() +void Song::executeOperationGroup2(Undo& operations) { - Undo& u = redoList->back(); - for (iUndoOp i = u.begin(); i != u.end(); ++i) { + for (iUndoOp i = operations.begin(); i != operations.end(); ++i) { Track* editable_track = const_cast<Track*>(i->track); // uncomment if needed Track* editable_property_track = const_cast<Track*>(i->_propertyTrack); Part* editable_part = const_cast<Part*>(i->part); @@ -789,17 +783,14 @@ void Song::addUndo(UndoOp i) } //--------------------------------------------------------- -// doUndo1 +// revertOperationGroup1 // non realtime context // return true if nothing to do //--------------------------------------------------------- -bool Song::doUndo1() +void Song::revertOperationGroup1(Undo& operations) { - if (undoList->empty()) - return true; - Undo& u = undoList->back(); - for (riUndoOp i = u.rbegin(); i != u.rend(); ++i) { + for (riUndoOp i = operations.rbegin(); i != operations.rend(); ++i) { Track* editable_track = const_cast<Track*>(i->track); Track* editable_property_track = const_cast<Track*>(i->_propertyTrack); Part* editable_part = const_cast<Part*>(i->part); @@ -886,18 +877,17 @@ bool Song::doUndo1() break; } } - return false; + return; } //--------------------------------------------------------- -// doUndo3 +// revertOperationGroup3 // non realtime context //--------------------------------------------------------- -void Song::doUndo3() +void Song::revertOperationGroup3(Undo& operations) { - Undo& u = undoList->back(); - for (riUndoOp i = u.rbegin(); i != u.rend(); ++i) { + for (riUndoOp i = operations.rbegin(); i != operations.rend(); ++i) { Track* editable_track = const_cast<Track*>(i->track); // uncomment if needed Track* editable_property_track = const_cast<Track*>(i->_propertyTrack); // uncomment if needed Part* editable_part = const_cast<Part*>(i->part); @@ -926,23 +916,17 @@ void Song::doUndo3() break; } } - redoList->push_back(u); // put item on redo list - undoList->pop_back(); - emit sigDirty(); } //--------------------------------------------------------- -// doRedo1 +// executeOperationGroup1 // non realtime context // return true if nothing to do //--------------------------------------------------------- -bool Song::doRedo1() +void Song::executeOperationGroup1(Undo& operations) { - if (redoList->empty()) - return true; - Undo& u = redoList->back(); - for (iUndoOp i = u.begin(); i != u.end(); ++i) { + for (iUndoOp i = operations.begin(); i != operations.end(); ++i) { Track* editable_track = const_cast<Track*>(i->track); Track* editable_property_track = const_cast<Track*>(i->_propertyTrack); Part* editable_part = const_cast<Part*>(i->part); @@ -1025,18 +1009,16 @@ bool Song::doRedo1() break; } } - return false; } //--------------------------------------------------------- -// doRedo3 +// executeOperationGroup3 // non realtime context //--------------------------------------------------------- -void Song::doRedo3() +void Song::executeOperationGroup3(Undo& operations) { - Undo& u = redoList->back(); - for (iUndoOp i = u.begin(); i != u.end(); ++i) { + for (iUndoOp i = operations.begin(); i != operations.end(); ++i) { Track* editable_track = const_cast<Track*>(i->track); // uncomment if needed Track* editable_property_track = const_cast<Track*>(i->_propertyTrack); // uncomment if needed Part* editable_part = const_cast<Part*>(i->part); @@ -1064,9 +1046,6 @@ void Song::doRedo3() break; } } - undoList->push_back(u); // put item on undo list - redoList->pop_back(); - emit sigDirty(); } diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h index f0bf35fc..f27dbcc3 100644 --- a/muse2/muse/undo.h +++ b/muse2/muse/undo.h @@ -132,6 +132,8 @@ class Undo : public std::list<UndoOp> { typedef Undo::iterator iUndoOp; typedef Undo::reverse_iterator riUndoOp; +typedef Undo::const_iterator ciUndoOp; +typedef Undo::const_reverse_iterator criUndoOp; class UndoList : public std::list<Undo> { protected: |