diff options
-rw-r--r-- | muse2/muse/ctrl/ctrlcanvas.cpp | 399 | ||||
-rw-r--r-- | muse2/muse/midiedit/dcanvas.cpp | 19 | ||||
-rw-r--r-- | muse2/muse/midiedit/dcanvas.h | 2 | ||||
-rw-r--r-- | muse2/muse/midiedit/ecanvas.cpp | 28 | ||||
-rw-r--r-- | muse2/muse/midiedit/ecanvas.h | 3 | ||||
-rw-r--r-- | muse2/muse/midiedit/prcanvas.cpp | 8 | ||||
-rw-r--r-- | muse2/muse/midiedit/prcanvas.h | 2 | ||||
-rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 8 | ||||
-rw-r--r-- | muse2/muse/part.cpp | 48 | ||||
-rw-r--r-- | muse2/muse/song.h | 2 | ||||
-rw-r--r-- | muse2/muse/undo.cpp | 19 | ||||
-rw-r--r-- | muse2/muse/widgets/canvas.h | 1 |
12 files changed, 77 insertions, 462 deletions
diff --git a/muse2/muse/ctrl/ctrlcanvas.cpp b/muse2/muse/ctrl/ctrlcanvas.cpp index f2f335cf..d1d6b2fa 100644 --- a/muse2/muse/ctrl/ctrlcanvas.cpp +++ b/muse2/muse/ctrl/ctrlcanvas.cpp @@ -545,14 +545,6 @@ void CtrlCanvas::partControllers(const MidiPart* part, int num, int* dnum, int* } *mcvl = tmcvl; - // Removed by T356. - // MidiCtrlValList not found is now an acceptable state (for multiple part editing). - //if (i == cvll->end()) { - // printf("CtrlCanvas::setController(0x%x): not found\n", num); - // for (i = cvll->begin(); i != cvll->end(); ++i) - // printf(" 0x%x\n", i->second->num()); - // return; - // } } } } @@ -566,98 +558,9 @@ void CtrlCanvas::updateItems() selection.clear(); items.clearDelete(); - /* - if(ctrl) - { - for(ciMidiCtrlVal imcv = ctrl->begin(); imcv != ctrl->end(); ++imcv) - { - MidiPart* part = (MidiPart*)imcv->part; - int val = imcv->val; - - bool edpart = false; - if(editor->parts()->index(part) != -1) - edpart = true; - - MidiController* mc; - MidiCtrlValList* mcvl; - partControllers(part, _cnum, 0, 0, &mc, &mcvl); - - Event e(Controller); - - if(_cnum == CTRL_VELOCITY && e.type() == Note) - { - items.add(new CEvent(e, part, e.velo())); - - } - - } - } - */ - - /* - MidiTrackList* mtl = song->midis(); - for(ciMidiTrack imt = mtl->begin(); imt != mtl->end(); ++imt) - { - //MidiTrack* mt = *imt; - PartList* pl = (*imt)->parts(); - for(ciPart p = pl->begin(); p != pl->end(); ++p) - { - MidiPart* part = (MidiPart*)(p->second); - - bool edpart = false; - if(editor->parts()->index(part) != -1) - edpart = true; - - EventList* el = part->events(); - MidiController* mc; - MidiCtrlValList* mcvl; - partControllers(part, _cnum, 0, 0, &mc, &mcvl); - - for(iEvent i = el->begin(); i != el->end(); ++i) - { - Event e = i->second; - if(_cnum == CTRL_VELOCITY && e.type() == Note) - { - if(curDrumInstrument == -1) - { - items.add(new CEvent(e, part, e.velo())); - } - else if (e.dataA() == curDrumInstrument) //same note - items.add(new CEvent(e, part, e.velo())); - } - else if (e.type() == Controller && e.dataA() == _didx) - { - if(mcvl && last.empty()) - { - Event le(Controller); - //le.setType(Controller); - le.setA(_didx); - //le.setB(e.dataB()); - le.setB(CTRL_VAL_UNKNOWN); - //lastce = new CEvent(Event(), part, mcvl->value(part->tick(), part)); - //lastce = new CEvent(le, part, mcvl->value(part->tick(), part)); - lastce = new CEvent(le, part, mcvl->value(part->tick())); - items.add(lastce); - } - if (lastce) - lastce->setEX(e.tick()); - lastce = new CEvent(e, part, e.dataB()); - items.add(lastce); - last = e; - } - } - } - } - */ - - - - if(!editor->parts()->empty()) { - //Event last; - //CEvent* lastce = 0; CEvent *newev = 0; for (iPart p = editor->parts()->begin(); p != editor->parts()->end(); ++p) @@ -790,7 +693,6 @@ void CtrlCanvas::viewMousePressEvent(QMouseEvent* event) } if(do_redraw) redraw(); // Let songChanged handle the redraw upon SC_SELECTION. - //song->update(SC_SELECTION); // } @@ -947,11 +849,8 @@ void CtrlCanvas::viewMouseReleaseEvent(QMouseEvent* event) } } drag = DRAG_OFF; - //if(do_redraw) - // redraw(); // Let songChanged handle the redraw upon SC_SELECTION. + // Let songChanged handle the redraw upon SC_SELECTION. song->update(SC_SELECTION); // - //else - // redraw(); } break; @@ -995,7 +894,7 @@ void CtrlCanvas::newValRamp(int x1, int y1, int x2, int y2) useRaster = true; } - song->startUndo(); + Undo operations; // delete existing events @@ -1003,44 +902,29 @@ void CtrlCanvas::newValRamp(int x1, int y1, int x2, int y2) int lastpv = CTRL_VAL_UNKNOWN; for (ciCEvent i = items.begin(); i != items.end(); ++i) { CEvent* ev = *i; - if(ev->part() != curPart) + if (ev->part() != curPart) continue; Event event = ev->event(); if (event.empty()) continue; int x = event.tick() + curPartTick; - //printf("CtrlCanvas::newValRamp x:%d xx1:%d xx2:%d len:%d\n", x, xx1, xx2, curPart->lenTick()); if (x < xx1) - { - // if(event.dataB() != CTRL_VAL_UNKNOWN) - // lastpv = event.dataB(); continue; - } - //if (x <= xx1) - //{ - // if(type == CTRL_PROGRAM && event.dataB() != CTRL_VAL_UNKNOWN && ((event.dataB() & 0xffffff) != 0xffffff)) - // lastpv = event.dataB(); - // if (x < xx1) - // continue; - //} + if (x >= xx2) break; - // Indicate no undo, and do port controller values and clone parts. - audio->msgDeleteEvent(event, curPart, false, true, true); + // Do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::DeleteEvent, event, curPart, true, true)); } - //if(type == CTRL_PROGRAM && lastpv == CTRL_VAL_UNKNOWN) - if(ctrl) + if (ctrl) lastpv = ctrl->hwVal(); unsigned curPartLen = curPart->lenTick(); // insert new events - //for (int x = xx1; x < xx2; x += raster) { - // int y = (x2==x1) ? y1 : (((y2-y1)*(x-x1))/(x2-x1))+y1; - // int nval = computeVal(_controller, y, height()); for (int x = xx1, step; x < xx2 ; x += step ) { step = useRaster ? raster : editor->rasterVal2(x + 1) - x; @@ -1048,21 +932,18 @@ void CtrlCanvas::newValRamp(int x1, int y1, int x2, int y2) int y = x + step >= xx2 || x2 == x1 ? y2 : (x == xx1 ? y1 : (((y2 - y1) * (x + step/2 - x1)) / (x2 - x1)) + y1); int nval = computeVal(_controller, y, height()); - //int tick = x - curPartTick; unsigned tick = x - curPartTick; - //printf("CtrlCanvas::newValRamp x:%d xx1:%d xx2:%d step:%d newtick:%d\n", x, xx1, xx2, step, tick); // Do not add events which are past the end of the part. - //if((unsigned)tick >= curPartLen) - if(tick >= curPartLen) + if (tick >= curPartLen) break; Event event(Controller); event.setTick(tick); event.setA(_didx); - if(type == CTRL_PROGRAM) + if (type == CTRL_PROGRAM) { - if(lastpv == CTRL_VAL_UNKNOWN) + if (lastpv == CTRL_VAL_UNKNOWN) { - if(song->mtype() == MT_GM) + if (song->mtype() == MT_GM) event.setB(0xffff00 | (nval - 1)); else event.setB(nval - 1); @@ -1073,13 +954,11 @@ void CtrlCanvas::newValRamp(int x1, int y1, int x2, int y2) else event.setB(nval); - // Indicate no undo, and do port controller values and clone parts. - audio->msgAddEvent(event, curPart, false, true, true); + // Do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::AddEvent, event, curPart, true, true)); } - ///song->update(0); - ///redraw(); - song->endUndo(SC_EVENT_MODIFIED | SC_EVENT_INSERTED | SC_EVENT_REMOVED); + song->applyOperationGroup(operations); } //--------------------------------------------------------- @@ -1091,27 +970,24 @@ void CtrlCanvas::changeValRamp(int x1, int y1, int x2, int y2) int h = height(); bool changed = false; int type = _controller->num(); - //int xx1 = editor->rasterVal1(x1); - song->startUndo(); + Undo operations; for (ciCEvent i = items.begin(); i != items.end(); ++i) { if ((*i)->contains(x1, x2)) { - //if ((*i)->contains(xx1, x2)) { CEvent* ev = *i; - if(ev->part() != curPart) + if (ev->part() != curPart) continue; + Event event = ev->event(); if (event.empty()) continue; - //MidiPart* part = ev->part(); - //int x = event.tick() + ev->part()->tick(); int x = event.tick() + curPart->tick(); int y = (x2==x1) ? y1 : (((y2-y1)*(x-x1))/(x2-x1))+y1; int nval = computeVal(_controller, y, h); - if(type == CTRL_PROGRAM) + if (type == CTRL_PROGRAM) { - if(event.dataB() == CTRL_VAL_UNKNOWN) + if (event.dataB() == CTRL_VAL_UNKNOWN) { --nval; if(song->mtype() == MT_GM) @@ -1123,16 +999,13 @@ void CtrlCanvas::changeValRamp(int x1, int y1, int x2, int y2) ev->setVal(nval); - //MidiController::ControllerType type = midiControllerType(_controller->num()); - //if (type == MidiController::Velo) { if (type == CTRL_VELOCITY) { if ((event.velo() != nval)) { Event newEvent = event.clone(); newEvent.setVelo(nval); ev->setEvent(newEvent); - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, curPart, false, false, false); - ///ev->setEvent(newEvent); + // Do not do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, curPart, false, false)); changed = true; } } @@ -1142,34 +1015,16 @@ void CtrlCanvas::changeValRamp(int x1, int y1, int x2, int y2) Event newEvent = event.clone(); newEvent.setB(nval); ev->setEvent(newEvent); - // Indicate no undo, and do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, curPart, false, true, true); - ///ev->setEvent(newEvent); + // Do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, curPart, true, true)); changed = true; } } - else { - //if(!ctrl) - //{ - // ctrl = - //} - - // Removed by T356. Never gets here? A good thing, don't wan't auto-create values. - //int oval = ctrl->value(0); - //if (oval != nval) { - // Changed by T356. - //ctrl->add(0, nval); - // ctrl->add(0, nval, part); - // changed = true; - // } - - } } } } - ///if (changed) - /// redraw(); - song->endUndo(SC_EVENT_MODIFIED); + + song->applyOperationGroup(operations); } //--------------------------------------------------------- @@ -1181,7 +1036,6 @@ void CtrlCanvas::changeVal(int x1, int x2, int y) bool changed = false; int newval = computeVal(_controller, y, height()); int type = _controller->num(); - //int xx1 = editor->rasterVal1(x1); for (ciCEvent i = items.begin(); i != items.end(); ++i) { if (!(*i)->contains(x1, x2)) @@ -1191,26 +1045,7 @@ void CtrlCanvas::changeVal(int x1, int x2, int y) if(ev->part() != curPart) continue; Event event = ev->event(); - //if(event.tick() >= curPart->lenTick()) - // break; - - //MidiPart* part = ev->part(); - //int nval = newval; - //if(type == CTRL_PROGRAM) - //{ - // if(event.dataB() == CTRL_VAL_UNKNOWN) - // { - // --nval; - // if(song->mtype() == MT_GM) - // nval |= 0xffff00; - // } - // else - // nval = (event.dataB() & 0xffff00) | (nval - 1); - //} - //ev->setVal(nval); - - //MidiController::ControllerType type = midiControllerType(_controller->num()); - //if (type == MidiController::Velo) { + if (type == CTRL_VELOCITY) { if ((event.velo() != newval)) { ev->setVal(newval); @@ -1249,160 +1084,12 @@ void CtrlCanvas::changeVal(int x1, int x2, int y) changed = true; } } - else { - //if(!ctrl) - //{ - // ctrl = - //} - - // Removed by T356. Never gets here? A good thing, don't wan't auto-create values. - //int oval = ctrl->value(0); - //if (oval != nval) { - // Changed by T356. - //ctrl->add(0, nval); - // ctrl->add(0, nval, part); - // changed = true; - // } - } } } if (changed) redraw(); } -/* -//--------------------------------------------------------- -// newVal -//--------------------------------------------------------- - -void CtrlCanvas::newVal(int x1, int x2, int y) - { - int xx1 = editor->rasterVal1(x1); - int xx2 = editor->rasterVal2(x2); - int newval = computeVal(_controller, y, height()); - int type = _controller->num(); - - bool found = false; - bool song_changed = false; - - int lastpv = CTRL_VAL_UNKNOWN; - if(ctrl) - lastpv = ctrl->hwVal(); - - for (ciCEvent i = items.begin(); i != items.end(); ++i) { - CEvent* ev = *i; - if(ev->part() != curPart) - continue; - //int partTick = ev->part()->tick(); - int partTick = curPart->tick(); - Event event = ev->event(); - if (event.empty()) - continue; - int ax = event.tick() + partTick; - //printf("CtrlCanvas::newVal ax:%d xx1:%d xx2:%d len:%d\n", ax, xx1, xx2, curPart->lenTick()); - - if (ax < xx1) - continue; - //if(ax <= xx1) - //{ - // if(type == CTRL_PROGRAM && event.dataB() != CTRL_VAL_UNKNOWN && ((event.dataB() & 0xffffff) != 0xffffff)) - // lastpv = event.dataB(); - // if(ax < xx1) - // continue; - //} - if (ax >= xx2) - break; - - // Added by T356. Do not add events which are past the end of the part. - //if(event.tick() >= curPart->lenTick()) - // break; - - int nval = newval; - if(type == CTRL_PROGRAM) - { - if(event.dataB() == CTRL_VAL_UNKNOWN) - { - //if(lastpv == CTRL_VAL_UNKNOWN) - // lastpv = ctrl->hwVal(); - - if(lastpv == CTRL_VAL_UNKNOWN) - { - --nval; - if(song->mtype() == MT_GM) - nval |= 0xffff00; - } - else - nval = (lastpv & 0xffff00) | (nval - 1); - } - else - nval = (event.dataB() & 0xffff00) | (nval - 1); - } - - if (ax == xx1) { - // change event - found = true; - ev->setVal(nval); - if ((event.dataB() != nval)) { - Event newEvent = event.clone(); - newEvent.setB(nval); - // Indicate no undo, and do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, curPart, false, true, true); - ev->setEvent(newEvent); - song_changed = true; - } - } - else if (ax < xx2) { - // delete event - - //printf("CtrlCanvas::newVal delete xx1:%d xx2:%d len:%d\n", xx1, xx2, curPart->lenTick()); - - // Indicate no undo, and do port controller values and clone parts. - audio->msgDeleteEvent(event, curPart, false, true, true); - - song_changed = true; - } - } - if (!found) { - // new event - int tick = xx1 - curPart->tick(); - // Do not add events which are past the end of the part. - if((unsigned)tick < curPart->lenTick()) - { - Event event(Controller); - event.setTick(tick); - event.setA(_didx); - if(type == CTRL_PROGRAM) - { - if(lastpv == CTRL_VAL_UNKNOWN) - { - if(song->mtype() == MT_GM) - event.setB(0xffff00 | (newval - 1)); - else - event.setB(newval - 1); - } - else - event.setB((lastpv & 0xffff00) | (newval - 1)); - } - else - event.setB(newval); - - //printf("CtrlCanvas::newVal add tick:%d A:%d B:%d\n", tick, event.dataA(), event.dataB()); - - // Indicate no undo, and do port controller values and clone parts. - audio->msgAddEvent(event, curPart, false, true, true); - - song_changed = true; - } - } - if (song_changed) - { - songChanged(0); - return; - } - redraw(); - } -*/ - //--------------------------------------------------------- // newVal //--------------------------------------------------------- @@ -1607,10 +1294,7 @@ void CtrlCanvas::newVal(int x1, int y) } } - //if(do_selchanged) - // song->update(SC_SELECTION); // Let songChanged handle the redraw upon SC_SELECTION. - //else - if(do_redraw) // + if(do_redraw) // Let songChanged handle the redraw upon SC_SELECTION. redraw(); } @@ -1637,12 +1321,8 @@ void CtrlCanvas::newVal(int x1, int y1, int x2, int y2) // So I draw from the first x. (TODO The idea may work now since I wrote this - more work was done.) p4.0.18 Tim. int xx1 = editor->rasterVal1(x1); - // Grab the 'second' raster. Nudge by +1 and let rasterVal2 snap to the next raster. - //int xn1 = editor->rasterVal2(xx1 + 1); int xx2 = editor->rasterVal2(x2); - // Grab the 'second last' raster. Nudge by -1 and let rasterVal1 snap to the previous raster. - //int xn2 = editor->rasterVal1(xx2 - 1); // If x1 and x2 happen to lie directly on the same raster, xx1 will equal xx2, // which is not good - there should always be a spread. Nudge by +1 and recompute. @@ -1661,7 +1341,6 @@ void CtrlCanvas::newVal(int x1, int y1, int x2, int y2) } bool do_redraw = false; - //bool do_selchanged = false; // delete existing events @@ -1671,7 +1350,6 @@ void CtrlCanvas::newVal(int x1, int y1, int x2, int y2) bool curPartFound = false; int lastpv = CTRL_VAL_UNKNOWN; int partTick = curPart->tick(); - //for (ciCEvent i = items.begin(); i != items.end(); ++i) for (iCEvent i = items.begin(); i != items.end() ; ) { CEvent* ev = *i; @@ -1701,10 +1379,7 @@ void CtrlCanvas::newVal(int x1, int y1, int x2, int y2) //printf("CtrlCanvas::newVal x:%d xx1:%d xx2:%d len:%d\n", x, xx1, xx2, curPart->lenTick()); if (x < xx1) - //if (x < (xn1 >= xx2 ? xx1 : xn1)) { - // if(event.dataB() != CTRL_VAL_UNKNOWN) - // lastpv = event.dataB(); prev_ev = i; ++i; continue; @@ -1739,24 +1414,14 @@ void CtrlCanvas::newVal(int x1, int y1, int x2, int y2) } do_redraw = true; // Let songChanged handle the redraw upon SC_SELECTION. - //do_selchanged = true; // prev_ev = i; } - //if(type == CTRL_PROGRAM && lastpv == CTRL_VAL_UNKNOWN) if(ctrl) lastpv = ctrl->hwVal(); // insert new events - //for (int x = xx1; x < xx2; x += raster) { - // Nudge x by +1 and let rasterVal2 snap to the next raster. - //for (int x = xx1; x < xx2; x = useRaster ? x + raster : editor->rasterVal2(x + 1)) - //for (int x = xn1; x < xx2; x = useRaster ? x + raster : editor->rasterVal2(x + 1)) - //for (int x = xn1, step; x < xx2 ; x += (step = useRaster ? raster : editor->rasterVal2(x + 1) - x) ) - // Start from the 'second' raster - the first raster is already set in mouseDown! - //for (int x = xn1, step; x < xx2 ; x += step ) - //for (int x = xn1 >= xx2 ? xx1 : xn1, step; x < xx2 ; x += step ) for (int x = xx1, step; x < xx2 ; x += step ) { step = useRaster ? raster : editor->rasterVal2(x + 1) - x; @@ -1808,9 +1473,6 @@ void CtrlCanvas::newVal(int x1, int y1, int x2, int y2) do_redraw = true; } - //if(do_selchanged) - // song->update(SC_SELECTION); // Let songChanged handle the redraw upon SC_SELECTION. - //else if(do_redraw) // redraw(); } @@ -1841,10 +1503,8 @@ void CtrlCanvas::deleteVal(int x1, int x2, int) iCEvent prev_ev = items.end(); bool curPartFound = false; - //bool song_changed = false; bool do_redraw = false; - //for (ciCEvent i = items.begin(); i != items.end(); ++i) for (iCEvent i = items.begin(); i != items.end() ;) { CEvent* ev = *i; @@ -1895,13 +1555,8 @@ void CtrlCanvas::deleteVal(int x1, int x2, int) prev_ev = i; } - //if (song_changed) { - // songChanged(0); - // return; - // } if(do_redraw) redraw(); // Let songChanged handle the redraw upon SC_SELECTION. - //song->update(SC_SELECTION); // } //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index a61b5001..61e98aea 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -95,7 +95,7 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx, // moveCanvasItems //--------------------------------------------------------- -Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, int* pflags) +Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype) { if(editor->parts()->empty()) return Undo(); //return empty list @@ -103,7 +103,6 @@ Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp PartsToChangeMap parts2change; Undo operations; - int modified = 0; for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip) { Part* part = ip->second; @@ -159,8 +158,6 @@ Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp newPart->setLenTick(newPart->lenTick() + diff); - modified = SC_PART_MODIFIED; - // BUG FIX: #1650953 // Added by T356. // Fixes posted "select and drag past end of part - crashing" bug @@ -229,9 +226,6 @@ Undo DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp selectItem(ci, false); } - if(pflags) - *pflags = modified; - return operations; } @@ -818,13 +812,6 @@ void DrumCanvas::keyReleased(int index, bool) void DrumCanvas::mapChanged(int spitch, int dpitch) { - //TODO: Circumvent undo behaviour, since this isn't really a true change of the events, - // but merely a change in pitch because the pitch relates to the order of the dlist. - // Right now the sequencer spits out internalError: undoOp without startUndo() if start/stopundo is there, which is misleading - // If start/stopundo is there, undo misbehaves since it doesn't undo but messes things up - // Other solution: implement a specific undo-event for this (SC_DRUMMAP_MODIFIED or something) which undoes movement of - // dlist-items (ml) - Undo operations; std::vector< std::pair<Part*, Event*> > delete_events; std::vector< std::pair<Part*, Event> > add_events; @@ -900,8 +887,8 @@ void DrumCanvas::mapChanged(int spitch, int dpitch) operations.push_back(UndoOp(UndoOp::AddEvent, theEvent, thePart, true, false)); } - song->applyOperationGroup(operations); - song->update(SC_DRUMMAP); + song->applyOperationGroup(operations, false); // do not indicate undo + song->update(SC_DRUMMAP); //this update is neccessary, as it's not handled by applyOperationGroup() } //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index 748dd74f..cc3b8fff 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -50,7 +50,7 @@ class DrumCanvas : public EventCanvas { virtual void drawItem(QPainter&, const CItem*, const QRect&); void drawTopItem(QPainter& p, const QRect& rect); virtual void drawMoving(QPainter&, const CItem*, const QRect&); - virtual Undo moveCanvasItems(CItemList&, int, int, DragType, int*); + virtual Undo moveCanvasItems(CItemList&, int, int, DragType); virtual UndoOp moveItem(CItem*, const QPoint&, DragType); virtual CItem* newItem(const QPoint&, int); virtual void resizeItem(CItem*, bool); diff --git a/muse2/muse/midiedit/ecanvas.cpp b/muse2/muse/midiedit/ecanvas.cpp index e084c212..9ce84147 100644 --- a/muse2/muse/midiedit/ecanvas.cpp +++ b/muse2/muse/midiedit/ecanvas.cpp @@ -101,16 +101,6 @@ QPoint EventCanvas::raster(const QPoint& p) const } //--------------------------------------------------------- -// update -//--------------------------------------------------------- - -void EventCanvas::updateSong(DragType dtype, int flags) - { - song->update(flags | ((dtype == MOVE_COPY || dtype == MOVE_CLONE) - ? SC_EVENT_INSERTED : SC_EVENT_MODIFIED)); - } - -//--------------------------------------------------------- // mouseMove //--------------------------------------------------------- @@ -465,7 +455,7 @@ void EventCanvas::pasteAt(const QString& pt, int pos) return; case Xml::TagStart: if (tag == "eventlist") { - song->startUndo(); + Undo operations; EventList* el = new EventList(); el->read(xml, "eventlist", true); int modified = SC_EVENT_INSERTED; @@ -474,7 +464,6 @@ void EventCanvas::pasteAt(const QString& pt, int pos) int tick = e.tick() + pos - curPart->tick(); if (tick<0) { printf("ERROR: trying to add event before current part!\n"); - song->endUndo(SC_EVENT_INSERTED); delete el; return; } @@ -484,15 +473,15 @@ void EventCanvas::pasteAt(const QString& pt, int pos) if (diff > 0) {// too short part? extend it Part* newPart = curPart->clone(); newPart->setLenTick(newPart->lenTick()+diff); - // Indicate no undo, and do port controller values but not clone parts. - audio->msgChangePart(curPart, newPart, false, true, false); + // Do port controller values but not clone parts. + operations.push_back(UndoOp(UndoOp::ModifyPart, curPart, newPart, true, false)); modified=modified|SC_PART_MODIFIED; curPart = newPart; // reassign } - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgAddEvent(e, curPart, false, false, false); + // Do not do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::AddEvent, e, curPart, false, false)); } - song->endUndo(modified); + song->applyOperationGroup(operations); delete el; return; } @@ -556,11 +545,8 @@ void EventCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir) - int modified = 0; - - Undo operations = moveCanvasItems(moving, dp, dx, dragtype, &modified); + Undo operations = moveCanvasItems(moving, dp, dx, dragtype); song->applyOperationGroup(operations); - updateSong(dragtype, modified); moving.clear(); updateSelection(); diff --git a/muse2/muse/midiedit/ecanvas.h b/muse2/muse/midiedit/ecanvas.h index 23875598..b3275607 100644 --- a/muse2/muse/midiedit/ecanvas.h +++ b/muse2/muse/midiedit/ecanvas.h @@ -53,10 +53,9 @@ class EventCanvas : public Canvas { virtual void addItem(Part*, Event&) = 0; // Added by T356. virtual QPoint raster(const QPoint&) const; - virtual Undo moveCanvasItems(CItemList&, int, int, DragType, int*) = 0; + virtual Undo moveCanvasItems(CItemList&, int, int, DragType) = 0; virtual UndoOp moveItem(CItem*, const QPoint&, DragType) = 0; virtual void endMoveItems(const QPoint&, DragType, int dir); - virtual void updateSong(DragType, int flags = 0); public slots: void redrawGrid() { redraw(); } diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index 6845bd12..05fe8252 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -258,7 +258,7 @@ void PianoCanvas::viewMouseDoubleClickEvent(QMouseEvent* event) // moveCanvasItems //--------------------------------------------------------- -Undo PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, int* pflags) +Undo PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype) { if(editor->parts()->empty()) return Undo(); //return empty list @@ -266,7 +266,6 @@ Undo PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty Undo operations; PartsToChangeMap parts2change; - int modified = 0; for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip) { Part* part = ip->second; @@ -322,8 +321,6 @@ Undo PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty newPart->setLenTick(newPart->lenTick() + diff); - modified = SC_PART_MODIFIED; - // BUG FIX: #1650953 // Added by T356. // Fixes posted "select and drag past end of part - crashing" bug @@ -392,9 +389,6 @@ Undo PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty selectItem(ci, false); } - if(pflags) - *pflags = modified; - return operations; } diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h index 94827354..7c77b229 100644 --- a/muse2/muse/midiedit/prcanvas.h +++ b/muse2/muse/midiedit/prcanvas.h @@ -49,7 +49,7 @@ class PianoCanvas : public EventCanvas { virtual void drawItem(QPainter&, const CItem*, const QRect&); void drawTopItem(QPainter &p, const QRect &rect); virtual void drawMoving(QPainter&, const CItem*, const QRect&); - virtual Undo moveCanvasItems(CItemList&, int, int, DragType, int*); + virtual Undo moveCanvasItems(CItemList&, int, int, DragType); virtual UndoOp moveItem(CItem*, const QPoint&, DragType); virtual CItem* newItem(const QPoint&, int); virtual void resizeItem(CItem*, bool noSnap); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index b60b6dbd..7f7382f4 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -4221,12 +4221,6 @@ void staff_t::apply_lasso(QRect rect, set<Event*>& already_processed) * o rename stuff: UndoOp -> Operation, Undo -> OpList, * UndoType -> OpType, iUndoOp, riUndoOp -> iOperation, * undo.cpp/.h -> operations.cpp/.h - * o resizing a part is slow, because events get erased - * o drag'n'drop in canvases is slow - * o drawing controller lines is slow - * o cut,copy'n'paste is slow - * o reordering drum list is dead slow - * o reordering drum list creates unneccessary, actually wrong undo entry * * * o drum list: scroll while dragging @@ -4241,8 +4235,6 @@ void staff_t::apply_lasso(QRect rect, set<Event*>& already_processed) * o legato: extend length to next note * o delete: add velo and len threshold * o thin out: remove unneeded ctrl messages - * o in drum roll: changing the list causes undo to be triggered, WTF? - * o changing list is dead slow * * less important stuff * o controller view in score editor diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index c9459c1f..231b947b 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -833,7 +833,7 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len) // - 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()) { - startUndo(); + Undo operations; for (iEvent i = el->begin(); i != el->end(); i++) { Event e = i->second; @@ -843,31 +843,30 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len) if (event_endframe < new_partlength) continue; if (event_startframe > new_partlength) { // If event start was after the new length, remove it from part - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgDeleteEvent(e, nPart, false); - audio->msgDeleteEvent(e, nPart, false, false, false); + // Do not do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::DeleteEvent, e, nPart, false, false)); continue; } if (event_endframe > new_partlength) { // If this event starts before new length and ends after, shrink it Event newEvent = e.clone(); newEvent.setLenFrame(new_partlength - event_startframe); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(e, newEvent, nPart, false); + // Do not do port controller values and clone parts. audio->msgChangeEvent(e, newEvent, nPart, false, false, false); + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, e, nPart, false,false)); } } nPart->setLenFrame(new_partlength); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangePart(oPart, nPart, false); - audio->msgChangePart(oPart, nPart, false, false, false); + // Do not do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::ModifyPart, oPart, nPart, false, false)); - endUndo(SC_PART_MODIFIED); + 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(); @@ -887,33 +886,27 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len) new_eventlength = clipframes; newEvent.setLenFrame(new_eventlength); - startUndo(); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(last, newEvent, nPart, false); - audio->msgChangeEvent(last, newEvent, nPart, false, false, false); - } - else - { - startUndo(); + // Do not do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, last, nPart, false, false)); } nPart->setLenFrame(new_partlength); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangePart(oPart, nPart, false); + // Do not do port controller values and clone parts. audio->msgChangePart(oPart, nPart, false, false, false); - endUndo(SC_PART_MODIFIED); + operations.push_back(UndoOp(UndoOp::ModifyPart, oPart, nPart, false, false)); + song->applyOperationGroup(operations); } } break; case Track::MIDI: case Track::DRUM: { - startUndo(); + Undo operations; MidiPart* nPart = new MidiPart(*(MidiPart*)oPart); nPart->setLenTick(len); - // Indicate no undo, and do port controller values but not clone parts. - audio->msgChangePart(oPart, nPart, false, true, false); + // Do port controller values but not clone parts. + operations.push_back(UndoOp(UndoOp::ModifyPart, oPart, nPart, true, false)); // cut Events in nPart // Changed by T356. Don't delete events if this is a clone part. @@ -926,14 +919,13 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len) for (; ie != el->end();) { iEvent i = ie; ++ie; - // Indicate no undo, and do port controller values and clone parts. - audio->msgDeleteEvent(i->second, nPart, false, true, true); //FINDMICH + // Do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::DeleteEvent, i->second, nPart, true, true)); } } } - - endUndo(SC_PART_MODIFIED); + song->applyOperationGroup(operations); break; } default: diff --git a/muse2/muse/song.h b/muse2/muse/song.h index cb9d0f9d..17d70833 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -147,7 +147,7 @@ class Song : public QObject { Song(const char* name = 0); ~Song(); - void applyOperationGroup(Undo& group); + void applyOperationGroup(Undo& group, bool doUndo=true); void putEvent(int pv); void endMsgCmd(); diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp index 2b90e26f..2a11c3dc 100644 --- a/muse2/muse/undo.cpp +++ b/muse2/muse/undo.cpp @@ -14,6 +14,8 @@ #include "song.h" #include "globals.h" +#include <QAction> + // iundo points to last Undo() in Undo-list static bool undoMode = false; // for debugging @@ -201,12 +203,21 @@ void Song::endUndo(int flags) } -void Song::applyOperationGroup(Undo& group) +void Song::applyOperationGroup(Undo& group, bool doUndo) +{ + if (!group.empty()) { - //this is a HACK! but it works :) (added by flo93) - redoList->push_back(group); - redo(); + //this is a HACK! but it works :) (added by flo93) + redoList->push_back(group); + redo(); + + if (!doUndo) + { + undoList->pop_back(); + undoAction->setEnabled(!undoList->empty()); + } } +} diff --git a/muse2/muse/widgets/canvas.h b/muse2/muse/widgets/canvas.h index 5037bf37..2eae3d03 100644 --- a/muse2/muse/widgets/canvas.h +++ b/muse2/muse/widgets/canvas.h @@ -105,7 +105,6 @@ class Canvas : public View { virtual void resizeItem(CItem*, bool noSnap=false) = 0; virtual void newItem(CItem*, bool noSnap=false) = 0; virtual bool deleteItem(CItem*) = 0; - virtual void updateSong(DragType, int flags) = 0; int getCurrentDrag(); /*! |