diff options
-rw-r--r-- | muse2/muse/arranger/pcanvas.cpp | 182 | ||||
-rw-r--r-- | muse2/muse/audio.cpp | 4 | ||||
-rw-r--r-- | muse2/muse/audio.h | 6 | ||||
-rw-r--r-- | muse2/muse/functions.cpp | 28 | ||||
-rw-r--r-- | muse2/muse/midiseq.cpp | 3 | ||||
-rw-r--r-- | muse2/muse/part.cpp | 62 | ||||
-rw-r--r-- | muse2/muse/seqmsg.cpp | 15 | ||||
-rw-r--r-- | muse2/muse/song.cpp | 69 | ||||
-rw-r--r-- | muse2/muse/song.h | 2 | ||||
-rw-r--r-- | muse2/muse/structure.cpp | 63 | ||||
-rw-r--r-- | muse2/muse/undo.cpp | 125 | ||||
-rw-r--r-- | muse2/muse/undo.h | 23 |
12 files changed, 229 insertions, 353 deletions
diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 646a9382..0e1e04a8 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -64,6 +64,10 @@ #include "utils.h" #include "dialogs.h" #include "widgets/pastedialog.h" +#include "undo.h" + +using MusECore::Undo; +using MusECore::UndoOp; #define ABS(x) (abs(x)) @@ -189,12 +193,12 @@ void PartCanvas::returnPressed() if (editMode) { //this check is neccessary, because it returnPressed may be called //twice. the second call would cause a crash, however! - MusECore::Part* oldPart = editPart->part(); - MusECore::Part* newPart = oldPart->clone(); - - newPart->setName(lineEditor->text()); + MusECore::Part* part = editPart->part(); // Indicate do undo, and do port controller values but not clone parts. - MusEGlobal::audio->msgChangePart(oldPart, newPart, true, true, false); + + Undo operations; + operations.push_back(UndoOp(UndoOp::ModifyPartName,part, part->name().toUtf8().data(), lineEditor->text().toUtf8().data())); // FIXME char sucks, better use QString directly. + MusEGlobal::song->applyOperationGroup(operations); editMode = false; @@ -314,7 +318,7 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp bool result=moveItem(operations, ci, newpos, dtype); if (result) - ci->move(newpos); + ci->move(newpos); if(moving.size() == 1) { itemReleased(curItem, newpos); @@ -333,102 +337,89 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp //--------------------------------------------------------- bool PartCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& newpos, DragType t) - { - NPart* npart = (NPart*) item; - MusECore::Part* spart = npart->part(); - MusECore::Track* track = npart->track(); - MusECore::Track* dtrack=NULL; - unsigned dtick = newpos.x(); - unsigned ntrack = y2pitch(item->mp().y()); - MusECore::Track::TrackType type = track->type(); - if (tracks->index(track) == ntrack && (dtick == spart->tick())) { - return false; - } - if (ntrack >= tracks->size()) { - ntrack = tracks->size(); - if (MusEGlobal::debugMsg) - printf("PartCanvas::moveItem - add new track\n"); - dtrack = MusEGlobal::song->addTrack(operations, type); // Add at end of list. - - if (type == MusECore::Track::WAVE) { - MusECore::WaveTrack* st = (MusECore::WaveTrack*) track; - MusECore::WaveTrack* dt = (MusECore::WaveTrack*) dtrack; - dt->setChannels(st->channels()); - } - emit tracklistChanged(); - } - else - { - dtrack = tracks->index(ntrack); - if (dtrack->type() != type) { - QMessageBox::critical(this, QString("MusE"), - tr("Cannot copy/move/clone to different Track-Type")); - return false; - } - } - - MusECore::Part* dpart; - bool clone = (t == MOVE_CLONE || (t == MOVE_COPY && spart->events()->arefCount() > 1)); - - if(t == MOVE_MOVE) - { - // This doesn't increment aref count, and doesn't chain clones. - // It also gives the new part a new serial number, but it is - // overwritten with the old one by Song::changePart(), from Audio::msgChangePart() below. - dpart = spart->clone(); - dpart->setTrack(dtrack); - } - else +{ + NPart* npart = (NPart*) item; + MusECore::Part* spart = npart->part(); + MusECore::Track* track = npart->track(); + MusECore::Track* dtrack=NULL; + unsigned dtick = newpos.x(); // FIXME TODO make subtick-compatible! + unsigned ntrack = y2pitch(item->mp().y()); + MusECore::Track::TrackType type = track->type(); + int new_partend; + if (tracks->index(track) == ntrack && (dtick == spart->tick())) { + return false; + } + if (ntrack >= tracks->size()) { + ntrack = tracks->size(); + if (MusEGlobal::debugMsg) + printf("PartCanvas::moveItem - add new track\n"); + dtrack = MusEGlobal::song->addTrack(operations, type); // Add at end of list. + + if (type == MusECore::Track::WAVE) { + MusECore::WaveTrack* st = (MusECore::WaveTrack*) track; + MusECore::WaveTrack* dt = (MusECore::WaveTrack*) dtrack; + dt->setChannels(st->channels()); + } + emit tracklistChanged(); + } + else + { + dtrack = tracks->index(ntrack); + if (dtrack->type() != type) { + QMessageBox::critical(this, QString("MusE"), + tr("Cannot copy/move/clone to different Track-Type")); + return false; + } + } + + + + if(t == MOVE_MOVE) + { + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::ModifyPartTick,spart,spart->tick(),dtick)); + + new_partend=(spart->lenTick() + dtick); + } + else + { + MusECore::Part* dpart; + bool clone = (t == MOVE_CLONE || (t == MOVE_COPY && spart->events()->arefCount() > 1)); + // This increments aref count if cloned, and chains clones. // It also gives the new part a new serial number. dpart = dtrack->newPart(spart, clone); - - dpart->setTick(dtick); - - if(t == MOVE_MOVE) - item->setPart(dpart); - if (t == MOVE_COPY && !clone) { + + dpart->setTick(dtick); + if (t == MOVE_COPY && !clone) { // Copy Events MusECore::EventList* se = spart->events(); MusECore::EventList* de = dpart->events(); for (MusECore::iEvent i = se->begin(); i != se->end(); ++i) { - MusECore::Event oldEvent = i->second; - MusECore::Event ev = oldEvent.clone(); - de->add(ev); - } + MusECore::Event oldEvent = i->second; + MusECore::Event ev = oldEvent.clone(); + de->add(ev); } - - - if (t == MOVE_COPY || t == MOVE_CLONE) { - dpart->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it - // so we must decrement it first :/ - // These will not increment ref count, and will not chain clones... - // TODO DELETETHIS: is the above comment still correct (by flo93)? i doubt it! - operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddPart,dpart)); - } - else if (t == MOVE_MOVE) { - // In all cases found ev lists were same. So this is redundant - Redo incs then decs the same list. - // But just in case we ever have two different lists... - dpart->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it - // so we must decrement it first :/ - spart->events()->incARef(1); // the later MusEGlobal::song->applyOperationGroup() will decrement it - // so we must increment it first :/ - dpart->setSelected(spart->selected()); - // These will increment ref count if not a clone, and will chain clones... - // TODO DELETETHIS: is the above comment still correct (by flo93)? i doubt it! - operations.push_back(MusECore::UndoOp(MusECore::UndoOp::ModifyPart,spart, dpart, true, false)); - - spart->setSelected(false); - } - // else // will never happen -> operations will never be empty - - if (MusEGlobal::song->len() < (dpart->lenTick() + dpart->tick())) + } + + dpart->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it + // so we must decrement it first :/ + // These will not increment ref count, and will not chain clones... + // TODO DELETETHIS: is the above comment still correct (by flo93)? i doubt it! + operations.push_back(MusECore::UndoOp(MusECore::UndoOp::AddPart,dpart)); + + new_partend=(dpart->lenTick() + dpart->tick()); + + } + + if (MusEGlobal::song->len() < new_partend) // FIXME this is buggy anyway. operations.push_back( MusECore::UndoOp(MusECore::UndoOp::ModifySongLen, - dpart->lenTick() + dpart->tick(), + new_partend, MusEGlobal::song->len() ) ); - - return true; - } + + + + return true; +} //--------------------------------------------------------- // raster @@ -866,9 +857,10 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt) MusECore::Event ev = oldEvent.clone(); de->add(ev); } - // Indicate undo, and do port controller values but not clone parts. - // changed by flo93: removed start and endUndo, instead changed first bool to true - MusEGlobal::audio->msgChangePart(spart, dpart, true, true, false); + Undo operations; + operations.push_back(UndoOp(UndoOp::DeletePart, spart)); + operations.push_back(UndoOp(UndoOp::AddPart, dpart)); + MusEGlobal::song->applyOperationGroup(operations); break; } case 16: // Export to file diff --git a/muse2/muse/audio.cpp b/muse2/muse/audio.cpp index 659ae8a9..bbc803c5 100644 --- a/muse2/muse/audio.cpp +++ b/muse2/muse/audio.cpp @@ -76,9 +76,9 @@ void initAudio() extern double curTime(); const char* seqMsgList[] = { - "SEQM_ADD_TRACK", "SEQM_REMOVE_TRACK", //"SEQM_CHANGE_TRACK", DELETETHIS + "SEQM_ADD_TRACK", "SEQM_REMOVE_TRACK", "SEQM_MOVE_TRACK", - "SEQM_ADD_PART", "SEQM_REMOVE_PART", "SEQM_CHANGE_PART", + "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_SET_GLOBAL_TEMPO", diff --git a/muse2/muse/audio.h b/muse2/muse/audio.h index a403e5bf..e8d22f78 100644 --- a/muse2/muse/audio.h +++ b/muse2/muse/audio.h @@ -60,9 +60,9 @@ class Track; //--------------------------------------------------------- enum { - SEQM_ADD_TRACK, SEQM_REMOVE_TRACK, //SEQM_CHANGE_TRACK, DELETETHIS + SEQM_ADD_TRACK, SEQM_REMOVE_TRACK, SEQM_MOVE_TRACK, - SEQM_ADD_PART, SEQM_REMOVE_PART, SEQM_CHANGE_PART, + 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, @@ -234,11 +234,9 @@ class Audio { void msgRemoveTrack(Track*, bool u = true); void msgRemoveTracks(); - //void msgChangeTrack(Track* oldTrack, Track* newTrack, bool u = true); DELETETHIS void msgMoveTrack(int idx1, int dx2, bool u = true); void msgAddPart(Part*, bool u = true); void msgRemovePart(Part*, bool u = true); - void msgChangePart(Part* oldPart, Part* newPart, bool u = true, bool doCtrls = true, bool doClones = false); 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); diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp index fa53f5d4..449461c5 100644 --- a/muse2/muse/functions.cpp +++ b/muse2/muse/functions.cpp @@ -2,7 +2,7 @@ // MusE // Linux Music Editor // $Id: functions.cpp,v 1.20.2.19 2011/05/05 20:10 flo93 Exp $ -// (C) Copyright 2011 Florian Jung (flo93@sourceforge.net) +// (C) Copyright 2011,2013 Florian Jung (flo93@sourceforge.net) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -1310,11 +1310,7 @@ void shrink_parts(int raster) if (len<min_len) len=min_len; if (len < part->second->lenTick()) - { - MidiPart* new_part = new MidiPart(*(MidiPart*)part->second); - new_part->setLenTick(len); - operations.push_back(UndoOp(UndoOp::ModifyPart, part->second, new_part, true, false)); - } + operations.push_back(UndoOp(UndoOp::ModifyPartLength, part->second, part->second->lenTick(), len, true, false)); } MusEGlobal::song->applyOperationGroup(operations); @@ -1326,8 +1322,8 @@ void schedule_resize_all_same_len_clone_parts(Part* part, unsigned new_len, Undo QSet<const Part*> already_done; for (Undo::iterator op_it=operations.begin(); op_it!=operations.end();op_it++) - if (op_it->type==UndoOp::ModifyPart || op_it->type==UndoOp::DeletePart) - already_done.insert(op_it->nPart); + if (op_it->type==UndoOp::DeletePart) + already_done.insert(op_it->part); unsigned old_len= part->type() == Pos::FRAMES ? part->lenFrame() : part->lenTick(); if (old_len!=new_len) @@ -1338,18 +1334,12 @@ void schedule_resize_all_same_len_clone_parts(Part* part, unsigned new_len, Undo if (part->type() == Pos::FRAMES) { if (part_it->lenFrame()==old_len && !already_done.contains(part_it)) - { - WavePart* new_part = new WavePart(*(WavePart*)part_it); - new_part->setLenFrame(new_len); - operations.push_back(UndoOp(UndoOp::ModifyPart, part_it, new_part, true, false)); - } + operations.push_back(UndoOp(UndoOp::ModifyPartLengthFrames, part_it, part_it->lenFrame(), new_len, true, false)); // FIXME FINDMICH frames suck :( } else if (part_it->lenTick()==old_len && !already_done.contains(part_it)) { - MidiPart* new_part = new MidiPart(*(MidiPart*)part_it); - new_part->setLenTick(new_len); - operations.push_back(UndoOp(UndoOp::ModifyPart, part_it, new_part, true, false)); + operations.push_back(UndoOp(UndoOp::ModifyPartLength, part_it, part_it->lenTick(), new_len, true, false)); } part_it=part_it->nextClone(); @@ -1381,11 +1371,7 @@ void expand_parts(int raster) if (len<min_len) len=min_len; if (len > part->second->lenTick()) - { - MidiPart* new_part = new MidiPart(*(MidiPart*)part->second); - new_part->setLenTick(len); - operations.push_back(UndoOp(UndoOp::ModifyPart, part->second, new_part, true, false)); - } + operations.push_back(UndoOp(UndoOp::ModifyPartLength, part->second, part->second->lenTick(), len, true, false)); } MusEGlobal::song->applyOperationGroup(operations); diff --git a/muse2/muse/midiseq.cpp b/muse2/muse/midiseq.cpp index b94e284e..8aa6c289 100644 --- a/muse2/muse/midiseq.cpp +++ b/muse2/muse/midiseq.cpp @@ -119,9 +119,6 @@ void MidiSeq::processMsg(const ThreadMsg* m) case MusECore::SEQM_REMOVE_PART: MusEGlobal::song->cmdRemovePart((Part*)msg->p1); break; - case MusECore::SEQM_CHANGE_PART: - MusEGlobal::song->cmdChangePart((Part*)msg->p1, (Part*)msg->p2, msg->a, msg->b); - break; case MusECore::SEQM_SET_TRACK_OUT_CHAN: diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index c530b1f3..10c7f201 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -372,8 +372,6 @@ void addPortCtrlEvents(Event& event, Part* part, bool doClones) { // Traverse and process the clone chain ring until we arrive at the same part again. // The loop is a safety net. - // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents, - // we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain. Part* p = part; while(1) { @@ -434,8 +432,6 @@ void addPortCtrlEvents(Part* part, bool doClones) { // Traverse and process the clone chain ring until we arrive at the same part again. // The loop is a safety net. - // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents, - // we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain. Part* p = part; while(1) { @@ -499,8 +495,6 @@ void removePortCtrlEvents(Event& event, Part* part, bool doClones) { // Traverse and process the clone chain ring until we arrive at the same part again. // The loop is a safety net. - // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents, - // we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain. Part* p = part; while(1) { @@ -555,8 +549,6 @@ void removePortCtrlEvents(Part* part, bool doClones) { // Traverse and process the clone chain ring until we arrive at the same part again. // The loop is a safety net. - // Update: Due to the varying calls, and order of, incARefcount, (msg)ChangePart, replaceClone, and remove/addPortCtrlEvents, - // we can not rely on the reference count as a safety net in these routines. We will just have to trust the clone chain. Part* p = part; while(1) { @@ -850,6 +842,10 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo EventList* el = nPart->events(); unsigned new_partlength = MusEGlobal::tempomap.deltaTick2frame(oPart->tick(), oPart->tick() + len); + // 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. + + /* // 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 @@ -865,7 +861,7 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo } nPart->setLenFrame(new_partlength); // Do not do port controller values and clone parts. - operations.push_back(UndoOp(UndoOp::ModifyPart, oPart, nPart, false, false)); + operations.push_back(UndoOp(UndoOp::Modify***Part, oPart, nPart, false, false)); MusEGlobal::song->applyOperationGroup(operations); } @@ -890,9 +886,9 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo nPart->setLenFrame(new_partlength); // Do not do port controller values and clone parts. - operations.push_back(UndoOp(UndoOp::ModifyPart, oPart, nPart, false, false)); + operations.push_back(UndoOp(UndoOp::Modify***Part, oPart, nPart, false, false)); MusEGlobal::song->applyOperationGroup(operations); - } + } */ } break; case Track::MIDI: @@ -907,10 +903,8 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo { if (part_it->lenTick()==orig_len) { - MidiPart* newPart = new MidiPart(*part_it); - newPart->setLenTick(len); // Do port controller values but not clone parts. - operations.push_back(UndoOp(UndoOp::ModifyPart, part_it, newPart, true, false)); + operations.push_back(UndoOp(UndoOp::ModifyPartLength, part_it, part_it->lenTick(), len, true, false)); } part_it=(MidiPart*)part_it->nextClone(); @@ -1032,45 +1026,23 @@ void Song::cmdSplitPart(Track* track, Part* part, int tick) Part* p2; track->splitPart(part, tick, p1, p2); - //MusEGlobal::song->informAboutNewParts(part, p1); // is unneccessary because of ChangePart below + MusEGlobal::song->informAboutNewParts(part, p1); MusEGlobal::song->informAboutNewParts(part, p2); - startUndo(); - // Indicate no undo, and do port controller values but not clone parts. - MusEGlobal::audio->msgChangePart(part, p1, false, true, false); - MusEGlobal::audio->msgAddPart(p2, false); - endUndo(SC_TRACK_MODIFIED | SC_PART_MODIFIED | SC_PART_INSERTED); + 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); } -//--------------------------------------------------------- -// changePart -//--------------------------------------------------------- - -void Song::changePart(Part* oPart, Part* nPart) - { - nPart->setSn(oPart->sn()); - - Track* oTrack = oPart->track(); - Track* nTrack = nPart->track(); - - oTrack->parts()->remove(oPart); - nTrack->parts()->add(nPart); - - - // Added by T356. - // adjust song len: - unsigned epos = nPart->tick() + nPart->lenTick(); - if (epos > len()) - _len = epos; - - } //--------------------------------------------------------- // 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; @@ -1126,8 +1098,8 @@ void Song::cmdGluePart(Track* track, Part* oPart) startUndo(); MusEGlobal::audio->msgRemovePart(nextPart, false); // Indicate no undo, and do port controller values but not clone parts. - MusEGlobal::audio->msgChangePart(oPart, nPart, false, true, false); - endUndo(SC_PART_MODIFIED | SC_PART_REMOVED); + MusEGlobal::audio->msgChange***Part(oPart, nPart, false, true, false); + endUndo(SC_PART_MODIFIED | SC_PART_REMOVED); */ } //--------------------------------------------------------- diff --git a/muse2/muse/seqmsg.cpp b/muse2/muse/seqmsg.cpp index fcffc332..61714b98 100644 --- a/muse2/muse/seqmsg.cpp +++ b/muse2/muse/seqmsg.cpp @@ -923,21 +923,6 @@ bool Song::msgRemoveParts() } //--------------------------------------------------------- -// msgChangePart -//--------------------------------------------------------- - -void Audio::msgChangePart(Part* oldPart, Part* newPart, bool doUndoFlag, bool doCtrls, bool doClones) - { - AudioMsg msg; - msg.id = SEQM_CHANGE_PART; - msg.p1 = oldPart; - msg.p2 = newPart; - msg.a = doCtrls; - msg.b = doClones; - sendMessage(&msg, doUndoFlag); - } - -//--------------------------------------------------------- // msgAddEvent //--------------------------------------------------------- diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 8a7bf39f..d457cb1d 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -886,42 +886,23 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start // Round the end up (again) using the Arranger part snap raster value. endTick = AL::sigmap.raster2(endTick, arrangerRaster()); - - removePortCtrlEvents(part, false); // Remove all of the part's port controller values. Don't do clone parts. - - // Clone the part. This doesn't increment aref count, and doesn't chain clones. - // It also gives the new part a new serial number, but it is - // overwritten with the old one by Song::changePart(), below. - Part* newPart = part->clone(); - - newPart->setLenTick(endTick); // Set the new part's length. - changePart(part, newPart); // Change the part. - - part->events()->incARef(-1); // Manually adjust reference counts. HACK! - newPart->events()->incARef(1); - - replaceClone(part, newPart); // Replace the part in the clone chain with the new part. - - // Now add all of the new part's port controller values. Indicate do not do clone parts. - addPortCtrlEvents(newPart, false); - // Create an undo op. Indicate do port controller values but not clone parts. - addUndo(UndoOp(UndoOp::ModifyPart, part, newPart, true, false)); + addUndo(UndoOp(UndoOp::ModifyPartLength, part, part->lenTick(), endTick, true, false)); // FIXME XTICKS! FINDMICHJETZT! updateFlags |= SC_PART_MODIFIED; if (_recMode == REC_REPLACE) { - iEvent si = newPart->events()->lower_bound(startTick - newPart->tick()); - iEvent ei = newPart->events()->lower_bound(newPart->endTick() - newPart->tick()); + iEvent si = part->events()->lower_bound(startTick - part->tick()); + iEvent ei = part->events()->lower_bound(part->endTick() - part->tick()); for (iEvent i = si; i != ei; ++i) { Event event = i->second; // Indicate do port controller values and clone parts. - addUndo(UndoOp(UndoOp::DeleteEvent, event, newPart, true, true)); + addUndo(UndoOp(UndoOp::DeleteEvent, event, part, true, true)); // Remove the event from the new part's port controller values, and do all clone parts. - removePortCtrlEvents(event, newPart, true); + removePortCtrlEvents(event, part, true); } - newPart->events()->erase(si, ei); + part->events()->erase(si, ei); } for (iEvent i = s; i != e; ++i) { @@ -929,13 +910,13 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start event.setTick(event.tick() - partTick); Event e; // Create an undo op. Indicate do port controller values and clone parts. - addUndo(UndoOp(UndoOp::AddEvent, e, event, newPart, true, true)); + addUndo(UndoOp(UndoOp::AddEvent, e, event, part, true, true)); - if(newPart->events()->find(event) == newPart->events()->end()) - newPart->events()->add(event); + if(part->events()->find(event) == part->events()->end()) + part->events()->add(event); // Add the event to the new part's port controller values, and do all clone parts. - addPortCtrlEvents(event, newPart, true); + addPortCtrlEvents(event, part, true); } } else { @@ -1886,7 +1867,6 @@ void Song::processMsg(AudioMsg* msg) updateFlags = SC_EVENT_MODIFIED; break; - // Moved here from MidiSeq::processMsg p4.0.34 case SEQM_ADD_TRACK: insertTrack2(msg->track, msg->ival); break; @@ -1899,9 +1879,6 @@ void Song::processMsg(AudioMsg* msg) case SEQM_REMOVE_PART: cmdRemovePart((Part*)msg->p1); break; - case SEQM_CHANGE_PART: - cmdChangePart((Part*)msg->p1, (Part*)msg->p2, msg->a, msg->b); - break; case SEQM_ADD_TEMPO: addUndo(UndoOp(UndoOp::AddTempo, msg->a, msg->b)); @@ -1980,32 +1957,6 @@ void Song::cmdRemovePart(Part* part) } //--------------------------------------------------------- -// cmdChangePart -//--------------------------------------------------------- - -void Song::cmdChangePart(Part* oldPart, Part* newPart, bool doCtrls, bool doClones) - { - if(doCtrls) - removePortCtrlEvents(oldPart, doClones); - - changePart(oldPart, newPart); - - addUndo(UndoOp(UndoOp::ModifyPart, oldPart, newPart, doCtrls, doClones)); - - // Changed by T356. Do not decrement ref count if the new part is a clone of the old part, since the event list - // will still be active. - if(oldPart->cevents() != newPart->cevents()) - oldPart->events()->incARef(-1); - - replaceClone(oldPart, newPart); - - if(doCtrls) - addPortCtrlEvents(newPart, doClones); - - updateFlags = SC_PART_MODIFIED; - } - -//--------------------------------------------------------- // panic //--------------------------------------------------------- diff --git a/muse2/muse/song.h b/muse2/muse/song.h index f6b1403d..909e54fc 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -298,12 +298,10 @@ class Song : public QObject { void addPart(Part* part); void removePart(Part* part); - void changePart(Part*, Part*); PartList* getSelectedMidiParts() const; PartList* getSelectedWaveParts() const; bool msgRemoveParts(); - void cmdChangePart(Part* oldPart, Part* newPart, bool doCtrls, bool doClones); void cmdRemovePart(Part* part); void cmdAddPart(Part* part); int arrangerRaster() { return _arrangerRaster; } // Used by Song::cmdAddRecordedWave to snap new wave parts diff --git a/muse2/muse/structure.cpp b/muse2/muse/structure.cpp index 65489cac..ad22b8d3 100644 --- a/muse2/muse/structure.cpp +++ b/muse2/muse/structure.cpp @@ -5,6 +5,7 @@ // // (C) Copyright 1999-2004 Werner Schweer (ws@seh.de) // (C) Copyright 2011 Robert Jonsson (rj@spamatica.se) +// (C) Copyright 2013 Florian Jung (flo93@sourceforge.net) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -161,19 +162,15 @@ void globalCut(bool onlySelectedTracks) else if ((t < lpos) && ((t+l) > lpos) && ((t+l) <= rpos)) { // remove part tail int len = lpos - t; - Part *nPart; - if (track->isMidiTrack()) - nPart = new MidiPart(*(MidiPart*)part); - else - nPart = new WavePart(*(WavePart*)part); - - nPart->setLenTick(len); - // cut Events in nPart - EventList* el = nPart->events(); - for (iEvent ie = el->lower_bound(len); ie != el->end(); ++ie) - operations.push_back(UndoOp(UndoOp::DeleteEvent,ie->second, nPart, false, false)); - - operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, true)); + + if (part->nextClone()==part) // no clones + { + // cut Events + EventList* el = part->events(); + for (iEvent ie = el->lower_bound(len); ie != el->end(); ++ie) + operations.push_back(UndoOp(UndoOp::DeleteEvent,ie->second, part, false, false)); + } + operations.push_back(UndoOp(UndoOp::ModifyPartLength, part, part->lenTick(), len, true, true)); } else if ((t < lpos) && ((t+l) > lpos) && ((t+l) > rpos)) { //---------------------- @@ -190,8 +187,9 @@ void globalCut(bool onlySelectedTracks) p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ p3->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ - // Indicate no undo, and do port controller values and clone parts. - operations.push_back(UndoOp(UndoOp::ModifyPart,part, p1, true, true)); + MusEGlobal::song->informAboutNewParts(part,p1,p3); + operations.push_back(UndoOp(UndoOp::DeletePart,part)); + operations.push_back(UndoOp(UndoOp::AddPart,p1)); operations.push_back(UndoOp(UndoOp::AddPart,p3)); } else if ((t >= lpos) && (t < rpos) && (t+l) > rpos) { @@ -203,19 +201,15 @@ void globalCut(bool onlySelectedTracks) delete p1; p2->setTick(lpos); p2->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ - operations.push_back(UndoOp(UndoOp::ModifyPart,part, p2, true, true)); + + MusEGlobal::song->informAboutNewParts(part,p2); + operations.push_back(UndoOp(UndoOp::DeletePart,part)); + operations.push_back(UndoOp(UndoOp::AddPart,p2)); } else if (t >= rpos) { // move part to the left - Part *nPart; - if (track->isMidiTrack()) - nPart = new MidiPart(*(MidiPart*)part); - else - nPart = new WavePart(*(WavePart*)part); int nt = part->tick(); - nPart->setTick(nt - (rpos -lpos)); - // Indicate no undo, and do port controller values but not clone parts. - operations.push_back(UndoOp(UndoOp::ModifyPart,part, nPart, true, false)); + operations.push_back(UndoOp(UndoOp::ModifyPartTick,part,part->tick(), nt - (rpos -lpos) )); } } } @@ -268,17 +262,13 @@ Undo movePartsTotheRight(unsigned int startTicks, int moveTicks, bool only_selec p2->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it so we must decrement it first :/ - operations.push_back(UndoOp(UndoOp::ModifyPart, part, p1, true, true)); + MusEGlobal::song->informAboutNewParts(part,p1,p2); + operations.push_back(UndoOp(UndoOp::DeletePart, part)); + operations.push_back(UndoOp(UndoOp::AddPart, p1)); operations.push_back(UndoOp(UndoOp::AddPart, p2)); } else if (t >= startTicks) { - Part *nPart; - if (track->isMidiTrack()) - nPart = new MidiPart(*(MidiPart*)part); - else - nPart = new WavePart(*(WavePart*)part); - nPart->setTick(t + moveTicks); - operations.push_back(UndoOp(UndoOp::ModifyPart, part, nPart, true, false)); + operations.push_back(UndoOp(UndoOp::ModifyPartTick, part, part->tick(), t + moveTicks)); } } } @@ -323,19 +313,20 @@ Undo partSplitter(unsigned int pos, bool onlySelectedTracks) p1->events()->incARef(-1); // the later MusEGlobal::song->applyOperationGroup() will increment it p2->events()->incARef(-1); // so we must decrement it first :/ - //MusEGlobal::song->informAboutNewParts(part, p1); // is unneccessary because of ModifyPart + MusEGlobal::song->informAboutNewParts(part, p1); MusEGlobal::song->informAboutNewParts(part, p2); - operations.push_back(UndoOp(UndoOp::ModifyPart,part, p1, true, false)); + operations.push_back(UndoOp(UndoOp::DeletePart,part)); + operations.push_back(UndoOp(UndoOp::AddPart,p1)); operations.push_back(UndoOp(UndoOp::AddPart,p2)); if (MusEGlobal::debugMsg) { printf("in partSplitter: part1 %d\n",p1->events()->refCount()); printf("in partSplitter: part2 %d\n",p2->events()->refCount()); - } - break; } + break; } } + } return operations; } diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp index fc6fc1d8..924ba745 100644 --- a/muse2/muse/undo.cpp +++ b/muse2/muse/undo.cpp @@ -50,7 +50,7 @@ const char* UndoOp::typeName() { static const char* name[] = { "AddTrack", "DeleteTrack", - "AddPart", "DeletePart", "ModifyPart", + "AddPart", "DeletePart", "ModifyPartTick", "ModifyPartLength", "ModifyPartLengthFrames", "ModifyPartName", "AddEvent", "DeleteEvent", "ModifyEvent", "AddTempo", "DeleteTempo", "AddSig", "DeleteSig", @@ -77,7 +77,10 @@ void UndoOp::dump() break; case AddPart: case DeletePart: - case ModifyPart: + case ModifyPartTick: + case ModifyPartLength: + case ModifyPartLengthFrames: + case ModifyPartName: break; case AddEvent: case DeleteEvent: @@ -136,11 +139,7 @@ void UndoList::clearDelete() break; case UndoOp::DeletePart: - delete i->oPart; - break; - - case UndoOp::ModifyPart: - delete i->oPart; + delete i->part; break; case UndoOp::ModifyMarker: @@ -176,12 +175,9 @@ void UndoList::clearDelete() break; case UndoOp::AddPart: - delete i->oPart; + delete i->part; break; - case UndoOp::ModifyPart: - delete i->nPart; - break; case UndoOp::ModifyMarker: if (i->realMarker) delete i->realMarker; @@ -295,12 +291,12 @@ void cleanOperationGroup(Undo& group) else processed_tracks.insert(op->track); } - else if ((op->type==UndoOp::ModifyPart) || (op->type==UndoOp::DeletePart)) + else if (op->type==UndoOp::DeletePart) { - if (processed_parts.find(op->oPart)!=processed_parts.end()) + if (processed_parts.find(op->part)!=processed_parts.end()) group.erase(op); else - processed_parts.insert(op->oPart); + processed_parts.insert(op->part); } op=op_; @@ -370,28 +366,33 @@ void Song::doUndo2() break; case UndoOp::AddPart: { - Part* part = i->oPart; + Part* part = i->part; removePart(part); updateFlags |= SC_PART_REMOVED; - i->oPart->events()->incARef(-1); - unchainClone(i->oPart); + i->part->events()->incARef(-1); + unchainClone(i->part); } break; case UndoOp::DeletePart: - addPart(i->oPart); + addPart(i->part); updateFlags |= SC_PART_INSERTED; - i->oPart->events()->incARef(1); - chainClone(i->oPart); + i->part->events()->incARef(1); + chainClone(i->part); break; - case UndoOp::ModifyPart: - if(i->doCtrls) - removePortCtrlEvents(i->nPart, i->doClones); - changePart(i->nPart, i->oPart); - i->nPart->events()->incARef(-1); - i->oPart->events()->incARef(1); - replaceClone(i->nPart, i->oPart); - if(i->doCtrls) - addPortCtrlEvents(i->oPart, i->doClones); + case UndoOp::ModifyPartName: + i->part->setName(i->_oldName); + updateFlags |= SC_PART_MODIFIED; + break; + case UndoOp::ModifyPartTick: // TODO FIXME (?) do port ctrls/clones? + i->part->setTick(i->old_partlen_or_tick); + updateFlags |= SC_PART_MODIFIED; + break; + case UndoOp::ModifyPartLength: // TODO FIXME (?) do port ctrls/clones? + i->part->setLenTick(i->old_partlen_or_tick); + updateFlags |= SC_PART_MODIFIED; + break; + case UndoOp::ModifyPartLengthFrames: // TODO FIXME FINDMICH frames deprecated! do port ctrls/clones? + i->part->setLenFrame(i->old_partlen_or_tick); updateFlags |= SC_PART_MODIFIED; break; case UndoOp::AddEvent: @@ -484,26 +485,31 @@ void Song::doRedo2() } break; case UndoOp::AddPart: - addPart(i->oPart); + addPart(i->part); updateFlags |= SC_PART_INSERTED; - i->oPart->events()->incARef(1); - chainClone(i->oPart); + i->part->events()->incARef(1); + chainClone(i->part); break; case UndoOp::DeletePart: - removePart(i->oPart); + removePart(i->part); updateFlags |= SC_PART_REMOVED; - i->oPart->events()->incARef(-1); - unchainClone(i->oPart); + i->part->events()->incARef(-1); + unchainClone(i->part); break; - case UndoOp::ModifyPart: - if(i->doCtrls) - removePortCtrlEvents(i->oPart, i->doClones); - changePart(i->oPart, i->nPart); - i->nPart->events()->incARef(1); - i->oPart->events()->incARef(-1); - replaceClone(i->oPart, i->nPart); - if(i->doCtrls) - addPortCtrlEvents(i->nPart, i->doClones); + case UndoOp::ModifyPartName: + i->part->setName(i->_newName); + updateFlags |= SC_PART_MODIFIED; + break; + case UndoOp::ModifyPartTick: // TODO FIXME (?) do port ctrls/clones? + i->part->setTick(i->new_partlen_or_tick); + updateFlags |= SC_PART_MODIFIED; + break; + case UndoOp::ModifyPartLength: // TODO FIXME (?) do port ctrls/clones? + i->part->setLenTick(i->new_partlen_or_tick); + updateFlags |= SC_PART_MODIFIED; + break; + case UndoOp::ModifyPartLengthFrames: // TODO FIXME FINDMICH frames deprecated! do port ctrls/clones? + i->part->setLenFrame(i->new_partlen_or_tick); updateFlags |= SC_PART_MODIFIED; break; case UndoOp::AddEvent: @@ -590,10 +596,12 @@ UndoOp::UndoOp(UndoType type_, int n, Track* track_) track = track_; } -UndoOp::UndoOp(UndoType type_, Part* part) +UndoOp::UndoOp(UndoType type_, Part* part, unsigned old_len_or_tick, unsigned new_len_or_tick, bool, bool) { type = type_; - oPart = part; + part = part; + old_partlen_or_tick=old_len_or_tick; + new_partlen_or_tick=new_len_or_tick; } UndoOp::UndoOp(UndoType type_, Event& oev, Event& nev, Part* part_, bool doCtrls_, bool doClones_) @@ -615,15 +623,6 @@ UndoOp::UndoOp(UndoType type_, Event& nev, Part* part_, bool doCtrls_, bool doCl doClones = doClones_; } -UndoOp::UndoOp(UndoType type_, Part* oPart_, Part* nPart_, bool doCtrls_, bool doClones_) - { - type = type_; - oPart = oPart_; - nPart = nPart_; - doCtrls = doCtrls_; - doClones = doClones_; - } - UndoOp::UndoOp(UndoType type_, int c, int ctrl_, int ov, int nv) { type = type_; @@ -649,10 +648,20 @@ UndoOp::UndoOp(UndoType type_, const char* changedFile, const char* changeData, endframe = endframe_; } +UndoOp::UndoOp(UndoOp::UndoType type_, Part* part_, const char* old_name, const char* new_name) +{ + type=type_; + part=part_; + _oldName = new char[strlen(old_name) + 1]; + _newName = new char[strlen(new_name) + 1]; + strcpy(_oldName, old_name); + strcpy(_newName, new_name); +} + UndoOp::UndoOp(UndoOp::UndoType type_, Track* track_, const char* old_name, const char* new_name) { type = type_; - _renamedTrack = track_; + track = track_; _oldName = new char[strlen(old_name) + 1]; _newName = new char[strlen(new_name) + 1]; strcpy(_oldName, old_name); @@ -727,7 +736,7 @@ bool Song::doUndo1() break; case UndoOp::ModifyTrackName: - i->_renamedTrack->setName(i->_oldName); + i->track->setName(i->_oldName); updateFlags |= SC_TRACK_MODIFIED; break; case UndoOp::ModifyClip: @@ -851,7 +860,7 @@ bool Song::doRedo1() removeTrack1(i->track); break; case UndoOp::ModifyTrackName: - i->_renamedTrack->setName(i->_newName); + i->track->setName(i->_newName); updateFlags |= SC_TRACK_MODIFIED; break; case UndoOp::ModifyClip: diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h index 2f582d8e..4fded825 100644 --- a/muse2/muse/undo.h +++ b/muse2/muse/undo.h @@ -46,7 +46,7 @@ extern std::list<QString> temporaryWavFiles; //!< Used for storing all tmp-files struct UndoOp { enum UndoType { AddTrack, DeleteTrack, - AddPart, DeletePart, ModifyPart, + AddPart, DeletePart, ModifyPartTick, ModifyPartLength, ModifyPartLengthFrames, /* FINDMICH FIXME frames are to be deprecated */ ModifyPartName, AddEvent, DeleteEvent, ModifyEvent, AddTempo, DeleteTempo, AddSig, DeleteSig, @@ -71,11 +71,9 @@ struct UndoOp { int trackno; }; struct { - Part* oPart; - Part* nPart; - }; - struct { - Part* part; // this part is only relevant for EVENT operations, NOT for part ops! + Part* part; + unsigned old_partlen_or_tick; // FIXME FINDMICHJETZT XTicks!! + unsigned new_partlen_or_tick; }; struct { int channel; @@ -94,16 +92,14 @@ struct UndoOp { Marker* copyMarker; }; struct { - Track* _renamedTrack; - char* _oldName; - char* _newName; - }; - struct { Track* _propertyTrack; int _oldPropValue; int _newPropValue; }; }; + + char* _oldName; + char* _newName; Event oEvent; Event nEvent; bool doCtrls; @@ -115,10 +111,11 @@ struct UndoOp { UndoOp(); UndoOp(UndoType type, int a, int b, int c=0); UndoOp(UndoType type, int n, Track* track); - UndoOp(UndoType type, Part* part); + UndoOp(UndoType type, Part* part, unsigned old_len_or_tick=-1, unsigned new_len_or_tick=-1, bool doCtrls=false, bool doClones=false); // FIXME these bools are UNUSED!! + UndoOp(UndoType type, Part* part, const char* old_name, const char* new_name); UndoOp(UndoType type, Event& oev, Event& nev, Part* part, bool doCtrls, bool doClones); UndoOp(UndoType type, Event& nev, Part* part, bool doCtrls, bool doClones); - UndoOp(UndoType type, Part* oPart, Part* nPart, bool doCtrls, bool doClones); + UndoOp(UndoType type, Part* part, unsigned tick, bool doCtrls, bool doClones); // FIXME FINDMICHJETZT XTicks! UndoOp(UndoType type, int c, int ctrl, int ov, int nv); UndoOp(UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe); UndoOp(UndoType type, Marker* copyMarker, Marker* realMarker); |