improve, cleanup, rationalize Session::cleanup_sources() and supporting infrastructure
[ardour.git] / libs / ardour / ardour / playlist.h
index 100a0f771303ad5015f6e5644fa71bd005fc611b..e21199e6420817b9de2512c149c71bc9e419c443 100644 (file)
@@ -35,7 +35,6 @@
 
 #include "pbd/undo.h"
 #include "pbd/stateful.h"
-#include "pbd/stateful_owner.h"
 #include "pbd/statefuldestructible.h"
 #include "pbd/sequence_property.h"
 
@@ -43,7 +42,6 @@
 
 #include "ardour/ardour.h"
 #include "ardour/session_object.h"
-#include "ardour/crossfade_compare.h"
 #include "ardour/data_type.h"
 
 namespace ARDOUR  {
@@ -51,6 +49,7 @@ namespace ARDOUR  {
 class Session;
 class Region;
 class Playlist;
+class Crossfade;       
 
 namespace Properties {
         /* fake the type, since regions are handled by SequenceProperty which doesn't
@@ -59,35 +58,30 @@ namespace Properties {
         extern PBD::PropertyDescriptor<bool> regions;
 }
 
-class RegionListProperty : public PBD::SequenceProperty<std::list<boost::shared_ptr<Region > > >
+class RegionListProperty : public PBD::SequenceProperty<std::list<boost::shared_ptr<Region> > >
 {
   public:
         RegionListProperty (Playlist&);
 
-        boost::shared_ptr<Region> lookup_id (const PBD::ID& id);
-        void diff (PBD::PropertyList& undo, PBD::PropertyList& redo, Command*) const;
-        bool involves (boost::shared_ptr<Region>);
+       RegionListProperty* clone () const;
+       void get_content_as_xml (boost::shared_ptr<Region>, XMLNode &) const;
+       boost::shared_ptr<Region> get_content_from_xml (XMLNode const &) const;
 
   private:
-        friend class Playlist;
-        std::list<boost::shared_ptr<Region> > rlist() { return _val; }
+       RegionListProperty* create () const;
+
+       /* copy construction only by ourselves */
+       RegionListProperty (RegionListProperty const & p);
 
+        friend class Playlist;
         /* we live and die with our playlist, no lifetime management needed */
         Playlist& _playlist;
-
-        /* create a copy of this RegionListProperty that only
-           has what is needed for use in a history list command. This
-           means that it won't contain the actual region list but
-           will have the added/removed list.
-        */
-        RegionListProperty* copy_for_history () const;
 };
 
-class Playlist : public SessionObject
-               , public PBD::StatefulOwner
-              , public boost::enable_shared_from_this<Playlist> {
-  public:
-       typedef std::list<boost::shared_ptr<Region> >    RegionList;
+class Playlist : public SessionObject , public boost::enable_shared_from_this<Playlist>
+{
+public:
+       typedef std::list<boost::shared_ptr<Region> > RegionList;
         static void make_property_quarks ();
 
        Playlist (Session&, const XMLNode&, DataType type, bool hidden = false);
@@ -97,14 +91,11 @@ class Playlist : public SessionObject
 
        virtual ~Playlist ();
 
-        bool set_property (const PBD::PropertyBase&);
         void update (const RegionListProperty::ChangeRecord&);
-        void clear_owned_history ();
-        void rdiff (std::vector<PBD::StatefulDiffCommand*>&) const;
+        void clear_owned_changes ();
+        void rdiff (std::vector<Command*>&) const;
 
-        PBD::PropertyList* property_factory (const XMLNode&) const;
-
-       boost::shared_ptr<Region> region_by_id (const PBD::ID&);
+       boost::shared_ptr<Region> region_by_id (const PBD::ID&) const;
 
        void set_region_ownership ();
 
@@ -126,7 +117,7 @@ class Playlist : public SessionObject
        bool hidden() const { return _hidden; }
        bool empty() const;
        uint32_t n_regions() const;
-       std::pair<framecnt_t, framecnt_t> get_extent () const;
+       std::pair<framepos_t, framepos_t> get_extent () const;
        layer_t top_layer() const;
 
        EditMode get_edit_mode() const { return _edit_mode; }
@@ -156,8 +147,10 @@ class Playlist : public SessionObject
        const RegionListProperty& region_list () const { return regions; }
 
        RegionList*                regions_at (framepos_t frame);
+        uint32_t                   count_regions_at (framepos_t);
        RegionList*                regions_touched (framepos_t start, framepos_t end);
        RegionList*                regions_to_read (framepos_t start, framepos_t end);
+       uint32_t                   region_use_count (boost::shared_ptr<Region>) const;
        boost::shared_ptr<Region>  find_region (const PBD::ID&) const;
        boost::shared_ptr<Region>  top_region_at (framepos_t frame);
        boost::shared_ptr<Region>  top_unmuted_region_at (framepos_t frame);
@@ -166,6 +159,7 @@ class Playlist : public SessionObject
        bool                       region_is_shuffle_constrained (boost::shared_ptr<Region>);
        bool                       has_region_at (framepos_t const) const;
 
+        bool uses_source (boost::shared_ptr<const Source> src) const;
 
        framepos_t find_next_transient (framepos_t position, int dir);
 
@@ -182,8 +176,15 @@ class Playlist : public SessionObject
        PBD::Signal0<void>      NameChanged;
        PBD::Signal0<void>      LengthChanged;
        PBD::Signal0<void>      LayeringChanged;
+
+       /** Emitted when regions have moved (not when regions have only been trimmed) */
        PBD::Signal2<void,std::list< Evoral::RangeMove<framepos_t> > const &, bool> RangesMoved;
 
+       /** Emitted when regions are extended; the ranges passed are the new extra time ranges
+           that these regions now occupy.
+       */
+       PBD::Signal1<void,std::list< Evoral::Range<framepos_t> > const &> RegionsExtended;
+
        static std::string bump_name (std::string old_name, Session&);
 
        void freeze ();
@@ -204,6 +205,8 @@ class Playlist : public SessionObject
 
        virtual bool destroy_region (boost::shared_ptr<Region>) = 0;
 
+        void sync_all_regions_with_regions ();
+
        /* special case function used by UI selection objects, which have playlists that actually own the regions
           within them.
        */
@@ -216,6 +219,12 @@ class Playlist : public SessionObject
 
        void set_explicit_relayering (bool e);
 
+       virtual boost::shared_ptr<Crossfade> find_crossfade (const PBD::ID &) const {
+               return boost::shared_ptr<Crossfade> ();
+       }
+
+       framepos_t find_next_top_layer_position (framepos_t) const;     
+
   protected:
        friend class Session;
 
@@ -253,7 +262,14 @@ class Playlist : public SessionObject
        bool             pending_contents_change;
        bool             pending_layering;
        bool             pending_length;
+
+       /** Movements of time ranges caused by region moves; note that
+        *  region trims are not included in this list; it is used to
+        *  do automation-follows-regions.
+        */
        std::list< Evoral::RangeMove<framepos_t> > pending_range_moves;
+       /** Extra sections added to regions during trims */
+       std::list< Evoral::Range<framepos_t> >     pending_region_extensions;
        bool             save_on_thaw;
        std::string      last_save_reason;
        uint32_t         in_set_state;
@@ -302,6 +318,8 @@ class Playlist : public SessionObject
        void notify_contents_changed ();
        void notify_state_changed (const PBD::PropertyChange&);
        void notify_region_moved (boost::shared_ptr<Region>);
+       void notify_region_start_trimmed (boost::shared_ptr<Region>);
+       void notify_region_end_trimmed (boost::shared_ptr<Region>);
 
        void mark_session_dirty();
 
@@ -331,11 +349,11 @@ class Playlist : public SessionObject
        bool add_region_internal (boost::shared_ptr<Region>, framepos_t position);
 
        int remove_region_internal (boost::shared_ptr<Region>);
-       RegionList *find_regions_at (framepos_t frame);
+       RegionList *find_regions_at (framepos_t);
        void copy_regions (RegionList&) const;
        void partition_internal (framepos_t start, framepos_t end, bool cutting, RegionList& thawlist);
 
-       std::pair<framecnt_t, framecnt_t> _get_extent() const;
+       std::pair<framepos_t, framepos_t> _get_extent() const;
 
        boost::shared_ptr<Playlist> cut_copy (boost::shared_ptr<Playlist> (Playlist::*pmf)(framepos_t, framecnt_t, bool),
                                              std::list<AudioRange>& ranges, bool result_is_hidden);