2 Copyright (C) 2000-2009 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include "ardour/diskstream.h"
28 #include "ardour/session.h"
32 #include "ardour_ui.h"
33 #include "audio_time_axis.h"
34 #include "midi_time_axis.h"
35 #include "mixer_strip.h"
36 #include "gui_thread.h"
39 #include "editor_group_tabs.h"
40 #include "editor_routes.h"
42 #include "pbd/unknown_type.h"
44 #include "ardour/route.h"
46 #include "gtkmm2ext/cell_renderer_pixbuf_multi.h"
47 #include "gtkmm2ext/cell_renderer_pixbuf_toggle.h"
53 using namespace ARDOUR;
56 using namespace Gtkmm2ext;
59 EditorRoutes::EditorRoutes (Editor* e)
60 : EditorComponent (e),
61 _ignore_reorder (false),
62 _no_redisplay (false),
63 _redisplay_does_not_sync_order_keys (false),
64 _redisplay_does_not_reset_order_keys (false),
67 _scroller.add (_display);
68 _scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
70 _model = ListStore::create (_columns);
71 _display.set_model (_model);
73 // Record enable toggle
74 CellRendererPixbufToggle* rec_col_renderer = manage (new CellRendererPixbufToggle());
76 rec_col_renderer->set_active_pixbuf (::get_icon("rec-enabled"));
77 rec_col_renderer->set_inactive_pixbuf (::get_icon("act-disabled"));
78 rec_col_renderer->signal_toggled().connect (mem_fun (*this, &EditorRoutes::on_tv_rec_enable_toggled));
80 TreeViewColumn* rec_state_column = manage (new TreeViewColumn("R", *rec_col_renderer));
82 rec_state_column->add_attribute(rec_col_renderer->property_active(), _columns.rec_enabled);
83 rec_state_column->add_attribute(rec_col_renderer->property_visible(), _columns.is_track);
86 CellRendererPixbufMulti* mute_col_renderer = manage (new CellRendererPixbufMulti());
88 mute_col_renderer->set_pixbuf (0, ::get_icon("act-disabled"));
89 mute_col_renderer->set_pixbuf (1, ::get_icon("mute-enabled"));
90 mute_col_renderer->signal_changed().connect (mem_fun (*this, &EditorRoutes::on_tv_mute_enable_toggled));
92 TreeViewColumn* mute_state_column = manage (new TreeViewColumn("M", *mute_col_renderer));
94 mute_state_column->add_attribute(mute_col_renderer->property_state(), _columns.mute_state);
97 CellRendererPixbufMulti* solo_col_renderer = manage (new CellRendererPixbufMulti());
99 solo_col_renderer->set_pixbuf (0, ::get_icon("act-disabled"));
100 solo_col_renderer->set_pixbuf (1, ::get_icon("solo-enabled"));
101 solo_col_renderer->signal_changed().connect (mem_fun (*this, &EditorRoutes::on_tv_solo_enable_toggled));
103 TreeViewColumn* solo_state_column = manage (new TreeViewColumn("S", *solo_col_renderer));
105 solo_state_column->add_attribute(solo_col_renderer->property_state(), _columns.solo_state);
107 _display.append_column (*rec_state_column);
108 _display.append_column (*mute_state_column);
109 _display.append_column (*solo_state_column);
110 _display.append_column (_("Show"), _columns.visible);
111 _display.append_column (_("Name"), _columns.text);
113 _display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0));
114 _display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1));
115 _display.get_column (2)->set_data (X_("colnum"), GUINT_TO_POINTER(2));
116 _display.get_column (3)->set_data (X_("colnum"), GUINT_TO_POINTER(3));
117 _display.get_column (4)->set_data (X_("colnum"), GUINT_TO_POINTER(4));
119 _display.set_headers_visible (true);
120 _display.set_name ("TrackListDisplay");
121 _display.get_selection()->set_mode (SELECTION_SINGLE);
122 _display.set_reorderable (true);
123 _display.set_rules_hint (true);
124 _display.set_size_request (100, -1);
125 _display.add_object_drag (_columns.route.index(), "routes");
127 CellRendererText* name_cell = dynamic_cast<CellRendererText*> (_display.get_column_cell_renderer (4));
130 TreeViewColumn* name_column = _display.get_column (4);
131 assert (name_column);
133 name_column->add_attribute (name_cell->property_editable(), _columns.name_editable);
134 name_cell->property_editable() = true;
135 name_cell->signal_edited().connect (mem_fun (*this, &EditorRoutes::name_edit));
137 CellRendererToggle* visible_cell = dynamic_cast<CellRendererToggle*> (_display.get_column_cell_renderer (3));
139 visible_cell->property_activatable() = true;
140 visible_cell->property_radio() = false;
141 visible_cell->signal_toggled().connect (mem_fun (*this, &EditorRoutes::visible_changed));
143 _model->signal_row_deleted().connect (mem_fun (*this, &EditorRoutes::route_deleted));
144 _model->signal_rows_reordered().connect (mem_fun (*this, &EditorRoutes::reordered));
145 _display.signal_button_press_event().connect (mem_fun (*this, &EditorRoutes::button_press), false);
147 Route::SyncOrderKeys.connect (mem_fun (*this, &EditorRoutes::sync_order_keys));
151 EditorRoutes::connect_to_session (Session* s)
153 EditorComponent::connect_to_session (s);
157 _session->SoloChanged.connect (mem_fun (*this, &EditorRoutes::solo_changed_so_update_mute));
161 EditorRoutes::on_tv_rec_enable_toggled (Glib::ustring const & path_string)
163 // Get the model row that has been toggled.
164 Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string));
166 row[_columns.name_editable] = !row[_columns.rec_enabled];
168 TimeAxisView *tv = row[_columns.tv];
169 AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
171 if (atv != 0 && atv->is_audio_track()){
172 atv->reversibly_apply_track_boolean ("rec-enable change", &Track::set_record_enable, !atv->track()->record_enabled(), this);
177 EditorRoutes::on_tv_mute_enable_toggled (Glib::ustring const & path_string)
179 // Get the model row that has been toggled.
180 Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string));
182 TimeAxisView *tv = row[_columns.tv];
183 AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
186 atv->reversibly_apply_route_boolean ("mute-enable change", &Route::set_mute, !atv->route()->muted(), this);
191 EditorRoutes::on_tv_solo_enable_toggled (Glib::ustring const & path_string)
193 // Get the model row that has been toggled.
194 Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string));
196 TimeAxisView *tv = row[_columns.tv];
197 AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
200 atv->reversibly_apply_route_boolean ("solo-enable change", &Route::set_solo, !atv->route()->soloed(), this);
205 EditorRoutes::build_menu ()
207 using namespace Menu_Helpers;
212 MenuList& items = _menu->items();
213 _menu->set_name ("ArdourContextMenu");
215 items.push_back (MenuElem (_("Show All"), mem_fun (*this, &EditorRoutes::show_all_routes)));
216 items.push_back (MenuElem (_("Hide All"), mem_fun (*this, &EditorRoutes::hide_all_routes)));
217 items.push_back (MenuElem (_("Show All Audio Tracks"), mem_fun (*this, &EditorRoutes::show_all_audiotracks)));
218 items.push_back (MenuElem (_("Hide All Audio Tracks"), mem_fun (*this, &EditorRoutes::hide_all_audiotracks)));
219 items.push_back (MenuElem (_("Show All Audio Busses"), mem_fun (*this, &EditorRoutes::show_all_audiobus)));
220 items.push_back (MenuElem (_("Hide All Audio Busses"), mem_fun (*this, &EditorRoutes::hide_all_audiobus)));
221 items.push_back (MenuElem (_("Show Tracks With Regions Under Playhead"), mem_fun (*this, &EditorRoutes::show_tracks_with_regions_at_playhead)));
225 EditorRoutes::show_menu ()
231 _menu->popup (1, gtk_get_current_event_time());
235 EditorRoutes::redisplay ()
237 TreeModel::Children rows = _model->children();
238 TreeModel::Children::iterator i;
246 for (n = 0, position = 0, i = rows.begin(); i != rows.end(); ++i) {
247 TimeAxisView *tv = (*i)[_columns.tv];
248 boost::shared_ptr<Route> route = (*i)[_columns.route];
251 // just a "title" row
255 if (!_redisplay_does_not_reset_order_keys) {
256 /* this reorder is caused by user action, so reassign sort order keys
259 route->set_order_key (N_ ("editor"), n);
262 bool visible = (*i)[_columns.visible];
264 /* show or hide the TimeAxisView */
266 tv->set_marked_for_display (true);
267 position += tv->show_at (position, n, &_editor->edit_controls_vbox);
268 tv->clip_to_viewport ();
270 tv->set_marked_for_display (false);
277 /* whenever we go idle, update the track view list to reflect the new order.
278 we can't do this here, because we could mess up something that is traversing
279 the track order and has caused a redisplay of the list.
281 Glib::signal_idle().connect (mem_fun (*_editor, &Editor::sync_track_view_list_and_routes));
283 _editor->full_canvas_height = position + _editor->canvas_timebars_vsize;
284 _editor->vertical_adjustment.set_upper (_editor->full_canvas_height);
286 if ((_editor->vertical_adjustment.get_value() + _editor->_canvas_height) > _editor->vertical_adjustment.get_upper()) {
288 We're increasing the size of the canvas while the bottom is visible.
289 We scroll down to keep in step with the controls layout.
291 _editor->vertical_adjustment.set_value (_editor->full_canvas_height - _editor->_canvas_height);
294 if (!_redisplay_does_not_reset_order_keys && !_redisplay_does_not_sync_order_keys) {
295 _session->sync_order_keys (N_ ("editor"));
300 EditorRoutes::route_deleted (Gtk::TreeModel::Path const &)
302 /* this could require an order reset & sync */
303 _session->set_remote_control_ids();
304 _ignore_reorder = true;
306 _ignore_reorder = false;
311 EditorRoutes::visible_changed (Glib::ustring const & path)
315 if ((iter = _model->get_iter (path))) {
316 TimeAxisView* tv = (*iter)[_columns.tv];
318 bool visible = (*iter)[_columns.visible];
319 (*iter)[_columns.visible] = !visible;
323 _redisplay_does_not_reset_order_keys = true;
324 _session->set_remote_control_ids();
326 _redisplay_does_not_reset_order_keys = false;
330 EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
334 _redisplay_does_not_sync_order_keys = true;
335 suspend_redisplay ();
337 for (list<RouteTimeAxisView*>::iterator x = routes.begin(); x != routes.end(); ++x) {
339 row = *(_model->append ());
341 row[_columns.text] = (*x)->route()->name();
342 row[_columns.visible] = (*x)->marked_for_display();
343 row[_columns.tv] = *x;
344 row[_columns.route] = (*x)->route ();
345 row[_columns.is_track] = (boost::dynamic_pointer_cast<Track> ((*x)->route()) != 0);
347 _ignore_reorder = true;
349 /* added a new fresh one at the end */
350 if ((*x)->route()->order_key (N_ ("editor")) == -1) {
351 (*x)->route()->set_order_key (N_ ("editor"), _model->children().size()-1);
354 _ignore_reorder = false;
356 boost::weak_ptr<Route> wr ((*x)->route());
357 (*x)->route()->gui_changed.connect (mem_fun (*this, &EditorRoutes::handle_gui_changes));
358 (*x)->route()->NameChanged.connect (bind (mem_fun (*this, &EditorRoutes::route_name_changed), wr));
359 (*x)->GoingAway.connect (bind (mem_fun (*this, &EditorRoutes::route_removed), *x));
361 if ((*x)->is_track()) {
362 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> ((*x)->route());
363 t->diskstream()->RecordEnableChanged.connect (mem_fun (*this, &EditorRoutes::update_rec_display));
366 (*x)->route()->mute_changed.connect (mem_fun (*this, &EditorRoutes::update_mute_display));
367 (*x)->route()->solo_changed.connect (mem_fun (*this, &EditorRoutes::update_solo_display));
370 update_rec_display ();
372 _redisplay_does_not_sync_order_keys = false;
376 EditorRoutes::handle_gui_changes (string const & what, void *src)
378 ENSURE_GUI_THREAD (bind (mem_fun(*this, &EditorRoutes::handle_gui_changes), what, src));
380 if (what == "track_height") {
381 /* Optional :make tracks change height while it happens, instead
384 //update_canvas_now ();
388 if (what == "visible_tracks") {
394 EditorRoutes::route_removed (TimeAxisView *tv)
396 ENSURE_GUI_THREAD (bind (mem_fun(*this, &EditorRoutes::route_removed), tv));
398 TreeModel::Children rows = _model->children();
399 TreeModel::Children::iterator ri;
401 /* the core model has changed, there is no need to sync
405 _redisplay_does_not_sync_order_keys = true;
407 for (ri = rows.begin(); ri != rows.end(); ++ri) {
408 if ((*ri)[_columns.tv] == tv) {
414 _redisplay_does_not_sync_order_keys = false;
418 EditorRoutes::route_name_changed (boost::weak_ptr<Route> r)
420 ENSURE_GUI_THREAD (bind (mem_fun (*this, &EditorRoutes::route_name_changed), r));
422 boost::shared_ptr<Route> route = r.lock ();
427 TreeModel::Children rows = _model->children();
428 TreeModel::Children::iterator i;
430 for (i = rows.begin(); i != rows.end(); ++i) {
431 boost::shared_ptr<Route> t = (*i)[_columns.route];
433 (*i)[_columns.text] = route->name();
440 EditorRoutes::update_visibility ()
442 TreeModel::Children rows = _model->children();
443 TreeModel::Children::iterator i;
445 suspend_redisplay ();
447 for (i = rows.begin(); i != rows.end(); ++i) {
448 TimeAxisView *tv = (*i)[_columns.tv];
449 (*i)[_columns.visible] = tv->marked_for_display ();
450 cerr << "marked " << tv->name() << " for display = " << tv->marked_for_display() << endl;
457 EditorRoutes::hide_track_in_display (TimeAxisView& tv)
459 TreeModel::Children rows = _model->children();
460 TreeModel::Children::iterator i;
462 for (i = rows.begin(); i != rows.end(); ++i) {
463 if ((*i)[_columns.tv] == &tv) {
464 (*i)[_columns.visible] = false;
471 EditorRoutes::show_track_in_display (TimeAxisView& tv)
473 TreeModel::Children rows = _model->children();
474 TreeModel::Children::iterator i;
476 for (i = rows.begin(); i != rows.end(); ++i) {
477 if ((*i)[_columns.tv] == &tv) {
478 (*i)[_columns.visible] = true;
485 EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, int* /*what*/)
490 /** If src != "editor", take editor order keys from each route and use them to rearrange the
491 * route list so that the visual arrangement of routes matches the order keys from the routes.
494 EditorRoutes::sync_order_keys (string const & src)
496 vector<int> neworder;
497 TreeModel::Children rows = _model->children();
498 TreeModel::Children::iterator ri;
500 if (src == N_ ("editor") || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
504 for (ri = rows.begin(); ri != rows.end(); ++ri) {
505 neworder.push_back (0);
508 bool changed = false;
511 for (order = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
512 boost::shared_ptr<Route> route = (*ri)[_columns.route];
515 int new_key = route->order_key (N_ ("editor"));
517 neworder[new_key] = old_key;
519 if (new_key != old_key) {
525 _redisplay_does_not_reset_order_keys = true;
526 _model->reorder (neworder);
527 _redisplay_does_not_reset_order_keys = false;
533 EditorRoutes::hide_all_tracks (bool /*with_select*/)
535 TreeModel::Children rows = _model->children();
536 TreeModel::Children::iterator i;
538 suspend_redisplay ();
540 for (i = rows.begin(); i != rows.end(); ++i) {
542 TreeModel::Row row = (*i);
543 TimeAxisView *tv = row[_columns.tv];
549 row[_columns.visible] = false;
554 /* XXX this seems like a hack and half, but its not clear where to put this
558 //reset_scrolling_region ();
562 EditorRoutes::set_all_tracks_visibility (bool yn)
564 TreeModel::Children rows = _model->children();
565 TreeModel::Children::iterator i;
567 suspend_redisplay ();
569 for (i = rows.begin(); i != rows.end(); ++i) {
571 TreeModel::Row row = (*i);
572 TimeAxisView* tv = row[_columns.tv];
578 (*i)[_columns.visible] = yn;
585 EditorRoutes::set_all_audio_visibility (int tracks, bool yn)
587 TreeModel::Children rows = _model->children();
588 TreeModel::Children::iterator i;
590 suspend_redisplay ();
592 for (i = rows.begin(); i != rows.end(); ++i) {
593 TreeModel::Row row = (*i);
594 TimeAxisView* tv = row[_columns.tv];
595 AudioTimeAxisView* atv;
601 if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
604 (*i)[_columns.visible] = yn;
608 if (atv->is_audio_track()) {
609 (*i)[_columns.visible] = yn;
614 if (!atv->is_audio_track()) {
615 (*i)[_columns.visible] = yn;
626 EditorRoutes::hide_all_routes ()
628 set_all_tracks_visibility (false);
632 EditorRoutes::show_all_routes ()
634 set_all_tracks_visibility (true);
638 EditorRoutes::show_all_audiobus ()
640 set_all_audio_visibility (2, true);
643 EditorRoutes::hide_all_audiobus ()
645 set_all_audio_visibility (2, false);
649 EditorRoutes::show_all_audiotracks()
651 set_all_audio_visibility (1, true);
654 EditorRoutes::hide_all_audiotracks ()
656 set_all_audio_visibility (1, false);
660 EditorRoutes::button_press (GdkEventButton* ev)
662 if (Keyboard::is_context_menu_event (ev)) {
671 EditorRoutes::selection_filter (Glib::RefPtr<TreeModel> const &, TreeModel::Path const &, bool)
676 struct EditorOrderRouteSorter {
677 bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
678 /* use of ">" forces the correct sort order */
679 return a->order_key (N_ ("editor")) < b->order_key (N_ ("editor"));
684 EditorRoutes::initial_display ()
686 boost::shared_ptr<RouteList> routes = _session->get_routes();
687 RouteList r (*routes);
688 EditorOrderRouteSorter sorter;
692 suspend_redisplay ();
695 _editor->handle_new_route (r);
697 /* don't show master bus in a new session */
699 if (ARDOUR_UI::instance()->session_is_new ()) {
701 TreeModel::Children rows = _model->children();
702 TreeModel::Children::iterator i;
704 _no_redisplay = true;
706 for (i = rows.begin(); i != rows.end(); ++i) {
707 TimeAxisView *tv = (*i)[_columns.tv];
708 RouteTimeAxisView *rtv;
710 if ((rtv = dynamic_cast<RouteTimeAxisView*>(tv)) != 0) {
711 if (rtv->route()->is_master()) {
712 _display.get_selection()->unselect (i);
717 _no_redisplay = false;
725 EditorRoutes::track_list_reorder (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &, int* /*new_order*/)
727 _redisplay_does_not_sync_order_keys = true;
728 _session->set_remote_control_ids();
730 _redisplay_does_not_sync_order_keys = false;
734 EditorRoutes::display_drag_data_received (const RefPtr<Gdk::DragContext>& context,
736 const SelectionData& data,
737 guint info, guint time)
739 if (data.get_target() == "GTK_TREE_MODEL_ROW") {
740 _display.on_drag_data_received (context, x, y, data, info, time);
744 context->drag_finish (true, false, time);
748 EditorRoutes::move_selected_tracks (bool up)
750 if (_editor->selection->tracks.empty()) {
754 typedef std::pair<TimeAxisView*,boost::shared_ptr<Route> > ViewRoute;
755 std::list<ViewRoute> view_routes;
756 std::vector<int> neworder;
757 TreeModel::Children rows = _model->children();
758 TreeModel::Children::iterator ri;
760 for (ri = rows.begin(); ri != rows.end(); ++ri) {
761 TimeAxisView* tv = (*ri)[_columns.tv];
762 boost::shared_ptr<Route> route = (*ri)[_columns.route];
764 view_routes.push_back (ViewRoute (tv, route));
767 list<ViewRoute>::iterator trailing;
768 list<ViewRoute>::iterator leading;
772 trailing = view_routes.begin();
773 leading = view_routes.begin();
777 while (leading != view_routes.end()) {
778 if (_editor->selection->selected (leading->first)) {
779 view_routes.insert (trailing, ViewRoute (leading->first, leading->second));
780 leading = view_routes.erase (leading);
789 /* if we could use reverse_iterator in list::insert, this code
790 would be a beautiful reflection of the code above. but we can't
791 and so it looks like a bit of a mess.
794 trailing = view_routes.end();
795 leading = view_routes.end();
797 --leading; if (leading == view_routes.begin()) { return; }
803 if (_editor->selection->selected (leading->first)) {
804 list<ViewRoute>::iterator tmp;
806 /* need to insert *after* trailing, not *before* it,
807 which is what insert (iter, val) normally does.
813 view_routes.insert (tmp, ViewRoute (leading->first, leading->second));
815 /* can't use iter = cont.erase (iter); form here, because
816 we need iter to move backwards.
824 if (leading == view_routes.begin()) {
825 /* the one we've just inserted somewhere else
826 was the first in the list. erase this copy,
827 and then break, because we're done.
832 view_routes.erase (leading);
841 if (leading == view_routes.begin()) {
850 for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) {
851 neworder.push_back (leading->second->order_key (N_ ("editor")));
854 _model->reorder (neworder);
856 _session->sync_order_keys (N_ ("editor"));
860 EditorRoutes::update_rec_display ()
862 TreeModel::Children rows = _model->children();
863 TreeModel::Children::iterator i;
865 for (i = rows.begin(); i != rows.end(); ++i) {
866 boost::shared_ptr<Route> route = (*i)[_columns.route];
868 if (boost::dynamic_pointer_cast<Track>(route)) {
869 (*i)[_columns.rec_enabled] = route->record_enabled ();
870 (*i)[_columns.name_editable] = !route->record_enabled ();
876 EditorRoutes::update_mute_display (void* /*src*/)
878 TreeModel::Children rows = _model->children();
879 TreeModel::Children::iterator i;
881 for (i = rows.begin(); i != rows.end(); ++i) {
882 boost::shared_ptr<Route> route = (*i)[_columns.route];
883 (*i)[_columns.mute_state] = RouteUI::mute_visual_state (*_session, route) > 0 ? 1 : 0;
888 EditorRoutes::update_solo_display (void* /*src*/)
890 TreeModel::Children rows = _model->children();
891 TreeModel::Children::iterator i;
893 for (i = rows.begin(); i != rows.end(); ++i) {
894 boost::shared_ptr<Route> route = (*i)[_columns.route];
895 (*i)[_columns.solo_state] = RouteUI::solo_visual_state (route) > 0 ? 1 : 0;
900 EditorRoutes::views () const
902 list<TimeAxisView*> v;
903 for (TreeModel::Children::iterator i = _model->children().begin(); i != _model->children().end(); ++i) {
904 v.push_back ((*i)[_columns.tv]);
911 EditorRoutes::clear ()
913 _display.set_model (Glib::RefPtr<Gtk::TreeStore> (0));
915 _display.set_model (_model);
919 EditorRoutes::name_edit (Glib::ustring const & path, Glib::ustring const & new_text)
921 TreeIter iter = _model->get_iter (path);
926 boost::shared_ptr<Route> route = (*iter)[_columns.route];
928 if (route && route->name() != new_text) {
929 route->set_name (new_text);
934 EditorRoutes::solo_changed_so_update_mute ()
936 ENSURE_GUI_THREAD (mem_fun (*this, &EditorRoutes::solo_changed_so_update_mute));
938 update_mute_display (this);
942 EditorRoutes::show_tracks_with_regions_at_playhead ()
944 boost::shared_ptr<RouteList> const r = _session->get_routes_with_regions_at (_session->transport_frame ());
946 set<TimeAxisView*> show;
947 for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
948 TimeAxisView* tav = _editor->axis_view_from_route (i->get ());
954 suspend_redisplay ();
956 TreeModel::Children rows = _model->children ();
957 for (TreeModel::Children::iterator i = rows.begin(); i != rows.end(); ++i) {
958 TimeAxisView* tv = (*i)[_columns.tv];
959 (*i)[_columns.visible] = (show.find (tv) != show.end());