X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Flocation.cc;h=579a0e2820d2eb9faf31ae4662fd8e33134457f1;hb=1bd4c5b3a212460eed1773f6b049d18c89625565;hp=f4eea2cfc5555c2b8af0c91fce4f3f45ea6d23e7;hpb=ddfc8d2185ec9cef7afe74091ea544ec286f13a8;p=ardour.git diff --git a/libs/ardour/location.cc b/libs/ardour/location.cc index f4eea2cfc5..579a0e2820 100644 --- a/libs/ardour/location.cc +++ b/libs/ardour/location.cc @@ -30,12 +30,15 @@ #include #include +#include +#include #include "i18n.h" using namespace std; using namespace ARDOUR; using namespace sigc; +using namespace PBD; Location::Location (const Location& other) : _name (other._name), @@ -43,6 +46,17 @@ Location::Location (const Location& other) _end (other._end), _flags (other._flags) { + /* start and end flags can never be copied, because there can only ever be one of each */ + + _flags = Flags (_flags & ~IsStart); + _flags = Flags (_flags & ~IsEnd); +} + +Location::Location (const XMLNode& node) +{ + if (set_state (node)) { + throw failed_constructor (); + } } Location* @@ -63,13 +77,25 @@ Location::operator= (const Location& other) } int -Location::set_start (jack_nframes_t s) +Location::set_start (nframes_t s) { if (is_mark()) { if (_start != s) { + _start = s; _end = s; + start_changed(this); /* EMIT SIGNAL */ + + if ( is_start() ) { + + Session::StartTimeChanged (); /* EMIT SIGNAL */ + AudioFileSource::set_header_position_offset ( s ); + } + + if ( is_end() ) { + Session::EndTimeChanged (); /* EMIT SIGNAL */ + } } return 0; } @@ -87,7 +113,7 @@ Location::set_start (jack_nframes_t s) } int -Location::set_end (jack_nframes_t e) +Location::set_end (nframes_t e) { if (is_mark()) { if (_start != e) { @@ -110,7 +136,7 @@ Location::set_end (jack_nframes_t e) } int -Location::set (jack_nframes_t start, jack_nframes_t end) +Location::set (nframes_t start, nframes_t end) { if (is_mark() && start != end) { return -1; @@ -232,13 +258,16 @@ XMLNode& Location::get_state (void) { XMLNode *node = new XMLNode ("Location"); - char buf[32]; + char buf[64]; typedef map::const_iterator CI; + for(CI m = cd_info.begin(); m != cd_info.end(); ++m){ node->add_child_nocopy(cd_info_node(m->first, m->second)); } + id().print (buf, sizeof (buf)); + node->add_property("id", buf); node->add_property ("name", name()); snprintf (buf, sizeof (buf), "%u", start()); node->add_property ("start", buf); @@ -253,7 +282,6 @@ Location::get_state (void) int Location::set_state (const XMLNode& node) { - XMLPropertyList plist; const XMLProperty *prop; XMLNodeList cd_list = node.children(); @@ -263,14 +291,17 @@ Location::set_state (const XMLNode& node) string cd_name; string cd_value; - if (node.name() != "Location") { error << _("incorrect XML node passed to Location::set_state") << endmsg; return -1; } - plist = node.properties(); - + if ((prop = node.property ("id")) == 0) { + warning << _("XML node for Location has no ID information") << endmsg; + } else { + _id = prop->value (); + } + if ((prop = node.property ("name")) == 0) { error << _("XML node for Location has no name information") << endmsg; return -1; @@ -341,27 +372,16 @@ Locations::Locations () { current_location = 0; - save_state (_("initial")); } Locations::~Locations () { - std::set all_locations; - - for (StateMap::iterator siter = states.begin(); siter != states.end(); ++siter) { - - State* lstate = dynamic_cast (*siter); - - for (LocationList::iterator liter = lstate->locations.begin(); liter != lstate->locations.end(); ++liter) { - all_locations.insert (*liter); - } - - for (LocationList::iterator siter = lstate->states.begin(); siter != lstate->states.end(); ++siter) { - all_locations.insert (*siter); - } + for (LocationList::iterator i = locations.begin(); i != locations.end(); ) { + LocationList::iterator tmp = i; + ++tmp; + delete *i; + i = tmp; } - - set_delete (&all_locations); } int @@ -371,7 +391,7 @@ Locations::set_current (Location *loc, bool want_lock) int ret; if (want_lock) { - LockMonitor lm (lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (lock); ret = set_current_unlocked (loc); } else { ret = set_current_unlocked (loc); @@ -399,12 +419,12 @@ void Locations::clear () { { - LockMonitor lm (lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (lock); LocationList::iterator tmp; for (LocationList::iterator i = locations.begin(); i != locations.end(); ) { tmp = i; ++tmp; - if (!(*i)->is_end()) { + if (!(*i)->is_end() && !(*i)->is_start()) { locations.erase (i); } i = tmp; @@ -414,8 +434,6 @@ Locations::clear () current_location = 0; } - save_state (_("clear")); - changed (); /* EMIT SIGNAL */ current_changed (0); /* EMIT SIGNAL */ } @@ -424,14 +442,14 @@ void Locations::clear_markers () { { - LockMonitor lm (lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (lock); LocationList::iterator tmp; for (LocationList::iterator i = locations.begin(); i != locations.end(); ) { tmp = i; ++tmp; - if ((*i)->is_mark() && !(*i)->is_end()) { + if ((*i)->is_mark() && !(*i)->is_end() && !(*i)->is_start()) { locations.erase (i); } @@ -439,8 +457,6 @@ Locations::clear_markers () } } - save_state (_("clear markers")); - changed (); /* EMIT SIGNAL */ } @@ -448,7 +464,7 @@ void Locations::clear_ranges () { { - LockMonitor lm (lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (lock); LocationList::iterator tmp; for (LocationList::iterator i = locations.begin(); i != locations.end(); ) { @@ -467,8 +483,6 @@ Locations::clear_ranges () current_location = 0; } - save_state (_("clear ranges")); - changed (); /* EMIT SIGNAL */ current_changed (0); /* EMIT SIGNAL */ } @@ -477,7 +491,7 @@ void Locations::add (Location *loc, bool make_current) { { - LockMonitor lm (lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (lock); locations.push_back (loc); if (make_current) { @@ -485,8 +499,6 @@ Locations::add (Location *loc, bool make_current) } } - save_state (_("add")); - added (loc); /* EMIT SIGNAL */ if (make_current) { @@ -502,12 +514,12 @@ Locations::remove (Location *loc) bool was_current = false; LocationList::iterator i; - if (loc->is_end()) { + if (loc->is_end() || loc->is_start()) { return; } { - LockMonitor lm (lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (lock); for (i = locations.begin(); i != locations.end(); ++i) { if ((*i) == loc) { @@ -523,9 +535,8 @@ Locations::remove (Location *loc) } if (was_removed) { - save_state (_("remove")); - - removed (loc); /* EMIT SIGNAL */ + + removed (loc); /* EMIT SIGNAL */ if (was_current) { current_changed (0); /* EMIT SIGNAL */ @@ -538,7 +549,6 @@ Locations::remove (Location *loc) void Locations::location_changed (Location* loc) { - save_state (X_("location changed")); changed (); /* EMIT SIGNAL */ } @@ -547,7 +557,7 @@ Locations::get_state () { XMLNode *node = new XMLNode ("Locations"); LocationList::iterator iter; - LockMonitor lm (lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (lock); for (iter = locations.begin(); iter != locations.end(); ++iter) { node->add_child_nocopy ((*iter)->get_state ()); @@ -570,19 +580,23 @@ Locations::set_state (const XMLNode& node) nlist = node.children(); { - LockMonitor lm (lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (lock); for (niter = nlist.begin(); niter != nlist.end(); ++niter) { - Location *loc = new Location; - if (loc->set_state (**niter)) { - delete loc; - } else { + try { + + Location *loc = new Location (**niter); locations.push_back (loc); } + + catch (failed_constructor& err) { + error << _("could not load location from session file - ignored") << endmsg; + } } if (locations.size()) { + current_location = locations.front(); } else { current_location = 0; @@ -609,12 +623,12 @@ struct LocationStartLaterComparison }; Location * -Locations::first_location_before (jack_nframes_t frame) +Locations::first_location_before (nframes_t frame) { LocationList locs; { - LockMonitor lm (lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (lock); locs = locations; } @@ -633,12 +647,12 @@ Locations::first_location_before (jack_nframes_t frame) } Location * -Locations::first_location_after (jack_nframes_t frame) +Locations::first_location_after (nframes_t frame) { LocationList locs; { - LockMonitor lm (lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (lock); locs = locations; } @@ -656,6 +670,80 @@ Locations::first_location_after (jack_nframes_t frame) return 0; } +nframes_t +Locations::first_mark_before (nframes_t frame) +{ + LocationList locs; + + { + Glib::Mutex::Lock lm (lock); + locs = locations; + } + + LocationStartLaterComparison cmp; + locs.sort (cmp); + + /* locs is now sorted latest..earliest */ + + for (LocationList::iterator i = locs.begin(); i != locs.end(); ++i) { + if (!(*i)->is_hidden()) { + if ((*i)->is_mark()) { + /* MARK: start == end */ + if ((*i)->start() < frame) { + return (*i)->start(); + } + } else { + /* RANGE: start != end, compare start and end */ + if ((*i)->end() < frame) { + return (*i)->end(); + } + if ((*i)->start () < frame) { + return (*i)->start(); + } + } + } + } + + return 0; +} + +nframes_t +Locations::first_mark_after (nframes_t frame) +{ + LocationList locs; + + { + Glib::Mutex::Lock lm (lock); + locs = locations; + } + + LocationStartEarlierComparison cmp; + locs.sort (cmp); + + /* locs is now sorted earliest..latest */ + + for (LocationList::iterator i = locs.begin(); i != locs.end(); ++i) { + if (!(*i)->is_hidden()) { + if ((*i)->is_mark()) { + /* MARK, start == end so just compare start */ + if ((*i)->start() > frame) { + return (*i)->start(); + } + } else { + /* RANGE, start != end, compare start and end */ + if ((*i)->start() > frame ) { + return (*i)->start (); + } + if ((*i)->end() > frame) { + return (*i)->end (); + } + } + } + } + + return max_frames; +} + Location* Locations::end_location () const { @@ -700,50 +788,11 @@ Locations::auto_punch_location () const return 0; } -StateManager::State* -Locations::state_factory (std::string why) const -{ - State* state = new State (why); - - state->locations = locations; - - for (LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) { - state->states.push_back (new Location (**i)); - } - - return state; -} - -Change -Locations::restore_state (StateManager::State& state) -{ - { - LockMonitor lm (lock, __LINE__, __FILE__); - State* lstate = dynamic_cast (&state); - - locations = lstate->locations; - LocationList& states = lstate->states; - LocationList::iterator l, s; - - for (l = locations.begin(), s = states.begin(); s != states.end(); ++s, ++l) { - (*l) = (*s); - } - } - - return Change (0); -} - -UndoAction -Locations::get_memento () const -{ - return sigc::bind (mem_fun (*(const_cast (this)), &StateManager::use_state), _current_state_id); -} - uint32_t Locations::num_range_markers () const { uint32_t cnt = 0; - LockMonitor lm (lock, __LINE__, __FILE__); + Glib::Mutex::Lock lm (lock); for (LocationList::const_iterator i = locations.begin(); i != locations.end(); ++i) { if ((*i)->is_range_marker()) { ++cnt; @@ -751,3 +800,14 @@ Locations::num_range_markers () const } return cnt; } + +Location * +Locations::get_location_by_id(PBD::ID id) +{ + LocationList::iterator it; + for (it = locations.begin(); it != locations.end(); it++) + if (id == (*it)->id()) + return *it; + + return 0; +}