summaryrefslogtreecommitdiff
path: root/muse2/muse/undo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/muse/undo.cpp')
-rw-r--r--muse2/muse/undo.cpp58
1 files changed, 48 insertions, 10 deletions
diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp
index b5ee3cec..fdb24dad 100644
--- a/muse2/muse/undo.cpp
+++ b/muse2/muse/undo.cpp
@@ -274,12 +274,10 @@ void Song::setUndoRedoText()
}
-void cleanOperationGroup(Undo& group)
+void prepareOperationGroup(Undo& group)
{
- using std::set;
-
- set<const Track*> processed_tracks;
- set<const Part*> processed_parts;
+ QSet<const Track*> deleted_tracks;
+ QSet<const Part*> deleted_parts;
for (iUndoOp op=group.begin(); op!=group.end();)
{
@@ -288,21 +286,61 @@ void cleanOperationGroup(Undo& group)
if (op->type==UndoOp::DeleteTrack)
{
- if (processed_tracks.find(op->track)!=processed_tracks.end())
+ if (deleted_tracks.contains(op->track))
+ {
group.erase(op);
+ }
else
- processed_tracks.insert(op->track);
+ {
+ const PartList* pl = op->track->cparts();
+ for (ciPart part = pl->begin(); part != pl->end(); part++)
+ if (!deleted_parts.contains(part->second))
+ {
+ // they will be inserted between op and op_
+ // because we set op=op_ below, the inserted
+ // elements will be skipped.
+ group.insert(op, UndoOp(UndoOp::DeletePart, part->second));
+ deleted_parts.insert(part->second);
+ }
+
+ deleted_tracks.insert(op->track);
+ }
}
else if (op->type==UndoOp::DeletePart)
{
- if (processed_parts.find(op->part)!=processed_parts.end())
+ if (deleted_parts.contains(op->part))
group.erase(op);
else
- processed_parts.insert(op->part);
+ deleted_parts.insert(op->part);
}
op=op_;
}
+
+ // replicate Event modifications to keep clones up to date
+ for (iUndoOp op=group.begin(); op!=group.end(); op++)
+ {
+ if (op->type==UndoOp::AddEvent || op->type==UndoOp::DeleteEvent || op->type==UndoOp::ModifyEvent || op->type==UndoOp::SelectEvent)
+ {
+ for (const Part* it = op->part->nextClone(); it!=op->part; it=it->nextClone())
+ {
+ UndoOp newop;
+ if (op->type==UndoOp::AddEvent) // we need to clone the event
+ newop = UndoOp(UndoOp::AddEvent, op->nEvent.clone(), it, op->doCtrls, op->doClones);
+ else if (op->type==UndoOp::DeleteEvent)
+ newop = UndoOp(UndoOp::DeleteEvent, it->events().findSimilar(op->nEvent)->second, it, op->doCtrls, op->doClones);
+ else if (op->type==UndoOp::ModifyEvent)
+ newop = UndoOp(UndoOp::ModifyEvent, op->nEvent.clone(), it->events().findSimilar(op->oEvent)->second, it, op->doCtrls, op->doClones);
+ else if (op->type==UndoOp::SelectEvent)
+ {
+ const Event& found = it->events().findSimilar(op->nEvent)->second;
+ newop= UndoOp(UndoOp::SelectEvent, found, op->selected, found.selected());
+ }
+
+ group.insert(op, newop);
+ }
+ }
+ }
}
bool Song::applyOperation(const UndoOp& op, bool doUndo)
@@ -316,7 +354,7 @@ bool Song::applyOperationGroup(Undo& group, bool doUndo)
{
if (!group.empty())
{
- cleanOperationGroup(group);
+ prepareOperationGroup(group);
//this is a HACK! but it works :) (added by flo93)
redoList->push_back(group);
redo();