diff options
Diffstat (limited to 'muse2/muse/midiedit/dcanvas.cpp')
-rw-r--r-- | muse2/muse/midiedit/dcanvas.cpp | 207 |
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); |