summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-05-27 13:20:58 +0000
committerFlorian Jung <flo@windfisch.org>2011-05-27 13:20:58 +0000
commit4b344cf08471bcfbce5814ddead384dddb9bb86b (patch)
tree12c3245f05008b21d51b6b29fb090ee8c43ee43f
parente8612708161b71b43d56ef47eede6cc58b035967 (diff)
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.
-rw-r--r--muse2/muse/helper.cpp25
-rw-r--r--muse2/muse/helper.h5
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp89
-rw-r--r--muse2/muse/midiedit/scoreedit.h13
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 <QString>
+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="<<trackIdx<<", partIdx="<<partIdx;
Track* track = song->tracks()->index(trackIdx);
if (track)
part = track->parts()->find(partIdx);
+ if (debugMsg) cout << ", track="<<track<<", part="<<part<<endl;
}
}
break;
@@ -701,12 +703,15 @@ void staff_t::read_status(Xml& xml)
case Xml::TagEnd:
if (tag == "staff")
- return;
+ goto staff_readstatus_end;
default:
break;
}
}
+
+ staff_readstatus_end:
+ update_part_indices();
}
@@ -979,6 +984,7 @@ void ScoreCanvas::add_staves(PartList* pl, bool all_in_one)
staff.parts.insert(part_it->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<staff_t>::iterator dest, list<staff_t>::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<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++)
+ it->cleanup_parts();
+
+ cleanup_staves();
+
+ for (list<staff_t>::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<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++)
- {
- if (it->cleanup_parts())
- something_changed=true;
- }
-
- cleanup_staves();
-
- for (list<staff_t>::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<staff_t>::iterator it=staves.begin(); it!=staves.end(); it++)
+ it->update_parts();
+}
+
+void staff_t::update_parts()
+{
+ parts.clear();
+
+ for (set<int>::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<Part*>::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 <set>
#include <map>
@@ -489,6 +490,7 @@ enum staff_mode_t
struct staff_t
{
set<Part*> parts;
+ set<int> 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<Part*> from the set<int>
+ void update_part_indices(); //re-populates the set<int> from the set<Part*>
};
list<int> 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 set<Part*>s from the set<int>s
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<Part*> get_all_parts();