various fixes for moving markers, fixes a crash reported by tim blechmann and also...
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 2 Jan 2013 23:54:06 +0000 (23:54 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 2 Jan 2013 23:54:06 +0000 (23:54 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@13754 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/editor_drag.cc
gtk2_ardour/editor_drag.h
gtk2_ardour/selection.cc
gtk2_ardour/startup.cc
libs/ardour/ardour/location.h
libs/ardour/location.cc

index 0c309d723458ddb727de2def826b36fc0421d27d..1cc5e97dc6c06fbd2c3e83291ed9930c8b0ed262 100644 (file)
@@ -2543,11 +2543,18 @@ MarkerDrag::MarkerDrag (Editor* e, ArdourCanvas::Item* i)
 
 MarkerDrag::~MarkerDrag ()
 {
-       for (list<Location*>::iterator i = _copied_locations.begin(); i != _copied_locations.end(); ++i) {
-               delete *i;
+       for (CopiedLocationInfo::iterator i = _copied_locations.begin(); i != _copied_locations.end(); ++i) {
+               delete i->location;
        }
 }
 
+MarkerDrag::CopiedLocationMarkerInfo::CopiedLocationMarkerInfo (Location* l, Marker* m)
+{
+       location = new Location (*l);
+       markers.push_back (m);
+       move_both = false;
+}
+
 void
 MarkerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
 {
@@ -2573,7 +2580,7 @@ MarkerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
 
        switch (op) {
        case Selection::Toggle:
-               _editor->selection->toggle (_marker);
+               /* we toggle on the button release */
                break;
        case Selection::Set:
                if (!_editor->selection->selected (_marker)) {
@@ -2615,11 +2622,37 @@ MarkerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
                break;
        }
 
-       /* Set up copies for us to manipulate during the drag */
+       /* Set up copies for us to manipulate during the drag 
+        */
 
        for (MarkerSelection::iterator i = _editor->selection->markers.begin(); i != _editor->selection->markers.end(); ++i) {
+
                Location* l = _editor->find_location_from_marker (*i, is_start);
-               _copied_locations.push_back (new Location (*l));
+
+               if (!l) {
+                       continue;
+               }
+
+               if (l->is_mark()) {
+                       _copied_locations.push_back (CopiedLocationMarkerInfo (l, *i));
+               } else {
+                       /* range: check that the other end of the range isn't
+                          already there.
+                       */
+                       CopiedLocationInfo::iterator x;
+                       for (x = _copied_locations.begin(); x != _copied_locations.end(); ++x) {
+                               if (*(*x).location == *l) {
+                                       break;
+                               }
+                       }
+                       if (x == _copied_locations.end()) {
+                               _copied_locations.push_back (CopiedLocationMarkerInfo (l, *i));
+                       } else {
+                               (*x).markers.push_back (*i);
+                               (*x).move_both = true;
+                       }
+               }
+                       
        }
 }
 
@@ -2637,33 +2670,31 @@ MarkerDrag::motion (GdkEvent* event, bool)
        framecnt_t f_delta = 0;
        bool is_start;
        bool move_both = false;
-       Marker* marker;
        Location *real_location;
        Location *copy_location = 0;
 
        framepos_t const newframe = adjusted_current_frame (event);
-
        framepos_t next = newframe;
 
        if (Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) {
                move_both = true;
        }
 
-       MarkerSelection::iterator i;
-       list<Location*>::iterator x;
+       CopiedLocationInfo::iterator x;
 
        /* find the marker we're dragging, and compute the delta */
 
-       for (i = _editor->selection->markers.begin(), x = _copied_locations.begin();
-            x != _copied_locations.end() && i != _editor->selection->markers.end();
-            ++i, ++x) {
+       for (x = _copied_locations.begin(); x != _copied_locations.end(); ++x) {
+
+               copy_location = (*x).location;
 
-               copy_location = *x;
-               marker = *i;
+               if (find (x->markers.begin(), x->markers.end(), _marker) != x->markers.end()) {
 
-               if (marker == _marker) {
+                       /* this marker is represented by this
+                        * CopiedLocationMarkerInfo 
+                        */
 
-                       if ((real_location = _editor->find_location_from_marker (marker, is_start)) == 0) {
+                       if ((real_location = _editor->find_location_from_marker (_marker, is_start)) == 0) {
                                /* que pasa ?? */
                                return;
                        }
@@ -2673,7 +2704,7 @@ MarkerDrag::motion (GdkEvent* event, bool)
                        } else {
 
 
-                               switch (marker->type()) {
+                               switch (_marker->type()) {
                                case Marker::SessionStart:
                                case Marker::RangeStart:
                                case Marker::LoopStart:
@@ -2692,27 +2723,25 @@ MarkerDrag::motion (GdkEvent* event, bool)
                                        return;
                                }
                        }
+
                        break;
                }
        }
 
-       if (i == _editor->selection->markers.end()) {
+       if (x == _copied_locations.end()) {
                /* hmm, impossible - we didn't find the dragged marker */
                return;
        }
 
        /* now move them all */
 
-       for (i = _editor->selection->markers.begin(), x = _copied_locations.begin();
-            x != _copied_locations.end() && i != _editor->selection->markers.end();
-            ++i, ++x) {
+       for (x = _copied_locations.begin(); x != _copied_locations.end(); ++x) {
 
-               copy_location = *x;
-               marker = *i;
+               copy_location = x->location;
 
                /* call this to find out if its the start or end */
 
-               if ((real_location = _editor->find_location_from_marker (marker, is_start)) == 0) {
+               if ((real_location = _editor->find_location_from_marker (x->markers.front(), is_start)) == 0) {
                        continue;
                }
 
@@ -2727,13 +2756,22 @@ MarkerDrag::motion (GdkEvent* event, bool)
                        copy_location->set_start (copy_location->start() + f_delta);
 
                } else {
-
+                       
                        framepos_t new_start = copy_location->start() + f_delta;
                        framepos_t new_end = copy_location->end() + f_delta;
+                       
+                       /* if we are moving multiple markers, we can have
+                        * forced earlier ones back before zero ... don't
+                        * do this 
+                        */
 
-                       if (is_start) { // start-of-range marker
+                       if (new_start < 0 || new_end < 0) {
+                               continue;
+                       }
 
-                               if (move_both) {
+                       if (is_start) { // start-of-range marker
+                               
+                               if (move_both || (*x).move_both) {
                                        copy_location->set_start (new_start);
                                        copy_location->set_end (new_end);
                                } else  if (new_start < copy_location->end()) {
@@ -2746,7 +2784,7 @@ MarkerDrag::motion (GdkEvent* event, bool)
 
                        } else { // end marker
 
-                               if (move_both) {
+                               if (move_both || (*x).move_both) {
                                        copy_location->set_end (new_end);
                                        copy_location->set_start (new_start);
                                } else if (new_end > copy_location->start()) {
@@ -2760,12 +2798,20 @@ MarkerDrag::motion (GdkEvent* event, bool)
                }
 
                update_item (copy_location);
-
+               
+               /* now lookup the actual GUI items used to display this
+                * location and move them to wherever the copy of the location
+                * is now. This means that the logic in ARDOUR::Location is
+                * still enforced, even though we are not (yet) modifying 
+                * the real Location itself.
+                */
+               
                Editor::LocationMarkers* lm = _editor->find_location_markers (real_location);
 
                if (lm) {
                        lm->set_position (copy_location->start(), copy_location->end());
                }
+
        }
 
        assert (!_copied_locations.empty());
@@ -2796,6 +2842,10 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred)
                        break;
 
                case Selection::Toggle:
+                       /* we toggle on the button release, click only */
+                       _editor->selection->toggle (_marker);
+                       break;
+
                case Selection::Extend:
                case Selection::Add:
                        break;
@@ -2810,7 +2860,7 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred)
        XMLNode &before = _editor->session()->locations()->get_state();
 
        MarkerSelection::iterator i;
-       list<Location*>::iterator x;
+       CopiedLocationInfo::iterator x;
        bool is_start;
 
        for (i = _editor->selection->markers.begin(), x = _copied_locations.begin();
@@ -2826,9 +2876,9 @@ MarkerDrag::finished (GdkEvent* event, bool movement_occurred)
                        }
 
                        if (location->is_mark()) {
-                               location->set_start ((*x)->start());
+                               location->set_start (((*x).location)->start());
                        } else {
-                               location->set ((*x)->start(), (*x)->end());
+                               location->set (((*x).location)->start(), ((*x).location)->end());
                        }
                }
        }
index e3e4b5e665cf2ec48d8bfa7ad2910e5b464ccda6..196552f96a9e99fd824700513b0b519700316b1e 100644 (file)
@@ -682,7 +682,16 @@ private:
        void update_item (ARDOUR::Location *);
 
        Marker* _marker; ///< marker being dragged
-       std::list<ARDOUR::Location*> _copied_locations;
+
+        struct CopiedLocationMarkerInfo {
+           ARDOUR::Location* location;
+           std::vector<Marker*> markers;
+           bool    move_both;
+           CopiedLocationMarkerInfo (ARDOUR::Location* l, Marker* m);
+       };
+
+        typedef std::list<CopiedLocationMarkerInfo> CopiedLocationInfo;
+        CopiedLocationInfo _copied_locations;
        ArdourCanvas::Points _points;
 };
 
index f6643d382911cb91fd9c4c3c020a6e6e74866b26..146d9a65c50f9c2da169a66bdc44b8a7988e0aac 100644 (file)
@@ -1129,7 +1129,7 @@ void
 Selection::set (Marker* m)
 {
        clear_time ();  //enforce region/object exclusivity
-       clear_objects();
+       markers.clear ();
 
        add (m);
 }
@@ -1137,8 +1137,6 @@ Selection::set (Marker* m)
 void
 Selection::toggle (Marker* m)
 {
-       clear_time ();  //enforce region/object exclusivity
-
        MarkerSelection::iterator i;
 
        if ((i = find (markers.begin(), markers.end(), m)) == markers.end()) {
index 328e06c9c0c49c1a9907c188ce5d9ee65f6814f3..acd26fcaaf24f77b17090905b67f5ed1901503af 100644 (file)
@@ -63,6 +63,11 @@ static string poor_mans_glob (string path)
        return copy;
 }
 
+static void show_me (Gtk::FileChooserButton* fcb)
+{
+       cerr << " Current folder of " << fcb << " changed to " << fcb->get_current_folder() << endl;
+}
+
 
 ArdourStartup::ArdourStartup (bool require_new, const std::string& session_name, const std::string& session_path, const std::string& template_name)
        : _response (RESPONSE_OK)
@@ -94,6 +99,8 @@ Ardour will play NO role in monitoring"))
        need_audio_setup = EngineControl::need_setup ();
        need_session_info = (session_name.empty() || require_new);
 
+       new_folder_chooser.signal_current_folder_changed().connect (sigc::bind (sigc::ptr_fun (show_me), &new_folder_chooser));
+
        _provided_session_name = session_name;
        _provided_session_path = session_path;
        
@@ -298,6 +305,7 @@ ArdourStartup::session_folder ()
 
        if (ic_new_session_button.get_active()) {
                std::string legal_session_folder_name = legalize_for_path (new_name_entry.get_text());
+               cerr << "using NFC @ " << &new_folder_chooser << ' ' << new_folder_chooser.get_current_folder() << " file " << new_folder_chooser.get_filename() << endl;
                return Glib::build_filename (new_folder_chooser.get_current_folder(), legal_session_folder_name);
        } else if (_existing_session_chooser_used) {
                /* existing session chosen from file chooser */
index 414f332b5e02e430e51643a4a263cb0db90dd5a3..2b9c53e0633c7852a8da8bbf4b75486b334f5087 100644 (file)
@@ -56,6 +56,8 @@ class Location : public SessionHandleRef, public PBD::StatefulDestructible
        Location (const Location& other);
        Location (Session &, const XMLNode&);
        Location* operator= (const Location& other);
+    
+        bool operator==(const Location& other);
 
        bool locked() const { return _locked; }
        void lock ();
index 96a289e06f8efadde00b279fd5f1c35c541ed3b0..4586fbee26d342b216e820751d11c0429872fe2f 100644 (file)
@@ -105,6 +105,21 @@ Location::Location (Session& s, const XMLNode& node)
        assert (_end >= 0);
 }
 
+bool
+Location::operator== (const Location& other)
+{
+       if (_name != other._name ||
+           _start != other._start ||
+           _end != other._end ||
+           _bbt_start != other._bbt_start ||
+           _bbt_end != other._bbt_end ||
+           _flags != other._flags ||
+           _position_lock_style != other._position_lock_style) {
+               return false;
+       }
+       return true;
+}
+
 Location*
 Location::operator= (const Location& other)
 {
@@ -140,6 +155,10 @@ Location::operator= (const Location& other)
 int
 Location::set_start (framepos_t s, bool force, bool allow_bbt_recompute)
 {
+       if (s < 0) {
+               return -1;
+       }
+
        if (_locked) {
                return -1;
        }
@@ -196,6 +215,10 @@ Location::set_start (framepos_t s, bool force, bool allow_bbt_recompute)
 int
 Location::set_end (framepos_t e, bool force, bool allow_bbt_recompute)
 {
+       if (e < 0) {
+               return -1;
+       }
+
        if (_locked) {
                return -1;
        }
@@ -224,6 +247,7 @@ Location::set_end (framepos_t e, bool force, bool allow_bbt_recompute)
        }
 
        if (e != _end) {
+
                framepos_t const old = _end;
 
                _end = e;
@@ -245,6 +269,10 @@ Location::set_end (framepos_t e, bool force, bool allow_bbt_recompute)
 int
 Location::set (framepos_t start, framepos_t end, bool allow_bbt_recompute)
 {
+       if (start < 0 || end < 0) {
+               return -1;
+       }
+
        /* check validity */
        if (((is_auto_punch() || is_auto_loop()) && start >= end) || (!is_mark() && start > end)) {
                return -1;
@@ -260,6 +288,10 @@ Location::set (framepos_t start, framepos_t end, bool allow_bbt_recompute)
 int
 Location::move_to (framepos_t pos)
 {
+       if (pos < 0) {
+               return -1;
+       }
+
        if (_locked) {
                return -1;
        }