}
}
+// exactly the same as shuffle_edits except for 1 line
+void Track::reverse_edits(double start, double end, int first_track)
+{
+ ArrayList<Edit*> new_edits;
+ ArrayList<Label*> new_labels;
+ int64_t start_units = to_units(start, 0);
+ int64_t end_units = to_units(end, 0);
+// Sample range of all edits selected
+ //int64_t total_start_units = 0;
+ //int64_t total_end_units = 0;
+// Edit before range
+ Edit *start_edit = 0;
+ int have_start_edit = 0;
+
+// Move all edit pointers to list
+ for(Edit *current = edits->first;
+ current; )
+ {
+ if(current->startproject >= start_units &&
+ current->startproject + current->length <= end_units)
+ {
+ if(!have_start_edit) start_edit = current->previous;
+ have_start_edit = 1;
+ //total_start_units = current->startproject;
+ //total_end_units = current->startproject + current->length;
+ new_edits.append(current);
+
+// Move label pointers
+ if(first_track && edl->session->labels_follow_edits)
+ {
+ double start_seconds = from_units(current->startproject);
+ double end_seconds = from_units(current->startproject +
+ current->length);
+ for(Label *label = edl->labels->first;
+ label;
+ label = label->next)
+ {
+ if(label->position >= start_seconds &&
+ label->position < end_seconds)
+ {
+ new_labels.append(label);
+ edl->labels->remove_pointer(label);
+ }
+ }
+ }
+
+// Remove edit pointer
+ Edit *previous = current;
+ current = NEXT;
+ edits->remove_pointer(previous);
+ }
+ else
+ {
+ current = NEXT;
+ }
+ }
+
+// Insert pointers in reverse order
+ while(new_edits.size())
+ {
+ int index = new_edits.size() - 1;
+ Edit *edit = new_edits.get(index);
+ new_edits.remove_number(index);
+ edits->insert_after(start_edit, edit);
+ start_edit = edit;
+
+// Recalculate start position
+// Save old position for moving labels
+ int64_t startproject1 = edit->startproject;
+ int64_t startproject2 = 0;
+ if(edit->previous)
+ {
+ edit->startproject =
+ startproject2 =
+ edit->previous->startproject + edit->previous->length;
+ }
+ else
+ {
+ edit->startproject = startproject2 = 0;
+ }
+
+
+// Insert label pointers
+ if(first_track && edl->session->labels_follow_edits)
+ {
+ double start_seconds1 = from_units(startproject1);
+ double start_seconds2 = from_units(startproject2);
+ //double end_seconds1 = from_units(edit->startproject + edit->length);
+ for(int i = new_labels.size() - 1; i >= 0; i--)
+ {
+ Label *label = new_labels.get(i);
+// Was in old edit position
+ if(label->position >= start_seconds1 &&
+ label->position < start_seconds2)
+ {
+// Move to new edit position
+ double position = label->position -
+ start_seconds1 +
+ start_seconds2;
+ edl->labels->insert_label(position);
+ new_labels.remove_object_number(i);
+ }
+ }
+ }
+
+
+ }
+
+ optimize();
+
+ if(first_track && edl->session->labels_follow_edits)
+ {
+ edl->labels->optimize();
+ }
+}
+
void Track::align_edits(double start,
double end,
ArrayList<double> *times)