diff options
-rw-r--r-- | muse2/muse/arranger/arrangerview.cpp | 4 | ||||
-rw-r--r-- | muse2/muse/arranger/pcanvas.cpp | 9 | ||||
-rw-r--r-- | muse2/muse/arranger/tlist.cpp | 23 | ||||
-rw-r--r-- | muse2/muse/audio.cpp | 6 | ||||
-rw-r--r-- | muse2/muse/audio.h | 26 | ||||
-rw-r--r-- | muse2/muse/functions.cpp | 79 | ||||
-rw-r--r-- | muse2/muse/functions.h | 3 | ||||
-rw-r--r-- | muse2/muse/midiedit/dcanvas.cpp | 11 | ||||
-rw-r--r-- | muse2/muse/mixer/strip.cpp | 6 | ||||
-rw-r--r-- | muse2/muse/part.cpp | 156 | ||||
-rw-r--r-- | muse2/muse/seqmsg.cpp | 119 | ||||
-rw-r--r-- | muse2/muse/song.cpp | 217 | ||||
-rw-r--r-- | muse2/muse/song.h | 33 | ||||
-rw-r--r-- | muse2/muse/synth.cpp | 6 | ||||
-rw-r--r-- | muse2/muse/wave.cpp | 5 |
15 files changed, 159 insertions, 544 deletions
diff --git a/muse2/muse/arranger/arrangerview.cpp b/muse2/muse/arranger/arrangerview.cpp index 7974369a..ecedd968 100644 --- a/muse2/muse/arranger/arrangerview.cpp +++ b/muse2/muse/arranger/arrangerview.cpp @@ -519,14 +519,14 @@ void ArrangerView::cmd(int cmd) arranger->cmd(Arranger::CMD_INSERT_EMPTYMEAS); break; case CMD_DELETE: - if (!MusEGlobal::song->msgRemoveParts()) //automatically does undo if neccessary and returns true then + if (!MusECore::delete_selected_parts()) { QMessageBox::StandardButton btn = QMessageBox::warning( this,tr("Remove track(s)"),tr("Are you sure you want to remove this track(s)?"), QMessageBox::Ok|QMessageBox::Cancel, QMessageBox::Ok); if (btn == QMessageBox::Cancel) - break; //msgRemoveParts() returned false -> no parts to remove? + break; MusEGlobal::song->startUndo(); MusEGlobal::audio->msgRemoveTracks(); //TODO FINDME this could still be speeded up! MusEGlobal::song->endUndo(SC_TRACK_REMOVED); diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index a280d58b..57645a97 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -668,12 +668,11 @@ bool PartCanvas::deleteItem(CItem* i) void PartCanvas::splitItem(CItem* item, const QPoint& pt) { NPart* np = (NPart*) item; - MusECore::Track* t = np->track(); MusECore::Part* p = np->part(); int x = pt.x(); if (x < 0) x = 0; - MusEGlobal::song->cmdSplitPart(t, p, AL::sigmap.raster(x, *_raster)); + split_part(p,AL::sigmap.raster(x, *_raster)); } //--------------------------------------------------------- @@ -683,9 +682,7 @@ void PartCanvas::splitItem(CItem* item, const QPoint& pt) void PartCanvas::glueItem(CItem* item) { NPart* np = (NPart*) item; - MusECore::Track* t = np->track(); - MusECore::Part* p = np->part(); - MusEGlobal::song->cmdGluePart(t, p); + merge_with_next_part(np->part()); } //--------------------------------------------------------- @@ -1116,7 +1113,7 @@ void PartCanvas::keyPress(QKeyEvent* event) if (getCurrentDrag()) return; - MusEGlobal::song->msgRemoveParts(); + MusECore::delete_selected_parts(); return; } else if (key == shortcuts[SHRT_POS_DEC].key) { diff --git a/muse2/muse/arranger/tlist.cpp b/muse2/muse/arranger/tlist.cpp index b27a48e1..7ebcad4d 100644 --- a/muse2/muse/arranger/tlist.cpp +++ b/muse2/muse/arranger/tlist.cpp @@ -75,6 +75,8 @@ #include "dssihost.h" #endif +using MusECore::UndoOp; + namespace MusEGui { static const int MIN_TRACKHEIGHT = 20; @@ -599,13 +601,10 @@ void TList::returnPressed() } } - MusEGlobal::song->startUndo(); - MusEGlobal::song->addUndo(MusECore::UndoOp(MusECore::UndoOp::ModifyTrackName, + MusEGlobal::song->applyOperation(MusECore::UndoOp(MusECore::UndoOp::ModifyTrackName, editTrack, editTrack->name().toLatin1().constData(), editor->text().toLatin1().constData())); - editTrack->setName(editor->text()); - MusEGlobal::song->endUndo(-1); //uagh, why "-1", why no proper flags? } } @@ -640,16 +639,10 @@ void TList::chanValueFinished() channel = 0; if(channel != mt->outChannel()) { - MusEGlobal::song->startUndo(); - MusEGlobal::song->addUndo(MusECore::UndoOp(MusECore::UndoOp::ModifyTrackChannel, + MusEGlobal::song->applyOperation(MusECore::UndoOp(MusECore::UndoOp::ModifyTrackChannel, editTrack, mt->outChannel(), channel)); - MusEGlobal::audio->msgIdle(true); - mt->setOutChanAndUpdate(channel); - MusEGlobal::audio->msgIdle(false); - MusEGlobal::audio->msgUpdateSoloStates(); - MusEGlobal::song->endUndo(SC_MIDI_TRACK_PROP); } } } @@ -667,13 +660,10 @@ void TList::chanValueFinished() n = 1; if(n != at->channels()) { - MusEGlobal::song->startUndo(); - MusEGlobal::song->addUndo(MusECore::UndoOp(MusECore::UndoOp::ModifyTrackChannel, + MusEGlobal::song->applyOperation(MusECore::UndoOp(MusECore::UndoOp::ModifyTrackChannel, editTrack, at->channels(), n)); - MusEGlobal::audio->msgSetChannels(at, n); - MusEGlobal::song->endUndo(SC_CHANNELS); } } } @@ -1962,8 +1952,7 @@ void TList::mousePressEvent(QMouseEvent* ev) { switch (n) { case 1001: // delete track - MusEGlobal::song->removeTrack0(t); - MusEGlobal::audio->msgUpdateSoloStates(); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::DeleteTrack, MusEGlobal::song->tracks()->index(t), t)); break; case 1002: // show track comment diff --git a/muse2/muse/audio.cpp b/muse2/muse/audio.cpp index f7caa6a0..f399a24c 100644 --- a/muse2/muse/audio.cpp +++ b/muse2/muse/audio.cpp @@ -76,12 +76,8 @@ void initAudio() extern double curTime(); const char* seqMsgList[] = { - "SEQM_ADD_TRACK", "SEQM_REMOVE_TRACK", - "SEQM_MOVE_TRACK", - "SEQM_ADD_PART", "SEQM_REMOVE_PART", - "SEQM_ADD_EVENT", "SEQM_REMOVE_EVENT", "SEQM_CHANGE_EVENT", "SEQM_ADD_TEMPO", "SEQM_SET_TEMPO", "SEQM_REMOVE_TEMPO", "SEQM_ADD_SIG", "SEQM_REMOVE_SIG", - "SEQM_ADD_KEY", "SEQM_REMOVE_KEY", + "SEQM_ADD_KEY", "SEQM_REMOVE_KEY", "SEQM_SET_GLOBAL_TEMPO", "SEQM_REVERT_OPERATION_GROUP", "SEQM_EXECUTE_OPERATION_GROUP", "SEQM_RESET_DEVICES", "SEQM_INIT_DEVICES", "SEQM_PANIC", diff --git a/muse2/muse/audio.h b/muse2/muse/audio.h index 044760ac..e1a90485 100644 --- a/muse2/muse/audio.h +++ b/muse2/muse/audio.h @@ -61,10 +61,6 @@ class Undo; //--------------------------------------------------------- enum { - SEQM_ADD_TRACK, SEQM_REMOVE_TRACK, - SEQM_MOVE_TRACK, - SEQM_ADD_PART, SEQM_REMOVE_PART, - SEQM_ADD_EVENT, SEQM_REMOVE_EVENT, SEQM_CHANGE_EVENT, 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, @@ -226,18 +222,18 @@ class Audio { 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); - void msgAddPart(Part*, bool u = true); - void msgRemovePart(Part*, bool u = true); - void msgAddEvent(Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false); - void msgDeleteEvent(Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false); - void msgChangeEvent(Event&, Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false); - void msgAddTempo(int tick, int tempo, bool doUndoFlag = true); - void msgSetTempo(int tick, int tempo, bool doUndoFlag = true); - void msgDeleteTempo(int tick, int tempo, bool doUndoFlag = true); - void msgUpdateSoloStates(); + void msgRemoveTrack(Track*, bool u = true); // only does applyOperation + void msgMoveTrack(int idx1, int dx2, bool u = true); // only does applyOperation + void msgAddPart(Part*, bool u = true); // only does applyOperation + void msgRemovePart(Part*, bool u = true); // only does applyOperation + void msgAddEvent(Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false); // only does applyOperation + void msgDeleteEvent(Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false); // only does applyOperation + void msgChangeEvent(Event&, Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false); // only does applyOperation + void msgAddTempo(int tick, int tempo, bool doUndoFlag = true); // only does applyOperation + void msgSetTempo(int tick, int tempo, bool doUndoFlag = true); // FIXME FINDMICHJETZT TODO! + void msgDeleteTempo(int tick, int tempo, bool doUndoFlag = true); // only does applyOperation + void msgUpdateSoloStates(); // TODO and below void msgSetAux(AudioTrack*, int, double); void msgSetGlobalTempo(int val); void msgAddSig(int tick, int z, int n, bool doUndoFlag = true); diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp index 380d9718..f13736b9 100644 --- a/muse2/muse/functions.cpp +++ b/muse2/muse/functions.cpp @@ -1422,6 +1422,40 @@ void clean_parts() MusEGlobal::song->applyOperationGroup(operations); } + +bool merge_with_next_part(const Part* oPart) +{ + const Track* track = oPart->track(); + + if(track->type() != Track::WAVE && !track->isMidiTrack()) + return false; + + const PartList* pl = track->cparts(); + const Part* nextPart = 0; + + for (ciPart ip = pl->begin(); ip != pl->end(); ++ip) + { + if (ip->second == oPart) + { + ++ip; + if (ip == pl->end()) + return false; + nextPart = ip->second; + break; + } + } + + if (nextPart) + { + set<const Part*> parts; + parts.insert(oPart); + parts.insert(nextPart); + return merge_parts(parts); + } + else + return false; +} + bool merge_selected_parts() { set<const Part*> temp = get_all_selected_parts(); @@ -1494,4 +1528,49 @@ bool merge_parts(const set<const Part*>& parts) return MusEGlobal::song->applyOperationGroup(operations); } +bool split_part(const Part* part, int tick) +{ + int l1 = tick - part->tick(); + int l2 = part->lenTick() - l1; + if (l1 <= 0 || l2 <= 0) + return false; + Part* p1; + Part* p2; + part->splitPart(tick, p1, p2); + + MusEGlobal::song->informAboutNewParts(part, p1); + MusEGlobal::song->informAboutNewParts(part, p2); + + Undo operations; + operations.push_back(UndoOp(UndoOp::DeletePart, part)); + operations.push_back(UndoOp(UndoOp::AddPart, p1)); + operations.push_back(UndoOp(UndoOp::AddPart, p2)); + return MusEGlobal::song->applyOperationGroup(operations); +} + +bool delete_selected_parts() +{ + Undo operations; + bool partSelected = false; + + TrackList* tl = MusEGlobal::song->tracks(); + + for (iTrack it = tl->begin(); it != tl->end(); ++it) + { + PartList* pl = (*it)->parts(); + for (iPart ip = pl->begin(); ip != pl->end(); ++ip) + { + if (ip->second->selected()) + { + operations.push_back(UndoOp(UndoOp::DeletePart,ip->second)); + partSelected = true; + } + } + } + + MusEGlobal::song->applyOperationGroup(operations); + + return partSelected; +} + } // namespace MusECore diff --git a/muse2/muse/functions.h b/muse2/muse/functions.h index 9493caf7..28e178da 100644 --- a/muse2/muse/functions.h +++ b/muse2/muse/functions.h @@ -105,8 +105,11 @@ void shrink_parts(int raster=-1); //negative values mean "config.division" void expand_parts(int raster=-1); void schedule_resize_all_same_len_clone_parts(const Part* part, unsigned new_len, Undo& operations); void clean_parts(); +bool merge_with_next_part(const Part* part); bool merge_selected_parts(); bool merge_parts(const std::set<const Part*>& parts); +bool split_part(const Part* part, int tick); +bool delete_selected_parts(); // internal QMimeData* file_to_mimedata(FILE *datafile, QString mimeType); diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index 893694c3..ba18d8a3 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -1212,8 +1212,7 @@ void DrumCanvas::resizeEvent(QResizeEvent* ev) void DrumCanvas::modifySelected(NoteInfo::ValType type, int val, bool delta_mode) { QList< QPair<int,MusECore::Event> > already_done; - MusEGlobal::audio->msgIdle(true); - MusEGlobal::song->startUndo(); + MusECore::Undo operations; for (iCItem i = items.begin(); i != items.end(); ++i) { if (!(i->second->isSelected())) continue; @@ -1302,14 +1301,12 @@ void DrumCanvas::modifySelected(NoteInfo::ValType type, int val, bool delta_mode } break; } - MusEGlobal::song->changeEvent(event, newEvent, part); - // Indicate do not do port controller values and clone parts. - MusEGlobal::song->addUndo(MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part, false, false)); + + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part, false, false)); already_done.append(QPair<int,MusECore::Event>(part->clonemaster_sn(), event)); } - MusEGlobal::song->endUndo(SC_EVENT_MODIFIED); - MusEGlobal::audio->msgIdle(false); + MusEGlobal::song->applyOperationGroup(operations); } //--------------------------------------------------------- diff --git a/muse2/muse/mixer/strip.cpp b/muse2/muse/mixer/strip.cpp index 06ee9443..cf4be792 100644 --- a/muse2/muse/mixer/strip.cpp +++ b/muse2/muse/mixer/strip.cpp @@ -42,6 +42,9 @@ #include "meter.h" #include "utils.h" #include "icons.h" +#include "undo.h" + +using MusECore::UndoOp; namespace MusEGui { @@ -340,8 +343,7 @@ void Strip::mousePressEvent(QMouseEvent* ev) QFrame::mousePressEvent(ev); return; } - MusEGlobal::song->removeTrack0(track); - MusEGlobal::audio->msgUpdateSoloStates(); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::DeleteTrack, MusEGlobal::song->tracks()->index(track), track)); ev->accept(); return; } diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index c46e7ab9..82427d28 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -609,59 +609,24 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo switch(track->type()) { case Track::WAVE: { - // TODO FINDMICH FIXME this is totally broken. we don't want to remove events just because they're beyond end-of-part. - // we also don't want to auto-resize the last event. + Undo operations; + + unsigned orig_len=oPart->lenFrame(); + WavePart* part_it=(WavePart*)oPart; + do + { + if (part_it->lenFrame()==orig_len) + { + // Do port controller values but not clone parts. + operations.push_back(UndoOp(UndoOp::ModifyPartLengthFrames, part_it, part_it->lenFrame(), len, true, false)); + } + + part_it=(WavePart*)part_it->nextClone(); + } while (doClones && (part_it != (WavePart*)oPart)); - /* - MusECore::WavePart* nPart = new MusECore::WavePart(*(MusECore::WavePart*)oPart); - EventList* el = nPart->events(); - unsigned new_partlength = MusEGlobal::tempomap.deltaTick2frame(oPart->tick(), oPart->tick() + len); - - // If new nr of frames is less than previous what can happen is: - // - 0 or more events are beginning after the new final position. Those are removed from the part - // - The last event begins before new final position and ends after it. If so, it will be resized to end at new part length - if (new_partlength < oPart->lenFrame()) { - Undo operations; - - for (iEvent i = el->begin(); i != el->end(); i++) { - Event e = i->second; - unsigned event_startframe = e.frame(); - unsigned event_endframe = event_startframe + e.lenFrame(); - if (event_endframe < new_partlength) - continue; - } - nPart->setLenFrame(new_partlength); - // Do not do port controller values and clone parts. - operations.push_back(UndoOp(UndoOp::Modify***Part, oPart, nPart, false, false)); - - MusEGlobal::song->applyOperationGroup(operations); - } - // If the part is expanded there can be no additional events beginning after the previous final position - // since those are removed if the part has been shrunk at some time (see above) - // The only thing we need to check is the final event: If it has data after the previous final position, - // we'll expand that event - else { - Undo operations; - if(!el->empty()) - { - iEvent i = el->end(); - i--; - Event last = i->second; - MusECore::SndFileR file = last.sndFile(); - if (file.isNull()) - return; - Event newEvent = last.clone(); - // Do not do port controller values and clone parts. - operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, last, nPart, false, false)); - } - - nPart->setLenFrame(new_partlength); - // Do not do port controller values and clone parts. - operations.push_back(UndoOp(UndoOp::Modify***Part, oPart, nPart, false, false)); - MusEGlobal::song->applyOperationGroup(operations); - } */ - } + MusEGlobal::song->applyOperationGroup(operations); break; + } case Track::MIDI: case Track::DRUM: case Track::NEW_DRUM: @@ -775,95 +740,6 @@ void Part::splitPart(int tickpos, Part*& p1, Part*& p2) const } } -//--------------------------------------------------------- -// cmdSplitPart -//--------------------------------------------------------- - -void Song::cmdSplitPart(Track* track, Part* part, int tick) - { - int l1 = tick - part->tick(); - int l2 = part->lenTick() - l1; - if (l1 <= 0 || l2 <= 0) - return; - Part* p1; - Part* p2; - part->splitPart(tick, p1, p2); - - MusEGlobal::song->informAboutNewParts(part, p1); - MusEGlobal::song->informAboutNewParts(part, p2); - - Undo operations; - operations.push_back(UndoOp(UndoOp::DeletePart, part)); - operations.push_back(UndoOp(UndoOp::AddPart, p1)); - operations.push_back(UndoOp(UndoOp::AddPart, p2)); - applyOperationGroup(operations); - } - - -//--------------------------------------------------------- -// cmdGluePart -//--------------------------------------------------------- - -void Song::cmdGluePart(Track* track, Part* oPart) - { /* disabled for now, to be deleted - // p3.3.54 - if(track->type() != Track::WAVE && !track->isMidiTrack()) - return; - - PartList* pl = track->parts(); - Part* nextPart = 0; - - for (iPart ip = pl->begin(); ip != pl->end(); ++ip) { - if (ip->second == oPart) { - ++ip; - if (ip == pl->end()) - return; - nextPart = ip->second; - break; - } - } - - Part* nPart = track->newPart(oPart); - nPart->setLenTick(nextPart->tick() + nextPart->lenTick() - oPart->tick()); - - // populate nPart with Events from oPart and nextPart - - EventList* sl1 = oPart->events(); - EventList* dl = nPart->events(); - - for (iEvent ie = sl1->begin(); ie != sl1->end(); ++ie) - dl->add(ie->second); - - EventList* sl2 = nextPart->events(); - - if(track->type() == Track::WAVE) - { - int frameOffset = nextPart->frame() - oPart->frame(); - for (iEvent ie = sl2->begin(); ie != sl2->end(); ++ie) - { - Event event = ie->second.clone(); - event.setFrame(event.frame() + frameOffset); - dl->add(event); - } - } - else - if(track->isMidiTrack()) - { - int tickOffset = nextPart->tick() - oPart->tick(); - for (iEvent ie = sl2->begin(); ie != sl2->end(); ++ie) - { - Event event = ie->second.clone(); - event.setTick(event.tick() + tickOffset); - dl->add(event); - } - } - - startUndo(); - MusEGlobal::audio->msgRemovePart(nextPart, false); - // Indicate no undo, and do port controller values but not clone parts. - MusEGlobal::audio->msgChange***Part(oPart, nPart, false, true, false); - endUndo(SC_PART_MODIFIED | SC_PART_REMOVED); */ - } //--------------------------------------------------------- // dump diff --git a/muse2/muse/seqmsg.cpp b/muse2/muse/seqmsg.cpp index 3b914fda..3dca4d44 100644 --- a/muse2/muse/seqmsg.cpp +++ b/muse2/muse/seqmsg.cpp @@ -661,24 +661,7 @@ void Audio::msgPlay(bool val) } } -//--------------------------------------------------------- -// msgAddTrack -//--------------------------------------------------------- -void Song::msgInsertTrack(Track* track, int idx, bool doUndoFlag) - { - AudioMsg msg; - msg.id = SEQM_ADD_TRACK; - msg.track = track; - msg.ival = idx; - if (doUndoFlag) { - MusEGlobal::song->startUndo(); - addUndo(UndoOp(UndoOp::AddTrack, idx, track)); - } - MusEGlobal::audio->sendMsg(&msg); - if (doUndoFlag) - endUndo(SC_TRACK_INSERTED); - } //--------------------------------------------------------- // msgRemoveTrack @@ -686,10 +669,7 @@ void Song::msgInsertTrack(Track* track, int idx, bool doUndoFlag) void Audio::msgRemoveTrack(Track* track, bool doUndoFlag) { - AudioMsg msg; - msg.id = SEQM_REMOVE_TRACK; - msg.track = track; - sendMessage(&msg, doUndoFlag); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::DeleteTrack, MusEGlobal::song->tracks()->index(track), track)); } //--------------------------------------------------------- @@ -749,23 +729,6 @@ void Audio::msgRemoveTracks() } -/* DELETETHIS 18 -//--------------------------------------------------------- -// msgChangeTrack -// oldTrack - copy of the original track befor modification -// newTrack - modified original track -//--------------------------------------------------------- - -void Audio::msgChangeTrack(Track* oldTrack, Track* newTrack, bool doUndoFlag) - { - AudioMsg msg; - msg.id = SEQM_CHANGE_TRACK; - msg.p1 = oldTrack; - msg.p2 = newTrack; - sendMessage(&msg, doUndoFlag); - } -*/ - //--------------------------------------------------------- // msgMoveTrack // move track idx1 to slot idx2 @@ -778,11 +741,7 @@ void Audio::msgMoveTrack(int idx1, int idx2, bool doUndoFlag) int n = MusEGlobal::song->tracks()->size(); if (idx1 >= n || idx2 >= n) // sanity check return; - AudioMsg msg; - msg.id = SEQM_MOVE_TRACK; - msg.a = idx1; - msg.b = idx2; - sendMessage(&msg, doUndoFlag); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::SwapTrack, idx1, idx2), doUndoFlag); } //--------------------------------------------------------- @@ -791,10 +750,7 @@ void Audio::msgMoveTrack(int idx1, int idx2, bool doUndoFlag) void Audio::msgAddPart(Part* part, bool doUndoFlag) { - AudioMsg msg; - msg.id = SEQM_ADD_PART; - msg.p1 = part; - sendMessage(&msg, doUndoFlag); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::AddPart, part), doUndoFlag); } //--------------------------------------------------------- @@ -803,39 +759,9 @@ void Audio::msgAddPart(Part* part, bool doUndoFlag) void Audio::msgRemovePart(Part* part, bool doUndoFlag) { - AudioMsg msg; - msg.id = SEQM_REMOVE_PART; - msg.p1 = part; - sendMessage(&msg, doUndoFlag); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::DeletePart, part), doUndoFlag); } -//--------------------------------------------------------- -// msgRemoveParts -// remove selected parts; return true if any part was -// removed -//--------------------------------------------------------- - -bool Song::msgRemoveParts() - { - Undo operations; - bool partSelected = false; - - TrackList* tl = MusEGlobal::song->tracks(); - - for (iTrack it = tl->begin(); it != tl->end(); ++it) { - PartList* pl = (*it)->parts(); - for (iPart ip = pl->begin(); ip != pl->end(); ++ip) { - if (ip->second->selected()) { - operations.push_back(UndoOp(UndoOp::DeletePart,ip->second)); - partSelected = true; - } - } - } - - MusEGlobal::song->applyOperationGroup(operations); - - return partSelected; - } //--------------------------------------------------------- // msgAddEvent @@ -843,13 +769,7 @@ bool Song::msgRemoveParts() void Audio::msgAddEvent(Event& event, Part* part, bool doUndoFlag, bool doCtrls, bool doClones) { - AudioMsg msg; - msg.id = SEQM_ADD_EVENT; - msg.ev1 = event; - msg.p2 = part; - msg.a = doCtrls; - msg.b = doClones; - sendMessage(&msg, doUndoFlag); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::AddEvent, event,part, doCtrls, doClones), doUndoFlag); } //--------------------------------------------------------- @@ -858,13 +778,7 @@ void Audio::msgAddEvent(Event& event, Part* part, bool doUndoFlag, bool doCtrls, void Audio::msgDeleteEvent(Event& event, Part* part, bool doUndoFlag, bool doCtrls, bool doClones) { - AudioMsg msg; - msg.id = SEQM_REMOVE_EVENT; - msg.ev1 = event; - msg.p2 = part; - msg.a = doCtrls; - msg.b = doClones; - sendMessage(&msg, doUndoFlag); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::DeleteEvent, event,part, doCtrls, doClones), doUndoFlag); } //--------------------------------------------------------- @@ -873,14 +787,7 @@ void Audio::msgDeleteEvent(Event& event, Part* part, bool doUndoFlag, bool doCtr void Audio::msgChangeEvent(Event& oe, Event& ne, Part* part, bool doUndoFlag, bool doCtrls, bool doClones) { - AudioMsg msg; - msg.id = SEQM_CHANGE_EVENT; - msg.ev1 = oe; - msg.ev2 = ne; - msg.p3 = part; - msg.a = doCtrls; - msg.b = doClones; - sendMessage(&msg, doUndoFlag); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::ModifyEvent, ne,oe, part, doCtrls, doClones), doUndoFlag); } //--------------------------------------------------------- @@ -889,11 +796,7 @@ void Audio::msgChangeEvent(Event& oe, Event& ne, Part* part, bool doUndoFlag, bo void Audio::msgAddTempo(int tick, int tempo, bool doUndoFlag) { - AudioMsg msg; - msg.id = SEQM_ADD_TEMPO; - msg.a = tick; - msg.b = tempo; - sendMessage(&msg, doUndoFlag); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::AddTempo, tick, tempo), doUndoFlag); } //--------------------------------------------------------- @@ -927,11 +830,7 @@ void Audio::msgSetGlobalTempo(int val) void Audio::msgDeleteTempo(int tick, int tempo, bool doUndoFlag) { - AudioMsg msg; - msg.id = SEQM_REMOVE_TEMPO; - msg.a = tick; - msg.b = tempo; - sendMessage(&msg, doUndoFlag); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::DeleteTempo, tick, tempo), doUndoFlag); } //--------------------------------------------------------- diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index e18dfc01..7e6c08d0 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -434,7 +434,8 @@ void Song::duplicateTracks() QString track_name; int idx; int trackno = tl.size(); - MusEGlobal::song->startUndo(); + + Undo operations; for(TrackList::reverse_iterator it = tl.rbegin(); it != tl.rend(); ++it) { Track* track = *it; @@ -444,114 +445,23 @@ void Song::duplicateTracks() for(int cp = 0; cp < copies; ++cp) { - // There are two ways to copy a track now. Using the copy constructor or using new + assign(). - // Tested: Both ways seem OK. Prefer copy constructors for simplicity. But new + assign() may be - // required for fine-grained control over initializing various track types. - // - - // Set to 0 to use the copy constructor. Set to 1 to use new + assign(). - // DELETETHIS is this still necessary to keep around? - // also consider removing and adding a hint to a revision number instead - #if 0 - - Track* new_track = 0; - int lastAuxIdx = _auxs.size(); - switch(track->type()) - { - case Track::AUDIO_SOFTSYNTH: // TODO: Handle synths. p4.0.47 - // ((AudioTrack*)new_track)->addAuxSend(lastAuxIdx); DELETETHIS? - break; - - case Track::MIDI: - new_track = new MidiTrack(); - new_track->setType(Track::MIDI); - break; - case Track::DRUM: - new_track = new MidiTrack(); - new_track->setType(Track::DRUM); - //((MidiTrack*)new_track)->setOutChannel(9); DELETETHIS? - break; - case Track::WAVE: - new_track = new MusECore::WaveTrack(); - //((AudioTrack*)new_track)->addAuxSend(lastAuxIdx); DELETETHIS? - break; - case Track::AUDIO_OUTPUT: - new_track = new AudioOutput(); - break; - case Track::AUDIO_GROUP: - new_track = new AudioGroup(); - //((AudioTrack*)new_track)->addAuxSend(lastAuxIdx); DELETETHIS? - break; - case Track::AUDIO_AUX: - new_track = new AudioAux(); - break; - case Track::AUDIO_INPUT: - new_track = new AudioInput(); - //((AudioTrack*)new_track)->addAuxSend(lastAuxIdx); DELETETHIS? - break; - default: - printf("Song::duplicateTracks: Illegal type %d\n", track->type()); - break; - } - - if(new_track) - { - new_track->assign(*track, flags); - #else - { Track* new_track = track->clone(flags); - #endif //new_track->setDefaultName(track_name); // Handled in class now. idx = trackno + cp; - insertTrack1(new_track, idx); - addUndo(MusECore::UndoOp(MusECore::UndoOp::AddTrack, idx, new_track)); - msgInsertTrack(new_track, idx, false); // No undo. - insertTrack3(new_track, idx); - } + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddTrack, idx, new_track)); } } --trackno; } - MusECore::SongChangedFlags_t update_flags = SC_TRACK_INSERTED; - if(flags & (Track::ASSIGN_ROUTES | Track::ASSIGN_DEFAULT_ROUTES)) - update_flags |= SC_ROUTE; - MusEGlobal::song->endUndo(update_flags); + MusEGlobal::song->applyOperationGroup(operations); MusEGlobal::audio->msgUpdateSoloStates(); } -//--------------------------------------------------------- -// cmdRemoveTrack -//--------------------------------------------------------- -void Song::cmdRemoveTrack(Track* track) - { - int idx = _tracks.index(track); - addUndo(UndoOp(UndoOp::DeleteTrack, idx, track)); - removeTrack2(track); - updateFlags |= SC_TRACK_REMOVED; - } -//--------------------------------------------------------- -// removeMarkedTracks -//--------------------------------------------------------- - -void Song::removeMarkedTracks() - { - bool loop; - do { - loop = false; - for (iTrack t = _tracks.begin(); t != _tracks.end(); ++t) { - if ((*t)->selected()) { - removeTrack2(*t); - loop = true; - break; - } - } - } while (loop); - } //--------------------------------------------------------- // deselectTracks @@ -753,16 +663,6 @@ void Song::changeAllPortDrumCtrlEvents(bool add, bool drumonly) } } -void Song::addACEvent(AudioTrack* t, int acid, int frame, double val) -{ - MusEGlobal::audio->msgAddACEvent(t, acid, frame, val); -} - -void Song::changeACEvent(AudioTrack* t, int acid, int frame, int newFrame, double val) -{ - MusEGlobal::audio->msgChangeACEvent(t, acid, frame, newFrame, val); -} - //--------------------------------------------------------- // cmdAddRecordedEvents // add recorded Events into part @@ -1368,23 +1268,6 @@ void Song::updatePos() } //--------------------------------------------------------- -// setChannelMute -// mute all midi tracks associated with channel -//--------------------------------------------------------- - -void Song::setChannelMute(int channel, bool val) - { - for (iTrack i = _tracks.begin(); i != _tracks.end(); ++i) { - MidiTrack* track = dynamic_cast<MidiTrack*>(*i); - if (track == 0) - continue; - if (track->outChannel() == channel) - track->setMute(val); - } - emit songChanged(SC_MUTE); - } - -//--------------------------------------------------------- // len //--------------------------------------------------------- @@ -1822,63 +1705,8 @@ void Song::processMsg(AudioMsg* msg) case SEQM_REVERT_OPERATION_GROUP: revertOperationGroup2(*msg->operations); break; - case SEQM_MOVE_TRACK: - if (msg->a > msg->b) { - for (int i = msg->a; i > msg->b; --i) { - swapTracks(i, i-1); - } - } - else { - for (int i = msg->a; i < msg->b; ++i) { - swapTracks(i, i+1); - } - } - updateFlags = SC_TRACK_MODIFIED; - break; - case SEQM_ADD_EVENT: - updateFlags = SC_EVENT_INSERTED; - if (addEvent(msg->ev1, (MidiPart*)msg->p2)) { - addUndo(UndoOp(UndoOp::AddEvent, msg->ev1, (Part*)msg->p2, msg->a, msg->b)); - } - else - updateFlags = 0; - if(msg->a) - addPortCtrlEvents(msg->ev1, (Part*)msg->p2, msg->b); - break; - case SEQM_REMOVE_EVENT: - { - Event event = msg->ev1; - MidiPart* part = (MidiPart*)msg->p2; - if(msg->a) - removePortCtrlEvents(event, part, msg->b); - addUndo(UndoOp(UndoOp::DeleteEvent, event, (Part*)part, msg->a, msg->b)); - deleteEvent(event, part); - updateFlags = SC_EVENT_REMOVED; - } - break; - case SEQM_CHANGE_EVENT: - if(msg->a) - removePortCtrlEvents(msg->ev1, (MidiPart*)msg->p3, msg->b); - changeEvent(msg->ev1, msg->ev2, (MidiPart*)msg->p3); - if(msg->a) - addPortCtrlEvents(msg->ev2, (Part*)msg->p3, msg->b); - addUndo(UndoOp(UndoOp::ModifyEvent, msg->ev2, msg->ev1, (Part*)msg->p3, msg->a, msg->b)); - updateFlags = SC_EVENT_MODIFIED; - break; - - case SEQM_ADD_TRACK: - insertTrack2(msg->track, msg->ival); - break; - case SEQM_REMOVE_TRACK: - cmdRemoveTrack(msg->track); - break; - case SEQM_ADD_PART: - cmdAddPart((Part*)msg->p1); - break; - case SEQM_REMOVE_PART: - cmdRemovePart((Part*)msg->p1); - break; + case SEQM_ADD_TEMPO: addUndo(UndoOp(UndoOp::AddTempo, msg->a, msg->b)); MusEGlobal::tempomap.addTempo(msg->a, msg->b); @@ -1932,29 +1760,6 @@ void Song::processMsg(AudioMsg* msg) } //--------------------------------------------------------- -// cmdAddPart -//--------------------------------------------------------- - -void Song::cmdAddPart(Part* part) - { - addPart(part); - addUndo(UndoOp(UndoOp::AddPart, part)); - updateFlags = SC_PART_INSERTED; - } - -//--------------------------------------------------------- -// cmdRemovePart -//--------------------------------------------------------- - -void Song::cmdRemovePart(Part* part) - { - removePart(part); - addUndo(UndoOp(UndoOp::DeletePart, part)); - part->unchainClone(); - updateFlags = SC_PART_REMOVED; - } - -//--------------------------------------------------------- // panic //--------------------------------------------------------- @@ -3165,18 +2970,6 @@ void Song::insertTrack3(Track* /*track*/, int /*idx*/)//prevent compiler warning } //--------------------------------------------------------- -// removeTrack0 -//--------------------------------------------------------- - -void Song::removeTrack0(Track* track) - { - removeTrack1(track); - MusEGlobal::audio->msgRemoveTrack(track); - removeTrack3(track); - update(SC_TRACK_REMOVED); - } - -//--------------------------------------------------------- // removeTrack1 // non realtime part of removeTrack //--------------------------------------------------------- diff --git a/muse2/muse/song.h b/muse2/muse/song.h index c62f1c08..a25f1d55 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -282,33 +282,28 @@ class Song : public QObject { void cmdAddRecordedWave(WaveTrack* track, Pos, Pos); void cmdAddRecordedEvents(MidiTrack*, const EventList&, unsigned); - bool addEvent(Event&, Part*); - void changeEvent(Event&, Event&, Part*); - void deleteEvent(Event&, Part*); - void cmdChangeWave(QString original, QString tmpfile, unsigned sx, unsigned ex); - void remapPortDrumCtrlEvents(int mapidx, int newnote, int newchan, int newport); - void changeAllPortDrumCtrlEvents(bool add, bool drumonly = false); + bool addEvent(Event&, Part*); // only called from audio thread. FIXME TODO: move functionality into undo.cpp + void changeEvent(Event&, Event&, Part*); // only called from audio thread. FIXME TODO: move functionality into undo.cpp + void deleteEvent(Event&, Part*); // only called from audio thread. FIXME TODO: move functionality into undo.cpp + void cmdChangeWave(QString original, QString tmpfile, unsigned sx, unsigned ex); // FIXME TODO broken, fix that. + void remapPortDrumCtrlEvents(int mapidx, int newnote, int newchan, int newport); // called from GUI thread + void changeAllPortDrumCtrlEvents(bool add, bool drumonly = false); // called from GUI thread - void addACEvent(AudioTrack* t, int acid, int frame, double val); - void changeACEvent(AudioTrack* t, int acid, int frame, int newFrame, double val); void addExternalTempo(const TempoRecEvent& e) { _tempoFifo.put(e); } //----------------------------------------- // part manipulations //----------------------------------------- - void cmdResizePart(Track* t, Part* p, unsigned int size, bool doClones=false); - void cmdSplitPart(Track* t, Part* p, int tick); - void cmdGluePart(Track* t, Part* p); + void cmdResizePart(Track* t, Part* p, unsigned int size, bool doClones=false); // called from GUI thread, calls applyOperationGroup. FIXME TODO: better move that into functions.cpp or whatever. void addPart(Part* part); void removePart(Part* part); - PartList* getSelectedMidiParts() const; + + + PartList* getSelectedMidiParts() const; // FIXME TODO move functionality into function.cpp PartList* getSelectedWaveParts() const; - bool msgRemoveParts(); - void cmdRemovePart(Part* part); - void cmdAddPart(Part* part); int arrangerRaster() { return _arrangerRaster; } // Used by Song::cmdAddRecordedWave to snap new wave parts void setArrangerRaster(int r) { _arrangerRaster = r; } // Used by Arranger snap combo box @@ -325,17 +320,12 @@ class Song : public QObject { AuxList* auxs() { return &_auxs; } SynthIList* syntis() { return &_synthIs; } - void cmdRemoveTrack(Track* track); - void removeTrack0(Track* track); void removeTrack1(Track* track); void removeTrack2(Track* track); void removeTrack3(Track* track); - void removeMarkedTracks(); - //void changeTrack(Track* oldTrack, Track* newTrack); DELETETHIS MidiTrack* findTrack(const Part* part) const; Track* findTrack(const QString& name) const; void swapTracks(int i1, int i2); - void setChannelMute(int channel, bool flag); void setRecordFlag(Track*, bool); void insertTrack0(Track*, int idx); void insertTrack1(Track*, int idx); @@ -344,7 +334,6 @@ class Song : public QObject { void deselectTracks(); void readRoute(Xml& xml); void recordEvent(MidiTrack*, Event&); - void msgInsertTrack(Track* track, int idx, bool u = true); // Enable all track and plugin controllers, and synth controllers if applicable, which are NOT in AUTO_WRITE mode. void reenableTouchedControllers(); void clearRecAutomation(bool clearList); @@ -362,7 +351,7 @@ class Song : public QObject { void startUndo(); void endUndo(MusECore::SongChangedFlags_t); - void undoOp(UndoOp::UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe); + void undoOp(UndoOp::UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe); // FIXME FINDMICHJETZT what's that?! remove it! void executeOperationGroup1(Undo& operations); void executeOperationGroup2(Undo& operations); diff --git a/muse2/muse/synth.cpp b/muse2/muse/synth.cpp index d8d09048..32568e31 100644 --- a/muse2/muse/synth.cpp +++ b/muse2/muse/synth.cpp @@ -696,11 +696,7 @@ SynthI* Song::createSynthI(const QString& sclass, const QString& label, Synth::T int idx = insertAt ? _tracks.index(insertAt) : -1; - insertTrack1(si, idx); - - msgInsertTrack(si, idx, true); // add to instance list - - insertTrack3(si, idx); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::AddTrack, idx, si)); OutputList* ol = MusEGlobal::song->outputs(); // add default route to master (first audio output) diff --git a/muse2/muse/wave.cpp b/muse2/muse/wave.cpp index 73e4d837..9bf26753 100644 --- a/muse2/muse/wave.cpp +++ b/muse2/muse/wave.cpp @@ -1114,7 +1114,10 @@ void Song::cmdAddRecordedWave(MusECore::WaveTrack* track, MusECore::Pos s, MusEC event.setLenFrame(e.frame() - s.frame()); part->addEvent(event); - MusEGlobal::song->cmdAddPart(part); + // TODO FIXME that's ugly (flo) + addPart(part); + addUndo(UndoOp(UndoOp::AddPart, part)); + updateFlags = SC_PART_INSERTED; if (MusEGlobal::song->len() < etick) MusEGlobal::song->setLen(etick); |