Merged with trunk (painfully)
[ardour.git] / libs / ardour / playlist.cc
index 8977135ba7e5b52d97bdd4d49c5296a41331c72f..1bc6ccac6db957af9feed18e07a0a152779f7a65 100644 (file)
@@ -98,11 +98,32 @@ Playlist::Playlist (const Playlist& other, string namestr, bool hide)
 {
        init (hide);
 
-       other.copy_regions (regions);
+       RegionList tmp;
+       other.copy_regions (tmp);
+       
+       in_set_state = true;
 
-       for (list<Region*>::iterator x = regions.begin(); x != regions.end(); ++x) {
-               (*x)->set_playlist (this);
+       for (list<Region*>::iterator x = tmp.begin(); x != tmp.end(); ++x) {
+               add_region_internal( (*x), (*x)->position() );
        }
+
+       in_set_state = false;
+
+       _splicing  = other._splicing;
+       _nudging   = other._nudging;
+       _edit_mode = other._edit_mode;
+
+       in_set_state = false;
+       in_flush = false;
+       in_partition = false;
+       subcnt = 0;
+       _read_data_count = 0;
+       _frozen = other._frozen;
+       save_on_thaw = false;
+       
+       layer_op_counter = other.layer_op_counter;
+       freeze_length = other.freeze_length;
+       
 }
 
 Playlist::Playlist (const Playlist& other, jack_nframes_t start, jack_nframes_t cnt, string str, bool hide)
@@ -204,8 +225,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;
@@ -223,8 +244,6 @@ Playlist::init (bool hide)
        layer_op_counter = 0;
        freeze_length = 0;
 
-       // _session.LayerModelChanged.connect (slot (*this, &Playlist::relayer));
-
        Modified.connect (mem_fun (*this, &Playlist::mark_session_dirty));
 }
 
@@ -273,13 +292,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 ();
 }
 
@@ -287,14 +306,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 ();
        } 
 }
@@ -411,8 +430,10 @@ Playlist::flush_notifications ()
        }
 
        if (n || pending_modified) {
-               possibly_splice ();
-               relayer ();
+               if (!in_set_state) {
+                       possibly_splice ();
+                       relayer ();
+               }
                pending_modified = false;
                Modified (); /* EMIT SIGNAL */
        }
@@ -961,10 +982,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;
@@ -975,14 +992,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,9 +1364,13 @@ Playlist::set_state (const XMLNode& node)
 
                        add_region (*region, region->position(), 1.0, false);
 
+                       // So that layer_op ordering doesn't get screwed up
+                       region->set_last_layer_op( region->layer());
+
                }                       
        }
 
+       
        /* update dependents, which was not done during add_region_internal 
           due to in_set_state being true 
        */
@@ -1338,7 +1378,7 @@ Playlist::set_state (const XMLNode& node)
        for (RegionList::iterator r = regions.begin(); r != regions.end(); ++r) {
                check_dependents (**r, false);
        }
-
+       
        in_set_state = false;
 
        return 0;