Allow markers to be glued to bar/beat time. Fixes #1815.
authorCarl Hetherington <carl@carlh.net>
Mon, 9 Aug 2010 16:40:31 +0000 (16:40 +0000)
committerCarl Hetherington <carl@carlh.net>
Mon, 9 Aug 2010 16:40:31 +0000 (16:40 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@7573 d708f5d6-7413-0410-9779-e7cbd77b26cf

18 files changed:
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_markers.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/location_ui.cc
libs/ardour/ardour/location.h
libs/ardour/ardour/session.h
libs/ardour/export_profile_manager.cc
libs/ardour/location.cc
libs/ardour/location_importer.cc
libs/ardour/session.cc
libs/ardour/session_command.cc
libs/ardour/session_process.cc
libs/ardour/session_state.cc
libs/ardour/session_transport.cc
libs/surfaces/control_protocol/basic_ui.cc
libs/surfaces/mackie/mackie_control_protocol.cc

index 28d9ee543a374458e7f6c96820c9c045a5b649f6..5080636db221869cf69d41cad04d183ed5e73a49 100644 (file)
@@ -1135,7 +1135,7 @@ Editor::set_session (Session *t)
 
        Location* loc = _session->locations()->auto_loop_location();
        if (loc == 0) {
-               loc = new Location (0, _session->current_end_frame(), _("Loop"),(Location::Flags) (Location::IsAutoLoop | Location::IsHidden));
+               loc = new Location (*_session, 0, _session->current_end_frame(), _("Loop"),(Location::Flags) (Location::IsAutoLoop | Location::IsHidden));
                if (loc->start() == loc->end()) {
                        loc->set_end (loc->start() + 1);
                }
@@ -1148,7 +1148,7 @@ Editor::set_session (Session *t)
 
        loc = _session->locations()->auto_punch_location();
        if (loc == 0) {
-               loc = new Location (0, _session->current_end_frame(), _("Punch"), (Location::Flags) (Location::IsAutoPunch | Location::IsHidden));
+               loc = new Location (*_session, 0, _session->current_end_frame(), _("Punch"), (Location::Flags) (Location::IsAutoPunch | Location::IsHidden));
                if (loc->start() == loc->end()) {
                        loc->set_end (loc->start() + 1);
                }
@@ -4602,7 +4602,7 @@ Editor::set_loop_range (nframes64_t start, nframes64_t end, string cmd)
        Location* tll;
 
        if ((tll = transport_loop_location()) == 0) {
-               Location* loc = new Location (start, end, _("Loop"),  Location::IsAutoLoop);
+               Location* loc = new Location (*_session, start, end, _("Loop"),  Location::IsAutoLoop);
                XMLNode &before = _session->locations()->get_state();
                _session->locations()->add (loc, true);
                _session->set_auto_loop_location (loc);
@@ -4629,7 +4629,7 @@ Editor::set_punch_range (nframes64_t start, nframes64_t end, string cmd)
        Location* tpl;
 
        if ((tpl = transport_punch_location()) == 0) {
-               Location* loc = new Location (start, end, _("Loop"),  Location::IsAutoPunch);
+               Location* loc = new Location (*_session, start, end, _("Loop"),  Location::IsAutoPunch);
                XMLNode &before = _session->locations()->get_state();
                _session->locations()->add (loc, true);
                _session->set_auto_loop_location (loc);
index 27e20e698ba02ad171d323a5b8b3ab0dc9d1cbfb..ecd13778a145859bab47f461cc62c2e51d00e2a0 100644 (file)
@@ -1465,6 +1465,7 @@ public:
        void marker_menu_remove ();
        void marker_menu_rename ();
        void toggle_marker_menu_lock ();
+       void toggle_marker_menu_glue ();
        void marker_menu_hide ();
        void marker_menu_loop_range ();
        void marker_menu_select_all_selectables_using_range ();
index 58bccf68d4b41028cfe4e4ef7daaa581e80df754..09a1573829308fb7e1a400d2d9783f70d3c38d02 100644 (file)
@@ -3504,7 +3504,7 @@ RangeMarkerBarDrag::start_grab (GdkEvent* event, Gdk::Cursor *)
        Gdk::Cursor* cursor = 0;
 
        if (!_editor->temp_location) {
-               _editor->temp_location = new Location;
+               _editor->temp_location = new Location (*_editor->session());
        }
 
        switch (_operation) {
@@ -3625,7 +3625,10 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred)
                                flags = Location::IsRangeMarker;
                                _editor->range_bar_drag_rect->hide();
                        }
-                       newloc = new Location(_editor->temp_location->start(), _editor->temp_location->end(), rangename, (Location::Flags) flags);
+                       newloc = new Location (
+                               *_editor->session(), _editor->temp_location->start(), _editor->temp_location->end(), rangename, (Location::Flags) flags
+                               );
+                       
                        _editor->session()->locations()->add (newloc, true);
                        XMLNode &after = _editor->session()->locations()->get_state();
                        _editor->session()->add_command(new MementoCommand<Locations>(*(_editor->session()->locations()), &before, &after));
index 87bc4b5138309766cead71b03cc88eda6d5d92de..23332047bd6bd8152c224ecec446cd829ab1d63f 100644 (file)
@@ -413,7 +413,7 @@ Editor::mouse_add_new_marker (nframes64_t where, bool is_cd, bool is_xrun)
                if (!is_xrun && !choose_new_marker_name(markername)) {
                        return;
                }
-               Location *location = new Location (where, where, markername, (Location::Flags) flags);
+               Location *location = new Location (*_session, where, where, markername, (Location::Flags) flags);
                _session->begin_reversible_command (_("add marker"));
                XMLNode &before = _session->locations()->get_state();
                _session->locations()->add (location, true);
@@ -628,6 +628,13 @@ Editor::build_marker_menu (bool session_range, Location* loc)
                lock_item->set_active ();
        }
        lock_item->signal_activate().connect (sigc::mem_fun (*this, &Editor::toggle_marker_menu_lock));
+
+       items.push_back (CheckMenuElem (_("Glue to Bars and Beats")));
+       CheckMenuItem* glue_item = static_cast<CheckMenuItem*> (&items.back());
+       if (loc->position_lock_style() == MusicTime) {
+               glue_item->set_active ();
+       }
+       glue_item->signal_activate().connect (sigc::mem_fun (*this, &Editor::toggle_marker_menu_glue));
        
        items.push_back (SeparatorElem());
 
@@ -867,7 +874,7 @@ Editor::marker_menu_range_to_next ()
                string range_name = l->name();
                range_name += "-range";
 
-               Location* newrange = new Location (marker->position(), end, range_name, Location::IsRangeMarker);
+               Location* newrange = new Location (*_session, marker->position(), end, range_name, Location::IsRangeMarker);
                _session->locations()->add (newrange);
        }
 }
@@ -1243,3 +1250,30 @@ Editor::goto_nth_marker (int n)
                }
        }
 }
+
+void
+Editor::toggle_marker_menu_glue ()
+{
+       Marker* marker;
+
+       if ((marker = reinterpret_cast<Marker *> (marker_menu_item->get_data ("marker"))) == 0) {
+               fatal << _("programming error: marker canvas item has no marker object pointer!") << endmsg;
+               /*NOTREACHED*/
+       }
+
+       Location* loc;
+       bool ignored;
+
+       loc = find_location_from_marker (marker, ignored);
+
+       if (!loc) {
+               return;
+       }
+
+       if (loc->position_lock_style() == MusicTime) {
+               loc->set_position_lock_style (AudioTime);
+       } else {
+               loc->set_position_lock_style (MusicTime);
+       }
+
+}
index cb76fcb1ec7b3cda0c83477ebe611bf274a2a9b3..2eb3987b8915fe75f8c6765e4ad58844dc3c9173 100644 (file)
@@ -1904,7 +1904,7 @@ Editor::add_location_from_selection ()
        nframes64_t end = selection->time[clicked_selection].end;
 
        _session->locations()->next_available_name(rangename,"selection");
-       Location *location = new Location (start, end, rangename, Location::IsRangeMarker);
+       Location *location = new Location (*_session, start, end, rangename, Location::IsRangeMarker);
 
        _session->begin_reversible_command (_("add marker"));
         XMLNode &before = _session->locations()->get_state();
@@ -1925,7 +1925,7 @@ Editor::add_location_mark (nframes64_t where)
        if (!choose_new_marker_name(markername)) {
                return;
        }
-       Location *location = new Location (where, where, markername, Location::IsMark);
+       Location *location = new Location (*_session, where, where, markername, Location::IsMark);
        _session->begin_reversible_command (_("add marker"));
         XMLNode &before = _session->locations()->get_state();
        _session->locations()->add (location, true);
@@ -1958,7 +1958,7 @@ Editor::add_locations_from_audio_region ()
 
                boost::shared_ptr<Region> region = (*i)->region ();
 
-               Location *location = new Location (region->position(), region->last_frame(), region->name(), Location::IsRangeMarker);
+               Location *location = new Location (*_session, region->position(), region->last_frame(), region->name(), Location::IsRangeMarker);
 
                _session->locations()->add (location, true);
        }
@@ -1997,7 +1997,7 @@ Editor::add_location_from_audio_region ()
        }
 
        // single range spanning all selected
-       Location *location = new Location (rs.start(), rs.end_frame(), markername, Location::IsRangeMarker);
+       Location *location = new Location (*_session, rs.start(), rs.end_frame(), markername, Location::IsRangeMarker);
        _session->locations()->add (location, true);
 
        XMLNode &after = _session->locations()->get_state();
@@ -2114,7 +2114,7 @@ Editor::set_mark ()
        if (!choose_new_marker_name(markername)) {
                return;
        }
-       _session->locations()->add (new Location (pos, 0, markername, Location::IsMark), true);
+       _session->locations()->add (new Location (*_session, pos, 0, markername, Location::IsMark), true);
 }
 
 void
index fda29be193a336d4ecd87b44b589c32d12765313..fb30450a54e5baa7e635640c5720d26662062955 100644 (file)
@@ -829,7 +829,7 @@ LocationUI::add_new_location()
        if (_session) {
                nframes_t where = _session->audible_frame();
                _session->locations()->next_available_name(markername,"mark");
-               Location *location = new Location (where, where, markername, Location::IsMark);
+               Location *location = new Location (*_session, where, where, markername, Location::IsMark);
                if (Config->get_name_new_markers()) {
                        newest_location = location;
                }
@@ -851,7 +851,7 @@ LocationUI::add_new_range()
        if (_session) {
                nframes_t where = _session->audible_frame();
                _session->locations()->next_available_name(rangename,"unnamed");
-               Location *location = new Location (where, where, rangename, Location::IsRangeMarker);
+               Location *location = new Location (*_session, where, where, rangename, Location::IsRangeMarker);
                _session->begin_reversible_command (_("add range marker"));
                XMLNode &before = _session->locations()->get_state();
                _session->locations()->add (location, true);
index 24387cdaef4b2aeafb702749df6a93cb8a58a0c9..cafcf3849431a4ce73292ff1c313a62bd37bb7ed 100644 (file)
 #include "pbd/statefuldestructible.h"
 
 #include "ardour/ardour.h"
+#include "ardour/session_handle.h"
 
 namespace ARDOUR {
 
-class Location : public PBD::StatefulDestructible
+class Location : public SessionHandleRef, public PBD::StatefulDestructible
 {
   public:
        enum Flags {
@@ -50,26 +51,10 @@ class Location : public PBD::StatefulDestructible
                IsSessionRange = 0x40
        };
 
-       Location (nframes64_t sample_start,
-                       nframes64_t sample_end,
-                       const std::string &name,
-                       Flags bits = Flags(0))
-
-               : _name (name),
-               _start (sample_start),
-               _end (sample_end),
-               _flags (bits),
-               _locked (false) { }
-
-       Location () {
-               _start = 0;
-               _end = 0;
-               _flags = Flags (0);
-               _locked = false;
-       }
-
+       Location (Session &);
+       Location (Session &, nframes64_t, nframes64_t, const std::string &, Flags bits = Flags(0));
        Location (const Location& other);
-       Location (const XMLNode&);
+       Location (Session &, const XMLNode&);
        Location* operator= (const Location& other);
 
        bool locked() const { return _locked; }
@@ -80,9 +65,9 @@ class Location : public PBD::StatefulDestructible
        nframes64_t end() const { return _end; }
        nframes64_t length() const { return _end - _start; }
 
-       int set_start (nframes64_t s, bool force = false);
-       int set_end (nframes64_t e, bool force = false);
-       int set (nframes64_t start, nframes64_t end);
+       int set_start (nframes64_t s, bool force = false, bool allow_bbt_recompute = true);
+       int set_end (nframes64_t e, bool force = false, bool allow_bbt_recompute = true);
+       int set (nframes64_t start, nframes64_t end, bool allow_bbt_recompute = true);
 
        int move_to (nframes64_t pos);
 
@@ -124,23 +109,31 @@ class Location : public PBD::StatefulDestructible
        XMLNode& get_state (void);
        int set_state (const XMLNode&, int version);
 
+       PositionLockStyle position_lock_style() const { return _position_lock_style; }
+       void set_position_lock_style (PositionLockStyle ps);
+       void recompute_frames_from_bbt ();
+
   private:
        std::string   _name;
        nframes64_t   _start;
+       BBT_Time      _bbt_start;
        nframes64_t   _end;
+       BBT_Time      _bbt_end;
        Flags         _flags;
        bool          _locked;
+       PositionLockStyle _position_lock_style;
 
        void set_mark (bool yn);
        bool set_flag_internal (bool yn, Flags flag);
+       void recompute_bbt_from_frames ();
 };
 
-class Locations : public PBD::StatefulDestructible
+class Locations : public SessionHandleRef, public PBD::StatefulDestructible
 {
   public:
        typedef std::list<Location *> LocationList;
 
-       Locations ();
+       Locations (Session &);
        ~Locations ();
 
        const LocationList& list() { return locations; }
index 7d822e64bcc1e6fba6b75eff87edbcb2868fdaee..5a7a69269101eeb9a589c36e8f8e2a9d0a600ff0 100644 (file)
@@ -334,7 +334,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        /* Locations */
 
-       Locations *locations() { return &_locations; }
+       Locations *locations() { return _locations; }
 
        PBD::Signal1<void,Location*>    auto_loop_location_changed;
        PBD::Signal1<void,Location*>    auto_punch_location_changed;
@@ -1024,7 +1024,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
        void set_rf_speed (float speed);
        void reset_rf_scale (nframes_t frames_moved);
 
-       Locations        _locations;
+       Locations*       _locations;
        void              locations_changed ();
        void              locations_added (Location*);
        void              handle_locations_changed (Locations::LocationList&);
@@ -1428,6 +1428,8 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        /** true if timecode transmission by the transport is suspended, otherwise false */
        mutable gint _suspend_timecode_transmission;
+
+       void update_locations_after_tempo_map_change (Locations::LocationList &);
 };
 
 } // namespace ARDOUR
index 53e6338a12836cd0e37c02f2822594c74ff1d3db..521f72747fcb32ee687b2b552b4ed2ab0bf2dc9c 100644 (file)
@@ -52,7 +52,7 @@ ExportProfileManager::ExportProfileManager (Session & s) :
   handler (s.get_export_handler()),
   session (s),
 
-  session_range (new Location ()),
+  session_range (new Location (s)),
   ranges (new LocationList ()),
   single_range_mode (false),
 
@@ -286,7 +286,7 @@ ExportProfileManager::set_selection_range (nframes_t start, nframes_t end)
 {
 
        if (start || end) {
-               selection_range.reset (new Location());
+               selection_range.reset (new Location (session));
                selection_range->set_name (_("Selection"));
                selection_range->set (start, end);
        } else {
@@ -303,7 +303,7 @@ ExportProfileManager::set_single_range (nframes_t start, nframes_t end, Glib::us
 {
        single_range_mode = true;
 
-       single_range.reset (new Location());
+       single_range.reset (new Location (session));
        single_range->set_name (name);
        single_range->set (start, end);
 
index 6fba55e16f6f109b392fceaf4ba9a1641bb02acc..5828c57f65149fc96418831147fdf0d4007a2c80 100644 (file)
@@ -25,7 +25,6 @@
 #include <ctime>
 #include <list>
 
-
 #include "pbd/stl_delete.h"
 #include "pbd/xml++.h"
 #include "pbd/enumwriter.h"
@@ -33,6 +32,7 @@
 #include "ardour/location.h"
 #include "ardour/session.h"
 #include "ardour/audiofilesource.h"
+#include "ardour/tempo.h"
 
 #include "i18n.h"
 
@@ -42,19 +42,47 @@ using namespace std;
 using namespace ARDOUR;
 using namespace PBD;
 
+Location::Location (Session& s)
+       : SessionHandleRef (s)
+       , _start (0)
+       , _end (0)
+       , _flags (Flags (0))
+       , _locked (false)
+       , _position_lock_style (AudioTime)
+{
+
+}
+
+Location::Location (Session& s, nframes64_t sample_start, nframes64_t sample_end, const std::string &name, Flags bits)
+       : SessionHandleRef (s)
+       , _name (name)
+       , _start (sample_start)
+       , _end (sample_end)
+       , _flags (bits)
+       , _locked (false)
+       , _position_lock_style (AudioTime)
+{
+       recompute_bbt_from_frames ();
+}
+
 Location::Location (const Location& other)
-       : StatefulDestructible(),
-         _name (other._name),
-         _start (other._start),
-         _end (other._end),
-         _flags (other._flags)
+       : SessionHandleRef (other._session)
+       , StatefulDestructible()
+       , _name (other._name)
+       , _start (other._start)
+       , _bbt_start (other._bbt_start)
+       , _end (other._end)
+       , _bbt_end (other._bbt_end)
+       , _flags (other._flags)
+       , _position_lock_style (other._position_lock_style)
 {
        /* copy is not locked even if original was */
 
        _locked = false;
 }
 
-Location::Location (const XMLNode& node)
+Location::Location (Session& s, const XMLNode& node)
+       : SessionHandleRef (s)
 {
        if (set_state (node, Stateful::loading_state_version)) {
                throw failed_constructor ();
@@ -70,8 +98,11 @@ Location::operator= (const Location& other)
 
        _name = other._name;
        _start = other._start;
+       _bbt_start = other._bbt_start;
        _end = other._end;
+       _bbt_end = other._bbt_end;
        _flags = other._flags;
+       _position_lock_style = other._position_lock_style;
 
        /* copy is not locked even if original was */
 
@@ -85,9 +116,10 @@ Location::operator= (const Location& other)
 /** Set start position.
  *  @param s New start.
  *  @param force true to force setting, even if the given new start is after the current end.
+ *  @param allow_bbt_recompute True to recompute BBT start time from the new given start time.
  */
 int
-Location::set_start (nframes64_t s, bool force)
+Location::set_start (nframes64_t s, bool force, bool allow_bbt_recompute)
 {
        if (_locked) {
                return -1;
@@ -103,6 +135,9 @@ Location::set_start (nframes64_t s, bool force)
                if (_start != s) {
                        _start = s;
                        _end = s;
+                       if (allow_bbt_recompute) {
+                               recompute_bbt_from_frames ();
+                       }
                        start_changed (this); /* EMIT SIGNAL */
                        end_changed (this); /* EMIT SIGNAL */
                }
@@ -111,6 +146,9 @@ Location::set_start (nframes64_t s, bool force)
        
        if (s != _start) {
                _start = s;
+               if (allow_bbt_recompute) {
+                       recompute_bbt_from_frames ();
+               }
                start_changed (this); /* EMIT SIGNAL */
                if (is_session_range ()) {
                        Session::StartTimeChanged (); /* EMIT SIGNAL */
@@ -124,9 +162,10 @@ Location::set_start (nframes64_t s, bool force)
 /** Set end position.
  *  @param s New end.
  *  @param force true to force setting, even if the given new start is after the current end.
+ *  @param allow_bbt_recompute True to recompute BBT end time from the new given end time.
  */
 int
-Location::set_end (nframes64_t e, bool force)
+Location::set_end (nframes64_t e, bool force, bool allow_bbt_recompute)
 {
        if (_locked) {
                return -1;
@@ -142,6 +181,9 @@ Location::set_end (nframes64_t e, bool force)
                if (_start != e) {
                        _start = e;
                        _end = e;
+                       if (allow_bbt_recompute) {
+                               recompute_bbt_from_frames ();
+                       }
                        start_changed (this); /* EMIT SIGNAL */
                        end_changed (this); /* EMIT SIGNAL */
                }
@@ -150,6 +192,9 @@ Location::set_end (nframes64_t e, bool force)
 
        if (e != _end) {
                _end = e;
+               if (allow_bbt_recompute) {
+                       recompute_bbt_from_frames ();
+               }
                end_changed(this); /* EMIT SIGNAL */
 
                if (is_session_range()) {
@@ -161,7 +206,7 @@ Location::set_end (nframes64_t e, bool force)
 }
 
 int
-Location::set (nframes64_t start, nframes64_t end)
+Location::set (nframes64_t start, nframes64_t end, bool allow_bbt_recompute)
 {
        /* check validity */
        if (((is_auto_punch() || is_auto_loop()) && start >= end) || (!is_mark() && start > end)) {
@@ -169,8 +214,8 @@ Location::set (nframes64_t start, nframes64_t end)
        }
 
        /* now we know these values are ok, so force-set them */
-       int const s = set_start (start, true);
-       int const e = set_end (end, true);
+       int const s = set_start (start, true, allow_bbt_recompute);
+       int const e = set_end (end, true, allow_bbt_recompute);
 
        return (s == 0 && e == 0) ? 0 : -1;
 }
@@ -185,6 +230,7 @@ Location::move_to (nframes64_t pos)
        if (_start != pos) {
                _start = pos;
                _end = _start + length();
+               recompute_bbt_from_frames ();
 
                changed (this); /* EMIT SIGNAL */
        }
@@ -291,7 +337,7 @@ Location::cd_info_node(const string & name, const string & value)
 
 
 XMLNode&
-Location::get_state (void)
+Location::get_state ()
 {
        XMLNode *node = new XMLNode ("Location");
        char buf[64];
@@ -401,15 +447,51 @@ Location::set_state (const XMLNode& node, int /*version*/)
 
        }
 
-       changed(this); /* EMIT SIGNAL */
+       recompute_bbt_from_frames ();
+
+       changed (this); /* EMIT SIGNAL */
 
        return 0;
 }
 
-/*---------------------------------------------------------------------- */
+void
+Location::set_position_lock_style (PositionLockStyle ps)
+{
+       if (_position_lock_style == ps) {
+               return;
+       }
 
-Locations::Locations ()
+       _position_lock_style = ps;
 
+       recompute_bbt_from_frames ();
+}
+
+void
+Location::recompute_bbt_from_frames ()
+{
+       if (_position_lock_style != MusicTime) {
+               return;
+       }
+       
+       _session.tempo_map().bbt_time (_start, _bbt_start);
+       _session.tempo_map().bbt_time (_end, _bbt_end);
+}
+
+void
+Location::recompute_frames_from_bbt ()
+{
+       if (_position_lock_style != MusicTime) {
+               return;
+       }
+
+       TempoMap& map (_session.tempo_map());
+       set (map.frame_time (_bbt_start), map.frame_time (_bbt_end), false);
+}
+
+/*---------------------------------------------------------------------- */
+
+Locations::Locations (Session& s)
+       : SessionHandleRef (s)
 {
        current_location = 0;
 }
@@ -426,7 +508,6 @@ Locations::~Locations ()
 
 int
 Locations::set_current (Location *loc, bool want_lock)
-
 {
        int ret;
 
@@ -658,7 +739,7 @@ Locations::set_state (const XMLNode& node, int version)
 
        Location* session_range_location = 0;
        if (version < 3000) {
-               session_range_location = new Location (0, 0, _("session"), Location::IsSessionRange);
+               session_range_location = new Location (_session, 0, 0, _("session"), Location::IsSessionRange);
                locations.push_back (session_range_location);
        }
 
@@ -670,7 +751,7 @@ Locations::set_state (const XMLNode& node, int version)
 
                        try {
 
-                               Location *loc = new Location (**niter);
+                               Location *loc = new Location (_session, **niter);
 
                                bool add = true;
 
index 8d6af300ca597d746dc2a7f0a4a9067323f988a7..167461609615a69b28528a52abb3be315b868a8b 100644 (file)
@@ -133,7 +133,7 @@ bool
 LocationImporter::_prepare_move ()
 {
        try {
-               Location const original (xml_location);
+               Location const original (session, xml_location);
                location = new Location (original); // Updates id
        } catch (failed_constructor& err) {
                throw std::runtime_error (X_("Error in session file!"));
index 79781236951b6c9ecb0714462312996dcd84cafe..2989e14afa5324a96bbf4d6a407f5f8cc7620ee6 100644 (file)
@@ -157,6 +157,8 @@ Session::Session (AudioEngine &eng,
          _have_rec_enabled_track (false),
          _suspend_timecode_transmission (0)
 {
+       _locations = new Locations (*this);
+               
        playlists.reset (new SessionPlaylists);
        
        interpolation.add_channel_to (0, 0);
@@ -313,6 +315,8 @@ Session::destroy ()
 
        boost_debug_list_ptrs ();
 
+       delete _locations;
+
        DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n");
 }
 
@@ -871,7 +875,7 @@ Session::set_auto_punch_location (Location* location)
 {
        Location* existing;
 
-       if ((existing = _locations.auto_punch_location()) != 0 && existing != location) {
+       if ((existing = _locations->auto_punch_location()) != 0 && existing != location) {
                punch_connections.drop_connections();
                existing->set_auto_punch (false, this);
                remove_event (existing->start(), SessionEvent::PunchIn);
@@ -908,7 +912,7 @@ Session::set_auto_loop_location (Location* location)
 {
        Location* existing;
 
-       if ((existing = _locations.auto_loop_location()) != 0 && existing != location) {
+       if ((existing = _locations->auto_loop_location()) != 0 && existing != location) {
                loop_connections.drop_connections ();
                existing->set_auto_loop (false, this);
                remove_event (existing->end(), SessionEvent::AutoLoop);
@@ -954,7 +958,7 @@ Session::locations_added (Location *)
 void
 Session::locations_changed ()
 {
-       _locations.apply (*this, &Session::handle_locations_changed);
+       _locations->apply (*this, &Session::handle_locations_changed);
 }
 
 void
@@ -3262,9 +3266,19 @@ Session::tempo_map_changed (const PropertyChange&)
 
        playlists->update_after_tempo_map_change ();
 
+       _locations->apply (*this, &Session::update_locations_after_tempo_map_change);
+       
        set_dirty ();
 }
 
+void
+Session::update_locations_after_tempo_map_change (Locations::LocationList& loc)
+{
+       for (Locations::LocationList::iterator i = loc.begin(); i != loc.end(); ++i) {
+               (*i)->recompute_frames_from_bbt ();
+       }
+}
+
 /** Ensures that all buffers (scratch, send, silent, etc) are allocated for
  * the given count with the current block size.
  */
@@ -3968,8 +3982,8 @@ Session::current_end_frame () const
 void
 Session::add_session_range_location (nframes_t start, nframes_t end)
 {
-       _session_range_location = new Location (start, end, _("session"), Location::IsSessionRange);
-       _locations.add (_session_range_location);
+       _session_range_location = new Location (*this, start, end, _("session"), Location::IsSessionRange);
+       _locations->add (_session_range_location);
 }
 
 /** Called when one of our routes' order keys has changed */
index dc918dfe1cd77a4cdb15bcdcbcb17d52b01a4624..8d3ce793bcf6eb65c74b0b89144f34bf798b29f1 100644 (file)
@@ -103,13 +103,13 @@ Session::memento_command_factory(XMLNode *n)
                    return new MementoCommand<Source>(*sources[id], before, after);
 
     } else if (obj_T == "ARDOUR::Location") {
-           Location* loc = _locations.get_location_by_id(id);
+           Location* loc = _locations->get_location_by_id(id);
            if (loc) {
                    return new MementoCommand<Location>(*loc, before, after);
            }
 
     } else if (obj_T == "ARDOUR::Locations") {
-           return new MementoCommand<Locations>(_locations, before, after);
+           return new MementoCommand<Locations>(*_locations, before, after);
 
     } else if (obj_T == "ARDOUR::TempoMap") {
            return new MementoCommand<TempoMap>(*_tempo_map, before, after);
index f4f2c5ad0eca56445774af9b676913276e468a85..6889e714fda67bdd69dfd303dbf901b7f0c3d32f 100644 (file)
@@ -608,7 +608,7 @@ Session::track_slave_state (float slave_speed, nframes_t slave_transport_frame,
 
                                _slave_state = Running;
 
-                               Location* al = _locations.auto_loop_location();
+                               Location* al = _locations->auto_loop_location();
 
                                if (al && play_loop && (slave_transport_frame < al->start() || slave_transport_frame > al->end())) {
                                        // cancel looping
index 94ea4bb2a1a78707805137b49581104c6160d260..a2dc6ced68f64bded95a7d66586cce08f8baa899 100644 (file)
@@ -325,8 +325,8 @@ Session::second_stage_init ()
 
        _state_of_the_state = StateOfTheState (_state_of_the_state|CannotSave|Loading);
 
-       _locations.changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
-       _locations.added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
+       _locations->changed.connect_same_thread (*this, boost::bind (&Session::locations_changed, this));
+       _locations->added.connect_same_thread (*this, boost::bind (&Session::locations_added, this, _1));
        setup_click_sounds (0);
        setup_midi_control ();
 
@@ -1094,12 +1094,12 @@ Session::state(bool full_state)
        }
 
        if (full_state) {
-               node->add_child_nocopy (_locations.get_state());
+               node->add_child_nocopy (_locations->get_state());
        } else {
                // for a template, just create a new Locations, populate it
                // with the default start and end, and get the state for that.
-               Locations loc;
-               Location* range = new Location (0, 0, _("session"), Location::IsSessionRange);
+               Locations loc (*this);
+               Location* range = new Location (*this, 0, 0, _("session"), Location::IsSessionRange);
                range->set (max_frames, 0);
                loc.add (range);
                node->add_child_nocopy (loc.get_state());
@@ -1278,21 +1278,21 @@ Session::set_state (const XMLNode& node, int version)
        if ((child = find_named_node (node, "Locations")) == 0) {
                error << _("Session: XML state has no locations section") << endmsg;
                goto out;
-       } else if (_locations.set_state (*child, version)) {
+       } else if (_locations->set_state (*child, version)) {
                goto out;
        }
 
        Location* location;
 
-       if ((location = _locations.auto_loop_location()) != 0) {
+       if ((location = _locations->auto_loop_location()) != 0) {
                set_auto_loop_location (location);
        }
 
-       if ((location = _locations.auto_punch_location()) != 0) {
+       if ((location = _locations->auto_punch_location()) != 0) {
                set_auto_punch_location (location);
        }
 
-       if ((location = _locations.session_range_location()) != 0) {
+       if ((location = _locations->session_range_location()) != 0) {
                delete _session_range_location;
                _session_range_location = location;
        }
@@ -3165,7 +3165,7 @@ Session::config_changed (std::string p, bool ours)
 
                Location* location;
 
-               if ((location = _locations.auto_punch_location()) != 0) {
+               if ((location = _locations->auto_punch_location()) != 0) {
 
                        if (config.get_punch_in ()) {
                                replace_event (SessionEvent::PunchIn, location->start());
@@ -3178,7 +3178,7 @@ Session::config_changed (std::string p, bool ours)
 
                Location* location;
 
-               if ((location = _locations.auto_punch_location()) != 0) {
+               if ((location = _locations->auto_punch_location()) != 0) {
 
                        if (config.get_punch_out()) {
                                replace_event (SessionEvent::PunchOut, location->end());
index b722bc04a78b9dd38e759cc3caeaf3afeb2aa36b..64f9d1e6163415109813aeb987f895f05ee89647 100644 (file)
@@ -142,7 +142,7 @@ void
 Session::request_play_loop (bool yn, bool leave_rolling)
 {
        SessionEvent* ev;
-       Location *location = _locations.auto_loop_location();
+       Location *location = _locations->auto_loop_location();
 
        if (location == 0 && yn) {
                error << _("Cannot loop - no loop range defined")
@@ -503,7 +503,7 @@ Session::non_realtime_stop (bool abort, int on_entry, bool& finished)
 
                                                if (!synced_to_jack()) {
 
-                                                       Location *location = _locations.auto_loop_location();
+                                                       Location *location = _locations->auto_loop_location();
                                                        
                                                        if (location != 0) {
                                                                _transport_frame = location->start();
@@ -653,7 +653,7 @@ Session::set_play_loop (bool yn)
 
        Location *loc;
 
-       if (yn == play_loop || (actively_recording() && yn) || (loc = _locations.auto_loop_location()) == 0) {
+       if (yn == play_loop || (actively_recording() && yn) || (loc = _locations->auto_loop_location()) == 0) {
                /* nothing to do, or can't change loop status while recording */
                return;
        }
@@ -873,7 +873,7 @@ Session::locate (nframes64_t target_frame, bool with_roll, bool with_flush, bool
 
        /* cancel looped playback if transport pos outside of loop range */
        if (play_loop) {
-               Location* al = _locations.auto_loop_location();
+               Location* al = _locations->auto_loop_location();
 
                if (al && (_transport_frame < al->start() || _transport_frame > al->end())) {
                        // cancel looping directly, this is called from event handling context
index 2c3305e66faf3b97e6229f13b9510861aea59657..2bea3b529cfbe60ef1c805803e0e4e6c27bb204b 100644 (file)
@@ -95,7 +95,7 @@ void
 BasicUI::add_marker ()
 {
        nframes_t when = session->audible_frame();
-       session->locations()->add (new Location (when, when, _("unnamed"), Location::IsMark));
+       session->locations()->add (new Location (*session, when, when, _("unnamed"), Location::IsMark));
 }
 
 void
index e9f3223796e6d23c8de78591d56424f5918fc77e..72827e9fc90c1721fd13e53f7015a194124d1f1c 100644 (file)
@@ -1601,7 +1601,7 @@ MackieControlProtocol::marker_press (Button &)
        string markername;
        nframes_t where = session->audible_frame();
        session->locations()->next_available_name(markername,"mcu");
-       Location *location = new Location (where, where, markername, Location::IsMark);
+       Location *location = new Location (*session, where, where, markername, Location::IsMark);
        session->begin_reversible_command (_("add marker"));
        XMLNode &before = session->locations()->get_state();
        session->locations()->add (location, true);