summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--muse2/muse/ctrl/ctrlcanvas.cpp399
-rw-r--r--muse2/muse/midiedit/dcanvas.cpp19
-rw-r--r--muse2/muse/midiedit/dcanvas.h2
-rw-r--r--muse2/muse/midiedit/ecanvas.cpp28
-rw-r--r--muse2/muse/midiedit/ecanvas.h3
-rw-r--r--muse2/muse/midiedit/prcanvas.cpp8
-rw-r--r--muse2/muse/midiedit/prcanvas.h2
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp8
-rw-r--r--muse2/muse/part.cpp48
-rw-r--r--muse2/muse/song.h2
-rw-r--r--muse2/muse/undo.cpp19
-rw-r--r--muse2/muse/widgets/canvas.h1
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();
/*!