Remove internal edit mode and add "content" tool.
[ardour.git] / gtk2_ardour / editor.cc
index 13d6f904983017ba8438a59449c7086f88975e72..c91337bb6e8dee1657a569b4723e2ceed8a8a36e 100644 (file)
@@ -305,6 +305,8 @@ Editor::Editor ()
        
        selection = new Selection (this);
        cut_buffer = new Selection (this);
+       _selection_memento = new SelectionMemento ();
+       before.clear();
 
        clicked_regionview = 0;
        clicked_axisview = 0;
@@ -390,15 +392,14 @@ Editor::Editor ()
 
        sfbrowser = 0;
 
-       location_marker_color = ARDOUR_UI::config()->get_LocationMarker();
-       location_range_color = ARDOUR_UI::config()->get_LocationRange();
-       location_cd_marker_color = ARDOUR_UI::config()->get_LocationCDMarker();
-       location_loop_color = ARDOUR_UI::config()->get_LocationLoop();
-       location_punch_color = ARDOUR_UI::config()->get_LocationPunch();
+       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");
 
        zoom_focus = ZoomFocusLeft;
        _edit_point = EditAtMouse;
-       _internal_editing = false;
        current_canvas_cursor = 0;
        _visible_track_count = -1;
 
@@ -668,11 +669,6 @@ Editor::Editor ()
        _snap_mode = SnapOff;
        set_snap_mode (_snap_mode);
        set_mouse_mode (MouseObject, true);
-        pre_internal_mouse_mode = MouseObject;
-        pre_internal_snap_type = _snap_type;
-        pre_internal_snap_mode = _snap_mode;
-        internal_snap_type = _snap_type;
-        internal_snap_mode = _snap_mode;
        set_edit_point_preference (EditAtMouse, true);
 
        _playlist_selector = new PlaylistSelector();
@@ -875,7 +871,7 @@ Editor::set_entered_regionview (RegionView* rv)
        entered_regionview = rv;
 
        if (entered_regionview  != 0) {
-               entered_regionview->entered (internal_editing ());
+               entered_regionview->entered ();
        }
 
        if (!_all_region_actions_sensitized && _last_region_menu_was_main) {
@@ -1392,6 +1388,7 @@ Editor::set_session (Session *t)
 
        /* register for undo history */
        _session->register_with_memento_command_factory(id(), this);
+       _session->register_with_memento_command_factory(_selection_memento->id(), _selection_memento);
 
        ActionManager::ui_manager->signal_pre_activate().connect (sigc::mem_fun (*this, &Editor::action_pre_activated));
 
@@ -1484,8 +1481,10 @@ void
 Editor::popup_xfade_in_context_menu (int button, int32_t time, ArdourCanvas::Item* item, ItemType /*item_type*/)
 {
        using namespace Menu_Helpers;
-       AudioRegionView* arv = static_cast<AudioRegionView*> (item->get_data ("regionview"));
-       assert(arv);
+       AudioRegionView* arv = dynamic_cast<AudioRegionView*> ((RegionView*)item->get_data ("regionview"));
+       if (!arv) {
+               return;
+       }
 
        MenuList& items (xfade_in_context_menu.items());
        items.clear ();
@@ -1507,8 +1506,10 @@ void
 Editor::popup_xfade_out_context_menu (int button, int32_t time, ArdourCanvas::Item* item, ItemType /*item_type*/)
 {
        using namespace Menu_Helpers;
-       AudioRegionView* arv = static_cast<AudioRegionView*> (item->get_data ("regionview"));
-       assert(arv);
+       AudioRegionView* arv = dynamic_cast<AudioRegionView*> ((RegionView*)item->get_data ("regionview"));
+       if (!arv) {
+               return;
+       }
 
        MenuList& items (xfade_out_context_menu.items());
        items.clear ();
@@ -2085,12 +2086,6 @@ Editor::set_snap_mode (SnapMode mode)
 {
        string str = snap_mode_strings[(int)mode];
 
-       if (_internal_editing) {
-               internal_snap_mode = mode;
-       } else {
-               pre_internal_snap_mode = mode;
-       }
-
        _snap_mode = mode;
 
        if (str != snap_mode_selector.get_text ()) {
@@ -2242,23 +2237,6 @@ Editor::set_state (const XMLNode& node, int /*version*/)
                snap_mode_selection_done((SnapMode) string_2_enum (prop->value(), _snap_mode));
        }
 
-       if ((prop = node.property ("internal-snap-to"))) {
-               internal_snap_type = (SnapType) string_2_enum (prop->value(), internal_snap_type);
-       }
-
-       if ((prop = node.property ("internal-snap-mode"))) {
-               internal_snap_mode = (SnapMode) string_2_enum (prop->value(), internal_snap_mode);
-       }
-
-       if ((prop = node.property ("pre-internal-snap-to"))) {
-               pre_internal_snap_type = (SnapType) string_2_enum (prop->value(), pre_internal_snap_type);
-       }
-
-
-       if ((prop = node.property ("pre-internal-snap-mode"))) {
-               pre_internal_snap_mode = (SnapMode) string_2_enum (prop->value(), pre_internal_snap_mode);
-       }
-
        if ((prop = node.property ("mouse-mode"))) {
                MouseMode m = str2mousemode(prop->value());
                set_mouse_mode (m, true);
@@ -2280,16 +2258,6 @@ Editor::set_state (const XMLNode& node, int /*version*/)
                reset_y_origin (atof (prop->value ()));
        }
 
-       if ((prop = node.property ("internal-edit"))) {
-               bool yn = string_is_affirmative (prop->value());
-               RefPtr<Action> act = ActionManager::get_action (X_("MouseMode"), X_("toggle-internal-edit"));
-               if (act) {
-                       RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
-                       tact->set_active (!yn);
-                       tact->set_active (yn);
-               }
-       }
-
        if ((prop = node.property ("join-object-range"))) {
                RefPtr<Action> act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-object-range"));
                bool yn = string_is_affirmative (prop->value());
@@ -2460,10 +2428,6 @@ Editor::get_state ()
        node->add_property ("zoom", buf);
        node->add_property ("snap-to", enum_2_string (_snap_type));
        node->add_property ("snap-mode", enum_2_string (_snap_mode));
-       node->add_property ("internal-snap-to", enum_2_string (internal_snap_type));
-       node->add_property ("internal-snap-mode", enum_2_string (internal_snap_mode));
-       node->add_property ("pre-internal-snap-to", enum_2_string (pre_internal_snap_type));
-       node->add_property ("pre-internal-snap-mode", enum_2_string (pre_internal_snap_mode));
        node->add_property ("edit-point", enum_2_string (_edit_point));
        snprintf (buf, sizeof(buf), "%d", _visible_track_count);
        node->add_property ("visible-track-count", buf);
@@ -2481,7 +2445,6 @@ Editor::get_state ()
        node->add_property ("stationary-playhead", _stationary_playhead ? "yes" : "no");
        node->add_property ("region-list-sort-type", enum_2_string (_regions->sort_type ()));
        node->add_property ("mouse-mode", enum2str(mouse_mode));
-       node->add_property ("internal-edit", _internal_editing ? "yes" : "no");
        node->add_property ("join-object-range", smart_mode_action->get_active () ? "yes" : "no");
 
        Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("show-editor-mixer"));
@@ -2856,7 +2819,7 @@ Editor::setup_toolbar ()
        mouse_mode_size_group->add_widget (mouse_timefx_button);
        mouse_mode_size_group->add_widget (mouse_audition_button);
        mouse_mode_size_group->add_widget (mouse_draw_button);
-       mouse_mode_size_group->add_widget (internal_edit_button);
+       mouse_mode_size_group->add_widget (mouse_content_button);
 
        mouse_mode_size_group->add_widget (zoom_in_button);
        mouse_mode_size_group->add_widget (zoom_out_button);
@@ -2895,7 +2858,7 @@ Editor::setup_toolbar ()
                mouse_mode_hbox->pack_start (mouse_timefx_button, false, false);
                mouse_mode_hbox->pack_start (mouse_audition_button, false, false);
                mouse_mode_hbox->pack_start (mouse_draw_button, false, false);
-               mouse_mode_hbox->pack_start (internal_edit_button, false, false, 0);
+               mouse_mode_hbox->pack_start (mouse_content_button, false, false);
        }
 
        mouse_mode_vbox->pack_start (*mouse_mode_hbox);
@@ -3186,7 +3149,7 @@ Editor::setup_tooltips ()
        ARDOUR_UI::instance()->set_tip (mouse_draw_button, _("Draw/Edit Gain/Notes/Automation"));
        ARDOUR_UI::instance()->set_tip (mouse_timefx_button, _("Stretch/Shrink Regions and MIDI Notes"));
        ARDOUR_UI::instance()->set_tip (mouse_audition_button, _("Listen to Specific Regions"));
-       ARDOUR_UI::instance()->set_tip (internal_edit_button, _("Note Level Editing"));
+       ARDOUR_UI::instance()->set_tip (mouse_content_button, _("Select/move contents (notes and automation)"));
        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"));
@@ -3313,6 +3276,7 @@ void
 Editor::begin_reversible_command (string name)
 {
        if (_session) {
+               before.push_back (&_selection_memento->get_state ());
                _session->begin_reversible_command (name);
        }
 }
@@ -3321,6 +3285,7 @@ void
 Editor::begin_reversible_command (GQuark q)
 {
        if (_session) {
+               before.push_back (&_selection_memento->get_state ());
                _session->begin_reversible_command (q);
        }
 }
@@ -3329,6 +3294,14 @@ void
 Editor::commit_reversible_command ()
 {
        if (_session) {
+               if (before.size() == 1) {
+                       _session->add_command (new MementoCommand<SelectionMemento>(*(_selection_memento), before.front(), &_selection_memento->get_state ()));
+               }
+
+               if (!before.empty()) {
+                       before.pop_back();
+               }
+
                _session->commit_reversible_command ();
        }
 }
@@ -4178,7 +4151,7 @@ Editor::copy_playlists (TimeAxisView* v)
 void
 Editor::clear_playlists (TimeAxisView* v)
 {
-       begin_reversible_command (_("clear playlists"));
+       begin_reversible_command (_("clear playlists"));        
        vector<boost::shared_ptr<ARDOUR::Playlist> > playlists;
        _session->playlists->get (playlists);
        mapover_tracks (sigc::mem_fun (*this, &Editor::mapped_clear_playlist), v, ARDOUR::Properties::select.property_id);
@@ -4216,6 +4189,12 @@ Editor::on_key_release_event (GdkEventKey* ev)
        // return key_press_focus_accelerator_handler (*this, ev);
 }
 
+double
+Editor::get_y_origin () const
+{
+       return vertical_adjustment.get_value ();
+}
+
 /** Queue up a change to the viewport x origin.
  *  @param frame New x origin.
  */
@@ -4625,8 +4604,7 @@ Editor::set_punch_range (framepos_t start, framepos_t end, string cmd)
                _session->set_auto_punch_location (loc);
                XMLNode &after = _session->locations()->get_state();
                _session->add_command (new MementoCommand<Locations>(*(_session->locations()), &before, &after));
-       }
-       else {
+       } else {
                XMLNode &before = tpl->get_state();
                tpl->set_hidden (false, this);
                tpl->set (start, end);
@@ -4803,6 +4781,35 @@ Editor::get_regions_from_selection_and_entered ()
        return regions;
 }
 
+void
+Editor::get_regionviews_by_id (PBD::ID const & id, RegionSelection & regions) const
+{
+       for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i) {
+               RouteTimeAxisView* tatv;
+               
+               if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
+                       boost::shared_ptr<Playlist> pl;
+                       std::vector<boost::shared_ptr<Region> > results;
+                       boost::shared_ptr<Track> tr;
+                       
+                       if ((tr = tatv->track()) == 0) {
+                               /* bus */
+                               continue;
+                       }
+                       
+                       if ((pl = (tr->playlist())) != 0) {
+                               boost::shared_ptr<Region> r = pl->region_by_id (id);
+                               if (r) {
+                                       RegionView* marv = tatv->view()->find_view (r);
+                                       if (marv) {
+                                               regions.push_back (marv);
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
 void
 Editor::get_regions_corresponding_to (boost::shared_ptr<Region> region, vector<RegionView*>& regions, bool src_comparison)
 {
@@ -4962,8 +4969,15 @@ Editor::located ()
 }
 
 void
-Editor::region_view_added (RegionView *)
+Editor::region_view_added (RegionView * rv)
 {
+       for (list<PBD::ID>::iterator pr = selection->regions.pending.begin (); pr != selection->regions.pending.end (); ++pr) {
+               if (rv->region ()->id () == (*pr)) {
+                       selection->add (rv);
+                       selection->regions.pending.erase (pr);
+                       break;
+               }
+       }
        _summary->set_background_dirty ();
 }
 
@@ -5052,12 +5066,6 @@ Editor::add_routes (RouteList& routes)
 
                rtv->effective_gain_display ();
 
-                if (internal_editing()) {
-                        rtv->enter_internal_edit_mode ();
-                } else {
-                        rtv->leave_internal_edit_mode ();
-                }
-
                rtv->view()->RegionViewAdded.connect (sigc::mem_fun (*this, &Editor::region_view_added));
                rtv->view()->RegionViewRemoved.connect (sigc::mem_fun (*this, &Editor::region_view_removed));
        }