#include <cstdlib>
#include "pbd/stacktrace.h"
+#include "pbd/unwind.h"
#include "ardour/midi_region.h"
#include "ardour/playlist.h"
visible_views.push_back (*i);
}
}
+ PBD::Unwinder<bool> uw (_track_selection_change_without_scroll, true);
selection->set (visible_views);
}
if (!regions.empty()) {
selection->add (regions);
commit = true;
+ } else if (selection->regions.empty() && !selection->selected (clicked_regionview)) {
+ /* ensure that at least the clicked regionview is selected. */
+ selection->set (clicked_regionview);
+ commit = true;
}
+
}
out:
case 0:
break;
default:
- set_selected_mixer_strip (*(selection->tracks.front()));
+ /* last element in selection list is the most recently
+ * selected, because we always append to that list.
+ */
+ set_selected_mixer_strip (*(selection->tracks.back()));
+ if (!_track_selection_change_without_scroll) {
+ ensure_time_axis_view_is_visible (*(selection->tracks.back()), false);
+ }
break;
}
ActionManager::set_sensitive (ActionManager::track_selection_sensitive_actions, !selection->tracks.empty());
+ sensitize_the_right_region_actions (false);
+
/* notify control protocols */
ControlProtocol::StripableSelectionChanged (stripables);
_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;
+ framepos_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 */