X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor.cc;h=f080ed24fb1c0ecc0513932de63db2fcb35f1b95;hb=8509b5fddc538853a80c97dfdb5b425996bf9662;hp=a29c1ebeef04b0dfbe37beae43d8b29b6e743a55;hpb=c7affd79c24a6a633c9b400de9662087d210ac60;p=ardour.git diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index a29c1ebeef..f080ed24fb 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -68,6 +68,7 @@ #include "ardour/audio_track.h" #include "ardour/audioengine.h" #include "ardour/audioregion.h" +#include "ardour/lmath.h" #include "ardour/location.h" #include "ardour/profile.h" #include "ardour/route_group.h" @@ -114,6 +115,7 @@ #include "note_base.h" #include "playlist_selector.h" #include "public_editor.h" +#include "quantize_dialog.h" #include "region_layering_order_editor.h" #include "rgb_macros.h" #include "rhythm_ferret.h" @@ -122,6 +124,8 @@ #include "tempo_lines.h" #include "time_axis_view.h" #include "timers.h" +#include "tooltips.h" +#include "ui_config.h" #include "utils.h" #include "verbose_cursor.h" @@ -231,7 +235,7 @@ pane_size_watcher (Paned* pane) X: hard to access Quartz: impossible to access - + so stop that by preventing it from ever getting too narrow. 35 pixels is basically a rough guess at the tab width. @@ -299,6 +303,8 @@ Editor::Editor () , _following_mixer_selection (false) , _control_point_toggled_on_press (false) , _stepping_axis_view (0) + , quantize_dialog (0) + , _main_menu_disabler (0) { constructed = false; @@ -307,7 +313,7 @@ Editor::Editor () PublicEditor::_instance = this; _have_idled = false; - + selection = new Selection (this); cut_buffer = new Selection (this); _selection_memento = new SelectionMemento (); @@ -317,6 +323,7 @@ Editor::Editor () clicked_regionview = 0; clicked_axisview = 0; clicked_routeview = 0; + clicked_selection = 0; clicked_control_point = 0; last_update_frame = 0; last_paste_pos = 0; @@ -376,6 +383,7 @@ Editor::Editor () region_edit_menu_split_item = 0; temp_location = 0; leftmost_frame = 0; + mouse_mode = MouseObject; current_stepping_trackview = 0; entered_track = 0; entered_regionview = 0; @@ -397,21 +405,21 @@ Editor::Editor () sfbrowser = 0; - location_marker_color = ARDOUR_UI::config()->color ("location marker"); - location_range_color = ARDOUR_UI::config()->color ("location range"); - location_cd_marker_color = ARDOUR_UI::config()->color ("location cd marker"); - location_loop_color = ARDOUR_UI::config()->color ("location loop"); - location_punch_color = ARDOUR_UI::config()->color ("location punch"); + location_marker_color = UIConfiguration::instance().color ("location marker"); + location_range_color = UIConfiguration::instance().color ("location range"); + location_cd_marker_color = UIConfiguration::instance().color ("location cd marker"); + location_loop_color = UIConfiguration::instance().color ("location loop"); + location_punch_color = UIConfiguration::instance().color ("location punch"); - zoom_focus = ZoomFocusLeft; + zoom_focus = ZoomFocusPlayhead; _edit_point = EditAtMouse; _visible_track_count = -1; samples_per_pixel = 2048; /* too early to use reset_zoom () */ - timebar_height = std::max(12., ceil (15. * ARDOUR_UI::config()->get_font_scale() / 102400.)); + timebar_height = std::max(12., ceil (15. * UIConfiguration::instance().get_ui_scale())); TimeAxisView::setup_sizes (); - Marker::setup_sizes (timebar_height); + ArdourMarker::setup_sizes (timebar_height); _scroll_callbacks = 0; @@ -525,8 +533,8 @@ Editor::Editor () controls_layout.signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::control_layout_scroll), false); _cursors = new MouseCursors; - _cursors->set_cursor_set (ARDOUR_UI::config()->get_icon_set()); - cerr << "Set cursor set to " << ARDOUR_UI::config()->get_icon_set() << endl; + _cursors->set_cursor_set (UIConfiguration::instance().get_icon_set()); + cerr << "Set cursor set to " << UIConfiguration::instance().get_icon_set() << endl; /* Push default cursor to ever-present bottom of cursor stack. */ push_canvas_cursor(_cursors->grabber); @@ -694,10 +702,10 @@ Editor::Editor () /* nudge stuff */ nudge_forward_button.set_name ("nudge button"); - nudge_forward_button.set_image(::get_icon("nudge_right")); + nudge_forward_button.set_icon(ArdourIcon::NudgeRight); nudge_backward_button.set_name ("nudge button"); - nudge_backward_button.set_image(::get_icon("nudge_left")); + nudge_backward_button.set_icon(ArdourIcon::NudgeLeft); fade_context_menu.set_name ("ArdourContextMenu"); @@ -735,7 +743,7 @@ Editor::Editor () signal_delete_event().connect (sigc::mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::exit_on_main_window_close)); Gtkmm2ext::Keyboard::the_keyboard().ZoomVerticalModifierReleased.connect (sigc::mem_fun (*this, &Editor::zoom_vertical_modifier_released)); - + /* allow external control surfaces/protocols to do various things */ ControlProtocol::ZoomToSession.connect (*this, invalidator (*this), boost::bind (&Editor::temporal_zoom_session, this), gui_context()); @@ -766,7 +774,7 @@ Editor::Editor () Session::AskAboutPlaylistDeletion.connect_same_thread (*this, boost::bind (&Editor::playlist_deletion_dialog, this, _1)); Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&Editor::parameter_changed, this, _1), gui_context()); - ARDOUR_UI::config()->ParameterChanged.connect (sigc::mem_fun (*this, &Editor::ui_parameter_changed)); + UIConfiguration::instance().ParameterChanged.connect (sigc::mem_fun (*this, &Editor::ui_parameter_changed)); TimeAxisView::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&Editor::timeaxisview_deleted, this, _1), gui_context()); @@ -793,7 +801,7 @@ Editor::Editor () /* grab current parameter state */ boost::function pc (boost::bind (&Editor::ui_parameter_changed, this, _1)); - ARDOUR_UI::config()->map_parameters (pc); + UIConfiguration::instance().map_parameters (pc); setup_fade_images (); @@ -808,6 +816,17 @@ Editor::~Editor() delete _track_canvas_viewport; delete _drags; delete nudge_clock; + delete quantize_dialog; + delete _summary; + delete _group_tabs; + delete _regions; + delete _snapshots; + delete _locations; + delete _playlist_selector; + + for (list::iterator i = selection_op_history.begin(); i != selection_op_history.end(); ++i) { + delete *i; + } } XMLNode* @@ -1000,12 +1019,12 @@ Editor::control_unselect () } void -Editor::control_select (uint32_t rid, Selection::Operation op) +Editor::control_select (uint32_t rid, Selection::Operation op) { /* handles the (static) signal from the ControlProtocol class that * requests setting the selected track to a given RID */ - + if (!_session) { return; } @@ -1144,7 +1163,7 @@ Editor::on_realize () Window::on_realize (); Realized (); - if (ARDOUR_UI::config()->get_lock_gui_after_seconds()) { + if (UIConfiguration::instance().get_lock_gui_after_seconds()) { start_lock_event_timing (); } @@ -1176,7 +1195,7 @@ Editor::generic_event_handler (GdkEvent* ev) case GDK_NOTIFY_UNKNOWN: case GDK_NOTIFY_INFERIOR: case GDK_NOTIFY_ANCESTOR: - break; + break; case GDK_NOTIFY_VIRTUAL: case GDK_NOTIFY_NONLINEAR: case GDK_NOTIFY_NONLINEAR_VIRTUAL: @@ -1204,7 +1223,7 @@ Editor::lock_timeout_callback () timersub (&now, &last_event_time, &delta); - if (delta.tv_sec > (time_t) ARDOUR_UI::config()->get_lock_gui_after_seconds()) { + if (delta.tv_sec > (time_t) UIConfiguration::instance().get_lock_gui_after_seconds()) { lock (); /* don't call again. Returning false will effectively disconnect us from the timer callback. @@ -1450,18 +1469,18 @@ Editor::fill_xfade_menu (Menu_Helpers::MenuList& items, bool start) sigc::bind (sigc::mem_fun (*this, emf), FadeLinear) ) ); - + dynamic_cast(&items.back())->set_always_show_image (); - + items.push_back ( ImageMenuElem ( _("Constant power"), *(*images)[FadeConstantPower], sigc::bind (sigc::mem_fun (*this, emf), FadeConstantPower) )); - + dynamic_cast(&items.back())->set_always_show_image (); - + items.push_back ( ImageMenuElem ( _("Symmetric"), @@ -1469,25 +1488,25 @@ Editor::fill_xfade_menu (Menu_Helpers::MenuList& items, bool start) sigc::bind (sigc::mem_fun (*this, emf), FadeSymmetric) ) ); - + dynamic_cast(&items.back())->set_always_show_image (); - + items.push_back ( ImageMenuElem ( _("Slow"), *(*images)[FadeSlow], sigc::bind (sigc::mem_fun (*this, emf), FadeSlow) )); - + dynamic_cast(&items.back())->set_always_show_image (); - + items.push_back ( ImageMenuElem ( _("Fast"), *(*images)[FadeFast], sigc::bind (sigc::mem_fun (*this, emf), FadeFast) )); - + dynamic_cast(&items.back())->set_always_show_image (); } @@ -1795,10 +1814,18 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items, boost::sha _popup_region_menu_item->set_label (menu_item_name); } - const framepos_t position = get_preferred_edit_position (false, true); + /* No latering allowed in later is higher layering model */ + RefPtr act = ActionManager::get_action (X_("EditorMenu"), X_("RegionMenuLayering")); + if (act && Config->get_layer_model() == LaterHigher) { + act->set_sensitive (false); + } else if (act) { + act->set_sensitive (true); + } + + const framepos_t position = get_preferred_edit_position (EDIT_IGNORE_NONE, true); edit_items.push_back (*_popup_region_menu_item); - if (track->playlist()->count_regions_at (position) > 1 && (layering_order_editor == 0 || !layering_order_editor->is_visible ())) { + if (Config->get_layer_model() == Manual && track->playlist()->count_regions_at (position) > 1 && (layering_order_editor == 0 || !layering_order_editor->is_visible ())) { edit_items.push_back (*manage (_region_actions->get_action ("choose-top-region-context-menu")->create_menu_item ())); } edit_items.push_back (SeparatorElem()); @@ -1868,17 +1895,16 @@ Editor::add_selection_context_items (Menu_Helpers::MenuList& edit_items) edit_items.push_back (SeparatorElem()); edit_items.push_back (MenuElem (_("Crop Region to Range"), sigc::mem_fun(*this, &Editor::crop_region_to_selection))); - edit_items.push_back (MenuElem (_("Fill Range with Region"), sigc::mem_fun(*this, &Editor::region_fill_selection))); edit_items.push_back (MenuElem (_("Duplicate Range"), sigc::bind (sigc::mem_fun(*this, &Editor::duplicate_range), false))); edit_items.push_back (SeparatorElem()); edit_items.push_back (MenuElem (_("Consolidate Range"), sigc::bind (sigc::mem_fun(*this, &Editor::bounce_range_selection), true, false))); - edit_items.push_back (MenuElem (_("Consolidate Range With Processing"), sigc::bind (sigc::mem_fun(*this, &Editor::bounce_range_selection), true, true))); + edit_items.push_back (MenuElem (_("Consolidate Range with Processing"), sigc::bind (sigc::mem_fun(*this, &Editor::bounce_range_selection), true, true))); edit_items.push_back (MenuElem (_("Bounce Range to Region List"), sigc::bind (sigc::mem_fun(*this, &Editor::bounce_range_selection), false, false))); - edit_items.push_back (MenuElem (_("Bounce Range to Region List With Processing"), sigc::bind (sigc::mem_fun(*this, &Editor::bounce_range_selection), false, true))); + edit_items.push_back (MenuElem (_("Bounce Range to Region List with Processing"), sigc::bind (sigc::mem_fun(*this, &Editor::bounce_range_selection), false, true))); edit_items.push_back (MenuElem (_("Export Range..."), sigc::mem_fun(*this, &Editor::export_selection))); if (ARDOUR_UI::instance()->video_timeline->get_duration() > 0) { - edit_items.push_back (MenuElem (_("Export Video Range..."), sigc::bind (sigc::mem_fun(*this, &Editor::export_video), true))); + edit_items.push_back (MenuElem (_("Export Video Range..."), sigc::bind (sigc::mem_fun(*(ARDOUR_UI::instance()), &ARDOUR_UI::export_video), true))); } } @@ -1894,8 +1920,8 @@ Editor::add_dstream_context_items (Menu_Helpers::MenuList& edit_items) MenuList& play_items = play_menu->items(); play_menu->set_name ("ArdourContextMenu"); - play_items.push_back (MenuElem (_("Play From Edit Point"), sigc::mem_fun(*this, &Editor::play_from_edit_point))); - play_items.push_back (MenuElem (_("Play From Start"), sigc::mem_fun(*this, &Editor::play_from_start))); + play_items.push_back (MenuElem (_("Play from Edit Point"), sigc::mem_fun(*this, &Editor::play_from_edit_point))); + play_items.push_back (MenuElem (_("Play from Start"), sigc::mem_fun(*this, &Editor::play_from_start))); play_items.push_back (MenuElem (_("Play Region"), sigc::mem_fun(*this, &Editor::play_selected_region))); play_items.push_back (SeparatorElem()); play_items.push_back (MenuElem (_("Loop Region"), sigc::bind (sigc::mem_fun (*this, &Editor::set_loop_from_region), true))); @@ -1915,9 +1941,10 @@ Editor::add_dstream_context_items (Menu_Helpers::MenuList& edit_items) select_items.push_back (SeparatorElem()); select_items.push_back (MenuElem (_("Set Range to Loop Range"), sigc::mem_fun(*this, &Editor::set_selection_from_loop))); select_items.push_back (MenuElem (_("Set Range to Punch Range"), sigc::mem_fun(*this, &Editor::set_selection_from_punch))); + select_items.push_back (MenuElem (_("Set Range to Selected Regions"), sigc::mem_fun(*this, &Editor::set_selection_from_region))); select_items.push_back (SeparatorElem()); - select_items.push_back (MenuElem (_("Select All After Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_edit), true))); - select_items.push_back (MenuElem (_("Select All Before Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_edit), false))); + select_items.push_back (MenuElem (_("Select All After Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_edit), true, true))); + select_items.push_back (MenuElem (_("Select All Before Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_edit), false, true))); select_items.push_back (MenuElem (_("Select All After Playhead"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, true))); select_items.push_back (MenuElem (_("Select All Before Playhead"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, false))); select_items.push_back (MenuElem (_("Select All Between Playhead and Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_between), false))); @@ -1975,8 +2002,8 @@ Editor::add_bus_context_items (Menu_Helpers::MenuList& edit_items) MenuList& play_items = play_menu->items(); play_menu->set_name ("ArdourContextMenu"); - play_items.push_back (MenuElem (_("Play From Edit Point"), sigc::mem_fun(*this, &Editor::play_from_edit_point))); - play_items.push_back (MenuElem (_("Play From Start"), sigc::mem_fun(*this, &Editor::play_from_start))); + play_items.push_back (MenuElem (_("Play from Edit Point"), sigc::mem_fun(*this, &Editor::play_from_edit_point))); + play_items.push_back (MenuElem (_("Play from Start"), sigc::mem_fun(*this, &Editor::play_from_start))); edit_items.push_back (MenuElem (_("Play"), *play_menu)); /* Selection */ @@ -1990,8 +2017,8 @@ Editor::add_bus_context_items (Menu_Helpers::MenuList& edit_items) select_items.push_back (MenuElem (_("Invert Selection in Track"), sigc::mem_fun(*this, &Editor::invert_selection_in_track))); select_items.push_back (MenuElem (_("Invert Selection"), sigc::mem_fun(*this, &Editor::invert_selection))); select_items.push_back (SeparatorElem()); - select_items.push_back (MenuElem (_("Select All After Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_edit), true))); - select_items.push_back (MenuElem (_("Select All Before Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_edit), false))); + select_items.push_back (MenuElem (_("Select All After Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_edit), true, true))); + select_items.push_back (MenuElem (_("Select All Before Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_edit), false, true))); select_items.push_back (MenuElem (_("Select All After Playhead"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, true))); select_items.push_back (MenuElem (_("Select All Before Playhead"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, false))); @@ -2078,7 +2105,7 @@ Editor::set_snap_to (SnapType st) case SnapToBeatDiv2: { ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin; ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end; - + compute_current_bbt_points (leftmost_frame, leftmost_frame + current_page_samples(), current_bbt_points_begin, current_bbt_points_end); compute_bbt_ruler_scale (leftmost_frame, leftmost_frame + current_page_samples(), @@ -2123,6 +2150,7 @@ Editor::set_snap_mode (SnapMode mode) instant_save (); } + void Editor::set_edit_point_preference (EditPoint ep, bool force) { @@ -2321,37 +2349,16 @@ Editor::set_state (const XMLNode& node, int /*version*/) if ((prop = node.property ("show-measures"))) { bool yn = string_is_affirmative (prop->value()); _show_measures = yn; - RefPtr act = ActionManager::get_action (X_("Editor"), X_("ToggleMeasureVisibility")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic(act); - /* do it twice to force the change */ - tact->set_active (!yn); - tact->set_active (yn); - } } if ((prop = node.property ("follow-playhead"))) { bool yn = string_is_affirmative (prop->value()); set_follow_playhead (yn); - RefPtr act = ActionManager::get_action (X_("Editor"), X_("toggle-follow-playhead")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic(act); - if (tact->get_active() != yn) { - tact->set_active (yn); - } - } } if ((prop = node.property ("stationary-playhead"))) { bool yn = string_is_affirmative (prop->value()); set_stationary_playhead (yn); - RefPtr act = ActionManager::get_action (X_("Editor"), X_("toggle-stationary-playhead")); - if (act) { - RefPtr tact = RefPtr::cast_dynamic(act); - if (tact->get_active() != yn) { - tact->set_active (yn); - } - } } if ((prop = node.property ("region-list-sort-type"))) { @@ -2427,6 +2434,42 @@ Editor::set_state (const XMLNode& node, int /*version*/) nudge_clock->set (_session->frame_rate() * 5, true); } + { + /* apply state + * Not all properties may have been in XML, but + * those that are linked to a private variable may need changing + */ + RefPtr act; + bool yn; + + act = ActionManager::get_action (X_("Editor"), X_("ToggleMeasureVisibility")); + if (act) { + yn = _show_measures; + RefPtr tact = RefPtr::cast_dynamic(act); + /* do it twice to force the change */ + tact->set_active (!yn); + tact->set_active (yn); + } + + act = ActionManager::get_action (X_("Editor"), X_("toggle-follow-playhead")); + yn = _follow_playhead; + if (act) { + RefPtr tact = RefPtr::cast_dynamic(act); + if (tact->get_active() != yn) { + tact->set_active (yn); + } + } + + act = ActionManager::get_action (X_("Editor"), X_("toggle-stationary-playhead")); + yn = _stationary_playhead; + if (act) { + RefPtr tact = RefPtr::cast_dynamic(act); + if (tact->get_active() != yn) { + tact->set_active (yn); + } + } + } + return 0; } @@ -2548,9 +2591,9 @@ Editor::trackview_by_y_position (double y, bool trackview_relative_offset) const } for (TrackViewList::const_iterator iter = track_views.begin(); iter != track_views.end(); ++iter) { - + std::pair const r = (*iter)->covers_y_position (y); - + if (r.first) { return r; } @@ -2571,25 +2614,28 @@ Editor::snap_to_with_modifier (framepos_t& start, GdkEvent const * event, RoundM return; } - if (Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) { + if (ArdourKeyboard::indicates_snap (event->button.state)) { if (_snap_mode == SnapOff) { snap_to_internal (start, direction, for_mark); } } else { if (_snap_mode != SnapOff) { snap_to_internal (start, direction, for_mark); + } else if (ArdourKeyboard::indicates_snap_delta (event->button.state)) { + /* SnapOff, but we pressed the snap_delta modifier */ + snap_to_internal (start, direction, for_mark); } } } void -Editor::snap_to (framepos_t& start, RoundMode direction, bool for_mark) +Editor::snap_to (framepos_t& start, RoundMode direction, bool for_mark, bool ensure_snap) { - if (!_session || _snap_mode == SnapOff) { + if (!_session || (_snap_mode == SnapOff && !ensure_snap)) { return; } - snap_to_internal (start, direction, for_mark); + snap_to_internal (start, direction, for_mark, ensure_snap); } void @@ -2659,7 +2705,7 @@ Editor::timecode_snap_to_internal (framepos_t& start, RoundMode direction, bool } void -Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark) +Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark, bool ensure_snap) { const framepos_t one_second = _session->frame_rate(); const framepos_t one_minute = _session->frame_rate() * 60; @@ -2829,6 +2875,10 @@ Editor::snap_to_internal (framepos_t& start, RoundMode direction, bool for_mark) case SnapMagnetic: + if (ensure_snap) { + return; + } + if (presnap > start) { if (presnap > (start + pixel_to_sample(snap_threshold))) { start = presnap; @@ -2902,7 +2952,7 @@ Editor::setup_toolbar () if (!ARDOUR::Profile->get_mixbus()) { mouse_mode_hbox->pack_start (mouse_cut_button, false, false); } - + if (!ARDOUR::Profile->get_trx()) { mouse_mode_hbox->pack_start (mouse_timefx_button, false, false); mouse_mode_hbox->pack_start (mouse_audition_button, false, false); @@ -2953,17 +3003,17 @@ Editor::setup_toolbar () zoom_preset_selector.set_size_request (42, -1); zoom_in_button.set_name ("zoom button"); - zoom_in_button.set_image(::get_icon ("zoom_in")); + zoom_in_button.set_icon (ArdourIcon::ZoomIn); act = ActionManager::get_action (X_("Editor"), X_("temporal-zoom-in")); zoom_in_button.set_related_action (act); zoom_out_button.set_name ("zoom button"); - zoom_out_button.set_image(::get_icon ("zoom_out")); + zoom_out_button.set_icon (ArdourIcon::ZoomOut); act = ActionManager::get_action (X_("Editor"), X_("temporal-zoom-out")); zoom_out_button.set_related_action (act); zoom_out_full_button.set_name ("zoom button"); - zoom_out_full_button.set_image(::get_icon ("zoom_full")); + zoom_out_full_button.set_icon (ArdourIcon::ZoomFull); act = ActionManager::get_action (X_("Editor"), X_("zoom-to-session")); zoom_out_full_button.set_related_action (act); @@ -2991,12 +3041,12 @@ Editor::setup_toolbar () } tav_expand_button.set_name ("zoom button"); - tav_expand_button.set_image(::get_icon ("tav_exp")); + tav_expand_button.set_icon (ArdourIcon::TimeAxisExpand); act = ActionManager::get_action (X_("Editor"), X_("expand-tracks")); tav_expand_button.set_related_action (act); tav_shrink_button.set_name ("zoom button"); - tav_shrink_button.set_image(::get_icon ("tav_shrink")); + tav_shrink_button.set_icon (ArdourIcon::TimeAxisShrink); act = ActionManager::get_action (X_("Editor"), X_("shrink-tracks")); tav_shrink_button.set_related_action (act); @@ -3013,7 +3063,7 @@ Editor::setup_toolbar () if (!ARDOUR::Profile->get_trx()) { _zoom_tearoff = manage (new TearOff (_zoom_box)); - + _zoom_tearoff->Detach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast(&toolbar_hbox), &_zoom_tearoff->tearoff_window())); _zoom_tearoff->Attach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast (&toolbar_hbox), @@ -3022,7 +3072,7 @@ Editor::setup_toolbar () &_zoom_tearoff->tearoff_window())); _zoom_tearoff->Visible.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast (&toolbar_hbox), &_zoom_tearoff->tearoff_window(), 0)); - } + } if (Profile->get_sae() || Profile->get_mixbus() ) { _zoom_tearoff->set_can_be_torn_off (false); @@ -3088,11 +3138,7 @@ Editor::setup_toolbar () if (!ARDOUR::Profile->get_trx()) { hbox->pack_start (snap_box, false, false); - if ( !Profile->get_small_screen() || Profile->get_mixbus() ) { - hbox->pack_start (*nudge_box, false, false); - } else { - ARDOUR_UI::instance()->editor_transport_box().pack_start (*nudge_box, false, false); - } + hbox->pack_start (*nudge_box, false, false); } hbox->pack_start (panic_box, false, false); @@ -3127,7 +3173,7 @@ void Editor::build_edit_mode_menu () { using namespace Menu_Helpers; - + edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_strings[(int)Slide], sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Slide))); // edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_strings[(int)Splice], sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Splice))); edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_strings[(int)Ripple], sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Ripple))); @@ -3191,30 +3237,30 @@ Editor::build_snap_type_menu () void Editor::setup_tooltips () { - ARDOUR_UI::instance()->set_tip (smart_mode_button, _("Smart Mode (add Range functions to Grab mode)")); - ARDOUR_UI::instance()->set_tip (mouse_move_button, _("Grab Mode (select/move objects)")); - ARDOUR_UI::instance()->set_tip (mouse_cut_button, _("Cut Mode (split regions)")); - ARDOUR_UI::instance()->set_tip (mouse_select_button, _("Range Mode (select time ranges)")); - ARDOUR_UI::instance()->set_tip (mouse_draw_button, _("Draw Mode (draw and edit gain/notes/automation)")); - ARDOUR_UI::instance()->set_tip (mouse_timefx_button, _("Stretch Mode (time-stretch audio and midi regions, preserving pitch)")); - ARDOUR_UI::instance()->set_tip (mouse_audition_button, _("Audition Mode (listen to regions)")); - ARDOUR_UI::instance()->set_tip (mouse_content_button, _("Internal Edit Mode (edit notes and gain curves inside regions)")); - ARDOUR_UI::instance()->set_tip (*_group_tabs, _("Groups: click to (de)activate\nContext-click for other operations")); - ARDOUR_UI::instance()->set_tip (nudge_forward_button, _("Nudge Region/Selection Later")); - ARDOUR_UI::instance()->set_tip (nudge_backward_button, _("Nudge Region/Selection Earlier")); - ARDOUR_UI::instance()->set_tip (zoom_in_button, _("Zoom In")); - ARDOUR_UI::instance()->set_tip (zoom_out_button, _("Zoom Out")); - ARDOUR_UI::instance()->set_tip (zoom_preset_selector, _("Zoom to Time Scale")); - ARDOUR_UI::instance()->set_tip (zoom_out_full_button, _("Zoom to Session")); - ARDOUR_UI::instance()->set_tip (zoom_focus_selector, _("Zoom focus")); - ARDOUR_UI::instance()->set_tip (tav_expand_button, _("Expand Tracks")); - ARDOUR_UI::instance()->set_tip (tav_shrink_button, _("Shrink Tracks")); - ARDOUR_UI::instance()->set_tip (visible_tracks_selector, _("Number of visible tracks")); - ARDOUR_UI::instance()->set_tip (snap_type_selector, _("Snap/Grid Units")); - ARDOUR_UI::instance()->set_tip (snap_mode_selector, _("Snap/Grid Mode")); - ARDOUR_UI::instance()->set_tip (edit_point_selector, _("Edit point")); - ARDOUR_UI::instance()->set_tip (edit_mode_selector, _("Edit Mode")); - ARDOUR_UI::instance()->set_tip (nudge_clock, _("Nudge Clock\n(controls distance used to nudge regions and selections)")); + set_tooltip (smart_mode_button, _("Smart Mode (add range functions to Grab Mode)")); + set_tooltip (mouse_move_button, _("Grab Mode (select/move objects)")); + set_tooltip (mouse_cut_button, _("Cut Mode (split regions)")); + set_tooltip (mouse_select_button, _("Range Mode (select time ranges)")); + set_tooltip (mouse_draw_button, _("Draw Mode (draw and edit gain/notes/automation)")); + set_tooltip (mouse_timefx_button, _("Stretch Mode (time-stretch audio and midi regions, preserving pitch)")); + set_tooltip (mouse_audition_button, _("Audition Mode (listen to regions)")); + set_tooltip (mouse_content_button, _("Internal Edit Mode (edit notes and automation points)")); + set_tooltip (*_group_tabs, _("Groups: click to (de)activate\nContext-click for other operations")); + set_tooltip (nudge_forward_button, _("Nudge Region/Selection Later")); + set_tooltip (nudge_backward_button, _("Nudge Region/Selection Earlier")); + set_tooltip (zoom_in_button, _("Zoom In")); + set_tooltip (zoom_out_button, _("Zoom Out")); + set_tooltip (zoom_preset_selector, _("Zoom to Time Scale")); + set_tooltip (zoom_out_full_button, _("Zoom to Session")); + set_tooltip (zoom_focus_selector, _("Zoom Focus")); + set_tooltip (tav_expand_button, _("Expand Tracks")); + set_tooltip (tav_shrink_button, _("Shrink Tracks")); + set_tooltip (visible_tracks_selector, _("Number of visible tracks")); + set_tooltip (snap_type_selector, _("Snap/Grid Units")); + set_tooltip (snap_mode_selector, _("Snap/Grid Mode")); + set_tooltip (edit_point_selector, _("Edit Point")); + set_tooltip (edit_mode_selector, _("Edit Mode")); + set_tooltip (nudge_clock, _("Nudge Clock\n(controls distance used to nudge regions and selections)")); } int @@ -3326,7 +3372,12 @@ Editor::begin_selection_op_history () { selection_op_cmd_depth = 0; selection_op_history_it = 0; - selection_op_history.clear(); + + while(!selection_op_history.empty()) { + delete selection_op_history.front(); + selection_op_history.pop_front(); + } + selection_undo_action->set_sensitive (false); selection_redo_action->set_sensitive (false); selection_op_history.push_front (&_selection_memento->get_state ()); @@ -3349,10 +3400,19 @@ Editor::commit_reversible_selection_op () if (selection_op_cmd_depth == 1) { if (selection_op_history_it > 0 && selection_op_history_it < selection_op_history.size()) { - /* the user has undone some selection ops and then made a new one */ + /** + The user has undone some selection ops and then made a new one, + making anything earlier in the list invalid. + */ + list::iterator it = selection_op_history.begin(); - advance (it, selection_op_history_it); - selection_op_history.erase (selection_op_history.begin(), it); + list::iterator e_it = it; + advance (e_it, selection_op_history_it); + + for ( ; it != e_it; ++it) { + delete *it; + } + selection_op_history.erase (selection_op_history.begin(), e_it); } selection_op_history.push_front (&_selection_memento->get_state ()); @@ -3428,12 +3488,25 @@ Editor::begin_reversible_command (GQuark q) } } +void +Editor::abort_reversible_command () +{ + if (_session) { + while(!before.empty()) { + delete before.front(); + before.pop_front(); + } + _session->abort_reversible_command (); + } +} + void Editor::commit_reversible_command () { if (_session) { if (before.size() == 1) { _session->add_command (new MementoCommand(*(_selection_memento), before.front(), &_selection_memento->get_state ())); + redo_action->set_sensitive(false); undo_action->set_sensitive(true); begin_selection_op_history (); } @@ -3465,8 +3538,10 @@ Editor::history_changed () if (redo_action && _session) { if (_session->redo_depth() == 0) { label = _("Redo"); + redo_action->set_sensitive (false); } else { label = string_compose(_("Redo (%1)"), _session->next_redo()); + redo_action->set_sensitive (true); } redo_action->property_label() = label; } @@ -3531,7 +3606,7 @@ Editor::duplicate_range (bool with_dialog) } else if (get_smart_mode()) { if (selection->time.length()) { duplicate_selection (times); - } else + } else duplicate_some_regions (rs, times); } else { duplicate_some_regions (rs, times); @@ -3695,7 +3770,7 @@ Editor::set_zoom_preset (int64_t ms) temporal_zoom_session(); return; } - + ARDOUR::framecnt_t const sample_rate = ARDOUR::AudioEngine::instance()->sample_rate(); temporal_zoom( (sample_rate * ms / 1000) / _visible_canvas_width ); } @@ -3710,7 +3785,7 @@ Editor::set_visible_track_count (int32_t n) allocation happens, we will get called again and then we can do the real work. */ - + if (_visible_canvas_height <= 1) { return; } @@ -3718,7 +3793,7 @@ Editor::set_visible_track_count (int32_t n) int h; string str; DisplaySuspender ds; - + if (_visible_track_count > 0) { h = trackviews_height() / _visible_track_count; std::ostringstream s; @@ -3734,7 +3809,7 @@ Editor::set_visible_track_count (int32_t n) h = trackviews_height() / n; str = _("All"); } else { - /* negative value means that the visible track count has + /* negative value means that the visible track count has been overridden by explicit track height changes. */ visible_tracks_selector.set_text (X_("*")); @@ -3742,9 +3817,9 @@ Editor::set_visible_track_count (int32_t n) } for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - (*i)->set_height (h); + (*i)->set_height (h, TimeAxisView::HeightPerLane); } - + if (str != visible_tracks_selector.get_text()) { visible_tracks_selector.set_text (str); } @@ -3898,8 +3973,8 @@ Editor::pane_allocation_handler (Allocation &alloc, Paned* which) void Editor::detach_tearoff (Box* /*b*/, Window* /*w*/) { - if ((_tools_tearoff->torn_off() || !_tools_tearoff->visible()) && - (_mouse_mode_tearoff->torn_off() || !_mouse_mode_tearoff->visible()) && + if ((_tools_tearoff->torn_off() || !_tools_tearoff->visible()) && + (_mouse_mode_tearoff->torn_off() || !_mouse_mode_tearoff->visible()) && (_zoom_tearoff && (_zoom_tearoff->torn_off() || !_zoom_tearoff->visible()))) { top_hbox.remove (toolbar_frame); } @@ -3926,10 +4001,10 @@ Editor::set_show_measures (bool yn) ARDOUR::TempoMap::BBTPointList::const_iterator begin; ARDOUR::TempoMap::BBTPointList::const_iterator end; - + compute_current_bbt_points (leftmost_frame, leftmost_frame + current_page_samples(), begin, end); draw_measures (begin, end); - } + } instant_save (); } @@ -4085,19 +4160,34 @@ Editor::playlist_deletion_dialog (boost::shared_ptr pl) label.show (); + dialog.add_button (_("Delete All Unused"), RESPONSE_YES); // needs clarification. this and all remaining ones dialog.add_button (_("Delete Playlist"), RESPONSE_ACCEPT); - dialog.add_button (_("Keep Playlist"), RESPONSE_REJECT); + Button* keep = dialog.add_button (_("Keep Playlist"), RESPONSE_REJECT); + dialog.add_button (_("Keep Remaining"), RESPONSE_NO); // ditto dialog.add_button (_("Cancel"), RESPONSE_CANCEL); + // by default gtk uses the left most button + keep->grab_focus (); + switch (dialog.run ()) { + case RESPONSE_NO: + /* keep this and all remaining ones */ + return -2; + break; + + case RESPONSE_YES: + /* delete this and all others */ + return 2; + break; + case RESPONSE_ACCEPT: /* delete the playlist */ - return 0; + return 1; break; case RESPONSE_REJECT: /* keep the playlist */ - return 1; + return 0; break; default: @@ -4180,7 +4270,7 @@ Editor::session_state_saved (string) void Editor::update_tearoff_visibility() { - bool visible = ARDOUR_UI::config()->get_keep_tearoffs(); + bool visible = UIConfiguration::instance().get_keep_tearoffs(); _mouse_mode_tearoff->set_visible (visible); _tools_tearoff->set_visible (visible); if (_zoom_tearoff) { @@ -4260,7 +4350,7 @@ Editor::copy_playlists (TimeAxisView* v) void Editor::clear_playlists (TimeAxisView* v) { - begin_reversible_command (_("clear playlists")); + begin_reversible_command (_("clear playlists")); vector > playlists; _session->playlists->get (playlists); mapover_tracks (sigc::mem_fun (*this, &Editor::mapped_clear_playlist), v, ARDOUR::Properties::select.property_id); @@ -4365,7 +4455,7 @@ Editor::current_visual_state (bool with_tracks) vs->leftmost_frame = leftmost_frame; vs->zoom_focus = zoom_focus; - if (with_tracks) { + if (with_tracks) { *vs->gui_state = *ARDOUR_UI::instance()->gui_object_state; } @@ -4429,11 +4519,12 @@ Editor::use_visual_state (VisualState& vs) set_zoom_focus (vs.zoom_focus); reposition_and_zoom (vs.leftmost_frame, vs.samples_per_pixel); - + if (vs.gui_state) { *ARDOUR_UI::instance()->gui_object_state = *vs.gui_state; - - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + (*i)->clear_property_cache(); (*i)->reset_visual_state (); } } @@ -4542,7 +4633,7 @@ Editor::idle_visual_changer () pending_visual_change.idle_handler_id = -1; pending_visual_change.being_handled = true; - + VisualChange vc = pending_visual_change; pending_visual_change.pending = (VisualChange::Type) 0; @@ -4566,7 +4657,7 @@ Editor::visual_changer (const VisualChange& vc) ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin; ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end; - + compute_current_bbt_points (vc.time_origin, pending_visual_change.time_origin + current_page_samples(), current_bbt_points_begin, current_bbt_points_end); compute_bbt_ruler_scale (vc.time_origin, pending_visual_change.time_origin + current_page_samples(), @@ -4611,15 +4702,15 @@ Editor::sort_track_selection (TrackViewList& sel) } framepos_t -Editor::get_preferred_edit_position (bool ignore_playhead, bool from_context_menu, bool from_outside_canvas) +Editor::get_preferred_edit_position (EditIgnoreOption ignore, bool from_context_menu, bool from_outside_canvas) { bool ignored; framepos_t where = 0; EditPoint ep = _edit_point; - if(Profile->get_mixbus()) + if (Profile->get_mixbus()) if (ep == EditAtSelectedMarker) - ep=EditAtPlayhead; + ep = EditAtPlayhead; if (from_outside_canvas && (ep == EditAtMouse)) { ep = EditAtPlayhead; @@ -4632,19 +4723,21 @@ Editor::get_preferred_edit_position (bool ignore_playhead, bool from_context_men return entered_marker->position(); } - if (ignore_playhead && ep == EditAtPlayhead) { + if ( (ignore==EDIT_IGNORE_PHEAD) && ep == EditAtPlayhead) { ep = EditAtSelectedMarker; } + if ( (ignore==EDIT_IGNORE_MOUSE) && ep == EditAtMouse) { + ep = EditAtPlayhead; + } + switch (ep) { case EditAtPlayhead: if (_dragging_playhead) { - if (!mouse_frame (where, ignored)) { - /* XXX not right but what can we do ? */ - return 0; - } - } else + where = *_control_scroll_target; + } else { where = _session->audible_frame(); + } DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("GPEP: use playhead @ %1\n", where)); break; @@ -4836,7 +4929,7 @@ Editor::get_regions_from_selection_and_edit_point () if (!tracks.empty()) { /* no region selected or entered, but some selected tracks: * act on all regions on the selected tracks at the edit point - */ + */ framepos_t const where = get_preferred_edit_position (); get_regions_at(regions, where, tracks); } @@ -4873,7 +4966,7 @@ Editor::get_regions_from_selection_and_mouse (framepos_t pos) if (!tracks.empty()) { /* no region selected or entered, but some selected tracks: * act on all regions on the selected tracks at the edit point - */ + */ get_regions_at(regions, pos, tracks); } } @@ -4903,17 +4996,17 @@ Editor::get_regionviews_by_id (PBD::ID const id, RegionSelection & regions) cons { for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i) { RouteTimeAxisView* rtav; - + if ((rtav = dynamic_cast (*i)) != 0) { boost::shared_ptr pl; std::vector > results; boost::shared_ptr tr; - + if ((tr = rtav->track()) == 0) { /* bus */ continue; } - + if ((pl = (tr->playlist())) != 0) { boost::shared_ptr r = pl->region_by_id (id); if (r) { @@ -4939,7 +5032,7 @@ Editor::get_per_region_note_selection (listget_per_region_note_selection (selection); } } - + } void @@ -4995,8 +5088,9 @@ void Editor::first_idle () { MessageDialog* dialog = 0; - + if (track_views.size() > 1) { + Timers::TimerSuspender t; dialog = new MessageDialog ( *this, string_compose (_("Please wait while %1 loads visual data."), PROGRAM_NAME), @@ -5182,6 +5276,7 @@ void Editor::resume_route_redisplay () { if (_routes) { + _routes->redisplay(); // queue redisplay _routes->resume_redisplay(); } } @@ -5193,6 +5288,8 @@ Editor::add_routes (RouteList& routes) RouteTimeAxisView *rtv; list new_views; + TrackViewList new_selection; + bool from_scratch = (track_views.size() == 0); for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) { boost::shared_ptr route = (*x); @@ -5215,6 +5312,7 @@ Editor::add_routes (RouteList& routes) new_views.push_back (rtv); track_views.push_back (rtv); + new_selection.push_back (rtv); rtv->effective_gain_display (); @@ -5227,6 +5325,12 @@ Editor::add_routes (RouteList& routes) _summary->routes_added (new_views); } + if (!from_scratch) { + selection->tracks.clear(); + selection->add (new_selection); + begin_selection_op_history(); + } + if (show_editor_mixer_when_tracks_arrive) { show_editor_mixer (true); } @@ -5330,7 +5434,7 @@ Editor::sync_track_view_list_and_routes () { track_views = TrackViewList (_routes->views ()); - _summary->set_dirty (); + _summary->set_background_dirty(); _group_tabs->set_dirty (); return false; // do not call again (until needed) @@ -5521,7 +5625,7 @@ Editor::reset_x_origin_to_follow_playhead () } else { framepos_t l = 0; - + if (frame < leftmost_frame) { /* moving left */ if (_session->transport_rolling()) { @@ -5545,7 +5649,7 @@ Editor::reset_x_origin_to_follow_playhead () if (l < 0) { l = 0; } - + center_screen_internal (l + (current_page_samples() / 2), current_page_samples ()); } } @@ -5612,24 +5716,20 @@ Editor::super_rapid_screen_update () } else { - /* don't do continuous scroll till the new position is in the rightmost quarter of the - editor canvas - */ -#if 0 - // FIXME DO SOMETHING THAT WORKS HERE - this is 2.X code - double target = ((double)frame - (double)current_page_samples()/2.0) / samples_per_pixel; - if (target <= 0.0) { - target = 0.0; - } - if (fabs(target - current) < current_page_samples() / samples_per_pixel) { - target = (target * 0.15) + (current * 0.85); - } else { - /* relax */ + if (!_dragging_playhead && _follow_playhead && _session->requested_return_frame() < 0 && !pending_visual_change.being_handled) { + framepos_t const frame = playhead_cursor->current_frame (); + double target = ((double)frame - (double)current_page_samples()/2.0); + if (target <= 0.0) { + target = 0.0; + } + // compare to EditorCursor::set_position() + double const old_pos = sample_to_pixel_unrounded (leftmost_frame); + double const new_pos = sample_to_pixel_unrounded (target); + if (rint (new_pos) != rint (old_pos)) { + reset_x_origin (pixel_to_sample (floor (new_pos))); + } } - current = target; - set_horizontal_position (current); -#endif } } @@ -5694,7 +5794,7 @@ Editor::session_going_away () clear_marker_display (); stop_step_editing (); - + /* get rid of any existing editor mixer strip */ WindowTitle title(Glib::get_application_name()); @@ -5719,7 +5819,7 @@ Editor::show_editor_list (bool yn) void Editor::change_region_layering_order (bool from_context_menu) { - const framepos_t position = get_preferred_edit_position (false, from_context_menu); + const framepos_t position = get_preferred_edit_position (EDIT_IGNORE_NONE, from_context_menu); if (!clicked_routeview) { if (layering_order_editor) { @@ -5770,7 +5870,7 @@ Editor::setup_fade_images () _fade_out_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadeout-fast-cut"))); _fade_out_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadeout-slow-cut"))); _fade_out_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadeout-constant-power"))); - + _xfade_in_images[FadeLinear] = new Gtk::Image (get_icon_path (X_("fadein-linear"))); _xfade_in_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadein-symmetric"))); _xfade_in_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadein-fast-cut"))); @@ -5841,10 +5941,10 @@ void Editor::popup_control_point_context_menu (ArdourCanvas::Item* item, GdkEvent* event) { using namespace Menu_Helpers; - + MenuList& items = _control_point_context_menu.items (); items.clear (); - + items.push_back (MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun (*this, &Editor::edit_control_point), item))); items.push_back (MenuElem (_("Delete"), sigc::bind (sigc::mem_fun (*this, &Editor::remove_control_point), item))); if (!can_remove_control_point (item)) { @@ -5870,20 +5970,41 @@ Editor::popup_note_context_menu (ArdourCanvas::Item* item, GdkEvent* event) MidiRegionView& mrv = note->region_view(); const RegionSelection rs = get_regions_from_selection_and_entered (); + const uint32_t sel_size = mrv.selection_size (); MenuList& items = _note_context_menu.items(); items.clear(); - items.push_back(MenuElem(_("Delete"), - sigc::mem_fun(mrv, &MidiRegionView::delete_selection))); + if (sel_size > 0) { + items.push_back(MenuElem(_("Delete"), + sigc::mem_fun(mrv, &MidiRegionView::delete_selection))); + } + items.push_back(MenuElem(_("Edit..."), - sigc::bind(sigc::mem_fun(*this, &Editor::edit_notes), &mrv))); + sigc::bind(sigc::mem_fun(*this, &Editor::edit_notes), &mrv))); + if (sel_size != 1) { + items.back().set_sensitive (false); + } + + items.push_back(MenuElem(_("Transpose..."), + sigc::bind(sigc::mem_fun(*this, &Editor::transpose_regions), rs))); + + items.push_back(MenuElem(_("Legatize"), - sigc::bind(sigc::mem_fun(*this, &Editor::legatize_regions), rs, false))); + sigc::bind(sigc::mem_fun(*this, &Editor::legatize_regions), rs, false))); + if (sel_size < 2) { + items.back().set_sensitive (false); + } + items.push_back(MenuElem(_("Quantize..."), sigc::bind(sigc::mem_fun(*this, &Editor::quantize_regions), rs))); + items.push_back(MenuElem(_("Remove Overlap"), - sigc::bind(sigc::mem_fun(*this, &Editor::legatize_regions), rs, true))); + sigc::bind(sigc::mem_fun(*this, &Editor::legatize_regions), rs, true))); + if (sel_size < 2) { + items.back().set_sensitive (false); + } + items.push_back(MenuElem(_("Transform..."), sigc::bind(sigc::mem_fun(*this, &Editor::transform_regions), rs))); @@ -5903,11 +6024,11 @@ Editor::ui_parameter_changed (string parameter) while (!_cursor_stack.empty()) { _cursor_stack.pop_back(); } - _cursors->set_cursor_set (ARDOUR_UI::config()->get_icon_set()); + _cursors->set_cursor_set (UIConfiguration::instance().get_icon_set()); _cursor_stack.push_back(_cursors->grabber); } else if (parameter == "draggable-playhead") { if (_verbose_cursor) { - playhead_cursor->set_sensitive (ARDOUR_UI::config()->get_draggable_playhead()); + playhead_cursor->set_sensitive (UIConfiguration::instance().get_draggable_playhead()); } } }