diff options
-rw-r--r-- | muse2/muse/app.cpp | 15 | ||||
-rw-r--r-- | muse2/muse/arranger/pcanvas.cpp | 180 | ||||
-rw-r--r-- | muse2/muse/arranger/pcanvas.h | 8 | ||||
-rw-r--r-- | muse2/muse/audio.h | 6 | ||||
-rw-r--r-- | muse2/muse/functions.cpp | 2 | ||||
-rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 3 | ||||
-rw-r--r-- | muse2/muse/seqmsg.cpp | 20 | ||||
-rw-r--r-- | muse2/muse/undo.cpp | 7 | ||||
-rw-r--r-- | muse2/muse/undo.h | 4 |
9 files changed, 110 insertions, 135 deletions
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index 72cdad6a..04c55b01 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -2971,14 +2971,13 @@ void MusE::cmd(int cmd) arranger->cmd(Arranger::CMD_INSERT_EMPTYMEAS); break; case CMD_DELETE: - song->startUndo(); - if (song->msgRemoveParts()) { - song->endUndo(SC_PART_REMOVED); - break; - } - else - audio->msgRemoveTracks(); - song->endUndo(SC_TRACK_REMOVED); + if (!song->msgRemoveParts()) //automatically does undo if neccessary and returns true then + { + //msgRemoveParts() returned false -> no parts to remove? + song->startUndo(); + audio->msgRemoveTracks(); //TODO FINDME this could still be speeded up! + song->endUndo(SC_TRACK_REMOVED); + } break; case CMD_DELETE_TRACK: song->startUndo(); diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 54f431cc..e17d08e1 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -259,8 +259,10 @@ void PartCanvas::updateSong(DragType t, int flags) // moveCanvasItems //--------------------------------------------------------- -void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, int*) +void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype) { + Undo operations; + for(iCItem ici = items.begin(); ici != items.end(); ++ici) { CItem* ci = ici->second; @@ -278,15 +280,21 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp QPoint newpos = raster(QPoint(nx, ny)); selectItem(ci, true); - if (moveItem(ci, newpos, dtype)) + UndoOp operation=moveItem(ci, newpos, dtype); + if (operation.type != UndoOp::DoNothing) + { ci->move(newpos); + operations.push_back(operation); + } if(moving.size() == 1) { itemReleased(curItem, newpos); } if(dtype == MOVE_COPY || dtype == MOVE_CLONE) selectItem(ci, false); - } + } + + song->applyOperationGroup(operations); } //--------------------------------------------------------- @@ -295,7 +303,7 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp //--------------------------------------------------------- // Changed by T356. -bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t) +UndoOp PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t) { UndoOp result; NPart* npart = (NPart*) item; @@ -305,7 +313,7 @@ bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t) unsigned ntrack = y2pitch(item->mp().y()); Track::TrackType type = track->type(); if (tracks->index(track) == ntrack && (dtick == spart->tick())) { - return false; //FINDMICH + return UndoOp(UndoOp::DoNothing); } if (ntrack >= tracks->size()) { ntrack = tracks->size(); @@ -323,7 +331,7 @@ bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t) if (dtrack->type() != type) { QMessageBox::critical(this, QString("MusE"), tr("Cannot copy/move/clone to different Track-Type")); - return false; //FINDMICH + return UndoOp(UndoOp::DoNothing); } Part* dpart; @@ -341,6 +349,8 @@ bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t) // 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->events()->incARef(-1); // the later song->applyOperationGroup() will increment it + // so we must decrement it first :/ dpart->setTick(dtick); @@ -359,33 +369,24 @@ bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t) } } if (t == MOVE_COPY || t == MOVE_CLONE) { - // These will not increment ref count, and will not chain clones... - if (dtrack->type() == Track::WAVE) - audio->msgAddPart((WavePart*)dpart,false); - else - audio->msgAddPart(dpart,false); + // These will not increment ref count, and will not chain clones... + // TODO: is this still correct (by flo93)? + result=UndoOp(UndoOp::AddPart,dpart); } else if (t == MOVE_MOVE) { dpart->setSelected(spart->selected()); // These will increment ref count if not a clone, and will chain clones... - - if (dtrack->type() == Track::WAVE) { - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangePart((WavePart*)spart, (WavePart*)dpart, false, false, false); - } - else { - // Indicate no undo, and do port controller values but not clone parts. - audio->msgChangePart(spart, dpart, false, true, false); - } + // TODO: is this still correct (by flo93)? + result=UndoOp(UndoOp::ModifyPart,spart, dpart, true, false); + spart->setSelected(false); - } + // else // will never happen -> result will always be defined if (song->len() < (dpart->lenTick() + dpart->tick())) song->setLen(dpart->lenTick() + dpart->tick()); - return true; //FINDMICH - //TODO FINDMICH returns nothing... should be fixed (flo93) + return result; } //--------------------------------------------------------- @@ -521,7 +522,7 @@ void PartCanvas::newItem(CItem* i, bool noSnap) len = AL::sigmap.rasterStep(p->tick(), *_raster); p->setLenTick(len); p->setSelected(true); - audio->msgAddPart(p); + audio->msgAddPart(p, true); //indicate undo } //--------------------------------------------------------- @@ -531,7 +532,7 @@ void PartCanvas::newItem(CItem* i, bool noSnap) bool PartCanvas::deleteItem(CItem* i) { Part* p = ((NPart*)(i))->part(); - audio->msgRemovePart(p); //Invokes songChanged which calls partsChanged which makes it difficult to delete them there + audio->msgRemovePart(p, true); //Invokes songChanged which calls partsChanged which makes it difficult to delete them there return true; } @@ -712,11 +713,9 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt) Event ev = oldEvent.clone(); de->add(ev); } - song->startUndo(); - // Indicate no undo, and do port controller values but not clone parts. - audio->msgChangePart(spart, dpart, false, true, false); - - song->endUndo(SC_PART_MODIFIED); + // Indicate undo, and do port controller values but not clone parts. + // changed by flo93: removed start and endUndo, instead changed first bool to true + audio->msgChangePart(spart, dpart, true, true, false); break; // Has to be break here, right? } case 16: // Export to file @@ -929,14 +928,10 @@ void PartCanvas::keyPress(QKeyEvent* event) key += Qt::CTRL; if (key == shortcuts[SHRT_DELETE].key) { - if (getCurrentDrag()) { - //printf("dragging!!\n"); + if (getCurrentDrag()) return; - } - song->startUndo(); song->msgRemoveParts(); - song->endUndo(SC_PART_REMOVED); return; } else if (key == shortcuts[SHRT_POS_DEC].key) { @@ -1807,26 +1802,23 @@ void PartCanvas::cmd(int cmd) } switch (cmd) { case CMD_CUT_PART: + { copy(&pl); - song->startUndo(); - bool loop; - do - { - loop = false; - for (iCItem i = items.begin(); i != items.end(); ++i) { - if (!i->second->isSelected()) - continue; - NPart* p = (NPart*)(i->second); - Part* part = p->part(); - audio->msgRemovePart(part); - - loop = true; - break; - } - } while (loop); - song->endUndo(SC_PART_REMOVED); + Undo operations; + + for (iCItem i = items.begin(); i != items.end(); ++i) { + if (i->second->isSelected()) { + NPart* p = (NPart*)(i->second); + Part* part = p->part(); + operations.push_back(UndoOp(UndoOp::DeletePart, part)); + } + } + + song->applyOperationGroup(operations); + break; + } case CMD_COPY_PART: copy(&pl); break; @@ -1846,11 +1838,10 @@ void PartCanvas::cmd(int cmd) paste(false, false, true); break; case CMD_INSERT_EMPTYMEAS: - song->startUndo(); int startPos=song->vcpos(); int oneMeas=AL::sigmap.ticksMeasure(startPos); - movePartsTotheRight(startPos,oneMeas); - song->endUndo(SC_PART_INSERTED); + Undo temp=movePartsTotheRight(startPos,oneMeas); + song->applyOperationGroup(temp); break; } } @@ -1947,8 +1938,10 @@ void PartCanvas::copy(PartList* pl) // pasteAt //--------------------------------------------------------- -int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool clone, bool toTrack) +Undo PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool clone, bool toTrack, int* finalPosPtr) { + Undo operations; + QByteArray ba = pt.toLatin1(); const char* ptxt = ba.constData(); Xml xml(ptxt); @@ -1959,7 +1952,6 @@ int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool int done = 0; bool end = false; - //song->startUndo(); for (;;) { Xml::Token token = xml.parse(); const QString& tag = xml.s1(); @@ -1973,6 +1965,7 @@ int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool // Read the part. Part* p = 0; p = readXmlPart(xml, track, clone, toTrack); + // If it could not be created... if(!p) { @@ -1980,6 +1973,9 @@ int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool ++notDone; break; } + + p->events()->incARef(-1); // the later song->applyOperationGroup() will increment it + // so we must decrement it first :/ // Increment the number of parts done. ++done; @@ -1992,8 +1988,7 @@ int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool if (p->tick()+p->lenTick()>finalPos) { finalPos=p->tick()+p->lenTick(); } - //pos += p->lenTick(); - audio->msgAddPart(p,false); + operations.push_back(UndoOp(UndoOp::AddPart,p)); } else xml.unknown("PartCanvas::pasteAt"); @@ -2008,8 +2003,6 @@ int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool break; } - //song->endUndo(SC_PART_INSERTED); - //return pos; if(notDone) { @@ -2020,7 +2013,8 @@ int PartCanvas::pasteAt(const QString& pt, Track* track, unsigned int pos, bool tr(" could not be pasted.\nLikely the selected track is the wrong type.")); } - return finalPos; + if (finalPosPtr) *finalPosPtr=finalPos; + return operations; } @@ -2110,30 +2104,30 @@ void PartCanvas::paste(bool clone, bool toTrack, bool doInsert) return; } - int endPos=0; - unsigned int startPos=song->vcpos(); if (!txt.isEmpty()) { - song->startUndo(); - endPos=pasteAt(txt, track, startPos, clone, toTrack); + int endPos=0; + unsigned int startPos=song->vcpos(); + Undo operations=pasteAt(txt, track, startPos, clone, toTrack, &endPos); Pos p(endPos, true); song->setPos(0, p); - if (!doInsert) - song->endUndo(SC_PART_INSERTED); + if (doInsert) { + int offset = endPos-startPos; + Undo temp=movePartsTotheRight(startPos, offset); + operations.insert(operations.end(), temp.begin(), temp.end()); + } + song->applyOperationGroup(operations); } - if (doInsert) { - int offset = endPos-startPos; - movePartsTotheRight(startPos, offset); - song->endUndo(SC_PART_INSERTED); - } } //--------------------------------------------------------- // movePartsToTheRight //--------------------------------------------------------- -void PartCanvas::movePartsTotheRight(unsigned int startTicks, int length) +Undo PartCanvas::movePartsTotheRight(unsigned int startTicks, int length) { + Undo operations; + // all parts that start after the pasted parts will be moved the entire length of the pasted parts for (iCItem i = items.begin(); i != items.end(); ++i) { if (!i->second->isSelected()) { @@ -2141,12 +2135,8 @@ void PartCanvas::movePartsTotheRight(unsigned int startTicks, int length) if (part->tick() >= startTicks) { Part *newPart = part->clone(); newPart->setTick(newPart->tick()+length); - if (part->track()->type() == Track::WAVE) { - audio->msgChangePart((WavePart*)part,(WavePart*)newPart,false,false,false); - } else { - audio->msgChangePart(part,newPart,false,false,false); - } - + + operations.push_back(UndoOp(UndoOp::ModifyPart,part,newPart,false,false)); } } } @@ -2159,9 +2149,11 @@ void PartCanvas::movePartsTotheRight(unsigned int startTicks, int length) Marker *oldMarker = new Marker(); *oldMarker = *m; m->setTick(m->tick()+length); - song->addUndo(UndoOp(UndoOp::ModifyMarker,oldMarker, m)); + operations.push_back(UndoOp(UndoOp::ModifyMarker,oldMarker, m)); } } + + return operations; } //--------------------------------------------------------- // startDrag @@ -2284,11 +2276,11 @@ void PartCanvas::viewDropEvent(QDropEvent* event) Track* track = 0; if (trackNo < tracks->size()) track = tracks->index(trackNo); - if (track) { - song->startUndo(); - pasteAt(text, track, x); - song->endUndo(SC_PART_INSERTED); - } + if (track) + { + Undo temp=pasteAt(text, track, x); + song->applyOperationGroup(temp); + } } else if (type == 2) { @@ -2967,8 +2959,6 @@ double PartCanvas::valToDb(double inV) void PartCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir) { - song->startUndo(); - int dp = y2pitch(pos.y()) - y2pitch(start.y()); int dx = pos.x() - start.x(); @@ -2976,19 +2966,9 @@ void PartCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir) dp = 0; else if (dir == 2) dx = 0; + + moveCanvasItems(moving, dp, dx, dragtype); - - - int modified = 0; - - moveCanvasItems(moving, dp, dx, dragtype, &modified); - - if (dragtype == MOVE_COPY || dragtype == MOVE_CLONE) - modified|=SC_PART_INSERTED; - else - modified|=SC_PART_MODIFIED; - - song->endUndo(modified); moving.clear(); updateSelection(); redraw(); diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h index daa244b2..acfe565e 100644 --- a/muse2/muse/arranger/pcanvas.h +++ b/muse2/muse/arranger/pcanvas.h @@ -86,8 +86,8 @@ class PartCanvas : public Canvas { virtual void resizeItem(CItem*,bool); virtual void newItem(CItem*,bool); virtual bool deleteItem(CItem*); - virtual void moveCanvasItems(CItemList&, int, int, DragType, int*); - virtual bool moveItem(CItem*, const QPoint&, DragType); + virtual void moveCanvasItems(CItemList&, int, int, DragType); + virtual UndoOp moveItem(CItem*, const QPoint&, DragType); virtual void updateSong(DragType, int); virtual void startDrag(CItem*, DragType); @@ -102,8 +102,8 @@ class PartCanvas : public Canvas { void copy(PartList*); void paste(bool clone = false, bool toTrack = true, bool doInsert=false); - int pasteAt(const QString&, Track*, unsigned int, bool clone = false, bool toTrack = true); - void movePartsTotheRight(unsigned int startTick, int length); + Undo pasteAt(const QString&, Track*, unsigned int, bool clone = false, bool toTrack = true, int* finalPosPtr = NULL); + Undo movePartsTotheRight(unsigned int startTick, int length); //Part* readClone(Xml&, Track*, bool toTrack = true); void drawWavePart(QPainter&, const QRect&, WavePart*, const QRect&); //void drawMidiPart(QPainter&, const QRect& rect, EventList* events, MidiTrack*mt, const QRect& r, int pTick, int from, int to); diff --git a/muse2/muse/audio.h b/muse2/muse/audio.h index 940dd2a5..e332f516 100644 --- a/muse2/muse/audio.h +++ b/muse2/muse/audio.h @@ -124,7 +124,6 @@ class Audio { bool idle; // do nothing in idle mode bool _freewheel; bool _bounce; - //bool loopPassed; unsigned _loopFrame; // Startframe of loop if in LOOP mode. Not quite the same as left marker ! int _loopCount; // Number of times we have looped so far @@ -202,13 +201,9 @@ class Audio { 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); void msgChangePart(Part* oldPart, Part* newPart, bool u = true, bool doCtrls = true, bool doClones = false); - //void msgAddEvent(Event&, Part*, bool u = true); void msgAddEvent(Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false); - //void msgDeleteEvent(Event&, Part*, bool u = true); void msgDeleteEvent(Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false); - //void msgChangeEvent(Event&, Event&, Part*, bool u = true); void msgChangeEvent(Event&, Event&, Part*, bool u = true, bool doCtrls = true, bool doClones = false); void msgScanAlsaMidiPorts(); void msgAddTempo(int tick, int tempo, bool doUndoFlag = true); @@ -250,7 +245,6 @@ class Audio { void msgResetMidiDevices(); void msgIdle(bool); void msgBounce(); - //void msgSetPluginCtrlVal(PluginI* /*plugin*/, int /*param*/, double /*val*/); void msgSetPluginCtrlVal(AudioTrack*, int /*param*/, double /*val*/); void msgSwapControllerIDX(AudioTrack*, int, int); void msgClearControllerEvents(AudioTrack*, int); diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp index 4a65d19c..a6c9c95a 100644 --- a/muse2/muse/functions.cpp +++ b/muse2/muse/functions.cpp @@ -759,7 +759,7 @@ void paste_at(Part* dest_part, const QString& pt, int pos) goto end_of_paste_at; } else - xml.unknown("pasteAt"); + xml.unknown("paste_at"); break; case Xml::Attribut: diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 0ec300cf..ca88d36a 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4457,7 +4457,8 @@ void staff_t::update_part_indices() * * CURRENT TODO * o speed up list editor - * o speed up arranger + * o insert empty measure should also work inside parts + * o canvas editor: create clone via "alt+drag" moves window instead * * o rename stuff: UndoOp -> Operation, Undo -> OpList, * UndoType -> OpType, iUndoOp, riUndoOp -> iOperation, diff --git a/muse2/muse/seqmsg.cpp b/muse2/muse/seqmsg.cpp index 0aa74aaa..57aadc18 100644 --- a/muse2/muse/seqmsg.cpp +++ b/muse2/muse/seqmsg.cpp @@ -893,31 +893,23 @@ void Audio::msgRemovePart(Part* part, bool doUndoFlag) bool Song::msgRemoveParts() { - bool loop; + Undo operations; bool partSelected = false; - do { - loop = false; + TrackList* tl = 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()) { - if ((*it)->type() == Track::WAVE) { - audio->msgRemovePart((WavePart*)(ip->second)); - } - else { - audio->msgRemovePart(ip->second, false); - } - loop = true; + operations.push_back(UndoOp(UndoOp::DeletePart,ip->second)); partSelected = true; - break; } } - if (loop) - break; } - } while (loop); + + song->applyOperationGroup(operations); + return partSelected; } diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp index c57bb5c1..c5b211b2 100644 --- a/muse2/muse/undo.cpp +++ b/muse2/muse/undo.cpp @@ -480,6 +480,7 @@ void Song::doUndo2() break; case UndoOp::ModifyClip: case UndoOp::ModifyMarker: + case UndoOp::DoNothing: break; } } @@ -716,6 +717,7 @@ void Song::doRedo2() break; case UndoOp::ModifyClip: case UndoOp::ModifyMarker: + case UndoOp::DoNothing: break; } } @@ -725,6 +727,11 @@ UndoOp::UndoOp() { } +UndoOp::UndoOp(UndoType type_) +{ + type = type_; +} + UndoOp::UndoOp(UndoType type_, int a_, int b_, int c_) { type = type_; diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h index 88810b80..b8f69d9f 100644 --- a/muse2/muse/undo.h +++ b/muse2/muse/undo.h @@ -36,7 +36,8 @@ struct UndoOp { AddKey, DeleteKey, SwapTrack, ModifyClip, - ModifyMarker + ModifyMarker, + DoNothing }; UndoType type; @@ -99,6 +100,7 @@ struct UndoOp { UndoOp(UndoType type, SigEvent* oevent, SigEvent* nevent); UndoOp(UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe); UndoOp(UndoType type, Marker* copyMarker, Marker* realMarker); + UndoOp(UndoType type); }; class Undo : public std::list<UndoOp> { |