#include <ctime>
#include <list>
+#include "pbd/convert.h"
#include "pbd/stl_delete.h"
#include "pbd/xml++.h"
#include "pbd/enumwriter.h"
#include "i18n.h"
-#define SUFFIX_MAX 32
-
using namespace std;
using namespace ARDOUR;
using namespace PBD;
PBD::Signal1<void,Location*> Location::name_changed;
PBD::Signal1<void,Location*> Location::end_changed;
PBD::Signal1<void,Location*> Location::start_changed;
+PBD::Signal1<void,Location*> Location::flags_changed;
+PBD::Signal1<void,Location*> Location::lock_changed;
+PBD::Signal1<void,Location*> Location::position_lock_style_changed;
PBD::Signal1<void,Location*> Location::changed;
Location::Location (Session& s)
return this;
}
+/** Set location name
+ */
+
+void
+Location::set_name (const std::string& str)
+{
+ _name = str;
+
+ name_changed (this); /* EMIT SIGNAL */
+ NameChanged (); /* EMIT SIGNAL */
+}
+
/** Set start position.
* @param s New start.
* @param force true to force setting, even if the given new start is after the current end.
}
start_changed (this); /* EMIT SIGNAL */
+ StartChanged (); /* EMIT SIGNAL */
end_changed (this); /* EMIT SIGNAL */
+ EndChanged (); /* EMIT SIGNAL */
}
/* moving the start (position) of a marker with a scene change
recompute_bbt_from_frames ();
}
start_changed (this); /* EMIT SIGNAL */
+ StartChanged (); /* EMIT SIGNAL */
if (is_session_range ()) {
Session::StartTimeChanged (old); /* EMIT SIGNAL */
recompute_bbt_from_frames ();
}
start_changed (this); /* EMIT SIGNAL */
+ StartChanged (); /* EMIT SIGNAL */
end_changed (this); /* EMIT SIGNAL */
+ EndChanged (); /* EMIT SIGNAL */
}
assert (_start >= 0);
if (allow_bbt_recompute) {
recompute_bbt_from_frames ();
}
+
end_changed(this); /* EMIT SIGNAL */
+ EndChanged(); /* EMIT SIGNAL */
if (is_session_range()) {
Session::EndTimeChanged (old); /* EMIT SIGNAL */
}
int
-Location::set (framepos_t start, framepos_t end, bool allow_bbt_recompute)
+Location::set (framepos_t s, framepos_t e, bool allow_bbt_recompute)
{
- if (start < 0 || end < 0) {
+ if (s < 0 || e < 0) {
return -1;
}
/* check validity */
- if (((is_auto_punch() || is_auto_loop()) && start >= end) || (!is_mark() && start > end)) {
+ if (((is_auto_punch() || is_auto_loop()) && s >= e) || (!is_mark() && s > e)) {
return -1;
}
- /* now we know these values are ok, so force-set them */
- int const s = set_start (start, true, allow_bbt_recompute);
- int const e = set_end (end, true, allow_bbt_recompute);
+ bool start_change = false;
+ bool end_change = false;
+
+ if (is_mark()) {
+
+ if (_start != s) {
+ _start = s;
+ _end = s;
+
+ if (allow_bbt_recompute) {
+ recompute_bbt_from_frames ();
+ }
+
+ start_change = true;
+ end_change = true;
+ }
+
+ assert (_start >= 0);
+ assert (_end >= 0);
- return (s == 0 && e == 0) ? 0 : -1;
+ } else {
+
+ if (s != _start) {
+
+ framepos_t const old = _start;
+ _start = s;
+
+ if (allow_bbt_recompute) {
+ recompute_bbt_from_frames ();
+ }
+
+ start_change = true;
+
+ if (is_session_range ()) {
+ Session::StartTimeChanged (old); /* EMIT SIGNAL */
+ AudioFileSource::set_header_position_offset (s);
+ }
+ }
+
+
+ if (e != _end) {
+
+ framepos_t const old = _end;
+ _end = e;
+
+ if (allow_bbt_recompute) {
+ recompute_bbt_from_frames ();
+ }
+
+ end_change = true;
+
+ if (is_session_range()) {
+ Session::EndTimeChanged (old); /* EMIT SIGNAL */
+ }
+ }
+
+ assert (_end >= 0);
+ }
+
+ if (start_change) {
+ start_changed(this); /* EMIT SIGNAL */
+ StartChanged(); /* EMIT SIGNAL */
+ }
+
+ if (end_change) {
+ end_changed(this); /* EMIT SIGNAL */
+ EndChanged(); /* EMIT SIGNAL */
+ }
+
+ if (start_change && end_change) {
+ changed (this);
+ Changed ();
+ }
+
+ return 0;
}
int
recompute_bbt_from_frames ();
changed (this); /* EMIT SIGNAL */
+ Changed (); /* EMIT SIGNAL */
}
assert (_start >= 0);
}
void
-Location::set_hidden (bool yn, void *src)
+Location::set_hidden (bool yn, void*)
{
if (set_flag_internal (yn, IsHidden)) {
- FlagsChanged (this, src); /* EMIT SIGNAL */
+ flags_changed (this); /* EMIT SIGNAL */
+ FlagsChanged ();
}
}
void
-Location::set_cd (bool yn, void *src)
+Location::set_cd (bool yn, void*)
{
// XXX this really needs to be session start
// but its not available here - leave to GUI
}
if (set_flag_internal (yn, IsCDMarker)) {
- FlagsChanged (this, src); /* EMIT SIGNAL */
+ flags_changed (this); /* EMIT SIGNAL */
+ FlagsChanged ();
}
}
void
-Location::set_is_range_marker (bool yn, void *src)
+Location::set_is_range_marker (bool yn, void*)
{
if (set_flag_internal (yn, IsRangeMarker)) {
- FlagsChanged (this, src); /* EMIT SIGNAL */
+ flags_changed (this);
+ FlagsChanged (); /* EMIT SIGNAL */
}
}
void
-Location::set_auto_punch (bool yn, void *src)
+Location::set_skip (bool yn)
+{
+ if (is_range_marker() && length() > 0) {
+ if (set_flag_internal (yn, IsSkip)) {
+ flags_changed (this);
+ FlagsChanged ();
+ }
+ }
+}
+
+void
+Location::set_skipping (bool yn)
+{
+ if (is_range_marker() && is_skip() && length() > 0) {
+ if (set_flag_internal (yn, IsSkipping)) {
+ flags_changed (this);
+ FlagsChanged ();
+ }
+ }
+}
+
+void
+Location::set_auto_punch (bool yn, void*)
{
if (is_mark() || _start == _end) {
return;
}
if (set_flag_internal (yn, IsAutoPunch)) {
- FlagsChanged (this, src); /* EMIT SIGNAL */
+ flags_changed (this); /* EMIT SIGNAL */
+ FlagsChanged (); /* EMIT SIGNAL */
}
}
void
-Location::set_auto_loop (bool yn, void *src)
+Location::set_auto_loop (bool yn, void*)
{
if (is_mark() || _start == _end) {
return;
}
if (set_flag_internal (yn, IsAutoLoop)) {
- FlagsChanged (this, src); /* EMIT SIGNAL */
+ flags_changed (this); /* EMIT SIGNAL */
+ FlagsChanged (); /* EMIT SIGNAL */
}
}
recompute_bbt_from_frames ();
changed (this); /* EMIT SIGNAL */
+ Changed (); /* EMIT SIGNAL */
assert (_start >= 0);
assert (_end >= 0);
recompute_bbt_from_frames ();
- PositionLockStyleChanged (this); /* EMIT SIGNAL */
+ position_lock_style_changed (this); /* EMIT SIGNAL */
+ PositionLockStyleChanged (); /* EMIT SIGNAL */
}
void
Location::lock ()
{
_locked = true;
- LockChanged (this);
+ lock_changed (this);
+ LockChanged ();
}
void
Location::unlock ()
{
_locked = false;
- LockChanged (this);
+ lock_changed (this);
+ LockChanged ();
}
void
: SessionHandleRef (s)
{
current_location = 0;
-
- Location::changed.connect_same_thread (*this, boost::bind (&Locations::location_changed, this, _1));
- Location::start_changed.connect_same_thread (*this, boost::bind (&Locations::location_changed, this, _1));
- Location::end_changed.connect_same_thread (*this, boost::bind (&Locations::location_changed, this, _1));
}
Locations::~Locations ()
Locations::next_available_name(string& result,string base)
{
LocationList::iterator i;
- Location* location;
- string temp;
string::size_type l;
int suffix;
char buf[32];
- bool available[SUFFIX_MAX+1];
+ std::map<uint32_t,bool> taken;
+ uint32_t n;
result = base;
- for (int k=1; k<SUFFIX_MAX; k++) {
- available[k] = true;
- }
- l = base.length();
- for (i = locations.begin(); i != locations.end(); ++i) {
- location =* i;
- temp = location->name();
- if (l && !temp.find(base,0)) {
- suffix = atoi(temp.substr(l,3).c_str());
- if (suffix) available[suffix] = false;
- }
- }
- for (int k=1; k<=SUFFIX_MAX; k++) {
- if (available[k]) {
- snprintf (buf, 31, "%d", k);
- result += buf;
- return 1;
- }
- }
+ l = base.length();
+
+ if (!base.empty()) {
+
+ /* find all existing names that match "base", and store
+ the numeric part of them (if any) in the map "taken"
+ */
+
+ for (i = locations.begin(); i != locations.end(); ++i) {
+
+ const string& temp ((*i)->name());
+
+ if (!temp.find (base,0)) {
+
+ if ((suffix = atoi (temp.substr(l,3))) != 0) {
+ taken.insert (make_pair (suffix,true));
+ }
+ }
+ }
+ }
+
+ /* Now search for an un-used suffix to add to "base". This
+ will find "holes" in the numbering sequence when a location
+ was deleted.
+
+ This must start at 1, both for human-numbering reasons
+ and also because the call to atoi() above would return
+ zero if there is no recognizable numeric suffix, causing
+ "base 0" not to be inserted into the "taken" map.
+ */
+
+ n = 1;
+
+ while (n < UINT32_MAX) {
+ if (taken.find (n) == taken.end()) {
+ snprintf (buf, sizeof(buf), "%d", n);
+ result += buf;
+ return 1;
+ }
+ ++n;
+ }
+
return 0;
}
current_location = 0;
}
- changed (OTHER); /* EMIT SIGNAL */
+ changed (); /* EMIT SIGNAL */
current_changed (0); /* EMIT SIGNAL */
}
i = tmp;
}
}
-
- changed (OTHER); /* EMIT SIGNAL */
+
+ changed (); /* EMIT SIGNAL */
}
void
current_location = 0;
}
- changed (OTHER); /* EMIT SIGNAL */
+ changed ();
current_changed (0); /* EMIT SIGNAL */
}
if (was_removed) {
removed (loc); /* EMIT SIGNAL */
-
+
if (was_current) {
current_changed (0); /* EMIT SIGNAL */
}
-
- changed (REMOVAL); /* EMIT_SIGNAL */
}
}
-void
-Locations::location_changed (Location* /*loc*/)
-{
- changed (OTHER); /* EMIT SIGNAL */
-}
-
XMLNode&
Locations::get_state ()
{
}
}
- changed (OTHER); /* EMIT SIGNAL */
+ changed (); /* EMIT SIGNAL */
return 0;
}