#include "ardour/legatize.h"
#include "ardour/region_factory.h"
#include "ardour/reverse.h"
+#include "ardour/selection.h"
#include "ardour/session.h"
#include "ardour/session_playlists.h"
#include "ardour/strip_silence.h"
#include "ardour/transient_detector.h"
+#include "ardour/transport_master_manager.h"
#include "ardour/transpose.h"
#include "ardour/vca_manager.h"
#include "canvas/canvas.h"
#include "actions.h"
+#include "ardour_ui.h"
#include "audio_region_view.h"
#include "audio_streamview.h"
#include "audio_time_axis.h"
}
void
-Editor::split_regions_at (MusicSample where, RegionSelection& regions, bool snap_sample)
+Editor::split_regions_at (MusicSample where, RegionSelection& regions)
{
bool frozen = false;
begin_reversible_command (_("split"));
- // if splitting a single region, and snap-to is using
- // region boundaries, don't pay attention to them
if (regions.size() == 1) {
- switch (_snap_type) {
- case SnapToRegionStart:
- case SnapToRegionSync:
- case SnapToRegionEnd:
- break;
- default:
- if (snap_sample) {
- snap_to (where);
- }
- }
+ /* TODO: if splitting a single region, and snap-to is using
+ region boundaries, mabye we shouldn't pay attention to them? */
} else {
- if (snap_sample) {
- snap_to (where);
- }
-
frozen = true;
EditorFreeze(); /* Emit Signal */
}
if (rsas & Existing) {
// region selections that existed before the split.
- selection->add ( pre_selected_regions );
+ selection->add (pre_selected_regions);
}
for (RegionSelection::iterator ri = latest_regionviews.begin(); ri != latest_regionviews.end(); ri++) {
}
}
}
- } else {
- if( working_on_selection ) {
- selection->add (latest_regionviews); //these are the new regions created after the split
- }
}
commit_reversible_command ();
void
Editor::build_region_boundary_cache ()
{
+
+ /* TODO: maybe set a timer so we don't recalutate when lots of changes are coming in */
+ /* TODO: maybe somehow defer this until session is fully loaded. */
+
+ if (!_region_boundary_cache_dirty)
+ return;
+
samplepos_t pos = 0;
vector<RegionPoint> interesting_points;
boost::shared_ptr<Region> r;
bool maybe_first_sample = false;
- switch (_snap_type) {
- case SnapToRegionStart:
+ if (UIConfiguration::instance().get_snap_to_region_start()) {
interesting_points.push_back (Start);
maybe_first_sample = true;
- break;
- case SnapToRegionEnd:
+ }
+
+ if (UIConfiguration::instance().get_snap_to_region_end()) {
interesting_points.push_back (End);
- break;
- case SnapToRegionSync:
+ }
+
+ if (UIConfiguration::instance().get_snap_to_region_sync()) {
interesting_points.push_back (SyncPoint);
- break;
- case SnapToRegionBoundary:
- interesting_points.push_back (Start);
- interesting_points.push_back (End);
- maybe_first_sample = true;
- break;
- default:
- fatal << string_compose (_("build_region_boundary_cache called with snap_type = %1"), _snap_type) << endmsg;
- abort(); /*NOTREACHED*/
+ }
+
+ /* if no snap selections are set, boundary cache should be left empty */
+ if ( interesting_points.empty() ) {
+ _region_boundary_cache_dirty = false;
return;
}
TimeAxisView *ontrack = 0;
TrackViewList tlist;
- if (!selection->tracks.empty()) {
- tlist = selection->tracks.filter_to_unique_playlists ();
- } else {
- tlist = track_views.filter_to_unique_playlists ();
- }
+ tlist = track_views.filter_to_unique_playlists ();
if (maybe_first_sample) {
TrackViewList::const_iterator i;
}
}
- while (pos < _session->current_end_sample() && !at_end) {
+ //allow regions to snap to the video start (if any) as if it were a "region"
+ if (ARDOUR_UI::instance()->video_timeline) {
+ region_boundary_cache.push_back (ARDOUR_UI::instance()->video_timeline->get_video_start_offset());
+ }
+
+ std::pair<samplepos_t, samplepos_t> ext = session_gui_extents (false);
+ samplepos_t session_end = ext.second;
+
+ while (pos < session_end && !at_end) {
samplepos_t rpos;
- samplepos_t lpos = max_samplepos;
+ samplepos_t lpos = session_end;
for (vector<RegionPoint>::iterator p = interesting_points.begin(); p != interesting_points.end(); ++p) {
/* finally sort to be sure that the order is correct */
sort (region_boundary_cache.begin(), region_boundary_cache.end());
+
+ _region_boundary_cache_dirty = false;
}
boost::shared_ptr<Region>
//zoom-behavior-tweaks
//limit our maximum zoom to the session gui extents value
std::pair<samplepos_t, samplepos_t> ext = session_gui_extents();
- samplecnt_t session_extents_pp = ( ext.second - ext.first ) / _visible_canvas_width;
+ samplecnt_t session_extents_pp = (ext.second - ext.first) / _visible_canvas_width;
if (nspp > session_extents_pp)
nspp = session_extents_pp;
//ToDo: if control points are selected, set extents to that selection
- if ( !selection->regions.empty() ) {
+ if (!selection->regions.empty()) {
RegionSelection rs = get_regions_from_selection_and_entered ();
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
{
if (!selection) return;
+ if (selection->regions.empty() && selection->time.empty()) {
+ if (axes == Horizontal || axes == Both) {
+ temporal_zoom_step(true);
+ }
+ if (axes == Vertical || axes == Both) {
+ if (!track_views.empty()) {
+
+ TrackViewList tvl;
+
+ //implicit hack: by extending the top & bottom check outside the current view limits, we include the trackviews immediately above & below what is visible
+ const double top = vertical_adjustment.get_value() - 10;
+ const double btm = top + _visible_canvas_height + 10;
+
+ for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+ if ((*iter)->covered_by_y_range (top, btm)) {
+ tvl.push_back(*iter);
+ }
+ }
+
+ fit_tracks (tvl);
+ }
+ }
+ return;
+ }
+
//ToDo: if notes are selected, zoom to that
//ToDo: if control points are selected, zoom to that
if (axes == Vertical || axes == Both) {
fit_selection ();
}
+
+ //normally, we don't do anything "automatic" to the user's selection.
+ //but in this case, we will clear the selection after a zoom-to-selection.
+ selection->clear();
}
void
samplecnt_t start = _session->current_start_sample();
samplecnt_t end = _session->current_end_sample();
- if (_session->actively_recording () ) {
+ if (_session->actively_recording ()) {
samplepos_t cur = playhead_cursor->current_sample ();
if (cur > end) {
/* recording beyond the end marker; zoom out
ENSURE_GUI_THREAD (*this, &Editor::temporal_zoom_extents)
if (_session) {
- std::pair<samplepos_t, samplepos_t> ext = session_gui_extents( false ); //in this case we want to zoom to the extents explicitly; ignore the users prefs for extra padding
+ std::pair<samplepos_t, samplepos_t> ext = session_gui_extents (false); //in this case we want to zoom to the extents explicitly; ignore the users prefs for extra padding
samplecnt_t start = ext.first;
samplecnt_t end = ext.second;
- if (_session->actively_recording () ) {
+ if (_session->actively_recording ()) {
samplepos_t cur = playhead_cursor->current_sample ();
if (cur > end) {
/* recording beyond the end marker; zoom out
Location* loc;
if ((loc = _session->locations()->session_range_location()) == 0) { //should never happen
- _session->set_session_extents ( _session->audible_sample(), _session->audible_sample() );
+ _session->set_session_extents (_session->audible_sample(), _session->audible_sample());
} else {
XMLNode &before = loc->get_state();
- _session->set_session_extents ( _session->audible_sample(), loc->end() );
+ _session->set_session_extents (_session->audible_sample(), loc->end());
XMLNode &after = loc->get_state();
Location* loc;
if ((loc = _session->locations()->session_range_location()) == 0) { //should never happen
- _session->set_session_extents ( _session->audible_sample(), _session->audible_sample() );
+ _session->set_session_extents (_session->audible_sample(), _session->audible_sample());
} else {
XMLNode &before = loc->get_state();
- _session->set_session_extents ( loc->start(), _session->audible_sample() );
+ _session->set_session_extents (loc->start(), _session->audible_sample());
XMLNode &after = loc->get_state();
samplepos_t pos = _session->locations()->first_mark_before (playhead_cursor->current_sample());
//handle the case where we are rolling, and we're less than one-half second past the mark, we want to go to the prior mark...
- if ( _session->transport_rolling() ) {
- if ( (playhead_cursor->current_sample() - pos) < _session->sample_rate()/2 ) {
- samplepos_t prior = _session->locations()->first_mark_before ( pos );
+ if (_session->transport_rolling()) {
+ if ((playhead_cursor->current_sample() - pos) < _session->sample_rate()/2) {
+ samplepos_t prior = _session->locations()->first_mark_before (pos);
pos = prior;
}
}
}
if (_session->config.get_external_sync()) {
- switch (Config->get_sync_source()) {
+ switch (TransportMasterManager::instance().current()->type()) {
case Engine:
break;
default:
samplepos_t start_sample;
samplepos_t return_sample;
- start_sample = get_preferred_edit_position ( EDIT_IGNORE_PHEAD );
+ start_sample = get_preferred_edit_position (EDIT_IGNORE_PHEAD);
if (_session->transport_rolling()) {
_session->request_locate (start_sample, false);
Editor::play_selection ()
{
samplepos_t start, end;
- if (!get_selection_extents ( start, end))
+ if (!get_selection_extents (start, end))
return;
AudioRange ar (start, end, 0);
void
Editor::maybe_locate_with_edit_preroll (samplepos_t location)
{
- if ( _session->transport_rolling() || !UIConfiguration::instance().get_follow_edits() || _session->config.get_external_sync() )
+ if (_session->transport_rolling() || !UIConfiguration::instance().get_follow_edits() || _session->config.get_external_sync())
return;
location -= _session->preroll_samples (location);
}
//if follow_playhead is on, keep the playhead on the screen
- if ( _follow_playhead )
- if ( location < _leftmost_sample )
+ if (_follow_playhead)
+ if (location < _leftmost_sample)
location = _leftmost_sample;
- _session->request_locate( location );
+ _session->request_locate (location);
}
void
Editor::play_with_preroll ()
{
samplepos_t start, end;
- if ( UIConfiguration::instance().get_follow_edits() && get_selection_extents ( start, end) ) {
+ if (UIConfiguration::instance().get_follow_edits() && get_selection_extents (start, end)) {
const samplepos_t preroll = _session->preroll_samples (start);
samplepos_t ret = start;
playlist->partition ((*rl)->first_sample() - 1, (*rl)->last_sample() + 1, true);
//Re-add region that was just removed due to the partition operation
- playlist->add_region( (*rl), (*rl)->first_sample() );
+ playlist->add_region ((*rl), (*rl)->first_sample());
}
vector<PlaylistState>::iterator pl;
//special case: if the user is pointing in the editor/mixer strip, they may be trying to delete a plugin.
//we need this because the editor-mixer strip is in the editor window, so it doesn't get the bindings from the mix window
bool deleted = false;
- if ( current_mixer_strip && current_mixer_strip == MixerStrip::entered_mixer_strip() )
+ if (current_mixer_strip && current_mixer_strip == MixerStrip::entered_mixer_strip())
deleted = current_mixer_strip->delete_processors ();
if (!deleted)
}
}
- if ( op != Delete ) { //"Delete" doesn't change copy/paste buf
+ if (op != Delete) { //"Delete" doesn't change copy/paste buf
cut_buffer->clear ();
}
DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("preferred edit position is %1\n", position));
}
- if (position == last_paste_pos) {
- /* repeated paste in the same position */
- ++paste_count;
- } else {
+ if (position != last_paste_pos) {
/* paste in new location, reset repeated paste state */
paste_count = 0;
last_paste_pos = position;
}
}
+ ++paste_count;
+
commit_reversible_command ();
}
}
boost::shared_ptr<Playlist> playlist;
+ std::set<boost::shared_ptr<Playlist> > playlists; // list of unique playlists affected by duplication
RegionSelection sel = regions; // clear (below) may clear the argument list if its the current region selection
RegionSelection foo;
samplepos_t const start_sample = regions.start ();
samplepos_t const end_sample = regions.end_sample ();
- samplecnt_t const gap = end_sample - start_sample + 1;
+ samplecnt_t const span = end_sample - start_sample + 1;
begin_reversible_command (Operations::duplicate_region);
selection->clear_regions ();
+ /* ripple first so that we don't move the duplicates that will be added */
+
+ if (Config->get_edit_mode() == Ripple) {
+
+ /* convert RegionSelection into RegionList so that we can pass it to ripple and exclude the regions we will duplicate */
+
+ RegionList exclude;
+
+ for (RegionSelection::iterator i = sel.begin(); i != sel.end(); ++i) {
+ exclude.push_back ((*i)->region());
+ playlist = (*i)->region()->playlist();
+ if (playlists.insert (playlist).second) {
+ /* successfully inserted into set, so it's the first time we've seen this playlist */
+ playlist->clear_changes ();
+ }
+ }
+
+ for (set<boost::shared_ptr<Playlist> >::iterator p = playlists.begin(); p != playlists.end(); ++p) {
+ (*p)->ripple (start_sample, span * times, &exclude);
+ }
+ }
+
for (RegionSelection::iterator i = sel.begin(); i != sel.end(); ++i) {
boost::shared_ptr<Region> r ((*i)->region());
samplepos_t const position = end_sample + (r->first_sample() - start_sample + 1);
playlist = (*i)->region()->playlist();
- playlist->clear_changes ();
- playlist->duplicate (r, position, gap, times);
- _session->add_command(new StatefulDiffCommand (playlist));
+
+ if (Config->get_edit_mode() != Ripple) {
+ if (playlists.insert (playlist).second) {
+ playlist->clear_changes ();
+ }
+ }
+
+ playlist->duplicate (r, position, span, times);
c.disconnect ();
foo.insert (foo.end(), latest_regionviews.begin(), latest_regionviews.end());
}
+ for (set<boost::shared_ptr<Playlist> >::iterator p = playlists.begin(); p != playlists.end(); ++p) {
+ _session->add_command (new StatefulDiffCommand (*p));
+ vector<Command*> cmds;
+ (*p)->rdiff (cmds);
+ _session->add_commands (cmds);
+ }
+
if (!foo.empty()) {
selection->set (foo);
}
}
}
+StripableList
+tracklist_to_stripables (TrackViewList list)
+{
+ StripableList ret;
+
+ for (TrackSelection::iterator i = list.begin(); i != list.end(); ++i) {
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> ((*i));
+
+ if (rtv && rtv->is_track()) {
+ ret.push_back (rtv->track());
+ }
+ }
+
+ return ret;
+}
+
+void
+Editor::play_solo_selection (bool restart)
+{
+ //note: session::solo_selection takes care of invalidating the region playlist
+
+ if ((!selection->tracks.empty()) && selection->time.length() > 0) { //a range is selected; solo the tracks and roll
+
+ StripableList sl = tracklist_to_stripables (selection->tracks);
+ _session->solo_selection (sl, true);
+
+ if (restart) {
+ samplepos_t start = selection->time.start();
+ samplepos_t end = selection->time.end_sample();
+ _session->request_bounded_roll (start, end);
+ }
+ } else if (! selection->tracks.empty()) { //no range is selected, but tracks are selected; solo the tracks and roll
+ StripableList sl = tracklist_to_stripables (selection->tracks);
+ _session->solo_selection (sl, true);
+ _session->request_cancel_play_range();
+ transition_to_rolling (true);
+
+ } else if (! selection->regions.empty()) { //solo any tracks with selected regions, and roll
+ StripableList sl = tracklist_to_stripables (get_tracks_for_range_action());
+ _session->solo_selection (sl, true);
+ _session->request_cancel_play_range();
+ transition_to_rolling (true);
+ } else {
+ _session->request_cancel_play_range();
+ transition_to_rolling (true); //no selection. just roll.
+ }
+}
+
void
Editor::toggle_solo ()
{
void
Editor::split_region ()
{
- if (_drags->active ()) {
+ if (_dragging_playhead) {
+ /*continue*/
+ } else if (_drags->active ()) {
+ /*any other kind of drag, bail out so we avoid Undo snafu*/
return;
}
//if a range is selected, separate it
- if ( !selection->time.empty()) {
+ if (!selection->time.empty()) {
separate_regions_between (selection->time);
return;
}
//if no range was selected, try to find some regions to split
- if (current_mouse_mode() == MouseObject) { //don't try this for Internal Edit, Stretch, Draw, etc.
+ if (current_mouse_mode() == MouseObject || current_mouse_mode() == MouseRange ) { //don't try this for Internal Edit, Stretch, Draw, etc.
RegionSelection rs = get_regions_from_selection_and_edit_point ();
const samplepos_t pos = get_preferred_edit_position();
void
Editor::select_next_stripable (bool routes_only)
{
- if (selection->tracks.empty()) {
- selection->set (track_views.front());
- return;
- }
-
- TimeAxisView* current = selection->tracks.front();
-
- bool valid;
- do {
- for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-
- if (*i == current) {
- ++i;
- if (i != track_views.end()) {
- current = (*i);
- } else {
- current = (*(track_views.begin()));
- //selection->set (*(track_views.begin()));
- }
- break;
- }
- }
-
- if (routes_only) {
- RouteUI* rui = dynamic_cast<RouteUI *>(current);
- valid = rui && rui->route()->active();
- } else {
- valid = 0 != current->stripable ().get();
- }
-
- } while (current->hidden() || !valid);
-
- selection->set (current);
-
- ensure_time_axis_view_is_visible (*current, false);
+ _session->selection().select_next_stripable (false, routes_only);
}
void
Editor::select_prev_stripable (bool routes_only)
{
- if (selection->tracks.empty()) {
- selection->set (track_views.front());
- return;
- }
-
- TimeAxisView* current = selection->tracks.front();
-
- bool valid;
- do {
- for (TrackViewList::reverse_iterator i = track_views.rbegin(); i != track_views.rend(); ++i) {
-
- if (*i == current) {
- ++i;
- if (i != track_views.rend()) {
- current = (*i);
- } else {
- current = *(track_views.rbegin());
- }
- break;
- }
- }
- if (routes_only) {
- RouteUI* rui = dynamic_cast<RouteUI *>(current);
- valid = rui && rui->route()->active();
- } else {
- valid = 0 != current->stripable ().get();
- }
-
- } while (current->hidden() || !valid);
-
- selection->set (current);
-
- ensure_time_axis_view_is_visible (*current, false);
+ _session->selection().select_prev_stripable (false, routes_only);
}
void
}
samplepos_t start, end;
- if (!get_selection_extents ( start, end))
+ if (!get_selection_extents (start, end))
return;
set_loop_range (start, end, _("set loop range from selection"));
Editor::set_loop_from_region (bool play)
{
samplepos_t start, end;
- if (!get_selection_extents ( start, end))
+ if (!get_selection_extents (start, end))
return;
set_loop_range (start, end, _("set loop range from region"));
}
samplepos_t start, end;
- if (!get_selection_extents ( start, end))
+ if (!get_selection_extents (start, end))
return;
set_punch_range (start, end, _("set punch range from selection"));
}
samplepos_t start, end;
- if (!get_selection_extents ( start, end))
+ if (!get_selection_extents (start, end))
return;
Location* loc;
start.sample = get_preferred_edit_position();
}
- //snap the selection start/end
- snap_to(start);
-
//if there's not already a sensible selection endpoint, go "forever"
- if (start.sample > end ) {
+ if (start.sample > end) {
end = max_samplepos;
}
end.sample = get_preferred_edit_position();
}
- //snap the selection start/end
- snap_to (end);
-
set_punch_range (start, end.sample, _("set punch end from EP"));
}
start.sample = get_preferred_edit_position();
}
- //snap the selection start/end
- snap_to (start);
-
//if there's not already a sensible selection endpoint, go "forever"
- if (start.sample > end ) {
+ if (start.sample > end) {
end = max_samplepos;
}
end.sample = get_preferred_edit_position();
}
- //snap the selection start/end
- snap_to(end);
-
set_loop_range (start, end.sample, _("set loop end from EP"));
}
}
Editor::set_punch_from_region ()
{
samplepos_t start, end;
- if (!get_selection_extents ( start, end))
+ if (!get_selection_extents (start, end))
return;
set_punch_range (start, end, _("set punch range from region"));
(*r)->region()->clear_changes ();
MusicSample start ((*r)->region()->first_sample (), 0);
- snap_to (start);
+ snap_to (start, RoundNearest, SnapToGrid_Unscaled, true);
(*r)->region()->set_position (start.sample, start.division);
_session->add_command(new StatefulDiffCommand ((*r)->region()));
}
}
(*r)->region()->clear_changes ();
- (*r)->region()->trim_front( (position - pull_back_samples));
+ (*r)->region()->trim_front((position - pull_back_samples));
last_region->clear_changes ();
- last_region->trim_end( (position - pull_back_samples + crossfade_len));
+ last_region->trim_end ((position - pull_back_samples + crossfade_len));
_session->add_command (new StatefulDiffCommand ((*r)->region()));
_session->add_command (new StatefulDiffCommand (last_region));
return;
}
- MusicSample pos (playhead_cursor->current_sample (), 0);
+ MusicSample pos (playhead_cursor->current_sample (), 0);
- if (pos.sample < max_samplepos - 1) {
- pos.sample += 2;
- snap_to_internal (pos, RoundUpAlways, false, true);
- _session->request_locate (pos.sample);
+ if ( _grid_type == GridTypeNone) {
+ if (pos.sample < max_samplepos - current_page_samples()*0.1) {
+ pos.sample += current_page_samples()*0.1;
+ _session->request_locate (pos.sample);
+ } else {
+ _session->request_locate (0);
+ }
+ } else {
+
+ if (pos.sample < max_samplepos - 1) {
+ pos.sample += 2;
+ pos = snap_to_grid (pos, RoundUpAlways, SnapToGrid_Scaled);
+ _session->request_locate (pos.sample);
+ }
+ }
+
+
+ /* keep PH visible in window */
+ if (pos.sample > (_leftmost_sample + current_page_samples() *0.9)) {
+ reset_x_origin (pos.sample - (current_page_samples()*0.9));
}
}
MusicSample pos (playhead_cursor->current_sample (), 0);
- if (pos.sample > 2) {
- pos.sample -= 2;
- snap_to_internal (pos, RoundDownAlways, false, true);
- _session->request_locate (pos.sample);
+ if ( _grid_type == GridTypeNone) {
+ if ( pos.sample > current_page_samples()*0.1 ) {
+ pos.sample -= current_page_samples()*0.1;
+ _session->request_locate (pos.sample);
+ } else {
+ _session->request_locate (0);
+ }
+ } else {
+
+ if (pos.sample > 2) {
+ pos.sample -= 2;
+ pos = snap_to_grid (pos, RoundDownAlways, SnapToGrid_Scaled);
+ }
+
+ //handle the case where we are rolling, and we're less than one-half second past the mark, we want to go to the prior mark...
+ //also see: jump_backward_to_mark
+ if (_session->transport_rolling()) {
+ if ((playhead_cursor->current_sample() - pos.sample) < _session->sample_rate()/2) {
+ pos = snap_to_grid (pos, RoundDownAlways, SnapToGrid_Scaled);
+ }
+ }
+
+ _session->request_locate (pos.sample, _session->transport_rolling());
+ }
+
+ /* keep PH visible in window */
+ if (pos.sample < (_leftmost_sample + current_page_samples() *0.1)) {
+ reset_x_origin (pos.sample - (current_page_samples()*0.1));
}
}
/* Route deletion calls Editor::timeaxisview_deleted() iteratively (for each deleted
* route). If the deleted route is currently displayed in the Editor-Mixer (highly
* likely because deletion requires selection) this will call
- * Editor::set_selected_mixer_strip () which is expensive ( MixerStrip::set_route() ).
+ * Editor::set_selected_mixer_strip () which is expensive (MixerStrip::set_route()).
* It's likewise likely that the route that has just been displayed in the
* Editor-Mixer will be next in line for deletion.
*
Editor::do_insert_time ()
{
if (selection->tracks.empty()) {
+ MessageDialog msg (_("You must first select some tracks to Insert Time."),
+ true, MESSAGE_INFO, BUTTONS_OK, true);
+ msg.set_position (WIN_POS_MOUSE);
+ msg.run ();
+ return;
+ }
+
+ if (Config->get_edit_mode() == Lock) {
+ MessageDialog msg (_("You cannot insert time in Lock Edit mode."),
+ true, MESSAGE_INFO, BUTTONS_OK, true);
+ msg.set_position (WIN_POS_MOUSE);
+ msg.run ();
return;
}
Editor::do_remove_time ()
{
if (selection->tracks.empty()) {
+ MessageDialog msg (_("You must first select some tracks to Remove Time."),
+ true, MESSAGE_INFO, BUTTONS_OK, true);
+ msg.set_position (WIN_POS_MOUSE);
+ msg.run ();
+ return;
+ }
+
+ if (Config->get_edit_mode() == Lock) {
+ MessageDialog msg (_("You cannot remove time in Lock Edit mode."),
+ true, MESSAGE_INFO, BUTTONS_OK, true);
+ msg.set_position (WIN_POS_MOUSE);
+ msg.run ();
return;
}
}
}
- } else if ((*i)->start() >= pos && (*i)->start() < pos+samples ) {
+ } else if ((*i)->start() >= pos && (*i)->start() < pos+samples) {
loc_kill_list.push_back(*i);
moved = true;
} else if ((*i)->start() >= pos) {
}
for (list<Location*>::iterator i = loc_kill_list.begin(); i != loc_kill_list.end(); ++i) {
- _session->locations()->remove( *i );
+ _session->locations()->remove (*i);
}
if (moved) {
if (tempo_too) {
XMLNode& before (_session->tempo_map().get_state());
- if (_session->tempo_map().remove_time (pos, samples) ) {
+ if (_session->tempo_map().remove_time (pos, samples)) {
if (!in_command) {
begin_reversible_command (_("remove time"));
in_command = true;