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_toggle.h"
52 using namespace ARDOUR;
55 using namespace Gtkmm2ext;
58 EditorRoutes::EditorRoutes (Editor* e)
59 : EditorComponent (e),
60 _ignore_reorder (false),
61 _no_redisplay (false),
62 _redisplay_does_not_sync_order_keys (false),
63 _redisplay_does_not_reset_order_keys (false),
66 _scroller.add (_display);
67 _scroller.set_policy (POLICY_NEVER, POLICY_AUTOMATIC);
69 _model = ListStore::create (_columns);
70 _display.set_model (_model);
72 // Record enable toggle
73 CellRendererPixbufToggle* rec_col_renderer = manage (new CellRendererPixbufToggle());
75 rec_col_renderer->set_active_pixbuf (::get_icon("rec-enabled"));
76 rec_col_renderer->set_inactive_pixbuf (::get_icon("act-disabled"));
77 rec_col_renderer->signal_toggled().connect (mem_fun (*this, &EditorRoutes::on_tv_rec_enable_toggled));
79 Gtk::TreeViewColumn* rec_state_column = manage (new TreeViewColumn("R", *rec_col_renderer));
81 rec_state_column->add_attribute(rec_col_renderer->property_active(), _columns.rec_enabled);
82 rec_state_column->add_attribute(rec_col_renderer->property_visible(), _columns.is_track);
85 CellRendererPixbufToggle* mute_col_renderer = manage (new CellRendererPixbufToggle());
87 mute_col_renderer->set_active_pixbuf (::get_icon("mute-enabled"));
88 mute_col_renderer->set_inactive_pixbuf (::get_icon("act-disabled"));
89 mute_col_renderer->signal_toggled().connect (mem_fun (*this, &EditorRoutes::on_tv_mute_enable_toggled));
91 Gtk::TreeViewColumn* mute_state_column = manage (new TreeViewColumn("M", *mute_col_renderer));
93 mute_state_column->add_attribute(mute_col_renderer->property_active(), _columns.mute_enabled);
94 mute_state_column->add_attribute(mute_col_renderer->property_visible(), _columns.is_track);
97 CellRendererPixbufToggle* solo_col_renderer = manage (new CellRendererPixbufToggle());
99 solo_col_renderer->set_active_pixbuf (::get_icon("solo-enabled"));
100 solo_col_renderer->set_inactive_pixbuf (::get_icon("act-disabled"));
101 solo_col_renderer->signal_toggled().connect (mem_fun (*this, &EditorRoutes::on_tv_solo_enable_toggled));
103 Gtk::TreeViewColumn* solo_state_column = manage (new TreeViewColumn("S", *solo_col_renderer));
105 solo_state_column->add_attribute(solo_col_renderer->property_active(), _columns.solo_enabled);
106 solo_state_column->add_attribute(solo_col_renderer->property_visible(), _columns.is_track);
109 _display.append_column (*rec_state_column);
110 _display.append_column (*mute_state_column);
111 _display.append_column (*solo_state_column);
112 _display.append_column (_("Show"), _columns.visible);
113 _display.append_column (_("Name"), _columns.text);
115 _display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0));
116 _display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1));
117 _display.get_column (2)->set_data (X_("colnum"), GUINT_TO_POINTER(2));
118 _display.get_column (3)->set_data (X_("colnum"), GUINT_TO_POINTER(3));
119 _display.get_column (4)->set_data (X_("colnum"), GUINT_TO_POINTER(4));
121 _display.set_headers_visible (true);
122 _display.set_name ("TrackListDisplay");
123 _display.get_selection()->set_mode (SELECTION_SINGLE);
124 _display.set_reorderable (true);
125 _display.set_rules_hint (true);
126 _display.set_size_request (100, -1);
127 _display.add_object_drag (_columns.route.index(), "routes");
129 CellRendererText* name_cell = dynamic_cast<CellRendererText*> (_display.get_column_cell_renderer (4));
132 name_cell->property_editable() = true;
133 name_cell->signal_edited().connect (mem_fun (*this, &EditorRoutes::name_edit));
135 CellRendererToggle* visible_cell = dynamic_cast<CellRendererToggle*>(_display.get_column_cell_renderer (3));
137 visible_cell->property_activatable() = true;
138 visible_cell->property_radio() = false;
140 _model->signal_row_deleted().connect (mem_fun (*this, &EditorRoutes::route_deleted));
141 _model->signal_row_changed().connect (mem_fun (*this, &EditorRoutes::changed));
142 _model->signal_rows_reordered().connect (mem_fun (*this, &EditorRoutes::reordered));
143 _display.signal_button_press_event().connect (mem_fun (*this, &EditorRoutes::button_press), false);
145 Route::SyncOrderKeys.connect (mem_fun (*this, &EditorRoutes::sync_order_keys));
149 EditorRoutes::connect_to_session (Session* s)
151 EditorComponent::connect_to_session (s);
157 EditorRoutes::on_tv_rec_enable_toggled (Glib::ustring const & path_string)
159 // Get the model row that has been toggled.
160 Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string));
162 TimeAxisView *tv = row[_columns.tv];
163 AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
165 if (atv != 0 && atv->is_audio_track()){
166 atv->reversibly_apply_track_boolean ("rec-enable change", &Track::set_record_enable, !atv->track()->record_enabled(), this);
172 EditorRoutes::on_tv_mute_enable_toggled (Glib::ustring const & path_string)
174 // Get the model row that has been toggled.
175 Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string));
177 TimeAxisView *tv = row[_columns.tv];
178 AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
180 if (atv != 0 && atv->is_audio_track()){
181 atv->reversibly_apply_track_boolean ("mute-enable change", &Track::set_mute, !atv->track()->muted(), this);
188 EditorRoutes::on_tv_solo_enable_toggled (Glib::ustring const & path_string)
190 // Get the model row that has been toggled.
191 Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string));
193 TimeAxisView *tv = row[_columns.tv];
194 AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
196 if (atv != 0 && atv->is_audio_track()){
197 atv->reversibly_apply_track_boolean ("solo-enable change", &Track::set_solo, !atv->track()->soloed(), this);
203 EditorRoutes::build_menu ()
205 using namespace Menu_Helpers;
210 MenuList& items = _menu->items();
211 _menu->set_name ("ArdourContextMenu");
213 items.push_back (MenuElem (_("Show All"), mem_fun (*this, &EditorRoutes::show_all_routes)));
214 items.push_back (MenuElem (_("Hide All"), mem_fun (*this, &EditorRoutes::hide_all_routes)));
215 items.push_back (MenuElem (_("Show All Audio Tracks"), mem_fun (*this, &EditorRoutes::show_all_audiotracks)));
216 items.push_back (MenuElem (_("Hide All Audio Tracks"), mem_fun (*this, &EditorRoutes::hide_all_audiotracks)));
217 items.push_back (MenuElem (_("Show All Audio Busses"), mem_fun (*this, &EditorRoutes::show_all_audiobus)));
218 items.push_back (MenuElem (_("Hide All Audio Busses"), mem_fun (*this, &EditorRoutes::hide_all_audiobus)));
223 EditorRoutes::show_menu ()
229 _menu->popup (1, gtk_get_current_event_time());
233 EditorRoutes::redisplay ()
235 TreeModel::Children rows = _model->children();
236 TreeModel::Children::iterator i;
244 for (n = 0, position = 0, i = rows.begin(); i != rows.end(); ++i) {
245 TimeAxisView *tv = (*i)[_columns.tv];
246 boost::shared_ptr<Route> route = (*i)[_columns.route];
249 // just a "title" row
253 if (!_redisplay_does_not_reset_order_keys) {
254 /* this reorder is caused by user action, so reassign sort order keys
257 route->set_order_key (N_ ("editor"), n);
260 bool visible = (*i)[_columns.visible];
262 /* show or hide the TimeAxisView */
264 tv->set_marked_for_display (true);
265 position += tv->show_at (position, n, &_editor->edit_controls_vbox);
266 tv->clip_to_viewport ();
268 tv->set_marked_for_display (false);
275 /* whenever we go idle, update the track view list to reflect the new order.
276 we can't do this here, because we could mess up something that is traversing
277 the track order and has caused a redisplay of the list.
279 Glib::signal_idle().connect (mem_fun (*_editor, &Editor::sync_track_view_list_and_routes));
281 _editor->full_canvas_height = position + _editor->canvas_timebars_vsize;
282 _editor->vertical_adjustment.set_upper (_editor->full_canvas_height);
284 if ((_editor->vertical_adjustment.get_value() + _editor->_canvas_height) > _editor->vertical_adjustment.get_upper()) {
286 We're increasing the size of the canvas while the bottom is visible.
287 We scroll down to keep in step with the controls layout.
289 _editor->vertical_adjustment.set_value (_editor->full_canvas_height - _editor->_canvas_height);
292 if (!_redisplay_does_not_reset_order_keys && !_redisplay_does_not_sync_order_keys) {
293 _session->sync_order_keys (N_ ("editor"));
298 EditorRoutes::route_deleted (Gtk::TreeModel::Path const &)
300 /* this could require an order reset & sync */
301 _session->set_remote_control_ids();
302 _ignore_reorder = true;
304 _ignore_reorder = false;
309 EditorRoutes::changed (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &)
311 /* never reset order keys because of a property change */
312 _redisplay_does_not_reset_order_keys = true;
313 _session->set_remote_control_ids();
315 _redisplay_does_not_reset_order_keys = false;
319 EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
323 _redisplay_does_not_sync_order_keys = true;
324 suspend_redisplay ();
326 for (list<RouteTimeAxisView*>::iterator x = routes.begin(); x != routes.end(); ++x) {
328 row = *(_model->append ());
330 row[_columns.text] = (*x)->route()->name();
331 row[_columns.visible] = (*x)->marked_for_display();
332 row[_columns.tv] = *x;
333 row[_columns.route] = (*x)->route ();
334 row[_columns.is_track] = (boost::dynamic_pointer_cast<Track> ((*x)->route()) != 0);
336 _ignore_reorder = true;
338 /* added a new fresh one at the end */
339 if ((*x)->route()->order_key (N_ ("editor")) == -1) {
340 (*x)->route()->set_order_key (N_ ("editor"), _model->children().size()-1);
343 _ignore_reorder = false;
345 boost::weak_ptr<Route> wr ((*x)->route());
346 (*x)->route()->gui_changed.connect (mem_fun (*this, &EditorRoutes::handle_gui_changes));
347 (*x)->route()->NameChanged.connect (bind (mem_fun (*this, &EditorRoutes::route_name_changed), wr));
348 (*x)->GoingAway.connect (bind (mem_fun (*this, &EditorRoutes::route_removed), *x));
350 if ((*x)->is_track()) {
351 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> ((*x)->route());
352 t->diskstream()->RecordEnableChanged.connect (mem_fun (*this, &EditorRoutes::update_rec_display));
353 t->mute_changed.connect (mem_fun (*this, &EditorRoutes::update_mute_display));
354 t->solo_changed.connect (mem_fun (*this, &EditorRoutes::update_solo_display));
359 _redisplay_does_not_sync_order_keys = false;
363 EditorRoutes::handle_gui_changes (string const & what, void *src)
365 ENSURE_GUI_THREAD (bind (mem_fun(*this, &EditorRoutes::handle_gui_changes), what, src));
367 if (what == "track_height") {
368 /* Optional :make tracks change height while it happens, instead
371 //update_canvas_now ();
375 if (what == "visible_tracks") {
381 EditorRoutes::route_removed (TimeAxisView *tv)
383 ENSURE_GUI_THREAD (bind (mem_fun(*this, &EditorRoutes::route_removed), tv));
385 TreeModel::Children rows = _model->children();
386 TreeModel::Children::iterator ri;
388 /* the core model has changed, there is no need to sync
392 _redisplay_does_not_sync_order_keys = true;
394 for (ri = rows.begin(); ri != rows.end(); ++ri) {
395 if ((*ri)[_columns.tv] == tv) {
401 _redisplay_does_not_sync_order_keys = false;
405 EditorRoutes::route_name_changed (boost::weak_ptr<Route> r)
407 ENSURE_GUI_THREAD (bind (mem_fun (*this, &EditorRoutes::route_name_changed), r));
409 boost::shared_ptr<Route> route = r.lock ();
414 TreeModel::Children rows = _model->children();
415 TreeModel::Children::iterator i;
417 for (i = rows.begin(); i != rows.end(); ++i) {
418 boost::shared_ptr<Route> t = (*i)[_columns.route];
420 (*i)[_columns.text] = route->name();
427 EditorRoutes::update_visibility ()
429 TreeModel::Children rows = _model->children();
430 TreeModel::Children::iterator i;
432 suspend_redisplay ();
434 for (i = rows.begin(); i != rows.end(); ++i) {
435 TimeAxisView *tv = (*i)[_columns.tv];
436 (*i)[_columns.visible] = tv->marked_for_display ();
437 cerr << "marked " << tv->name() << " for display = " << tv->marked_for_display() << endl;
444 EditorRoutes::hide_track_in_display (TimeAxisView& tv)
446 TreeModel::Children rows = _model->children();
447 TreeModel::Children::iterator i;
449 for (i = rows.begin(); i != rows.end(); ++i) {
450 if ((*i)[_columns.tv] == &tv) {
451 (*i)[_columns.visible] = false;
458 EditorRoutes::show_track_in_display (TimeAxisView& tv)
460 TreeModel::Children rows = _model->children();
461 TreeModel::Children::iterator i;
463 for (i = rows.begin(); i != rows.end(); ++i) {
464 if ((*i)[_columns.tv] == &tv) {
465 (*i)[_columns.visible] = true;
472 EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, int* /*what*/)
477 /** If src != "editor", take editor order keys from each route and use them to rearrange the
478 * route list so that the visual arrangement of routes matches the order keys from the routes.
481 EditorRoutes::sync_order_keys (string const & src)
483 vector<int> neworder;
484 TreeModel::Children rows = _model->children();
485 TreeModel::Children::iterator ri;
487 if (src == N_ ("editor") || !_session || (_session->state_of_the_state() & Session::Loading) || rows.empty()) {
491 for (ri = rows.begin(); ri != rows.end(); ++ri) {
492 neworder.push_back (0);
495 bool changed = false;
498 for (order = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
499 boost::shared_ptr<Route> route = (*ri)[_columns.route];
502 int new_key = route->order_key (N_ ("editor"));
504 neworder[new_key] = old_key;
506 if (new_key != old_key) {
512 _redisplay_does_not_reset_order_keys = true;
513 _model->reorder (neworder);
514 _redisplay_does_not_reset_order_keys = false;
520 EditorRoutes::hide_all_tracks (bool /*with_select*/)
522 TreeModel::Children rows = _model->children();
523 TreeModel::Children::iterator i;
525 suspend_redisplay ();
527 for (i = rows.begin(); i != rows.end(); ++i) {
529 TreeModel::Row row = (*i);
530 TimeAxisView *tv = row[_columns.tv];
536 row[_columns.visible] = false;
541 /* XXX this seems like a hack and half, but its not clear where to put this
545 //reset_scrolling_region ();
549 EditorRoutes::set_all_tracks_visibility (bool yn)
551 TreeModel::Children rows = _model->children();
552 TreeModel::Children::iterator i;
554 suspend_redisplay ();
556 for (i = rows.begin(); i != rows.end(); ++i) {
558 TreeModel::Row row = (*i);
559 TimeAxisView* tv = row[_columns.tv];
565 (*i)[_columns.visible] = yn;
572 EditorRoutes::set_all_audio_visibility (int tracks, bool yn)
574 TreeModel::Children rows = _model->children();
575 TreeModel::Children::iterator i;
577 suspend_redisplay ();
579 for (i = rows.begin(); i != rows.end(); ++i) {
580 TreeModel::Row row = (*i);
581 TimeAxisView* tv = row[_columns.tv];
582 AudioTimeAxisView* atv;
588 if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
591 (*i)[_columns.visible] = yn;
595 if (atv->is_audio_track()) {
596 (*i)[_columns.visible] = yn;
601 if (!atv->is_audio_track()) {
602 (*i)[_columns.visible] = yn;
613 EditorRoutes::hide_all_routes ()
615 set_all_tracks_visibility (false);
619 EditorRoutes::show_all_routes ()
621 set_all_tracks_visibility (true);
625 EditorRoutes::show_all_audiobus ()
627 set_all_audio_visibility (2, true);
630 EditorRoutes::hide_all_audiobus ()
632 set_all_audio_visibility (2, false);
636 EditorRoutes::show_all_audiotracks()
638 set_all_audio_visibility (1, true);
641 EditorRoutes::hide_all_audiotracks ()
643 set_all_audio_visibility (1, false);
647 EditorRoutes::button_press (GdkEventButton* ev)
649 if (Keyboard::is_context_menu_event (ev)) {
655 TreeModel::Path path;
656 TreeViewColumn* column;
660 if (!_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) {
664 switch (GPOINTER_TO_UINT (column->get_data (X_("colnum")))) {
667 /* allow normal processing to occur */
670 /* allow normal processing to occur */
673 /* allow normal processing to occur */
676 if ((iter = _model->get_iter (path))) {
677 TimeAxisView* tv = (*iter)[_columns.tv];
679 bool visible = (*iter)[_columns.visible];
680 (*iter)[_columns.visible] = !visible;
686 /* allow normal processing to occur */
697 EditorRoutes::selection_filter (Glib::RefPtr<TreeModel> const &, TreeModel::Path const &, bool)
702 struct EditorOrderRouteSorter {
703 bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
704 /* use of ">" forces the correct sort order */
705 return a->order_key (N_ ("editor")) < b->order_key (N_ ("editor"));
710 EditorRoutes::initial_display ()
712 boost::shared_ptr<RouteList> routes = _session->get_routes();
713 RouteList r (*routes);
714 EditorOrderRouteSorter sorter;
718 suspend_redisplay ();
721 _editor->handle_new_route (r);
723 /* don't show master bus in a new session */
725 if (ARDOUR_UI::instance()->session_is_new ()) {
727 TreeModel::Children rows = _model->children();
728 TreeModel::Children::iterator i;
730 _no_redisplay = true;
732 for (i = rows.begin(); i != rows.end(); ++i) {
733 TimeAxisView *tv = (*i)[_columns.tv];
734 RouteTimeAxisView *rtv;
736 if ((rtv = dynamic_cast<RouteTimeAxisView*>(tv)) != 0) {
737 if (rtv->route()->is_master()) {
738 _display.get_selection()->unselect (i);
743 _no_redisplay = false;
751 EditorRoutes::track_list_reorder (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &, int* /*new_order*/)
753 _redisplay_does_not_sync_order_keys = true;
754 _session->set_remote_control_ids();
756 _redisplay_does_not_sync_order_keys = false;
760 EditorRoutes::display_drag_data_received (const RefPtr<Gdk::DragContext>& context,
762 const SelectionData& data,
763 guint info, guint time)
765 if (data.get_target() == "GTK_TREE_MODEL_ROW") {
766 _display.on_drag_data_received (context, x, y, data, info, time);
770 context->drag_finish (true, false, time);
774 EditorRoutes::move_selected_tracks (bool up)
776 if (_editor->selection->tracks.empty()) {
780 typedef std::pair<TimeAxisView*,boost::shared_ptr<Route> > ViewRoute;
781 std::list<ViewRoute> view_routes;
782 std::vector<int> neworder;
783 TreeModel::Children rows = _model->children();
784 TreeModel::Children::iterator ri;
786 for (ri = rows.begin(); ri != rows.end(); ++ri) {
787 TimeAxisView* tv = (*ri)[_columns.tv];
788 boost::shared_ptr<Route> route = (*ri)[_columns.route];
790 view_routes.push_back (ViewRoute (tv, route));
793 list<ViewRoute>::iterator trailing;
794 list<ViewRoute>::iterator leading;
798 trailing = view_routes.begin();
799 leading = view_routes.begin();
803 while (leading != view_routes.end()) {
804 if (_editor->selection->selected (leading->first)) {
805 view_routes.insert (trailing, ViewRoute (leading->first, leading->second));
806 leading = view_routes.erase (leading);
815 /* if we could use reverse_iterator in list::insert, this code
816 would be a beautiful reflection of the code above. but we can't
817 and so it looks like a bit of a mess.
820 trailing = view_routes.end();
821 leading = view_routes.end();
823 --leading; if (leading == view_routes.begin()) { return; }
829 if (_editor->selection->selected (leading->first)) {
830 list<ViewRoute>::iterator tmp;
832 /* need to insert *after* trailing, not *before* it,
833 which is what insert (iter, val) normally does.
839 view_routes.insert (tmp, ViewRoute (leading->first, leading->second));
841 /* can't use iter = cont.erase (iter); form here, because
842 we need iter to move backwards.
850 if (leading == view_routes.begin()) {
851 /* the one we've just inserted somewhere else
852 was the first in the list. erase this copy,
853 and then break, because we're done.
858 view_routes.erase (leading);
867 if (leading == view_routes.begin()) {
876 for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) {
877 neworder.push_back (leading->second->order_key (N_ ("editor")));
880 _model->reorder (neworder);
882 _session->sync_order_keys (N_ ("editor"));
886 EditorRoutes::update_rec_display ()
888 TreeModel::Children rows = _model->children();
889 TreeModel::Children::iterator i;
891 for (i = rows.begin(); i != rows.end(); ++i) {
892 boost::shared_ptr<Route> route = (*i)[_columns.route];
894 if (boost::dynamic_pointer_cast<Track>(route)) {
896 if (route->record_enabled()){
897 (*i)[_columns.rec_enabled] = true;
899 (*i)[_columns.rec_enabled] = false;
906 EditorRoutes::update_mute_display (void* /*src*/)
908 TreeModel::Children rows = _model->children();
909 TreeModel::Children::iterator i;
911 for (i = rows.begin(); i != rows.end(); ++i) {
912 boost::shared_ptr<Route> route = (*i)[_columns.route];
914 if (boost::dynamic_pointer_cast<Track>(route)) {
917 (*i)[_columns.mute_enabled] = true;
919 (*i)[_columns.mute_enabled] = false;
926 EditorRoutes::update_solo_display (void* /*src*/)
928 TreeModel::Children rows = _model->children();
929 TreeModel::Children::iterator i;
931 for (i = rows.begin(); i != rows.end(); ++i) {
932 boost::shared_ptr<Route> route = (*i)[_columns.route];
934 if (boost::dynamic_pointer_cast<Track>(route)) {
936 if (route->soloed()){
937 (*i)[_columns.solo_enabled] = true;
939 (*i)[_columns.solo_enabled] = false;
946 EditorRoutes::views () const
948 list<TimeAxisView*> v;
949 for (TreeModel::Children::iterator i = _model->children().begin(); i != _model->children().end(); ++i) {
950 v.push_back ((*i)[_columns.tv]);
957 EditorRoutes::clear ()
959 _display.set_model (Glib::RefPtr<Gtk::TreeStore> (0));
961 _display.set_model (_model);
965 EditorRoutes::name_edit (Glib::ustring const & path, Glib::ustring const & new_text)
967 TreeIter iter = _model->get_iter (path);
972 boost::shared_ptr<Route> route = (*iter)[_columns.route];
975 route->set_name (new_text);