+ XMLNode& after (_session->locations()->get_state());
+ _session->add_command (new MementoCommand<Locations>(*_session->locations(), &before, &after));
+ }
+ }
+
+ if (tempo_too) {
+ if (!in_command) {
+ begin_reversible_command (_("insert time"));
+ in_command = true;
+ }
+ XMLNode& before (_session->tempo_map().get_state());
+ _session->tempo_map().insert_time (pos, frames);
+ XMLNode& after (_session->tempo_map().get_state());
+ _session->add_command (new MementoCommand<TempoMap>(_session->tempo_map(), &before, &after));
+ }
+
+ if (in_command) {
+ commit_reversible_command ();
+ }
+}
+
+void
+Editor::do_remove_time ()
+{
+ if (selection->tracks.empty()) {
+ return;
+ }
+
+ framepos_t pos = get_preferred_edit_position (EDIT_IGNORE_MOUSE);
+ InsertRemoveTimeDialog d (*this, true);
+
+ int response = d.run ();
+
+ if (response != RESPONSE_OK) {
+ return;
+ }
+
+ framecnt_t distance = d.distance();
+
+ if (distance == 0) {
+ return;
+ }
+
+ remove_time (
+ pos,
+ distance,
+ SplitIntersected,
+ d.move_glued(),
+ d.move_markers(),
+ d.move_glued_markers(),
+ d.move_locked_markers(),
+ d.move_tempos()
+ );
+}
+
+void
+Editor::remove_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt,
+ bool ignore_music_glue, bool markers_too, bool glued_markers_too, bool locked_markers_too, bool tempo_too)
+{
+ if (Config->get_edit_mode() == Lock) {
+ error << (_("Cannot insert or delete time when in Lock edit.")) << endmsg;
+ return;
+ }
+ bool in_command = false;
+
+ for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
+ /* regions */
+ boost::shared_ptr<Playlist> pl = (*x)->playlist();
+
+ if (pl) {
+
+ XMLNode &before = pl->get_state();
+
+ std::list<AudioRange> rl;
+ AudioRange ar(pos, pos+frames, 0);
+ rl.push_back(ar);
+ pl->cut (rl);
+ pl->shift (pos, -frames, true, ignore_music_glue);
+
+ if (!in_command) {
+ begin_reversible_command (_("remove time"));
+ in_command = true;
+ }
+ XMLNode &after = pl->get_state();
+
+ _session->add_command (new MementoCommand<Playlist> (*pl, &before, &after));
+ }
+
+ /* automation */
+ RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (*x);
+ if (rtav) {
+ if (!in_command) {
+ begin_reversible_command (_("remove time"));
+ in_command = true;
+ }
+ rtav->route ()->shift (pos, -frames);
+ }
+ }
+
+ std::list<Location*> loc_kill_list;
+
+ /* markers */
+ if (markers_too) {
+ bool moved = false;
+ XMLNode& before (_session->locations()->get_state());
+ Locations::LocationList copy (_session->locations()->list());
+
+ for (Locations::LocationList::iterator i = copy.begin(); i != copy.end(); ++i) {
+ if ((*i)->position_lock_style() == AudioTime || glued_markers_too) {
+
+ bool const was_locked = (*i)->locked ();
+ if (locked_markers_too) {
+ (*i)->unlock ();
+ }
+
+ if (!(*i)->is_mark()) { // it's a range; have to handle both start and end
+ if ((*i)->end() >= pos
+ && (*i)->end() < pos+frames
+ && (*i)->start() >= pos
+ && (*i)->end() < pos+frames) { // range is completely enclosed; kill it
+ moved = true;
+ loc_kill_list.push_back(*i);
+ } else { // only start or end is included, try to do the right thing
+ // move start before moving end, to avoid trying to move the end to before the start
+ // if we're removing more time than the length of the range
+ if ((*i)->start() >= pos && (*i)->start() < pos+frames) {
+ // start is within cut
+ (*i)->set_start (pos); // bring the start marker to the beginning of the cut
+ moved = true;
+ } else if ((*i)->start() >= pos+frames) {
+ // start (and thus entire range) lies beyond end of cut
+ (*i)->set_start ((*i)->start() - frames); // slip the start marker back
+ moved = true;
+ }
+ if ((*i)->end() >= pos && (*i)->end() < pos+frames) {
+ // end is inside cut
+ (*i)->set_end (pos); // bring the end to the cut
+ moved = true;
+ } else if ((*i)->end() >= pos+frames) {
+ // end is beyond end of cut
+ (*i)->set_end ((*i)->end() - frames); // slip the end marker back
+ moved = true;
+ }
+
+ }
+ } else if ((*i)->start() >= pos && (*i)->start() < pos+frames ) {
+ loc_kill_list.push_back(*i);
+ moved = true;
+ } else if ((*i)->start() >= pos) {
+ (*i)->set_start ((*i)->start() -frames);
+ moved = true;
+ }
+
+ if (was_locked) {
+ (*i)->lock ();
+ }
+ }
+ }
+
+ for (list<Location*>::iterator i = loc_kill_list.begin(); i != loc_kill_list.end(); ++i) {
+ _session->locations()->remove( *i );