summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse2/muse/arranger/pcanvas.cpp13
-rw-r--r--muse2/muse/part.h3
-rw-r--r--muse2/muse/remote/pyapi.cpp4
-rw-r--r--muse2/muse/song.cpp13
-rw-r--r--muse2/muse/song.h8
-rw-r--r--muse2/muse/songfile.cpp4
-rw-r--r--muse2/muse/undo.cpp58
-rw-r--r--muse2/muse/waveedit/wavecanvas.cpp1
8 files changed, 67 insertions, 37 deletions
diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp
index c3c3bcb8..a280d58b 100644
--- a/muse2/muse/arranger/pcanvas.cpp
+++ b/muse2/muse/arranger/pcanvas.cpp
@@ -353,7 +353,7 @@ bool PartCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint&
ntrack = tracks->size();
if (MusEGlobal::debugMsg)
printf("PartCanvas::moveItem - add new track\n");
- dtrack = MusEGlobal::song->addTrack(operations, type); // Add at end of list.
+ dtrack = MusEGlobal::song->addTrack(type); // Add at end of list. Creates additional Undo entry.
if (type == MusECore::Track::WAVE) {
MusECore::WaveTrack* st = (MusECore::WaveTrack*) track;
@@ -385,8 +385,7 @@ bool PartCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint&
MusECore::Part* dpart;
bool clone = (t == MOVE_CLONE || (t == MOVE_COPY && spart->hasClones()));
- // This increments aref count if cloned, and chains clones.
- // It also gives the new part a new serial number.
+ // Gives the new part a new serial number.
if (clone)
dpart = spart->createNewClone();
else
@@ -2756,13 +2755,9 @@ void PartCanvas::viewDropEvent(QDropEvent* event)
if (!track) { // we need to create a track for this drop
if (text.endsWith(".mpt", Qt::CaseInsensitive)) {
- MusECore::Undo operations;
- track = MusEGlobal::song->addTrack(operations, MusECore::Track::MIDI); // Add at end of list.
- MusEGlobal::song->applyOperationGroup(operations);
+ track = MusEGlobal::song->addTrack(MusECore::Track::MIDI); // Add at end of list.
} else {
- MusECore::Undo operations;
- track = MusEGlobal::song->addTrack(operations, MusECore::Track::WAVE); // Add at end of list.
- MusEGlobal::song->applyOperationGroup(operations);
+ track = MusEGlobal::song->addTrack(MusECore::Track::WAVE); // Add at end of list.
}
}
if (track->type() == MusECore::Track::WAVE &&
diff --git a/muse2/muse/part.h b/muse2/muse/part.h
index e579e64d..02056a2d 100644
--- a/muse2/muse/part.h
+++ b/muse2/muse/part.h
@@ -109,8 +109,9 @@ class Part : public PosLen {
bool isCloneOf(const Part*) const;
bool hasClones() const { return _prevClone!=this || _nextClone!=this; }
int nClones() const;
- Part* prevClone() const { return _prevClone; } // FINDMICHJETZT DELETETHIS 2x
+ Part* prevClone() const { return _prevClone; } // FINDMICHJETZT make it const Part*!
Part* nextClone() const { return _nextClone; }
+ Part* backupClone() const { return _backupClone; }
void unchainClone();
void chainClone(Part* p); // *this is made a sibling of p! p is not touched (except for its clone-chain), whereas this->events will get altered
diff --git a/muse2/muse/remote/pyapi.cpp b/muse2/muse/remote/pyapi.cpp
index 7d03e36b..8f5abe06 100644
--- a/muse2/muse/remote/pyapi.cpp
+++ b/muse2/muse/remote/pyapi.cpp
@@ -1131,9 +1131,7 @@ bool Song::event(QEvent* _e)
break;
}
case QPybridgeEvent::SONG_ADD_TRACK: {
- MusECore::Undo operations;
- MusEGlobal::song->addTrack(operations, (Track::TrackType)e->getP1()); // Add at end of list.
- MusEGlobal::song->applyOperationGroup(operations);
+ MusEGlobal::song->addTrack((Track::TrackType)e->getP1()); // Add at end of list.
break;
}
case QPybridgeEvent::SONG_CHANGE_TRACKNAME: {
diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp
index b6d866e1..3cf1960d 100644
--- a/muse2/muse/song.cpp
+++ b/muse2/muse/song.cpp
@@ -216,9 +216,7 @@ Track* Song::addNewTrack(QAction* action, Track* insertAt)
if((Track::TrackType)n >= Track::AUDIO_SOFTSYNTH)
return 0;
- Undo operations;
- Track* t = addTrack(operations, (Track::TrackType)n, insertAt);
- applyOperationGroup(operations);
+ Track* t = addTrack((Track::TrackType)n, insertAt);
if (t->isVisible()) {
deselectTracks();
t->setSelected(true);
@@ -236,7 +234,7 @@ Track* Song::addNewTrack(QAction* action, Track* insertAt)
// If insertAt is valid, inserts before insertAt. Else at the end after all tracks.
//---------------------------------------------------------
-Track* Song::addTrack(Undo& /*operations*/, Track::TrackType type, Track* insertAt)
+Track* Song::addTrack(Track::TrackType type, Track* insertAt)
{
Track* track = 0;
int lastAuxIdx = _auxs.size();
@@ -293,12 +291,9 @@ Track* Song::addTrack(Undo& /*operations*/, Track::TrackType type, Track* insert
int idx = insertAt ? _tracks.index(insertAt) : -1;
- insertTrack1(track, idx); // this and the below are replaced
- msgInsertTrack(track, idx, true); // by the UndoOp-operation
- insertTrack3(track, idx); // does nothing
- // No, can't do this. insertTrack2 needs to be called now, not later, otherwise it sees
+ // Apply it *now*. insertTrack2 needs to be called now, not later, otherwise it sees
// that the track may have routes, and reciprocates them, causing duplicate routes.
- ///operations.push_back(UndoOp(UndoOp::AddTrack, idx, track));
+ applyOperation(UndoOp(UndoOp::AddTrack, idx, track));
// Add default track <-> midiport routes.
if(track->isMidiTrack())
diff --git a/muse2/muse/song.h b/muse2/muse/song.h
index 6410084f..bc1aa9a1 100644
--- a/muse2/muse/song.h
+++ b/muse2/muse/song.h
@@ -171,7 +171,11 @@ class Song : public QObject {
Song(const char* name = 0);
~Song();
- bool applyOperationGroup(Undo& group, bool doUndo=true); // group may be changed! cleanOperationGroup is called on group!
+ /** It is not allowed nor checked(!) to AddPart a clone, and
+ * to AddEvent/DeleteEvent/ModifyEvent/SelectEvent events which
+ * would need to be replicated to the newly added clone part!
+ */
+ bool applyOperationGroup(Undo& group, bool doUndo=true); // group may be changed! prepareOperationGroup is called on group!
bool applyOperation(const UndoOp& op, bool doUndo=true);
/** this sends emits a signal to each MidiEditor or whoever is interested.
@@ -424,7 +428,7 @@ class Song : public QObject {
void setQuantize(bool val);
void panic();
void seqSignal(int fd);
- Track* addTrack(Undo& operations, Track::TrackType type, Track* insertAt = 0);
+ Track* addTrack(Track::TrackType type, Track* insertAt = 0);
Track* addNewTrack(QAction* action, Track* insertAt = 0);
void duplicateTracks();
QString getScriptPath(int id, bool delivered);
diff --git a/muse2/muse/songfile.cpp b/muse2/muse/songfile.cpp
index 9b52791a..680e4dcd 100644
--- a/muse2/muse/songfile.cpp
+++ b/muse2/muse/songfile.cpp
@@ -197,7 +197,7 @@ Part* Part::readFromXml(Xml& xml, Track* track, bool doClone, bool toTrack)
{
if(i->id == id) // Is a matching part found in the clone list?
{
- // This makes a clone, chains the part, and increases ref counts.
+ // Create a clone. It must still be added later in a operationgroup
npart = track->newPart((Part*)i->cp, true);
break;
}
@@ -242,7 +242,7 @@ Part* Part::readFromXml(Xml& xml, Track* track, bool doClone, bool toTrack)
if(!doClone && !isclone)
break;
- // This makes a clone, chains the part, and increases ref counts.
+ // Create a clone. It must still be added later in a operationgroup
npart = track->newPart((Part*)i->cp, true);
break;
}
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();
diff --git a/muse2/muse/waveedit/wavecanvas.cpp b/muse2/muse/waveedit/wavecanvas.cpp
index 0ba0bdbc..db886bce 100644
--- a/muse2/muse/waveedit/wavecanvas.cpp
+++ b/muse2/muse/waveedit/wavecanvas.cpp
@@ -1477,7 +1477,6 @@ void WaveCanvas::newItem(MusEGui::CItem* item, bool noSnap)
if (diff > 0)// part must be extended?
{
- //schedule_resize_all_same_len_clone_parts(part, event.endTick(), operations);
schedule_resize_all_same_len_clone_parts(part, event.endFrame(), operations);
printf("newItem: extending\n");
}