summaryrefslogtreecommitdiff
path: root/muse2/muse/midiedit/dcanvas.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/muse/midiedit/dcanvas.cpp')
-rw-r--r--muse2/muse/midiedit/dcanvas.cpp207
1 files changed, 22 insertions, 185 deletions
diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp
index 89cb1e4c..92e514af 100644
--- a/muse2/muse/midiedit/dcanvas.cpp
+++ b/muse2/muse/midiedit/dcanvas.cpp
@@ -100,14 +100,14 @@ DrumCanvas::DrumCanvas(MidiEditor* pr, QWidget* parent, int sx,
// moveCanvasItems
//---------------------------------------------------------
-void 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;
+ return Undo(); //return empty list
PartsToChangeMap parts2change;
+ Undo operations;
- int modified = 0;
for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip)
{
Part* part = ip->second;
@@ -143,34 +143,6 @@ void DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp
if(npartoffset > 0)
{
- // Create new part...
- // if there are several events that are moved outside the part, it will be recreated for each
- // so the part _in_ the event will not be valid, ask the authority.
-// Part* newPart = part->clone();
- //Part* newPart = Canvas::part()->clone();
-
-// newPart->setLenTick(newPart->lenTick() + npartoffset);
- //audio->msgChangePart(part, newPart,false);
-
-// modified = SC_PART_MODIFIED;
-
- // BUG FIX: #1650953
- // Added by T356.
- // Fixes posted "select and drag past end of part - crashing" bug
-// for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip)
-// {
-// if(ip->second == part)
-// {
-// editor->parts()->erase(ip);
-// break;
-// }
-// }
-
-// editor->parts()->add(newPart);
-// audio->msgChangePart(part, newPart,false);
-
-// if(parts2change.find(part) == parts2change.end())
-// parts2change.insert(std::pair<Part*, Part*> (part, newPart));
iPartToChange ip2c = parts2change.find(part);
if(ip2c == parts2change.end())
{
@@ -179,14 +151,6 @@ void DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp
}
else
ip2c->second.xdiff = npartoffset;
-
-
- //part = newPart; // reassign
- //item->setPart(part);
- //item->setEvent(newEvent);
- //curPart = part;
- //curPartId = curPart->sn();
-
}
}
@@ -199,8 +163,6 @@ void 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
@@ -214,9 +176,8 @@ void DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp
}
editor->parts()->add(newPart);
- // Indicate no undo, and do port controller values but not clone parts.
- //audio->msgChangePart(opart, newPart, false);
- audio->msgChangePart(opart, newPart, false, true, false);
+ // Do port controller values but not clone parts.
+ operations.push_back(UndoOp(UndoOp::ModifyPart, opart, newPart, true, false));
ip2c->second.npart = newPart;
@@ -256,21 +217,12 @@ void DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp
break;
// Do not process if the event has already been processed (meaning it's an event in a clone part)...
- //if(moveItem(ci, newpos, dtype))
- if(idl != doneList.end())
- // Just move the canvas item.
- ci->move(newpos);
- else
+ if (idl == doneList.end())
{
- // Currently moveItem always returns true.
- if(moveItem(ci, newpos, dtype))
- {
- // Add the canvas item to the list of done items.
- doneList.push_back(ci);
- // Move the canvas item.
- ci->move(newpos);
- }
+ operations.push_back(moveItem(ci, newpos, dtype));
+ doneList.push_back(ci);
}
+ ci->move(newpos);
if(moving.size() == 1) {
itemReleased(curItem, newpos);
@@ -279,22 +231,17 @@ void DrumCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp
selectItem(ci, false);
}
- if(pflags)
- *pflags = modified;
+ return operations;
}
//---------------------------------------------------------
// moveItem
//---------------------------------------------------------
-// Changed by T356.
-//bool DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype, int* pflags)
-bool DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype)
+UndoOp DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype)
{
DEvent* nevent = (DEvent*) item;
- // Changed by T356.
- //MidiPart* part = (MidiPart*)Canvas::part(); // part can be dynamically recreated, ask the authority
MidiPart* part = (MidiPart*)nevent->part();
Event event = nevent->event();
@@ -310,40 +257,6 @@ bool DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype)
newEvent.setPitch(npitch);
newEvent.setTick(ntick);
- // Removed by T356.
- /*
- // Added by T356.
- int modified = 0;
- //song->startUndo();
- int diff = newEvent.endTick()-part->lenTick();
- if (diff > 0) // too short part? extend it
- {
- // if there are several events that are moved outside the part, it will be recreated for each
- // so the part _in_ the event will not be valid, ask the authority.
- //Part* newPart = part->clone();
- MidiPart* newPart = (MidiPart*)Canvas::part()->clone();
- newPart->setLenTick(newPart->lenTick()+diff);
- audio->msgChangePart(Canvas::part(), newPart,false);
-
- modified = SC_PART_MODIFIED;
- part = newPart; // reassign
- for(iPart i = editor->parts()->begin(); i != editor->parts()->end(); ++i)
- {
- if(i->second == Canvas::part())
- {
- editor->parts()->erase(i);
- break;
- }
- }
- editor->parts()->add(part);
- item->setPart(part);
- item->setEvent(newEvent);
- curPart = part;
- curPartId = curPart->sn();
- }
- */
-
- // Added by T356.
// msgAddEvent and msgChangeEvent (below) will set these, but set them here first?
//item->setPart(part);
item->setEvent(newEvent);
@@ -352,22 +265,10 @@ bool DrumCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype)
if(((int)newEvent.endTick() - (int)part->lenTick()) > 0)
printf("DrumCanvas::moveItem Error! New event end:%d exceeds length:%d of part:%s\n", newEvent.endTick(), part->lenTick(), part->name().toLatin1().constData());
- if (dtype == MOVE_COPY || dtype == MOVE_CLONE) {
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgAddEvent(newEvent, part, false);
- audio->msgAddEvent(newEvent, part, false, false, false);
- }
- else {
- // Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, newEvent, part, false);
- audio->msgChangeEvent(event, newEvent, part, false, false, false);
- }
-
- // Removed by T356.
- //if(pflags)
- // *pflags = modified;
-
- return true;
+ if (dtype == MOVE_COPY || dtype == MOVE_CLONE)
+ return UndoOp(UndoOp::AddEvent, newEvent, part, false, false);
+ else
+ return UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false);
}
//---------------------------------------------------------
@@ -412,7 +313,6 @@ void DrumCanvas::resizeItem(CItem* item, bool)
DEvent* nevent = (DEvent*) item;
Event ev = nevent->event();
// Indicate do undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(ev, nevent->part());
audio->msgDeleteEvent(ev, nevent->part(), true, false, false);
}
@@ -431,7 +331,6 @@ void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace)
if (!noSnap)
x = editor->rasterVal(x);
event.setTick(x - nevent->part()->tick());
- //int npitch = drumMap[y2pitch(item->y())].enote;
int npitch = event.pitch();
event.setPitch(npitch);
@@ -451,7 +350,6 @@ void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace)
if (ev.pitch() == npitch) {
// Indicate do undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(ev, nevent->part());
audio->msgDeleteEvent(ev, nevent->part(), true, false, false);
if (replace)
break;
@@ -470,16 +368,13 @@ void DrumCanvas::newItem(CItem* item, bool noSnap, bool replace)
Part* newPart = part->clone();
newPart->setLenTick(newPart->lenTick()+diff);
// Indicate no undo, and do port controller values but not clone parts.
- //audio->msgChangePart(part, newPart,false);
audio->msgChangePart(part, newPart, false, true, false);
modified=modified|SC_PART_MODIFIED;
part = newPart; // reassign
}
// Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgAddEvent(event, part,false);
audio->msgAddEvent(event, part, false, false, false);
song->endUndo(modified);
-
}
//---------------------------------------------------------
@@ -490,7 +385,6 @@ bool DrumCanvas::deleteItem(CItem* item)
{
Event ev = ((DEvent*)item)->event();
// Indicate do undo, and do not do port controller values and clone parts.
- //audio->msgDeleteEvent(ev, ((DEvent*)item)->part());
audio->msgDeleteEvent(ev, ((DEvent*)item)->part(), true, false, false);
return false;
}
@@ -559,10 +453,6 @@ void DrumCanvas::drawItem(QPainter&p, const CItem*item, const QRect& rect)
void DrumCanvas::drawMoving(QPainter& p, const CItem* item, const QRect& rect)
{
- //if(((DEvent*)item)->part() != curPart)
- // return;
- //if(!item->isMoving())
- // return;
QPolygon pa(4);
QPoint pt = map(item->mp());
int x = pt.x();
@@ -745,7 +635,6 @@ void DrumCanvas::cmd(int cmd)
Event newEvent = event.clone();
newEvent.setLenTick(drumMap[event.pitch()].len);
// Indicate no undo, and do not do port controller values and clone parts.
- //audio->msgChangeEvent(event, newEvent, devent->part() , false);
audio->msgChangeEvent(event, newEvent, devent->part(), false, false, false);
}
}
@@ -785,8 +674,6 @@ void DrumCanvas::cmd(int cmd)
case CMD_RIGHT_NOSNAP:
{
Pos p(pos[0] + editor->rasterStep(pos[0]), true);
- //if (p > part->tick())
- // p = part->tick();
song->setPos(0, p, true, true, true); //CDW
}
break;
@@ -796,7 +683,6 @@ void DrumCanvas::cmd(int cmd)
}
-
//---------------------------------------------------------
// startDrag
//---------------------------------------------------------
@@ -806,10 +692,6 @@ void DrumCanvas::startDrag(CItem* /* item*/, bool copymode)
QMimeData* md = selected_events_to_mime(partlist_to_set(editor->parts()), 1);
if (md) {
-// QApplication::clipboard()->setData(drag, QClipboard::Clipboard); // This line NOT enabled in muse-1
- //QApplication::clipboard()->setMimeData(md); // TODO CHECK Tim.
- //QApplication::clipboard()->setMimeData(drag->mimeData()); //
-
// "Note that setMimeData() assigns ownership of the QMimeData object to the QDrag object.
// The QDrag must be constructed on the heap with a parent QWidget to ensure that Qt can
// clean up after the drag and drop operation has been completed. "
@@ -848,6 +730,7 @@ void DrumCanvas::dragLeaveEvent(QDragLeaveEvent*)
{
}
+
//---------------------------------------------------------
// keyPressed - called from DList
//---------------------------------------------------------
@@ -890,13 +773,7 @@ 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;
@@ -951,16 +828,10 @@ void DrumCanvas::mapChanged(int spitch, int dpitch)
}
}
- song->startUndo();
for (idel_ev i = delete_events.begin(); i != delete_events.end(); i++) {
- //std::pair<Part*, Event*> pair = *i;
- //Part* thePart = pair.first;
- //Event* theEvent = pair.second;
Part* thePart = (*i).first;
Event* theEvent = (*i).second;
- // Indicate no undo, and do port controller values but not clone parts.
- //audio->msgDeleteEvent(*theEvent, thePart, false);
- audio->msgDeleteEvent(*theEvent, thePart, false, true, false);
+ operations.push_back(UndoOp(UndoOp::DeleteEvent, *theEvent, thePart, true, false));
}
DrumMap dm = drumMap[spitch];
@@ -972,18 +843,13 @@ void DrumCanvas::mapChanged(int spitch, int dpitch)
drumOutmap[int(drumMap[int(dpitch)].anote)] = dpitch;
for (iadd_ev i = add_events.begin(); i != add_events.end(); i++) {
- //std::pair<Part*, Event> pair = *i;
- //Part* thePart = pair.first;
- //Event& theEvent = pair.second;
Part* thePart = (*i).first;
Event& theEvent = (*i).second;
- // Indicate no undo, and do port controller values but not clone parts.
- //audio->msgAddEvent(theEvent, thePart, false);
- audio->msgAddEvent(theEvent, thePart, false, true, false);
+ operations.push_back(UndoOp(UndoOp::AddEvent, theEvent, thePart, true, false));
}
- song->endUndo(SC_EVENT_MODIFIED);
- 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()
}
//---------------------------------------------------------
@@ -1027,40 +893,12 @@ void DrumCanvas::modifySelected(NoteInfo::ValType type, int delta)
}
break;
case NoteInfo::VAL_LEN:
- /*
- {
- int len = event.lenTick() + delta;
- if (len < 1)
- len = 1;
- newEvent.setLenTick(len);
- }
- */
printf("DrumCanvas::modifySelected - NoteInfo::VAL_LEN not implemented\n");
break;
case NoteInfo::VAL_VELON:
- /*
- {
- int velo = event->velo() + delta;
- if (velo > 127)
- velo = 127;
- else if (velo < 0)
- velo = 0;
- newEvent.setVelo(velo);
- }
- */
printf("DrumCanvas::modifySelected - NoteInfo::VAL_VELON not implemented\n");
break;
case NoteInfo::VAL_VELOFF:
- /*
- {
- int velo = event.veloOff() + delta;
- if (velo > 127)
- velo = 127;
- else if (velo < 0)
- velo = 0;
- newEvent.setVeloOff(velo);
- }
- */
printf("DrumCanvas::modifySelected - NoteInfo::VAL_VELOFF not implemented\n");
break;
case NoteInfo::VAL_PITCH:
@@ -1076,8 +914,7 @@ void DrumCanvas::modifySelected(NoteInfo::ValType type, int delta)
}
song->changeEvent(event, newEvent, part);
// Indicate do not do port controller values and clone parts.
- //song->undoOp(UndoOp::ModifyEvent, newEvent, event, part);
- song->undoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false);
+ song->addUndo(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false));
}
song->endUndo(SC_EVENT_MODIFIED);
audio->msgIdle(false);