diff options
-rw-r--r-- | muse2/muse/arranger/pcanvas.cpp | 24 | ||||
-rw-r--r-- | muse2/muse/functions.cpp | 29 | ||||
-rw-r--r-- | muse2/muse/midiedit/scoreedit.cpp | 15 | ||||
-rw-r--r-- | muse2/muse/part.cpp | 4 | ||||
-rw-r--r-- | muse2/muse/part.h | 4 | ||||
-rw-r--r-- | muse2/muse/song.cpp | 4 | ||||
-rw-r--r-- | muse2/muse/song.h | 3 | ||||
-rw-r--r-- | muse2/muse/undo.cpp | 60 | ||||
-rw-r--r-- | muse2/muse/undo.h | 8 |
9 files changed, 106 insertions, 45 deletions
diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 91c0df5e..fde31c08 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -484,14 +484,23 @@ void PartCanvas::partsChanged() //--------------------------------------------------------- void PartCanvas::updateSelection() - { +{ + Undo operations; + bool changed=false; for (iCItem i = items.begin(); i != items.end(); ++i) { NPart* part = (NPart*)(i->second); - part->part()->setSelected(i->second->isSelected()); + operations.push_back(UndoOp(UndoOp::SelectPart, part->part(), i->second->isSelected(), part->part()->selected())); + if (i->second->isSelected() != part->part()->selected()) + changed=true; } - emit selectionChanged(); - redraw(); + + if (changed) + { + MusEGlobal::song->applyOperationGroup(operations); + emit selectionChanged(); + redraw(); } +} //--------------------------------------------------------- // resizeItem @@ -886,13 +895,14 @@ void PartCanvas::itemPopup(CItem* item, int n, const QPoint& pt) // The loop is a safety net. MusECore::Part* p = part; + Undo operations; if(part->hasClones()) { - p->setSelected(true); + operations.push_back(UndoOp(UndoOp::SelectPart, p, true, p->selected())); for(MusECore::Part* it = p->nextClone(); it!=p; it=it->nextClone()) - it->setSelected(true); + operations.push_back(UndoOp(UndoOp::SelectPart, it, true, it->selected())); - MusEGlobal::song->update(SC_SELECTION); + MusEGlobal::song->applyOperationGroup(operations); } break; diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp index c2941a72..7d5547cb 100644 --- a/muse2/muse/functions.cpp +++ b/muse2/muse/functions.cpp @@ -1228,59 +1228,64 @@ void paste_at(const QString& pt, int pos, int max_distance, bool always_new_part void select_all(const set<const Part*>& parts) { + Undo operations; for (set<const Part*>::iterator part=parts.begin(); part!=parts.end(); part++) for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { const Event& event=ev_it->second; - event.setSelected(true); + operations.push_back(UndoOp(UndoOp::SelectEvent,event, true, event.selected())); } - MusEGlobal::song->update(SC_SELECTION); + MusEGlobal::song->applyOperationGroup(operations); } void select_none(const set<const Part*>& parts) { + Undo operations; for (set<const Part*>::iterator part=parts.begin(); part!=parts.end(); part++) for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { const Event& event=ev_it->second; - event.setSelected(false); + operations.push_back(UndoOp(UndoOp::SelectEvent,event, false, event.selected())); } - MusEGlobal::song->update(SC_SELECTION); + MusEGlobal::song->applyOperationGroup(operations); } void select_invert(const set<const Part*>& parts) { + Undo operations; for (set<const Part*>::iterator part=parts.begin(); part!=parts.end(); part++) for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { const Event& event=ev_it->second; - event.setSelected(!event.selected()); + operations.push_back(UndoOp(UndoOp::SelectEvent,event, !event.selected(), event.selected())); } - MusEGlobal::song->update(SC_SELECTION); + MusEGlobal::song->applyOperationGroup(operations); } void select_in_loop(const set<const Part*>& parts) { - select_none(parts); + select_none(parts); // this will automatically be grouped into one OperationGroup + Undo operations; for (set<const Part*>::iterator part=parts.begin(); part!=parts.end(); part++) for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { const Event& event=ev_it->second; - event.setSelected((event.tick()>=MusEGlobal::song->lpos() && event.endTick()<=MusEGlobal::song->rpos())); + operations.push_back(UndoOp(UndoOp::SelectEvent,event, (event.tick()>=MusEGlobal::song->lpos() && event.endTick()<=MusEGlobal::song->rpos()), event.selected())); } - MusEGlobal::song->update(SC_SELECTION); + MusEGlobal::song->applyOperationGroup(operations); } void select_not_in_loop(const set<const Part*>& parts) { - select_none(parts); + select_none(parts); // this will automatically be grouped into one OperationGroup + Undo operations; for (set<const Part*>::iterator part=parts.begin(); part!=parts.end(); part++) for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { const Event& event=ev_it->second; - event.setSelected(!(event.tick()>=MusEGlobal::song->lpos() && event.endTick()<=MusEGlobal::song->rpos())); + operations.push_back(UndoOp(UndoOp::SelectEvent,event, !(event.tick()>=MusEGlobal::song->lpos() && event.endTick()<=MusEGlobal::song->rpos()), event.selected())); } - MusEGlobal::song->update(SC_SELECTION); + MusEGlobal::song->applyOperationGroup(operations); } diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 1b8daefc..96fcc5a5 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -73,6 +73,7 @@ using namespace std; using MusEGlobal::debugMsg; using MusEGlobal::heavyDebugMsg; +using MusECore::UndoOp; namespace MusEGui { @@ -3927,9 +3928,7 @@ void ScoreCanvas::mouseReleaseEvent (QMouseEvent* event) if (!ctrl) deselect_all(); - clicked_event_ptr->setSelected(!clicked_event_ptr->selected()); - - MusEGlobal::song->update(SC_SELECTION); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::SelectEvent, *clicked_event_ptr, !clicked_event_ptr->selected(), clicked_event_ptr->selected())); } setMouseTracking(false); @@ -4028,9 +4027,7 @@ void ScoreCanvas::mouseMoveEvent (QMouseEvent* event) if (!ctrl) deselect_all(); - clicked_event_ptr->setSelected(true); - - MusEGlobal::song->update(SC_SELECTION); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::SelectEvent, *clicked_event_ptr, true, clicked_event_ptr->selected())); } old_pitch=-1; @@ -4508,9 +4505,7 @@ void ScoreCanvas::deselect_all() for (set<const MusECore::Part*>::iterator part=all_parts.begin(); part!=all_parts.end(); part++) for (MusECore::ciEvent event=(*part)->events().begin(); event!=(*part)->events().end(); event++) - event->second.setSelected(false); - - MusEGlobal::song->update(SC_SELECTION); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::SelectEvent, event->second, false, event->second.selected())); } bool staff_t::cleanup_parts() @@ -4568,7 +4563,7 @@ void staff_t::apply_lasso(QRect rect, set<const MusECore::Event*>& already_proce if (rect.contains(it2->x, it2->y)) if (already_processed.find(it2->source_event)==already_processed.end()) { - it2->source_event->setSelected(!it2->source_event->selected()); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::SelectEvent,*it2->source_event,!it2->source_event->selected(),it2->source_event->selected())); already_processed.insert(it2->source_event); } } diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index 9c3f0e38..e25643c8 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -96,7 +96,7 @@ void Part::rechainClone() // unchainTrackParts //--------------------------------------------------------- -void unchainTrackParts(Track* t, bool decRefCount) +void unchainTrackParts(Track* t) { PartList* pl = t->parts(); for(iPart ip = pl->begin(); ip != pl->end(); ++ip) @@ -107,7 +107,7 @@ void unchainTrackParts(Track* t, bool decRefCount) // chainTrackParts //--------------------------------------------------------- -void chainTrackParts(Track* t, bool incRefCount) +void chainTrackParts(Track* t) { PartList* pl = t->parts(); for(riPart ip = pl->rbegin(); ip != pl->rend(); ++ip) // walk through in opposite direction than we unchained them. diff --git a/muse2/muse/part.h b/muse2/muse/part.h index d128460b..ea19410d 100644 --- a/muse2/muse/part.h +++ b/muse2/muse/part.h @@ -196,8 +196,8 @@ class PartList : public std::multimap<int, Part*, std::less<unsigned> > { }; extern void chainCheckErr(Part* p); -extern void unchainTrackParts(Track* t, bool decRefCount); -extern void chainTrackParts(Track* t, bool incRefCount); +extern void unchainTrackParts(Track* t); +extern void chainTrackParts(Track* t); extern void addPortCtrlEvents(Part* part, bool doClones); extern void addPortCtrlEvents(Event& event, Part* part, bool doClones); extern void removePortCtrlEvents(Part* part, bool doClones); diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 5c755a9d..4e70adf5 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -3224,12 +3224,12 @@ void Song::removeTrack2(Track* track) case Track::DRUM: case Track::NEW_DRUM: removePortCtrlEvents(((MidiTrack*)track)); - unchainTrackParts(track, true); + unchainTrackParts(track); _midis.erase(track); break; case Track::WAVE: - unchainTrackParts(track, true); + unchainTrackParts(track); _waves.erase(track); break; diff --git a/muse2/muse/song.h b/muse2/muse/song.h index 91745c96..95a383cd 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -171,7 +171,8 @@ class Song : public QObject { Song(const char* name = 0); ~Song(); - bool applyOperationGroup(Undo& group, bool doUndo=true); + bool applyOperationGroup(Undo& group, bool doUndo=true); // group may be changed! cleanOperationGroup is called on group! + bool applyOperation(const UndoOp& op, bool doUndo=true); /** this sends emits a signal to each MidiEditor or whoever is interested. * For each part which is 1) opened in this MidiEditor and 2) which is diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp index f49d3990..5dbe1e9e 100644 --- a/muse2/muse/undo.cpp +++ b/muse2/muse/undo.cpp @@ -52,8 +52,8 @@ const char* UndoOp::typeName() { static const char* name[] = { "AddTrack", "DeleteTrack", - "AddPart", "DeletePart", "ModifyPartTick", "ModifyPartLength", "ModifyPartLengthFrames", "ModifyPartName", - "AddEvent", "DeleteEvent", "ModifyEvent", + "AddPart", "DeletePart", "ModifyPartTick", "ModifyPartLength", "ModifyPartLengthFrames", "ModifyPartName", "SelectPart", + "AddEvent", "DeleteEvent", "ModifyEvent", "SelectEvent", "AddTempo", "DeleteTempo", "AddSig", "DeleteSig", "AddKey", "DeleteKey", @@ -305,6 +305,12 @@ void cleanOperationGroup(Undo& group) } } +bool Song::applyOperation(const UndoOp& op, bool doUndo) +{ + Undo operations; + operations.push_back(op); + return applyOperationGroup(operations, doUndo); +} bool Song::applyOperationGroup(Undo& group, bool doUndo) { @@ -353,9 +359,9 @@ void Song::doUndo2() removeTrack2(editable_track); updateFlags |= SC_TRACK_REMOVED; break; - case UndoOp::DeleteTrack: // FINDMICHJETZT FIXME TODO: DeletePart on all parts, only empty tracks may be deleted! this removes the necessarity of unchainTrackParts... + case UndoOp::DeleteTrack: // FINDMICHJETZT FIXME TODO: DeletePart on all parts, only empty tracks may be deleted! this removes the necessarity of un... insertTrack2(editable_track, i->trackno); - chainTrackParts(editable_track, true); + chainTrackParts(editable_track); updateFlags |= SC_TRACK_INSERTED; break; @@ -472,7 +478,7 @@ void Song::doRedo2() switch(i->type) { case UndoOp::AddTrack: insertTrack2(editable_track, i->trackno); - chainTrackParts(editable_track, true); + chainTrackParts(editable_track); updateFlags |= SC_TRACK_INSERTED; break; @@ -613,6 +619,18 @@ UndoOp::UndoOp(UndoType type_, const Part* part_, unsigned old_len_or_tick, unsi old_partlen_or_tick=old_len_or_tick; new_partlen_or_tick=new_len_or_tick; } + +UndoOp::UndoOp(UndoType type_, const Part* part_, bool selected_, bool sel_old_) +{ + assert(type_==SelectPart); + assert(part); + + type=type_; + part = part_; + selected=selected_; + selected_old=sel_old_; +} + UndoOp::UndoOp(UndoType type_, const Event& oev, const Event& nev, const Part* part_, bool doCtrls_, bool doClones_) { @@ -638,6 +656,16 @@ UndoOp::UndoOp(UndoType type_, const Event& nev, const Part* part_, bool doCtrls doCtrls = doCtrls_; doClones = doClones_; } + +UndoOp::UndoOp(UndoType type_, const Event& nev, bool selected_, bool sel_old_) +{ + assert(type_==SelectEvent); + + type=type_; + nEvent = nev; + selected=selected_; + selected_old=sel_old_; +} UndoOp::UndoOp(UndoType type_, Marker* copyMarker_, Marker* realMarker_) @@ -737,8 +765,17 @@ bool Song::doUndo1() for (riUndoOp i = u.rbegin(); i != u.rend(); ++i) { Track* editable_track = const_cast<Track*>(i->track); Track* editable_property_track = const_cast<Track*>(i->_propertyTrack); -// uncomment if needed Part* editable_part = const_cast<Part*>(i->part); + Part* editable_part = const_cast<Part*>(i->part); switch(i->type) { + case UndoOp::SelectPart: + editable_part->setSelected(i->selected_old); + updateFlags |= SC_SELECTION; + break; + case UndoOp::SelectEvent: + i->nEvent.setSelected(i->selected_old); + updateFlags |= SC_SELECTION; + break; + case UndoOp::AddTrack: removeTrack1(editable_track); break; @@ -871,8 +908,17 @@ bool Song::doRedo1() for (iUndoOp i = u.begin(); i != u.end(); ++i) { Track* editable_track = const_cast<Track*>(i->track); Track* editable_property_track = const_cast<Track*>(i->_propertyTrack); -// uncomment if needed Part* editable_part = const_cast<Part*>(i->part); + Part* editable_part = const_cast<Part*>(i->part); switch(i->type) { + case UndoOp::SelectPart: + editable_part->setSelected(i->selected); + updateFlags |= SC_SELECTION; + break; + case UndoOp::SelectEvent: + i->nEvent.setSelected(i->selected); + updateFlags |= SC_SELECTION; + break; + case UndoOp::AddTrack: insertTrack1(editable_track, i->trackno); diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h index 9997d4cb..6c372624 100644 --- a/muse2/muse/undo.h +++ b/muse2/muse/undo.h @@ -46,8 +46,8 @@ extern std::list<QString> temporaryWavFiles; //!< Used for storing all tmp-files struct UndoOp { enum UndoType { AddTrack, DeleteTrack, - AddPart, DeletePart, ModifyPartTick, ModifyPartLength, ModifyPartLengthFrames, /* FINDMICH FIXME frames are to be deprecated */ ModifyPartName, - AddEvent, DeleteEvent, ModifyEvent, + AddPart, DeletePart, ModifyPartTick, ModifyPartLength, ModifyPartLengthFrames, /* FINDMICH FIXME frames are to be deprecated */ ModifyPartName, SelectPart, + AddEvent, DeleteEvent, ModifyEvent, SelectEvent, AddTempo, DeleteTempo, AddSig, DeleteSig, AddKey, DeleteKey, @@ -102,6 +102,8 @@ struct UndoOp { char* _newName; Event oEvent; Event nEvent; + bool selected; + bool selected_old; bool doCtrls; bool doClones; @@ -113,8 +115,10 @@ struct UndoOp { UndoOp(UndoType type, int n, const Track* track); UndoOp(UndoType type, const Part* part, unsigned old_len_or_tick=-1, unsigned new_len_or_tick=-1, bool doCtrls=false, bool doClones=false); // FIXME these bools are UNUSED!!. XTICKS! UndoOp(UndoType type, const Part* part, const char* old_name, const char* new_name); + UndoOp(UndoType type, const Part* part, bool selected, bool selected_old); UndoOp(UndoType type, const Event& oev, const Event& nev, const Part* part, bool doCtrls, bool doClones); UndoOp(UndoType type, const Event& nev, const Part* part, bool doCtrls, bool doClones); + UndoOp(UndoType type, const Event& nev, bool selected, bool selected_old); UndoOp(UndoType type, const char* changedFile, const char* changeData, int startframe, int endframe); UndoOp(UndoType type, Marker* copyMarker, Marker* realMarker); UndoOp(UndoType type, const Track* track, const char* old_name, const char* new_name); |