Use a shared_ptr for SessionPlaylists so that it can be explicitly destroyed in ...
[ardour.git] / gtk2_ardour / editor_routes.cc
index 8feebe9df3d030d192ae2c0557c5b729b42386e7..ca22b8cbf70bb7ee98fc4925fc883fab26328dee 100644 (file)
@@ -77,7 +77,7 @@ EditorRoutes::EditorRoutes (Editor* e)
        rec_col_renderer->set_inactive_pixbuf (::get_icon("act-disabled"));
        rec_col_renderer->signal_toggled().connect (mem_fun (*this, &EditorRoutes::on_tv_rec_enable_toggled));
 
-       Gtk::TreeViewColumn* rec_state_column = manage (new TreeViewColumn("R", *rec_col_renderer));
+       TreeViewColumn* rec_state_column = manage (new TreeViewColumn("R", *rec_col_renderer));
 
        rec_state_column->add_attribute(rec_col_renderer->property_active(), _columns.rec_enabled);
        rec_state_column->add_attribute(rec_col_renderer->property_visible(), _columns.is_track);
@@ -89,10 +89,9 @@ EditorRoutes::EditorRoutes (Editor* e)
        mute_col_renderer->set_pixbuf (1, ::get_icon("mute-enabled"));
        mute_col_renderer->signal_changed().connect (mem_fun (*this, &EditorRoutes::on_tv_mute_enable_toggled));
 
-       Gtk::TreeViewColumn* mute_state_column = manage (new TreeViewColumn("M", *mute_col_renderer));
+       TreeViewColumn* mute_state_column = manage (new TreeViewColumn("M", *mute_col_renderer));
 
        mute_state_column->add_attribute(mute_col_renderer->property_state(), _columns.mute_state);
-       mute_state_column->add_attribute(mute_col_renderer->property_visible(), _columns.is_track);
 
        // Solo enable toggle
        CellRendererPixbufMulti* solo_col_renderer = manage (new CellRendererPixbufMulti());
@@ -101,12 +100,10 @@ EditorRoutes::EditorRoutes (Editor* e)
        solo_col_renderer->set_pixbuf (1, ::get_icon("solo-enabled"));
        solo_col_renderer->signal_changed().connect (mem_fun (*this, &EditorRoutes::on_tv_solo_enable_toggled));
 
-       Gtk::TreeViewColumn* solo_state_column = manage (new TreeViewColumn("S", *solo_col_renderer));
+       TreeViewColumn* solo_state_column = manage (new TreeViewColumn("S", *solo_col_renderer));
 
        solo_state_column->add_attribute(solo_col_renderer->property_state(), _columns.solo_state);
-       solo_state_column->add_attribute(solo_col_renderer->property_visible(), _columns.is_track);
 
-       
        _display.append_column (*rec_state_column);
        _display.append_column (*mute_state_column);
        _display.append_column (*solo_state_column);
@@ -128,18 +125,22 @@ EditorRoutes::EditorRoutes (Editor* e)
        _display.add_object_drag (_columns.route.index(), "routes");
 
        CellRendererText* name_cell = dynamic_cast<CellRendererText*> (_display.get_column_cell_renderer (4));
-       
        assert (name_cell);
+
+       TreeViewColumn* name_column = _display.get_column (4);
+       assert (name_column);
+
+       name_column->add_attribute (name_cell->property_editable(), _columns.name_editable);
        name_cell->property_editable() = true;
        name_cell->signal_edited().connect (mem_fun (*this, &EditorRoutes::name_edit));
 
-       CellRendererToggle* visible_cell = dynamic_cast<CellRendererToggle*>(_display.get_column_cell_renderer (3));
+       CellRendererToggle* visible_cell = dynamic_cast<CellRendererToggle*> (_display.get_column_cell_renderer (3));
 
        visible_cell->property_activatable() = true;
        visible_cell->property_radio() = false;
+       visible_cell->signal_toggled().connect (mem_fun (*this, &EditorRoutes::visible_changed));
 
        _model->signal_row_deleted().connect (mem_fun (*this, &EditorRoutes::route_deleted));
-       _model->signal_row_changed().connect (mem_fun (*this, &EditorRoutes::changed));
        _model->signal_rows_reordered().connect (mem_fun (*this, &EditorRoutes::reordered));
        _display.signal_button_press_event().connect (mem_fun (*this, &EditorRoutes::button_press), false);
 
@@ -152,6 +153,8 @@ EditorRoutes::connect_to_session (Session* s)
        EditorComponent::connect_to_session (s);
 
        initial_display ();
+
+       _session->SoloChanged.connect (mem_fun (*this, &EditorRoutes::solo_changed_so_update_mute));
 }
 
 void
@@ -160,6 +163,8 @@ EditorRoutes::on_tv_rec_enable_toggled (Glib::ustring const & path_string)
        // Get the model row that has been toggled.
        Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string));
 
+       row[_columns.name_editable] = !row[_columns.rec_enabled];
+       
        TimeAxisView *tv = row[_columns.tv];
        AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
 
@@ -177,8 +182,8 @@ EditorRoutes::on_tv_mute_enable_toggled (Glib::ustring const & path_string)
        TimeAxisView *tv = row[_columns.tv];
        AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
 
-       if (atv != 0 && atv->is_audio_track()){
-               atv->reversibly_apply_track_boolean ("mute-enable change", &Track::set_mute, !atv->track()->muted(), this);
+       if (atv != 0{
+               atv->reversibly_apply_route_boolean ("mute-enable change", &Route::set_mute, !atv->route()->muted(), this);
        }
 }
 
@@ -191,8 +196,8 @@ EditorRoutes::on_tv_solo_enable_toggled (Glib::ustring const & path_string)
        TimeAxisView *tv = row[_columns.tv];
        AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
 
-       if (atv != 0 && atv->is_audio_track()){
-               atv->reversibly_apply_track_boolean ("solo-enable change", &Track::set_solo, !atv->track()->soloed(), this);
+       if (atv != 0{
+               atv->reversibly_apply_route_boolean ("solo-enable change", &Route::set_solo, !atv->route()->soloed(), this);
        }
 }
 
@@ -213,7 +218,7 @@ EditorRoutes::build_menu ()
        items.push_back (MenuElem (_("Hide All Audio Tracks"), mem_fun (*this, &EditorRoutes::hide_all_audiotracks)));
        items.push_back (MenuElem (_("Show All Audio Busses"), mem_fun (*this, &EditorRoutes::show_all_audiobus)));
        items.push_back (MenuElem (_("Hide All Audio Busses"), mem_fun (*this, &EditorRoutes::hide_all_audiobus)));
-
+       items.push_back (MenuElem (_("Show Tracks With Regions Under Playhead"), mem_fun (*this, &EditorRoutes::show_tracks_with_regions_at_playhead)));
 }
 
 void
@@ -303,9 +308,18 @@ EditorRoutes::route_deleted (Gtk::TreeModel::Path const &)
 
 
 void
-EditorRoutes::changed (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &)
+EditorRoutes::visible_changed (Glib::ustring const & path)
 {
-       /* never reset order keys because of a property change */
+       TreeIter iter;
+
+       if ((iter = _model->get_iter (path))) {
+               TimeAxisView* tv = (*iter)[_columns.tv];
+               if (tv) {
+                       bool visible = (*iter)[_columns.visible];
+                       (*iter)[_columns.visible] = !visible;
+               }
+       }
+
        _redisplay_does_not_reset_order_keys = true;
        _session->set_remote_control_ids();
        redisplay ();
@@ -347,11 +361,13 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
                if ((*x)->is_track()) {
                        boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> ((*x)->route());
                        t->diskstream()->RecordEnableChanged.connect (mem_fun (*this, &EditorRoutes::update_rec_display));
-                       t->mute_changed.connect (mem_fun (*this, &EditorRoutes::update_mute_display));
-                       t->solo_changed.connect (mem_fun (*this, &EditorRoutes::update_solo_display));
                }
+
+               (*x)->route()->mute_changed.connect (mem_fun (*this, &EditorRoutes::update_mute_display));
+               (*x)->route()->solo_changed.connect (mem_fun (*this, &EditorRoutes::update_solo_display));
        }
 
+       update_rec_display ();
        resume_redisplay ();
        _redisplay_does_not_sync_order_keys = false;
 }
@@ -481,7 +497,7 @@ EditorRoutes::sync_order_keys (string const & src)
        TreeModel::Children rows = _model->children();
        TreeModel::Children::iterator ri;
 
-       if (src == N_ ("editor") || !_session || (_session->state_of_the_state() & Session::Loading) || rows.empty()) {
+       if (src == N_ ("editor") || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
                return;
        }
 
@@ -648,45 +664,6 @@ EditorRoutes::button_press (GdkEventButton* ev)
                return true;
        }
 
-       TreeIter iter;
-       TreeModel::Path path;
-       TreeViewColumn* column;
-       int cellx;
-       int celly;
-
-       if (!_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) {
-               return false;
-       }
-
-       switch (GPOINTER_TO_UINT (column->get_data (X_("colnum")))) {
-
-       case 0:
-               /* allow normal processing to occur */
-               return false;
-       case 1:
-               /* allow normal processing to occur */
-               return false;
-       case 2:
-               /* allow normal processing to occur */
-               return false;           
-       case 3:
-               if ((iter = _model->get_iter (path))) {
-                       TimeAxisView* tv = (*iter)[_columns.tv];
-                       if (tv) {
-                               bool visible = (*iter)[_columns.visible];
-                               (*iter)[_columns.visible] = !visible;
-                       }
-               }
-               return true;
-
-       case 4:
-               /* allow normal processing to occur */
-               return false;
-
-       default:
-               break;
-       }
-
        return false;
 }
 
@@ -889,12 +866,8 @@ EditorRoutes::update_rec_display ()
                boost::shared_ptr<Route> route = (*i)[_columns.route];
 
                if (boost::dynamic_pointer_cast<Track>(route)) {
-
-                       if (route->record_enabled()){
-                               (*i)[_columns.rec_enabled] = true;
-                       } else {
-                               (*i)[_columns.rec_enabled] = false;
-                       }
+                       (*i)[_columns.rec_enabled] = route->record_enabled ();
+                       (*i)[_columns.name_editable] = !route->record_enabled ();
                }
        }
 }
@@ -907,15 +880,7 @@ EditorRoutes::update_mute_display (void* /*src*/)
 
        for (i = rows.begin(); i != rows.end(); ++i) {
                boost::shared_ptr<Route> route = (*i)[_columns.route];
-
-               if (boost::dynamic_pointer_cast<Track>(route)) {
-
-                       if (route->muted()){
-                               (*i)[_columns.mute_state] = 1;
-                       } else {
-                               (*i)[_columns.mute_state] = 0;
-                       }
-               }
+               (*i)[_columns.mute_state] = RouteUI::mute_visual_state (*_session, route) > 0 ? 1 : 0;
        }
 }
 
@@ -927,15 +892,7 @@ EditorRoutes::update_solo_display (void* /*src*/)
 
        for (i = rows.begin(); i != rows.end(); ++i) {
                boost::shared_ptr<Route> route = (*i)[_columns.route];
-
-               if (boost::dynamic_pointer_cast<Track>(route)) {
-
-                       if (route->soloed()){
-                               (*i)[_columns.solo_state] = 1;
-                       } else {
-                               (*i)[_columns.solo_state] = 0;
-                       }
-               }
+               (*i)[_columns.solo_state] = RouteUI::solo_visual_state (route) > 0 ? 1 : 0;
        }
 }
 
@@ -968,7 +925,40 @@ EditorRoutes::name_edit (Glib::ustring const & path, Glib::ustring const & new_t
 
        boost::shared_ptr<Route> route = (*iter)[_columns.route];
 
-       if (route) {
+       if (route && route->name() != new_text) {
                route->set_name (new_text);
        }
 }
+
+void
+EditorRoutes::solo_changed_so_update_mute ()
+{
+       ENSURE_GUI_THREAD (mem_fun (*this, &EditorRoutes::solo_changed_so_update_mute));
+
+       update_mute_display (this);
+}
+
+void
+EditorRoutes::show_tracks_with_regions_at_playhead ()
+{
+       boost::shared_ptr<RouteList> const r = _session->get_routes_with_regions_at (_session->transport_frame ());
+
+       set<TimeAxisView*> show;
+       for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
+               TimeAxisView* tav = _editor->axis_view_from_route (i->get ());
+               if (tav) {
+                       show.insert (tav);
+               }
+       }
+
+       suspend_redisplay ();
+       
+       TreeModel::Children rows = _model->children ();
+       for (TreeModel::Children::iterator i = rows.begin(); i != rows.end(); ++i) {
+               TimeAxisView* tv = (*i)[_columns.tv];
+               (*i)[_columns.visible] = (show.find (tv) != show.end());
+       }
+
+       resume_redisplay ();
+       
+}