Anywhere that deletes regions needs to use a rdiff() on the playlist
authorCarl Hetherington <carl@carlh.net>
Fri, 30 Dec 2011 23:41:17 +0000 (23:41 +0000)
committerCarl Hetherington <carl@carlh.net>
Fri, 30 Dec 2011 23:41:17 +0000 (23:41 +0000)
for the undo history, so that changes to regions' layering_index
get stored in the undo record.  Make Playlist::update use add_region_internal
so that undone regions don't have their layering_index corrupted.
Setup layering indices on relayer() so that deletion of regions
causes an update.

git-svn-id: svn://localhost/ardour2/branches/3.0@11123 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/editor_ops.cc
libs/ardour/ardour/playlist.h
libs/ardour/playlist.cc

index 9bdd2e26a85eb554ce541d9c41713a02c8064493..96ae169aed2783cba1e75bcce59d4a8612407bff 100644 (file)
@@ -3706,7 +3706,16 @@ Editor::remove_clicked_region ()
 
        begin_reversible_command (_("remove region"));
        playlist->clear_changes ();
+       playlist->clear_owned_changes ();
        playlist->remove_region (clicked_regionview->region());
+
+       /* We might have removed regions, which alters other regions' layering_index,
+          so we need to do a recursive diff here.
+       */
+       vector<Command*> cmds;
+       playlist->rdiff (cmds);
+       _session->add_commands (cmds);
+       
        _session->add_command(new StatefulDiffCommand (playlist));
        commit_reversible_command ();
 }
@@ -3758,6 +3767,7 @@ Editor::remove_selected_regions ()
                playlists.push_back (playlist);
 
                playlist->clear_changes ();
+               playlist->clear_owned_changes ();
                playlist->freeze ();
                playlist->remove_region (*rl);
        }
@@ -3766,6 +3776,14 @@ Editor::remove_selected_regions ()
 
        for (pl = playlists.begin(); pl != playlists.end(); ++pl) {
                (*pl)->thaw ();
+
+               /* We might have removed regions, which alters other regions' layering_index,
+                  so we need to do a recursive diff here.
+               */
+               vector<Command*> cmds;
+               (*pl)->rdiff (cmds);
+               _session->add_commands (cmds);
+               
                _session->add_command(new StatefulDiffCommand (*pl));
        }
 
@@ -3812,6 +3830,7 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
 
                                if (fl == freezelist.end()) {
                                        pl->clear_changes();
+                                       pl->clear_owned_changes ();
                                        pl->freeze ();
                                        freezelist.insert (pl);
                                }
@@ -3927,6 +3946,14 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
 
        for (FreezeList::iterator pl = freezelist.begin(); pl != freezelist.end(); ++pl) {
                (*pl)->thaw ();
+
+               /* We might have removed regions, which alters other regions' layering_index,
+                  so we need to do a recursive diff here.
+               */
+               vector<Command*> cmds;
+               (*pl)->rdiff (cmds);
+               _session->add_commands (cmds);
+               
                _session->add_command (new StatefulDiffCommand (*pl));
        }
 }
@@ -4615,6 +4642,7 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress
                        if (arv->audio_region()->apply (filter, progress) == 0) {
 
                                playlist->clear_changes ();
+                               playlist->clear_owned_changes ();
 
                                if (filter.results.empty ()) {
 
@@ -4637,6 +4665,13 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress
 
                                }
 
+                               /* We might have removed regions, which alters other regions' layering_index,
+                                  so we need to do a recursive diff here.
+                               */
+                               vector<Command*> cmds;
+                               playlist->rdiff (cmds);
+                               _session->add_commands (cmds);
+                               
                                _session->add_command(new StatefulDiffCommand (playlist));
                        } else {
                                goto out;
@@ -5716,6 +5751,7 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
        AnalysisFeatureList::const_iterator x;
 
        pl->clear_changes ();
+       pl->clear_owned_changes ();
 
        x = positions.begin();
 
@@ -5802,6 +5838,13 @@ Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList
 
        pl->thaw ();
 
+       /* We might have removed regions, which alters other regions' layering_index,
+          so we need to do a recursive diff here.
+       */
+       vector<Command*> cmds;
+       pl->rdiff (cmds);
+       _session->add_commands (cmds);
+       
        _session->add_command (new StatefulDiffCommand (pl));
 
        if (select_new) {
index 67cc1ccf545b57173c7076dc290efdef70b557b3..626df720bd7bb8cd391e828154b2c019d7ac1631 100644 (file)
@@ -378,6 +378,10 @@ public:
           with its constituent regions
        */
        virtual void pre_uncombine (std::vector<boost::shared_ptr<Region> >&, boost::shared_ptr<Region>) {}
+
+private:
+
+       void setup_layering_indices (RegionList const &) const;
 };
 
 } /* namespace ARDOUR */
index d3a461ea9eecb9bb8e8c74d39236e774519fbfad..c11e55779c4302769f0d64fa8b6a6aa84dbd06c7 100644 (file)
@@ -653,6 +653,7 @@ Playlist::flush_notifications (bool from_undo)
    PLAYLIST OPERATIONS
   *************************************************************/
 
+/** Note: this calls set_layer (..., DBL_MAX) so it will reset the layering index of region */
  void
  Playlist::add_region (boost::shared_ptr<Region> region, framepos_t position, float times, bool auto_partition)
  {
@@ -2097,7 +2098,7 @@ Playlist::flush_notifications (bool from_undo)
         freeze ();
         /* add the added regions */
         for (RegionListProperty::ChangeContainer::iterator i = change.added.begin(); i != change.added.end(); ++i) {
-                add_region ((*i), (*i)->position());
+                add_region_internal ((*i), (*i)->position());
         }
         /* remove the removed regions */
         for (RegionListProperty::ChangeContainer::iterator i = change.removed.begin(); i != change.removed.end(); ++i) {
@@ -2371,13 +2372,19 @@ Playlist::set_layer (boost::shared_ptr<Region> region, double new_layer)
        
        copy.insert (i, region);
 
-       /* Then re-write layering indices */
+       setup_layering_indices (copy);
+}
+
+void
+Playlist::setup_layering_indices (RegionList const & regions) const
+{
        uint64_t j = 0;
-       for (RegionList::iterator k = copy.begin(); k != copy.end(); ++k) {
+       for (RegionList::const_iterator k = regions.begin(); k != regions.end(); ++k) {
                (*k)->set_layering_index (j++);
        }
 }
 
+
 /** Take the layering indices of each of our regions, compute the layers
  *  that they should be on, and write the layers back to the regions.
  */
@@ -2493,6 +2500,12 @@ Playlist::relayer ()
        if (changed) {
                notify_layering_changed ();
        }
+
+       /* This relayer() may have been called as a result of a region removal, in which
+          case we need to setup layering indices so account for the one that has just
+          gone away.
+       */
+       setup_layering_indices (copy);
 }
 
 void