summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse2/muse/audio.cpp2
-rw-r--r--muse2/muse/audio.h9
-rw-r--r--muse2/muse/seqmsg.cpp39
-rw-r--r--muse2/muse/song.cpp34
-rw-r--r--muse2/muse/song.h14
-rw-r--r--muse2/muse/undo.cpp85
-rw-r--r--muse2/muse/undo.h2
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: