+ Edit *a = *ap, *b = *bp;
+ if( a->track != b->track ) return 0;
+ return a->startproject > b->startproject ? -1 : 1;
+}
+
+void EDL::delete_edits(ArrayList<Edit*> *edits, int collapse)
+{
+ edits->sort(dead_edit_cmp);
+ for( int i=0; i<edits->size(); ++i ) {
+ Edit *edit = edits->get(i);
+ Track *track = edit->track;
+ int64_t start = edit->startproject;
+ int64_t length = edit->length;
+ int64_t end = start + length;
+ if( session->autos_follow_edits ) {
+ track->automation->clear(start, end, 0, collapse);
+ }
+ if( session->plugins_follow_edits ) {
+ for( int k=0; k<track->plugin_set.size(); ++k ) {
+ PluginSet *plugin_set = track->plugin_set[k];
+ plugin_set->clear(start, end, 1);
+ if( !collapse )
+ plugin_set->paste_silence(start, end, 1);
+ plugin_set->optimize();
+ }
+ }
+ Edit *dead_edit = edit;
+ if( collapse ) {
+ while( (edit=edit->next) )
+ edit->startproject -= length;
+ }
+ delete dead_edit;
+ track->edits->optimize();
+ }
+}
+
+class Range {
+public:
+ static int cmp(Range *ap, Range *bp);
+ double start, end;
+ bool operator ==(Range &that) { return this->start == that.start; }
+ bool operator >(Range &that) { return this->start > that.start; }
+};
+int Range::cmp(Range *ap, Range *bp) {
+ return ap->start < bp->start ? -1 : ap->start == bp->start ? 0 : 1;
+}
+
+static void get_edit_regions(ArrayList<Edit*> *edits, ArrayList<Range> ®ions)
+{
+// move edit inclusive labels by regions
+ for( int i=0; i<edits->size(); ++i ) {
+ Edit *edit = edits->get(i);
+ double pos = edit->track->from_units(edit->startproject);
+ double end = edit->track->from_units(edit->startproject + edit->length);
+ int n = regions.size(), k = n;
+ while( --k >= 0 ) {
+ Range &range = regions[k];
+ if( pos >= range.end ) continue;
+ if( range.start >= end ) continue;
+ int expand = 0;
+ if( range.start > pos ) { range.start = pos; expand = 1; }
+ if( range.end < end ) { range.end = end; expand = 1; }
+ if( !expand ) break;
+ k = n;
+ }
+ if( k < 0 ) {
+ Range &range = regions.append();
+ range.start = pos; range.end = end;
+ }
+ }
+ regions.sort(Range::cmp);
+}
+
+void EDL::delete_edit_labels(ArrayList<Edit*> *edits, int collapse)
+{
+ ArrayList<Range> regions;
+ get_edit_regions(edits, regions);
+ int n = regions.size(), k = n;
+ while( --k >= 0 ) {
+ Range &range = regions[k];
+ labels->clear(range.start, range.end, collapse);
+ }
+}
+
+void EDL::move_edit_labels(ArrayList<Edit*> *edits, double dist)
+{
+ ArrayList<Range> regions;
+ get_edit_regions(edits, regions);
+ int n = regions.size(), k = n;
+ Labels moved(this, 0);
+ while( --k >= 0 ) {
+ Range &range = regions[k];
+ Label *label = labels->label_of(range.start);
+ for( Label *next=0; label && label->position <= range.end; label=next ) {
+ next = label->next;
+ labels->remove_pointer(label);
+ label->position += dist;
+ moved.append(label);
+ }
+ Label *current = labels->first;
+ while( (label=moved.first) ) {
+ moved.remove_pointer(label);
+ while( current && current->position < label->position )
+ current = current->next;
+ if( current && current->position == label->position ) {
+ delete label; continue;
+ }
+ labels->insert_before(current, label);
+ }
+ }
+}
+
+void EDL::modify_edithandles(double oldposition, double newposition,
+ int currentend, int handle_mode, int edit_labels,
+ int edit_plugins, int edit_autos, int group_id)
+{
+ tracks->modify_edithandles(oldposition, newposition,
+ currentend, handle_mode, edit_labels,
+ edit_plugins, edit_autos, group_id);
+}
+
+void EDL::modify_pluginhandles(double oldposition, double newposition,
+ int currentend, int handle_mode, int edit_labels,
+ int edit_autos, Edits *trim_edits)
+{
+ tracks->modify_pluginhandles(oldposition, newposition,
+ currentend, handle_mode, edit_labels,
+ edit_autos, trim_edits);