Change the feedback alert to a flashing button; works
[ardour.git] / libs / ardour / ardour / playlist.h
index 2cc1f570f48b94c572121dd713968fe5328e46c4..9e15b9cf5d10795f2d283d93eb866a3d12e296ea 100644 (file)
@@ -42,7 +42,6 @@
 
 #include "ardour/ardour.h"
 #include "ardour/session_object.h"
-#include "ardour/crossfade_compare.h"
 #include "ardour/data_type.h"
 
 namespace ARDOUR  {
@@ -50,19 +49,19 @@ namespace ARDOUR  {
 class Session;
 class Region;
 class Playlist;
-class Crossfade;       
+class Crossfade;
 
 namespace Properties {
-        /* fake the type, since regions are handled by SequenceProperty which doesn't
-           care about such things.
-        */
-        extern PBD::PropertyDescriptor<bool> regions;
+       /* fake the type, since regions are handled by SequenceProperty which doesn't
+          care about such things.
+       */
+       extern PBD::PropertyDescriptor<bool> regions;
 }
 
 class RegionListProperty : public PBD::SequenceProperty<std::list<boost::shared_ptr<Region> > >
 {
   public:
-        RegionListProperty (Playlist&);
+       RegionListProperty (Playlist&);
 
        RegionListProperty* clone () const;
        void get_content_as_xml (boost::shared_ptr<Region>, XMLNode &) const;
@@ -74,16 +73,16 @@ class RegionListProperty : public PBD::SequenceProperty<std::list<boost::shared_
        /* 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;
+       friend class Playlist;
+       /* we live and die with our playlist, no lifetime management needed */
+       Playlist& _playlist;
 };
 
 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 ();
+       static void make_property_quarks ();
 
        Playlist (Session&, const XMLNode&, DataType type, bool hidden = false);
        Playlist (Session&, std::string name, DataType type, bool hidden = false);
@@ -92,12 +91,14 @@ public:
 
        virtual ~Playlist ();
 
-        void update (const RegionListProperty::ChangeRecord&);
-        void clear_owned_changes ();
-        void rdiff (std::vector<Command*>&) const;
+       void update (const RegionListProperty::ChangeRecord&);
+       void clear_owned_changes ();
+       void rdiff (std::vector<Command*>&) const;
 
        boost::shared_ptr<Region> region_by_id (const PBD::ID&) const;
 
+       uint32_t max_source_level () const;
+
        void set_region_ownership ();
 
        virtual void clear (bool with_signals=true);
@@ -108,7 +109,7 @@ public:
        bool used () const { return _refcnt != 0; }
 
        bool set_name (const std::string& str);
-        int sort_id() { return _sort_id; }
+       int sort_id() { return _sort_id; }
 
        const DataType& data_type() const { return _type; }
 
@@ -118,7 +119,7 @@ public:
        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; }
@@ -138,6 +139,9 @@ public:
        void partition (framepos_t start, framepos_t end, bool cut = false);
        void duplicate (boost::shared_ptr<Region>, framepos_t position, float times);
        void nudge_after (framepos_t start, framecnt_t distance, bool forwards);
+       boost::shared_ptr<Region> combine (const RegionList&);
+       void uncombine (boost::shared_ptr<Region>);
+
        void shuffle (boost::shared_ptr<Region>, int dir);
        void update_after_tempo_map_change ();
 
@@ -148,7 +152,8 @@ public:
        const RegionListProperty& region_list () const { return regions; }
 
        RegionList*                regions_at (framepos_t frame);
-        uint32_t                   count_regions_at (framepos_t);
+       uint32_t                   count_regions_at (framepos_t) const;
+       uint32_t                   count_joined_regions () const;
        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;
@@ -160,6 +165,7 @@ public:
        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);
 
@@ -180,6 +186,11 @@ public:
        /** 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 ();
@@ -190,8 +201,6 @@ public:
        void raise_region_to_top (boost::shared_ptr<Region>);
        void lower_region_to_bottom (boost::shared_ptr<Region>);
 
-       uint32_t read_data_count() const { return _read_data_count; }
-
        /* XXX: use of diskstream here is a little unfortunate */
        const PBD::ID& get_orig_diskstream_id () const { return _orig_diskstream_id; }
        void set_orig_diskstream_id (const PBD::ID& did) { _orig_diskstream_id = did; }
@@ -200,6 +209,8 @@ public:
 
        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 +227,9 @@ public:
                return boost::shared_ptr<Crossfade> ();
        }
 
+       framepos_t find_next_top_layer_position (framepos_t) const;
+       uint32_t combine_ops() const { return _combine_ops; }
+
   protected:
        friend class Session;
 
@@ -239,11 +253,11 @@ public:
 
        friend class RegionLock;
 
-        RegionListProperty   regions;  /* the current list of regions in the playlist */
+       RegionListProperty   regions;  /* the current list of regions in the playlist */
        std::set<boost::shared_ptr<Region> > all_regions; /* all regions ever added to this playlist */
        PBD::ScopedConnectionList region_state_changed_connections;
        DataType        _type;
-        int             _sort_id;
+       int             _sort_id;
        mutable gint    block_notifications;
        mutable gint    ignore_state_changes;
        mutable Glib::RecMutex region_lock;
@@ -259,6 +273,8 @@ public:
         *  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;
@@ -274,11 +290,11 @@ public:
        bool             in_partition;
        bool            _frozen;
        uint32_t         subcnt;
-       uint32_t        _read_data_count;
        PBD::ID         _orig_diskstream_id;
        uint64_t         layer_op_counter;
        framecnt_t       freeze_length;
        bool             auto_partition;
+       uint32_t        _combine_ops;
 
        /** true if relayering should be done using region's current layers and their `pending explicit relayer'
         *  flags; otherwise false if relayering should be done using the layer-model (most recently moved etc.)
@@ -298,7 +314,7 @@ public:
        virtual void flush_notifications (bool from_undo = false);
        void clear_pending ();
 
-        void _set_sort_id ();
+       void _set_sort_id ();
 
        void notify_region_removed (boost::shared_ptr<Region>);
        void notify_region_added (boost::shared_ptr<Region>);
@@ -307,6 +323,8 @@ public:
        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();
 
@@ -340,7 +358,7 @@ public:
        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);
@@ -358,6 +376,25 @@ public:
        void timestamp_layer_op (boost::shared_ptr<Region>);
 
        void _split_region (boost::shared_ptr<Region>, framepos_t position);
+
+       typedef std::pair<boost::shared_ptr<Region>, boost::shared_ptr<Region> > TwoRegions;
+       virtual void copy_dependents (const std::vector<TwoRegions>&, Playlist*) const { }
+
+       struct RegionInfo {
+           boost::shared_ptr<Region> region;
+           framepos_t position;
+           framecnt_t length;
+           framepos_t start;
+       };
+
+       /* this is called before we create a new compound region */
+       virtual void pre_combine (std::vector<boost::shared_ptr<Region> >&) {}
+       /* this is called before we create a new compound region */
+       virtual void post_combine (std::vector<boost::shared_ptr<Region> >&, boost::shared_ptr<Region>) {}
+       /* this is called before we remove a compound region and replace it
+          with its constituent regions
+       */
+       virtual void pre_uncombine (std::vector<boost::shared_ptr<Region> >&, boost::shared_ptr<Region>) {}
 };
 
 } /* namespace ARDOUR */