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 Gtk::TreeViewColumn* name_column = _display.get_column (4);
134 assert (name_column);
136 name_column->add_attribute (name_cell->property_editable(), _columns.name_editable);
138 name_cell->property_editable() = true;
139 name_cell->signal_edited().connect (mem_fun (*this, &EditorRoutes::name_edit));
141 CellRendererToggle* visible_cell = dynamic_cast<CellRendererToggle*>(_display.get_column_cell_renderer (3));
143 visible_cell->property_activatable() = true;
144 visible_cell->property_radio() = false;
146 _model->signal_row_deleted().connect (mem_fun (*this, &EditorRoutes::route_deleted));
147 _model->signal_row_changed().connect (mem_fun (*this, &EditorRoutes::changed));
148 _model->signal_rows_reordered().connect (mem_fun (*this, &EditorRoutes::reordered));
149 _display.signal_button_press_event().connect (mem_fun (*this, &EditorRoutes::button_press), false);
151 Route::SyncOrderKeys.connect (mem_fun (*this, &EditorRoutes::sync_order_keys));
155 EditorRoutes::connect_to_session (Session* s)
157 EditorComponent::connect_to_session (s);
163 EditorRoutes::on_tv_rec_enable_toggled (Glib::ustring const & path_string)
165 // Get the model row that has been toggled.
166 Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string));
168 row[_columns.name_editable] = !row[_columns.rec_enabled];
170 TimeAxisView *tv = row[_columns.tv];
171 AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
173 if (atv != 0 && atv->is_audio_track()){
174 atv->reversibly_apply_track_boolean ("rec-enable change", &Track::set_record_enable, !atv->track()->record_enabled(), this);
179 EditorRoutes::on_tv_mute_enable_toggled (Glib::ustring const & path_string)
181 // Get the model row that has been toggled.
182 Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string));
184 TimeAxisView *tv = row[_columns.tv];
185 AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
187 if (atv != 0 && atv->is_audio_track()){
188 atv->reversibly_apply_track_boolean ("mute-enable change", &Track::set_mute, !atv->track()->muted(), this);
193 EditorRoutes::on_tv_solo_enable_toggled (Glib::ustring const & path_string)
195 // Get the model row that has been toggled.
196 Gtk::TreeModel::Row row = *_model->get_iter (Gtk::TreeModel::Path (path_string));
198 TimeAxisView *tv = row[_columns.tv];
199 AudioTimeAxisView *atv = dynamic_cast<AudioTimeAxisView*> (tv);
201 if (atv != 0 && atv->is_audio_track()){
202 atv->reversibly_apply_track_boolean ("solo-enable change", &Track::set_solo, !atv->track()->soloed(), this);
207 EditorRoutes::build_menu ()
209 using namespace Menu_Helpers;
214 MenuList& items = _menu->items();
215 _menu->set_name ("ArdourContextMenu");
217 items.push_back (MenuElem (_("Show All"), mem_fun (*this, &EditorRoutes::show_all_routes)));
218 items.push_back (MenuElem (_("Hide All"), mem_fun (*this, &EditorRoutes::hide_all_routes)));
219 items.push_back (MenuElem (_("Show All Audio Tracks"), mem_fun (*this, &EditorRoutes::show_all_audiotracks)));
220 items.push_back (MenuElem (_("Hide All Audio Tracks"), mem_fun (*this, &EditorRoutes::hide_all_audiotracks)));
221 items.push_back (MenuElem (_("Show All Audio Busses"), mem_fun (*this, &EditorRoutes::show_all_audiobus)));
222 items.push_back (MenuElem (_("Hide All Audio Busses"), mem_fun (*this, &EditorRoutes::hide_all_audiobus)));
227 EditorRoutes::show_menu ()
233 _menu->popup (1, gtk_get_current_event_time());
237 EditorRoutes::redisplay ()
239 TreeModel::Children rows = _model->children();
240 TreeModel::Children::iterator i;
248 for (n = 0, position = 0, i = rows.begin(); i != rows.end(); ++i) {
249 TimeAxisView *tv = (*i)[_columns.tv];
250 boost::shared_ptr<Route> route = (*i)[_columns.route];
253 // just a "title" row
257 if (!_redisplay_does_not_reset_order_keys) {
258 /* this reorder is caused by user action, so reassign sort order keys
261 route->set_order_key (N_ ("editor"), n);
264 bool visible = (*i)[_columns.visible];
266 /* show or hide the TimeAxisView */
268 tv->set_marked_for_display (true);
269 position += tv->show_at (position, n, &_editor->edit_controls_vbox);
270 tv->clip_to_viewport ();
272 tv->set_marked_for_display (false);
279 /* whenever we go idle, update the track view list to reflect the new order.
280 we can't do this here, because we could mess up something that is traversing
281 the track order and has caused a redisplay of the list.
283 Glib::signal_idle().connect (mem_fun (*_editor, &Editor::sync_track_view_list_and_routes));
285 _editor->full_canvas_height = position + _editor->canvas_timebars_vsize;
286 _editor->vertical_adjustment.set_upper (_editor->full_canvas_height);
288 if ((_editor->vertical_adjustment.get_value() + _editor->_canvas_height) > _editor->vertical_adjustment.get_upper()) {
290 We're increasing the size of the canvas while the bottom is visible.
291 We scroll down to keep in step with the controls layout.
293 _editor->vertical_adjustment.set_value (_editor->full_canvas_height - _editor->_canvas_height);
296 if (!_redisplay_does_not_reset_order_keys && !_redisplay_does_not_sync_order_keys) {
297 _session->sync_order_keys (N_ ("editor"));
302 EditorRoutes::route_deleted (Gtk::TreeModel::Path const &)
304 /* this could require an order reset & sync */
305 _session->set_remote_control_ids();
306 _ignore_reorder = true;
308 _ignore_reorder = false;
313 EditorRoutes::changed (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &)
315 /* never reset order keys because of a property change */
316 _redisplay_does_not_reset_order_keys = true;
317 _session->set_remote_control_ids();
319 _redisplay_does_not_reset_order_keys = false;
323 EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
327 _redisplay_does_not_sync_order_keys = true;
328 suspend_redisplay ();
330 for (list<RouteTimeAxisView*>::iterator x = routes.begin(); x != routes.end(); ++x) {
332 row = *(_model->append ());
334 row[_columns.text] = (*x)->route()->name();
335 row[_columns.visible] = (*x)->marked_for_display();
336 row[_columns.tv] = *x;
337 row[_columns.route] = (*x)->route ();
338 row[_columns.is_track] = (boost::dynamic_pointer_cast<Track> ((*x)->route()) != 0);
340 _ignore_reorder = true;
342 /* added a new fresh one at the end */
343 if ((*x)->route()->order_key (N_ ("editor")) == -1) {
344 (*x)->route()->set_order_key (N_ ("editor"), _model->children().size()-1);
347 _ignore_reorder = false;
349 boost::weak_ptr<Route> wr ((*x)->route());
350 (*x)->route()->gui_changed.connect (mem_fun (*this, &EditorRoutes::handle_gui_changes));
351 (*x)->route()->NameChanged.connect (bind (mem_fun (*this, &EditorRoutes::route_name_changed), wr));
352 (*x)->GoingAway.connect (bind (mem_fun (*this, &EditorRoutes::route_removed), *x));
354 if ((*x)->is_track()) {
355 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> ((*x)->route());
356 t->diskstream()->RecordEnableChanged.connect (mem_fun (*this, &EditorRoutes::update_rec_display));
357 t->mute_changed.connect (mem_fun (*this, &EditorRoutes::update_mute_display));
358 t->solo_changed.connect (mem_fun (*this, &EditorRoutes::update_solo_display));
362 update_rec_display ();
364 _redisplay_does_not_sync_order_keys = false;
368 EditorRoutes::handle_gui_changes (string const & what, void *src)
370 ENSURE_GUI_THREAD (bind (mem_fun(*this, &EditorRoutes::handle_gui_changes), what, src));
372 if (what == "track_height") {
373 /* Optional :make tracks change height while it happens, instead
376 //update_canvas_now ();
380 if (what == "visible_tracks") {
386 EditorRoutes::route_removed (TimeAxisView *tv)
388 ENSURE_GUI_THREAD (bind (mem_fun(*this, &EditorRoutes::route_removed), tv));
390 TreeModel::Children rows = _model->children();
391 TreeModel::Children::iterator ri;
393 /* the core model has changed, there is no need to sync
397 _redisplay_does_not_sync_order_keys = true;
399 for (ri = rows.begin(); ri != rows.end(); ++ri) {
400 if ((*ri)[_columns.tv] == tv) {
406 _redisplay_does_not_sync_order_keys = false;
410 EditorRoutes::route_name_changed (boost::weak_ptr<Route> r)
412 ENSURE_GUI_THREAD (bind (mem_fun (*this, &EditorRoutes::route_name_changed), r));
414 boost::shared_ptr<Route> route = r.lock ();
419 TreeModel::Children rows = _model->children();
420 TreeModel::Children::iterator i;
422 for (i = rows.begin(); i != rows.end(); ++i) {
423 boost::shared_ptr<Route> t = (*i)[_columns.route];
425 (*i)[_columns.text] = route->name();
432 EditorRoutes::update_visibility ()
434 TreeModel::Children rows = _model->children();
435 TreeModel::Children::iterator i;
437 suspend_redisplay ();
439 for (i = rows.begin(); i != rows.end(); ++i) {
440 TimeAxisView *tv = (*i)[_columns.tv];
441 (*i)[_columns.visible] = tv->marked_for_display ();
442 cerr << "marked " << tv->name() << " for display = " << tv->marked_for_display() << endl;
449 EditorRoutes::hide_track_in_display (TimeAxisView& tv)
451 TreeModel::Children rows = _model->children();
452 TreeModel::Children::iterator i;
454 for (i = rows.begin(); i != rows.end(); ++i) {
455 if ((*i)[_columns.tv] == &tv) {
456 (*i)[_columns.visible] = false;
463 EditorRoutes::show_track_in_display (TimeAxisView& tv)
465 TreeModel::Children rows = _model->children();
466 TreeModel::Children::iterator i;
468 for (i = rows.begin(); i != rows.end(); ++i) {
469 if ((*i)[_columns.tv] == &tv) {
470 (*i)[_columns.visible] = true;
477 EditorRoutes::reordered (TreeModel::Path const &, TreeModel::iterator const &, int* /*what*/)
482 /** If src != "editor", take editor order keys from each route and use them to rearrange the
483 * route list so that the visual arrangement of routes matches the order keys from the routes.
486 EditorRoutes::sync_order_keys (string const & src)
488 vector<int> neworder;
489 TreeModel::Children rows = _model->children();
490 TreeModel::Children::iterator ri;
492 if (src == N_ ("editor") || !_session || (_session->state_of_the_state() & (Session::Loading|Session::Deletion)) || rows.empty()) {
496 for (ri = rows.begin(); ri != rows.end(); ++ri) {
497 neworder.push_back (0);
500 bool changed = false;
503 for (order = 0, ri = rows.begin(); ri != rows.end(); ++ri, ++order) {
504 boost::shared_ptr<Route> route = (*ri)[_columns.route];
507 int new_key = route->order_key (N_ ("editor"));
509 neworder[new_key] = old_key;
511 if (new_key != old_key) {
517 _redisplay_does_not_reset_order_keys = true;
518 _model->reorder (neworder);
519 _redisplay_does_not_reset_order_keys = false;
525 EditorRoutes::hide_all_tracks (bool /*with_select*/)
527 TreeModel::Children rows = _model->children();
528 TreeModel::Children::iterator i;
530 suspend_redisplay ();
532 for (i = rows.begin(); i != rows.end(); ++i) {
534 TreeModel::Row row = (*i);
535 TimeAxisView *tv = row[_columns.tv];
541 row[_columns.visible] = false;
546 /* XXX this seems like a hack and half, but its not clear where to put this
550 //reset_scrolling_region ();
554 EditorRoutes::set_all_tracks_visibility (bool yn)
556 TreeModel::Children rows = _model->children();
557 TreeModel::Children::iterator i;
559 suspend_redisplay ();
561 for (i = rows.begin(); i != rows.end(); ++i) {
563 TreeModel::Row row = (*i);
564 TimeAxisView* tv = row[_columns.tv];
570 (*i)[_columns.visible] = yn;
577 EditorRoutes::set_all_audio_visibility (int tracks, bool yn)
579 TreeModel::Children rows = _model->children();
580 TreeModel::Children::iterator i;
582 suspend_redisplay ();
584 for (i = rows.begin(); i != rows.end(); ++i) {
585 TreeModel::Row row = (*i);
586 TimeAxisView* tv = row[_columns.tv];
587 AudioTimeAxisView* atv;
593 if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) != 0) {
596 (*i)[_columns.visible] = yn;
600 if (atv->is_audio_track()) {
601 (*i)[_columns.visible] = yn;
606 if (!atv->is_audio_track()) {
607 (*i)[_columns.visible] = yn;
618 EditorRoutes::hide_all_routes ()
620 set_all_tracks_visibility (false);
624 EditorRoutes::show_all_routes ()
626 set_all_tracks_visibility (true);
630 EditorRoutes::show_all_audiobus ()
632 set_all_audio_visibility (2, true);
635 EditorRoutes::hide_all_audiobus ()
637 set_all_audio_visibility (2, false);
641 EditorRoutes::show_all_audiotracks()
643 set_all_audio_visibility (1, true);
646 EditorRoutes::hide_all_audiotracks ()
648 set_all_audio_visibility (1, false);
652 EditorRoutes::button_press (GdkEventButton* ev)
654 if (Keyboard::is_context_menu_event (ev)) {
660 TreeModel::Path path;
661 TreeViewColumn* column;
665 if (!_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) {
669 switch (GPOINTER_TO_UINT (column->get_data (X_("colnum")))) {
672 /* allow normal processing to occur */
675 /* allow normal processing to occur */
678 /* allow normal processing to occur */
681 if ((iter = _model->get_iter (path))) {
682 TimeAxisView* tv = (*iter)[_columns.tv];
684 bool visible = (*iter)[_columns.visible];
685 (*iter)[_columns.visible] = !visible;
691 /* allow normal processing to occur */
702 EditorRoutes::selection_filter (Glib::RefPtr<TreeModel> const &, TreeModel::Path const &, bool)
707 struct EditorOrderRouteSorter {
708 bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) {
709 /* use of ">" forces the correct sort order */
710 return a->order_key (N_ ("editor")) < b->order_key (N_ ("editor"));
715 EditorRoutes::initial_display ()
717 boost::shared_ptr<RouteList> routes = _session->get_routes();
718 RouteList r (*routes);
719 EditorOrderRouteSorter sorter;
723 suspend_redisplay ();
726 _editor->handle_new_route (r);
728 /* don't show master bus in a new session */
730 if (ARDOUR_UI::instance()->session_is_new ()) {
732 TreeModel::Children rows = _model->children();
733 TreeModel::Children::iterator i;
735 _no_redisplay = true;
737 for (i = rows.begin(); i != rows.end(); ++i) {
738 TimeAxisView *tv = (*i)[_columns.tv];
739 RouteTimeAxisView *rtv;
741 if ((rtv = dynamic_cast<RouteTimeAxisView*>(tv)) != 0) {
742 if (rtv->route()->is_master()) {
743 _display.get_selection()->unselect (i);
748 _no_redisplay = false;
756 EditorRoutes::track_list_reorder (Gtk::TreeModel::Path const &, Gtk::TreeModel::iterator const &, int* /*new_order*/)
758 _redisplay_does_not_sync_order_keys = true;
759 _session->set_remote_control_ids();
761 _redisplay_does_not_sync_order_keys = false;
765 EditorRoutes::display_drag_data_received (const RefPtr<Gdk::DragContext>& context,
767 const SelectionData& data,
768 guint info, guint time)
770 if (data.get_target() == "GTK_TREE_MODEL_ROW") {
771 _display.on_drag_data_received (context, x, y, data, info, time);
775 context->drag_finish (true, false, time);
779 EditorRoutes::move_selected_tracks (bool up)
781 if (_editor->selection->tracks.empty()) {
785 typedef std::pair<TimeAxisView*,boost::shared_ptr<Route> > ViewRoute;
786 std::list<ViewRoute> view_routes;
787 std::vector<int> neworder;
788 TreeModel::Children rows = _model->children();
789 TreeModel::Children::iterator ri;
791 for (ri = rows.begin(); ri != rows.end(); ++ri) {
792 TimeAxisView* tv = (*ri)[_columns.tv];
793 boost::shared_ptr<Route> route = (*ri)[_columns.route];
795 view_routes.push_back (ViewRoute (tv, route));
798 list<ViewRoute>::iterator trailing;
799 list<ViewRoute>::iterator leading;
803 trailing = view_routes.begin();
804 leading = view_routes.begin();
808 while (leading != view_routes.end()) {
809 if (_editor->selection->selected (leading->first)) {
810 view_routes.insert (trailing, ViewRoute (leading->first, leading->second));
811 leading = view_routes.erase (leading);
820 /* if we could use reverse_iterator in list::insert, this code
821 would be a beautiful reflection of the code above. but we can't
822 and so it looks like a bit of a mess.
825 trailing = view_routes.end();
826 leading = view_routes.end();
828 --leading; if (leading == view_routes.begin()) { return; }
834 if (_editor->selection->selected (leading->first)) {
835 list<ViewRoute>::iterator tmp;
837 /* need to insert *after* trailing, not *before* it,
838 which is what insert (iter, val) normally does.
844 view_routes.insert (tmp, ViewRoute (leading->first, leading->second));
846 /* can't use iter = cont.erase (iter); form here, because
847 we need iter to move backwards.
855 if (leading == view_routes.begin()) {
856 /* the one we've just inserted somewhere else
857 was the first in the list. erase this copy,
858 and then break, because we're done.
863 view_routes.erase (leading);
872 if (leading == view_routes.begin()) {
881 for (leading = view_routes.begin(); leading != view_routes.end(); ++leading) {
882 neworder.push_back (leading->second->order_key (N_ ("editor")));
885 _model->reorder (neworder);
887 _session->sync_order_keys (N_ ("editor"));
891 EditorRoutes::update_rec_display ()
893 TreeModel::Children rows = _model->children();
894 TreeModel::Children::iterator i;
896 for (i = rows.begin(); i != rows.end(); ++i) {
897 boost::shared_ptr<Route> route = (*i)[_columns.route];
899 if (boost::dynamic_pointer_cast<Track>(route)) {
900 (*i)[_columns.rec_enabled] = route->record_enabled ();
901 (*i)[_columns.name_editable] = !route->record_enabled ();
907 EditorRoutes::update_mute_display (void* /*src*/)
909 TreeModel::Children rows = _model->children();
910 TreeModel::Children::iterator i;
912 for (i = rows.begin(); i != rows.end(); ++i) {
913 boost::shared_ptr<Route> route = (*i)[_columns.route];
915 if (boost::dynamic_pointer_cast<Track>(route)) {
918 (*i)[_columns.mute_state] = 1;
920 (*i)[_columns.mute_state] = 0;
927 EditorRoutes::update_solo_display (void* /*src*/)
929 TreeModel::Children rows = _model->children();
930 TreeModel::Children::iterator i;
932 for (i = rows.begin(); i != rows.end(); ++i) {
933 boost::shared_ptr<Route> route = (*i)[_columns.route];
935 if (boost::dynamic_pointer_cast<Track>(route)) {
937 if (route->soloed()){
938 (*i)[_columns.solo_state] = 1;
940 (*i)[_columns.solo_state] = 0;
947 EditorRoutes::views () const
949 list<TimeAxisView*> v;
950 for (TreeModel::Children::iterator i = _model->children().begin(); i != _model->children().end(); ++i) {
951 v.push_back ((*i)[_columns.tv]);
958 EditorRoutes::clear ()
960 _display.set_model (Glib::RefPtr<Gtk::TreeStore> (0));
962 _display.set_model (_model);
966 EditorRoutes::name_edit (Glib::ustring const & path, Glib::ustring const & new_text)
968 TreeIter iter = _model->get_iter (path);
973 boost::shared_ptr<Route> route = (*iter)[_columns.route];
975 if (route && route->name() != new_text) {
976 route->set_name (new_text);