*/
-#define __STDC_LIMIT_MACROS
#include <stdint.h>
-
#include <set>
#include <fstream>
#include <algorithm>
#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"
: SequenceProperty<std::list<boost::shared_ptr<Region> > > (Properties::regions.property_id, boost::bind (&Playlist::update, &pl, _1))
, _playlist (pl)
{
+
}
-boost::shared_ptr<Region>
-RegionListProperty::lookup_id (const ID& id) const
+RegionListProperty::RegionListProperty (RegionListProperty const & p)
+ : PBD::SequenceProperty<std::list<boost::shared_ptr<Region> > > (p)
+ , _playlist (p._playlist)
{
- boost::shared_ptr<Region> ret = _playlist.region_by_id (id);
-
- if (!ret) {
- ret = RegionFactory::region_by_id (id);
- }
- return ret;
}
-RegionListProperty* RegionListProperty::clone () const
+RegionListProperty *
+RegionListProperty::clone () const
{
return new RegionListProperty (*this);
}
-RegionListProperty* RegionListProperty::create () const
+RegionListProperty *
+RegionListProperty::create () const
{
return new RegionListProperty (_playlist);
}
+void
+RegionListProperty::get_content_as_xml (boost::shared_ptr<Region> region, XMLNode & node) const
+{
+ /* All regions (even those which are deleted) have their state saved by other
+ code, so we can just store ID here.
+ */
+
+ node.add_property ("id", region->id().to_s ());
+}
+
+boost::shared_ptr<Region>
+RegionListProperty::get_content_from_xml (XMLNode const & node) const
+{
+ XMLProperty const * prop = node.property ("id");
+ assert (prop);
+
+ PBD::ID id (prop->value ());
+
+ boost::shared_ptr<Region> ret = _playlist.region_by_id (id);
+
+ if (!ret) {
+ ret = RegionFactory::region_by_id (id);
+ }
+
+ return ret;
+}
+
Playlist::Playlist (Session& sess, string nom, DataType type, bool hide)
: SessionObject(sess, nom)
, regions (*this)
RegionLock rlock (const_cast<Playlist *> (this));
for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
- newlist.push_back (RegionFactory::RegionFactory::create (*i));
+ newlist.push_back (RegionFactory::RegionFactory::create (*i, true));
}
}
/* the length change might not be true, but we have to act
as though it could be.
*/
-
+
if (holding_state()) {
pending_adds.insert (r);
pending_contents_change = true;
*/
for (int i = 0; i < itimes; ++i) {
- boost::shared_ptr<Region> copy = RegionFactory::create (region);
+ boost::shared_ptr<Region> copy = RegionFactory::create (region, true);
add_region_internal (copy, pos);
pos += region->length();
}
while (itimes--) {
for (RegionList::iterator i = other->regions.begin(); i != other->regions.end(); ++i) {
- boost::shared_ptr<Region> copy_of_region = RegionFactory::create (*i);
+ boost::shared_ptr<Region> copy_of_region = RegionFactory::create (*i, true);
/* put these new regions on top of all existing ones, but preserve
the ordering they had in the original playlist.
*/
copy_of_region->set_layer (copy_of_region->layer() + top_layer);
- add_region_internal (copy_of_region, copy_of_region->position() + pos);
+ add_region_internal (copy_of_region, (*i)->position() + pos);
}
pos += shift;
}
framepos_t pos = position + 1;
while (itimes--) {
- boost::shared_ptr<Region> copy = RegionFactory::create (region);
+ boost::shared_ptr<Region> copy = RegionFactory::create (region, true);
add_region_internal (copy, pos);
pos += region->length();
}
framepos_t new_pos = (*i)->position() + distance;
if (new_pos < 0) {
new_pos = 0;
- } else if (new_pos >= max_frames - (*i)->length()) {
- new_pos = max_frames - (*i)->length();
+ } else if (new_pos >= max_framepos - (*i)->length()) {
+ new_pos = max_framepos - (*i)->length();
}
(*i)->set_position (new_pos, this);
return find_regions_at (frame);
}
+uint32_t
+Playlist::count_regions_at (framepos_t frame)
+{
+ RegionLock rlock (this);
+ uint32_t cnt = 0;
+
+ for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+ if ((*i)->covers (frame)) {
+ cnt++;
+ }
+ }
+
+ return cnt;
+}
+
boost::shared_ptr<Region>
Playlist::top_region_at (framepos_t frame)
{
RegionLock rlock (this);
boost::shared_ptr<Region> ret;
- framepos_t closest = max_frames;
+ framepos_t closest = max_framepos;
bool end_iter = false;
break;
case SyncPoint:
pos = r->sync_position ();
- // r->adjust_to_sync (r->first_frame());
break;
}
{
RegionLock rlock (this);
- framepos_t closest = max_frames;
+ framepos_t closest = max_framepos;
framepos_t ret = -1;
if (dir > 0) {
}
void
-Playlist::rdiff (vector<StatefulDiffCommand*>& cmds) const
+Playlist::rdiff (vector<Command*>& cmds) const
{
RegionLock rlock (const_cast<Playlist *> (this));
Stateful::rdiff (cmds);
return regions.size();
}
-pair<framecnt_t, framecnt_t>
+pair<framepos_t, framepos_t>
Playlist::get_extent () const
{
RegionLock rlock (const_cast<Playlist *>(this), false);
return _get_extent ();
}
-pair<framecnt_t, framecnt_t>
+pair<framepos_t, framepos_t>
Playlist::_get_extent () const
{
- pair<framecnt_t, framecnt_t> ext (max_frames, 0);
+ pair<framepos_t, framepos_t> ext (max_framepos, 0);
for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
- pair<framecnt_t, framecnt_t> const e ((*i)->position(), (*i)->position() + (*i)->length());
+ pair<framepos_t, framepos_t> const e ((*i)->position(), (*i)->position() + (*i)->length());
if (e.first < ext.first) {
ext.first = e.first;
}
void
Playlist::raise_region (boost::shared_ptr<Region> region)
{
- uint32_t rsz = regions.size();
+ uint32_t top = regions.size() - 1;
layer_t target = region->layer() + 1U;
- if (target >= rsz) {
+ if (target >= top) {
/* its already at the effective top */
return;
}
}
}
+ freeze ();
+
/* now reset the layers without holding the region lock */
for (list<LayerInfo>::iterator x = layerinfo.begin(); x != layerinfo.end(); ++x) {
region->set_layer (target_layer);
-#if 0
- /* now check all dependents */
+ /* now check all dependents, since we changed the layering */
for (list<LayerInfo>::iterator x = layerinfo.begin(); x != layerinfo.end(); ++x) {
check_dependents (x->first, false);
}
check_dependents (region, false);
-#endif
+ notify_layering_changed ();
+
+ thaw ();
return 0;
}
if (forwards) {
- if ((*i)->last_frame() > max_frames - distance) {
- new_pos = max_frames - (*i)->length();
+ if ((*i)->last_frame() > max_framepos - distance) {
+ new_pos = max_framepos - (*i)->length();
} else {
new_pos = (*i)->position() + distance;
}
return boost::shared_ptr<Region> ();
}
+uint32_t
+Playlist::region_use_count (boost::shared_ptr<Region> r) const
+{
+ RegionLock rlock (const_cast<Playlist*> (this));
+ uint32_t cnt = 0;
+
+ for (RegionList::const_iterator i = regions.begin(); i != regions.end(); ++i) {
+ if ((*i) == r) {
+ cnt++;
+ }
+ }
+
+ return cnt;
+}
+
boost::shared_ptr<Region>
Playlist::region_by_id (const ID& id) const
{
i = j;
}
}
+
+/** Look from a session frame time and find the start time of the next region
+ * which is on the top layer of this playlist.
+ * @param t Time to look from.
+ * @return Position of next top-layered region, or max_framepos if there isn't one.
+ */
+framepos_t
+Playlist::find_next_top_layer_position (framepos_t t) const
+{
+ RegionLock rlock (const_cast<Playlist *> (this));
+
+ layer_t const top = top_layer ();
+
+ RegionList copy = regions.rlist ();
+ copy.sort (RegionSortByPosition ());
+
+ for (RegionList::const_iterator i = copy.begin(); i != copy.end(); ++i) {
+ if ((*i)->position() >= t && (*i)->layer() == top) {
+ return (*i)->position();
+ }
+ }
+
+ return max_framepos;
+}