From 4933ccfe7552dc5dbb2921f6583bbeb92dd144b4 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Fri, 16 Aug 2013 23:04:08 +0200 Subject: Parts have their own, non-shared EventList (still WIP!) removed refcounting in Eventlist Part::events() is now a const EventList& chaining parts now a Part:: member function made Track::events, ::mpevents public instead of using an insane reference-accessor TODO: need a grouping indicator of clones (like the eventlist pointer was used for) --- muse2/muse/part.h | 54 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) (limited to 'muse2/muse/part.h') diff --git a/muse2/muse/part.h b/muse2/muse/part.h index 357ec1db..a9241807 100644 --- a/muse2/muse/part.h +++ b/muse2/muse/part.h @@ -60,12 +60,8 @@ typedef CloneList::iterator iClone; class Part : public PosLen { public: enum HiddenEventsType { NoEventsHidden = 0, LeftEventsHidden, RightEventsHidden }; - - // @@@@@@@@@@@ IMPORTANT @@@@@@@@@@@@ - // @@ when adding member variables @@ - // @@ here, don't forget to update @@ - // @@ the copy-constructor! @@ - // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + static Part* readFromXml(Xml&, Track*, bool doClone = false, bool toTrack = true); private: static int snGen; @@ -78,22 +74,23 @@ class Part : public PosLen { protected: Track* _track; - EventList* _events; + EventList _events; Part* _prevClone; Part* _nextClone; + Part* _backupClone; // when a part gets removed, it's still there; and for undo-ing the remove, it must know about where it was clone-chained to. int _hiddenEvents; // Combination of HiddenEventsType. - + public: Part(Track*); - Part(Track*, EventList*); - Part(const Part& p); virtual ~Part(); + virtual Part* duplicate() = 0; + virtual Part* duplicateEmpty() = 0; + virtual Part* createNewClone() = 0; + int sn() { return _sn; } void setSn(int n) { _sn = n; } int newSn() { return snGen++; } - virtual Part* clone() const = 0; - const QString& name() const { return _name; } void setName(const QString& s) { _name = s; } bool selected() const { return _selected; } @@ -102,15 +99,19 @@ class Part : public PosLen { void setMute(bool b) { _mute = b; } Track* track() const { return _track; } void setTrack(Track*t) { _track = t; } - EventList* events() const { return _events; } - const EventList* cevents() const { return _events; } + const EventList& events() const { return _events; } + EventList& nonconst_events() { return _events; } int colorIndex() const { return _colorIndex; } void setColorIndex(int idx) { _colorIndex = idx; } + bool hasClones() { return _prevClone!=this || _nextClone!=this; } + int nClones(); Part* prevClone() { return _prevClone; } Part* nextClone() { return _nextClone; } - void setPrevClone(Part* p) { _prevClone = p; } - void setNextClone(Part* p) { _nextClone = p; } + + void unchainClone(); + void chainClone(Part* p); // *this is made a sibling of p! p is not touched (except for its clone-chain), whereas this->events will get altered + void rechainClone(); // re-chains the part to the same clone chain it was unchained before // Returns combination of HiddenEventsType enum. virtual int hasHiddenEvents() = 0; @@ -118,7 +119,7 @@ class Part : public PosLen { // call this after hasHiddenEvents(). int cachedHasHiddenEvents() const { return _hiddenEvents; } - iEvent addEvent(Event& p); + iEvent addEvent(Event& p); // DEPRECATED. requires the part to be NOT a clone. FIXME remove! virtual void write(int, Xml&, bool isCopy = false, bool forceWavePaths = false) const; @@ -134,10 +135,12 @@ class MidiPart : public Part { public: MidiPart(MidiTrack* t) : Part((Track*)t) {} - MidiPart(MidiTrack* t, EventList* ev) : Part((Track*)t, ev) {} - MidiPart(const MidiPart& p); virtual ~MidiPart() {} - virtual MidiPart* clone() const; + virtual MidiPart* duplicate(); + virtual MidiPart* duplicateEmpty(); + virtual MidiPart* createNewClone(); + + MidiTrack* track() const { return (MidiTrack*)Part::track(); } // Returns combination of HiddenEventsType enum. int hasHiddenEvents(); @@ -154,13 +157,15 @@ class WavePart : public Part { // p3.3.31 AudioConvertMap _converters; - + public: WavePart(WaveTrack* t); WavePart(WaveTrack* t, EventList* ev); - WavePart(const WavePart& p); virtual ~WavePart() {} - virtual WavePart* clone() const; + virtual WavePart* duplicate(); + virtual WavePart* duplicateEmpty(); + virtual WavePart* createNewClone(); + WaveTrack* track() const { return (WaveTrack*)Part::track(); } // Returns combination of HiddenEventsType enum. int hasHiddenEvents(); @@ -191,10 +196,8 @@ class PartList : public std::multimap > { } }; -extern void chainClone(Part* p); extern void chainClone(Part* p1, Part* p2); extern void unchainClone(Part* p); -extern void replaceClone(Part* p1, Part* p2); extern void chainCheckErr(Part* p); extern void unchainTrackParts(Track* t, bool decRefCount); extern void chainTrackParts(Track* t, bool incRefCount); @@ -202,7 +205,6 @@ extern void addPortCtrlEvents(Part* part, bool doClones); extern void addPortCtrlEvents(Event& event, Part* part, bool doClones); extern void removePortCtrlEvents(Part* part, bool doClones); extern void removePortCtrlEvents(Event& event, Part* part, bool doClones); -extern Part* readXmlPart(Xml&, Track*, bool doClone = false, bool toTrack = true); } // namespace MusECore -- cgit v1.2.3 From 013294f58a6433671da3b34775de5a3a7ea91464 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Mon, 19 Aug 2013 22:10:22 +0200 Subject: some const-correctness. Part interface overhaul. various fixes. --- muse2/muse/arranger/pcanvas.cpp | 6 +- muse2/muse/event.cpp | 2 +- muse2/muse/event.h | 3 +- muse2/muse/eventbase.h | 2 +- muse2/muse/eventlist.cpp | 13 +- muse2/muse/exportmidi.cpp | 2 +- muse2/muse/functions.cpp | 269 ++++++++++++++++++------------------- muse2/muse/functions.h | 74 +++++----- muse2/muse/helper.cpp | 6 +- muse2/muse/helper.h | 2 +- muse2/muse/importmidi.cpp | 14 +- muse2/muse/midiedit/dcanvas.cpp | 6 +- muse2/muse/midiedit/prcanvas.cpp | 6 +- muse2/muse/midiedit/scoreedit.cpp | 12 +- muse2/muse/midiedit/scoreedit.h | 2 +- muse2/muse/midievent.cpp | 2 +- muse2/muse/midievent.h | 2 +- muse2/muse/miditransform.cpp | 46 +++---- muse2/muse/miditransform.h | 4 +- muse2/muse/part.cpp | 151 +++++---------------- muse2/muse/part.h | 41 +++--- muse2/muse/song.cpp | 21 ++- muse2/muse/steprec.cpp | 10 +- muse2/muse/structure.cpp | 12 +- muse2/muse/track.cpp | 4 +- muse2/muse/track.h | 1 - muse2/muse/undo.cpp | 18 +-- muse2/muse/undo.h | 22 +-- muse2/muse/waveedit/wavecanvas.cpp | 8 +- muse2/muse/waveevent.cpp | 4 +- muse2/muse/waveevent.h | 2 +- muse2/muse/wavetrack.cpp | 4 +- 32 files changed, 341 insertions(+), 430 deletions(-) (limited to 'muse2/muse/part.h') diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index 860a33ac..91c0df5e 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -2321,7 +2321,7 @@ void PartCanvas::copy_in_range(MusECore::PartList* pl_) MusECore::Part* p1; MusECore::Part* p2; - track->splitPart(part, lpos, p1, p2); + part->splitPart(lpos, p1, p2); part=p2; } @@ -2331,7 +2331,7 @@ void PartCanvas::copy_in_range(MusECore::PartList* pl_) MusECore::Part* p1; MusECore::Part* p2; - track->splitPart(part, rpos, p1, p2); + part->splitPart(rpos, p1, p2); part=p1; } @@ -2427,7 +2427,7 @@ MusECore::Undo PartCanvas::pasteAt(const QString& pt, MusECore::Track* track, un if (tag == "part") { // Read the part. MusECore::Part* p = 0; - p = Part::readFromXml(xml, track, clone, toTrack); + p = MusECore::Part::readFromXml(xml, track, clone, toTrack); // If it could not be created... if(!p) diff --git a/muse2/muse/event.cpp b/muse2/muse/event.cpp index 73611448..065a49cf 100644 --- a/muse2/muse/event.cpp +++ b/muse2/muse/event.cpp @@ -203,7 +203,7 @@ void Event::read(Xml& xml) void Event::write(int a, Xml& xml, const Pos& o, bool forceWavePaths) const { ev->write(a, xml, o, forceWavePaths); } void Event::dump(int n) const { ev->dump(n); } -Event Event::mid(unsigned a, unsigned b) { return Event(ev->mid(a, b)); } +Event Event::mid(unsigned a, unsigned b) const { return Event(ev->mid(a, b)); } bool Event::isNote() const { return ev->isNote(); } bool Event::isNoteOff() const { return ev->isNoteOff(); } diff --git a/muse2/muse/event.h b/muse2/muse/event.h index 78ac7f93..ed1ddb87 100644 --- a/muse2/muse/event.h +++ b/muse2/muse/event.h @@ -74,7 +74,7 @@ class Event { void write(int a, Xml& xml, const Pos& offset, bool ForceWavePaths = false) const; void dump(int n = 0) const; Event clone() const; - Event mid(unsigned a, unsigned b); + Event mid(unsigned a, unsigned b) const; bool isNote() const; bool isNoteOff() const; @@ -135,6 +135,7 @@ class EventList : public EL { void deselect(); public: + ciEvent find(const Event&) const; iEvent find(const Event&); iEvent add(Event& event); void move(Event& event, unsigned tick); diff --git a/muse2/muse/eventbase.h b/muse2/muse/eventbase.h index 9e7b2df8..adf7da97 100644 --- a/muse2/muse/eventbase.h +++ b/muse2/muse/eventbase.h @@ -60,7 +60,7 @@ class EventBase : public PosLen { virtual void read(Xml&) = 0; virtual void write(int, Xml&, const Pos& offset, bool forcePath = false) const = 0; virtual void dump(int n = 0) const; - virtual EventBase* mid(unsigned, unsigned) = 0; + virtual EventBase* mid(unsigned, unsigned) const = 0; friend class Event; virtual bool isNote() const { return false; } diff --git a/muse2/muse/eventlist.cpp b/muse2/muse/eventlist.cpp index 50ba2652..f499fd2d 100644 --- a/muse2/muse/eventlist.cpp +++ b/muse2/muse/eventlist.cpp @@ -129,11 +129,22 @@ void EventList::move(Event& event, unsigned tick) //--------------------------------------------------------- iEvent EventList::find(const Event& event) +{ + std::pair range = equal_range(event.type() == Wave ? event.frame() : event.tick()); + + for (iEvent i = range.first; i != range.second; ++i) { + if (i->second == event) + return i; + } + return end(); +} + +ciEvent EventList::find(const Event& event) const { EventRange range = equal_range(event.type() == Wave ? event.frame() : event.tick()); - for (iEvent i = range.first; i != range.second; ++i) { + for (ciEvent i = range.first; i != range.second; ++i) { if (i->second == event) return i; } diff --git a/muse2/muse/exportmidi.cpp b/muse2/muse/exportmidi.cpp index aa9b83cc..34ac8983 100644 --- a/muse2/muse/exportmidi.cpp +++ b/muse2/muse/exportmidi.cpp @@ -490,7 +490,7 @@ void MusE::exportMidi() { MusECore::EventList* el = instr->midiInit(); if(!el->empty()) - MusECore::addEventList(el, l, NULL, NULL, port, channel); // No track or part passed for init sequences + MusECore::addEventList(*el, l, NULL, NULL, port, channel); // No track or part passed for init sequences } //-------------------------- diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp index 8b978843..c2941a72 100644 --- a/muse2/muse/functions.cpp +++ b/muse2/muse/functions.cpp @@ -71,9 +71,9 @@ bool read_eventlist_and_part(Xml& xml, EventList* el, int* part_id); -set partlist_to_set(PartList* pl) +set partlist_to_set(PartList* pl) { - set result; + set result; for (PartList::iterator it=pl->begin(); it!=pl->end(); it++) result.insert(it->second); @@ -81,16 +81,16 @@ set partlist_to_set(PartList* pl) return result; } -set part_to_set(Part* p) +set part_to_set(const Part* p) { - set result; + set result; result.insert(p); return result; } -set get_all_parts() +set get_all_parts() { - set result; + set result; TrackList* tracks=MusEGlobal::song->tracks(); for (TrackList::const_iterator t_it=tracks->begin(); t_it!=tracks->end(); t_it++) @@ -103,9 +103,9 @@ set get_all_parts() return result; } -set get_all_selected_parts() +set get_all_selected_parts() { - set result; + set result; TrackList* tracks=MusEGlobal::song->tracks(); for (TrackList::const_iterator t_it=tracks->begin(); t_it!=tracks->end(); t_it++) @@ -137,14 +137,14 @@ bool is_relevant(const Event& event, const Part* part, int range) } -map get_events(const set& parts, int range) +map get_events(const set& parts, int range) { - map events; + map events; - for (set::iterator part=parts.begin(); part!=parts.end(); part++) + for (set::iterator part=parts.begin(); part!=parts.end(); part++) for (ciEvent event=(*part)->events().begin(); event!=(*part)->events().end(); event++) if (is_relevant(event->second, *part, range)) - events.insert(pair(&event->second, *part)); + events.insert(pair(&event->second, *part)); return events; } @@ -152,7 +152,7 @@ map get_events(const set& parts, int range) -bool modify_notelen(const set& parts) +bool modify_notelen(const set& parts) { if (!MusEGui::gatetime_dialog->exec()) return false; @@ -162,7 +162,7 @@ bool modify_notelen(const set& parts) return true; } -bool modify_velocity(const set& parts) +bool modify_velocity(const set& parts) { if (!MusEGui::velocity_dialog->exec()) return false; @@ -172,7 +172,7 @@ bool modify_velocity(const set& parts) return true; } -bool quantize_notes(const set& parts) +bool quantize_notes(const set& parts) { if (!MusEGui::quantize_dialog->exec()) return false; @@ -185,7 +185,7 @@ bool quantize_notes(const set& parts) return true; } -bool erase_notes(const set& parts) +bool erase_notes(const set& parts) { if (!MusEGui::erase_dialog->exec()) return false; @@ -196,7 +196,7 @@ bool erase_notes(const set& parts) return true; } -bool delete_overlaps(const set& parts) +bool delete_overlaps(const set& parts) { if (!MusEGui::del_overlaps_dialog->exec()) return false; @@ -206,7 +206,7 @@ bool delete_overlaps(const set& parts) return true; } -bool set_notelen(const set& parts) +bool set_notelen(const set& parts) { if (!MusEGui::set_notelen_dialog->exec()) return false; @@ -216,7 +216,7 @@ bool set_notelen(const set& parts) return true; } -bool move_notes(const set& parts) +bool move_notes(const set& parts) { if (!MusEGui::move_notes_dialog->exec()) return false; @@ -226,7 +226,7 @@ bool move_notes(const set& parts) return true; } -bool transpose_notes(const set& parts) +bool transpose_notes(const set& parts) { if (!MusEGui::transpose_dialog->exec()) return false; @@ -236,7 +236,7 @@ bool transpose_notes(const set& parts) return true; } -bool crescendo(const set& parts) +bool crescendo(const set& parts) { if (MusEGlobal::song->rpos() <= MusEGlobal::song->lpos()) { @@ -252,7 +252,7 @@ bool crescendo(const set& parts) return true; } -bool legato(const set& parts) +bool legato(const set& parts) { if (!MusEGui::legato_dialog->exec()) return false; @@ -269,7 +269,7 @@ bool modify_notelen() if (!MusEGui::gatetime_dialog->exec()) return false; - set parts; + set parts; if (MusEGui::gatetime_dialog->range & FUNCTION_RANGE_ONLY_SELECTED) parts=get_all_selected_parts(); else @@ -285,7 +285,7 @@ bool modify_velocity() if (!MusEGui::velocity_dialog->exec()) return false; - set parts; + set parts; if (MusEGui::velocity_dialog->range & FUNCTION_RANGE_ONLY_SELECTED) parts=get_all_selected_parts(); else @@ -301,7 +301,7 @@ bool quantize_notes() if (!MusEGui::quantize_dialog->exec()) return false; - set parts; + set parts; if (MusEGui::quantize_dialog->range & FUNCTION_RANGE_ONLY_SELECTED) parts=get_all_selected_parts(); else @@ -320,7 +320,7 @@ bool erase_notes() if (!MusEGui::erase_dialog->exec()) return false; - set parts; + set parts; if (MusEGui::erase_dialog->range & FUNCTION_RANGE_ONLY_SELECTED) parts=get_all_selected_parts(); else @@ -337,7 +337,7 @@ bool delete_overlaps() if (!MusEGui::del_overlaps_dialog->exec()) return false; - set parts; + set parts; if (MusEGui::del_overlaps_dialog->range & FUNCTION_RANGE_ONLY_SELECTED) parts=get_all_selected_parts(); else @@ -353,7 +353,7 @@ bool set_notelen() if (!MusEGui::set_notelen_dialog->exec()) return false; - set parts; + set parts; if (MusEGui::set_notelen_dialog->range & FUNCTION_RANGE_ONLY_SELECTED) parts=get_all_selected_parts(); else @@ -369,7 +369,7 @@ bool move_notes() if (!MusEGui::move_notes_dialog->exec()) return false; - set parts; + set parts; if (MusEGui::move_notes_dialog->range & FUNCTION_RANGE_ONLY_SELECTED) parts=get_all_selected_parts(); else @@ -385,7 +385,7 @@ bool transpose_notes() if (!MusEGui::transpose_dialog->exec()) return false; - set parts; + set parts; if (MusEGui::transpose_dialog->range & FUNCTION_RANGE_ONLY_SELECTED) parts=get_all_selected_parts(); else @@ -407,7 +407,7 @@ bool crescendo() if (!MusEGui::crescendo_dialog->exec()) return false; - set parts; + set parts; if (MusEGui::crescendo_dialog->range & FUNCTION_RANGE_ONLY_SELECTED) parts=get_all_selected_parts(); else @@ -423,7 +423,7 @@ bool legato() if (!MusEGui::legato_dialog->exec()) return false; - set parts; + set parts; if (MusEGui::legato_dialog->range & FUNCTION_RANGE_ONLY_SELECTED) parts=get_all_selected_parts(); else @@ -439,17 +439,17 @@ bool legato() -bool modify_velocity(const set& parts, int range, int rate, int offset) +bool modify_velocity(const set& parts, int range, int rate, int offset) { - map events = get_events(parts, range); + map events = get_events(parts, range); Undo operations; if ( (!events.empty()) && ((rate!=100) || (offset!=0)) ) { - for (map::iterator it=events.begin(); it!=events.end(); it++) + for (map::iterator it=events.begin(); it!=events.end(); it++) { - Event& event=*(it->first); - Part* part=it->second; + const Event& event=*(it->first); + const Part* part=it->second; int velo = event.velo(); @@ -475,17 +475,17 @@ bool modify_velocity(const set& parts, int range, int rate, int offset) return false; } -bool modify_off_velocity(const set& parts, int range, int rate, int offset) +bool modify_off_velocity(const set& parts, int range, int rate, int offset) { - map events = get_events(parts, range); + map events = get_events(parts, range); Undo operations; if ( (!events.empty()) && ((rate!=100) || (offset!=0)) ) { - for (map::iterator it=events.begin(); it!=events.end(); it++) + for (map::iterator it=events.begin(); it!=events.end(); it++) { - Event& event=*(it->first); - Part* part=it->second; + const Event& event=*(it->first); + const Part* part=it->second; int velo = event.veloOff(); @@ -511,18 +511,18 @@ bool modify_off_velocity(const set& parts, int range, int rate, int offse return false; } -bool modify_notelen(const set& parts, int range, int rate, int offset) +bool modify_notelen(const set& parts, int range, int rate, int offset) { - map events = get_events(parts, range); + map events = get_events(parts, range); Undo operations; - map partlen; + map partlen; if ( (!events.empty()) && ((rate!=100) || (offset!=0)) ) { - for (map::iterator it=events.begin(); it!=events.end(); it++) + for (map::iterator it=events.begin(); it!=events.end(); it++) { - Event& event=*(it->first); - Part* part=it->second; + const Event& event=*(it->first); + const Part* part=it->second; unsigned int len = event.lenTick(); //prevent compiler warning: comparison singed/unsigned @@ -543,7 +543,7 @@ bool modify_notelen(const set& parts, int range, int rate, int offset) } } - for (map::iterator it=partlen.begin(); it!=partlen.end(); it++) + for (map::iterator it=partlen.begin(); it!=partlen.end(); it++) schedule_resize_all_same_len_clone_parts(it->first, it->second, operations); return MusEGlobal::song->applyOperationGroup(operations); @@ -552,7 +552,7 @@ bool modify_notelen(const set& parts, int range, int rate, int offset) return false; } -bool set_notelen(const set& parts, int range, int len) +bool set_notelen(const set& parts, int range, int len) { return modify_notelen(parts, range, 0, len); } @@ -579,17 +579,17 @@ unsigned quantize_tick(unsigned tick, unsigned raster, int swing) return tick_dest1; } -bool quantize_notes(const set& parts, int range, int raster, bool quant_len, int strength, int swing, int threshold) +bool quantize_notes(const set& parts, int range, int raster, bool quant_len, int strength, int swing, int threshold) { - map events = get_events(parts, range); + map events = get_events(parts, range); Undo operations; if (!events.empty()) { - for (map::iterator it=events.begin(); it!=events.end(); it++) + for (map::iterator it=events.begin(); it!=events.end(); it++) { - Event& event=*(it->first); - Part* part=it->second; + const Event& event=*(it->first); + const Part* part=it->second; unsigned begin_tick = event.tick() + part->tick(); int begin_diff = quantize_tick(begin_tick, raster, swing) - begin_tick; @@ -625,17 +625,17 @@ bool quantize_notes(const set& parts, int range, int raster, bool quant_l return false; } -bool erase_notes(const set& parts, int range, int velo_threshold, bool velo_thres_used, int len_threshold, bool len_thres_used) +bool erase_notes(const set& parts, int range, int velo_threshold, bool velo_thres_used, int len_threshold, bool len_thres_used) { - map events = get_events(parts, range); + map events = get_events(parts, range); Undo operations; if (!events.empty()) { - for (map::iterator it=events.begin(); it!=events.end(); it++) + for (map::iterator it=events.begin(); it!=events.end(); it++) { - Event& event=*(it->first); - Part* part=it->second; + const Event& event=*(it->first); + const Part* part=it->second; if ( (!velo_thres_used && !len_thres_used) || (velo_thres_used && event.velo() < velo_threshold) || @@ -649,17 +649,17 @@ bool erase_notes(const set& parts, int range, int velo_threshold, bool ve return false; } -bool transpose_notes(const set& parts, int range, signed int halftonesteps) +bool transpose_notes(const set& parts, int range, signed int halftonesteps) { - map events = get_events(parts, range); + map events = get_events(parts, range); Undo operations; if ( (!events.empty()) && (halftonesteps!=0) ) { - for (map::iterator it=events.begin(); it!=events.end(); it++) + for (map::iterator it=events.begin(); it!=events.end(); it++) { - Event& event=*(it->first); - Part* part=it->second; + const Event& event=*(it->first); + const Part* part=it->second; Event newEvent = event.clone(); int pitch = event.pitch()+halftonesteps; @@ -675,9 +675,9 @@ bool transpose_notes(const set& parts, int range, signed int halftonestep return false; } -bool crescendo(const set& parts, int range, int start_val, int end_val, bool absolute) +bool crescendo(const set& parts, int range, int start_val, int end_val, bool absolute) { - map events = get_events(parts, range); + map events = get_events(parts, range); Undo operations; int from=MusEGlobal::song->lpos(); @@ -685,10 +685,10 @@ bool crescendo(const set& parts, int range, int start_val, int end_val, b if ( (!events.empty()) && (to>from) ) { - for (map::iterator it=events.begin(); it!=events.end(); it++) + for (map::iterator it=events.begin(); it!=events.end(); it++) { - Event& event=*(it->first); - Part* part=it->second; + const Event& event=*(it->first); + const Part* part=it->second; unsigned tick = event.tick() + part->tick(); float curr_val= (float)start_val + (float)(end_val-start_val) * (tick-from) / (to-from); @@ -713,18 +713,18 @@ bool crescendo(const set& parts, int range, int start_val, int end_val, b return false; } -bool move_notes(const set& parts, int range, signed int ticks) +bool move_notes(const set& parts, int range, signed int ticks) { - map events = get_events(parts, range); + map events = get_events(parts, range); Undo operations; - map partlen; + map partlen; if ( (!events.empty()) && (ticks!=0) ) { - for (map::iterator it=events.begin(); it!=events.end(); it++) + for (map::iterator it=events.begin(); it!=events.end(); it++) { - Event& event=*(it->first); - Part* part=it->second; + const Event& event=*(it->first); + const Part* part=it->second; bool del=false; Event newEvent = event.clone(); @@ -752,7 +752,7 @@ bool move_notes(const set& parts, int range, signed int ticks) operations.push_back(UndoOp(UndoOp::DeleteEvent, event, part, false, false)); } - for (map::iterator it=partlen.begin(); it!=partlen.end(); it++) + for (map::iterator it=partlen.begin(); it!=partlen.end(); it++) schedule_resize_all_same_len_clone_parts(it->first, it->second, operations); return MusEGlobal::song->applyOperationGroup(operations); @@ -762,27 +762,27 @@ bool move_notes(const set& parts, int range, signed int ticks) } -bool delete_overlaps(const set& parts, int range) +bool delete_overlaps(const set& parts, int range) { - map events = get_events(parts, range); + map events = get_events(parts, range); Undo operations; - set deleted_events; + set deleted_events; if (!events.empty()) { - for (map::iterator it1=events.begin(); it1!=events.end(); it1++) + for (map::iterator it1=events.begin(); it1!=events.end(); it1++) { - Event& event1=*(it1->first); - Part* part1=it1->second; + const Event& event1=*(it1->first); + const Part* part1=it1->second; // we may NOT optimize by letting it2 start at (it1 +1); this optimisation // is only allowed when events was sorted by time. it is, however, sorted // randomly by pointer. - for (map::iterator it2=events.begin(); it2!=events.end(); it2++) + for (map::iterator it2=events.begin(); it2!=events.end(); it2++) { - Event& event2=*(it2->first); - Part* part2=it2->second; + const Event& event2=*(it2->first); + const Part* part2=it2->second; if ( (part1->isCloneOf(part2)) && // part1 and part2 are the same or are duplicates (&event1 != &event2) && // and event1 and event2 aren't the same @@ -817,28 +817,28 @@ bool delete_overlaps(const set& parts, int range) return false; } -bool legato(const set& parts, int range, int min_len, bool dont_shorten) +bool legato(const set& parts, int range, int min_len, bool dont_shorten) { - map events = get_events(parts, range); + map events = get_events(parts, range); Undo operations; if (min_len<=0) min_len=1; if (!events.empty()) { - for (map::iterator it1=events.begin(); it1!=events.end(); it1++) + for (map::iterator it1=events.begin(); it1!=events.end(); it1++) { - Event& event1=*(it1->first); - Part* part1=it1->second; + const Event& event1=*(it1->first); + const Part* part1=it1->second; unsigned len=INT_MAX; // we may NOT optimize by letting it2 start at (it1 +1); this optimisation // is only allowed when events was sorted by time. it is, however, sorted // randomly by pointer. - for (map::iterator it2=events.begin(); it2!=events.end(); it2++) + for (map::iterator it2=events.begin(); it2!=events.end(); it2++) { - Event& event2=*(it2->first); - Part* part2=it2->second; + const Event& event2=*(it2->first); + const Part* part2=it2->second; bool relevant = (event2.tick() >= event1.tick() + min_len); if (dont_shorten) @@ -869,7 +869,7 @@ bool legato(const set& parts, int range, int min_len, bool dont_shorten) -void copy_notes(const set& parts, int range) +void copy_notes(const set& parts, int range) { QMimeData* drag = selected_events_to_mime(parts,range); @@ -951,11 +951,11 @@ void paste_notes(int max_distance, bool always_new_part, bool never_new_part, Pa } // if nothing is selected/relevant, this function returns NULL -QMimeData* selected_events_to_mime(const set& parts, int range) +QMimeData* selected_events_to_mime(const set& parts, int range) { unsigned start_tick = INT_MAX; //will be the tick of the first event or INT_MAX if no events are there - for (set::iterator part=parts.begin(); part!=parts.end(); part++) + for (set::iterator part=parts.begin(); part!=parts.end(); part++) for (ciEvent ev=(*part)->events().begin(); ev!=(*part)->events().end(); ev++) if (is_relevant(ev->second, *part, range)) if (ev->second.tick() < start_tick) @@ -978,7 +978,7 @@ QMimeData* selected_events_to_mime(const set& parts, int range) Xml xml(tmp); int level = 0; - for (set::iterator part=parts.begin(); part!=parts.end(); part++) + for (set::iterator part=parts.begin(); part!=parts.end(); part++) { xml.tag(level++, "eventlist part_id=\"%d\"", (*part)->sn()); for (ciEvent ev=(*part)->events().begin(); ev!=(*part)->events().end(); ev++) @@ -993,7 +993,7 @@ QMimeData* selected_events_to_mime(const set& parts, int range) } // if nothing is selected/relevant, this function returns NULL -QMimeData* parts_to_mime(const set& parts) +QMimeData* parts_to_mime(const set& parts) { //--------------------------------------------------- @@ -1012,7 +1012,7 @@ QMimeData* parts_to_mime(const set& parts) bool midi=false; bool wave=false; - for (set::iterator part=parts.begin(); part!=parts.end(); part++) + for (set::iterator part=parts.begin(); part!=parts.end(); part++) { if ((*part)->track()->type() == MusECore::Track::MIDI) midi=true; @@ -1226,58 +1226,58 @@ void paste_at(const QString& pt, int pos, int max_distance, bool always_new_part MusEGlobal::song->update(SC_SELECTION); } -void select_all(const std::set& parts) +void select_all(const set& parts) { - for (set::iterator part=parts.begin(); part!=parts.end(); part++) + for (set::iterator part=parts.begin(); part!=parts.end(); part++) for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { - Event& event=ev_it->second; + const Event& event=ev_it->second; event.setSelected(true); } MusEGlobal::song->update(SC_SELECTION); } -void select_none(const std::set& parts) +void select_none(const set& parts) { - for (set::iterator part=parts.begin(); part!=parts.end(); part++) + for (set::iterator part=parts.begin(); part!=parts.end(); part++) for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { - Event& event=ev_it->second; + const Event& event=ev_it->second; event.setSelected(false); } MusEGlobal::song->update(SC_SELECTION); } -void select_invert(const std::set& parts) +void select_invert(const set& parts) { - for (set::iterator part=parts.begin(); part!=parts.end(); part++) + for (set::iterator part=parts.begin(); part!=parts.end(); part++) for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { - Event& event=ev_it->second; + const Event& event=ev_it->second; event.setSelected(!event.selected()); } MusEGlobal::song->update(SC_SELECTION); } -void select_in_loop(const std::set& parts) +void select_in_loop(const set& parts) { select_none(parts); - for (set::iterator part=parts.begin(); part!=parts.end(); part++) + for (set::iterator part=parts.begin(); part!=parts.end(); part++) for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { - Event& event=ev_it->second; + const Event& event=ev_it->second; event.setSelected((event.tick()>=MusEGlobal::song->lpos() && event.endTick()<=MusEGlobal::song->rpos())); } MusEGlobal::song->update(SC_SELECTION); } -void select_not_in_loop(const std::set& parts) +void select_not_in_loop(const set& parts) { select_none(parts); - for (set::iterator part=parts.begin(); part!=parts.end(); part++) - for (diEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) + for (set::iterator part=parts.begin(); part!=parts.end(); part++) + for (ciEvent ev_it=(*part)->events().begin(); ev_it!=(*part)->events().end(); ev_it++) { - Event& event=ev_it->second; + const Event& event=ev_it->second; event.setSelected(!(event.tick()>=MusEGlobal::song->lpos() && event.endTick()<=MusEGlobal::song->rpos())); } MusEGlobal::song->update(SC_SELECTION); @@ -1314,7 +1314,7 @@ void shrink_parts(int raster) } -void schedule_resize_all_same_len_clone_parts(Part* part, unsigned new_len, Undo& operations) +void schedule_resize_all_same_len_clone_parts(const Part* part, unsigned new_len, Undo& operations) { QSet already_done; @@ -1325,7 +1325,7 @@ void schedule_resize_all_same_len_clone_parts(Part* part, unsigned new_len, Undo unsigned old_len= part->type() == Pos::FRAMES ? part->lenFrame() : part->lenTick(); if (old_len!=new_len) { - Part* part_it=part; + const Part* part_it=part; do { if (part->type() == Pos::FRAMES) @@ -1376,7 +1376,7 @@ void expand_parts(int raster) void clean_parts() { Undo operations; - set already_processed; + set already_processed; TrackList* tracks = MusEGlobal::song->tracks(); for (iTrack track = tracks->begin(); track != tracks->end(); track++) @@ -1388,7 +1388,7 @@ void clean_parts() // multiple clones) unsigned len=0; - Part* part_it=part->second; + const Part* part_it=part->second; do { if (part_it->lenTick() > len) @@ -1418,31 +1418,31 @@ void clean_parts() bool merge_selected_parts() { - set temp = get_all_selected_parts(); + set temp = get_all_selected_parts(); return merge_parts(temp); } -bool merge_parts(const set& parts) +bool merge_parts(const set& parts) { - set tracks; - for (set::iterator it=parts.begin(); it!=parts.end(); it++) + set tracks; + for (set::iterator it=parts.begin(); it!=parts.end(); it++) tracks.insert( (*it)->track() ); Undo operations; // process tracks separately - for (set::iterator t_it=tracks.begin(); t_it!=tracks.end(); t_it++) + for (set::iterator t_it=tracks.begin(); t_it!=tracks.end(); t_it++) { - Track* track=*t_it; + const Track* track=*t_it; unsigned begin=INT_MAX, end=0; - Part* first_part=NULL; + const Part* first_part=NULL; // find begin of the first and end of the last part - for (set::iterator it=parts.begin(); it!=parts.end(); it++) + for (set::iterator it=parts.begin(); it!=parts.end(); it++) if ((*it)->track()==track) { - Part* p=*it; + const Part* p=*it; if (p->tick() < begin) { begin=p->tick(); @@ -1465,21 +1465,20 @@ bool merge_parts(const set& parts) new_part->setLenTick(end-begin); // copy all events from the source parts into the new part - EventList& new_el = new_part->events(); - for (set::iterator p_it=parts.begin(); p_it!=parts.end(); p_it++) + for (set::iterator p_it=parts.begin(); p_it!=parts.end(); p_it++) if ((*p_it)->track()==track) { - EventList* old_el= (*p_it)->events(); - for (iEvent ev_it=old_el->begin(); ev_it!=old_el->end(); ev_it++) + const EventList& old_el= (*p_it)->events(); + for (ciEvent ev_it=old_el.begin(); ev_it!=old_el.end(); ev_it++) { - Event new_event=ev_it->second; + Event new_event=ev_it->second.clone(); new_event.setTick( new_event.tick() + (*p_it)->tick() - new_part->tick() ); new_part->nonconst_events().add(new_event); } } // delete all the source parts - for (set::iterator it=parts.begin(); it!=parts.end(); it++) + for (set::iterator it=parts.begin(); it!=parts.end(); it++) if ((*it)->track()==track) operations.push_back( UndoOp(UndoOp::DeletePart, *it) ); // and add the new one diff --git a/muse2/muse/functions.h b/muse2/muse/functions.h index 31c91fe4..b746470c 100644 --- a/muse2/muse/functions.h +++ b/muse2/muse/functions.h @@ -39,36 +39,36 @@ class QMimeData; namespace MusECore { class Undo; -std::set partlist_to_set(PartList* pl); -std::set part_to_set(Part* p); -std::map get_events(const std::set& parts, int range); +std::set partlist_to_set(PartList* pl); +std::set part_to_set(Part* p); +std::map get_events(const std::set& parts, int range); //these functions simply do their job, non-interactively -bool modify_velocity(const std::set& parts, int range, int rate, int offset=0); -bool modify_off_velocity(const std::set& parts, int range, int rate, int offset=0); -bool modify_notelen(const std::set& parts, int range, int rate, int offset=0); -bool quantize_notes(const std::set& parts, int range, int raster, bool len=false, int strength=100, int swing=0, int threshold=0); -bool erase_notes(const std::set& 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& parts, int range); -bool set_notelen(const std::set& parts, int range, int len); -bool move_notes(const std::set& parts, int range, signed int ticks); -bool transpose_notes(const std::set& parts, int range, signed int halftonesteps); -bool crescendo(const std::set& parts, int range, int start_val, int end_val, bool absolute); -bool legato(const std::set& parts, int range, int min_len=1, bool dont_shorten=false); +bool modify_velocity(const std::set& parts, int range, int rate, int offset=0); +bool modify_off_velocity(const std::set& parts, int range, int rate, int offset=0); +bool modify_notelen(const std::set& parts, int range, int rate, int offset=0); +bool quantize_notes(const std::set& parts, int range, int raster, bool len=false, int strength=100, int swing=0, int threshold=0); +bool erase_notes(const std::set& 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& parts, int range); +bool set_notelen(const std::set& parts, int range, int len); +bool move_notes(const std::set& parts, int range, signed int ticks); +bool transpose_notes(const std::set& parts, int range, signed int halftonesteps); +bool crescendo(const std::set& parts, int range, int start_val, int end_val, bool absolute); +bool legato(const std::set& parts, int range, int min_len=1, bool dont_shorten=false); //the below functions automatically open the dialog //they return true if you click "ok" and false if "abort" -bool modify_velocity(const std::set& parts); -bool modify_notelen(const std::set& parts); -bool quantize_notes(const std::set& parts); -bool set_notelen(const std::set& parts); -bool move_notes(const std::set& parts); -bool transpose_notes(const std::set& parts); -bool crescendo(const std::set& parts); -bool erase_notes(const std::set& parts); -bool delete_overlaps(const std::set& parts); -bool legato(const std::set& parts); +bool modify_velocity(const std::set& parts); +bool modify_notelen(const std::set& parts); +bool quantize_notes(const std::set& parts); +bool set_notelen(const std::set& parts); +bool move_notes(const std::set& parts); +bool transpose_notes(const std::set& parts); +bool crescendo(const std::set& parts); +bool erase_notes(const std::set& parts); +bool delete_overlaps(const std::set& parts); +bool legato(const std::set& parts); //the below functions operate on selected parts bool modify_velocity(); @@ -84,29 +84,29 @@ bool legato(); //functions for copy'n'paste -void copy_notes(const std::set& parts, int range); -bool paste_notes(Part* paste_into_part=NULL); // shows a dialog -void paste_notes(int max_distance=3072, bool always_new_part=false, bool never_new_part=false, Part* paste_into_part=NULL, int amount=1, int raster=3072); -QMimeData* selected_events_to_mime(const std::set& parts, int range); -QMimeData* parts_to_mime(const std::set& parts); +void copy_notes(const std::set& parts, int range); +bool paste_notes(const Part* paste_into_part=NULL); // shows a dialog +void paste_notes(int max_distance=3072, bool always_new_part=false, bool never_new_part=false, const Part* paste_into_part=NULL, int amount=1, int raster=3072); +QMimeData* selected_events_to_mime(const std::set& parts, int range); +QMimeData* parts_to_mime(const std::set& parts); -void paste_at(const QString& pt, int pos, int max_distance=3072, bool always_new_part=false, bool never_new_part=false, Part* paste_into_part=NULL, int amount=1, int raster=3072); +void paste_at(const QString& pt, int pos, int max_distance=3072, bool always_new_part=false, bool never_new_part=false, const Part* paste_into_part=NULL, int amount=1, int raster=3072); //functions for selections -void select_all(const std::set& parts); -void select_none(const std::set& parts); -void select_invert(const std::set& parts); -void select_in_loop(const std::set& parts); -void select_not_in_loop(const std::set& parts); +void select_all(const std::set& parts); +void select_none(const std::set& parts); +void select_invert(const std::set& parts); +void select_in_loop(const std::set& parts); +void select_not_in_loop(const std::set& parts); //functions for parts void shrink_parts(int raster=-1); //negative values mean "config.division" void expand_parts(int raster=-1); -void schedule_resize_all_same_len_clone_parts(Part* part, unsigned new_len, Undo& operations); +void schedule_resize_all_same_len_clone_parts(const Part* part, unsigned new_len, Undo& operations); void clean_parts(); bool merge_selected_parts(); -bool merge_parts(const std::set& parts); +bool merge_parts(const std::set& parts); // internal QMimeData* file_to_mimedata(FILE *datafile, QString mimeType); diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp index e71be282..75cbce9f 100644 --- a/muse2/muse/helper.cpp +++ b/muse2/muse/helper.cpp @@ -108,7 +108,7 @@ Part* partFromSerialNumber(int serial) return NULL; } -bool any_event_selected(const set& parts, bool in_range) +bool any_event_selected(const set& parts, bool in_range) { return !get_events(parts, in_range ? 3 : 1).empty(); } @@ -942,8 +942,8 @@ int populateMidiCtrlMenu(PopupMenu* menu, MusECore::PartList* part_list, MusECor bool used = false; for (MusECore::iPart ip = part_list->begin(); ip != part_list->end(); ++ip) { const MusECore::EventList& el = ip->second->events(); - for (MusECore::iEvent ie = el.begin(); ie != el.end(); ++ie) { - MusECore::Event e = ie->second; + for (MusECore::ciEvent ie = el.begin(); ie != el.end(); ++ie) { + const MusECore::Event& e = ie->second; if(e.type() != MusECore::Controller) continue; int ctl_num = e.dataA(); diff --git a/muse2/muse/helper.h b/muse2/muse/helper.h index 33b2e9a0..b5763a4e 100644 --- a/muse2/muse/helper.h +++ b/muse2/muse/helper.h @@ -43,7 +43,7 @@ class PartList; QString pitch2string(int v); Part* partFromSerialNumber(int serial); -bool any_event_selected(const std::set&, bool in_range=false); +bool any_event_selected(const std::set&, bool in_range=false); bool drummaps_almost_equal(const DrumMap* one, const DrumMap* two, int drummap_size=128); diff --git a/muse2/muse/importmidi.cpp b/muse2/muse/importmidi.cpp index 7cd69095..b0affa24 100644 --- a/muse2/muse/importmidi.cpp +++ b/muse2/muse/importmidi.cpp @@ -379,7 +379,7 @@ bool MusE::importMidi(const QString name, bool merge) void MusE::processTrack(MusECore::MidiTrack* track) { - const MusECore::EventList& tevents = track->events; + MusECore::EventList& tevents = track->events; if (tevents.empty()) return; @@ -394,8 +394,8 @@ void MusE::processTrack(MusECore::MidiTrack* track) MusECore::PartList* pl = track->parts(); int lastTick = 0; - for (MusECore::iEvent i = tevents.begin(); i != tevents.end(); ++i) { - MusECore::Event event = i->second; + for (MusECore::ciEvent i = tevents.begin(); i != tevents.end(); ++i) { + const MusECore::Event& event = i->second; int epos = event.tick() + event.lenTick(); if (epos > lastTick) lastTick = epos; @@ -440,8 +440,8 @@ void MusE::processTrack(MusECore::MidiTrack* track) st = x1; // begin new part //HACK: //lastOff: - for (MusECore::iEvent i = i1; i != i2; ++i) { - MusECore::Event event = i->second; + for (MusECore::ciEvent i = i1; i != i2; ++i) { + const MusECore::Event& event = i->second; if (event.type() == MusECore::Note) { int off = event.tick() + event.lenTick(); if (off > lastOff) @@ -481,7 +481,7 @@ void MusE::processTrack(MusECore::MidiTrack* track) int startTick = part->tick(); for (MusECore::iEvent i = r1; i != r2; ++i) { - MusECore::Event ev = i->second; + MusECore::Event& ev = i->second; int ntick = ev.tick() - startTick; ev.setTick(ntick); part->nonconst_events().add(ev); @@ -615,7 +615,7 @@ void MusE::importPartToTrack(QString& filename, unsigned tick, MusECore::Track* if (tag == "part") { // Read the part. MusECore::Part* p = 0; - p = Part::readFromXml(xml, track); + p = MusECore::Part::readFromXml(xml, track); // If it could not be created... if(!p) { diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp index e3dac210..893694c3 100644 --- a/muse2/muse/midiedit/dcanvas.cpp +++ b/muse2/muse/midiedit/dcanvas.cpp @@ -1211,7 +1211,7 @@ void DrumCanvas::resizeEvent(QResizeEvent* ev) void DrumCanvas::modifySelected(NoteInfo::ValType type, int val, bool delta_mode) { - QList< QPair > already_done; + QList< QPair > already_done; MusEGlobal::audio->msgIdle(true); MusEGlobal::song->startUndo(); for (iCItem i = items.begin(); i != items.end(); ++i) { @@ -1224,7 +1224,7 @@ void DrumCanvas::modifySelected(NoteInfo::ValType type, int val, bool delta_mode MusECore::MidiPart* part = (MusECore::MidiPart*)(e->part()); - if (already_done.contains(QPair(part->events(), event))) + if (already_done.contains(QPair(part->clonemaster_sn(), event))) continue; MusECore::Event newEvent = event.clone(); @@ -1306,7 +1306,7 @@ void DrumCanvas::modifySelected(NoteInfo::ValType type, int val, bool delta_mode // Indicate do not do port controller values and clone parts. MusEGlobal::song->addUndo(MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part, false, false)); - already_done.append(QPair(part->events(), event)); + already_done.append(QPair(part->clonemaster_sn(), event)); } MusEGlobal::song->endUndo(SC_EVENT_MODIFIED); MusEGlobal::audio->msgIdle(false); diff --git a/muse2/muse/midiedit/prcanvas.cpp b/muse2/muse/midiedit/prcanvas.cpp index a46b5a5c..5be4c090 100644 --- a/muse2/muse/midiedit/prcanvas.cpp +++ b/muse2/muse/midiedit/prcanvas.cpp @@ -986,7 +986,7 @@ void PianoCanvas::curPartChanged() void PianoCanvas::modifySelected(MusEGui::NoteInfo::ValType type, int val, bool delta_mode) { - QList< QPair > already_done; + QList< QPair > already_done; MusEGlobal::audio->msgIdle(true); MusEGlobal::song->startUndo(); for (MusEGui::iCItem i = items.begin(); i != items.end(); ++i) { @@ -999,7 +999,7 @@ void PianoCanvas::modifySelected(MusEGui::NoteInfo::ValType type, int val, bool MusECore::MidiPart* part = (MusECore::MidiPart*)(e->part()); - if (already_done.contains(QPair(part->events(), event))) + if (already_done.contains(QPair(part->clonemaster_sn(), event))) continue; MusECore::Event newEvent = event.clone(); @@ -1069,7 +1069,7 @@ void PianoCanvas::modifySelected(MusEGui::NoteInfo::ValType type, int val, bool // Indicate do not do port controller values and clone parts. MusEGlobal::song->addUndo(MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part, false, false)); - already_done.append(QPair(part->events(), event)); + already_done.append(QPair(part->clonemaster_sn(), event)); } MusEGlobal::song->endUndo(SC_EVENT_MODIFIED); MusEGlobal::audio->msgIdle(false); diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 54ff0c2f..1b8daefc 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -653,7 +653,7 @@ void ScoreEdit::song_changed(MusECore::SongChangedFlags_t flags) if (flags & (SC_SELECTION | SC_EVENT_MODIFIED | SC_EVENT_REMOVED)) { - map selection=get_events(score_canvas->get_all_parts(),1); + map selection=get_events(score_canvas->get_all_parts(),1); if (selection.empty()) { apply_velo_to_label->setText(tr("Apply to new notes:")); @@ -664,7 +664,7 @@ void ScoreEdit::song_changed(MusECore::SongChangedFlags_t flags) int velo=-1; int velo_off=-1; - for (map::iterator it=selection.begin(); it!=selection.end(); it++) + for (map::iterator it=selection.begin(); it!=selection.end(); it++) if (it->first->type()==MusECore::Note) { if (velo==-1) velo=it->first->velo(); @@ -1520,9 +1520,9 @@ void ScoreCanvas::move_staff_below(list::iterator dest, list:: move_staff_above(dest, src); } -set ScoreCanvas::get_all_parts() +set ScoreCanvas::get_all_parts() { - set result; + set result; for (list::iterator it=staves.begin(); it!=staves.end(); it++) result.insert(it->parts.begin(), it->parts.end()); @@ -4504,9 +4504,9 @@ void ScoreCanvas::set_velo_off(int velo) void ScoreCanvas::deselect_all() { - set all_parts=get_all_parts(); + set all_parts=get_all_parts(); - for (set::iterator part=all_parts.begin(); part!=all_parts.end(); part++) + for (set::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); diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index cc7acbd5..2175e1d1 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -860,7 +860,7 @@ class ScoreCanvas : public MusEGui::View MusECore::Part* get_dragged_event_part() {return dragged_event_part;} void set_dragged_event_part(MusECore::Part* p) {dragged_event_part=p; if (dragged_event_part) dragged_event_part_index=dragged_event_part->sn();} - set get_all_parts(); + set get_all_parts(); void write_staves(int level, MusECore::Xml& xml) const; diff --git a/muse2/muse/midievent.cpp b/muse2/muse/midievent.cpp index 9fd47eaf..5330b518 100644 --- a/muse2/muse/midievent.cpp +++ b/muse2/muse/midievent.cpp @@ -45,7 +45,7 @@ MidiEventBase::MidiEventBase(EventType t) // MidiEventBase::mid //--------------------------------------------------------- -EventBase* MidiEventBase::mid(unsigned b, unsigned e) +EventBase* MidiEventBase::mid(unsigned b, unsigned e) const { if (tick() < b || tick() >= e) return 0; diff --git a/muse2/muse/midievent.h b/muse2/muse/midievent.h index 30f0d84f..8aa38f0e 100644 --- a/muse2/muse/midievent.h +++ b/muse2/muse/midievent.h @@ -71,7 +71,7 @@ class MidiEventBase : public EventBase { virtual void dump(int n = 0) const; virtual void read(Xml&); virtual void write(int, Xml&, const Pos& offset, bool forcePath = false) const; - virtual EventBase* mid(unsigned, unsigned); + virtual EventBase* mid(unsigned, unsigned) const; }; } // namespace MusECore diff --git a/muse2/muse/miditransform.cpp b/muse2/muse/miditransform.cpp index 247fdaf8..75e6f4f7 100644 --- a/muse2/muse/miditransform.cpp +++ b/muse2/muse/miditransform.cpp @@ -758,7 +758,7 @@ void MidiTransformerDialog::processEvent(MusECore::Event& event, MusECore::MidiP // return true if event is selected //--------------------------------------------------------- -bool MidiTransformerDialog::isSelected(MusECore::Event& event, MusECore::MidiPart*) +bool MidiTransformerDialog::isSelected(const MusECore::Event& event) { MusECore::MidiTransformation* cmt = data->cmt; @@ -926,8 +926,8 @@ void MidiTransformerDialog::apply() bool copyExtract = (data->cmt->funcOp == MusECore::Copy) || (data->cmt->funcOp == MusECore::Extract); - std::vector< MusECore::EventList* > doneList; - typedef std::vector< MusECore::EventList* >::iterator iDoneList; + QSet< int > doneList; + typedef std::set< int >::iterator iDoneList; iDoneList idl; MusECore::MidiTrackList* tracks = MusEGlobal::song->midis(); @@ -941,21 +941,18 @@ void MidiTransformerDialog::apply() // check wether we must generate a new track for (MusECore::iPart p = pl->begin(); p != pl->end(); ++p) { MusECore::MidiPart* part = (MusECore::MidiPart *) p->second; - MusECore::EventList* el = part->events(); + const MusECore::EventList& el = part->events(); // Check if the event list has already been done. Skip repeated clones. - for(idl = doneList.begin(); idl != doneList.end(); ++idl) - if(*idl == el) - break; - if(idl != doneList.end()) + if (doneList.contains(part->clonemaster_sn())) break; - doneList.push_back(el); + doneList.insert(part->clonemaster_sn()); - for (MusECore::iEvent i = el->begin(); i != el->end(); ++i) { - MusECore::Event event = i->second; + for (MusECore::ciEvent i = el.begin(); i != el.end(); ++i) { + const MusECore::Event& event = i->second; unsigned tick = event.tick(); if (data->cmt->insideLoop && (tick < MusEGlobal::song->lpos() || tick >= MusEGlobal::song->rpos())) continue; - if (isSelected(event, part)) { + if (isSelected(event)) { newTrack = new MusECore::MidiTrack(); tl.push_back(newTrack); break; @@ -969,23 +966,20 @@ void MidiTransformerDialog::apply() for (MusECore::iPart p = pl->begin(); p != pl->end(); ++p) { MusECore::MidiPart* part = (MusECore::MidiPart *) p->second; MusECore::MidiPart* newPart = 0; - MusECore::EventList* el = part->events(); + const MusECore::EventList& el = part->events(); // Check if the event list has already been done. Skip repeated clones. - for(idl = doneList.begin(); idl != doneList.end(); ++idl) - if(*idl == el) + if (doneList.contains(part->clonemaster_sn())) break; - if(idl != doneList.end()) - break; - doneList.push_back(el); + doneList.insert(part->clonemaster_sn()); if (copyExtract) { // check wether we must generate a new part - for (MusECore::iEvent i = el->begin(); i != el->end(); ++i) { - MusECore::Event event = i->second; + for (MusECore::ciEvent i = el.begin(); i != el.end(); ++i) { + const MusECore::Event& event = i->second; unsigned tick = event.tick(); if (data->cmt->insideLoop && (tick < MusEGlobal::song->lpos() || tick >= MusEGlobal::song->rpos())) continue; - if (isSelected(event, part)) { + if (isSelected(event)) { newPart = new MusECore::MidiPart(newTrack); newPart->setName(part->name()); newPart->setColorIndex(part->colorIndex()); @@ -998,12 +992,12 @@ void MidiTransformerDialog::apply() } } MusECore::EventList pel; - for (MusECore::iEvent i = el->begin(); i != el->end(); ++i) { - MusECore::Event event = i->second; + for (MusECore::ciEvent i = el.begin(); i != el.end(); ++i) { + const MusECore::Event& event = i->second; unsigned tick = event.tick(); if (data->cmt->insideLoop && (tick < MusEGlobal::song->lpos() || tick >= MusEGlobal::song->rpos())) continue; - int flag = isSelected(event, part); + int flag = isSelected(event); if (data->cmt->funcOp == MusECore::Select) event.setSelected(flag); else if (flag) @@ -1705,9 +1699,9 @@ void MidiTransformerDialog::insideLoopChanged(bool val) /*! - \fn MidiTransformerDialog::typesMatch(MusECore::MidiEvent e, unsigned t) + \fn MidiTransformerDialog::typesMatch(const MusECore::MidiEvent e, unsigned t) */ -bool MidiTransformerDialog::typesMatch(MusECore::Event& e, unsigned selType) +bool MidiTransformerDialog::typesMatch(const MusECore::Event& e, unsigned selType) { bool matched = false; switch (selType) diff --git a/muse2/muse/miditransform.h b/muse2/muse/miditransform.h index 2ed366bf..997c144d 100644 --- a/muse2/muse/miditransform.h +++ b/muse2/muse/miditransform.h @@ -71,9 +71,9 @@ class MidiTransformerDialog : public QDialog, public Ui::MidiTransformDialogBase virtual void accept(); void setValOp(QWidget* a, QWidget* b, MusECore::ValOp op); void processEvent(MusECore::Event&, MusECore::MidiPart*, MusECore::MidiPart*); - bool isSelected(MusECore::Event&, MusECore::MidiPart*); + bool isSelected(const MusECore::Event&); void transformEvent(MusECore::Event&, MusECore::MidiPart*, MusECore::MidiPart*); - bool typesMatch(MusECore::Event& e, unsigned selType); + bool typesMatch(const MusECore::Event& e, unsigned selType); void updatePresetList(); diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index 7e99fa2b..9c3f0e38 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -56,6 +56,8 @@ void Part::unchainClone() // Isolate the part. _prevClone = this; _nextClone = this; + + _clonemaster_sn = this->_sn; } void Part::chainClone(Part* p) @@ -63,17 +65,21 @@ void Part::chainClone(Part* p) // FIXME assertion this->unchainClone(); - + // Make our links to the chain this->_prevClone = p; - this->_nextClone = p->nextClone; + this->_nextClone = p->_nextClone; // Make the chain's links to us this->_nextClone->_prevClone = this; p->_nextClone = this; - // Synchronize this->_events to p->_events - this->_events = p->_events; + // Synchronize this->_events to p->_events. Need to deep-copy, i.e. clone() the Events. + this->_events.clear(); + for (ciEvent it = p->_events.begin(); it!=p->_events.end(); it++) + this->_events.insert(std::pair(it->first, it->second.clone())); + + this->_clonemaster_sn = p->_sn; } void Part::rechainClone() @@ -94,22 +100,7 @@ void unchainTrackParts(Track* t, bool decRefCount) { PartList* pl = t->parts(); for(iPart ip = pl->begin(); ip != pl->end(); ++ip) - { - Part* p = ip->second; - chainCheckErr(p); - - // Do we want to decrease the reference count? - if(decRefCount) - p->events()->incARef(-1); - - // Unchain the part. - p->prevClone()->setNextClone(p->nextClone()); - p->nextClone()->setPrevClone(p->prevClone()); - - // Isolate the part. - p->setPrevClone(p); - p->setNextClone(p); - } + ip->second->unchainClone(); } //--------------------------------------------------------- @@ -119,80 +110,8 @@ void unchainTrackParts(Track* t, bool decRefCount) void chainTrackParts(Track* t, bool incRefCount) { PartList* pl = t->parts(); - for(iPart ip = pl->begin(); ip != pl->end(); ++ip) - { - Part* p = ip->second; - chainCheckErr(p); - - // Do we want to increase the reference count? - if(incRefCount) - p->events()->incARef(1); - - Part* p1 = 0; - - // Look for a part with the same event list, that we can chain to. - // It's faster if track type is known... - - if(!t || (t && t->isMidiTrack())) - { - MidiTrack* mt = 0; - MidiTrackList* mtl = MusEGlobal::song->midis(); - for(ciMidiTrack imt = mtl->begin(); imt != mtl->end(); ++imt) - { - mt = *imt; - const PartList* pl = mt->cparts(); - for(ciPart ip = pl->begin(); ip != pl->end(); ++ip) - { - if(ip->second != p && ip->second->cevents() == p->cevents()) - { - p1 = ip->second; - break; - } - } - // If a suitable part was found on a different track, we're done. We will chain to it. - // Otherwise keep looking for parts on another track. If no others found, then we - // chain to any suitable part which was found on the same given track t. - if(p1 && mt != t) - break; - } - } - if((!p1 && !t) || (t && t->type() == Track::WAVE)) - { - MusECore::WaveTrack* wt = 0; - MusECore::WaveTrackList* wtl = MusEGlobal::song->waves(); - for(MusECore::ciWaveTrack iwt = wtl->begin(); iwt != wtl->end(); ++iwt) - { - wt = *iwt; - const PartList* pl = wt->cparts(); - for(ciPart ip = pl->begin(); ip != pl->end(); ++ip) - { - if(ip->second != p && ip->second->cevents() == p->cevents()) - { - p1 = ip->second; - break; - } - } - if(p1 && wt != t) - break; - } - } - - // No part found with same event list? Done. - if(!p1) - continue; - - // Make sure the part to be chained is unchained first. - p->prevClone()->setNextClone(p->nextClone()); - p->nextClone()->setPrevClone(p->prevClone()); - - // Link the part to be chained. - p->setPrevClone(p1); - p->setNextClone(p1->nextClone()); - - // Re-link the existing part. - p1->nextClone()->setPrevClone(p); - p1->setNextClone(p); - } + for(riPart ip = pl->rbegin(); ip != pl->rend(); ++ip) // walk through in opposite direction than we unchained them. + ip->second->rechainClone(); } //--------------------------------------------------------- @@ -487,7 +406,8 @@ Part::Part(Track* t) _prevClone = this; _nextClone = this; _backupClone = NULL; - setSn(newSn()); + _sn = newSn(); + _clonemaster_sn = _sn; _track = t; _selected = false; _mute = false; @@ -530,13 +450,6 @@ WavePart::WavePart(WaveTrack* t) setType(FRAMES); } -WavePart::WavePart(WaveTrack* t, EventList* ev) - : Part(t, ev) - { - setType(FRAMES); - } - - //--------------------------------------------------------- // Part @@ -730,21 +643,21 @@ void Song::cmdResizePart(Track* track, Part* oPart, unsigned int len, bool doClo // create two new parts p1 and p2 //--------------------------------------------------------- -void Part::splitPart(int tickpos, Part*& p1, Part*& p2) +void Part::splitPart(int tickpos, Part*& p1, Part*& p2) const { int l1 = 0; // len of first new part (ticks or samples) int l2 = 0; // len of second new part int samplepos = MusEGlobal::tempomap.tick2frame(tickpos); - switch (type()) { - case WAVE: + switch (track()->type()) { + case Track::WAVE: l1 = samplepos - frame(); l2 = lenFrame() - l1; break; - case MIDI: - case DRUM: - case NEW_DRUM: + case Track::MIDI: + case Track::DRUM: + case Track::NEW_DRUM: l1 = tickpos - tick(); l2 = lenTick() - l1; break; @@ -758,15 +671,15 @@ void Part::splitPart(int tickpos, Part*& p1, Part*& p2) p1 = this->duplicateEmpty(); // new left part p2 = this->duplicateEmpty(); // new right part - switch (type()) { - case WAVE: + switch (track()->type()) { + case Track::WAVE: p1->setLenFrame(l1); p2->setFrame(samplepos); p2->setLenFrame(l2); break; - case MIDI: - case DRUM: - case NEW_DRUM: + case Track::MIDI: + case Track::DRUM: + case Track::NEW_DRUM: p1->setLenTick(l1); p2->setTick(tickpos); p2->setLenTick(l2); @@ -775,16 +688,14 @@ void Part::splitPart(int tickpos, Part*& p1, Part*& p2) break; } - p2->setSn(p2->newSn()); - - if (type() == WAVE) { + if (track()->type() == Track::WAVE) { int ps = this->frame(); int d1p1 = p1->frame(); int d2p1 = p1->endFrame(); int d1p2 = p2->frame(); int d2p2 = p2->endFrame(); - for (iEvent ie = _events.begin(); ie != _events.end(); ++ie) { - Event event = ie->second; + for (ciEvent ie = _events.begin(); ie != _events.end(); ++ie) { + const Event& event = ie->second; int s1 = event.frame() + ps; int s2 = event.endFrame() + ps; @@ -799,7 +710,7 @@ void Part::splitPart(int tickpos, Part*& p1, Part*& p2) } } else { - for (iEvent ie = se->begin(); ie != se->end(); ++ie) { + for (ciEvent ie = _events.begin(); ie != _events.end(); ++ie) { Event event = ie->second.clone(); int t = event.tick(); if (t >= l1) { @@ -824,7 +735,7 @@ void Song::cmdSplitPart(Track* track, Part* part, int tick) return; Part* p1; Part* p2; - track->splitPart(part, tick, p1, p2); + part->splitPart(tick, p1, p2); MusEGlobal::song->informAboutNewParts(part, p1); MusEGlobal::song->informAboutNewParts(part, p2); diff --git a/muse2/muse/part.h b/muse2/muse/part.h index a9241807..d128460b 100644 --- a/muse2/muse/part.h +++ b/muse2/muse/part.h @@ -66,6 +66,7 @@ class Part : public PosLen { private: static int snGen; int _sn; + int _clonemaster_sn; // the serial number of some clone in the chain. every member of the chain has the same value here. QString _name; bool _selected; @@ -83,12 +84,13 @@ class Part : public PosLen { public: Part(Track*); virtual ~Part(); - virtual Part* duplicate() = 0; - virtual Part* duplicateEmpty() = 0; - virtual Part* createNewClone() = 0; + virtual Part* duplicate() const = 0; + virtual Part* duplicateEmpty() const = 0; + virtual Part* createNewClone() const = 0; + virtual void splitPart(int tickpos, Part*& p1, Part*& p2) const; - int sn() { return _sn; } - void setSn(int n) { _sn = n; } + int clonemaster_sn() const { return _clonemaster_sn; } + int sn() const { return _sn; } int newSn() { return snGen++; } const QString& name() const { return _name; } @@ -104,20 +106,18 @@ class Part : public PosLen { int colorIndex() const { return _colorIndex; } void setColorIndex(int idx) { _colorIndex = idx; } - bool hasClones() { return _prevClone!=this || _nextClone!=this; } - int nClones(); - Part* prevClone() { return _prevClone; } - Part* nextClone() { return _nextClone; } + bool isCloneOf(const Part*) const; + bool hasClones() const { return _prevClone!=this || _nextClone!=this; } + int nClones() const; + Part* prevClone() const { return _prevClone; } // FINDMICHJETZT DELETETHIS 2x + Part* nextClone() const { return _nextClone; } void unchainClone(); void chainClone(Part* p); // *this is made a sibling of p! p is not touched (except for its clone-chain), whereas this->events will get altered void rechainClone(); // re-chains the part to the same clone chain it was unchained before // Returns combination of HiddenEventsType enum. - virtual int hasHiddenEvents() = 0; - // If repeated calls to hasHiddenEvents() are desired, then to avoid re-iteration of the event list, - // call this after hasHiddenEvents(). - int cachedHasHiddenEvents() const { return _hiddenEvents; } + virtual int hasHiddenEvents() const { return _hiddenEvents; } iEvent addEvent(Event& p); // DEPRECATED. requires the part to be NOT a clone. FIXME remove! @@ -136,9 +136,9 @@ class MidiPart : public Part { public: MidiPart(MidiTrack* t) : Part((Track*)t) {} virtual ~MidiPart() {} - virtual MidiPart* duplicate(); - virtual MidiPart* duplicateEmpty(); - virtual MidiPart* createNewClone(); + virtual MidiPart* duplicate() const; + virtual MidiPart* duplicateEmpty() const; + virtual MidiPart* createNewClone() const; MidiTrack* track() const { return (MidiTrack*)Part::track(); } @@ -160,11 +160,10 @@ class WavePart : public Part { public: WavePart(WaveTrack* t); - WavePart(WaveTrack* t, EventList* ev); virtual ~WavePart() {} - virtual WavePart* duplicate(); - virtual WavePart* duplicateEmpty(); - virtual WavePart* createNewClone(); + virtual WavePart* duplicate() const; + virtual WavePart* duplicateEmpty() const; + virtual WavePart* createNewClone() const; WaveTrack* track() const { return (WaveTrack*)Part::track(); } // Returns combination of HiddenEventsType enum. @@ -196,8 +195,6 @@ class PartList : public std::multimap > { } }; -extern void chainClone(Part* p1, Part* p2); -extern void unchainClone(Part* p); extern void chainCheckErr(Part* p); extern void unchainTrackParts(Track* t, bool decRefCount); extern void chainTrackParts(Track* t, bool incRefCount); diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index a9b9a892..be682f3e 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -646,8 +646,8 @@ void Song::remapPortDrumCtrlEvents(int mapidx, int newnote, int newchan, int new for(ciPart ip = pl->begin(); ip != pl->end(); ++ip) { MidiPart* part = (MidiPart*)(ip->second); - const EventList* el = part->cevents(); - for(ciEvent ie = el->begin(); ie != el->end(); ++ie) + const EventList& el = part->events(); + for(ciEvent ie = el.begin(); ie != el.end(); ++ie) { const Event& ev = ie->second; if(ev.type() != Controller) @@ -850,7 +850,7 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, const EventList& events, unsigned part->setName(mt->name()); // copy events for (ciEvent i = s; i != e; ++i) { - Event old = i->second; + const Event& old = i->second; Event event = old.clone(); event.setTick(old.tick() - startTick); // addEvent also adds port controller values. So does msgAddPart, below. Let msgAddPart handle them. @@ -869,8 +869,8 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, const EventList& events, unsigned if (endTick > part->endTick()) { // Determine new part length... endTick = 0; - for (iEvent i = s; i != e; ++i) { - Event event = i->second; + for (ciEvent i = s; i != e; ++i) { + const Event& event = i->second; unsigned tick = event.tick() - partTick + event.lenTick(); if (endTick < tick) endTick = tick; @@ -898,12 +898,11 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, const EventList& events, unsigned part->nonconst_events().erase(si, ei); } - for (iEvent i = s; i != e; ++i) { - Event event = i->second; + for (ciEvent i = s; i != e; ++i) { + Event event = i->second.clone(); event.setTick(event.tick() - partTick); - Event e; // Create an undo op. Indicate do port controller values and clone parts. - addUndo(UndoOp(UndoOp::AddEvent, e, event, part, true, true)); + addUndo(UndoOp(UndoOp::AddEvent, event, part, true, true)); if(part->nonconst_events().find(event) == part->nonconst_events().end()) part->nonconst_events().add(event); @@ -926,8 +925,8 @@ void Song::cmdAddRecordedEvents(MidiTrack* mt, const EventList& events, unsigned } part->nonconst_events().erase(si, ei); } - for (iEvent i = s; i != e; ++i) { - Event event = i->second; + for (ciEvent i = s; i != e; ++i) { + Event event = i->second.clone(); int tick = event.tick() - partTick; event.setTick(tick); diff --git a/muse2/muse/steprec.cpp b/muse2/muse/steprec.cpp index 466c4e21..5bbc38c6 100644 --- a/muse2/muse/steprec.cpp +++ b/muse2/muse/steprec.cpp @@ -79,9 +79,9 @@ void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ct const EventList& events = part->events(); if (ctrl) { - for (iEvent i = events.begin(); i != events.end(); ++i) + for (ciEvent i = events.begin(); i != events.end(); ++i) { - Event ev = i->second; + const Event& ev = i->second; if (ev.isNote() && ev.pitch() == pitch && ((ev.tick() + ev.lenTick() + part->tick()) == tick)) { Event e = ev.clone(); @@ -109,7 +109,7 @@ void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ct EventRange range = events.equal_range(tick - part->tick()); for (ciEvent i = range.first; i != range.second; ++i) { - Event ev = i->second; + const Event& ev = i->second; if (ev.isNote() && ev.pitch() == pitch) { MusEGlobal::audio->msgDeleteEvent(ev, part, true, false, false); @@ -163,9 +163,9 @@ void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ct set extend_set; const EventList& events = part->events(); - for (iEvent i = events.begin(); i != events.end(); ++i) + for (ciEvent i = events.begin(); i != events.end(); ++i) { - Event& ev = i->second; + const Event& ev = i->second; if (ev.isNote() && note_held_down[ev.pitch()] && ((ev.tick() + ev.lenTick() + part->tick()) == tick)) extend_set.insert(&ev); } diff --git a/muse2/muse/structure.cpp b/muse2/muse/structure.cpp index 98763a4a..0c1d673d 100644 --- a/muse2/muse/structure.cpp +++ b/muse2/muse/structure.cpp @@ -167,7 +167,7 @@ void globalCut(bool onlySelectedTracks) { // cut Events const EventList& el = part->events(); - for (iEvent ie = el.lower_bound(len); ie != el.end(); ++ie) + for (ciEvent ie = el.lower_bound(len); ie != el.end(); ++ie) operations.push_back(UndoOp(UndoOp::DeleteEvent,ie->second, part, false, false)); } operations.push_back(UndoOp(UndoOp::ModifyPartLength, part, part->lenTick(), len, true, true)); @@ -179,9 +179,9 @@ void globalCut(bool onlySelectedTracks) Part* p1; Part* p2; Part* p3; - track->splitPart(part, lpos, p1, p2); + part->splitPart(lpos, p1, p2); delete p2; - track->splitPart(part, rpos, p2, p3); + part->splitPart(rpos, p2, p3); delete p2; p3->setTick(lpos); @@ -195,7 +195,7 @@ void globalCut(bool onlySelectedTracks) Part* p1; Part* p2; - track->splitPart(part, rpos, p1, p2); + part->splitPart(rpos, p1, p2); delete p1; p2->setTick(lpos); @@ -254,7 +254,7 @@ Undo movePartsTotheRight(unsigned int startTicks, int moveTicks, bool only_selec // split part to insert new space Part* p1; Part* p2; - track->splitPart(part, startTicks, p1, p2); + part->splitPart(startTicks, p1, p2); p2->setTick(startTicks+moveTicks); MusEGlobal::song->informAboutNewParts(part,p1,p2); @@ -303,7 +303,7 @@ Undo partSplitter(unsigned int pos, bool onlySelectedTracks) if (pos > p1 && pos < (p1+l0)) { Part* p1; Part* p2; - track->splitPart(part, pos, p1, p2); + part->splitPart(pos, p1, p2); MusEGlobal::song->informAboutNewParts(part, p1); MusEGlobal::song->informAboutNewParts(part, p2); diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp index 7bb516bb..06bc34e1 100644 --- a/muse2/muse/track.cpp +++ b/muse2/muse/track.cpp @@ -589,7 +589,7 @@ void MidiTrack::internal_assign(const Track& t, int flags) Part* spart = ip->second; Part* dpart; if (spart->hasClones()) - dpart = spart->createNewClone() + dpart = spart->createNewClone(); else dpart = spart->duplicate(); @@ -787,7 +787,7 @@ void MidiTrack::setInPortAndChannelMask(unsigned int portmask, int chanmask) Part* MidiTrack::newPart(Part*p, bool clone) { - MidiPart* part = clone ? p->createNewClone() : new MidiPart(this); + MidiPart* part = clone ? (MidiPart*)p->createNewClone() : new MidiPart(this); if (p) { part->setName(p->name()); part->setColorIndex(p->colorIndex()); diff --git a/muse2/muse/track.h b/muse2/muse/track.h index 2e8f3af5..f3551ce0 100644 --- a/muse2/muse/track.h +++ b/muse2/muse/track.h @@ -158,7 +158,6 @@ class Track { virtual Part* newPart(Part*p=0, bool clone = false) = 0; void dump() const; - virtual void splitPart(Part*, int, Part*&, Part*&); virtual void setMute(bool val); virtual void setOff(bool val); diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp index 747914e1..dc31f043 100644 --- a/muse2/muse/undo.cpp +++ b/muse2/muse/undo.cpp @@ -278,8 +278,8 @@ void cleanOperationGroup(Undo& group) { using std::set; - set processed_tracks; - set processed_parts; + set processed_tracks; + set processed_parts; for (iUndoOp op=group.begin(); op!=group.end();) { @@ -588,7 +588,7 @@ UndoOp::UndoOp(UndoType type_, int a_, int b_, int c_) } -UndoOp::UndoOp(UndoType type_, int n, Track* track_) +UndoOp::UndoOp(UndoType type_, int n, const Track* track_) { assert(type_==AddTrack || type_==DeleteTrack); assert(track_); @@ -598,7 +598,7 @@ UndoOp::UndoOp(UndoType type_, int n, Track* track_) track = track_; } -UndoOp::UndoOp(UndoType type_, Part* part_, unsigned old_len_or_tick, unsigned new_len_or_tick, bool, bool) +UndoOp::UndoOp(UndoType type_, const Part* part_, unsigned old_len_or_tick, unsigned new_len_or_tick, bool, bool) { assert(type_==AddPart || type_==DeletePart || type_==ModifyPartLength || type_==ModifyPartLengthFrames || type_==ModifyPartTick ); assert(part_); @@ -609,7 +609,7 @@ UndoOp::UndoOp(UndoType type_, Part* part_, unsigned old_len_or_tick, unsigned n new_partlen_or_tick=new_len_or_tick; } -UndoOp::UndoOp(UndoType type_, const Event& oev, const Event& nev, Part* part_, bool doCtrls_, bool doClones_) +UndoOp::UndoOp(UndoType type_, const Event& oev, const Event& nev, const Part* part_, bool doCtrls_, bool doClones_) { assert(type_==ModifyEvent); assert(part_); @@ -622,7 +622,7 @@ UndoOp::UndoOp(UndoType type_, const Event& oev, const Event& nev, Part* part_, doClones = doClones_; } -UndoOp::UndoOp(UndoType type_, const Event& nev, Part* part_, bool doCtrls_, bool doClones_) +UndoOp::UndoOp(UndoType type_, const Event& nev, const Part* part_, bool doCtrls_, bool doClones_) { assert(type_==DeleteEvent || type_==AddEvent); assert(part_); @@ -657,7 +657,7 @@ UndoOp::UndoOp(UndoType type_, const char* changedFile, const char* changeData, endframe = endframe_; } -UndoOp::UndoOp(UndoOp::UndoType type_, Part* part_, const char* old_name, const char* new_name) +UndoOp::UndoOp(UndoOp::UndoType type_, const Part* part_, const char* old_name, const char* new_name) { assert(type_==ModifyPartName); assert(part_); @@ -672,7 +672,7 @@ UndoOp::UndoOp(UndoOp::UndoType type_, Part* part_, const char* old_name, const strcpy(_newName, new_name); } -UndoOp::UndoOp(UndoOp::UndoType type_, Track* track_, const char* old_name, const char* new_name) +UndoOp::UndoOp(UndoOp::UndoType type_, const Track* track_, const char* old_name, const char* new_name) { assert(type_==ModifyTrackName); assert(track_); @@ -687,7 +687,7 @@ UndoOp::UndoOp(UndoOp::UndoType type_, Track* track_, const char* old_name, cons strcpy(_newName, new_name); } -UndoOp::UndoOp(UndoOp::UndoType type_, Track* track_, int old_chan, int new_chan) +UndoOp::UndoOp(UndoOp::UndoType type_, const Track* track_, int old_chan, int new_chan) { assert(type_==ModifyTrackChannel); assert(track_); diff --git a/muse2/muse/undo.h b/muse2/muse/undo.h index 570fd5ab..9997d4cb 100644 --- a/muse2/muse/undo.h +++ b/muse2/muse/undo.h @@ -67,11 +67,11 @@ struct UndoOp { int c; }; struct { - Track* track; + const Track* track; int trackno; }; struct { - Part* part; + const Part* part; unsigned old_partlen_or_tick; // FIXME FINDMICHJETZT XTicks!! unsigned new_partlen_or_tick; }; @@ -88,11 +88,11 @@ struct UndoOp { const char* tmpwavfile; //!< The file with the changed data }; struct { - Marker* realMarker; + Marker* realMarker; Marker* copyMarker; }; struct { - Track* _propertyTrack; + const Track* _propertyTrack; int _oldPropValue; int _newPropValue; }; @@ -110,15 +110,15 @@ struct UndoOp { UndoOp(); UndoOp(UndoType type, int a, int b, int c=0); - UndoOp(UndoType type, int n, Track* track); - UndoOp(UndoType type, 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, Part* part, const char* old_name, const char* new_name); - UndoOp(UndoType type, const Event& oev, const Event& nev, Part* part, bool doCtrls, bool doClones); - UndoOp(UndoType type, const Event& nev, Part* part, bool doCtrls, bool doClones); + 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 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 char* changedFile, const char* changeData, int startframe, int endframe); UndoOp(UndoType type, Marker* copyMarker, Marker* realMarker); - UndoOp(UndoType type, Track* track, const char* old_name, const char* new_name); - UndoOp(UndoType type, Track* track, int old_chan, int new_chan); + UndoOp(UndoType type, const Track* track, const char* old_name, const char* new_name); + UndoOp(UndoType type, const Track* track, int old_chan, int new_chan); }; class Undo : public std::list { diff --git a/muse2/muse/waveedit/wavecanvas.cpp b/muse2/muse/waveedit/wavecanvas.cpp index 5bbe2f1f..0ba0bdbc 100644 --- a/muse2/muse/waveedit/wavecanvas.cpp +++ b/muse2/muse/waveedit/wavecanvas.cpp @@ -1936,7 +1936,7 @@ void WaveCanvas::cmd(int cmd) newEvent->setLenTick(MusEGlobal::song->rpos() - MusEGlobal::song->lpos()); tempPart->addEvent(*newEvent); } - std::set partList; + std::set partList; partList.insert(tempPart); QMimeData *mimeData = MusECore::parts_to_mime(partList); @@ -2585,7 +2585,7 @@ void WaveCanvas::curPartChanged() void WaveCanvas::modifySelected(MusEGui::NoteInfo::ValType type, int val, bool delta_mode) { // TODO: New WaveCanvas: Convert this routine to frames and remove unneeded operations. - QList< QPair > already_done; + QList< QPair > already_done; MusEGlobal::audio->msgIdle(true); MusEGlobal::song->startUndo(); for (MusEGui::iCItem i = items.begin(); i != items.end(); ++i) { @@ -2598,7 +2598,7 @@ void WaveCanvas::modifySelected(MusEGui::NoteInfo::ValType type, int val, bool d MusECore::WavePart* part = (MusECore::WavePart*)(e->part()); - if (already_done.contains(QPair(part->events(), event))) + if (already_done.contains(QPair(part->clonemaster_sn(), event))) continue; MusECore::Event newEvent = event.clone(); @@ -2668,7 +2668,7 @@ void WaveCanvas::modifySelected(MusEGui::NoteInfo::ValType type, int val, bool d // Indicate do not do port controller values and clone parts. MusEGlobal::song->addUndo(MusECore::UndoOp(MusECore::UndoOp::ModifyEvent, newEvent, event, part, false, false)); - already_done.append(QPair(part->events(), event)); + already_done.append(QPair(part->clonemaster_sn(), event)); } MusEGlobal::song->endUndo(SC_EVENT_MODIFIED); MusEGlobal::audio->msgIdle(false); diff --git a/muse2/muse/waveevent.cpp b/muse2/muse/waveevent.cpp index 38ae10c6..842e40b9 100644 --- a/muse2/muse/waveevent.cpp +++ b/muse2/muse/waveevent.cpp @@ -53,7 +53,7 @@ WaveEventBase::WaveEventBase(EventType t) // WaveEventBase::clone //--------------------------------------------------------- -EventBase* WaveEventBase::clone() +EventBase* WaveEventBase::clone() const { return new WaveEventBase(*this); } @@ -62,7 +62,7 @@ EventBase* WaveEventBase::clone() // WaveEvent::mid //--------------------------------------------------------- -EventBase* WaveEventBase::mid(unsigned b, unsigned e) +EventBase* WaveEventBase::mid(unsigned b, unsigned e) const { WaveEventBase* ev = new WaveEventBase(*this); unsigned fr = frame(); diff --git a/muse2/muse/waveevent.h b/muse2/muse/waveevent.h index e539342c..4174e3f5 100644 --- a/muse2/muse/waveevent.h +++ b/muse2/muse/waveevent.h @@ -52,7 +52,7 @@ class WaveEventBase : public EventBase { virtual void read(Xml&); virtual void write(int, Xml&, const Pos& offset, bool forcePath = false) const; - virtual EventBase* mid(unsigned, unsigned); + virtual EventBase* mid(unsigned, unsigned) const; virtual void dump(int n = 0) const; diff --git a/muse2/muse/wavetrack.cpp b/muse2/muse/wavetrack.cpp index 4faaca43..ce11b222 100644 --- a/muse2/muse/wavetrack.cpp +++ b/muse2/muse/wavetrack.cpp @@ -62,7 +62,7 @@ void WaveTrack::internal_assign(const Track& t, int flags) Part* spart = ip->second; Part* dpart; if (spart->hasClones()) - dpart = spart->createNewClone() + dpart = spart->createNewClone(); else dpart = spart->duplicate(); @@ -214,7 +214,7 @@ void WaveTrack::read(Xml& xml) Part* WaveTrack::newPart(Part*p, bool clone) { - WavePart* part = clone ? p->createNewClone() : new WavePart(this); + WavePart* part = clone ? (WavePart*)p->createNewClone() : new WavePart(this); if (p) { part->setName(p->name()); part->setColorIndex(p->colorIndex()); -- cgit v1.2.3 From 02cba3c0588040450531b7d41690e31f4412be78 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Tue, 20 Aug 2013 17:31:43 +0200 Subject: Event/Part selection now via UndoOp::Select* additionally: added Song::applyOperation() removed unused param from (un)chainTrackParts --- muse2/muse/arranger/pcanvas.cpp | 24 +++++++++++----- muse2/muse/functions.cpp | 29 +++++++++++-------- muse2/muse/midiedit/scoreedit.cpp | 15 ++++------ muse2/muse/part.cpp | 4 +-- muse2/muse/part.h | 4 +-- muse2/muse/song.cpp | 4 +-- muse2/muse/song.h | 3 +- muse2/muse/undo.cpp | 60 ++++++++++++++++++++++++++++++++++----- muse2/muse/undo.h | 8 ++++-- 9 files changed, 106 insertions(+), 45 deletions(-) (limited to 'muse2/muse/part.h') 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& parts) { + Undo operations; for (set::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& parts) { + Undo operations; for (set::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& parts) { + Undo operations; for (set::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& parts) { - select_none(parts); + select_none(parts); // this will automatically be grouped into one OperationGroup + Undo operations; for (set::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& parts) { - select_none(parts); + select_none(parts); // this will automatically be grouped into one OperationGroup + Undo operations; for (set::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::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& 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 > { }; 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(i->track); Track* editable_property_track = const_cast(i->_propertyTrack); -// uncomment if needed Part* editable_part = const_cast(i->part); + Part* editable_part = const_cast(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(i->track); Track* editable_property_track = const_cast(i->_propertyTrack); -// uncomment if needed Part* editable_part = const_cast(i->part); + Part* editable_part = const_cast(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 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); -- cgit v1.2.3 From 8c8b3ac35c12af3817ff8d8c3d169af166821198 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Thu, 22 Aug 2013 18:44:42 +0200 Subject: more const-correctness for Part* --- muse2/muse/functions.cpp | 21 +++++++++++---------- muse2/muse/functions.h | 2 +- muse2/muse/midiedit/scoreedit.cpp | 36 ++++++++++++++++++------------------ muse2/muse/midiedit/scoreedit.h | 28 ++++++++++++++-------------- muse2/muse/midieditor.cpp | 10 +++++----- muse2/muse/midieditor.h | 2 +- muse2/muse/part.cpp | 4 ++-- muse2/muse/part.h | 2 +- muse2/muse/song.cpp | 8 ++++---- muse2/muse/song.h | 6 +++--- muse2/muse/steprec.cpp | 2 +- muse2/muse/steprec.h | 2 +- 12 files changed, 62 insertions(+), 61 deletions(-) (limited to 'muse2/muse/part.h') diff --git a/muse2/muse/functions.cpp b/muse2/muse/functions.cpp index 7d5547cb..380d9718 100644 --- a/muse2/muse/functions.cpp +++ b/muse2/muse/functions.cpp @@ -926,7 +926,7 @@ unsigned get_clipboard_len() return get_groupedevents_len(s); } -bool paste_notes(Part* paste_into_part) +bool paste_notes(const Part* paste_into_part) { unsigned temp_begin = AL::sigmap.raster1(MusEGlobal::song->cpos(),0); unsigned temp_end = AL::sigmap.raster2(temp_begin + get_clipboard_len(), 0); @@ -943,7 +943,7 @@ bool paste_notes(Part* paste_into_part) return true; } -void paste_notes(int max_distance, bool always_new_part, bool never_new_part, Part* paste_into_part, int amount, int raster) +void paste_notes(int max_distance, bool always_new_part, bool never_new_part, const Part* paste_into_part, int amount, int raster) { QString tmp="x-muse-groupedeventlists"; // QClipboard::text() expects a QString&, not a QString :( QString s = QApplication::clipboard()->text(tmp, QClipboard::Clipboard); // TODO CHECK Tim. @@ -1102,11 +1102,11 @@ bool read_eventlist_and_part(Xml& xml, EventList* el, int* part_id) // true on s } } -void paste_at(const QString& pt, int pos, int max_distance, bool always_new_part, bool never_new_part, Part* paste_into_part, int amount, int raster) +void paste_at(const QString& pt, int pos, int max_distance, bool always_new_part, bool never_new_part, const Part* paste_into_part, int amount, int raster) { Undo operations; - map expand_map; - map > new_part_map; + map expand_map; + map > new_part_map; QByteArray pt_= pt.toLatin1(); Xml xml(pt_.constData()); @@ -1128,9 +1128,9 @@ void paste_at(const QString& pt, int pos, int max_distance, bool always_new_part if (read_eventlist_and_part(xml, &el, &part_id)) { - Part* dest_part; + const Part* dest_part; Track* dest_track; - Part* old_dest_part; + const Part* old_dest_part; if (paste_into_part == NULL) dest_part = partFromSerialNumber(part_id); @@ -1157,11 +1157,12 @@ void paste_at(const QString& pt, int pos, int max_distance, bool always_new_part if (create_new_part) { - dest_part = dest_track->newPart(); - dest_part->setTick(AL::sigmap.raster1(first_paste_tick, config.division)); + Part* newpart = dest_track->newPart(); + newpart->setTick(AL::sigmap.raster1(first_paste_tick, config.division)); new_part_map[old_dest_part].insert(dest_part); operations.push_back(UndoOp(UndoOp::AddPart, dest_part)); + dest_part = newpart; } for (iEvent i = el.begin(); i != el.end(); ++i) @@ -1216,7 +1217,7 @@ void paste_at(const QString& pt, int pos, int max_distance, bool always_new_part out_of_paste_at_for: - for (map::iterator it = expand_map.begin(); it!=expand_map.end(); it++) + for (map::iterator it = expand_map.begin(); it!=expand_map.end(); it++) if (it->second != it->first->lenTick()) schedule_resize_all_same_len_clone_parts(it->first, it->second, operations); diff --git a/muse2/muse/functions.h b/muse2/muse/functions.h index b746470c..9493caf7 100644 --- a/muse2/muse/functions.h +++ b/muse2/muse/functions.h @@ -40,7 +40,7 @@ namespace MusECore { class Undo; std::set partlist_to_set(PartList* pl); -std::set part_to_set(Part* p); +std::set part_to_set(const Part* p); std::map get_events(const std::set& parts, int range); //these functions simply do their job, non-interactively diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index 96fcc5a5..a827e33c 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -520,7 +520,7 @@ ScoreEdit::ScoreEdit(QWidget* parent, const char* name, unsigned initPos) selection_changed(); connect(MusEGlobal::song, SIGNAL(songChanged(MusECore::SongChangedFlags_t)), SLOT(song_changed(MusECore::SongChangedFlags_t))); - connect(MusEGlobal::song, SIGNAL(newPartsCreated(const std::map< MusECore::Part*, std::set >&)), score_canvas, SLOT(add_new_parts(const std::map< MusECore::Part*, std::set >&))); + connect(MusEGlobal::song, SIGNAL(newPartsCreated(const std::map< const MusECore::Part*, std::set >&)), score_canvas, SLOT(add_new_parts(const std::map< const MusECore::Part*, std::set >&))); score_canvas->fully_recalculate(); score_canvas->goto_tick(initPos,true); @@ -898,7 +898,7 @@ void staff_t::write_status(int level, MusECore::Xml& xml) const xml.tag(level++, "staff"); xml.intTag(level, "type", type); xml.intTag(level, "clef", clef); - for (set::iterator part=parts.begin(); part!=parts.end(); part++) + for (set::iterator part=parts.begin(); part!=parts.end(); part++) { MusECore::Track* track = (*part)->track(); int trkIdx = MusEGlobal::song->tracks()->index(track); @@ -963,7 +963,7 @@ void ScoreEdit::writeStatus(int level, MusECore::Xml& xml) const xml.intTag(level, "preambleContainsKeysig", preamble_keysig_action->isChecked()); xml.intTag(level, "preambleContainsTimesig", preamble_timesig_action->isChecked()); - MusECore::Part* selected_part=score_canvas->get_selected_part(); + const MusECore::Part* selected_part=score_canvas->get_selected_part(); if (selected_part==NULL) { xml.put(level, "none"); @@ -1785,9 +1785,9 @@ void staff_t::create_appropriate_eventlist() // phase one: fill the list ----------------------------------------- //insert note on events - for (set::const_iterator part_it=parts.begin(); part_it!=parts.end(); part_it++) + for (set::const_iterator part_it=parts.begin(); part_it!=parts.end(); part_it++) { - MusECore::Part* part=*part_it; + const MusECore::Part* part=*part_it; for (MusECore::ciEvent it=part->events().begin(); it!=part->events().end(); it++) { @@ -3804,7 +3804,7 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event) if ((mouse_erases_notes) || (event->button()==Qt::MidButton)) //erase? { - MusEGlobal::audio->msgDeleteEvent(dragged_event, dragged_event_part, true, false, false); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::DeleteEvent,dragged_event, dragged_event_part, false, false)); } else if (event->button()==Qt::LeftButton) //edit? { @@ -3818,8 +3818,8 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event) { if (mouse_inserts_notes) { - MusECore::Part* curr_part = NULL; - set possible_dests=staff_it->parts_at_tick(tick); + const MusECore::Part* curr_part = NULL; + set possible_dests=staff_it->parts_at_tick(tick); if (!possible_dests.empty()) { @@ -3866,7 +3866,7 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event) newevent.setLenTick(curr_part->lenTick() - newevent.tick()); } - MusEGlobal::audio->msgAddEvent(newevent, curr_part, true, false, false); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::AddEvent, newevent, curr_part,false, false)); set_dragged_event_part(curr_part); dragged_event=newevent; @@ -3913,7 +3913,7 @@ void ScoreCanvas::mouseReleaseEvent (QMouseEvent* event) { if (debugMsg) cout << "new length <= 0, erasing item" << endl; if (undo_started) MusEGlobal::song->undo(); - MusEGlobal::audio->msgDeleteEvent(dragged_event, dragged_event_part, true, false, false); + MusEGlobal::song->applyOperation(UndoOp(UndoOp::DeleteEvent,dragged_event, dragged_event_part, false, false)); } else { @@ -4512,7 +4512,7 @@ bool staff_t::cleanup_parts() { bool did_something=false; - for (set::iterator it=parts.begin(); it!=parts.end();) + for (set::iterator it=parts.begin(); it!=parts.end();) { bool valid=false; @@ -4543,11 +4543,11 @@ bool staff_t::cleanup_parts() return did_something; } -set staff_t::parts_at_tick(unsigned tick) +set staff_t::parts_at_tick(unsigned tick) { - set result; + set result; - for (set::iterator it=parts.begin(); it!=parts.end(); it++) + for (set::iterator it=parts.begin(); it!=parts.end(); it++) if ((tick >= (*it)->tick()) && (tick<=(*it)->endTick())) result.insert(*it); @@ -4611,7 +4611,7 @@ void staff_t::update_part_indices() { part_indices.clear(); - for (set::iterator it=parts.begin(); it!=parts.end(); it++) + for (set::iterator it=parts.begin(); it!=parts.end(); it++) part_indices.insert((*it)->sn()); } @@ -4648,15 +4648,15 @@ void ScoreEdit::keyPressEvent(QKeyEvent* event) } -void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set >& param) +void ScoreCanvas::add_new_parts(const std::map< const MusECore::Part*, std::set >& param) { for (list::iterator staff=staves.begin(); staff!=staves.end(); staff++) { - for (std::map< MusECore::Part*, set >::const_iterator it = param.begin(); it!=param.end(); it++) + for (std::map< const MusECore::Part*, set >::const_iterator it = param.begin(); it!=param.end(); it++) if (staff->parts.find(it->first)!=staff->parts.end()) staff->parts.insert(it->second.begin(), it->second.end()); - //staff->cleanup_parts(); // don't cleanup here, because at this point, the parts may only exist + //staff->cleanup_parts(); // don't cleanup here, because at this point, the parts might exist only // in the operation group. cleanup could remove them immediately staff->update_part_indices(); } diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index 2175e1d1..31bc0cff 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -257,7 +257,7 @@ class FloEvent enum typeEnum { NOTE_ON = 30, NOTE_OFF = 10, BAR = 20, KEY_CHANGE=23, TIME_SIG=26 }; //the order matters! typeEnum type; unsigned tick; - MusECore::Part* source_part; + const MusECore::Part* source_part; const MusECore::Event* source_event; int pitch; @@ -270,7 +270,7 @@ class FloEvent MusECore::key_enum key; - FloEvent(unsigned ti, int p,int v,int l,typeEnum t, MusECore::Part* part=NULL, const MusECore::Event* event=NULL) + FloEvent(unsigned ti, int p,int v,int l,typeEnum t, const MusECore::Part* part=NULL, const MusECore::Event* event=NULL) { pitch=p; vel=v; @@ -313,7 +313,7 @@ class FloItem typeEnum type; unsigned begin_tick; const MusECore::Event* source_event; - MusECore::Part* source_part; + const MusECore::Part* source_part; note_pos_t pos; int len; @@ -343,7 +343,7 @@ class FloItem - FloItem(typeEnum t, note_pos_t p, int l=0,int d=0, bool ti=false, unsigned beg=0, MusECore::Part* part=NULL, const MusECore::Event* event=NULL) + FloItem(typeEnum t, note_pos_t p, int l=0,int d=0, bool ti=false, unsigned beg=0, const MusECore::Part* part=NULL, const MusECore::Event* event=NULL) { pos=p; dots=d; @@ -546,7 +546,7 @@ enum staff_mode_t struct staff_t { - set parts; + set parts; set part_indices; ScoreEventList eventlist; ScoreItemList itemlist; @@ -585,7 +585,7 @@ struct staff_t parent=parent_; } - staff_t (ScoreCanvas* parent_, staff_type_t type_, clef_t clef_, set parts_) + staff_t (ScoreCanvas* parent_, staff_type_t type_, clef_t clef_, set parts_) { type=type_; clef=clef_; @@ -596,7 +596,7 @@ struct staff_t bool cleanup_parts(); - set parts_at_tick(unsigned tick); + set parts_at_tick(unsigned tick); void read_status(MusECore::Xml& xml); void write_status(int level, MusECore::Xml& xml) const; @@ -718,7 +718,7 @@ class ScoreCanvas : public MusEGui::View float y_scroll_speed; float y_scroll_pos; - MusECore::Part* selected_part; + const MusECore::Part* selected_part; int selected_part_index; int last_len; @@ -742,7 +742,7 @@ class ScoreCanvas : public MusEGui::View bool inserting; bool dragging; bool drag_cursor_changed; - MusECore::Part* dragged_event_part; + const MusECore::Part* dragged_event_part; int dragged_event_part_index; MusECore::Event dragged_event; MusECore::Event original_dragged_event; @@ -790,7 +790,7 @@ class ScoreCanvas : public MusEGui::View void deselect_all(); void midi_note(int pitch, int velo); - void add_new_parts(const std::map< MusECore::Part*, std::set >&); + void add_new_parts(const std::map< const MusECore::Part*, std::set >&); public slots: void x_scroll_event(int); @@ -855,10 +855,10 @@ class ScoreCanvas : public MusEGui::View int get_last_len() {return last_len;} void set_last_len(int l) {last_len=l;} - MusECore::Part* get_selected_part() {return selected_part;} - void set_selected_part(MusECore::Part* p) {selected_part=p; if (selected_part) selected_part_index=selected_part->sn();} - MusECore::Part* get_dragged_event_part() {return dragged_event_part;} - void set_dragged_event_part(MusECore::Part* p) {dragged_event_part=p; if (dragged_event_part) dragged_event_part_index=dragged_event_part->sn();} + const MusECore::Part* get_selected_part() const {return selected_part;} + void set_selected_part(const MusECore::Part* p) {selected_part=p; if (selected_part) selected_part_index=selected_part->sn();} + const MusECore::Part* get_dragged_event_part() const {return dragged_event_part;} + void set_dragged_event_part(const MusECore::Part* p) {dragged_event_part=p; if (dragged_event_part) dragged_event_part_index=dragged_event_part->sn();} set get_all_parts(); diff --git a/muse2/muse/midieditor.cpp b/muse2/muse/midieditor.cpp index 13e6edc5..a4052d90 100644 --- a/muse2/muse/midieditor.cpp +++ b/muse2/muse/midieditor.cpp @@ -62,7 +62,7 @@ MidiEditor::MidiEditor(ToplevelType t, int r, MusECore::PartList* pl, mainGrid->setSpacing(0); setCentralWidget(mainw); - connect(MusEGlobal::song, SIGNAL(newPartsCreated(const std::map< MusECore::Part*, std::set >&)), SLOT(addNewParts(const std::map< MusECore::Part*, std::set >&))); + connect(MusEGlobal::song, SIGNAL(newPartsCreated(const std::map< const MusECore::Part*, std::set >&)), SLOT(addNewParts(const std::map< const MusECore::Part*, std::set >&))); } //--------------------------------------------------------- @@ -245,15 +245,15 @@ void MidiEditor::setCurCanvasPart(MusECore::Part* part) canvas->setCurrentPart(part); } -void MidiEditor::addNewParts(const std::map< MusECore::Part*, std::set >& param) +void MidiEditor::addNewParts(const std::map< const MusECore::Part*, std::set >& param) { using std::map; using std::set; - for (map< MusECore::Part*, set >::const_iterator it = param.begin(); it!=param.end(); it++) + for (map< const MusECore::Part*, set >::const_iterator it = param.begin(); it!=param.end(); it++) if (_pl->index(it->first) != -1) - for (set::const_iterator it2=it->second.begin(); it2!=it->second.end(); it2++) - addPart(*it2); + for (set::const_iterator it2=it->second.begin(); it2!=it->second.end(); it2++) + addPart(const_cast(*it2)); // FIXME make this const-correct! } } // namespace MusEGui diff --git a/muse2/muse/midieditor.h b/muse2/muse/midieditor.h index 900f06b1..39feeedf 100644 --- a/muse2/muse/midieditor.h +++ b/muse2/muse/midieditor.h @@ -76,7 +76,7 @@ class MidiEditor : public TopWin { void genPartlist(); private slots: - void addNewParts(const std::map< MusECore::Part*, std::set >&); + void addNewParts(const std::map< const MusECore::Part*, std::set >&); public slots: void songChanged(MusECore::SongChangedFlags_t type); diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index e25643c8..b6d1571a 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -375,10 +375,10 @@ iEvent Part::addEvent(Event& p) // index //--------------------------------------------------------- -int PartList::index(Part* part) +int PartList::index(const Part* part) const { int index = 0; - for (iPart i = begin(); i != end(); ++i, ++index) + for (ciPart i = begin(); i != end(); ++i, ++index) if (i->second == part) { return index; } diff --git a/muse2/muse/part.h b/muse2/muse/part.h index ea19410d..5523e71d 100644 --- a/muse2/muse/part.h +++ b/muse2/muse/part.h @@ -186,7 +186,7 @@ class PartList : public std::multimap > { iPart findPart(unsigned tick); iPart add(Part*); void remove(Part* part); - int index(Part*); + int index(const Part*) const; Part* find(int idx); void clearDelete() { for (iPart i = begin(); i != end(); ++i) diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 6085b1ba..bdd24f8b 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -3520,14 +3520,14 @@ QString Song::getScriptPath(int id, bool isdelivered) return path; } -void Song::informAboutNewParts(const std::map< Part*, std::set >& param) +void Song::informAboutNewParts(const std::map< const Part*, std::set >& param) { emit newPartsCreated(param); } -void Song::informAboutNewParts(Part* orig, Part* p1, Part* p2, Part* p3, Part* p4, Part* p5, Part* p6, Part* p7, Part* p8, Part* p9) +void Song::informAboutNewParts(const Part* orig, const Part* p1, const Part* p2, const Part* p3, const Part* p4, const Part* p5, const Part* p6, const Part* p7, const Part* p8, const Part* p9) { - std::map< Part*, std::set > temp; + std::map > temp; temp[orig].insert(p1); temp[orig].insert(p2); @@ -3538,7 +3538,7 @@ void Song::informAboutNewParts(Part* orig, Part* p1, Part* p2, Part* p3, Part* p temp[orig].insert(p7); temp[orig].insert(p8); temp[orig].insert(p9); - temp[orig].erase(static_cast(NULL)); + temp[orig].erase(static_cast(NULL)); temp[orig].erase(orig); informAboutNewParts(temp); diff --git a/muse2/muse/song.h b/muse2/muse/song.h index 95a383cd..6410084f 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -179,7 +179,7 @@ class Song : public QObject { * a key in this map, the Editors shall no more edit this part, but instead * all parts in the_map[old_part] (which is a std::set) */ - void informAboutNewParts(const std::map< Part*, std::set >&); + void informAboutNewParts(const std::map< const Part*, std::set >&); /** 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 * a key in this map, the Editors shall no more edit this part, but instead @@ -187,7 +187,7 @@ class Song : public QObject { * this is a special case of the general function, which only replaces one part * by up to nine different. */ - void informAboutNewParts(Part* orig, Part* p1, Part* p2=NULL, Part* p3=NULL, Part* p4=NULL, Part* p5=NULL, Part* p6=NULL, Part* p7=NULL, Part* p8=NULL, Part* p9=NULL); + void informAboutNewParts(const Part* orig, const Part* p1, const Part* p2=NULL, const Part* p3=NULL, const Part* p4=NULL, const Part* p5=NULL, const Part* p6=NULL, const Part* p7=NULL, const Part* p8=NULL, const Part* p9=NULL); void putEvent(int pv); void endMsgCmd(); @@ -444,7 +444,7 @@ class Song : public QObject { void midiPortsChanged(); void midiNote(int pitch, int velo); void controllerChanged(MusECore::Track*, int); - void newPartsCreated(const std::map< MusECore::Part*, std::set >&); + void newPartsCreated(const std::map< const MusECore::Part*, std::set >&); void sigDirty(); }; diff --git a/muse2/muse/steprec.cpp b/muse2/muse/steprec.cpp index ab4893d0..44da5a7e 100644 --- a/muse2/muse/steprec.cpp +++ b/muse2/muse/steprec.cpp @@ -55,7 +55,7 @@ void StepRec::timeout() } } -void StepRec::record(Part* part, int pitch, int len, int step, int velo, bool ctrl, bool shift, int incoming_pitch) +void StepRec::record(const Part* part, int pitch, int len, int step, int velo, bool ctrl, bool shift, int incoming_pitch) { unsigned tick = MusEGlobal::song->cpos(); unsigned lasttick=0; diff --git a/muse2/muse/steprec.h b/muse2/muse/steprec.h index a82cab20..f99fffc4 100644 --- a/muse2/muse/steprec.h +++ b/muse2/muse/steprec.h @@ -37,7 +37,7 @@ class StepRec : public QObject public: StepRec(bool* note_held_down_array); - void record(Part* part, int recorded_pitch, int len, int step, int velo=80, bool ctrl=false, bool shift=false, int incoming_pitch=1337); + void record(const Part* part, int recorded_pitch, int len, int step, int velo=80, bool ctrl=false, bool shift=false, int incoming_pitch=1337); private slots: void timeout(); -- cgit v1.2.3 From 3b165cb0e152d2514618c6e256bdb4f49ac7d867 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Thu, 22 Aug 2013 18:50:19 +0200 Subject: implemented missing functions of Part --- muse2/muse/event.h | 2 +- muse2/muse/eventlist.cpp | 2 +- muse2/muse/part.cpp | 97 ++++++++++++++++++++++++++++++++++++------------ muse2/muse/part.h | 4 +- 4 files changed, 78 insertions(+), 27 deletions(-) (limited to 'muse2/muse/part.h') diff --git a/muse2/muse/event.h b/muse2/muse/event.h index ed1ddb87..e512e03d 100644 --- a/muse2/muse/event.h +++ b/muse2/muse/event.h @@ -137,7 +137,7 @@ class EventList : public EL { public: ciEvent find(const Event&) const; iEvent find(const Event&); - iEvent add(Event& event); + iEvent add(Event event); void move(Event& event, unsigned tick); void dump() const; void read(Xml& xml, const char* name, bool midi); diff --git a/muse2/muse/eventlist.cpp b/muse2/muse/eventlist.cpp index f499fd2d..ecc7f452 100644 --- a/muse2/muse/eventlist.cpp +++ b/muse2/muse/eventlist.cpp @@ -62,7 +62,7 @@ void EventList::read(Xml& xml, const char* name, bool midi) // add //--------------------------------------------------------- -iEvent EventList::add(Event& event) +iEvent EventList::add(Event event) { // Changed by Tim. An event list containing wave events should be sorted by // frames. WaveTrack::fetchData() relies on the sorting order, and diff --git a/muse2/muse/part.cpp b/muse2/muse/part.cpp index b6d1571a..9b869567 100644 --- a/muse2/muse/part.cpp +++ b/muse2/muse/part.cpp @@ -74,11 +74,8 @@ void Part::chainClone(Part* p) this->_nextClone->_prevClone = this; p->_nextClone = this; - // Synchronize this->_events to p->_events. Need to deep-copy, i.e. clone() the Events. - this->_events.clear(); - for (ciEvent it = p->_events.begin(); it!=p->_events.end(); it++) - this->_events.insert(std::pair(it->first, it->second.clone())); - + // we only chain clones. we must trust in the GUI thread that the eventlist is consistent. + this->_clonemaster_sn = p->_sn; } @@ -90,6 +87,22 @@ void Part::rechainClone() _backupClone = NULL; } +bool Part::isCloneOf(const Part* other) const +{ + return this->_clonemaster_sn == other->_clonemaster_sn; +} + +int Part::nClones() const +{ + int n=1; + + for(const Part* it = this->_nextClone; it!=this; it=it->_nextClone) + n++; + + return n; +} + + // FIXME FINDMICHJETZT TODO: weg damit! //--------------------------------------------------------- @@ -414,30 +427,68 @@ Part::Part(Track* t) _colorIndex = 0; } - -/* FINDMICHJETZT FIXME! -Part* Part::duplicate() const +WavePart* WavePart::duplicateEmpty() const { - Part* dup = duplicateEmpty(); + WavePart* part = new WavePart((WaveTrack*)this->_track); + part->setName(name()); + part->setColorIndex(colorIndex()); + + *(PosLen*)part = *(PosLen*)this; + part->setMute(mute()); + + return part; +} - // copy the eventlist; duplicate each Event(Ptr!). - for (MusECore::ciEvent i = _events.begin(); i != _events.end(); ++i) - dup->_events.add(i->second.clone()) - - return dup; +WavePart* WavePart::duplicate() const +{ + return (WavePart*)Part::duplicate(); } -Part* Part::duplicateEmpty() const +WavePart* WavePart::createNewClone() const { - MidiPart* part = new MidiPart(this->_track); - part->setName(name()); - part->setColorIndex(colorIndex()); + return (WavePart*)Part::createNewClone(); +} - *(PosLen*)part = *(PosLen*)this; - part->setMute(mute()); - - return part; -} */ +MidiPart* MidiPart::duplicateEmpty() const +{ + MidiPart* part = new MidiPart((MidiTrack*)this->_track); + part->setName(name()); + part->setColorIndex(colorIndex()); + + *(PosLen*)part = *(PosLen*)this; + part->setMute(mute()); + + return part; +} + +MidiPart* MidiPart::duplicate() const +{ + return (MidiPart*)Part::duplicate(); +} + +MidiPart* MidiPart::createNewClone() const +{ + return (MidiPart*)Part::createNewClone(); +} + + +Part* Part::createNewClone() const +{ + Part* clone = duplicate(); + clone->_backupClone=const_cast(this); + return clone; +} + +Part* Part::duplicate() const +{ + Part* dup = duplicateEmpty(); + + // copy the eventlist; duplicate each Event(Ptr!). + for (MusECore::ciEvent i = _events.begin(); i != _events.end(); ++i) + dup->_events.add(i->second.clone()); + + return dup; +} //--------------------------------------------------------- diff --git a/muse2/muse/part.h b/muse2/muse/part.h index 5523e71d..e579e64d 100644 --- a/muse2/muse/part.h +++ b/muse2/muse/part.h @@ -84,9 +84,9 @@ class Part : public PosLen { public: Part(Track*); virtual ~Part(); - virtual Part* duplicate() const = 0; + virtual Part* duplicate() const; virtual Part* duplicateEmpty() const = 0; - virtual Part* createNewClone() const = 0; + virtual Part* createNewClone() const; // this does NOT chain clones yet. Chain is updated only when the part is really added! virtual void splitPart(int tickpos, Part*& p1, Part*& p2) const; int clonemaster_sn() const { return _clonemaster_sn; } -- cgit v1.2.3 From c5e6fd0f6dfbf18847b601668ba8c657d776da31 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Wed, 28 Aug 2013 00:49:49 +0200 Subject: operations are now replicated for all clones. minor cleanups. it compiles and seems to work again! :) --- muse2/muse/arranger/pcanvas.cpp | 13 +++------ muse2/muse/part.h | 3 +- muse2/muse/remote/pyapi.cpp | 4 +-- muse2/muse/song.cpp | 13 +++------ muse2/muse/song.h | 8 ++++-- muse2/muse/songfile.cpp | 4 +-- muse2/muse/undo.cpp | 58 +++++++++++++++++++++++++++++++------- muse2/muse/waveedit/wavecanvas.cpp | 1 - 8 files changed, 67 insertions(+), 37 deletions(-) (limited to 'muse2/muse/part.h') diff --git a/muse2/muse/arranger/pcanvas.cpp b/muse2/muse/arranger/pcanvas.cpp index c3c3bcb8..a280d58b 100644 --- a/muse2/muse/arranger/pcanvas.cpp +++ b/muse2/muse/arranger/pcanvas.cpp @@ -353,7 +353,7 @@ bool PartCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& ntrack = tracks->size(); if (MusEGlobal::debugMsg) printf("PartCanvas::moveItem - add new track\n"); - dtrack = MusEGlobal::song->addTrack(operations, type); // Add at end of list. + dtrack = MusEGlobal::song->addTrack(type); // Add at end of list. Creates additional Undo entry. if (type == MusECore::Track::WAVE) { MusECore::WaveTrack* st = (MusECore::WaveTrack*) track; @@ -385,8 +385,7 @@ bool PartCanvas::moveItem(MusECore::Undo& operations, CItem* item, const QPoint& MusECore::Part* dpart; bool clone = (t == MOVE_CLONE || (t == MOVE_COPY && spart->hasClones())); - // This increments aref count if cloned, and chains clones. - // It also gives the new part a new serial number. + // Gives the new part a new serial number. if (clone) dpart = spart->createNewClone(); else @@ -2756,13 +2755,9 @@ void PartCanvas::viewDropEvent(QDropEvent* event) if (!track) { // we need to create a track for this drop if (text.endsWith(".mpt", Qt::CaseInsensitive)) { - MusECore::Undo operations; - track = MusEGlobal::song->addTrack(operations, MusECore::Track::MIDI); // Add at end of list. - MusEGlobal::song->applyOperationGroup(operations); + track = MusEGlobal::song->addTrack(MusECore::Track::MIDI); // Add at end of list. } else { - MusECore::Undo operations; - track = MusEGlobal::song->addTrack(operations, MusECore::Track::WAVE); // Add at end of list. - MusEGlobal::song->applyOperationGroup(operations); + track = MusEGlobal::song->addTrack(MusECore::Track::WAVE); // Add at end of list. } } if (track->type() == MusECore::Track::WAVE && diff --git a/muse2/muse/part.h b/muse2/muse/part.h index e579e64d..02056a2d 100644 --- a/muse2/muse/part.h +++ b/muse2/muse/part.h @@ -109,8 +109,9 @@ class Part : public PosLen { bool isCloneOf(const Part*) const; bool hasClones() const { return _prevClone!=this || _nextClone!=this; } int nClones() const; - Part* prevClone() const { return _prevClone; } // FINDMICHJETZT DELETETHIS 2x + Part* prevClone() const { return _prevClone; } // FINDMICHJETZT make it const Part*! Part* nextClone() const { return _nextClone; } + Part* backupClone() const { return _backupClone; } void unchainClone(); void chainClone(Part* p); // *this is made a sibling of p! p is not touched (except for its clone-chain), whereas this->events will get altered diff --git a/muse2/muse/remote/pyapi.cpp b/muse2/muse/remote/pyapi.cpp index 7d03e36b..8f5abe06 100644 --- a/muse2/muse/remote/pyapi.cpp +++ b/muse2/muse/remote/pyapi.cpp @@ -1131,9 +1131,7 @@ bool Song::event(QEvent* _e) break; } case QPybridgeEvent::SONG_ADD_TRACK: { - MusECore::Undo operations; - MusEGlobal::song->addTrack(operations, (Track::TrackType)e->getP1()); // Add at end of list. - MusEGlobal::song->applyOperationGroup(operations); + MusEGlobal::song->addTrack((Track::TrackType)e->getP1()); // Add at end of list. break; } case QPybridgeEvent::SONG_CHANGE_TRACKNAME: { diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index b6d866e1..3cf1960d 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -216,9 +216,7 @@ Track* Song::addNewTrack(QAction* action, Track* insertAt) if((Track::TrackType)n >= Track::AUDIO_SOFTSYNTH) return 0; - Undo operations; - Track* t = addTrack(operations, (Track::TrackType)n, insertAt); - applyOperationGroup(operations); + Track* t = addTrack((Track::TrackType)n, insertAt); if (t->isVisible()) { deselectTracks(); t->setSelected(true); @@ -236,7 +234,7 @@ Track* Song::addNewTrack(QAction* action, Track* insertAt) // If insertAt is valid, inserts before insertAt. Else at the end after all tracks. //--------------------------------------------------------- -Track* Song::addTrack(Undo& /*operations*/, Track::TrackType type, Track* insertAt) +Track* Song::addTrack(Track::TrackType type, Track* insertAt) { Track* track = 0; int lastAuxIdx = _auxs.size(); @@ -293,12 +291,9 @@ Track* Song::addTrack(Undo& /*operations*/, Track::TrackType type, Track* insert int idx = insertAt ? _tracks.index(insertAt) : -1; - insertTrack1(track, idx); // this and the below are replaced - msgInsertTrack(track, idx, true); // by the UndoOp-operation - insertTrack3(track, idx); // does nothing - // No, can't do this. insertTrack2 needs to be called now, not later, otherwise it sees + // Apply it *now*. insertTrack2 needs to be called now, not later, otherwise it sees // that the track may have routes, and reciprocates them, causing duplicate routes. - ///operations.push_back(UndoOp(UndoOp::AddTrack, idx, track)); + applyOperation(UndoOp(UndoOp::AddTrack, idx, track)); // Add default track <-> midiport routes. if(track->isMidiTrack()) diff --git a/muse2/muse/song.h b/muse2/muse/song.h index 6410084f..bc1aa9a1 100644 --- a/muse2/muse/song.h +++ b/muse2/muse/song.h @@ -171,7 +171,11 @@ class Song : public QObject { Song(const char* name = 0); ~Song(); - bool applyOperationGroup(Undo& group, bool doUndo=true); // group may be changed! cleanOperationGroup is called on group! + /** It is not allowed nor checked(!) to AddPart a clone, and + * to AddEvent/DeleteEvent/ModifyEvent/SelectEvent events which + * would need to be replicated to the newly added clone part! + */ + bool applyOperationGroup(Undo& group, bool doUndo=true); // group may be changed! prepareOperationGroup is called on group! bool applyOperation(const UndoOp& op, bool doUndo=true); /** this sends emits a signal to each MidiEditor or whoever is interested. @@ -424,7 +428,7 @@ class Song : public QObject { void setQuantize(bool val); void panic(); void seqSignal(int fd); - Track* addTrack(Undo& operations, Track::TrackType type, Track* insertAt = 0); + Track* addTrack(Track::TrackType type, Track* insertAt = 0); Track* addNewTrack(QAction* action, Track* insertAt = 0); void duplicateTracks(); QString getScriptPath(int id, bool delivered); diff --git a/muse2/muse/songfile.cpp b/muse2/muse/songfile.cpp index 9b52791a..680e4dcd 100644 --- a/muse2/muse/songfile.cpp +++ b/muse2/muse/songfile.cpp @@ -197,7 +197,7 @@ Part* Part::readFromXml(Xml& xml, Track* track, bool doClone, bool toTrack) { if(i->id == id) // Is a matching part found in the clone list? { - // This makes a clone, chains the part, and increases ref counts. + // Create a clone. It must still be added later in a operationgroup npart = track->newPart((Part*)i->cp, true); break; } @@ -242,7 +242,7 @@ Part* Part::readFromXml(Xml& xml, Track* track, bool doClone, bool toTrack) if(!doClone && !isclone) break; - // This makes a clone, chains the part, and increases ref counts. + // Create a clone. It must still be added later in a operationgroup npart = track->newPart((Part*)i->cp, true); break; } diff --git a/muse2/muse/undo.cpp b/muse2/muse/undo.cpp index b5ee3cec..fdb24dad 100644 --- a/muse2/muse/undo.cpp +++ b/muse2/muse/undo.cpp @@ -274,12 +274,10 @@ void Song::setUndoRedoText() } -void cleanOperationGroup(Undo& group) +void prepareOperationGroup(Undo& group) { - using std::set; - - set processed_tracks; - set processed_parts; + QSet deleted_tracks; + QSet deleted_parts; for (iUndoOp op=group.begin(); op!=group.end();) { @@ -288,21 +286,61 @@ void cleanOperationGroup(Undo& group) if (op->type==UndoOp::DeleteTrack) { - if (processed_tracks.find(op->track)!=processed_tracks.end()) + if (deleted_tracks.contains(op->track)) + { group.erase(op); + } else - processed_tracks.insert(op->track); + { + const PartList* pl = op->track->cparts(); + for (ciPart part = pl->begin(); part != pl->end(); part++) + if (!deleted_parts.contains(part->second)) + { + // they will be inserted between op and op_ + // because we set op=op_ below, the inserted + // elements will be skipped. + group.insert(op, UndoOp(UndoOp::DeletePart, part->second)); + deleted_parts.insert(part->second); + } + + deleted_tracks.insert(op->track); + } } else if (op->type==UndoOp::DeletePart) { - if (processed_parts.find(op->part)!=processed_parts.end()) + if (deleted_parts.contains(op->part)) group.erase(op); else - processed_parts.insert(op->part); + deleted_parts.insert(op->part); } op=op_; } + + // replicate Event modifications to keep clones up to date + for (iUndoOp op=group.begin(); op!=group.end(); op++) + { + if (op->type==UndoOp::AddEvent || op->type==UndoOp::DeleteEvent || op->type==UndoOp::ModifyEvent || op->type==UndoOp::SelectEvent) + { + for (const Part* it = op->part->nextClone(); it!=op->part; it=it->nextClone()) + { + UndoOp newop; + if (op->type==UndoOp::AddEvent) // we need to clone the event + newop = UndoOp(UndoOp::AddEvent, op->nEvent.clone(), it, op->doCtrls, op->doClones); + else if (op->type==UndoOp::DeleteEvent) + newop = UndoOp(UndoOp::DeleteEvent, it->events().findSimilar(op->nEvent)->second, it, op->doCtrls, op->doClones); + else if (op->type==UndoOp::ModifyEvent) + newop = UndoOp(UndoOp::ModifyEvent, op->nEvent.clone(), it->events().findSimilar(op->oEvent)->second, it, op->doCtrls, op->doClones); + else if (op->type==UndoOp::SelectEvent) + { + const Event& found = it->events().findSimilar(op->nEvent)->second; + newop= UndoOp(UndoOp::SelectEvent, found, op->selected, found.selected()); + } + + group.insert(op, newop); + } + } + } } bool Song::applyOperation(const UndoOp& op, bool doUndo) @@ -316,7 +354,7 @@ bool Song::applyOperationGroup(Undo& group, bool doUndo) { if (!group.empty()) { - cleanOperationGroup(group); + prepareOperationGroup(group); //this is a HACK! but it works :) (added by flo93) redoList->push_back(group); redo(); diff --git a/muse2/muse/waveedit/wavecanvas.cpp b/muse2/muse/waveedit/wavecanvas.cpp index 0ba0bdbc..db886bce 100644 --- a/muse2/muse/waveedit/wavecanvas.cpp +++ b/muse2/muse/waveedit/wavecanvas.cpp @@ -1477,7 +1477,6 @@ void WaveCanvas::newItem(MusEGui::CItem* item, bool noSnap) if (diff > 0)// part must be extended? { - //schedule_resize_all_same_len_clone_parts(part, event.endTick(), operations); schedule_resize_all_same_len_clone_parts(part, event.endFrame(), operations); printf("newItem: extending\n"); } -- cgit v1.2.3