fix up botched marker management scheme; add Editor::get_edit_op_range(); make cut...
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 9 Nov 2007 17:52:32 +0000 (17:52 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 9 Nov 2007 17:52:32 +0000 (17:52 +0000)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2614 d708f5d6-7413-0410-9779-e7cbd77b26cf

SConstruct
gtk2_ardour/SConscript
gtk2_ardour/ardour-sae.menus
gtk2_ardour/ardour.menus
gtk2_ardour/editor.h
gtk2_ardour/editor_actions.cc
gtk2_ardour/editor_markers.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_selection.cc

index be008c5c24acb65987773452a621ccee5922d921..91e0bc00996f7849332d19383a94a65faadce6a0 100644 (file)
@@ -472,6 +472,16 @@ libraries['raptor'].ParseConfig('pkg-config --cflags --libs raptor')
 libraries['samplerate'] = LibraryInfo()
 libraries['samplerate'].ParseConfig('pkg-config --cflags --libs samplerate')
 
+libraries['rubberband'] = LibraryInfo()
+#
+# chris cannam's rubberband has not yet been released
+# 
+if os.path.exists ('libs/rubberband'):
+    libraries['rubberband'] = LibraryInfo (LIBS='rubberband',
+                                           LIBPATH='#libs/rubberband/lib',
+                                           CPPPATH='#libs/rubberband/src',
+                                           CXXFLAGS='-DUSE_RUBBERBAND')
+
 if env['FFT_ANALYSIS']:
        libraries['fftw3f'] = LibraryInfo()
        libraries['fftw3f'].ParseConfig('pkg-config --cflags --libs fftw3f')
index b1c6a6b75c29a63eb76b949333f1373554a19ca3..04ebf15f5b12c80ec3ac49b99aae9ae0fdcdf716 100644 (file)
@@ -50,6 +50,7 @@ gtkardour.Merge ([
     libraries['xml'],
     libraries['xslt'],
     libraries['soundtouch'],
+    libraries['rubberband'],
     libraries['samplerate'],
     libraries['jack']
 ])
index 111678429fda6067c97bdfaac3381670b821469c..47bd89801c064a011d5b6a7de86ecd2d6209f2a7 100644 (file)
                <menuitem action='set-edit-point'/>
               <menuitem action='remove-last-capture'/>
                <separator/>       
-               <menu action="EditSelectRangeOptions">
-                   <menuitem action='select-range-between-cursors'/>
-                   <menuitem action='extend-range-to-start-of-region'/>
-                   <menuitem action='extend-range-to-end-of-region'/>
-                   <menuitem action='start-range'/>
-                   <menuitem action='finish-range'/>
-                   <menuitem action='finish-add-range'/>
-               </menu>
-               <menu action="EditSelectRegionOptions">
-                   <menuitem action='select-all'/>
-                   <menuitem action='select-all-after-edit-cursor'/>
-                   <menuitem action='select-all-before-edit-cursor'/>
-                   <menuitem action='select-all-after-playhead'/>
-                   <menuitem action='select-all-before-playhead'/>
-                   <menuitem action='select-all-between-cursors'/>
-                   <menuitem action='select-all-within-cursors'/>
-                   <menuitem action='select-all-in-punch-range'/>
-                   <menuitem action='select-all-in-loop-range'/>
-               </menu>
               <menu action='EditCursorMovementOptions'>
                    <menuitem action='edit-cursor-to-next-region-start'/>
                   <menuitem action='edit-cursor-to-next-region-end'/>
                 <separator/>       
                 <menuitem action='ToggleOptionsEditor'/>
         </menu>         
+       <menu name='Select' action='Select'>
+                   <menuitem action='select-range-between-cursors'/>
+                   <menuitem action='extend-range-to-start-of-region'/>
+                   <menuitem action='extend-range-to-end-of-region'/>
+                   <menuitem action='start-range'/>
+                   <menuitem action='finish-range'/>
+                   <menuitem action='finish-add-range'/>
+                  <separator/>
+                   <menuitem action='select-all'/>
+                   <menuitem action='select-all-after-edit-cursor'/>
+                   <menuitem action='select-all-before-edit-cursor'/>
+                   <menuitem action='select-all-after-playhead'/>
+                   <menuitem action='select-all-before-playhead'/>
+                   <menuitem action='select-all-between-cursors'/>
+                   <menuitem action='select-all-within-cursors'/>
+                   <menuitem action='select-all-in-punch-range'/>
+                   <menuitem action='select-all-in-loop-range'/>
+       </menu>
        <menu name='Regions' action='Regions'>
                    <menuitem action='crop'/>
                    <menuitem action='duplicate-region'/>
index d6f40a3fff8745d0704099bf07bf7432da9dcfd8..15865e273a72295c7031045494657be1bf9d08ee 100644 (file)
                <menuitem action='editor-paste'/>
               <menuitem action='remove-last-capture'/>
                <separator/>       
-               <menu action="EditSelectRangeOptions">
+              <menu action='EditCursorMovementOptions'>
+                   <menuitem action='edit-cursor-to-next-region-start'/>
+                  <menuitem action='edit-cursor-to-next-region-end'/>
+                          <menuitem action='edit-cursor-to-previous-region-start'/>
+                  <menuitem action='edit-cursor-to-previous-region-end'/>
+                  <menuitem action='edit-cursor-to-next-region-sync'/>
+                  <menuitem action='edit-cursor-to-previous-region-sync'/>
+                  <menuitem action='center-edit-cursor'/>
+                  <menuitem action='edit-to-playhead'/>
+                  <menuitem action='edit-cursor-to-range-start'/>
+                  <menuitem action='edit-cursor-to-range-end'/>
+              </menu>
+              <menu name='KeyMouse Actions' action='KeyMouse Actions'>
+                       <menuitem action='audition-at-mouse'/>
+                               <menuitem action='brush-at-mouse'/>
+                               <menuitem action='set-edit-point'/>
+                               <menuitem action='mute-unmute-region'/>
+                       <menuitem action='set-playhead'/>
+                       <menuitem action='split-region'/>
+                       <menuitem action='set-region-sync-position'/>
+                       <separator/>
+                       <menuitem action='set-mouse-mode-object'/>
+                       <menuitem action='set-mouse-mode-range'/>
+                       <menuitem action='set-mouse-mode-gain'/>
+                       <menuitem action='set-mouse-mode-zoom'/>
+                       <menuitem action='set-mouse-mode-timefx'/>
+          </menu>
+        </menu>         
+       <menu name='Select' action='Select'>
                    <menuitem action='select-range-between-cursors'/>
                    <menuitem action='extend-range-to-start-of-region'/>
                    <menuitem action='extend-range-to-end-of-region'/>
                    <menuitem action='start-range'/>
                    <menuitem action='finish-range'/>
                    <menuitem action='finish-add-range'/>
-               </menu>
-               <menu action="EditSelectRegionOptions">
+                  <separator/>
                    <menuitem action='select-all'/>
                    <menuitem action='select-all-after-edit-cursor'/>
                    <menuitem action='select-all-before-edit-cursor'/>
                    <menuitem action='select-all-within-cursors'/>
                    <menuitem action='select-all-in-punch-range'/>
                    <menuitem action='select-all-in-loop-range'/>
-               </menu>
-              <menu action='EditCursorMovementOptions'>
-                   <menuitem action='edit-cursor-to-next-region-start'/>
-                  <menuitem action='edit-cursor-to-next-region-end'/>
-                          <menuitem action='edit-cursor-to-previous-region-start'/>
-                  <menuitem action='edit-cursor-to-previous-region-end'/>
-                  <menuitem action='edit-cursor-to-next-region-sync'/>
-                  <menuitem action='edit-cursor-to-previous-region-sync'/>
-                  <menuitem action='center-edit-cursor'/>
-                  <menuitem action='edit-to-playhead'/>
-                  <menuitem action='edit-cursor-to-range-start'/>
-                  <menuitem action='edit-cursor-to-range-end'/>
-              </menu>
-              <menu action='RegionEditOps'>
+       </menu>
+       <menu name='Regions' action='Regions'>
                    <menuitem action='crop'/>
                    <menuitem action='duplicate-region'/>
                    <menuitem action='insert-region'/>
                   <menuitem action="nudge-next-forward"/>
                   <menuitem action="nudge-backward"/>
                   <menuitem action="nudge-next-backward"/>
+                  <menuitem action='split-region'/>
+                  <menuitem action='set-region-sync-position'/>
                    <separator/>       
                   <menuitem action='align-regions-start'/>
                   <menuitem action='align-regions-start-relative'/>
                   <menuitem action='align-regions-end-relative'/>
                   <menuitem action='align-regions-sync'/>
                   <menuitem action='align-regions-sync-relative'/>
-              </menu>
-              <menu name='KeyMouse Actions' action='KeyMouse Actions'>
-                       <menuitem action='audition-at-mouse'/>
-                               <menuitem action='brush-at-mouse'/>
-                               <menuitem action='set-edit-point'/>
-                               <menuitem action='mute-unmute-region'/>
-                       <menuitem action='set-playhead'/>
-                       <menuitem action='split-region'/>
-                       <menuitem action='set-region-sync-position'/>
-                       <separator/>
-                       <menuitem action='set-mouse-mode-object'/>
-                       <menuitem action='set-mouse-mode-range'/>
-                       <menuitem action='set-mouse-mode-gain'/>
-                       <menuitem action='set-mouse-mode-zoom'/>
-                       <menuitem action='set-mouse-mode-timefx'/>
-          </menu>
-        </menu>         
+       </menu>
         <menu name='View' action = 'View'>
                <menu name='ZoomFocus' action='ZoomFocus'>
                    <menuitem action='zoom-focus-left'/>
index c627e8da6366d0f7b49a512e6bb0d20baa87af73..25657e36f425bc5a5c3c7976362f25f045d071cc 100644 (file)
@@ -403,7 +403,10 @@ class Editor : public PublicEditor
        struct LocationMarkers {
            Marker* start;
            Marker* end;
+           bool    valid;
 
+           LocationMarkers () : start(0), end(0), valid (true) {}
+           
            ~LocationMarkers ();
 
            void hide();
@@ -906,6 +909,7 @@ class Editor : public PublicEditor
        void split_region_at (nframes_t);
        void split_regions_at (nframes_t, RegionSelection&);
        void crop_region_to_selection ();
+       void crop_region_to (nframes_t start, nframes_t end);
        void set_a_regions_sync_position (boost::shared_ptr<ARDOUR::Region>, nframes_t);
        void set_region_sync_from_edit_point ();
        void remove_region_sync();
@@ -1922,6 +1926,8 @@ class Editor : public PublicEditor
        Glib::RefPtr<Gtk::RadioAction> edit_point_action (Editing::EditPoint);
        std::vector<std::string> edit_point_strings;
 
+       bool get_edit_op_range (nframes64_t& start, nframes64_t& end) const;
+
        RegionSelection get_regions_at (nframes64_t where, const TrackSelection& ts) const;
 
 };
index 3742edcf7073846e49cadc53a843515fd2b60373..937d83c7c8c905f6fb764eff186c6b555da91c1b 100644 (file)
@@ -45,6 +45,7 @@ Editor::register_actions ()
        /* non-operative menu items for menu bar */
 
        ActionManager::register_action (editor_actions, X_("Edit"), _("Edit"));
+       ActionManager::register_action (editor_actions, X_("Select"), _("Select"));
        ActionManager::register_action (editor_actions, X_("EditSelectRegionOptions"), _("Select Regions"));
        ActionManager::register_action (editor_actions, X_("EditSelectRangeOptions"), _("Select Range Operations"));
        ActionManager::register_action (editor_actions, X_("EditCursorMovementOptions"), _("Move Selected Marker"));
index 772e5fd038027e3d4c72b57ae575043a0df37724..3e0868e048ae50fc31851c50ce405c5f69c1c791 100644 (file)
@@ -223,11 +223,43 @@ Editor::find_location_from_marker (Marker *marker, bool& is_start) const
 void
 Editor::refresh_location_display_internal (Locations::LocationList& locations)
 {
-       clear_marker_display ();
+       /* invalidate all */
+
+       for (LocationMarkerMap::iterator i = location_markers.begin(); i != location_markers.end(); ++i) {
+               i->second->valid = false;
+       }
        
+       /* add new ones */
+
        for (Locations::LocationList::iterator i = locations.begin(); i != locations.end(); ++i) {
+
+               LocationMarkerMap::iterator x;
+
+               if ((x = location_markers.find (*i)) != location_markers.end()) {
+                       x->second->valid = true;
+                       continue;
+               }
+
                add_new_location (*i);
        }
+
+       /* remove dead ones */
+
+       for (LocationMarkerMap::iterator i = location_markers.begin(); i != location_markers.end(); ) {
+
+               LocationMarkerMap::iterator tmp;
+
+               tmp = i;
+               ++tmp;
+
+               if (!i->second->valid) {
+                       delete i->second;
+                       location_markers.erase (i);
+               } 
+
+               i = tmp;
+       }
+       
 }
 
 void
index 442397f4f8378a89244088d4163dad4597102ea0..73681bd62c88f350281d920ccef307c91e74f9f8 100644 (file)
@@ -2323,16 +2323,37 @@ Editor::separate_regions_using_location (Location& loc)
 void
 Editor::crop_region_to_selection ()
 {
-       if (selection->time.empty() || selection->tracks.empty()) {
-               return;
+       if (!selection->time.empty()) {
+
+               crop_region_to (selection->time.start(), selection->time.end_frame());
+
+       } else if (_edit_point != EditAtPlayhead) {
+
+               nframes64_t start;
+               nframes64_t end;
+
+               if (get_edit_op_range (start, end)) {
+                       crop_region_to (start, end);
+               }
        }
+               
+}              
 
+void
+Editor::crop_region_to (nframes_t start, nframes_t end)
+{
        vector<boost::shared_ptr<Playlist> > playlists;
        boost::shared_ptr<Playlist> playlist;
+       TrackSelection* ts;
 
-       sort_track_selection ();
+       if (selection->tracks.empty()) {
+               ts = &track_views;
+       } else {
+               sort_track_selection ();
+               ts = &selection->tracks;
+       }
        
-       for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+       for (TrackSelection::iterator i = ts->begin(); i != ts->end(); ++i) {
                
                AudioTimeAxisView* atv;
                
@@ -2357,8 +2378,8 @@ Editor::crop_region_to_selection ()
                return;
        }
                
-       nframes_t start;
-       nframes_t end;
+       nframes_t the_start;
+       nframes_t the_end;
        nframes_t cnt;
        
        begin_reversible_command (_("trim to selection"));
@@ -2366,10 +2387,10 @@ Editor::crop_region_to_selection ()
        for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
                
                boost::shared_ptr<Region> region;
-               
-               start = selection->time.start();
-               
-               if ((region = (*i)->top_region_at(start)) == 0) {
+       
+               the_start = start;
+       
+               if ((region = (*i)->top_region_at(the_start)) == 0) {
                        continue;
                }
                
@@ -2377,17 +2398,17 @@ Editor::crop_region_to_selection ()
                   if the selection extends beyond the region
                */
                
-               start = max (start, region->position());
-               if (max_frames - start < region->length()) {
-                       end = start + region->length() - 1;
+               the_start = max (the_start, region->position());
+               if (max_frames - the_start < region->length()) {
+                       the_end = the_start + region->length() - 1;
                } else {
-                       end = max_frames;
+                       the_end = max_frames;
                }
-               end = min (selection->time.end_frame(), end);
-               cnt = end - start + 1;
+               the_end = min (end, the_end);
+               cnt = the_end - the_start + 1;
                
                XMLNode &before = (*i)->get_state();
-               region->trim_to (start, cnt, this);
+               region->trim_to (the_start, cnt, this);
                XMLNode &after = (*i)->get_state();
                session->add_command (new MementoCommand<Playlist>(*(*i), &before, &after));
        }
@@ -2927,21 +2948,31 @@ Editor::cut_copy (CutCopyOp op)
                        }
 
                        commit_reversible_command ();   
+                       break; // terminate case statement here
+               } 
+               if (!selection->time.empty()) {
+                       /* don't cause suprises */
+                       break;
                }
-               break;
+               // fall thru if there was nothing selected
                
        case MouseRange:
-               if (!selection->time.empty()) {
-
-                       begin_reversible_command (opname + _(" range"));
-                       cut_copy_ranges (op);
-                       commit_reversible_command ();
-
-                       if (op == Cut) {
-                               selection->clear_time ();
+               if (selection->time.empty()) {
+                       nframes64_t start, end;
+                       if (!get_edit_op_range (start, end)) {
+                               return;
                        }
+                       selection->set (0, start, end);
+               }
                        
+               begin_reversible_command (opname + _(" range"));
+               cut_copy_ranges (op);
+               commit_reversible_command ();
+               
+               if (op == Cut) {
+                       selection->clear_time ();
                }
+
                break;
                
        default:
index 91d3a3b9395f66cfd93692e969a5d70d0a863e07..9f825b0a514bcf0928ef0b14133fc5992677da83 100644 (file)
@@ -1040,29 +1040,17 @@ Editor::select_all_selectables_between (bool within)
        nframes64_t end;
        list<Selectable *> touched;
 
-       if (_edit_point == EditAtPlayhead) {
+       if (!get_edit_op_range (start, end)) {
                return;
        }
        
-       start = get_preferred_edit_position();
-       end = playhead_cursor->current_frame;
-
-       if (start == end) {
-               return;
-       }
-
-       if (start > end) {
-               swap (start, end);
-       }
-
-       end -= 1;
-       
        for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
                if ((*iter)->hidden()) {
                        continue;
                }
                (*iter)->get_selectables (start, end, 0, DBL_MAX, touched);
        }
+
        selection->set (touched);
 }
 
@@ -1071,25 +1059,70 @@ Editor::select_range_between ()
 {
         nframes64_t start;
        nframes64_t end;
-       list<Selectable *> touched;
-
-       if (_edit_point == EditAtPlayhead) {
+       
+       if (!get_edit_op_range (start, end)) {
                return;
        }
-       
-       start = get_preferred_edit_position();
-       end = playhead_cursor->current_frame;
+
+       set_mouse_mode (MouseRange);
+       selection->set (0, start, end);
+}
+
+bool
+Editor::get_edit_op_range (nframes64_t& start, nframes64_t& end) const
+{
+       nframes64_t m;
+       bool ignored;
+
+       /* in range mode, use any existing selection */
+
+       if (mouse_mode == MouseRange && !selection->time.empty()) {
+               /* we know that these are ordered */
+               start = selection->time.start();
+               end = selection->time.end_frame();
+               return true;
+       }
+
+       if (!mouse_frame (m, ignored)) {
+               /* mouse is not in a canvas, try playhead+selected marker.
+                  this is probably most true when using menus.
+                */
+
+               if (selection->markers.empty()) {
+                       return false;
+               }
+
+               start = selection->markers.front()->position();
+               end = session->audible_frame();
+
+       } else {
+
+               switch (_edit_point) {
+               case EditAtPlayhead:
+                       /* use mouse + playhead */
+                       start = m;
+                       end = session->audible_frame();
+                       break;
+                       
+               case EditAtMouse:
+               case EditAtSelectedMarker:
+                       /* use mouse + selected marker */
+                       if (selection->markers.empty()) {
+                               return false;
+                       }
+                       start = selection->markers.front()->position();
+                       end = m;
+                       break;
+               }
+       }
 
        if (start == end) {
-               return;
+               return false;
        }
 
        if (start > end) {
                swap (start, end);
        }
 
-       end -= 1;
-
-       set_mouse_mode (MouseRange);
-       selection->set (0, start, end);
+       return true;
 }