13
0

Handle overlaps better when executing DiffCommands.

git-svn-id: svn://localhost/ardour2/branches/3.0@8233 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Carl Hetherington 2010-12-09 21:37:14 +00:00
parent 555c7ac094
commit 627385cab4
2 changed files with 35 additions and 9 deletions

View File

@ -141,9 +141,9 @@ public:
};
/* Currently this class only supports changes of sys-ex time, but could be expanded */
class SysexDiffCommand : public DiffCommand {
class SysExDiffCommand : public DiffCommand {
public:
SysexDiffCommand (boost::shared_ptr<MidiModel> m, const XMLNode& node);
SysExDiffCommand (boost::shared_ptr<MidiModel> m, const XMLNode& node);
enum Property {
Time,
@ -160,7 +160,7 @@ public:
private:
struct Change {
boost::shared_ptr<Evoral::Event<TimeType> > sysex;
SysexDiffCommand::Property property;
SysExDiffCommand::Property property;
TimeType old_time;
TimeType new_time;
};
@ -172,7 +172,8 @@ public:
Change unmarshal_change (XMLNode *);
};
MidiModel::NoteDiffCommand* new_note_diff_command (const std::string name="midi edit");
MidiModel::NoteDiffCommand* new_note_diff_command (const std::string name = "midi edit");
MidiModel::SysExDiffCommand* new_sysex_diff_command (const std::string name = "midi edit");
void apply_command (Session& session, Command* cmd);
void apply_command_as_subcommand (Session& session, Command* cmd);

View File

@ -147,6 +147,8 @@ void
MidiModel::NoteDiffCommand::change (const NotePtr note, Property prop,
uint8_t new_value)
{
assert (note);
NoteChange change;
switch (prop) {
@ -191,6 +193,8 @@ void
MidiModel::NoteDiffCommand::change (const NotePtr note, Property prop,
TimeType new_time)
{
assert (note);
NoteChange change;
switch (prop) {
@ -307,8 +311,30 @@ MidiModel::NoteDiffCommand::operator() ()
for (set<NotePtr>::iterator i = temporary_removals.begin(); i != temporary_removals.end(); ++i) {
NoteDiffCommand side_effects (model(), "side effects");
_model->add_note_unlocked (*i, &side_effects);
*this += side_effects;
if (_model->add_note_unlocked (*i, &side_effects)) {
/* The note was re-added ok */
*this += side_effects;
} else {
/* The note that we removed earlier could not be re-added. This change record
must say that the note was removed. It is an un-note.
*/
/* We didn't change it... */
for (ChangeList::iterator j = _changes.begin(); j != _changes.end(); ) {
ChangeList::iterator k = j;
++k;
if (*i == j->note) {
_changes.erase (j);
}
j = k;
}
/* ...in fact, we removed it */
_removed_notes.push_back (*i);
}
}
if (!side_effect_removals.empty()) {
@ -1124,7 +1150,7 @@ MidiModel::resolve_overlaps_unlocked (const NotePtr note, void* arg)
TimeType note_length = note->length();
DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 checking overlaps for note %2 @ %3\n", this, (int)note->note(), note->time()));
for (Pitches::const_iterator i = p.lower_bound (search_note);
i != p.end() && (*i)->note() == note->note(); ++i) {
@ -1132,7 +1158,6 @@ MidiModel::resolve_overlaps_unlocked (const NotePtr note, void* arg)
TimeType eb = (*i)->end_time();
OverlapType overlap = OverlapNone;
if ((sb > sa) && (eb <= ea)) {
overlap = OverlapInternal;
} else if ((eb >= sa) && (eb <= ea)) {
@ -1146,7 +1171,7 @@ MidiModel::resolve_overlaps_unlocked (const NotePtr note, void* arg)
continue;
}
DEBUG_TRACE (DEBUG::Sequence, string_compose ("\toverlap is %1 for (%2,%3) vs (%4,%5)\n", enum_2_string(overlap),
DEBUG_TRACE (DEBUG::Sequence, string_compose ("\toverlap is %1 for (%2,%3) vs (%4,%5)\n", enum_2_string(overlap),
sa, ea, sb, eb));
if (insert_merge_policy() == InsertMergeReject) {