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 Gtk::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 Gtk::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);
95 mute_state_column->add_attribute(mute_col_renderer->property_visible(), _columns.is_track);
98 CellRendererPixbufMulti* solo_col_renderer = manage (new CellRendererPixbufMulti());
100 solo_col_renderer->set_pixbuf (0, ::get_icon("act-disabled"));
101 solo_col_renderer->set_pixbuf (1, ::get_icon("solo-enabled"));
102 solo_col_renderer->signal_changed().connect (mem_fun (*this, &EditorRoutes::on_tv_solo_enable_toggled));
104 Gtk::TreeViewColumn* solo_state_column = manage (new TreeViewColumn("S", *solo_col_renderer));
106 solo_state_column->add_attribute(solo_col_renderer->property_state(), _columns.solo_state);
107 solo_state_column->add_attribute(solo_col_renderer->property_visible(), _columns.is_track);
110 _display.append_column (*rec_state_column);
111 _display.append_column (*mute_state_column);
112 _display.append_column (*solo_state_column);
113 _display.append_column (_("Show"), _columns.visible);
114 _display.append_column (_("Name"), _columns.text);
116 _display.get_column (0)->set_data (X_("colnum"), GUINT_TO_POINTER(0));
117 _display.get_column (1)->set_data (X_("colnum"), GUINT_TO_POINTER(1));
118 _display.get_column (2)->set_data (X_("colnum"), GUINT_TO_POINTER(2));
119 _display.get_column (3)->set_data (X_("colnum"), GUINT_TO_POINTER(3));
120 _display.get_column (4)->set_data (X_("colnum"), GUINT_TO_POINTER(4));
122 _display.set_headers_visible (true);
123 _display.set_name ("TrackListDisplay");
124 _display.get_selection()->set_mode (SELECTION_SINGLE);
125 _display.set_reorderable (true);
126 _display.set_rules_hint (true);
127 _display.set_size_request (100, -1);
128 _display.add_object_drag (_columns.route.index(), "routes");
130 CellRendererText* name_cell = dynamic_cast<CellRendererText*> (_display.get_column_cell_renderer (4));
133 name_cell->property_editable() = true;
134 name_cell->signal_edited().connect (mem_fun (*this, &EditorRoutes::name_edit));
136 CellRendererToggle* visible_cell = dynamic_cast<CellRendererToggle*>(_display.get_column_cell_renderer (3));
138 visible_cell->property_activatable() = true;
139 visible_cell->property_radio() = false;
141 _model->signal_row_deleted().connect (mem_fun (*this, &EditorRoutes::route_deleted));
142 _model->signal_row_changed().connect (mem_fun (*this, &EditorRoutes::changed));
143 _model->signal_rows_reordered().connect (mem_fun (*this, &EditorRoutes::reordered));
144 _display.signal_button_press_event().connect (mem_fun (*this, &EditorRoutes::button_press), false);
146 Route::SyncOrderKeys.connect (mem_fun (*this, &EditorRoutes::sync_order_keys));
150 EditorRoutes::connect_to_session (Session* s)
152 EditorComponent::connect_to_session (s);
158 EditorRoutes::on_tv_rec_enable_toggled (Glib::ustring const & path_string)
160 // Get the model row that has been toggled.
161 Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string));
163 TimeAxisView *tv = row[_columns.tv];
164 AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
166 if (atv != 0 && atv->is_audio_track()){
167 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);
186 EditorRoutes::on_tv_solo_enable_toggled (Glib::ustring const & path_string)
188 // Get the model row that has been toggled.
189 Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string));
191 TimeAxisView *tv = row[_columns.tv];
192 AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
194 if (atv != 0 && atv->is_audio_track()){
195 atv->reversibly_apply_track_boolean ("solo-enable change", &Track::set_solo, !atv->track()->soloed(), this);
200 EditorRoutes::build_menu ()
202 using namespace Menu_Helpers;
207 MenuList& items = _menu->items();
208 _menu->set_name ("ArdourContextMenu");
210 items.push_back (MenuElem (_("Show All"), mem_fun (*this, &EditorRoutes::show_all_routes)));
211 items.push_back (MenuElem (_("Hide All"), mem_fun (*this, &EditorRoutes::hide_all_routes)));
212 items.push_back (MenuElem (_("Show All Audio Tracks"), mem_fun (*this, &EditorRoutes::show_all_audiotracks)));
213 items.push_back (MenuElem (_("Hide All Audio Tracks"), mem_fun (*this, &EditorRoutes::hide_all_audiotracks)));
214 items.push_back (MenuElem (_("Show All Audio Busses"), mem_fun (*this, &EditorRoutes::show_all_audiobus)));
215 items.push_back (MenuElem (_("Hide All Audio Busses"), mem_fun (*this, &EditorRoutes::hide_all_audiobus)));
220 EditorRoutes::show_menu ()
226 _menu->popup (1, gtk_get_current_event_time());
230 EditorRoutes::redisplay ()
232 TreeModel::Children rows = _model->children();
233 TreeModel::Children::iterator i;
241 for (n = 0, position = 0, i = rows.begin(); i != rows.end(); ++i) {
242 TimeAxisView *tv = (*i)[_columns.tv];
243 boost::shared_ptr<Route> route = (*i)[_columns.route];
246 // just a "title" row
250 if (!_redisplay_does_not_reset_order_keys) {
251 /* this reorder is caused by user action, so reassign sort order keys
254 route->set_order_key (N_ ("editor"), n);
257 bool visible = (*i)[_columns.visible];
259 /* show or hide the TimeAxisView */
261 tv->set_marked_for_display (true);
262 position += tv->show_at (position, n, &_editor->edit_controls_vbox);
263 tv->clip_to_viewport ();
265 tv->set_marked_for_display (false);
272 /* whenever we go idle, update the track view list to reflect the new order.
273 we can't do this here, because we could mess up something that is traversing
274 the track order and has caused a redisplay of the list.
276 Glib::signal_idle().connect (mem_fun (*_editor, &Editor::sync_track_view_list_and_routes));
278 _editor->full_canvas_height = position + _editor->canvas_timebars_vsize;
279 _editor->vertical_adjustment.set_upper (_editor->full_canvas_height);
281 if ((_editor->vertical_adjustment.get_value() + _editor->_canvas_height) > _editor->vertical_adjustment.get_upper()) {
283 We're increasing the size of the canvas while the bottom is visible.
284 We scroll down to keep in step with the controls layout.
286 _editor->vertical_adjustment.set_value (_editor->full_canvas_height - _editor->_canvas_height);
289 if (!_redisplay_does_not_reset_order_keys && !_redisplay_does_not_sync_order_keys) {
290 _session->sync_order_keys (N_ ("editor"));
295 EditorRoutes::route_deleted (Gtk::TreeModel::Path const &)
297 /* this could require an order reset & sync */
298 _session->set_remote_control_ids();
299 _ignore_reorder = true;
301 _ignore_reorder = false;
306 EditorRoutes::changed (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &)
308 /* never reset order keys because of a property change */
309 _redisplay_does_not_reset_order_keys = true;
310 _session->set_remote_control_ids();
312 _redisplay_does_not_reset_order_keys = false;
316 EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
320 _redisplay_does_not_sync_order_keys = true;
321 suspend_redisplay ();
323 for (list<RouteTimeAxisView*>::iterator x = routes.begin(); x != routes.end(); ++x) {
325 row = *(_model->append ());
327 row[_columns.text] = (*x)->route()->name();
328 row[_columns.visible] = (*x)->marked_for_display();
329 row[_columns.tv] = *x;
330 row[_columns.route] = (*x)->route ();
331 row[_columns.is_track] = (boost::dynamic_pointer_cast<Track> ((*x)->route()) != 0);
333 _ignore_reorder = true;
335 /* added a new fresh one at the end */
336 if ((*x)->route()->order_key (N_ ("editor")) == -1) {
337 (*x)->route()->set_order_key (N_ ("editor"), _model->children().size()-1);
340 _ignore_reorder = false;
342 boost::weak_ptr<Route> wr ((*x)->route());
343 (*x)->route()->gui_changed.connect (mem_fun (*this, &EditorRoutes::handle_gui_changes));
344 (*x)->route()->NameChanged.connect (bind (mem_fun (*this, &EditorRoutes::route_name_changed), wr));
345 (*x)->GoingAway.connect (bind (mem_fun (*this, &EditorRoutes::route_removed), *x));
347 if ((*x)->is_track()) {
348 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> ((*x)->route());
349 t->diskstream()->RecordEnableChanged.connect (mem_fun (*this, &EditorRoutes::update_rec_display));
350 t->mute_changed.connect (mem_fun (*this, &EditorRoutes::update_mute_display));
351 t->solo_changed.connect (mem_fun (*this, &EditorRoutes::update_solo_display));
356 _redisplay_does_not_sync_order_keys = false;
360 EditorRoutes::handle_gui_changes (string const & what, void *src)
362 ENSURE_GUI_THREAD (bind (mem_fun(*this, &EditorRoutes::handle_gui_changes), what, src));
364 if (what == "track_height") {
365 /* Optional :make tracks change height while it happens, instead
368 //update_canvas_now ();
372 if (what == "visible_tracks") {
378 EditorRoutes::route_removed (TimeAxisView *tv)
380 ENSURE_GUI_THREAD (bind (mem_fun(*this, &EditorRoutes::route_removed), tv));
382 TreeModel::Children rows = _model->children();
383 TreeModel::Children::iterator ri;
385 /* the core model has changed, there is no need to sync
389 _redisplay_does_not_sync_order_keys = true;
391 for (ri = rows.begin(); ri != rows.end(); ++ri) {
392 if ((*ri)[_columns.tv] == tv) {
398 _redisplay_does_not_sync_order_keys = false;
402 EditorRoutes::route_name_changed (boost::weak_ptr<Route> r)
404 ENSURE_GUI_THREAD (bind (mem_fun (*this, &EditorRoutes::route_name_changed), r));
406 boost::shared_ptr<Route> route = r.lock ();
411 TreeModel::Children rows = _model->children();
412 TreeModel::Children::iterator i;
414 for (i = rows.begin(); i != rows.end(); ++i) {
415 boost::shared_ptr<Route> t = (*i)[_columns.route];
417 (*i)[_columns.text] = route->name();
424 EditorRoutes::update_visibility ()
426 TreeModel::Children rows = _model->children();
427 TreeModel::Children::iterator i;
429 suspend_redisplay ();
431 for (i = rows.begin(); i != rows.end(); ++i) {
432 TimeAxisView *tv = (*i)[_columns.tv];
433 (*i)[_columns.visible] = tv->marked_for_display ();
434 cerr << "marked " << tv->name() << " for display = " << tv->marked_for_display() << endl;
441 EditorRoutes::hide_track_in_display (TimeAxisView& tv)
443 TreeModel::Children rows = _model->children();
444 TreeModel::Children::iterator i;
446 for (i = rows.begin(); i != rows.end(); ++i) {
447 if ((*i)[_columns.tv] == &tv) {
448 (*i)[_columns.visible] = false;
455 EditorRoutes::show_track_in_display (TimeAxisView& tv)
457 TreeModel::Children rows = _model->children();
458 TreeModel::Children::iterator i;
460 for (i = rows.begin(); i != rows.end(); ++i) {
461 if ((*i)[_columns.tv] == &tv) {
462 (*i)[_columns.visible] = true;
469 EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, int* /*what*/)
474 /** If src != "editor", take editor order keys from each route and use them to rearrange the
475 * route list so that the visual arrangement of routes matches the order keys from the routes.
478 EditorRoutes::sync_order_keys (string const & src)
480 vector<int> neworder;
481 TreeModel::Children rows = _model->children();
482 TreeModel::Children::iterator ri;
484 if (src == N_ ("editor") || !_session || (_session->state_of_the_state() & Session::Loading) || rows.empty()) {
488 for (ri = rows.begin(); ri != rows.end(); ++ri) {
489 neworder.push_back (0);
492 bool changed = false;
495 for (order = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
496 boost::shared_ptr<Route> route = (*ri)[_columns.route];
499 int new_key = route->order_key (N_ ("editor"));
501 neworder[new_key] = old_key;
503 if (new_key != old_key) {
509 _redisplay_does_not_reset_order_keys = true;
510 _model->reorder (neworder);
511 _redisplay_does_not_reset_order_keys = false;
517 EditorRoutes::hide_all_tracks (bool /*with_select*/)
519 TreeModel::Children rows = _model->children();
520 TreeModel::Children::iterator i;
522 suspend_redisplay ();
524 for (i = rows.begin(); i != rows.end(); ++i) {
526 TreeModel::Row row = (*i);
527 TimeAxisView *tv = row[_columns.tv];
533 row[_columns.visible] = false;
538 /* XXX this seems like a hack and half, but its not clear where to put this
542 //reset_scrolling_region ();
546 EditorRoutes::set_all_tracks_visibility (bool yn)
548 TreeModel::Children rows = _model->children();
549 TreeModel::Children::iterator i;
551 suspend_redisplay ();
553 for (i = rows.begin(); i != rows.end(); ++i) {
555 TreeModel::Row row = (*i);
556 TimeAxisView* tv = row[_columns.tv];
562 (*i)[_columns.visible] = yn;
569 EditorRoutes::set_all_audio_visibility (int tracks, bool yn)
571 TreeModel::Children rows = _model->children();
572 TreeModel::Children::iterator i;
574 suspend_redisplay ();
576 for (i = rows.begin(); i != rows.end(); ++i) {
577 TreeModel::Row row = (*i);
578 TimeAxisView* tv = row[_columns.tv];
579 AudioTimeAxisView* atv;
585 if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
588 (*i)[_columns.visible] = yn;
592 if (atv->is_audio_track()) {
593 (*i)[_columns.visible] = yn;
598 if (!atv->is_audio_track()) {
599 (*i)[_columns.visible] = yn;
610 EditorRoutes::hide_all_routes ()
612 set_all_tracks_visibility (false);
616 EditorRoutes::show_all_routes ()
618 set_all_tracks_visibility (true);
622 EditorRoutes::show_all_audiobus ()
624 set_all_audio_visibility (2, true);
627 EditorRoutes::hide_all_audiobus ()
629 set_all_audio_visibility (2, false);
633 EditorRoutes::show_all_audiotracks()
635 set_all_audio_visibility (1, true);
638 EditorRoutes::hide_all_audiotracks ()
640 set_all_audio_visibility (1, false);
644 EditorRoutes::button_press (GdkEventButton* ev)
646 if (Keyboard::is_context_menu_event (ev)) {
652 TreeModel::Path path;
653 TreeViewColumn* column;
657 if (!_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) {
661 switch (GPOINTER_TO_UINT (column->get_data (X_("colnum")))) {
664 /* allow normal processing to occur */
667 /* allow normal processing to occur */
670 /* allow normal processing to occur */
673 if ((iter = _model->get_iter (path))) {
674 TimeAxisView* tv = (*iter)[_columns.tv];
676 bool visible = (*iter)[_columns.visible];
677 (*iter)[_columns.visible] = !visible;
683 /* allow normal processing to occur */
694 EditorRoutes::selection_filter (Glib::RefPtr<TreeModel> const &, TreeModel::Path const &, bool)
699 struct EditorOrderRouteSorter {
700 bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
701 /* use of ">" forces the correct sort order */
702 return a->order_key (N_ ("editor")) < b->order_key (N_ ("editor"));
707 EditorRoutes::initial_display ()
709 boost::shared_ptr<RouteList> routes = _session->get_routes();
710 RouteList r (*routes);
711 EditorOrderRouteSorter sorter;
715 suspend_redisplay ();
718 _editor->handle_new_route (r);
720 /* don't show master bus in a new session */
722 if (ARDOUR_UI::instance()->session_is_new ()) {
724 TreeModel::Children rows = _model->children();
725 TreeModel::Children::iterator i;
727 _no_redisplay = true;
729 for (i = rows.begin(); i != rows.end(); ++i) {
730 TimeAxisView *tv = (*i)[_columns.tv];
731 RouteTimeAxisView *rtv;
733 if ((rtv = dynamic_cast<RouteTimeAxisView*>(tv)) != 0) {
734 if (rtv->route()->is_master()) {
735 _display.get_selection()->unselect (i);
740 _no_redisplay = false;
748 EditorRoutes::track_list_reorder (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &, int* /*new_order*/)
750 _redisplay_does_not_sync_order_keys = true;
751 _session->set_remote_control_ids();
753 _redisplay_does_not_sync_order_keys = false;
757 EditorRoutes::display_drag_data_received (const RefPtr<Gdk::DragContext>& context,
759 const SelectionData& data,
760 guint info, guint time)
762 if (data.get_target() == "GTK_TREE_MODEL_ROW") {
763 _display.on_drag_data_received (context, x, y, data, info, time);
767 context->drag_finish (true, false, time);
771 EditorRoutes::move_selected_tracks (bool up)
773 if (_editor->selection->tracks.empty()) {
777 typedef std::pair<TimeAxisView*,boost::shared_ptr<Route> > ViewRoute;
778 std::list<ViewRoute> view_routes;
779 std::vector<int> neworder;
780 TreeModel::Children rows = _model->children();
781 TreeModel::Children::iterator ri;
783 for (ri = rows.begin(); ri != rows.end(); ++ri) {
784 TimeAxisView* tv = (*ri)[_columns.tv];
785 boost::shared_ptr<Route> route = (*ri)[_columns.route];
787 view_routes.push_back (ViewRoute (tv, route));
790 list<ViewRoute>::iterator trailing;
791 list<ViewRoute>::iterator leading;
795 trailing = view_routes.begin();
796 leading = view_routes.begin();
800 while (leading != view_routes.end()) {
801 if (_editor->selection->selected (leading->first)) {
802 view_routes.insert (trailing, ViewRoute (leading->first, leading->second));
803 leading = view_routes.erase (leading);
812 /* if we could use reverse_iterator in list::insert, this code
813 would be a beautiful reflection of the code above. but we can't
814 and so it looks like a bit of a mess.
817 trailing = view_routes.end();
818 leading = view_routes.end();
820 --leading; if (leading == view_routes.begin()) { return; }
826 if (_editor->selection->selected (leading->first)) {
827 list<ViewRoute>::iterator tmp;
829 /* need to insert *after* trailing, not *before* it,
830 which is what insert (iter, val) normally does.
836 view_routes.insert (tmp, ViewRoute (leading->first, leading->second));
838 /* can't use iter = cont.erase (iter); form here, because
839 we need iter to move backwards.
847 if (leading == view_routes.begin()) {
848 /* the one we've just inserted somewhere else
849 was the first in the list. erase this copy,
850 and then break, because we're done.
855 view_routes.erase (leading);
864 if (leading == view_routes.begin()) {
873 for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) {
874 neworder.push_back (leading->second->order_key (N_ ("editor")));
877 _model->reorder (neworder);
879 _session->sync_order_keys (N_ ("editor"));
883 EditorRoutes::update_rec_display ()
885 TreeModel::Children rows = _model->children();
886 TreeModel::Children::iterator i;
888 for (i = rows.begin(); i != rows.end(); ++i) {
889 boost::shared_ptr<Route> route = (*i)[_columns.route];
891 if (boost::dynamic_pointer_cast<Track>(route)) {
893 if (route->record_enabled()){
894 (*i)[_columns.rec_enabled] = true;
896 (*i)[_columns.rec_enabled] = false;
903 EditorRoutes::update_mute_display (void* /*src*/)
905 TreeModel::Children rows = _model->children();
906 TreeModel::Children::iterator i;
908 for (i = rows.begin(); i != rows.end(); ++i) {
909 boost::shared_ptr<Route> route = (*i)[_columns.route];
911 if (boost::dynamic_pointer_cast<Track>(route)) {
914 (*i)[_columns.mute_state] = 1;
916 (*i)[_columns.mute_state] = 0;
923 EditorRoutes::update_solo_display (void* /*src*/)
925 TreeModel::Children rows = _model->children();
926 TreeModel::Children::iterator i;
928 for (i = rows.begin(); i != rows.end(); ++i) {
929 boost::shared_ptr<Route> route = (*i)[_columns.route];
931 if (boost::dynamic_pointer_cast<Track>(route)) {
933 if (route->soloed()){
934 (*i)[_columns.solo_state] = 1;
936 (*i)[_columns.solo_state] = 0;
943 EditorRoutes::views () const
945 list<TimeAxisView*> v;
946 for (TreeModel::Children::iterator i = _model->children().begin(); i != _model->children().end(); ++i) {
947 v.push_back ((*i)[_columns.tv]);
954 EditorRoutes::clear ()
956 _display.set_model (Glib::RefPtr<Gtk::TreeStore> (0));
958 _display.set_model (_model);
962 EditorRoutes::name_edit (Glib::ustring const & path, Glib::ustring const & new_text)
964 TreeIter iter = _model->get_iter (path);
969 boost::shared_ptr<Route> route = (*iter)[_columns.route];
972 route->set_name (new_text);