not actually working attempt to copy relevant xfades into compound regions; fix compi...
[ardour.git] / libs / ardour / playlist.cc
index fd9af56e80c1865e26a02b8a6b0b4960bb7272dc..d635819963434fd95353efc2b9a0acdcc991f803 100644 (file)
 
 #include <boost/lexical_cast.hpp>
 
+#include "pbd/convert.h"
 #include "pbd/failed_constructor.h"
 #include "pbd/stateful_diff_command.h"
 #include "pbd/xml++.h"
-#include "pbd/stacktrace.h"
 
 #include "ardour/debug.h"
 #include "ardour/playlist.h"
@@ -357,6 +357,7 @@ Playlist::init (bool hide)
        layer_op_counter = 0;
        freeze_length = 0;
        _explicit_relayering = false;
+       _combine_ops = 0;
 
        _session.history().BeginUndoRedo.connect_same_thread (*this, boost::bind (&Playlist::begin_undo, this));
        _session.history().EndUndoRedo.connect_same_thread (*this, boost::bind (&Playlist::end_undo, this));
@@ -2221,6 +2222,26 @@ Playlist::update (const RegionListProperty::ChangeRecord& change)
        thaw ();
 }
 
+void
+Playlist::load_nested_sources (const XMLNode& node)
+{
+       XMLNodeList nlist;
+       XMLNodeConstIterator niter;
+
+       nlist = node.children();
+
+       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+               if ((*niter)->name() == "Source") {
+                       try {
+                               SourceFactory::create (_session, **niter, true);
+                       } 
+                       catch (failed_constructor& err) {
+                               error << string_compose (_("Cannot reconstruct nested source for playlist %1"), name()) << endmsg;
+                       }
+               }
+       }
+}
+
 int
 Playlist::set_state (const XMLNode& node, int version)
 {
@@ -2257,6 +2278,8 @@ Playlist::set_state (const XMLNode& node, int version)
                        _orig_diskstream_id = prop->value ();
                } else if (prop->name() == X_("frozen")) {
                        _frozen = string_is_affirmative (prop->value());
+               } else if (prop->name() == X_("combine-ops")) {
+                       _combine_ops = atoi (prop->value());
                }
        }
 
@@ -2264,6 +2287,19 @@ Playlist::set_state (const XMLNode& node, int version)
 
        nlist = node.children();
 
+       /* find the "Nested" node, if any, and recreate the PlaylistSources
+          listed there
+       */
+
+       for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
+               child = *niter;
+
+               if (child->name() == "Nested") {
+                       load_nested_sources (*child);
+                       break;
+               }
+       }
+
        for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
 
                child = *niter;
@@ -2292,7 +2328,7 @@ Playlist::set_state (const XMLNode& node, int version)
                                error << _("Playlist: cannot create region from XML") << endmsg;
                                continue;
                        }
-
+                       
 
                        add_region (region, region->position(), 1.0);
 
@@ -2336,7 +2372,7 @@ XMLNode&
 Playlist::state (bool full_state)
 {
        XMLNode *node = new XMLNode (X_("Playlist"));
-       char buf[64] = "";
+       char buf[64];
 
        node->add_property (X_("id"), id().to_s());
        node->add_property (X_("name"), _name);
@@ -2348,6 +2384,34 @@ Playlist::state (bool full_state)
 
        if (full_state) {
                RegionLock rlock (this, false);
+               XMLNode* nested_node = 0;
+
+               snprintf (buf, sizeof (buf), "%u", _combine_ops);
+               node->add_property ("combine-ops", buf);
+
+               for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+                       if ((*i)->max_source_level() > 0) {
+
+                               if (!nested_node) {
+                                       nested_node = new XMLNode (X_("Nested"));
+                               }
+
+                               /* region is compound - get its playlist and
+                                  store that before we list the region that
+                                  needs it ...
+                               */
+
+                               const SourceList& sl ((*i)->sources());
+
+                               for (SourceList::const_iterator s = sl.begin(); s != sl.end(); ++s) {
+                                       nested_node->add_child_nocopy ((*s)->get_state ());
+                               }
+                       }
+               }
+
+               if (nested_node) {
+                       node->add_child_nocopy (*nested_node);
+               }
 
                for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
                        node->add_child_nocopy ((*i)->get_state());
@@ -3093,13 +3157,20 @@ Playlist::join (const RegionList& r, const std::string& name)
        uint32_t channels = 0;
        uint32_t layer = 0;
        framepos_t earliest_position = max_framepos;
+       vector<TwoRegions> old_and_new_regions;
 
        boost::shared_ptr<Playlist> pl = PlaylistFactory::create (_type, _session, name, true);
-       
+
        for (RegionList::const_iterator i = r.begin(); i != r.end(); ++i) {
                earliest_position = min (earliest_position, (*i)->position());
        }
 
+       /* enable this so that we do not try to create xfades etc. as we add
+        * regions
+        */
+
+       pl->in_partition = true;
+
        for (RegionList::const_iterator i = r.begin(); i != r.end(); ++i) {
 
                /* copy the region */
@@ -3107,6 +3178,8 @@ Playlist::join (const RegionList& r, const std::string& name)
                boost::shared_ptr<Region> original_region = (*i);
                boost::shared_ptr<Region> copied_region = RegionFactory::create (original_region, false);
 
+               old_and_new_regions.push_back (TwoRegions (original_region,copied_region));
+
                /* make position relative to zero */
 
                pl->add_region (copied_region, original_region->position() - earliest_position);
@@ -3120,6 +3193,8 @@ Playlist::join (const RegionList& r, const std::string& name)
                layer = max (layer, original_region->layer());
        }
 
+       pl->in_partition = false;
+
        /* now create a new PlaylistSource for each channel in the new playlist */
 
        SourceList sources;
@@ -3138,6 +3213,10 @@ Playlist::join (const RegionList& r, const std::string& name)
        
        boost::shared_ptr<Region> compound_region = RegionFactory::create (sources, plist, true);
 
+       /* add any dependent regions to the new playlist */
+
+       copy_dependents (old_and_new_regions, pl);
+
        /* remove all the selected regions from the current playlist
         */
 
@@ -3151,6 +3230,8 @@ Playlist::join (const RegionList& r, const std::string& name)
        
        add_region (compound_region, earliest_position);
 
+       _combine_ops++;
+
        thaw ();
 }