From 4b344cf08471bcfbce5814ddead384dddb9bb86b Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Fri, 27 May 2011 13:20:58 +0000 Subject: fixed bug: score editor didn't react on part changes which invalidate the Part*; it simply worked with the old, invalid pointers, which may lead to severe problems, and indeed leads to a bug when saving. --- muse2/muse/helper.cpp | 25 +++++++++++ muse2/muse/helper.h | 5 +++ muse2/muse/midiedit/scoreedit.cpp | 89 +++++++++++++++++++++++++++------------ muse2/muse/midiedit/scoreedit.h | 13 +++++- 4 files changed, 103 insertions(+), 29 deletions(-) diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp index 605d6f5c..d4a237ea 100644 --- a/muse2/muse/helper.cpp +++ b/muse2/muse/helper.cpp @@ -6,6 +6,9 @@ //========================================================= #include "helper.h" +#include "part.h" +#include "track.h" +#include "song.h" extern bool hIsB; static const char* vall[] = { @@ -38,3 +41,25 @@ QString pitch2string(int v) } + + +int partToIndex(Part* p) +{ + return p->track()->parts()->index(p); +} + +Part* partFromIndex(int index) +{ + TrackList* tl = song->tracks(); + for (iTrack it = tl->begin(); it != tl->end(); ++it) + { + PartList* pl = (*it)->parts(); + iPart ip; + for (ip = pl->begin(); ip != pl->end(); ++ip) + if (ip->second->sn() == index) + return ip->second; + } + + printf("ERROR: partFromIndex(%i) wasn't able to find an appropriate part!\n",index); + return NULL; +} diff --git a/muse2/muse/helper.h b/muse2/muse/helper.h index f772ebf6..d88dcb94 100644 --- a/muse2/muse/helper.h +++ b/muse2/muse/helper.h @@ -10,7 +10,12 @@ #include +class Part; + extern QString pitch2string(int v); +int partToIndex(Part* p); +Part* partFromIndex(int index); + #endif diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp index f8d2a3ba..8c6e85c7 100644 --- a/muse2/muse/midiedit/scoreedit.cpp +++ b/muse2/muse/midiedit/scoreedit.cpp @@ -51,7 +51,7 @@ using namespace std; #include "icons.h" #include "audio.h" #include "functions.h" - +#include "helper.h" #include "cmd.h" #include "sig.h" #include "song.h" @@ -649,9 +649,11 @@ Part* read_part(Xml& xml, QString tag_name="part") else { sscanf(tag.toLatin1().constData(), "%d:%d", &trackIdx, &partIdx); + if (debugMsg) cout << "read_part: trackIdx="<second); } staff.cleanup_parts(); + staff.update_part_indices(); switch (clef) { @@ -1023,6 +1029,7 @@ void ScoreCanvas::add_staves(PartList* pl, bool all_in_one) if (part_it->second->track() == *track_it) staff.parts.insert(part_it->second); staff.cleanup_parts(); + staff.update_part_indices(); switch (((MidiTrack*)(*track_it))->getClef()) { @@ -1256,6 +1263,8 @@ void ScoreCanvas::merge_staves(list::iterator dest, list::iter dest->parts.insert(src->parts.begin(), src->parts.end()); } + dest->update_part_indices(); + remove_staff(src); fully_recalculate(); @@ -1324,6 +1333,26 @@ void ScoreCanvas::fully_recalculate() void ScoreCanvas::song_changed(int flags) { + if (flags & (SC_PART_MODIFIED | SC_PART_REMOVED | SC_PART_INSERTED | SC_TRACK_REMOVED)) + { + update_parts(); + + if (flags & (SC_PART_REMOVED | SC_TRACK_REMOVED)) + { + for (list::iterator it=staves.begin(); it!=staves.end(); it++) + it->cleanup_parts(); + + cleanup_staves(); + + for (list::iterator it=staves.begin(); it!=staves.end(); it++) + it->recalculate(); + + recalc_staff_pos(); + + redraw(); + } + } + if (flags & (SC_PART_MODIFIED | SC_EVENT_INSERTED | SC_EVENT_MODIFIED | SC_EVENT_REMOVED | SC_SIG | SC_KEY) ) @@ -1339,26 +1368,6 @@ void ScoreCanvas::song_changed(int flags) emit canvas_width_changed(canvas_width()); } - if (flags & SC_PART_REMOVED) - { - bool something_changed=false; - - for (list::iterator it=staves.begin(); it!=staves.end(); it++) - { - if (it->cleanup_parts()) - something_changed=true; - } - - cleanup_staves(); - - for (list::iterator it=staves.begin(); it!=staves.end(); it++) - it->recalculate(); - - recalc_staff_pos(); - - redraw(); - } - if (flags & SC_SELECTION) { redraw(); @@ -3490,7 +3499,7 @@ void ScoreCanvas::mousePressEvent (QMouseEvent* event) int this_begin=tick; int this_end=this_begin+calc_len(set_it->len, set_it->dots); - selected_part=set_it->source_part; + set_selected_part(set_it->source_part); //that's the only note corresponding to the event? if (this_begin==total_begin && this_end==total_end) @@ -4263,6 +4272,7 @@ bool staff_t::cleanup_parts() it++; } + if (did_something) update_part_indices(); return did_something; } @@ -4314,6 +4324,32 @@ void ScoreCanvas::midi_note(int pitch, int velo) } + +void ScoreCanvas::update_parts() +{ + if (selected_part!=NULL) //if it's null, let it be null + selected_part=partFromIndex(selected_part_index); + + for (list::iterator it=staves.begin(); it!=staves.end(); it++) + it->update_parts(); +} + +void staff_t::update_parts() +{ + parts.clear(); + + for (set::iterator it=part_indices.begin(); it!=part_indices.end(); it++) + parts.insert(partFromIndex(*it)); +} + +void staff_t::update_part_indices() +{ + part_indices.clear(); + + for (set::iterator it=parts.begin(); it!=parts.end(); it++) + part_indices.insert(partToIndex(*it)); +} + //the following assertions are made: // pix_quarter.width() == pix_half.width() @@ -4339,7 +4375,8 @@ void ScoreCanvas::midi_note(int pitch, int velo) * between, for example, when a cis is tied to a des * * CURRENT TODO - * x nothing atm + * o controller view in score editor + * o deal with expanding parts * * IMPORTANT TODO * o do partial recalculating; recalculating can take pretty long @@ -4349,14 +4386,11 @@ void ScoreCanvas::midi_note(int pitch, int velo) * o thin out: remove unneeded ctrl messages * * less important stuff - * o drum list: scroll while dragging - * o controller view in score editor * o quantize-templates (everything is forced into a specified * rhythm) * o part-templates (you specify some notes and a control-chord; * the notes are set according to the chord then) * o add functions like set velo, mod/set velo-off - * o deal with expanding parts * o use bars instead of flags over groups of 8ths / 16ths etc * o support different keys in different tracks at the same time * calc_pos_add_list and calc_item_pos will be affected by this @@ -4373,6 +4407,7 @@ void ScoreCanvas::midi_note(int pitch, int velo) * o refuse to resize so that width gets smaller or equal than x_left * o draw a margin around notes which are in a bright color * o support drum tracks (x-note-heads etc.) + * o drum list: scroll while dragging: probably unneccessary with the "reorder list" function * * * stuff for the other muse developers diff --git a/muse2/muse/midiedit/scoreedit.h b/muse2/muse/midiedit/scoreedit.h index 71b672a9..0e61f066 100644 --- a/muse2/muse/midiedit/scoreedit.h +++ b/muse2/muse/midiedit/scoreedit.h @@ -35,6 +35,7 @@ #include "mtscale_flo.h" #include "steprec.h" #include "cleftypes.h" +#include "helper.h" #include #include @@ -489,6 +490,7 @@ enum staff_mode_t struct staff_t { set parts; + set part_indices; ScoreEventList eventlist; ScoreItemList itemlist; @@ -532,6 +534,7 @@ struct staff_t clef=clef_; parts=parts_; parent=parent_; + update_part_indices(); } bool cleanup_parts(); @@ -540,6 +543,9 @@ struct staff_t void read_status(Xml& xml); void write_status(int level, Xml& xml) const; + + void update_parts(); //re-populates the set from the set + void update_part_indices(); //re-populates the set from the set }; list calc_accidentials(key_enum key, clef_t clef, key_enum next_key=KEY_C); @@ -643,6 +649,8 @@ class ScoreCanvas : public View float y_scroll_pos; Part* selected_part; + int selected_part_index; + int last_len; int new_len; //when zero or negative, last_len is used @@ -728,7 +736,8 @@ class ScoreCanvas : public View void set_steprec(bool); void set_midiin(bool); - + + void update_parts(); //re-populates the sets from the sets signals: void xscroll_changed(int); void yscroll_changed(int); @@ -772,7 +781,7 @@ class ScoreCanvas : public View void set_last_len(int l) {last_len=l;} Part* get_selected_part() {return selected_part;} - void set_selected_part(Part* p) {selected_part=p;} + void set_selected_part(Part* p) {selected_part=p; if (selected_part) selected_part_index=partToIndex(selected_part);} set get_all_parts(); -- cgit v1.2.3