#include "editor_regions.h"
#include "editor_routes.h"
#include "gui_thread.h"
-#include "insert_time_dialog.h"
+#include "insert_remove_time_dialog.h"
#include "interthread_progress_window.h"
#include "item_counts.h"
#include "keyboard.h"
commit_reversible_command ();
}
+void
+Editor::set_session_start_from_playhead ()
+{
+ if (!_session)
+ return;
+
+ Location* loc;
+ if ((loc = _session->locations()->session_range_location()) == 0) { //should never happen
+ _session->set_session_extents ( _session->audible_frame(), _session->audible_frame() );
+ } else {
+ XMLNode &before = loc->get_state();
+
+ _session->set_session_extents ( _session->audible_frame(), loc->end() );
+
+ XMLNode &after = loc->get_state();
+
+ begin_reversible_command (_("Set session start"));
+
+ _session->add_command (new MementoCommand<Location>(*loc, &before, &after));
+
+ commit_reversible_command ();
+ }
+}
+
+void
+Editor::set_session_end_from_playhead ()
+{
+ if (!_session)
+ return;
+
+ Location* loc;
+ if ((loc = _session->locations()->session_range_location()) == 0) { //should never happen
+ _session->set_session_extents ( _session->audible_frame(), _session->audible_frame() );
+ } else {
+ XMLNode &before = loc->get_state();
+
+ _session->set_session_extents ( loc->start(), _session->audible_frame() );
+
+ XMLNode &after = loc->get_state();
+
+ begin_reversible_command (_("Set session start"));
+
+ _session->add_command (new MementoCommand<Location>(*loc, &before, &after));
+
+ commit_reversible_command ();
+ }
+}
+
void
Editor::add_location_from_playhead_cursor ()
{
framepos_t start_frame;
framepos_t return_frame;
- start_frame = get_preferred_edit_position (true);
+ start_frame = get_preferred_edit_position ( EDIT_IGNORE_PHEAD );
if (_session->transport_rolling()) {
_session->request_locate (start_frame, false);
{
DEBUG_TRACE (DEBUG::CutNPaste, "paste to preferred edit pos\n");
- paste_internal (get_preferred_edit_position (false, from_context), times);
+ paste_internal (get_preferred_edit_position (EDIT_IGNORE_NONE, from_context), times);
}
void
return;
}
- QuantizeDialog* qd = new QuantizeDialog (*this);
+ if (!quantize_dialog) {
+ quantize_dialog = new QuantizeDialog (*this);
+ }
- qd->present ();
- const int r = qd->run ();
- qd->hide ();
+ quantize_dialog->present ();
+ const int r = quantize_dialog->run ();
+ quantize_dialog->hide ();
if (r == Gtk::RESPONSE_OK) {
- Quantize quant (qd->snap_start(), qd->snap_end(),
- qd->start_grid_size(), qd->end_grid_size(),
- qd->strength(), qd->swing(), qd->threshold());
+ Quantize quant (quantize_dialog->snap_start(),
+ quantize_dialog->snap_end(),
+ quantize_dialog->start_grid_size(),
+ quantize_dialog->end_grid_size(),
+ quantize_dialog->strength(),
+ quantize_dialog->swing(),
+ quantize_dialog->threshold());
apply_midi_note_edit_op (quant, rs);
}
return;
}
- const framepos_t p = get_preferred_edit_position (false, from_context);
+ const framepos_t p = get_preferred_edit_position (EDIT_IGNORE_NONE, from_context);
/* XXX: bit of a hack; use the MIDNAM from the first selected region;
there may be more than one, but the PatchChangeDialog can only offer
if (!get_selection_extents ( start, end))
return;
- begin_reversible_command (_("set session start/end from selection"));
-
Location* loc;
if ((loc = _session->locations()->session_range_location()) == 0) {
_session->set_session_extents ( start, end ); // this will create a new session range; no need for UNDO
XMLNode &after = loc->get_state();
+ begin_reversible_command (_("set session start/end from selection"));
+
_session->add_command (new MementoCommand<Location>(*loc, &before, &after));
commit_reversible_command ();
return;
}
- InsertTimeDialog d (*this);
+ InsertRemoveTimeDialog d (*this);
int response = d.run ();
if (response != RESPONSE_OK) {
Locations::LocationList::const_iterator tmp;
- bool const was_locked = (*i)->locked ();
- if (locked_markers_too) {
- (*i)->unlock ();
- }
-
if ((*i)->position_lock_style() == AudioTime || glued_markers_too) {
+ bool const was_locked = (*i)->locked ();
+ if (locked_markers_too) {
+ (*i)->unlock ();
+ }
if ((*i)->start() >= pos) {
- (*i)->set_start ((*i)->start() + frames);
+ // move end first, in case we're moving by more than the length of the range
if (!(*i)->is_mark()) {
(*i)->set_end ((*i)->end() + frames);
}
+ (*i)->set_start ((*i)->start() + frames);
moved = true;
}
- }
-
- if (was_locked) {
- (*i)->lock ();
+ if (was_locked) {
+ (*i)->lock ();
+ }
}
}
}
}
+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)
+{
+ bool commit = false;
+
+ if (Config->get_edit_mode() == Lock) {
+ error << (_("Cannot insert or delete time when in Lock edit.")) << endmsg;
+ return;
+ }
+
+ begin_reversible_command (_("cut time"));
+
+ 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);
+
+ XMLNode &after = pl->get_state();
+
+ _session->add_command (new MementoCommand<Playlist> (*pl, &before, &after));
+ commit = true;
+ }
+
+ /* automation */
+ RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (*x);
+ if (rtav) {
+ rtav->route ()->shift (pos, -frames);
+ commit = true;
+ }
+ }
+
+ 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 );
+ }
+
+ if (moved) {
+ XMLNode& after (_session->locations()->get_state());
+ _session->add_command (new MementoCommand<Locations>(*_session->locations(), &before, &after));
+ commit = true;
+ }
+ }
+
+ if (tempo_too) {
+ XMLNode& before (_session->tempo_map().get_state());
+
+ if (_session->tempo_map().remove_time (pos, frames) ) {
+ XMLNode& after (_session->tempo_map().get_state());
+ _session->add_command (new MementoCommand<TempoMap>(_session->tempo_map(), &before, &after));
+ commit = true;
+ }
+ }
+
+ if (commit) {
+ commit_reversible_command ();
+ }
+}
+
void
Editor::fit_selection ()
{
lock_dialog->get_vbox()->show_all ();
lock_dialog->set_size_request (200, 200);
}
+
+ delete _main_menu_disabler;
+ _main_menu_disabler = new MainMenuDisabler;
-#ifdef __APPLE__
- /* The global menu bar continues to be accessible to applications
- with modal dialogs, which means that we need to desensitize
- all items in the menu bar. Since those items are really just
- proxies for actions, that means disabling all actions.
- */
- ActionManager::disable_all_actions ();
-#endif
lock_dialog->present ();
}
{
lock_dialog->hide ();
-#ifdef __APPLE__
- ActionManager::pop_action_state ();
-#endif
+ delete _main_menu_disabler;
if (ARDOUR_UI::config()->get_lock_gui_after_seconds()) {
start_lock_event_timing ();