#include <cstdlib>
#include "pbd/stacktrace.h"
+#include "pbd/unwind.h"
+#include "ardour/control_protocol_manager.h"
#include "ardour/midi_region.h"
#include "ardour/playlist.h"
#include "ardour/profile.h"
#include "ardour/route_group.h"
+#include "ardour/selection.h"
#include "ardour/session.h"
+#include "ardour/vca.h"
-#include "control_protocol/control_protocol.h"
-
-#include "editor_drag.h"
#include "editor.h"
+#include "editor_drag.h"
+#include "editor_routes.h"
#include "actions.h"
#include "audio_time_axis.h"
#include "audio_region_view.h"
sorted.sort (cmp);
- if (!selection->selected (&view)) {
- to_be_added.push_back (&view);
- }
-
/* figure out if we should go forward or backwards */
for (TrackViewList::iterator i = sorted.begin(); i != sorted.end(); ++i) {
}
}
+ if (!selection->selected (&view)) {
+ to_be_added.push_back (&view);
+ }
+
if (!to_be_added.empty()) {
selection->add (to_be_added);
return true;
visible_views.push_back (*i);
}
}
+ PBD::Unwinder<bool> uw (_track_selection_change_without_scroll, true);
selection->set (visible_views);
}
return;
}
+ PBD::Unwinder<bool> uw (_editor_track_selection_change_without_scroll, true);
+
RouteGroup* group = NULL;
if (clicked_routeview) {
group = clicked_routeview->route()->route_group();
break;
case Selection::Add:
- if (!selection->selected (&view)) {
- selection->add (&view);
- }
+ selection->add (&view);
break;
case Selection::Set:
RouteGroup* group = route_basis->route()->route_group();
- if (group && group->enabled_property(prop) && group->enabled_property (Properties::active.property_id) ) {
+ if (group && group->enabled_property(prop) && group->enabled_property (Properties::active.property_id)) {
/* the basis is a member of an active route group, with the appropriate
properties; find other members */
RouteGroup* group = route_basis->route()->route_group(); // could be null, not a problem
- if (group && group->enabled_property(prop) && group->enabled_property (Properties::active.property_id) ) {
+ if (group && group->enabled_property(prop) && group->enabled_property (Properties::active.property_id)) {
/* the basis is a member of an active route group, with the appropriate
properties; find other members */
} else if (op == Selection::Extend) {
list<Selectable*> results;
- framepos_t last_frame;
- framepos_t first_frame;
+ samplepos_t last_sample;
+ samplepos_t first_sample;
bool same_track = false;
/* 1. find the last selected regionview in the track that was clicked in */
- last_frame = 0;
- first_frame = max_framepos;
+ last_sample = 0;
+ first_sample = max_samplepos;
for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
if (&(*x)->get_time_axis_view() == &clicked_regionview->get_time_axis_view()) {
- if ((*x)->region()->last_frame() > last_frame) {
- last_frame = (*x)->region()->last_frame();
+ if ((*x)->region()->last_sample() > last_sample) {
+ last_sample = (*x)->region()->last_sample();
}
- if ((*x)->region()->first_frame() < first_frame) {
- first_frame = (*x)->region()->first_frame();
+ if ((*x)->region()->first_sample() < first_sample) {
+ first_sample = (*x)->region()->first_sample();
}
same_track = true;
/* 2. figure out the boundaries for our search for new objects */
- switch (clicked_regionview->region()->coverage (first_frame, last_frame)) {
+ switch (clicked_regionview->region()->coverage (first_sample, last_sample)) {
case Evoral::OverlapNone:
- if (last_frame < clicked_regionview->region()->first_frame()) {
- first_frame = last_frame;
- last_frame = clicked_regionview->region()->last_frame();
+ if (last_sample < clicked_regionview->region()->first_sample()) {
+ first_sample = last_sample;
+ last_sample = clicked_regionview->region()->last_sample();
} else {
- last_frame = first_frame;
- first_frame = clicked_regionview->region()->first_frame();
+ last_sample = first_sample;
+ first_sample = clicked_regionview->region()->first_sample();
}
break;
case Evoral::OverlapExternal:
- if (last_frame < clicked_regionview->region()->first_frame()) {
- first_frame = last_frame;
- last_frame = clicked_regionview->region()->last_frame();
+ if (last_sample < clicked_regionview->region()->first_sample()) {
+ first_sample = last_sample;
+ last_sample = clicked_regionview->region()->last_sample();
} else {
- last_frame = first_frame;
- first_frame = clicked_regionview->region()->first_frame();
+ last_sample = first_sample;
+ first_sample = clicked_regionview->region()->first_sample();
}
break;
case Evoral::OverlapInternal:
- if (last_frame < clicked_regionview->region()->first_frame()) {
- first_frame = last_frame;
- last_frame = clicked_regionview->region()->last_frame();
+ if (last_sample < clicked_regionview->region()->first_sample()) {
+ first_sample = last_sample;
+ last_sample = clicked_regionview->region()->last_sample();
} else {
- last_frame = first_frame;
- first_frame = clicked_regionview->region()->first_frame();
+ last_sample = first_sample;
+ first_sample = clicked_regionview->region()->first_sample();
}
break;
*/
- first_frame = clicked_regionview->region()->position();
- last_frame = clicked_regionview->region()->last_frame();
+ first_sample = clicked_regionview->region()->position();
+ last_sample = clicked_regionview->region()->last_sample();
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
- if ((*i)->region()->position() < first_frame) {
- first_frame = (*i)->region()->position();
+ if ((*i)->region()->position() < first_sample) {
+ first_sample = (*i)->region()->position();
}
- if ((*i)->region()->last_frame() + 1 > last_frame) {
- last_frame = (*i)->region()->last_frame();
+ if ((*i)->region()->last_sample() + 1 > last_sample) {
+ last_sample = (*i)->region()->last_sample();
}
}
}
*/
for (set<RouteTimeAxisView*>::iterator t = relevant_tracks.begin(); t != relevant_tracks.end(); ++t) {
- (*t)->get_selectables (first_frame, last_frame, -1.0, -1.0, results);
+ (*t)->get_selectables (first_sample, last_sample, -1.0, -1.0, results);
}
/* 4. convert to a vector of regions */
return commit;
}
+void
+Editor::set_selection (std::list<Selectable*> s, Selection::Operation op)
+{
+ if (s.empty()) {
+ return;
+ }
+ begin_reversible_selection_op (X_("set selection"));
+ switch (op) {
+ case Selection::Toggle:
+ selection->toggle (s);
+ break;
+ case Selection::Set:
+ selection->set (s);
+ break;
+ case Selection::Extend:
+ selection->add (s);
+ break;
+ case Selection::Add:
+ selection->add (s);
+ break;
+ }
+
+ commit_reversible_selection_op () ;
+}
void
Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> region, Selection::Operation op)
return true;
}
+struct SelectionOrderSorter {
+ bool operator() (TimeAxisView const * const a, TimeAxisView const * const b) const {
+ boost::shared_ptr<Stripable> sa = a->stripable ();
+ boost::shared_ptr<Stripable> sb = b->stripable ();
+ if (!sa && !sb) {
+ return a < b;
+ }
+ if (!sa) {
+ return false;
+ }
+ if (!sb) {
+ return true;
+ }
+ return sa->presentation_info().selection_cnt() < sb->presentation_info().selection_cnt();
+ }
+};
+
void
-Editor::track_selection_changed ()
+Editor::presentation_info_changed (PropertyChange const & what_changed)
{
- switch (selection->tracks.size()) {
- case 0:
- break;
- default:
- set_selected_mixer_strip (*(selection->tracks.front()));
- break;
+ uint32_t n_tracks = 0;
+ uint32_t n_busses = 0;
+ uint32_t n_vcas = 0;
+ uint32_t n_routes = 0;
+ uint32_t n_stripables = 0;
+
+ /* We cannot ensure ordering of the handlers for
+ * PresentationInfo::Changed, so we have to do everything in order
+ * here, as a single handler.
+ */
+
+ if (what_changed.contains (Properties::selected)) {
+ for (TrackViewList::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+ (*i)->set_selected (false);
+ (*i)->hide_selection ();
+ }
}
- RouteNotificationListPtr routes (new RouteNotificationList);
- StripableNotificationListPtr stripables (new StripableNotificationList);
+ /* STEP 1: set the GUI selection state (in which TimeAxisViews for the
+ * currently selected stripable/controllable duples are found and added
+ */
- for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ selection->core_selection_changed (what_changed);
- bool yn = (find (selection->tracks.begin(), selection->tracks.end(), *i) != selection->tracks.end());
+ /* STEP 2: update TimeAxisView's knowledge of their selected state
+ */
- (*i)->set_selected (yn);
+ if (what_changed.contains (Properties::selected)) {
- TimeAxisView::Children c = (*i)->get_child_list ();
- for (TimeAxisView::Children::iterator j = c.begin(); j != c.end(); ++j) {
- (*j)->set_selected (find (selection->tracks.begin(), selection->tracks.end(), j->get()) != selection->tracks.end());
- }
+ StripableNotificationListPtr stripables (new StripableNotificationList);
- if (yn) {
- (*i)->reshow_selection (selection->time);
- } else {
- (*i)->hide_selection ();
+ switch (selection->tracks.size()) {
+ case 0:
+ break;
+ default:
+ set_selected_mixer_strip (*(selection->tracks.back()));
+ if (!_track_selection_change_without_scroll && !_editor_track_selection_change_without_scroll) {
+ ensure_time_axis_view_is_visible (*(selection->tracks.back()), false);
+ }
+ break;
}
+ CoreSelection::StripableAutomationControls sc;
+ _session->selection().get_stripables (sc);
- if (yn) {
- RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (*i);
- if (rtav) {
- routes->push_back (rtav->route());
- stripables->push_back (rtav->route());
+ for (CoreSelection::StripableAutomationControls::const_iterator i = sc.begin(); i != sc.end(); ++i) {
+
+ AxisView* av = axis_view_by_stripable ((*i).stripable);
+
+ if (!av) {
+ continue;
}
- }
- }
- ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, !selection->tracks.empty());
+ n_stripables++;
- /* notify control protocols */
+ if (boost::dynamic_pointer_cast<Track> ((*i).stripable)) {
+ n_tracks++;
+ n_routes++;
+ } else if (boost::dynamic_pointer_cast<Route> ((*i).stripable)) {
+ n_busses++;
+ n_routes++;
+ } else if (boost::dynamic_pointer_cast<VCA> ((*i).stripable)) {
+ n_vcas++;
+ }
- ControlProtocol::StripableSelectionChanged (stripables);
+ TimeAxisView* tav = dynamic_cast<TimeAxisView*> (av);
- if (sfbrowser && _session && !_session->deletion_in_progress()) {
- uint32_t audio_track_cnt = 0;
- uint32_t midi_track_cnt = 0;
+ if (!tav) {
+ assert (0);
+ continue; /* impossible */
+ }
- for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
- AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*x);
+ if (!(*i).controllable) {
- if (atv) {
- if (atv->is_audio_track()) {
- audio_track_cnt++;
- }
+ /* "parent" track selected */
+ tav->set_selected (true);
+ tav->reshow_selection (selection->time);
} else {
- MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*>(*x);
- if (mtv) {
- if (mtv->is_midi_track()) {
- midi_track_cnt++;
+ /* possibly a child */
+
+ TimeAxisView::Children c = tav->get_child_list ();
+
+ for (TimeAxisView::Children::iterator j = c.begin(); j != c.end(); ++j) {
+
+ boost::shared_ptr<AutomationControl> control = (*j)->control ();
+
+ if (control != (*i).controllable) {
+ continue;
+ }
+
+ (*j)->set_selected (true);
+ (*j)->reshow_selection (selection->time);
+ }
+ }
+
+ stripables->push_back ((*i).stripable);
+ }
+
+ ActionManager::set_sensitive (ActionManager::stripable_selection_sensitive_actions, (n_stripables > 0));
+ ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, (n_tracks > 0));
+ ActionManager::set_sensitive (ActionManager::bus_selection_sensitive_actions, (n_busses > 0));
+ ActionManager::set_sensitive (ActionManager::route_selection_sensitive_actions, (n_routes > 0));
+ ActionManager::set_sensitive (ActionManager::vca_selection_sensitive_actions, (n_vcas > 0));
+
+ sensitize_the_right_region_actions (false);
+
+ /* STEP 4: notify control protocols */
+
+ ControlProtocolManager::instance().stripable_selection_changed (stripables);
+
+ if (sfbrowser && _session && !_session->deletion_in_progress()) {
+ uint32_t audio_track_cnt = 0;
+ uint32_t midi_track_cnt = 0;
+
+ for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
+ AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*x);
+
+ if (atv) {
+ if (atv->is_audio_track()) {
+ audio_track_cnt++;
+ }
+
+ } else {
+ MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*>(*x);
+
+ if (mtv) {
+ if (mtv->is_midi_track()) {
+ midi_track_cnt++;
+ }
}
}
}
+
+ sfbrowser->reset (audio_track_cnt, midi_track_cnt);
}
+ }
+
+ /* STEP 4: update EditorRoutes treeview */
- sfbrowser->reset (audio_track_cnt, midi_track_cnt);
+ PropertyChange soh;
+
+ soh.add (Properties::selected);
+ soh.add (Properties::order);
+ soh.add (Properties::hidden);
+
+ if (what_changed.contains (soh)) {
+ _routes->sync_treeview_from_presentation_info (what_changed);
}
}
+void
+Editor::track_selection_changed ()
+{
+ if ( _session->solo_selection_active() )
+ play_solo_selection(false);
+}
+
void
Editor::time_selection_changed ()
{
if (_session && !_drags->active()) {
if (selection->time.length() != 0) {
- _session->set_range_selection (selection->time.start(), selection->time.end_frame());
+ _session->set_range_selection (selection->time.start(), selection->time.end_sample());
} else {
_session->clear_range_selection ();
}
_all_region_actions_sensitized = s;
}
-/** Sensitize region-based actions based on the selection ONLY, ignoring the entered_regionview.
- * This method should be called just before displaying a Region menu. When a Region menu is not
- * currently being shown, all region actions are sensitized so that hotkey-triggered actions
- * on entered_regionviews work without having to check sensitivity every time the selection or
- * entered_regionview changes.
+/** Sensitize region-based actions.
*
- * This method also sets up toggle action state as appropriate.
+ * This method is called from whenever we leave the canvas, either by moving
+ * the pointer out of it, or by popping up a context menu. See
+ * Editor::{entered,left}_track_canvas() for details there.
*/
void
-Editor::sensitize_the_right_region_actions ()
+Editor::sensitize_the_right_region_actions (bool because_canvas_crossing)
{
- RegionSelection rs = get_regions_from_selection_and_entered ();
- sensitize_all_region_actions (!rs.empty ());
+ bool have_selection = false;
+ bool have_entered = false;
+ bool have_edit_point = false;
+ RegionSelection rs;
+
+ // std::cerr << "STRRA: crossing ? " << because_canvas_crossing << " within ? " << within_track_canvas
+ // << std::endl;
+
+ if (!selection->regions.empty()) {
+ have_selection = true;
+ rs = selection->regions;
+ }
+
+ if (entered_regionview) {
+ have_entered = true;
+ rs.add (entered_regionview);
+ }
+
+ if (rs.empty() && !selection->tracks.empty()) {
+
+ /* no selected regions, but some selected tracks.
+ */
+
+ if (_edit_point == EditAtMouse) {
+ if (!within_track_canvas) {
+ /* pointer is not in canvas, so edit point is meaningless */
+ have_edit_point = false;
+ } else {
+ /* inside canvas. we don't know where the edit
+ point will be when an action is invoked, but
+ assume it could intersect with a region.
+ */
+ have_edit_point = true;
+ }
+ } else {
+ RegionSelection at_edit_point;
+ samplepos_t const where = get_preferred_edit_position (Editing::EDIT_IGNORE_NONE, false, !within_track_canvas);
+ get_regions_at (at_edit_point, where, selection->tracks);
+ if (!at_edit_point.empty()) {
+ have_edit_point = true;
+ }
+ if (rs.empty()) {
+ rs.insert (rs.end(), at_edit_point.begin(), at_edit_point.end());
+ }
+ }
+ }
+
+ //std::cerr << "\tfinal have selection: " << have_selection
+ // << " have entered " << have_entered
+ // << " have edit point " << have_edit_point
+ // << " EP = " << enum_2_string (_edit_point)
+ // << std::endl;
+
+ typedef std::map<std::string,RegionAction> RegionActionMap;
_ignore_region_action = true;
+ for (RegionActionMap::iterator x = region_action_map.begin(); x != region_action_map.end(); ++x) {
+ RegionActionTarget tgt = x->second.target;
+ bool sensitive = false;
+
+ if ((tgt & SelectedRegions) && have_selection) {
+ sensitive = true;
+ } else if ((tgt & EnteredRegions) && have_entered) {
+ sensitive = true;
+ } else if ((tgt & EditPointRegions) && have_edit_point) {
+ sensitive = true;
+ }
+
+ x->second.action->set_sensitive (sensitive);
+ }
+
/* Look through the regions that are selected and make notes about what we have got */
bool have_audio = false;
/* others were already marked sensitive */
}
- if (_edit_point == EditAtMouse) {
- _region_actions->get_action("set-region-sync-position")->set_sensitive (false);
- _region_actions->get_action("trim-front")->set_sensitive (false);
- _region_actions->get_action("trim-back")->set_sensitive (false);
- _region_actions->get_action("split-region")->set_sensitive (false);
- _region_actions->get_action("place-transient")->set_sensitive (false);
- }
+ /* ok, moving along... */
if (have_compound_regions) {
_region_actions->get_action("uncombine-regions")->set_sensitive (true);
a = Glib::RefPtr<ToggleAction>::cast_dynamic (_region_actions->get_action("toggle-region-lock-style"));
a->set_active (have_position_lock_style_music && !have_position_lock_style_audio);
- if (have_position_lock_style_music && have_position_lock_style_audio) {
- // a->set_inconsistent ();
+ vector<Widget*> proxies = a->get_proxies();
+ for (vector<Widget*>::iterator p = proxies.begin(); p != proxies.end(); ++p) {
+ Gtk::CheckMenuItem* cmi = dynamic_cast<Gtk::CheckMenuItem*> (*p);
+ if (cmi) {
+ cmi->set_inconsistent (have_position_lock_style_music && have_position_lock_style_audio);
+ }
}
a = Glib::RefPtr<ToggleAction>::cast_dynamic (_region_actions->get_action("toggle-region-mute"));
_all_region_actions_sensitized = false;
}
-
void
Editor::region_selection_changed ()
{
_regions->block_change_connection (false);
editor_regions_selection_changed_connection.block(false);
- if (selection->regions.empty()) {
- sensitize_all_region_actions (false);
- } else {
- if (!_all_region_actions_sensitized) {
- /* This selection change might have changed what region actions
- are allowed, so sensitize them all in case a key is pressed.
- */
- sensitize_all_region_actions (true);
- }
- }
-
- if (_session && !_session->transport_rolling() && !selection->regions.empty()) {
- maybe_locate_with_edit_preroll (selection->regions.start());
- }
+ sensitize_the_right_region_actions (false);
/* propagate into backend */
if (_session) {
if (!selection->regions.empty()) {
- _session->set_object_selection (selection->regions.start(), selection->regions.end_frame());
+ _session->set_object_selection (selection->regions.start(), selection->regions.end_sample());
} else {
_session->clear_object_selection ();
}
}
+ if ( _session->solo_selection_active() )
+ play_solo_selection(false);
}
void
begin_reversible_selection_op (X_("Select All in Track"));
- clicked_routeview->get_selectables (0, max_framepos, 0, DBL_MAX, touched);
+ clicked_routeview->get_selectables (0, max_samplepos, 0, DBL_MAX, touched);
switch (op) {
case Selection::Toggle:
{
list<Selectable *> touched;
- TrackViewList ts = track_views;
-
if (internal_editing() && select_all_internal_edit(op)) {
return; // Selected notes
}
+ TrackViewList ts;
+
+ if (selection->tracks.empty()) {
+ ts = track_views;
+ } else {
+ ts = selection->tracks;
+ }
+
for (TrackViewList::iterator iter = ts.begin(); iter != ts.end(); ++iter) {
if ((*iter)->hidden()) {
continue;
}
- (*iter)->get_selectables (0, max_framepos, 0, DBL_MAX, touched);
- selection->add (*iter);
+ (*iter)->get_selectables (0, max_samplepos, 0, DBL_MAX, touched);
}
-
begin_reversible_selection_op (X_("select all"));
switch (op) {
case Selection::Add:
selection->add (touched);
break;
case Selection::Toggle:
- selection->add (touched);
+ selection->toggle (touched);
break;
case Selection::Set:
selection->set (touched);
commit_reversible_selection_op ();
}
-/** @param start Start time in session frames.
- * @param end End time in session frames.
+/** @param start Start time in session samples.
+ * @param end End time in session samples.
* @param top Top (lower) y limit in trackview coordinates (ie 0 at the top of the track view)
* @param bottom Bottom (higher) y limit in trackview coordinates (ie 0 at the top of the track view)
* @param preserve_if_selected true to leave the current selection alone if we're adding to the selection and all of the selectables
* within the region are already selected.
*/
void
-Editor::select_all_within (framepos_t start, framepos_t end, double top, double bot, const TrackViewList& tracklist, Selection::Operation op, bool preserve_if_selected)
+Editor::select_all_within (samplepos_t start, samplepos_t end, double top, double bot, const TrackViewList& tracklist, Selection::Operation op, bool preserve_if_selected)
{
list<Selectable*> found;
/* select range (this will clear the region selection) */
- selection->set (selection->regions.start(), selection->regions.end_frame());
+ selection->set (selection->regions.start(), selection->regions.end_sample());
/* and select the tracks */
selection->set (tvl);
- set_mouse_mode (Editing::MouseRange, false);
+ if (!get_smart_mode () || !(mouse_mode == Editing::MouseObject) ) {
+ set_mouse_mode (Editing::MouseRange, false);
+ }
}
void
Editor::set_selection_from_range (Location& loc)
{
begin_reversible_selection_op (X_("set selection from range"));
+
selection->set (loc.start(), loc.end());
+
+ // if no tracks are selected, enable all tracks
+ // (_something_ has to be selected for any range selection, otherwise the user won't see anything)
+ if (selection->tracks.empty()) {
+ select_all_tracks();
+ }
+
commit_reversible_selection_op ();
- set_mouse_mode (Editing::MouseRange, false);
+ if (!get_smart_mode () || mouse_mode != Editing::MouseObject) {
+ set_mouse_mode (MouseRange, false);
+ }
}
void
return;
}
- framepos_t start = selection->time[clicked_selection].start;
- framepos_t end = selection->time[clicked_selection].end;
+ samplepos_t start = selection->time[clicked_selection].start;
+ samplepos_t end = selection->time[clicked_selection].end;
if (end - start < 1) {
return;
void
Editor::select_all_selectables_using_cursor (EditorCursor *cursor, bool after)
{
- framepos_t start;
- framepos_t end;
+ samplepos_t start;
+ samplepos_t end;
list<Selectable *> touched;
if (after) {
- start = cursor->current_frame();
- end = _session->current_end_frame();
+ start = cursor->current_sample();
+ end = _session->current_end_sample();
} else {
- if (cursor->current_frame() > 0) {
+ if (cursor->current_sample() > 0) {
start = 0;
- end = cursor->current_frame() - 1;
+ end = cursor->current_sample() - 1;
} else {
return;
}
void
Editor::select_all_selectables_using_edit (bool after, bool from_context_menu)
{
- framepos_t start;
- framepos_t end;
+ samplepos_t start;
+ samplepos_t end;
list<Selectable *> touched;
if (after) {
start = get_preferred_edit_position(EDIT_IGNORE_NONE, from_context_menu);
- end = _session->current_end_frame();
+ end = _session->current_end_sample();
} else {
if ((end = get_preferred_edit_position(EDIT_IGNORE_NONE, from_context_menu)) > 1) {
start = 0;
void
Editor::select_all_selectables_between (bool within)
{
- framepos_t start;
- framepos_t end;
+ samplepos_t start;
+ samplepos_t end;
list<Selectable *> touched;
if (!get_edit_op_range (start, end)) {
void
Editor::select_range_between ()
{
- framepos_t start;
- framepos_t end;
+ samplepos_t start;
+ samplepos_t end;
- if ( !selection->time.empty() ) {
+ if (!selection->time.empty()) {
selection->clear_time ();
}
return;
}
+ if (!get_smart_mode () || mouse_mode != Editing::MouseObject) {
+ set_mouse_mode (MouseRange, false);
+ }
+
begin_reversible_selection_op (X_("Select Range Between"));
- set_mouse_mode (MouseRange);
selection->set (start, end);
commit_reversible_selection_op ();
}
bool
-Editor::get_edit_op_range (framepos_t& start, framepos_t& end) const
+Editor::get_edit_op_range (samplepos_t& start, samplepos_t& end) const
{
-// framepos_t m;
+// samplepos_t m;
// bool ignored;
/* if an explicit range exists, use it */
- if ( (mouse_mode == MouseRange || get_smart_mode() ) && !selection->time.empty()) {
+ if ((mouse_mode == MouseRange || get_smart_mode()) && !selection->time.empty()) {
/* we know that these are ordered */
start = selection->time.start();
- end = selection->time.end_frame();
+ end = selection->time.end_sample();
return true;
} else {
start = 0;
return false;
}
-// if (!mouse_frame (m, ignored)) {
+// if (!mouse_sample (m, ignored)) {
// /* mouse is not in a canvas, try playhead+selected marker.
// this is probably most true when using menus.
// */
// }
// start = selection->markers.front()->position();
-// end = _session->audible_frame();
+// end = _session->audible_sample();
// } else {
// if (selection->markers.empty()) {
// /* use mouse + playhead */
// start = m;
-// end = _session->audible_frame();
+// end = _session->audible_sample();
// } else {
// /* use playhead + selected marker */
-// start = _session->audible_frame();
+// start = _session->audible_sample();
// end = selection->markers.front()->position();
// }
// break;
// /* use mouse + selected marker */
// if (selection->markers.empty()) {
// start = m;
-// end = _session->audible_frame();
+// end = _session->audible_sample();
// } else {
// start = selection->markers.front()->position();
// end = m;
}
long
-Editor::select_range (framepos_t s, framepos_t e)
+Editor::select_range (samplepos_t s, samplepos_t e)
{
begin_reversible_selection_op (X_("Select Range"));
selection->add (clicked_axisview);