diff options
78 files changed, 568 insertions, 1552 deletions
diff --git a/muse2/awl/midimeter.h b/muse2/awl/midimeter.h index 2b0d3518..929e648c 100644 --- a/muse2/awl/midimeter.h +++ b/muse2/awl/midimeter.h @@ -31,8 +31,9 @@ namespace Awl { class MidiMeter : public Slider { - Q_PROPERTY(int meterWidth READ meterWidth WRITE setMeterWidth) Q_OBJECT + Q_PROPERTY(int meterWidth READ meterWidth WRITE setMeterWidth) + double meterval; int _meterWidth; diff --git a/muse2/awl/midimslider.h b/muse2/awl/midimslider.h index a2a2bdaf..a363348a 100644 --- a/muse2/awl/midimslider.h +++ b/muse2/awl/midimslider.h @@ -31,8 +31,9 @@ namespace Awl { class MidiMeterSlider : public Slider { - Q_PROPERTY(int meterWidth READ meterWidth WRITE setMeterWidth) Q_OBJECT + Q_PROPERTY(int meterWidth READ meterWidth WRITE setMeterWidth) + double meterval; int _meterWidth; diff --git a/muse2/awl/mslider.h b/muse2/awl/mslider.h index 4ae888b1..15dd8a7e 100644 --- a/muse2/awl/mslider.h +++ b/muse2/awl/mslider.h @@ -32,9 +32,10 @@ namespace Awl { class MeterSlider : public VolSlider { + Q_OBJECT Q_PROPERTY(int meterWidth READ meterWidth WRITE setMeterWidth) Q_PROPERTY(int channel READ channel WRITE setChannel) - Q_OBJECT + int _channel; std::vector<double> meterval; diff --git a/muse2/awl/pitchlabel.h b/muse2/awl/pitchlabel.h index e5c34dba..a09d1ced 100644 --- a/muse2/awl/pitchlabel.h +++ b/muse2/awl/pitchlabel.h @@ -30,9 +30,11 @@ namespace Awl { //--------------------------------------------------------- class PitchLabel : public QLabel { + Q_OBJECT + bool _pitchMode; int _value; - Q_OBJECT + protected: QSize sizeHint() const; diff --git a/muse2/awl/tempolabel.h b/muse2/awl/tempolabel.h index df9abfcd..b7df6b56 100644 --- a/muse2/awl/tempolabel.h +++ b/muse2/awl/tempolabel.h @@ -30,9 +30,10 @@ namespace Awl { //--------------------------------------------------------- class TempoLabel : public QLabel { + Q_OBJECT double _value; - Q_OBJECT + protected: QSize sizeHint() const; diff --git a/muse2/muse/appearance.h b/muse2/muse/appearance.h index ef99adbe..ec266f8e 100644 --- a/muse2/muse/appearance.h +++ b/muse2/muse/appearance.h @@ -15,6 +15,10 @@ class GlobalConfigValues; //--------------------------------------------------------- class Appearance : public QDialog, public Ui::AppearanceDialogBase { + + Q_OBJECT + + private: Arranger* arr; QColor* color; GlobalConfigValues* config; @@ -24,7 +28,7 @@ class Appearance : public QDialog, public Ui::AppearanceDialogBase { QTreeWidgetItem* lastSelectedBgItem; QTreeWidgetItem* lastSelectedColorItem; - Q_OBJECT + void updateFonts(); void updateColor(); diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 8c7c89ad..d65b8957 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -299,21 +299,12 @@ void PartCanvas::viewMouseDoubleClickEvent(QMouseEvent* event) } //--------------------------------------------------------- -// startUndo +// update //--------------------------------------------------------- -void PartCanvas::startUndo(DragType) +void PartCanvas::updateSong(DragType t, int flags) { - song->startUndo(); - } - -//--------------------------------------------------------- -// endUndo -//--------------------------------------------------------- - -void PartCanvas::endUndo(DragType t, int flags) - { - song->endUndo(flags | ((t == MOVE_COPY || t == MOVE_CLONE) + song->update(flags | ((t == MOVE_COPY || t == MOVE_CLONE) ? SC_PART_INSERTED : SC_PART_MODIFIED)); } @@ -323,101 +314,6 @@ void PartCanvas::endUndo(DragType t, int flags) void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtype, int*) { - /* - if(editor->parts()->empty()) - return; - - //struct p2c - //{ - // Part* newp; - // int xdiff; - //} - - //std::set<Part*> parts2change; - //typedef std::set<Part*>::iterator iptc; - std::map<Part*, Part*> parts2change; - typedef std::map<Part*, Part*>::iterator iP2C; - - int modified = 0; - for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip) - { - Part* part = ip->second; - if(!part) - continue; - - int npartoffset = 0; - for(iCItem ici = items.begin(); ici != items.end(); ++ici) - { - CItem* ci = ici->second; - //Part* pt = ci->part(); - //if(!pt) - if(ci->part() != part) - continue; - - int x = ci->pos().x() + dx; - int y = pitch2y(y2pitch(ci->pos().y()) + dp); - QPoint newpos = raster(QPoint(x, y)); - - // Test moving the item... - - //int offset = testMoveItem(ci, newpos, dragtype); - NEvent* nevent = (NEvent*) ci; - Event event = nevent->event(); - //int npitch = y2pitch(newpos.y()); - x = newpos.x(); - if (x < 0) - x = 0; - - int ntick = editor->rasterVal(x) - part->tick(); - if (ntick < 0) - ntick = 0; - int diff = ntick + event.lenTick() - part->lenTick(); - - // If moving the item would require a new part size... - if(diff > npartoffset) - npartoffset = diff; - } - - 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); - if(parts2change.find(part) == parts2change.end()) - parts2change.insert(std::pair<Part*, Part*> (part, newPart)); - -// part = newPart; // reassign -// item->setPart(part); -// item->setEvent(newEvent); -// curPart = part; -// curPartId = curPart->sn(); - - } - } -*/ - -// int modified = 0; for(iCItem ici = items.begin(); ici != items.end(); ++ici) { CItem* ci = ici->second; @@ -435,18 +331,15 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp QPoint newpos = raster(QPoint(nx, ny)); selectItem(ci, true); - if(moveItem(ci, newpos, dtype)) - ci->move(newpos); + if (moveItem(ci, newpos, dtype)) + ci->move(newpos); + if(moving.size() == 1) { itemReleased(curItem, newpos); } if(dtype == MOVE_COPY || dtype == MOVE_CLONE) selectItem(ci, false); } - - - //if(pflags) - // *pflags = modified; } //--------------------------------------------------------- @@ -455,9 +348,9 @@ void PartCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dtyp //--------------------------------------------------------- // Changed by T356. -//bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t, int*) bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t) { + UndoOp result; NPart* npart = (NPart*) item; Part* spart = npart->part(); Track* track = npart->track(); @@ -465,7 +358,7 @@ bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t) unsigned ntrack = y2pitch(item->mp().y()); Track::TrackType type = track->type(); if (tracks->index(track) == ntrack && (dtick == spart->tick())) { - return false; + return false; //FINDMICH } if (ntrack >= tracks->size()) { ntrack = tracks->size(); @@ -483,7 +376,7 @@ bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t) if (dtrack->type() != type) { QMessageBox::critical(this, QString("MusE"), tr("Cannot copy/move/clone to different Track-Type")); - return false; + return false; //FINDMICH } Part* dpart; @@ -552,7 +445,8 @@ bool PartCanvas::moveItem(CItem* item, const QPoint& newpos, DragType t) if (song->len() < (dpart->lenTick() + dpart->tick())) song->setLen(dpart->lenTick() + dpart->tick()); //endUndo(t); - return true; + return true; //FINDMICH + //TODO FINDMICH returns nothing... should be fixed (flo93) } //--------------------------------------------------------- @@ -2790,7 +2684,7 @@ void PartCanvas::movePartsTotheRight(unsigned int startTicks, int length) Marker *oldMarker = new Marker(); *oldMarker = *m; m->setTick(m->tick()+length); - song->undoOp(UndoOp::ModifyMarker,oldMarker, m); + song->addUndo(UndoOp(UndoOp::ModifyMarker,oldMarker, m)); } } } @@ -3623,3 +3517,40 @@ double PartCanvas::valToDb(double inV) { return exp10((inV*70.0-60.0)/20.0); } + +//--------------------------------------------------------- +// endMoveItems +// dir = 0 move in all directions +// 1 move only horizontal +// 2 move only vertical +//--------------------------------------------------------- + +void PartCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir) + { + song->startUndo(); + + int dp = y2pitch(pos.y()) - y2pitch(start.y()); + int dx = pos.x() - start.x(); + + if (dir == 1) + dp = 0; + else if (dir == 2) + dx = 0; + + + + int modified = 0; + + moveCanvasItems(moving, dp, dx, dragtype, &modified); + + if (dragtype == MOVE_COPY || dragtype == MOVE_CLONE) + modified|=SC_PART_INSERTED; + else + modified|=SC_PART_MODIFIED; + + song->endUndo(modified); + moving.clear(); + updateSelection(); + redraw(); + } + diff --git a/muse2/muse/arranger/pcanvas.h b/muse2/muse/arranger/pcanvas.h index a3dd7900..18e47426 100644 --- a/muse2/muse/arranger/pcanvas.h +++ b/muse2/muse/arranger/pcanvas.h @@ -57,6 +57,7 @@ class CtrlVal; //--------------------------------------------------------- class PartCanvas : public Canvas { + Q_OBJECT int* _raster; TrackList* tracks; @@ -69,7 +70,7 @@ class PartCanvas : public Canvas { AutomationObject automation; //std::vector<TrackAutomationView*> automationViews; - Q_OBJECT + virtual void keyPress(QKeyEvent*); virtual void mousePress(QMouseEvent*); virtual void mouseMove(QMouseEvent* event); @@ -83,15 +84,14 @@ class PartCanvas : public Canvas { virtual int y2pitch(int y) const; virtual int pitch2y(int p) const; - virtual void moveCanvasItems(CItemList&, int, int, DragType, int*); - virtual bool moveItem(CItem*, const QPoint&, DragType); virtual CItem* newItem(const QPoint&, int); virtual void resizeItem(CItem*,bool); virtual void newItem(CItem*,bool); virtual bool deleteItem(CItem*); - virtual void startUndo(DragType); - - virtual void endUndo(DragType, int); + virtual void moveCanvasItems(CItemList&, int, int, DragType, int*); + virtual bool moveItem(CItem*, const QPoint&, DragType); + + virtual void updateSong(DragType, int); virtual void startDrag(CItem*, DragType); virtual void dragEnterEvent(QDragEnterEvent*); virtual void dragMoveEvent(QDragMoveEvent*); @@ -126,6 +126,7 @@ class PartCanvas : public Canvas { protected: virtual void drawCanvas(QPainter&, const QRect&); + virtual void endMoveItems(const QPoint&, DragType, int dir); signals: void timeChanged(unsigned); diff --git a/muse2/muse/confmport.h b/muse2/muse/confmport.h index 3c139ee2..6901035a 100644 --- a/muse2/muse/confmport.h +++ b/muse2/muse/confmport.h @@ -28,6 +28,7 @@ class Xml; //--------------------------------------------------------- class MPConfig : public QDialog, Ui::SynthConfigBase { + Q_OBJECT QMenu* instrPopup; //QMenu* popup; PopupMenu* defpup; @@ -36,7 +37,7 @@ class MPConfig : public QDialog, Ui::SynthConfigBase { void setToolTip(QTableWidgetItem *item, int col); void addItem(int row, int col, QTableWidgetItem *item, QTableWidget *table); - Q_OBJECT + private slots: void rbClicked(QTableWidgetItem*); 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/ctrl/ctrlcanvas.h b/muse2/muse/ctrl/ctrlcanvas.h index 300cac19..e6864003 100644 --- a/muse2/muse/ctrl/ctrlcanvas.h +++ b/muse2/muse/ctrl/ctrlcanvas.h @@ -81,6 +81,8 @@ class CEventList: public std::list<CEvent*> { //--------------------------------------------------------- class CtrlCanvas : public View { + Q_OBJECT + MidiEditor* editor; MidiTrack* curTrack; MidiPart* curPart; @@ -120,7 +122,7 @@ class CtrlCanvas : public View { void pdrawItems(QPainter&, const QRect&, const MidiPart*, bool, bool); void partControllers(const MidiPart*, int, int*, int*, MidiController**, MidiCtrlValList**); - Q_OBJECT + protected: enum DragMode { DRAG_OFF, DRAG_NEW, DRAG_MOVE_START, DRAG_MOVE, diff --git a/muse2/muse/ctrl/ctrledit.h b/muse2/muse/ctrl/ctrledit.h index eec235b1..c5f5935e 100644 --- a/muse2/muse/ctrl/ctrledit.h +++ b/muse2/muse/ctrl/ctrledit.h @@ -24,10 +24,11 @@ class Xml; //--------------------------------------------------------- class CtrlEdit : public QWidget { + Q_OBJECT CtrlCanvas* canvas; CtrlPanel* panel; - Q_OBJECT + private slots: void destroy(); diff --git a/muse2/muse/ctrl/ctrlpanel.h b/muse2/muse/ctrl/ctrlpanel.h index 92911b8e..3f6de205 100644 --- a/muse2/muse/ctrl/ctrlpanel.h +++ b/muse2/muse/ctrl/ctrlpanel.h @@ -25,6 +25,8 @@ class MidiTrack; //--------------------------------------------------------- class CtrlPanel: public QWidget { + Q_OBJECT + //QMenu* pop; QPushButton* selCtrl; MidiEditor* editor; @@ -37,7 +39,7 @@ class CtrlPanel: public QWidget { DoubleLabel* _dl; int _val; - Q_OBJECT + signals: void destroyPanel(); diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp index 6fab2ee4..4a65d19c 100644 --- a/muse2/muse/functions.cpp +++ b/muse2/muse/functions.cpp @@ -7,6 +7,7 @@ #include "functions.h" #include "song.h" +#include "undo.h" #include "event.h" #include "audio.h" @@ -26,7 +27,6 @@ #include <QMessageBox> #include <QClipboard> - using namespace std; GateTime* gatetime_dialog=NULL; @@ -216,11 +216,10 @@ bool legato(const set<Part*>& parts) bool modify_velocity(const set<Part*>& parts, int range, int rate, int offset) { map<Event*, Part*> events = get_events(parts, range); + Undo operations; if ( (!events.empty()) && ((rate!=100) || (offset!=0)) ) { - song->startUndo(); - for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) { Event& event=*(it->first); @@ -240,13 +239,11 @@ bool modify_velocity(const set<Part*>& parts, int range, int rate, int offset) { Event newEvent = event.clone(); newEvent.setVelo(velo); - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, part, false, false, false); + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false)); } } - song->endUndo(SC_EVENT_MODIFIED); - return true; + return song->applyOperationGroup(operations); } else return false; @@ -255,11 +252,10 @@ bool modify_velocity(const set<Part*>& parts, int range, int rate, int offset) bool modify_off_velocity(const set<Part*>& parts, int range, int rate, int offset) { map<Event*, Part*> events = get_events(parts, range); + Undo operations; if ( (!events.empty()) && ((rate!=100) || (offset!=0)) ) { - song->startUndo(); - for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) { Event& event=*(it->first); @@ -279,13 +275,11 @@ bool modify_off_velocity(const set<Part*>& parts, int range, int rate, int offse { Event newEvent = event.clone(); newEvent.setVeloOff(velo); - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, part, false, false, false); + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false)); } } - - song->endUndo(SC_EVENT_MODIFIED); - return true; + + return song->applyOperationGroup(operations); } else return false; @@ -294,11 +288,10 @@ bool modify_off_velocity(const set<Part*>& parts, int range, int rate, int offse bool modify_notelen(const set<Part*>& parts, int range, int rate, int offset) { map<Event*, Part*> events = get_events(parts, range); + Undo operations; if ( (!events.empty()) && ((rate!=100) || (offset!=0)) ) { - song->startUndo(); - for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) { Event& event=*(it->first); @@ -316,13 +309,11 @@ bool modify_notelen(const set<Part*>& parts, int range, int rate, int offset) { Event newEvent = event.clone(); newEvent.setLenTick(len); - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, part, false, false, false); + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false)); } } - song->endUndo(SC_EVENT_MODIFIED); - return true; + return song->applyOperationGroup(operations); } else return false; @@ -358,7 +349,7 @@ unsigned quantize_tick(unsigned tick, unsigned raster, int swing) bool quantize_notes(const set<Part*>& parts, int range, int raster, bool quant_len, int strength, int swing, int threshold) { map<Event*, Part*> events = get_events(parts, range); - bool undo_started=false; + Undo operations; if (!events.empty()) { @@ -388,59 +379,50 @@ bool quantize_notes(const set<Part*>& parts, int range, int raster, bool quant_l if ( (event.lenTick() != len) || (event.tick() + part->tick() != begin_tick) ) { - if (!undo_started) - { - song->startUndo(); - undo_started=true; - } - Event newEvent = event.clone(); newEvent.setTick(begin_tick - part->tick()); newEvent.setLenTick(len); - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, part, false, false, false); + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false)); } } - if (undo_started) song->endUndo(SC_EVENT_MODIFIED); + return song->applyOperationGroup(operations); } - - return undo_started; + else + return false; } bool erase_notes(const set<Part*>& parts, int range, int velo_threshold, bool velo_thres_used, int len_threshold, bool len_thres_used) { map<Event*, Part*> events = get_events(parts, range); + Undo operations; if (!events.empty()) { - song->startUndo(); - for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) { Event& event=*(it->first); Part* part=it->second; + if ( (!velo_thres_used && !len_thres_used) || (velo_thres_used && event.velo() < velo_threshold) || (len_thres_used && int(event.lenTick()) < len_threshold) ) - audio->msgDeleteEvent(event, part, false, false, false); + operations.push_back(UndoOp(UndoOp::DeleteEvent, event, part, false, false)); } - song->endUndo(SC_EVENT_REMOVED); - return true; + return song->applyOperationGroup(operations); } else return false; } -bool transpose_notes(const set<Part*>& parts, int range, signed int halftonesteps, bool do_undo) +bool transpose_notes(const set<Part*>& parts, int range, signed int halftonesteps) { map<Event*, Part*> events = get_events(parts, range); + Undo operations; if ( (!events.empty()) && (halftonesteps!=0) ) { - if (do_undo) song->startUndo(); - for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) { Event& event=*(it->first); @@ -451,12 +433,10 @@ bool transpose_notes(const set<Part*>& parts, int range, signed int halftonestep if (pitch > 127) pitch=127; if (pitch < 0) pitch=0; newEvent.setPitch(pitch); - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, part, false, false, false); + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false)); } - if (do_undo) song->endUndo(SC_EVENT_MODIFIED); - return do_undo; + return song->applyOperationGroup(operations); } else return false; @@ -465,14 +445,13 @@ bool transpose_notes(const set<Part*>& parts, int range, signed int halftonestep bool crescendo(const set<Part*>& parts, int range, int start_val, int end_val, bool absolute) { map<Event*, Part*> events = get_events(parts, range); + Undo operations; int from=song->lpos(); int to=song->rpos(); if ( (!events.empty()) && (to>from) ) { - song->startUndo(); - for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) { Event& event=*(it->first); @@ -492,25 +471,22 @@ bool crescendo(const set<Part*>& parts, int range, int start_val, int end_val, b if (velo > 127) velo=127; if (velo <= 0) velo=1; newEvent.setVelo(velo); - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, part, false, false, false); + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false)); } - song->endUndo(SC_EVENT_MODIFIED); - return true; + return song->applyOperationGroup(operations); } else return false; } -bool move_notes(const set<Part*>& parts, int range, signed int ticks, bool do_undo) //TODO: clipping +bool move_notes(const set<Part*>& parts, int range, signed int ticks) //TODO: clipping { map<Event*, Part*> events = get_events(parts, range); + Undo operations; if ( (!events.empty()) && (ticks!=0) ) { - if (do_undo) song->startUndo(); - for (map<Event*, Part*>::iterator it=events.begin(); it!=events.end(); it++) { Event& event=*(it->first); @@ -532,24 +508,22 @@ bool move_notes(const set<Part*>& parts, int range, signed int ticks, bool do_un } if (del==false) - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgChangeEvent(event, newEvent, part, false, false, false); + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false)); else - // Indicate no undo, and do not do port controller values and clone parts. - audio->msgDeleteEvent(event, part, false, false, false); + operations.push_back(UndoOp(UndoOp::DeleteEvent, event, part, false, false)); } - if (do_undo) song->endUndo(SC_EVENT_MODIFIED); - return do_undo; + return song->applyOperationGroup(operations); } else return false; } + bool delete_overlaps(const set<Part*>& parts, int range) { map<Event*, Part*> events = get_events(parts, range); - bool undo_started=false; + Undo operations; set<Event*> deleted_events; @@ -576,17 +550,11 @@ bool delete_overlaps(const set<Part*>& parts, int range) (event1.tick() <= event2.tick()) && (event1.endTick() > event2.tick()) ) //they overlap { - if (undo_started==false) - { - song->startUndo(); - undo_started=true; - } - int new_len = event2.tick() - event1.tick(); if (new_len==0) { - audio->msgDeleteEvent(event1, part1, false, false, false); + operations.push_back(UndoOp(UndoOp::DeleteEvent, event1, part1, false, false)); deleted_events.insert(&event1); } else @@ -594,22 +562,23 @@ bool delete_overlaps(const set<Part*>& parts, int range) Event new_event1 = event1.clone(); new_event1.setLenTick(new_len); - audio->msgChangeEvent(event1, new_event1, part1, false, false, false); + operations.push_back(UndoOp(UndoOp::ModifyEvent, new_event1, event1, part1, false, false)); } } } } } - if (undo_started) song->endUndo(SC_EVENT_MODIFIED); + return song->applyOperationGroup(operations); } - return undo_started; + else + return false; } bool legato(const set<Part*>& parts, int range, int min_len, bool dont_shorten) { map<Event*, Part*> events = get_events(parts, range); - bool undo_started=false; + Undo operations; if (min_len<=0) min_len=1; @@ -643,22 +612,17 @@ bool legato(const set<Part*>& parts, int range, int min_len, bool dont_shorten) if (event1.lenTick() != len) { - if (undo_started==false) - { - song->startUndo(); - undo_started=true; - } - Event new_event1 = event1.clone(); new_event1.setLenTick(len); - audio->msgChangeEvent(event1, new_event1, part1, false, false, false); + operations.push_back(UndoOp(UndoOp::ModifyEvent, new_event1, event1, part1, false, false)); } } - if (undo_started) song->endUndo(SC_EVENT_MODIFIED); + return song->applyOperationGroup(operations); } - return undo_started; + else + return false; } @@ -749,6 +713,8 @@ QMimeData* selected_events_to_mime(const set<Part*>& parts, int range) void paste_at(Part* dest_part, const QString& pt, int pos) { + Undo operations; + Xml xml(pt.toLatin1().constData()); for (;;) { @@ -763,10 +729,8 @@ void paste_at(Part* dest_part, const QString& pt, int pos) case Xml::TagStart: if (tag == "eventlist") { - song->startUndo(); EventList el; el.read(xml, "eventlist", true); - int modified = SC_EVENT_INSERTED; for (iEvent i = el.begin(); i != el.end(); ++i) { Event e = i->second; @@ -774,7 +738,6 @@ void paste_at(Part* dest_part, const QString& pt, int pos) if (tick<0) { printf("ERROR: trying to add event before current part!\n"); - song->endUndo(SC_EVENT_INSERTED); goto end_of_paste_at; } @@ -786,14 +749,13 @@ void paste_at(Part* dest_part, const QString& pt, int pos) Part* newPart = dest_part->clone(); newPart->setLenTick(newPart->lenTick()+diff); // Indicate no undo, and do port controller values but not clone parts. - audio->msgChangePart(dest_part, newPart, false, true, false); - modified=modified|SC_PART_MODIFIED; + operations.push_back(UndoOp(UndoOp::ModifyPart,dest_part, newPart, true, false)); //FINDMICHJETZT oder andersrum? dest_part = newPart; // reassign TODO FINDME does this work, or has dest_part to be a nonconst reference? } // Indicate no undo, and do not do port controller values and clone parts. - audio->msgAddEvent(e, dest_part, false, false, false); + operations.push_back(UndoOp(UndoOp::AddEvent,e, dest_part, false, false)); } - song->endUndo(modified); + song->applyOperationGroup(operations); goto end_of_paste_at; } else diff --git a/muse2/muse/functions.h b/muse2/muse/functions.h index 226c43f7..bc2bb8f4 100644 --- a/muse2/muse/functions.h +++ b/muse2/muse/functions.h @@ -51,8 +51,8 @@ bool quantize_notes(const std::set<Part*>& parts, int range, int raster, bool le bool erase_notes(const std::set<Part*>& parts, int range, int velo_threshold=0, bool velo_thres_used=false, int len_threshold=0, bool len_thres_used=false); bool delete_overlaps(const std::set<Part*>& parts, int range); bool set_notelen(const std::set<Part*>& parts, int range, int len); -bool move_notes(const std::set<Part*>& parts, int range, signed int ticks, bool do_undo=true); -bool transpose_notes(const std::set<Part*>& parts, int range, signed int halftonesteps, bool do_undo=true); +bool move_notes(const std::set<Part*>& parts, int range, signed int ticks); +bool transpose_notes(const std::set<Part*>& parts, int range, signed int halftonesteps); bool crescendo(const std::set<Part*>& parts, int range, int start_val, int end_val, bool absolute); bool legato(const std::set<Part*>& parts, int range, int min_len=1, bool dont_shorten=false); diff --git a/muse2/muse/liste/listedit.h b/muse2/muse/liste/listedit.h index 5cf60a59..397a5e08 100644 --- a/muse2/muse/liste/listedit.h +++ b/muse2/muse/liste/listedit.h @@ -32,6 +32,8 @@ class Xml; //--------------------------------------------------------- class ListEdit : public MidiEditor { + Q_OBJECT + QTreeWidget* liste; QMenu* menuEdit; QActionGroup* insertItems; @@ -43,7 +45,7 @@ class ListEdit : public MidiEditor { enum { CMD_DELETE }; - Q_OBJECT + virtual void closeEvent(QCloseEvent*); virtual void keyPressEvent(QKeyEvent*); void initShortcuts(); diff --git a/muse2/muse/marker/markerview.h b/muse2/muse/marker/markerview.h index a271873c..5ad4f4bd 100644 --- a/muse2/muse/marker/markerview.h +++ b/muse2/muse/marker/markerview.h @@ -49,6 +49,8 @@ class MarkerItem : public QTreeWidgetItem { //--------------------------------------------------------- class MarkerView : public TopWin { + Q_OBJECT + QTreeWidget* table; QLineEdit* editName; ///PosEdit* editSMPTE; @@ -58,7 +60,7 @@ class MarkerView : public TopWin { QToolButton* lock; QToolBar* tools; - Q_OBJECT + virtual void closeEvent(QCloseEvent*); private slots: diff --git a/muse2/muse/master/lmaster.h b/muse2/muse/master/lmaster.h index 150e8236..b2919b23 100644 --- a/muse2/muse/master/lmaster.h +++ b/muse2/muse/master/lmaster.h @@ -114,13 +114,15 @@ class LMasterSigEventItem : public LMasterLViewItem { //--------------------------------------------------------- class LMaster : public MidiEditor { + Q_OBJECT + QTreeWidget* view; QToolBar* tools; QMenu* menuEdit; enum { CMD_DELETE, CMD_INSERT_SIG, CMD_INSERT_TEMPO, CMD_EDIT_BEAT, CMD_EDIT_VALUE, CMD_INSERT_KEY }; - Q_OBJECT + virtual void closeEvent(QCloseEvent*); void updateList(); void insertTempo(const TEvent*); diff --git a/muse2/muse/master/master.h b/muse2/muse/master/master.h index 52040aeb..2415b15e 100644 --- a/muse2/muse/master/master.h +++ b/muse2/muse/master/master.h @@ -26,6 +26,7 @@ class ScrollScale; //--------------------------------------------------------- class Master : public View { + Q_OBJECT enum DragMode { DRAG_OFF, DRAG_NEW, DRAG_MOVE_START, DRAG_MOVE, DRAG_DELETE, DRAG_COPY_START, DRAG_COPY, DRAG_RESIZE, DRAG_LASSO_START, DRAG_LASSO @@ -37,7 +38,7 @@ class Master : public View { DragMode drag; MidiEditor* editor; - Q_OBJECT + virtual void pdraw(QPainter&, const QRect&); virtual void viewMouseMoveEvent(QMouseEvent* event); virtual void leaveEvent(QEvent*e); diff --git a/muse2/muse/master/masteredit.h b/muse2/muse/master/masteredit.h index 59a5ab05..b2b06291 100644 --- a/muse2/muse/master/masteredit.h +++ b/muse2/muse/master/masteredit.h @@ -40,6 +40,8 @@ class TempoLabel; //--------------------------------------------------------- class MasterEdit : public MidiEditor { + Q_OBJECT + Master* canvas; ScrollScale* hscroll; ScrollScale* vscroll; @@ -62,7 +64,7 @@ class MasterEdit : public MidiEditor { static int _widthInit, _heightInit; static QByteArray _toolbarInit; - Q_OBJECT + virtual void closeEvent(QCloseEvent*); virtual void resizeEvent(QResizeEvent*); virtual void focusOutEvent(QFocusEvent*); 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); diff --git a/muse2/muse/midiedit/dcanvas.h b/muse2/muse/midiedit/dcanvas.h index 364d9268..868113a6 100644 --- a/muse2/muse/midiedit/dcanvas.h +++ b/muse2/muse/midiedit/dcanvas.h @@ -41,6 +41,7 @@ class PianoRoll; //--------------------------------------------------------- class DrumCanvas : public EventCanvas { + Q_OBJECT StepRec* steprec; @@ -48,15 +49,13 @@ class DrumCanvas : public EventCanvas { QPoint cursorPos; int _stepSize; - Q_OBJECT + virtual void drawCanvas(QPainter&, const QRect&); virtual void drawItem(QPainter&, const CItem*, const QRect&); void drawTopItem(QPainter& p, const QRect& rect); virtual void drawMoving(QPainter&, const CItem*, const QRect&); - virtual void moveCanvasItems(CItemList&, int, int, DragType, int*); - // Changed by T356. - //virtual bool moveItem(CItem*, const QPoint&, DragType, int*); - virtual bool moveItem(CItem*, const QPoint&, DragType); + 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); virtual void newItem(CItem*, bool); diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp index ab2ed230..66922e83 100644 --- a/muse2/muse/midiedit/dlist.cpp +++ b/muse2/muse/midiedit/dlist.cpp @@ -47,7 +47,6 @@ void DList::draw(QPainter& p, const QRect& rect) if (yy > y + h) break; DrumMap* dm = &drumMap[i]; -// if (dm->selected) if (dm == currentlySelected) p.fillRect(x, yy, w, TH, Qt::yellow); // else @@ -56,13 +55,11 @@ void DList::draw(QPainter& p, const QRect& rect) for (int k = 0; k < h->count(); ++k) { int x = h->sectionPosition(k); int w = h->sectionSize(k); - ///QRect r = p.xForm(QRect(x+2, yy, w-4, TH)); QRect r = p.combinedTransform().mapRect(QRect(x+2, yy, w-4, TH)); QString s; int align = Qt::AlignVCenter | Qt::AlignHCenter; p.save(); - ///p.setWorldXForm(false); p.setWorldMatrixEnabled(false); switch (k) { case COL_VOL: @@ -145,16 +142,13 @@ void DList::draw(QPainter& p, const QRect& rect) // vertical Lines //--------------------------------------------------- - ///p.setWorldXForm(false); p.setWorldMatrixEnabled(false); int n = header->count(); x = 0; for (int i = 0; i < n; i++) { - //x += header->sectionSize(i); x += header->sectionSize(header->visualIndex(i)); p.drawLine(x, 0, x, height()); } - ///p.setWorldXForm(true); p.setWorldMatrixEnabled(true); } @@ -174,7 +168,6 @@ void DList::devicesPopupMenu(DrumMap* t, int x, int y, bool changeAll) if(n != t->port) { audio->msgIdle(true); - //audio->msgRemapPortDrumCtlEvents(getSelectedInstrument(), -1, -1, n); song->remapPortDrumCtrlEvents(getSelectedInstrument(), -1, -1, n); audio->msgIdle(false); t->port = n; @@ -184,13 +177,11 @@ void DList::devicesPopupMenu(DrumMap* t, int x, int y, bool changeAll) else { audio->msgIdle(true); // Delete all port controller events. - //audio->msgChangeAllPortDrumCtrlEvents(false); song->changeAllPortDrumCtrlEvents(false); for (int i = 0; i < DRUM_MAPSIZE; i++) drumMap[i].port = n; // Add all port controller events. - //audio->msgChangeAllPortDrumCtrlEvents(true); song->changeAllPortDrumCtrlEvents(true); audio->msgIdle(false); @@ -323,13 +314,11 @@ void DList::viewMousePressEvent(QMouseEvent* ev) if (ev->modifiers() & Qt::ControlModifier) { audio->msgIdle(true); // Delete all port controller events. - //audio->msgChangeAllPortDrumCtrlEvents(false); song->changeAllPortDrumCtrlEvents(false, true); for (int i = 0; i < DRUM_MAPSIZE; i++) drumMap[i].channel = val; // Add all port controller events. - //audio->msgChangeAllPortDrumCtrlEvents(true); song->changeAllPortDrumCtrlEvents(true, true); audio->msgIdle(false); song->update(SC_DRUMMAP); @@ -339,7 +328,6 @@ void DList::viewMousePressEvent(QMouseEvent* ev) if(val != dm->channel) { audio->msgIdle(true); - //audio->msgRemapPortDrumCtlEvents(pitch, -1, val, -1); song->remapPortDrumCtrlEvents(pitch, -1, val, -1); audio->msgIdle(false); dm->channel = val; @@ -397,7 +385,6 @@ void DList::viewMouseDoubleClickEvent(QMouseEvent* ev) { int x = ev->x(); int y = ev->y(); -// int button = ev->button(); unsigned pitch = y / TH; int section = header->logicalIndexAt(x); @@ -474,7 +461,6 @@ void DList::lineEdit(int line, int section) break; } - // editor->setText(dm->name); editor->end(false); editor->setGeometry(colx, coly, colw, colh); // In all cases but the column name, select all text: @@ -738,7 +724,7 @@ DList::DList(QHeaderView* h, QWidget* parent, int ymag) { setBg(Qt::white); if (!h){ - h = new QHeaderView(Qt::Horizontal, parent);} + h = new QHeaderView(Qt::Horizontal, parent);} header = h; scroll = 0; //ORCAN- CHECK if really needed: header->setTracking(true); @@ -761,8 +747,6 @@ DList::DList(QHeaderView* h, QWidget* parent, int ymag) DList::~DList() { -// if (currentlySelected != 0) -// currentlySelected->selected = false; //Reset the global thingie } //--------------------------------------------------------- diff --git a/muse2/muse/midiedit/dlist.h b/muse2/muse/midiedit/dlist.h index 03437e64..00f21c55 100644 --- a/muse2/muse/midiedit/dlist.h +++ b/muse2/muse/midiedit/dlist.h @@ -70,6 +70,8 @@ class DPitchEdit: public Awl::PitchEdit //--------------------------------------------------------- class DList : public View { + Q_OBJECT + QHeaderView* header; ScrollScale* scroll; QLineEdit* editor; @@ -92,7 +94,7 @@ class DList : public View { int x2col(int x) const; void devicesPopupMenu(DrumMap* t, int x, int y, bool changeAll); - Q_OBJECT + //void setCurDrumInstrument(int n); private slots: diff --git a/muse2/muse/midiedit/drumedit.h b/muse2/muse/midiedit/drumedit.h index 30fe8487..64390cd9 100644 --- a/muse2/muse/midiedit/drumedit.h +++ b/muse2/muse/midiedit/drumedit.h @@ -49,6 +49,8 @@ class SNode; //--------------------------------------------------------- class DrumEdit : public MidiEditor { + Q_OBJECT + Event selEvent; MidiPart* selPart; int selTick; @@ -79,7 +81,7 @@ class DrumEdit : public MidiEditor { QAction *sallAction, *snoneAction, *invAction, *inAction , *outAction; QAction *prevAction, *nextAction; - Q_OBJECT + void initShortcuts(); virtual void closeEvent(QCloseEvent*); diff --git a/muse2/muse/midiedit/ecanvas.cpp b/muse2/muse/midiedit/ecanvas.cpp index d41a383c..ef47e0d6 100644 --- a/muse2/muse/midiedit/ecanvas.cpp +++ b/muse2/muse/midiedit/ecanvas.cpp @@ -102,25 +102,6 @@ QPoint EventCanvas::raster(const QPoint& p) const } //--------------------------------------------------------- -// startUndo -//--------------------------------------------------------- - -void EventCanvas::startUndo(DragType) - { - song->startUndo(); - } - -//--------------------------------------------------------- -// endUndo -//--------------------------------------------------------- - -void EventCanvas::endUndo(DragType dtype, int flags) - { - song->endUndo(flags | ((dtype == MOVE_COPY || dtype == MOVE_CLONE) - ? SC_EVENT_INSERTED : SC_EVENT_MODIFIED)); - } - -//--------------------------------------------------------- // mouseMove //--------------------------------------------------------- @@ -414,3 +395,30 @@ void EventCanvas::viewDropEvent(QDropEvent* event) } } + +//--------------------------------------------------------- +// endMoveItems +// dir = 0 move in all directions +// 1 move only horizontal +// 2 move only vertical +//--------------------------------------------------------- + +void EventCanvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir) + { + int dp = y2pitch(pos.y()) - y2pitch(Canvas::start.y()); + int dx = pos.x() - Canvas::start.x(); + + if (dir == 1) + dp = 0; + else if (dir == 2) + dx = 0; + + + + Undo operations = moveCanvasItems(moving, dp, dx, dragtype); + song->applyOperationGroup(operations); + + moving.clear(); + updateSelection(); + redraw(); + } diff --git a/muse2/muse/midiedit/ecanvas.h b/muse2/muse/midiedit/ecanvas.h index 0ae970ab..b847f0f9 100644 --- a/muse2/muse/midiedit/ecanvas.h +++ b/muse2/muse/midiedit/ecanvas.h @@ -38,12 +38,7 @@ class EventCanvas : public Canvas { Q_OBJECT virtual void leaveEvent(QEvent*e); virtual void enterEvent(QEvent*e); - // Removed by T356. - //virtual QPoint raster(const QPoint&) const; - virtual void startUndo(DragType); - - virtual void endUndo(DragType, int flags = 0); virtual void mouseMove(QMouseEvent* event); protected: @@ -58,6 +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) = 0; + virtual UndoOp moveItem(CItem*, const QPoint&, DragType) = 0; + virtual void endMoveItems(const QPoint&, DragType, int dir); public slots: void redrawGrid() { redraw(); } diff --git a/muse2/muse/midiedit/piano.h b/muse2/muse/midiedit/piano.h index 35106d64..f8deec52 100644 --- a/muse2/muse/midiedit/piano.h +++ b/muse2/muse/midiedit/piano.h @@ -23,6 +23,8 @@ class QPixmap; class Piano : public View { + Q_OBJECT + int curPitch; QPixmap* octave; QPixmap* c_keys[10]; @@ -34,7 +36,7 @@ class Piano : public View bool shift; int button; - Q_OBJECT + int y2pitch(int) const; int pitch2y(int) const; void viewMouseMoveEvent(QMouseEvent* event); diff --git a/muse2/muse/midiedit/pianoroll.h b/muse2/muse/midiedit/pianoroll.h index 58c2487a..1f53254d 100644 --- a/muse2/muse/midiedit/pianoroll.h +++ b/muse2/muse/midiedit/pianoroll.h @@ -51,6 +51,8 @@ class QScrollArea; //--------------------------------------------------------- class PianoRoll : public MidiEditor { + Q_OBJECT + Event selEvent; MidiPart* selPart; int selTick; @@ -125,7 +127,7 @@ class PianoRoll : public MidiEditor { //QScrollBar* infoScroll; QScrollArea* infoScroll; - Q_OBJECT + void initShortcuts(); void setEventColorMode(int); QWidget* genToolbar(QWidget* parent); diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index 4e81b2e9..091582ef 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -38,6 +38,8 @@ #include "audio.h" #include "functions.h" +#define CHORD_TIMEOUT 75 + //--------------------------------------------------------- // NEvent //--------------------------------------------------------- @@ -254,14 +256,14 @@ void PianoCanvas::viewMouseDoubleClickEvent(QMouseEvent* event) // moveCanvasItems //--------------------------------------------------------- -void 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; - + return Undo(); //return empty list + + Undo operations; PartsToChangeMap parts2change; - int modified = 0; for(iPart ip = editor->parts()->begin(); ip != editor->parts()->end(); ++ip) { Part* part = ip->second; @@ -297,34 +299,6 @@ void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty 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()) { @@ -333,13 +307,6 @@ void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty } else ip2c->second.xdiff = npartoffset; - - //part = newPart; // reassign - //item->setPart(part); - //item->setEvent(newEvent); - //curPart = part; - //curPartId = curPart->sn(); - } } @@ -352,8 +319,6 @@ void 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 @@ -367,8 +332,8 @@ void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty } editor->parts()->add(newPart); - // Indicate no undo, and do port controller values but not clone parts. - 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; @@ -384,6 +349,7 @@ void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty std::vector< CItem* > doneList; typedef std::vector< CItem* >::iterator iDoneList; + for(iCItem ici = items.begin(); ici != items.end(); ++ici) { CItem* ci = ici->second; @@ -408,21 +374,12 @@ void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty 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); @@ -430,8 +387,7 @@ void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty selectItem(ci, false); } - if(pflags) - *pflags = modified; + return operations; } //--------------------------------------------------------- @@ -439,9 +395,7 @@ void PianoCanvas::moveCanvasItems(CItemList& items, int dp, int dx, DragType dty // called after moving an object //--------------------------------------------------------- -// Changed by T356. -//bool PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype, int* pflags) -bool PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) +UndoOp PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) { NEvent* nevent = (NEvent*) item; Event event = nevent->event(); @@ -462,7 +416,7 @@ bool PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) // Changed by T356. Part* part = nevent->part(); // - //Part * part = Canvas::part(); // part can be dynamically recreated, ask the authority + //Part* part = Canvas::part(); // part can be dynamically recreated, ask the authority newEvent.setPitch(npitch); int ntick = editor->rasterVal(x) - part->tick(); @@ -471,46 +425,6 @@ bool PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) newEvent.setTick(ntick); newEvent.setLenTick(event.lenTick()); - // Removed 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(); - Part* newPart = Canvas::part()->clone(); - - newPart->setLenTick(newPart->lenTick()+diff); - audio->msgChangePart(Canvas::part(), newPart,false); - - modified = SC_PART_MODIFIED; - part = newPart; // reassign - - // BUG FIX: #1650953 - // Added by T356. - // Fixes posted "select and drag past end of part - crashing" bug - 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); // Added by T356. @@ -518,20 +432,9 @@ bool PianoCanvas::moveItem(CItem* item, const QPoint& pos, DragType dtype) printf("PianoCanvas::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); + return UndoOp(UndoOp::AddEvent, newEvent, part, 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); - //song->endUndo(modified); - - // Removed by T356. - //if(pflags) - // *pflags = modified; - - return true; + return UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false); } //--------------------------------------------------------- @@ -584,13 +487,11 @@ void PianoCanvas::newItem(CItem* item, bool noSnap) 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); } @@ -620,14 +521,12 @@ void PianoCanvas::resizeItem(CItem* item, bool noSnap) // experimental c } song->startUndo(); int modified=SC_EVENT_MODIFIED; - //printf("event.tick()=%d len=%d part->lenTick()=%d\n",event.endTick(),len,part->lenTick()); int diff = event.tick()+len-part->lenTick(); if (diff > 0) {// too short part? extend it //printf("extend Part!\n"); 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 @@ -635,7 +534,6 @@ void PianoCanvas::resizeItem(CItem* item, bool noSnap) // experimental c newEvent.setLenTick(len); // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(event, newEvent, nevent->part(),false); audio->msgChangeEvent(event, newEvent, nevent->part(), false, false, false); song->endUndo(modified); } @@ -650,7 +548,6 @@ bool PianoCanvas::deleteItem(CItem* item) if (nevent->part() == curPart) { Event ev = nevent->event(); // Indicate do undo, and do not do port controller values and clone parts. - //audio->msgDeleteEvent(ev, curPart); audio->msgDeleteEvent(ev, curPart, true, false, false); return true; } @@ -697,8 +594,6 @@ void PianoCanvas::pianoCmd(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; @@ -710,8 +605,9 @@ void PianoCanvas::pianoCmd(int cmd) if (part == 0) break; - song->startUndo(); + EventList* el = part->events(); + Undo operations; std::list <Event> elist; for (iEvent e = el->lower_bound(pos[0] - part->tick()); e != el->end(); ++e) @@ -720,11 +616,11 @@ void PianoCanvas::pianoCmd(int cmd) Event event = *i; Event newEvent = event.clone(); newEvent.setTick(event.tick() + editor->raster());// - part->tick()); - // 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); + // Do not do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false)); } - song->endUndo(SC_EVENT_MODIFIED); + song->applyOperationGroup(operations); + Pos p(editor->rasterVal(pos[0] + editor->rasterStep(pos[0])), true); song->setPos(0, p, true, false, true); } @@ -736,7 +632,8 @@ void PianoCanvas::pianoCmd(int cmd) MidiPart* part = (MidiPart*)curPart; if (part == 0) break; - song->startUndo(); + + Undo operations; EventList* el = part->events(); std::list<Event> elist; @@ -746,11 +643,10 @@ void PianoCanvas::pianoCmd(int cmd) Event event = *i; Event newEvent = event.clone(); newEvent.setTick(event.tick() - editor->raster() - part->tick()); - // 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); + // Do not do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false)); } - song->endUndo(SC_EVENT_MODIFIED); + song->applyOperationGroup(operations); Pos p(editor->rasterVal(pos[0] - editor->rasterStep(pos[0])), true); song->setPos(0, p, true, false, true); } @@ -769,14 +665,12 @@ void PianoCanvas::pianoPressed(int pitch, int velocity, bool shift) pitch += track()->transposition; // play note: - //MidiPlayEvent e(0, port, channel, 0x90, pitch, 127); MidiPlayEvent e(0, port, channel, 0x90, pitch, velocity); audio->msgPlayMidiEvent(&e); if (_steprec && pos[0] >= start_tick && pos[0] < end_tick && curPart) { steprec->record(curPart,pitch,editor->raster(),editor->raster(),velocity,globalKeyState&Qt::ControlModifier,shift); } - } //--------------------------------------------------------- @@ -817,14 +711,6 @@ void drawTickRaster(QPainter& p, int x, int y, int w, int h, int raster) int qq = raster; if (q < 8) // grid too dense qq *= 2; - //switch (quant) { - // case 32: - // case 48: - // case 64: - // case 96: - // case 192: // 8tel - // case 128: // 8tel Triolen - // case 288: p.setPen(Qt::lightGray); if (raster>=4) { int xx = x + qq; @@ -835,10 +721,6 @@ void drawTickRaster(QPainter& p, int x, int y, int w, int h, int raster) } xx = xxx; } - // break; - // default: - // break; - // } p.setPen(Qt::gray); for (int beat = 1; beat < z; beat++) { int xx = AL::sigmap.bar2tick(bar, beat, 0); @@ -873,9 +755,7 @@ void PianoCanvas::drawCanvas(QPainter& p, const QRect& rect) p.drawLine(x, yy, x + w, yy); break; default: - //p.setPen(lightGray); p.fillRect(x, yy-3, w, 6, QBrush(QColor(230,230,230))); - //p.drawLine(x, yy, x + w, yy); break; } --key; @@ -971,24 +851,7 @@ void PianoCanvas::cmd(int cmd) } break; - case CMD_FIXED_LEN: //Set notes to the length specified in the drummap - if (!selectionSize()) - break; - song->startUndo(); - for (iCItem k = items.begin(); k != items.end(); ++k) { - if (k->second->isSelected()) { - NEvent* nevent = (NEvent*)(k->second); - Event event = nevent->event(); - Event newEvent = event.clone(); - newEvent.setLenTick(editor->raster()); - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgChangeEvent(event, newEvent, nevent->part() , false); - audio->msgChangeEvent(event, newEvent, nevent->part(), false, false, false); - } - } - song->endUndo(SC_EVENT_MODIFIED); - break; - + case CMD_FIXED_LEN: case CMD_CRESCENDO: case CMD_TRANSPOSE: case CMD_THIN_OUT: @@ -1047,10 +910,6 @@ void PianoCanvas::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. " @@ -1233,8 +1092,8 @@ void PianoCanvas::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)); + song->addUndo(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, false, false)); } song->endUndo(SC_EVENT_MODIFIED); audio->msgIdle(false); diff --git a/muse2/muse/midiedit/prcanvas.h b/muse2/muse/midiedit/prcanvas.h index 96b5b4f5..c6e47c9e 100644 --- a/muse2/muse/midiedit/prcanvas.h +++ b/muse2/muse/midiedit/prcanvas.h @@ -40,6 +40,8 @@ class QRect; //--------------------------------------------------------- class PianoCanvas : public EventCanvas { + Q_OBJECT + int colorMode; int playedPitch; @@ -47,15 +49,13 @@ class PianoCanvas : public EventCanvas { StepRec* steprec; - Q_OBJECT + virtual void viewMouseDoubleClickEvent(QMouseEvent*); virtual void drawItem(QPainter&, const CItem*, const QRect&); void drawTopItem(QPainter &p, const QRect &rect); virtual void drawMoving(QPainter&, const CItem*, const QRect&); - virtual void moveCanvasItems(CItemList&, int, int, DragType, int*); - // Changed by T356. - //virtual bool moveItem(CItem*, const QPoint&, DragType, int*); - virtual bool moveItem(CItem*, const QPoint&, DragType); + 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); virtual void newItem(CItem*, bool noSnap); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 0660ebc5..0eb61554 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -552,8 +552,6 @@ ScoreEdit::~ScoreEdit() } - - void ScoreEdit::velo_box_changed() { emit velo_changed(velo_spinbox->value()); @@ -592,10 +590,9 @@ void ScoreEdit::song_changed(int flags) if (velo>=0) velo_spinbox->setValue(velo); if (velo_off>=0) velo_off_spinbox->setValue(velo_off); } - } - - if (flags & SC_SELECTION) + selection_changed(); + } } void ScoreEdit::canvas_width_changed(int width) @@ -3532,7 +3529,7 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event) int y=event->y() + y_pos - staff_it->y_draw; int x=event->x()+x_pos-x_left; int tick=flo_quantize_floor(x_to_tick(x), quant_ticks()); - + if (staff_it!=staves.end()) { if (event->x() <= x_left) //clicked in the preamble? @@ -4454,19 +4451,16 @@ void staff_t::update_part_indices() /* BUGS and potential bugs + * o quantize always quantizes length. make this selectable! * o when the keymap is not used, this will probably lead to a bug * same when mastertrack is disabled * o tied notes don't work properly when there's a key-change in * between, for example, when a cis is tied to a des * * CURRENT TODO - * o batch-movements: they may be destructive: if you move a chord - * upwards, so that some notes get clipped, - * they'll appear "damaged" in undo/redo - * maybe DO apply stuff with undo/redo, but count - * n_steps, and undo all steps before really - * applying the operation then. - * o allow batch-movements in score editor + * o rename stuff: UndoOp -> Operation, Undo -> OpList, + * UndoType -> OpType, iUndoOp, riUndoOp -> iOperation, + * undo.cpp/.h -> operations.cpp/.h * o either remove these "hidden notes", or deal with them in the score editor * o investigate with valgrind * o controller view in score editor @@ -4474,6 +4468,9 @@ void staff_t::update_part_indices() * o fix sigedit boxes * o mid-click in pianoroll: change to "delete", or initiate drag and drop between windows? * + * + * o drum list: scroll while dragging + * * IMPORTANT TODO * o do partial recalculating; recalculating can take pretty long * (0,5 sec) when displaying a whole song in scores diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index 1c45f578..e7302a46 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -707,15 +707,14 @@ class ScoreCanvas : public View int old_pitch; unsigned old_dest_tick; - - bool undo_started; - bool temp_undo; bool have_lasso; QPoint lasso_start; QRect lasso; - + bool undo_started; + bool temp_undo; + bool srec; bool held_notes[128]; diff --git a/muse2/muse/miditransform.cpp b/muse2/muse/miditransform.cpp index 1c73b7c2..9e9c87c0 100644 --- a/muse2/muse/miditransform.cpp +++ b/muse2/muse/miditransform.cpp @@ -662,14 +662,14 @@ void MidiTransformerDialog::transformEvent(Event& event, MidiPart* part, // Indicate do clone parts. addPortCtrlEvents(newEvent, part, true); // Indicate do port controller values and clone parts. - //song->undoOp(UndoOp::ModifyEvent, newEvent, event, part); - song->undoOp(UndoOp::ModifyEvent, newEvent, event, part, true, true); + //song->addUndo(UndoOp(UndoOp::ModifyEvent, newEvent, event, part)); + song->addUndo(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, true, true)); song->addUpdateFlags(SC_EVENT_MODIFIED); break; case Insert: // Indicate do port controller values and clone parts. - //song->undoOp(UndoOp::AddEvent, dummy, newEvent, part); - song->undoOp(UndoOp::AddEvent, dummy, newEvent, part, true, true); + //song->addUndo(UndoOp(UndoOp::AddEvent, dummy, newEvent, part)); + song->addUndo(UndoOp(UndoOp::AddEvent, dummy, newEvent, part, true, true)); song->addEvent(newEvent, part); // Indicate do clone parts. addPortCtrlEvents(newEvent, part, true); @@ -677,8 +677,8 @@ void MidiTransformerDialog::transformEvent(Event& event, MidiPart* part, break; case Extract: // Indicate do port controller values and clone parts. - //song->undoOp(UndoOp::DeleteEvent, dummy, event, part); - song->undoOp(UndoOp::DeleteEvent, dummy, event, part, true, true); + //song->addUndo(UndoOp(UndoOp::DeleteEvent, dummy, event, part)); + song->addUndo(UndoOp(UndoOp::DeleteEvent, dummy, event, part, true, true)); // Indicate do clone parts. removePortCtrlEvents(event, part, true); song->deleteEvent(event, part); @@ -713,8 +713,8 @@ void MidiTransformerDialog::processEvent(Event& event, MidiPart* part, MidiPart* // Indicate do clone parts. addPortCtrlEvents(newEvent, part, true); // Indicate do port controller values and clone parts. - //song->undoOp(UndoOp::ModifyEvent, newEvent, event, part); - song->undoOp(UndoOp::ModifyEvent, newEvent, event, part, true, true); + //song->addUndo(UndoOp(UndoOp::ModifyEvent, newEvent, event, part)); + song->addUndo(UndoOp(UndoOp::ModifyEvent, newEvent, event, part, true, true)); song->addUpdateFlags(SC_EVENT_MODIFIED); } } @@ -723,8 +723,8 @@ void MidiTransformerDialog::processEvent(Event& event, MidiPart* part, MidiPart* { Event ev; // Indicate do port controller values and clone parts. - //song->undoOp(UndoOp::DeleteEvent, ev, event, part, true, true); - song->undoOp(UndoOp::DeleteEvent, ev, event, part, true, true); + //song->addUndo(UndoOp(UndoOp::DeleteEvent, ev, event, part, true, true)); + song->addUndo(UndoOp(UndoOp::DeleteEvent, ev, event, part, true, true)); // Indicate do clone parts. removePortCtrlEvents(event, part, true); song->deleteEvent(event, part); diff --git a/muse2/muse/mixer/amixer.h b/muse2/muse/mixer/amixer.h index f8e365c3..ca8a3f4c 100644 --- a/muse2/muse/mixer/amixer.h +++ b/muse2/muse/mixer/amixer.h @@ -62,6 +62,8 @@ class ScrollArea : public QScrollArea //--------------------------------------------------------- class AudioMixerApp : public QMainWindow { + Q_OBJECT + //QString name; MixerConfig* cfg; StripList stripList; @@ -84,7 +86,7 @@ class AudioMixerApp : public QMainWindow { QAction* showAuxTracksId; QAction* showSyntiTracksId; - Q_OBJECT + virtual void closeEvent(QCloseEvent*); void addStrip(Track*, int); diff --git a/muse2/muse/mixer/rack.h b/muse2/muse/mixer/rack.h index 33c846bd..2b1bbb66 100644 --- a/muse2/muse/mixer/rack.h +++ b/muse2/muse/mixer/rack.h @@ -24,8 +24,11 @@ class Xml; //--------------------------------------------------------- class EffectRack : public QListWidget { - AudioTrack* track; Q_OBJECT + + + AudioTrack* track; + virtual QSize minimumSizeHint() const; virtual QSize sizeHint() const; diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index 99f070b2..231b947b 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -85,9 +85,6 @@ void chainCloneInternal(Part* p) const PartList* pl = mt->cparts(); for(ciPart ip = pl->begin(); ip != pl->end(); ++ip) { - // Added by Tim. p3.3.6 - //printf("chainCloneInternal track %p %s part %p %s evlist %p\n", (*imt), (*imt)->name().toLatin1().constData(), ip->second, ip->second->name().toLatin1().constData(), ip->second->cevents()); - if(ip->second != p && ip->second->cevents() == p->cevents()) { p1 = ip->second; @@ -224,16 +221,9 @@ void replaceClone(Part* p1, Part* p2) else p2->setNextClone(p2); - // Link the replacement... - //p2->setPrevClone(p1->prevClone()); - //p2->setNextClone(p1->nextClone()); - // Isolate the replaced part. p1->setNextClone(p1); p1->setPrevClone(p1); - // Added by Tim. p3.3.6 - //printf("replaceClone p1: %s %p arefs:%d p2: %s %p arefs:%d\n", p1->name().toLatin1().constData(), p1, ); - } //--------------------------------------------------------- @@ -278,9 +268,6 @@ void chainTrackParts(Track* t, bool incRefCount) if(incRefCount) p->events()->incARef(1); - // Added by Tim. p3.3.6 - //printf("chainTrackParts track %p %s part %p %s evlist %p\n", t, t->name().toLatin1().constData(), p, p->name().toLatin1().constData(), p->cevents()); - Part* p1 = 0; // Look for a part with the same event list, that we can chain to. @@ -296,9 +283,6 @@ void chainTrackParts(Track* t, bool incRefCount) const PartList* pl = mt->cparts(); for(ciPart ip = pl->begin(); ip != pl->end(); ++ip) { - // Added by Tim. p3.3.6 - //printf("chainTrackParts track %p %s part %p %s evlist %p\n", mt, mt->name().toLatin1().constData(), ip->second, ip->second->name().toLatin1().constData(), ip->second->cevents()); - if(ip->second != p && ip->second->cevents() == p->cevents()) { p1 = ip->second; @@ -381,21 +365,12 @@ void addPortCtrlEvents(Event& event, Part* part, bool doClones) //for(int i = 0; i < j; ++i) while(1) { - // Added by Tim. p3.3.6 - //printf("addPortCtrlEvents i:%d %s %p events %p refs:%d arefs:%d\n", i, p->name().toLatin1().constData(), p, part->cevents(), part->cevents()->refCount(), j); - Track* t = p->track(); if(t && t->isMidiTrack()) { MidiTrack* mt = (MidiTrack*)t; int port = mt->outPort(); - //const EventList* el = p->cevents(); unsigned len = p->lenTick(); - //for(ciEvent ie = el->begin(); ie != el->end(); ++ie) - //{ - //const Event& ev = ie->second; - // Added by Tim. p3.3.6 - //printf("addPortCtrlEvents %s len:%d end:%d etick:%d\n", p->name().toLatin1().constData(), p->lenTick(), p->endTick(), event.tick()); // Do not add events which are past the end of the part. if(event.tick() >= len) @@ -425,7 +400,6 @@ void addPortCtrlEvents(Event& event, Part* part, bool doClones) mp->setControllerVal(ch, tck, cntrl, val, p); } - //} } if(!doClones) @@ -456,9 +430,6 @@ void addPortCtrlEvents(Part* part, bool doClones) //for(int i = 0; i < j; ++i) while(1) { - // Added by Tim. p3.3.6 - //printf("addPortCtrlEvents i:%d %s %p events %p refs:%d arefs:%d\n", i, p->name().toLatin1().constData(), p, part->cevents(), part->cevents()->refCount(), j); - Track* t = p->track(); if(t && t->isMidiTrack()) { @@ -532,16 +503,6 @@ void removePortCtrlEvents(Event& event, Part* part, bool doClones) { MidiTrack* mt = (MidiTrack*)t; int port = mt->outPort(); - //const EventList* el = p->cevents(); - //unsigned len = p->lenTick(); - //for(ciEvent ie = el->begin(); ie != el->end(); ++ie) - //{ - //const Event& ev = ie->second; - // Added by T356. Do not remove events which are past the end of the part. - // No, actually, do remove ALL of them belonging to the part. - // Just in case there are stray values left after the part end. - //if(ev.tick() >= len) - // break; if(event.type() == Controller) { @@ -566,7 +527,6 @@ void removePortCtrlEvents(Event& event, Part* part, bool doClones) mp->deleteController(ch, tck, cntrl, p); } - //} } if(!doClones) @@ -734,14 +694,6 @@ MidiPart::MidiPart(const MidiPart& p) : Part(p) { _prevClone = this; _nextClone = this; - //setSn(newSn()); - //_sn = p._sn; - //_name = p._name; - //_selected = p._selected; - //_mute = p._mute; - //_colorIndex = p._colorIndex; - //_track = p._track; - //_events = p._events; } //--------------------------------------------------------- @@ -769,14 +721,6 @@ WavePart::WavePart(const WavePart& p) : Part(p) { _prevClone = this; _nextClone = this; - //setSn(newSn()); - //_sn = p._sn; - //_name = p._name; - //_selected = p._selected; - //_mute = p._mute; - //_colorIndex = p._colorIndex; - //_track = p._track; - //_events = p._events; } //--------------------------------------------------------- @@ -790,139 +734,6 @@ Part::~Part() delete _events; } -/* -//--------------------------------------------------------- -// unchainClone -//--------------------------------------------------------- - -void Part::unchainClone() -{ - chainCheckErr(); - - _prevClone->setNextClone(_nextClone); - _nextClone->setPrevClone(_prevClone); - - _prevClone = this; - _nextClone = this; -} - -//--------------------------------------------------------- -// chainClone -// The quick way - if part to chain to is known... -//--------------------------------------------------------- - -void Part::chainClone(const Part* p) -{ - chainCheckErr(); - - // Make sure the part is unchained first. - p->prevClone()->setNextClone(p->nextClone()); - p->nextClone()->setPrevClone(p->prevClone()); - - p->setPrevClone(this); - p->setNextClone(_nextClone->prevClone()); - - _nextClone->setPrevClone(p); - _nextClone = (Part*)p; -} - -//--------------------------------------------------------- -// chainClone -// The slow way - if part to chain to is not known... -//--------------------------------------------------------- - -void Part::chainClone() -{ - chainCheckErr(); - - // Look for a part with the same event list, that we can chain to... - Part* p = 0; - if(!_track || (_track && _track->isMidiTrack())) - { - MidiTrackList* mtl = song->midis(); - for(ciMidiTrack imt = mtl->begin(); imt != mtl->end(); ++imt) - { - const PartList* pl = (*imt)->cparts(); - for(ciPart ip = pl->begin(); ip != pl->end(); ++ip) - { - if(ip->second != this && ip->second->events() == _events) - { - p = ip->second; - break; - } - } - } - } - - if((!p && !_track) || (_track && _track->type() == Track::WAVE)) - { - WaveTrackList* wtl = song->waves(); - for(ciWaveTrack iwt = wtl->begin(); iwt != wtl->end(); ++iwt) - { - const PartList* pl = (*iwt)->cparts(); - for(ciPart ip = pl->begin(); ip != pl->end(); ++ip) - { - if(ip->second != this && ip->second->events() == _events) - { - p = ip->second; - break; - } - } - } - } - - // No part found with same event list? Done. - if(!p) - return; - - // Make sure this part is unchained first. - _prevClone->setNextClone(_nextClone); - _nextClone->setPrevClone(_prevClone); - - _prevClone = p; - _nextClone = p->nextClone(); - - p->nextClone()->setPrevClone(this); - p->setNextClone(this); -} - -//--------------------------------------------------------- -// replaceClone -//--------------------------------------------------------- - -void Part::replaceClone(const Part* p) -{ - chainCheckErr(); - - // Make sure the part is unchained first. - p->prevClone()->setNextClone(p->nextClone()); - p->nextClone()->setPrevClone(p->prevClone()); - - // If this part is a clone, not a single lone part... - if(_prevClone != this) - _prevClone->setNextClone(p); - if(_nextClone != this) - _nextClone->setPrevClone(p); - - p->setPrevClone(_prevClone); - p->setNextClone(_nextClone); - - _nextClone = this; - _prevClone = this; -} - -//--------------------------------------------------------- -// chainCheckErr -//--------------------------------------------------------- - -void Part::chainCheckErr() -{ - if(_nextClone->prevClone() != this) - printf("Part::chainCheckErr Error! Next clone:%s %x prev clone:%s %x != this:%s %x\n", _nextClone->name().toLatin1().constData(), _nextClone, _nextClone->prevClone()->name().toLatin1().constData(), _nextClone->prevClone(), name().toLatin1().constData(), this); - if(_prevClone->nextClone() != this) - printf("Part::chainCheckErr Error! Prev clone:%s %x next clone:%s %x != this:%s %x\n", _prevClone->name().toLatin1().constData(), _prevClone, _prevClone->nextClone()->name().toLatin1().constData(), _prevClone->nextClone(), name().toLatin1().constData(), this); -} -*/ //--------------------------------------------------------- // findPart @@ -988,7 +799,6 @@ void Song::addPart(Part* part) _len = epos; part->track()->addPart(part); - //part->addPortCtrlEvents(); // Indicate do not do clones. addPortCtrlEvents(part, false); } @@ -999,9 +809,7 @@ void Song::addPart(Part* part) void Song::removePart(Part* part) { - //part->removePortCtrlEvents(); // Indicate do not do clones. - //removePortCtrlEvents(part); removePortCtrlEvents(part, false); Track* track = part->track(); track->parts()->remove(part); @@ -1025,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; @@ -1035,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(); @@ -1079,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. @@ -1118,36 +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); + // Do port controller values and clone parts. + operations.push_back(UndoOp(UndoOp::DeleteEvent, i->second, nPart, true, true)); } } } - /* - // cut Events in nPart - // Changed by T356. Don't delete events if this is a clone part. - // The other clones might be longer than this one and need these events. - if(oPart->cevents()->arefCount() <= 1) - { - if (oPart->lenTick() > len) { - EventList* el = nPart->events(); - iEvent ie = el->lower_bound(len); - for (; ie != el->end();) { - iEvent i = ie; - ++ie; - // Indicate no undo, and do not do port controller values and clone parts. - //audio->msgDeleteEvent(i->second, nPart, false); - audio->msgDeleteEvent(i->second, nPart, false, false, false); - } - } - } - // Indicate no undo, and do port controller values but not clone parts. - //audio->msgChangePart(oPart, nPart, false); - audio->msgChangePart(oPart, nPart, false, true, false); - */ - - endUndo(SC_PART_MODIFIED); + song->applyOperationGroup(operations); break; } default: @@ -1281,27 +1059,9 @@ void Song::changePart(Part* oPart, Part* nPart) Track* oTrack = oPart->track(); Track* nTrack = nPart->track(); - // Added by Tim. p3.3.6 - //printf("Song::changePart before oPart->removePortCtrlEvents oldPart refs:%d Arefs:%d newPart refs:%d Arefs:%d\n", oPart->events()->refCount(), oPart->events()->arefCount(), nPart->events()->refCount(), nPart->events()->arefCount()); - - // Removed. Port controller events will have to be add/removed separately from this routine. - //oPart->removePortCtrlEvents(); - //removePortCtrlEvents(oPart); - - // Added by Tim. p3.3.6 - //printf("Song::changePart after oPart->removePortCtrlEvents oldPart refs:%d Arefs:%d newPart refs:%d Arefs:%d\n", oPart->events()->refCount(), oPart->events()->arefCount(), nPart->events()->refCount(), nPart->events()->arefCount()); - oTrack->parts()->remove(oPart); nTrack->parts()->add(nPart); - // Added by Tim. p3.3.6 - //printf("Song::changePart after add(nPart) oldPart refs:%d Arefs:%d newPart refs:%d Arefs:%d\n", oPart->events()->refCount(), oPart->events()->arefCount(), nPart->events()->refCount(), nPart->events()->arefCount()); - - //nPart->addPortCtrlEvents(); - //addPortCtrlEvents(nPart); - - // Added by Tim. p3.3.6 - //printf("Song::changePart after nPart->addPortCtrlEvents() oldPart refs:%d Arefs:%d newPart refs:%d Arefs:%d\n", oPart->events()->refCount(), oPart->events()->arefCount(), nPart->events()->refCount(), nPart->events()->arefCount()); // Added by T356. // adjust song len: @@ -1309,9 +1069,6 @@ void Song::changePart(Part* oPart, Part* nPart) if (epos > len()) _len = epos; - // Added by Tim. p3.3.6 - //printf("Song::changePart after len adjust oldPart refs:%d Arefs:%d newPart refs:%d Arefs:%d\n", oPart->events()->refCount(), oPart->events()->arefCount(), nPart->events()->refCount(), nPart->events()->arefCount()); - } //--------------------------------------------------------- @@ -1350,13 +1107,6 @@ void Song::cmdGluePart(Track* track, Part* oPart) EventList* sl2 = nextPart->events(); - //int frameOffset = nextPart->frame() - oPart->frame(); - //for (iEvent ie = sl2->begin(); ie != sl2->end(); ++ie) { - // Event event = ie->second.clone(); - // event.setFrame(event.frame() + frameOffset); - // dl->add(event); - // } - // p3.3.54 Changed. if(track->type() == Track::WAVE) { int frameOffset = nextPart->frame() - oPart->frame(); @@ -1382,7 +1132,6 @@ void Song::cmdGluePart(Track* track, Part* oPart) startUndo(); audio->msgRemovePart(nextPart, false); // Indicate no undo, and do port controller values but not clone parts. - //audio->msgChangePart(oPart, nPart, false); audio->msgChangePart(oPart, nPart, false, true, false); endUndo(SC_PART_MODIFIED | SC_PART_REMOVED); } diff --git a/muse2/muse/seqmsg.cpp b/muse2/muse/seqmsg.cpp index b4d65148..0aa74aaa 100644 --- a/muse2/muse/seqmsg.cpp +++ b/muse2/muse/seqmsg.cpp @@ -751,7 +751,7 @@ void Song::msgInsertTrack(Track* track, int idx, bool doUndoFlag) msg.ival = idx; if (doUndoFlag) { song->startUndo(); - undoOp(UndoOp::AddTrack, idx, track); + addUndo(UndoOp(UndoOp::AddTrack, idx, track)); } audio->sendMsg(&msg); if (doUndoFlag) diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 6750203a..6d0541a3 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -350,7 +350,7 @@ Track* Song::addTrack(int t) void Song::cmdRemoveTrack(Track* track) { int idx = _tracks.index(track); - undoOp(UndoOp::DeleteTrack, idx, track); + addUndo(UndoOp(UndoOp::DeleteTrack, idx, track)); removeTrack2(track); updateFlags |= SC_TRACK_REMOVED; } @@ -395,8 +395,8 @@ void Song::changeTrack(Track* oldTrack, Track* newTrack) oldTrack->setSelected(false); //?? int idx = _tracks.index(newTrack); - //undoOp(UndoOp::ModifyTrack, oldTrack, newTrack); - undoOp(UndoOp::ModifyTrack, idx, oldTrack, newTrack); + //addUndo(UndoOp(UndoOp::ModifyTrack, oldTrack, newTrack)); + addUndo(UndoOp(UndoOp::ModifyTrack, idx, oldTrack, newTrack)); updateFlags |= SC_TRACK_MODIFIED; } @@ -863,7 +863,7 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start // Now add all of the new part's port controller values. Indicate do not do clone parts. addPortCtrlEvents(newPart, false); // Create an undo op. Indicate do port controller values but not clone parts. - undoOp(UndoOp::ModifyPart, part, newPart, true, false); + addUndo(UndoOp(UndoOp::ModifyPart, part, newPart, true, false)); updateFlags |= SC_PART_MODIFIED; if (_recMode == REC_REPLACE) @@ -874,7 +874,7 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start { Event event = i->second; // Create an undo op. Indicate do port controller values and clone parts. - undoOp(UndoOp::DeleteEvent, event, newPart, true, true); + addUndo(UndoOp(UndoOp::DeleteEvent, event, newPart, true, true)); // Remove the event from the new part's port controller values, and do all clone parts. removePortCtrlEvents(event, newPart, true); } @@ -886,7 +886,7 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start event.setTick(event.tick() - partTick); Event e; // Create an undo op. Indicate do port controller values and clone parts. - undoOp(UndoOp::AddEvent, e, event, newPart, true, true); + addUndo(UndoOp(UndoOp::AddEvent, e, event, newPart, true, true)); if(newPart->events()->find(event) == newPart->events()->end()) newPart->events()->add(event); @@ -906,8 +906,8 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start { Event event = i->second; // Create an undo op. Indicate do port controller values and clone parts. - //undoOp(UndoOp::DeleteEvent, event, part); - undoOp(UndoOp::DeleteEvent, event, part, true, true); + //addUndo(UndoOp(UndoOp::DeleteEvent, event, part)); + addUndo(UndoOp(UndoOp::DeleteEvent, event, part, true, true)); //if (event.type() == Controller) { // MidiTrack* track = (MidiTrack*)part->track(); @@ -938,8 +938,8 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start event.setTick(tick); Event e; // Create an undo op. Indicate do port controller values and clone parts. - //undoOp(UndoOp::AddEvent, e, event, newPart); - undoOp(UndoOp::AddEvent, e, event, newPart, true, true); + //addUndo(UndoOp(UndoOp::AddEvent, e, event, newPart)); + addUndo(UndoOp(UndoOp::AddEvent, e, event, newPart, true, true)); // addEvent also adds port controller values. So does msgChangePart, below. Let msgChangePart handle them. //addEvent(event, (MidiPart*)newPart); @@ -965,9 +965,9 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start //printf("Song::cmdAddRecordedEvents after changePart part:%p events:%p refs:%d Arefs:%d newPart:%p events:%p refs:%d Arefs:%d\n", part, part->events(), part->events()->refCount(), part->events()->arefCount(), newPart, newPart->events(), newPart->events()->refCount(), newPart->events()->arefCount()); - //undoOp(UndoOp::ModifyPart, part, newPart); + //addUndo(UndoOp(UndoOp::ModifyPart, part, newPart)); // Create an undo op. Indicate do not do port controller values and clone parts. - undoOp(UndoOp::ModifyPart, part, newPart, false, false); + addUndo(UndoOp(UndoOp::ModifyPart, part, newPart, false, false)); // Removed by T356. //part->events()->incARef(-1); @@ -985,8 +985,8 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start for (iEvent i = si; i != ei; ++i) { Event event = i->second; // Create an undo op. Indicate that controller values and clone parts were handled. - //undoOp(UndoOp::DeleteEvent, event, part); - undoOp(UndoOp::DeleteEvent, event, part, true, true); + //addUndo(UndoOp(UndoOp::DeleteEvent, event, part)); + addUndo(UndoOp(UndoOp::DeleteEvent, event, part, true, true)); /* if (event.type() == Controller) { MidiTrack* track = (MidiTrack*)part->track(); @@ -1007,8 +1007,8 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, EventList* events, unsigned start event.setTick(tick); // Create an undo op. Indicate that controller values and clone parts were handled. - //undoOp(UndoOp::AddEvent, event, part); - undoOp(UndoOp::AddEvent, event, part, true, true); + //addUndo(UndoOp(UndoOp::AddEvent, event, part)); + addUndo(UndoOp(UndoOp::AddEvent, event, part, true, true)); //addEvent(event, part); if(part->events()->find(event) == part->events()->end()) @@ -1286,7 +1286,7 @@ void Song::setStopPlay(bool f) void Song::swapTracks(int i1, int i2) { - undoOp(UndoOp::SwapTrack, i1, i2); + addUndo(UndoOp(UndoOp::SwapTrack, i1, i2)); Track* track = _tracks[i1]; _tracks[i1] = _tracks[i2]; _tracks[i2] = track; @@ -1906,8 +1906,8 @@ void Song::processMsg(AudioMsg* msg) updateFlags = SC_EVENT_INSERTED; if (addEvent(msg->ev1, (MidiPart*)msg->p2)) { Event ev; - //undoOp(UndoOp::AddEvent, ev, msg->ev1, (Part*)msg->p2); - undoOp(UndoOp::AddEvent, ev, msg->ev1, (Part*)msg->p2, msg->a, msg->b); + //addUndo(UndoOp(UndoOp::AddEvent, ev, msg->ev1, (Part*)msg->p2)); + addUndo(UndoOp(UndoOp::AddEvent, ev, msg->ev1, (Part*)msg->p2, msg->a, msg->b)); } else updateFlags = 0; @@ -1921,8 +1921,8 @@ void Song::processMsg(AudioMsg* msg) if(msg->a) removePortCtrlEvents(event, part, msg->b); Event e; - //undoOp(UndoOp::DeleteEvent, e, event, (Part*)part); - undoOp(UndoOp::DeleteEvent, e, event, (Part*)part, msg->a, msg->b); + //addUndo(UndoOp(UndoOp::DeleteEvent, e, event, (Part*)part)); + addUndo(UndoOp(UndoOp::DeleteEvent, e, event, (Part*)part, msg->a, msg->b)); deleteEvent(event, part); updateFlags = SC_EVENT_REMOVED; } @@ -1933,21 +1933,21 @@ void Song::processMsg(AudioMsg* msg) changeEvent(msg->ev1, msg->ev2, (MidiPart*)msg->p3); if(msg->a) addPortCtrlEvents(msg->ev2, (Part*)msg->p3, msg->b); - //undoOp(UndoOp::ModifyEvent, msg->ev2, msg->ev1, (Part*)msg->p3); - undoOp(UndoOp::ModifyEvent, msg->ev2, msg->ev1, (Part*)msg->p3, msg->a, msg->b); + //addUndo(UndoOp(UndoOp::ModifyEvent, msg->ev2, msg->ev1, (Part*)msg->p3)); + addUndo(UndoOp(UndoOp::ModifyEvent, msg->ev2, msg->ev1, (Part*)msg->p3, msg->a, msg->b)); updateFlags = SC_EVENT_MODIFIED; break; case SEQM_ADD_TEMPO: //printf("processMsg (SEQM_ADD_TEMPO) UndoOp::AddTempo. adding tempo at: %d with tempo=%d\n", msg->a, msg->b); - undoOp(UndoOp::AddTempo, msg->a, msg->b); + addUndo(UndoOp(UndoOp::AddTempo, msg->a, msg->b)); tempomap.addTempo(msg->a, msg->b); updateFlags = SC_TEMPO; break; case SEQM_SET_TEMPO: //printf("processMsg (SEQM_SET_TEMPO) UndoOp::AddTempo. adding tempo at: %d with tempo=%d\n", msg->a, msg->b); - undoOp(UndoOp::AddTempo, msg->a, msg->b); + addUndo(UndoOp(UndoOp::AddTempo, msg->a, msg->b)); tempomap.setTempo(msg->a, msg->b); updateFlags = SC_TEMPO; break; @@ -1958,31 +1958,31 @@ void Song::processMsg(AudioMsg* msg) case SEQM_REMOVE_TEMPO: //printf("processMsg (SEQM_REMOVE_TEMPO) UndoOp::DeleteTempo. adding tempo at: %d with tempo=%d\n", msg->a, msg->b); - undoOp(UndoOp::DeleteTempo, msg->a, msg->b); + addUndo(UndoOp(UndoOp::DeleteTempo, msg->a, msg->b)); tempomap.delTempo(msg->a); updateFlags = SC_TEMPO; break; case SEQM_ADD_SIG: - undoOp(UndoOp::AddSig, msg->a, msg->b, msg->c); + addUndo(UndoOp(UndoOp::AddSig, msg->a, msg->b, msg->c)); AL::sigmap.add(msg->a, AL::TimeSignature(msg->b, msg->c)); updateFlags = SC_SIG; break; case SEQM_REMOVE_SIG: - undoOp(UndoOp::DeleteSig, msg->a, msg->b, msg->c); + addUndo(UndoOp(UndoOp::DeleteSig, msg->a, msg->b, msg->c)); AL::sigmap.del(msg->a); updateFlags = SC_SIG; break; case SEQM_ADD_KEY: - undoOp(UndoOp::AddKey, msg->a, msg->b); + addUndo(UndoOp(UndoOp::AddKey, msg->a, msg->b)); keymap.addKey(msg->a, (key_enum) msg->b); updateFlags = SC_KEY; break; case SEQM_REMOVE_KEY: - undoOp(UndoOp::DeleteKey, msg->a, msg->b); + addUndo(UndoOp(UndoOp::DeleteKey, msg->a, msg->b)); keymap.delKey(msg->a); updateFlags = SC_KEY; break; @@ -2000,7 +2000,7 @@ void Song::processMsg(AudioMsg* msg) void Song::cmdAddPart(Part* part) { addPart(part); - undoOp(UndoOp::AddPart, part); + addUndo(UndoOp(UndoOp::AddPart, part)); updateFlags = SC_PART_INSERTED; } @@ -2011,7 +2011,7 @@ void Song::cmdAddPart(Part* part) void Song::cmdRemovePart(Part* part) { removePart(part); - undoOp(UndoOp::DeletePart, part); + addUndo(UndoOp(UndoOp::DeletePart, part)); part->events()->incARef(-1); //part->unchainClone(); unchainClone(part); @@ -2032,8 +2032,8 @@ void Song::cmdChangePart(Part* oldPart, Part* newPart, bool doCtrls, bool doClon changePart(oldPart, newPart); - //undoOp(UndoOp::ModifyPart, oldPart, newPart); - undoOp(UndoOp::ModifyPart, oldPart, newPart, doCtrls, doClones); + //addUndo(UndoOp(UndoOp::ModifyPart, oldPart, newPart)); + addUndo(UndoOp(UndoOp::ModifyPart, oldPart, newPart, doCtrls, doClones)); // Changed by T356. Do not decrement ref count if the new part is a clone of the old part, since the event list // will still be active. diff --git a/muse2/muse/song.h b/muse2/muse/song.h index 47fd96d4..fd88b278 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -147,6 +147,8 @@ class Song : public QObject { Song(const char* name = 0); ~Song(); + bool applyOperationGroup(Undo& group, bool doUndo=true); + void putEvent(int pv); void endMsgCmd(); void processMsg(AudioMsg* msg); @@ -316,21 +318,9 @@ class Song : public QObject { void startUndo(); void endUndo(int); - //void undoOp(UndoOp::UndoType, Track* oTrack, Track* nTrack); - void undoOp(UndoOp::UndoType, int n, Track* oTrack, Track* nTrack); - void undoOp(UndoOp::UndoType, int, Track*); - void undoOp(UndoOp::UndoType, int, int, int = 0); - void undoOp(UndoOp::UndoType, Part*); - //void undoOp(UndoOp::UndoType, Event& nevent, Part*); - void undoOp(UndoOp::UndoType, Event& nevent, Part*, bool doCtrls, bool doClones); - //void undoOp(UndoOp::UndoType, Event& oevent, Event& nevent, Part*); - void undoOp(UndoOp::UndoType, Event& oevent, Event& nevent, Part*, bool doCtrls, bool doClones); - void undoOp(UndoOp::UndoType, SigEvent* oevent, SigEvent* nevent); - void undoOp(UndoOp::UndoType, int channel, int ctrl, int oval, int nval); - //void undoOp(UndoOp::UndoType, Part* oPart, Part* nPart); - void undoOp(UndoOp::UndoType, Part* oPart, Part* nPart, bool doCtrls, bool doClones); + void undoOp(UndoOp::UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe); - void undoOp(UndoOp::UndoType type, Marker* copyMarker, Marker* realMarker); + bool doUndo1(); void doUndo2(); void doUndo3(); @@ -338,7 +328,7 @@ class Song : public QObject { void doRedo2(); void doRedo3(); - void addUndo(UndoOp& i); + void addUndo(UndoOp i); //----------------------------------------- // Configuration diff --git a/muse2/muse/structure.cpp b/muse2/muse/structure.cpp index f0a4308a..27246315 100644 --- a/muse2/muse/structure.cpp +++ b/muse2/muse/structure.cpp @@ -99,12 +99,12 @@ void MusE::adjustGlobalLists(int startPos, int diff) Marker *oldMarker = new Marker(); *oldMarker = *m; markerlist->remove(m); - song->undoOp(UndoOp::ModifyMarker,oldMarker, 0); + song->addUndo(UndoOp(UndoOp::ModifyMarker,oldMarker, 0)); } else { Marker *oldMarker = new Marker(); *oldMarker = *m; m->setTick(tick + diff); - song->undoOp(UndoOp::ModifyMarker,oldMarker, m); + song->addUndo(UndoOp(UndoOp::ModifyMarker,oldMarker, m)); } } } diff --git a/muse2/muse/transport.h b/muse2/muse/transport.h index b2d3facf..ce8dcf1b 100644 --- a/muse2/muse/transport.h +++ b/muse2/muse/transport.h @@ -34,10 +34,12 @@ class Pos; //--------------------------------------------------------- class TempoSig : public QWidget { + Q_OBJECT + DoubleLabel* l1; SigLabel* l2; QLabel* l3; - Q_OBJECT + private slots: void configChanged(); @@ -76,6 +78,8 @@ class TimeLLabel; class Transport : public QWidget { + Q_OBJECT + PosEdit* tl1; // left mark PosEdit* tl2; // right mark PosEdit* time1; // tick time @@ -99,9 +103,7 @@ class Transport : public QWidget Handle *lefthandle, *righthandle; - Q_OBJECT - - private slots: + private slots: void cposChanged(const Pos&); void cposChanged(int); void lposChanged(const Pos&); diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp index a31b8e7a..c57bb5c1 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 @@ -184,6 +186,9 @@ void UndoList::clearDelete() void Song::startUndo() { + redoList->clear(); // added by flo93: redo must be invalidated when + redoAction->setEnabled(false); // a new undo is started + undoList->push_back(Undo()); updateFlags = 0; undoMode = true; @@ -200,6 +205,34 @@ void Song::endUndo(int flags) undoMode = false; } + +bool Song::applyOperationGroup(Undo& group, bool doUndo) +{ + if (!group.empty()) + { + //this is a HACK! but it works :) (added by flo93) + redoList->push_back(group); + redo(); + + if (!doUndo) + { + undoList->pop_back(); + undoAction->setEnabled(!undoList->empty()); + } + else + { + redoList->clear(); // added by flo93: redo must be invalidated when + redoAction->setEnabled(false); // a new undo is started + } + + return doUndo; + } + else + return false; +} + + + //--------------------------------------------------------- // doUndo2 // real time part @@ -688,134 +721,109 @@ void Song::doRedo2() } } -void Song::undoOp(UndoOp::UndoType type, int a, int b, int c) +UndoOp::UndoOp() +{ +} + +UndoOp::UndoOp(UndoType type_, int a_, int b_, int c_) { - UndoOp i; - i.type = type; - i.a = a; - i.b = b; - i.c = c; - addUndo(i); + type = type_; + a = a_; + b = b_; + c = c_; } -//void Song::undoOp(UndoOp::UndoType type, Track* oldTrack, Track* newTrack) -void Song::undoOp(UndoOp::UndoType type, int n, Track* oldTrack, Track* newTrack) +UndoOp::UndoOp(UndoType type_, int n, Track* oldTrack, Track* newTrack) { - UndoOp i; - i.type = type; - i.trackno = n; - i.oTrack = oldTrack; - i.nTrack = newTrack; - // Added by Tim. p3.3.6 - //printf("Song::undoOp ModifyTrack oTrack %p %s nTrack %p %s\n", i.oTrack, i.oTrack->name().toLatin1().constData(), i.nTrack, i.nTrack->name().toLatin1().constData()); - - addUndo(i); + type = type_; + trackno = n; + oTrack = oldTrack; + nTrack = newTrack; } -void Song::undoOp(UndoOp::UndoType type, int n, Track* track) +UndoOp::UndoOp(UndoType type_, int n, Track* track) { - UndoOp i; - i.type = type; - i.trackno = n; - i.oTrack = track; - if (type == UndoOp::AddTrack) - updateFlags |= SC_TRACK_INSERTED; - addUndo(i); + type = type_; + trackno = n; + oTrack = track; } -void Song::undoOp(UndoOp::UndoType type, Part* part) +UndoOp::UndoOp(UndoType type_, Part* part) { - UndoOp i; - i.type = type; - i.oPart = part; - addUndo(i); + type = type_; + oPart = part; } -//void Song::undoOp(UndoOp::UndoType type, Event& oev, Event& nev, Part* part) -void Song::undoOp(UndoOp::UndoType type, Event& oev, Event& nev, Part* part, bool doCtrls, bool doClones) +UndoOp::UndoOp(UndoType type_, Event& oev, Event& nev, Part* part_, bool doCtrls_, bool doClones_) { - UndoOp i; - i.type = type; - i.nEvent = nev; - i.oEvent = oev; - i.part = part; - i.doCtrls = doCtrls; - i.doClones = doClones; - addUndo(i); + type = type_; + nEvent = nev; + oEvent = oev; + part = part_; + doCtrls = doCtrls_; + doClones = doClones_; } -void Song::undoOp(UndoOp::UndoType type, Event& nev, Part* part, bool doCtrls, bool doClones) +UndoOp::UndoOp(UndoType type_, Event& nev, Part* part_, bool doCtrls_, bool doClones_) { - UndoOp i; - i.type = type; - i.nEvent = nev; - i.part = part; - i.doCtrls = doCtrls; - i.doClones = doClones; - addUndo(i); + type = type_; + nEvent = nev; + part = part_; + doCtrls = doCtrls_; + doClones = doClones_; } -//void Song::undoOp(UndoOp::UndoType type, Part* oPart, Part* nPart) -void Song::undoOp(UndoOp::UndoType type, Part* oPart, Part* nPart, bool doCtrls, bool doClones) +UndoOp::UndoOp(UndoType type_, Part* oPart_, Part* nPart_, bool doCtrls_, bool doClones_) { - UndoOp i; - i.type = type; - i.oPart = nPart; - i.nPart = oPart; - i.doCtrls = doCtrls; - i.doClones = doClones; - addUndo(i); + type = type_; + oPart = nPart_; + nPart = oPart_; + doCtrls = doCtrls_; + doClones = doClones_; } -void Song::undoOp(UndoOp::UndoType type, int c, int ctrl, int ov, int nv) +UndoOp::UndoOp(UndoType type_, int c, int ctrl_, int ov, int nv) { - UndoOp i; - i.type = type; - i.channel = c; - i.ctrl = ctrl; - i.oVal = ov; - i.nVal = nv; - addUndo(i); + type = type_; + channel = c; + ctrl = ctrl_; + oVal = ov; + nVal = nv; } -void Song::undoOp(UndoOp::UndoType type, SigEvent* oevent, SigEvent* nevent) +UndoOp::UndoOp(UndoType type_, SigEvent* oevent, SigEvent* nevent) { - UndoOp i; - i.type = type; - i.oSignature = oevent; - i.nSignature = nevent; - addUndo(i); + type = type_; + oSignature = oevent; + nSignature = nevent; } - -void Song::undoOp(UndoOp::UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe) +UndoOp::UndoOp(UndoType type_, Marker* copyMarker_, Marker* realMarker_) { - UndoOp i; - i.type = type; - i.filename = changedFile; - i.tmpwavfile = changeData; - i.startframe = startframe; - i.endframe = endframe; - addUndo(i); - temporaryWavFiles.push_back(QString(changeData)); - - //printf("Adding ModifyClip undo-operation: origfile=%s tmpfile=%s sf=%d ef=%d\n", changedFile, changeData, startframe, endframe); + type = type_; + realMarker = realMarker_; + copyMarker = copyMarker_; } -void Song::undoOp(UndoOp::UndoType type, Marker* copyMarker, Marker* realMarker) +UndoOp::UndoOp(UndoType type_, const char* changedFile, const char* changeData, int startframe_, int endframe_) { - UndoOp i; - i.type = type; - i.realMarker = realMarker; - i.copyMarker = copyMarker; + type = type_; + filename = changedFile; + tmpwavfile = changeData; + startframe = startframe_; + endframe = endframe_; + } - addUndo(i); +void Song::undoOp(UndoOp::UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe) + { + addUndo(UndoOp(type,changedFile,changeData,startframe,endframe)); + temporaryWavFiles.push_back(QString(changeData)); } //--------------------------------------------------------- // addUndo //--------------------------------------------------------- -void Song::addUndo(UndoOp& i) +void Song::addUndo(UndoOp i) { if (!undoMode) { printf("internal error: undoOp without startUndo()\n"); diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h index eb5600ef..88810b80 100644 --- a/muse2/muse/undo.h +++ b/muse2/muse/undo.h @@ -83,8 +83,22 @@ struct UndoOp { Event nEvent; bool doCtrls; bool doClones; + const char* typeName(); void dump(); + + UndoOp(); + UndoOp(UndoType type, int a, int b, int c=0); + UndoOp(UndoType type, int n, Track* oldTrack, Track* newTrack); + UndoOp(UndoType type, int n, Track* track); + UndoOp(UndoType type, Part* part); + UndoOp(UndoType type, Event& oev, Event& nev, Part* part, bool doCtrls, bool doClones); + UndoOp(UndoType type, Event& nev, Part* part, bool doCtrls, bool doClones); + UndoOp(UndoType type, Part* oPart, Part* nPart, bool doCtrls, bool doClones); + UndoOp(UndoType type, int c, int ctrl, int ov, int nv); + UndoOp(UndoType type, SigEvent* oevent, SigEvent* nevent); + UndoOp(UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe); + UndoOp(UndoType type, Marker* copyMarker, Marker* realMarker); }; class Undo : public std::list<UndoOp> { diff --git a/muse2/muse/value.h b/muse2/muse/value.h index 22aa9b5a..e5c74b20 100644 --- a/muse2/muse/value.h +++ b/muse2/muse/value.h @@ -18,9 +18,9 @@ class Xml; //--------------------------------------------------------- class IValue : public QObject { - int val; - Q_OBJECT + + int val; signals: void valueChanged(int); @@ -39,9 +39,11 @@ class IValue : public QObject { //--------------------------------------------------------- class BValue : public QObject { + Q_OBJECT + bool val; - Q_OBJECT + signals: void valueChanged(bool); diff --git a/muse2/muse/waveedit/waveedit.h b/muse2/muse/waveedit/waveedit.h index e966a635..1ff8a65b 100644 --- a/muse2/muse/waveedit/waveedit.h +++ b/muse2/muse/waveedit/waveedit.h @@ -33,6 +33,8 @@ class QAction; //--------------------------------------------------------- class WaveEdit : public MidiEditor { + Q_OBJECT + WaveView* view; QSlider* ymag; QToolBar* tools; @@ -49,7 +51,7 @@ class WaveEdit : public MidiEditor { static int _widthInit, _heightInit; static QByteArray _toolbarInit; - Q_OBJECT + virtual void closeEvent(QCloseEvent*); virtual void keyPressEvent(QKeyEvent*); virtual void resizeEvent(QResizeEvent* ev); diff --git a/muse2/muse/waveedit/waveview.h b/muse2/muse/waveedit/waveview.h index c7992952..1a646af9 100644 --- a/muse2/muse/waveedit/waveview.h +++ b/muse2/muse/waveedit/waveview.h @@ -34,6 +34,8 @@ typedef std::list<WaveEventSelection>::iterator iWaveSelection; //--------------------------------------------------------- class WaveView : public View { + Q_OBJECT + MidiEditor* editor; unsigned pos[3]; int yScale; @@ -50,7 +52,6 @@ class WaveView : public View { unsigned selectionStart, selectionStop, dragstartx; - Q_OBJECT virtual void pdraw(QPainter&, const QRect&); virtual void draw(QPainter&, const QRect&); virtual void viewMousePressEvent(QMouseEvent*); diff --git a/muse2/muse/widgets/bigtime.h b/muse2/muse/widgets/bigtime.h index bb32cedc..eff0ef92 100644 --- a/muse2/muse/widgets/bigtime.h +++ b/muse2/muse/widgets/bigtime.h @@ -13,9 +13,11 @@ class MusE; //--------------------------------------------------------- class BigTime : public QWidget { + Q_OBJECT + bool tickmode; MusE* seq; - Q_OBJECT + bool setString(unsigned); diff --git a/muse2/muse/widgets/canvas.cpp b/muse2/muse/widgets/canvas.cpp index 18de985b..fc0b1b6f 100644 --- a/muse2/muse/widgets/canvas.cpp +++ b/muse2/muse/widgets/canvas.cpp @@ -1210,56 +1210,6 @@ void Canvas::selectLasso(bool toggle) } } -//--------------------------------------------------------- -// endMoveItems -// dir = 0 move in all directions -// 1 move only horizontal -// 2 move only vertical -//--------------------------------------------------------- - -void Canvas::endMoveItems(const QPoint& pos, DragType dragtype, int dir) - { - startUndo(dragtype); - - int dp = y2pitch(pos.y()) - y2pitch(start.y()); - int dx = pos.x() - start.x(); - - if (dir == 1) - dp = 0; - else if (dir == 2) - dx = 0; - - - - int modified = 0; - - // Removed by T356. - /* - for (iCItem i = moving.begin(); i != moving.end(); ++i) { - int x = i->second->pos().x(); - int y = i->second->pos().y(); - int nx = x + dx; - int ny = pitch2y(y2pitch(y) + dp); - QPoint newpos = raster(QPoint(nx, ny)); - selectItem(i->second, true); - - if (moveItem(i->second, newpos, dragtype, &modified)) - i->second->move(newpos); - if (moving.size() == 1) { - itemReleased(curItem, newpos); - } - if (dragtype == MOVE_COPY || dragtype == MOVE_CLONE) - selectItem(i->second, false); - } - */ - - moveCanvasItems(moving, dp, dx, dragtype, &modified); - - endUndo(dragtype, modified); - moving.clear(); - updateSelection(); - redraw(); - } //--------------------------------------------------------- // getCurrentDrag diff --git a/muse2/muse/widgets/canvas.h b/muse2/muse/widgets/canvas.h index 6e8b9fa8..2eae3d03 100644 --- a/muse2/muse/widgets/canvas.h +++ b/muse2/muse/widgets/canvas.h @@ -11,6 +11,7 @@ #include "citem.h" #include "view.h" #include "tools.h" +#include "undo.h" #include <QWheelEvent> #include <QMouseEvent> @@ -100,17 +101,10 @@ class Canvas : public View { virtual int y2pitch(int) const = 0; //CDW virtual int pitch2y(int) const = 0; //CDW - virtual void moveCanvasItems(CItemList&, int, int, DragType, int*) = 0; - // Changed by T356. - //virtual bool moveItem(CItem*, const QPoint&, DragType, int*) = 0; - virtual bool moveItem(CItem*, const QPoint&, DragType) = 0; virtual CItem* newItem(const QPoint&, int state) = 0; virtual void resizeItem(CItem*, bool noSnap=false) = 0; virtual void newItem(CItem*, bool noSnap=false) = 0; virtual bool deleteItem(CItem*) = 0; - virtual void startUndo(DragType) = 0; - - virtual void endUndo(DragType, int flags) = 0; int getCurrentDrag(); /*! @@ -153,7 +147,7 @@ class Canvas : public View { void startMoving(const QPoint&, DragType); void moveItems(const QPoint&, int dir, bool rasterize = true); - void endMoveItems(const QPoint&, DragType, int dir); + virtual void endMoveItems(const QPoint&, DragType, int dir) = 0; virtual void selectLasso(bool toggle); diff --git a/muse2/muse/widgets/comment.h b/muse2/muse/widgets/comment.h index 688d7b2f..0dbd953b 100644 --- a/muse2/muse/widgets/comment.h +++ b/muse2/muse/widgets/comment.h @@ -36,8 +36,10 @@ class Comment : public QWidget, public Ui::CommentBase { //--------------------------------------------------------- class TrackComment : public Comment { - Track* track; Q_OBJECT + + Track* track; + private: virtual void setText(const QString& s); diff --git a/muse2/muse/widgets/function_dialogs/crescendo.h b/muse2/muse/widgets/function_dialogs/crescendo.h index eb00e94f..73a7e088 100644 --- a/muse2/muse/widgets/function_dialogs/crescendo.h +++ b/muse2/muse/widgets/function_dialogs/crescendo.h @@ -15,8 +15,9 @@ class Xml; class Crescendo : public QDialog, public Ui::CrescendoBase { + Q_OBJECT private: - Q_OBJECT + QButtonGroup* range_group; protected slots: diff --git a/muse2/muse/widgets/function_dialogs/deloverlaps.h b/muse2/muse/widgets/function_dialogs/deloverlaps.h index 813192a6..d151d5a5 100644 --- a/muse2/muse/widgets/function_dialogs/deloverlaps.h +++ b/muse2/muse/widgets/function_dialogs/deloverlaps.h @@ -15,8 +15,9 @@ class Xml; class DelOverlaps : public QDialog, public Ui::DelOverlapsBase { + Q_OBJECT private: - Q_OBJECT + QButtonGroup* range_group; protected slots: diff --git a/muse2/muse/widgets/function_dialogs/gatetime.h b/muse2/muse/widgets/function_dialogs/gatetime.h index f8f35ffd..baa5a97b 100644 --- a/muse2/muse/widgets/function_dialogs/gatetime.h +++ b/muse2/muse/widgets/function_dialogs/gatetime.h @@ -18,8 +18,9 @@ class Xml; //--------------------------------------------------------- class GateTime : public QDialog, public Ui::GateTimeBase { + Q_OBJECT private: - Q_OBJECT + QButtonGroup *rangeGroup; protected slots: diff --git a/muse2/muse/widgets/function_dialogs/legato.h b/muse2/muse/widgets/function_dialogs/legato.h index 80b371ca..00831830 100644 --- a/muse2/muse/widgets/function_dialogs/legato.h +++ b/muse2/muse/widgets/function_dialogs/legato.h @@ -15,8 +15,9 @@ class Xml; class Legato : public QDialog, public Ui::LegatoBase { + Q_OBJECT private: - Q_OBJECT + QButtonGroup* range_group; protected slots: diff --git a/muse2/muse/widgets/function_dialogs/move.h b/muse2/muse/widgets/function_dialogs/move.h index 4c90a922..5049c567 100644 --- a/muse2/muse/widgets/function_dialogs/move.h +++ b/muse2/muse/widgets/function_dialogs/move.h @@ -15,8 +15,9 @@ class Xml; class Move : public QDialog, public Ui::MoveBase { + Q_OBJECT private: - Q_OBJECT + QButtonGroup* range_group; protected slots: diff --git a/muse2/muse/widgets/function_dialogs/quantize.h b/muse2/muse/widgets/function_dialogs/quantize.h index 399e2545..a857e667 100644 --- a/muse2/muse/widgets/function_dialogs/quantize.h +++ b/muse2/muse/widgets/function_dialogs/quantize.h @@ -15,8 +15,9 @@ class Xml; class Quantize : public QDialog, public Ui::QuantBase { + Q_OBJECT private: - Q_OBJECT + QButtonGroup* range_group; protected slots: diff --git a/muse2/muse/widgets/function_dialogs/remove.h b/muse2/muse/widgets/function_dialogs/remove.h index 4c1a91e9..33ac3fd0 100644 --- a/muse2/muse/widgets/function_dialogs/remove.h +++ b/muse2/muse/widgets/function_dialogs/remove.h @@ -15,8 +15,9 @@ class Xml; class Remove : public QDialog, public Ui::RemoveBase { + Q_OBJECT private: - Q_OBJECT + QButtonGroup* range_group; protected slots: diff --git a/muse2/muse/widgets/function_dialogs/setlen.h b/muse2/muse/widgets/function_dialogs/setlen.h index ad66a38b..6a052bdb 100644 --- a/muse2/muse/widgets/function_dialogs/setlen.h +++ b/muse2/muse/widgets/function_dialogs/setlen.h @@ -15,8 +15,9 @@ class Xml; class Setlen : public QDialog, public Ui::SetlenBase { + Q_OBJECT private: - Q_OBJECT + QButtonGroup* range_group; protected slots: diff --git a/muse2/muse/widgets/function_dialogs/transpose.h b/muse2/muse/widgets/function_dialogs/transpose.h index 97dd443e..b85bb827 100644 --- a/muse2/muse/widgets/function_dialogs/transpose.h +++ b/muse2/muse/widgets/function_dialogs/transpose.h @@ -15,7 +15,6 @@ class Xml; class Transpose : public QDialog, public Ui::TransposeBase { - private: Q_OBJECT QButtonGroup* range_group; diff --git a/muse2/muse/widgets/function_dialogs/velocity.h b/muse2/muse/widgets/function_dialogs/velocity.h index cbea4e22..83aac54d 100644 --- a/muse2/muse/widgets/function_dialogs/velocity.h +++ b/muse2/muse/widgets/function_dialogs/velocity.h @@ -18,8 +18,9 @@ class Xml; //--------------------------------------------------------- class Velocity : public QDialog, public Ui::VelocityBase { - private: Q_OBJECT + private: + QButtonGroup* rangeGroup; protected slots: diff --git a/muse2/muse/widgets/lcombo.h b/muse2/muse/widgets/lcombo.h index b125fce5..760d4512 100644 --- a/muse2/muse/widgets/lcombo.h +++ b/muse2/muse/widgets/lcombo.h @@ -20,8 +20,9 @@ class QString; //--------------------------------------------------------- class LabelCombo : public QWidget { - QComboBox* box; Q_OBJECT + QComboBox* box; + signals: void activated(int); diff --git a/muse2/muse/widgets/menutitleitem.h b/muse2/muse/widgets/menutitleitem.h index 0c345ffe..20583bd1 100644 --- a/muse2/muse/widgets/menutitleitem.h +++ b/muse2/muse/widgets/menutitleitem.h @@ -15,8 +15,9 @@ //--------------------------------------------------------- class MenuTitleItem : public QWidgetAction { - private: Q_OBJECT + private: + QString s; diff --git a/muse2/muse/widgets/meter.h b/muse2/muse/widgets/meter.h index 2b816040..cced6e7a 100644 --- a/muse2/muse/widgets/meter.h +++ b/muse2/muse/widgets/meter.h @@ -17,6 +17,7 @@ class QPainter; class Meter : public QFrame { + Q_OBJECT public: enum MeterType {DBMeter, LinMeter}; private: @@ -29,7 +30,7 @@ class Meter : public QFrame { void drawVU(QPainter& p, int, int, int); - Q_OBJECT + void paintEvent(QPaintEvent*); void resizeEvent(QResizeEvent*); void mousePressEvent(QMouseEvent*); diff --git a/muse2/muse/widgets/noteinfo.h b/muse2/muse/widgets/noteinfo.h index cc8fe16d..64842988 100644 --- a/muse2/muse/widgets/noteinfo.h +++ b/muse2/muse/widgets/noteinfo.h @@ -25,6 +25,8 @@ class Pos; //--------------------------------------------------------- class NoteInfo : public QToolBar { + Q_OBJECT + ///PosEdit* selTime; Awl::PosEdit* selTime; QSpinBox* selLen; @@ -33,7 +35,7 @@ class NoteInfo : public QToolBar { QSpinBox* selVelOff; bool deltaMode; - Q_OBJECT + public: enum ValType {VAL_TIME, VAL_LEN, VAL_VELON, VAL_VELOFF, VAL_PITCH }; diff --git a/muse2/muse/widgets/pitchlabel.h b/muse2/muse/widgets/pitchlabel.h index 6372f711..d29a4ee4 100644 --- a/muse2/muse/widgets/pitchlabel.h +++ b/muse2/muse/widgets/pitchlabel.h @@ -15,9 +15,11 @@ //--------------------------------------------------------- class PitchLabel : public QLabel { + Q_OBJECT + bool _pitchMode; int _value; - Q_OBJECT + protected: QSize sizeHint() const; diff --git a/muse2/muse/widgets/poslabel.h b/muse2/muse/widgets/poslabel.h index 29c5297d..7be236ec 100644 --- a/muse2/muse/widgets/poslabel.h +++ b/muse2/muse/widgets/poslabel.h @@ -15,10 +15,12 @@ //--------------------------------------------------------- class PosLabel : public QLabel { + Q_OBJECT + bool _smpte; unsigned _tickValue; unsigned _sampleValue; - Q_OBJECT + void updateValue(); diff --git a/muse2/muse/widgets/projectcreateimpl.h b/muse2/muse/widgets/projectcreateimpl.h index 77547c1a..3ca61e36 100644 --- a/muse2/muse/widgets/projectcreateimpl.h +++ b/muse2/muse/widgets/projectcreateimpl.h @@ -6,7 +6,7 @@ class ProjectCreateImpl : public QDialog, Ui::ProjectCreate { -Q_OBJECT + Q_OBJECT QString directoryPath; public: diff --git a/muse2/muse/widgets/scrollscale.h b/muse2/muse/widgets/scrollscale.h index 32043070..67cfe573 100644 --- a/muse2/muse/widgets/scrollscale.h +++ b/muse2/muse/widgets/scrollscale.h @@ -21,6 +21,8 @@ class QToolButton; //--------------------------------------------------------- class ScrollScale : public QWidget { + Q_OBJECT + QSlider* scale; QScrollBar* scroll; int minVal, maxVal; @@ -38,8 +40,7 @@ class ScrollScale : public QWidget { double logbase; virtual void resizeEvent(QResizeEvent*); - Q_OBJECT - + private slots: void pageUp(); void pageDown(); diff --git a/muse2/muse/widgets/swidget.h b/muse2/muse/widgets/swidget.h index c5f4fd6a..45f8cad0 100644 --- a/muse2/muse/widgets/swidget.h +++ b/muse2/muse/widgets/swidget.h @@ -17,8 +17,9 @@ //--------------------------------------------------------- class SWidget : public QWidget { - virtual void resizeEvent(QResizeEvent*); Q_OBJECT + virtual void resizeEvent(QResizeEvent*); + signals: void heightChanged(int); diff --git a/muse2/muse/widgets/tb1.h b/muse2/muse/widgets/tb1.h index ff31593f..3e721e74 100644 --- a/muse2/muse/widgets/tb1.h +++ b/muse2/muse/widgets/tb1.h @@ -23,14 +23,15 @@ class LabelCombo; //--------------------------------------------------------- class Toolbar1 : public QToolBar { + Q_OBJECT + QToolButton* solo; PosLabel* pos; PitchLabel* pitch; LabelCombo* raster; QTableWidget* rlist; bool showPitch; - Q_OBJECT - + private slots: void _rasterChanged(int); diff --git a/muse2/muse/widgets/tempolabel.h b/muse2/muse/widgets/tempolabel.h index 71aeb4b8..69dc1450 100644 --- a/muse2/muse/widgets/tempolabel.h +++ b/muse2/muse/widgets/tempolabel.h @@ -16,9 +16,11 @@ //--------------------------------------------------------- class TempoLabel : public QLabel { + Q_OBJECT + double _value; - Q_OBJECT + protected: QSize sizeHint() const; diff --git a/muse2/muse/widgets/tools.h b/muse2/muse/widgets/tools.h index be479a50..2116b958 100644 --- a/muse2/muse/widgets/tools.h +++ b/muse2/muse/widgets/tools.h @@ -46,6 +46,7 @@ extern ToolB toolList[]; class EditToolBar : public QToolBar { Q_OBJECT + Action** actions; int nactions; diff --git a/muse2/muse/widgets/unusedwavefiles.h b/muse2/muse/widgets/unusedwavefiles.h index fd1f524c..e28754de 100644 --- a/muse2/muse/widgets/unusedwavefiles.h +++ b/muse2/muse/widgets/unusedwavefiles.h @@ -10,6 +10,7 @@ namespace Ui { class UnusedWaveFiles : public QDialog { Q_OBJECT + QStringList allWaveFiles; public: explicit UnusedWaveFiles(QWidget *parent = 0); diff --git a/muse2/muse/widgets/verticalmeter.h b/muse2/muse/widgets/verticalmeter.h index 699be1e5..facc8b8c 100644 --- a/muse2/muse/widgets/verticalmeter.h +++ b/muse2/muse/widgets/verticalmeter.h @@ -17,6 +17,8 @@ class QMouseEvent; class QPainter; class VerticalMeter : public Meter { + Q_OBJECT + private: MeterType mtype; bool overflow; @@ -27,7 +29,7 @@ class VerticalMeter : public Meter { void drawVU(QPainter& p, int, int, int); - Q_OBJECT + void paintEvent(QPaintEvent*); void resizeEvent(QResizeEvent*); diff --git a/muse2/muse/widgets/view.h b/muse2/muse/widgets/view.h index f8b0c90f..f53c4c72 100644 --- a/muse2/muse/widgets/view.h +++ b/muse2/muse/widgets/view.h @@ -24,12 +24,14 @@ class QResizeEvent; //--------------------------------------------------------- class View : public QWidget { + Q_OBJECT + QPixmap pm; // for double buffering bool pmValid; QPixmap bgPixmap; // background Pixmap QBrush brush; bool _virt; - Q_OBJECT + protected: int xorg; diff --git a/muse2/synti/deicsonze/deicsonzegui.h b/muse2/synti/deicsonze/deicsonzegui.h index 50fb55f6..4c3d5e8e 100644 --- a/muse2/synti/deicsonze/deicsonzegui.h +++ b/muse2/synti/deicsonze/deicsonzegui.h @@ -120,6 +120,8 @@ class QTreePreset:public QTreeWidgetItem { // DeicsOnzeGui //--------------------------------------------------------- class DeicsOnzeGui : public QDialog, public Ui::DeicsOnzeGuiBase, public MessGui { + Q_OBJECT + bool _enabledPreset; QFramePitchEnvelope* pitchEnvelopeGraph; @@ -134,7 +136,7 @@ class DeicsOnzeGui : public QDialog, public Ui::DeicsOnzeGuiBase, public MessGui std::vector<FloatEntry*> _reverbFloatEntryVector; std::vector<CheckBox*> _reverbCheckBoxVector; - Q_OBJECT + QString lastDir; private slots: void readMessage(int); diff --git a/muse2/synti/vam/vamgui.h b/muse2/synti/vam/vamgui.h index 2271c8aa..b5906ae8 100644 --- a/muse2/synti/vam/vamgui.h +++ b/muse2/synti/vam/vamgui.h @@ -38,6 +38,8 @@ class QSignalMapper; //--------------------------------------------------------- class VAMGui : public QWidget, public Ui::VAMGuiBase, public MessGui { + Q_OBJECT + QSignalMapper* map; int ctrlHi; int ctrlLo; @@ -46,7 +48,7 @@ class VAMGui : public QWidget, public Ui::VAMGuiBase, public MessGui { SynthGuiCtrl dctrl[NUM_CONTROLLER]; QString * presetFileName; - Q_OBJECT + void sendControllerChange(int ctrl, int val); void initParameter(); void setParam(int, int); |