Merging undo branch into trunk. It compiles and works for limited tests. Keep
[ardour.git] / libs / ardour / playlist.cc
index feb0ad8bb5e7af257f7e854497c305b30b8e1292..6d5e8f7847d5f0287cb96bbc21f540810b8d2a98 100644 (file)
@@ -41,7 +41,7 @@
 
 using namespace std;
 using namespace ARDOUR;
-//using namespace sigc;
+using namespace PBD;
 
 sigc::signal<void,Playlist*> Playlist::PlaylistCreated;
 
@@ -77,7 +77,6 @@ Playlist::Playlist (Session& sess, string nom, bool hide)
 {
        init (hide);
        _name = nom;
-       _orig_diskstream_id = 0;
        
 }
 
@@ -86,7 +85,6 @@ Playlist::Playlist (Session& sess, const XMLNode& node, bool hide)
 {
        init (hide);
        _name = "unnamed"; /* reset by set_state */
-       _orig_diskstream_id = 0;
        
        if (set_state (node)) {
                throw failed_constructor();
@@ -225,8 +223,8 @@ Playlist::copy_regions (RegionList& newlist) const
 void
 Playlist::init (bool hide)
 {
-       atomic_set (&block_notifications, 0);
-       atomic_set (&ignore_state_changes, 0);
+       g_atomic_int_set (&block_notifications, 0);
+       g_atomic_int_set (&ignore_state_changes, 0);
        pending_modified = false;
        pending_length = false;
        _refcnt = 0;
@@ -292,13 +290,13 @@ void
 Playlist::freeze ()
 {
        delay_notifications ();
-       atomic_inc (&ignore_state_changes);
+       g_atomic_int_inc (&ignore_state_changes);
 }
 
 void
 Playlist::thaw ()
 {
-       atomic_dec (&ignore_state_changes);
+       g_atomic_int_dec_and_test (&ignore_state_changes);
        release_notifications ();
 }
 
@@ -306,14 +304,14 @@ Playlist::thaw ()
 void
 Playlist::delay_notifications ()
 {
-       atomic_inc (&block_notifications);
+       g_atomic_int_inc (&block_notifications);
        freeze_length = _get_maximum_extent();
 }
 
 void
 Playlist::release_notifications ()
 {
-       if (atomic_dec_and_test(&block_notifications)) { 
+       if (g_atomic_int_dec_and_test (&block_notifications)) { 
                flush_notifications ();
        } 
 }
@@ -600,6 +598,31 @@ Playlist::remove_region_internal (Region *region, bool delay_sort)
        return -1;
 }
 
+void
+Playlist::get_equivalent_regions (const Region& other, vector<Region*>& results)
+{
+       for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+               if (Config->get_use_overlap_equivalency()) {
+                       if ((*i)->overlap_equivalent (other)) {
+                               results.push_back ((*i));
+                       } else if ((*i)->equivalent (other)) {
+                               results.push_back ((*i));
+                       }
+               }
+       }
+}
+
+void
+Playlist::get_region_list_equivalent_regions (const Region& other, vector<Region*>& results)
+{
+       for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+
+               if ((*i) && (*i)->region_list_equivalent (other)) {
+                       results.push_back (*i);
+               }
+       }
+}
+
 void
 Playlist::partition (jack_nframes_t start, jack_nframes_t end, bool just_top_level)
 {
@@ -982,10 +1005,6 @@ Playlist::split_region (Region& region, jack_nframes_t playlist_position)
                return;
        }
 
-       if (remove_region_internal (&region, true)) {
-               return;
-       }
-
        Region *left;
        Region *right;
        jack_nframes_t before;
@@ -996,14 +1015,33 @@ Playlist::split_region (Region& region, jack_nframes_t playlist_position)
        before = playlist_position - region.position();
        after = region.length() - before;
        
+       
        _session.region_name (before_name, region.name(), false);
        left = createRegion (region, 0, before, before_name, region.layer(), Region::Flag (region.flags()|Region::LeftOfSplit));
 
        _session.region_name (after_name, region.name(), false);
        right = createRegion (region, before, after, after_name, region.layer(), Region::Flag (region.flags()|Region::RightOfSplit));
-       
+
        add_region_internal (left, region.position(), true);
        add_region_internal (right, region.position() + before);
+       
+       uint64_t orig_layer_op = region.last_layer_op();
+       for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+               if ((*i)->last_layer_op() > orig_layer_op) {
+                       (*i)->set_last_layer_op( (*i)->last_layer_op() + 1 );
+               }
+       }
+       
+       left->set_last_layer_op ( orig_layer_op );
+       right->set_last_layer_op ( orig_layer_op + 1);
+
+       layer_op_counter++;
+
+       finalize_split_region (&region, left, right);
+       
+       if (remove_region_internal (&region, true)) {
+               return;
+       }
 
        maybe_save_state (_("split"));
 }
@@ -1328,7 +1366,7 @@ Playlist::set_state (const XMLNode& node)
                if (prop->name() == X_("name")) {
                        _name = prop->value();
                } else if (prop->name() == X_("orig_diskstream_id")) {
-                       sscanf (prop->value().c_str(), "%" PRIu64, &_orig_diskstream_id);
+                       _orig_diskstream_id = prop->value ();
                } else if (prop->name() == X_("frozen")) {
                        _frozen = (prop->value() == X_("yes"));
                }
@@ -1389,7 +1427,7 @@ Playlist::state (bool full_state)
        
        node->add_property (X_("name"), _name);
 
-       snprintf (buf, sizeof(buf), "%" PRIu64, _orig_diskstream_id);
+       _orig_diskstream_id.print (buf);
        node->add_property (X_("orig_diskstream_id"), buf);
        node->add_property (X_("frozen"), _frozen ? "yes" : "no");
 
@@ -1710,7 +1748,7 @@ Playlist::nudge_after (jack_nframes_t start, jack_nframes_t distance, bool forwa
 }
 
 Region*
-Playlist::find_region (id_t id) const
+Playlist::find_region (const ID& id) const
 {
        RegionLock rlock (const_cast<Playlist*> (this));
        RegionList::const_iterator i;