fix a crash when deleting a MIDI region with CC automation (see recipe below)
[ardour.git] / gtk2_ardour / editor_routes.cc
index 4e97f757967c2b108e0b4204f99bcd5c5bac1668..075242459ede71396019b392a49fadb0c4df08f5 100644 (file)
@@ -57,7 +57,7 @@
 #include "vca_time_axis.h"
 #include "utils.h"
 
-#include "i18n.h"
+#include "pbd/i18n.h"
 
 using namespace std;
 using namespace ARDOUR;
@@ -581,7 +581,6 @@ EditorRoutes::redisplay_real ()
 
        for (n = 0, position = 0, i = rows.begin(); i != rows.end(); ++i) {
                TimeAxisView *tv = (*i)[_columns.tv];
-               boost::shared_ptr<Stripable> route = (*i)[_columns.stripable];
 
                if (tv == 0) {
                        // just a "title" row
@@ -801,6 +800,7 @@ EditorRoutes::time_axis_views_added (list<TimeAxisView*> tavs)
 
                stripable->gui_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::handle_gui_changes, this, _1, _2), gui_context());
                stripable->PropertyChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::route_property_changed, this, _1, ws), gui_context());
+               stripable->presentation_info().PropertyChanged.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::route_property_changed, this, _1, ws), gui_context());
 
                if (boost::dynamic_pointer_cast<Track> (stripable)) {
                        boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (stripable);
@@ -925,7 +925,9 @@ EditorRoutes::route_property_changed (const PropertyChange& what_changed, boost:
 
                        if (what_changed.contains (ARDOUR::Properties::hidden)) {
                                (*i)[_columns.visible] = !stripable->presentation_info().hidden();
+                               cerr << stripable->name() << " visibility changed, redisplay\n";
                                redisplay ();
+
                        }
 
                        break;
@@ -1011,6 +1013,14 @@ EditorRoutes::sync_presentation_info_from_treeview ()
        TreeModel::Children::iterator ri;
        bool change = false;
        PresentationInfo::order_t order = 0;
+       bool master_is_first = false;
+       uint32_t count = 0;
+
+       // special case master if it's got PI order 0 lets keep it there
+       if (_session->master_out() && (_session->master_out()->presentation_info().order() == 0)) {
+               order++;
+               master_is_first = true;
+       }
 
        for (ri = rows.begin(); ri != rows.end(); ++ri) {
 
@@ -1027,17 +1037,37 @@ EditorRoutes::sync_presentation_info_from_treeview ()
 
                stripable->presentation_info().set_hidden (!visible);
 
+               /* special case master if it's got PI order 0 lets keep it there
+                * but still allow master to move if first non-master route has
+                * presentation order 1
+                */
+               if ((count == 0) && master_is_first && (stripable->presentation_info().order()  == 1)) {
+                       master_is_first = false; // someone has moved master
+                       order = 0;
+               }
+
+               if (stripable->is_master() && master_is_first) {
+                       if (count) {
+                               continue;
+                       } else {
+                               count++;
+                               continue;
+                       }
+               }
+
                if (order != stripable->presentation_info().order()) {
-                       stripable->set_presentation_order_explicit (order);
+                       stripable->set_presentation_order (order, false);
                        change = true;
                }
 
                ++order;
+               ++count;
        }
 
        if (change) {
                DEBUG_TRACE (DEBUG::OrderKeys, "... notify PI change from editor GUI\n");
                _session->notify_presentation_info_change ();
+               _session->set_dirty();
        }
 }
 
@@ -1800,7 +1830,7 @@ EditorRoutes::show_tracks_with_regions_at_playhead ()
 
        set<TimeAxisView*> show;
        for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
-               TimeAxisView* tav = _editor->axis_view_from_route (*i);
+               TimeAxisView* tav = _editor->axis_view_from_stripable (*i);
                if (tav) {
                        show.insert (tav);
                }