merged with trunk revs 2605-2627
authorPaul Davis <paul@linuxaudiosystems.com>
Mon, 12 Nov 2007 22:23:01 +0000 (22:23 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Mon, 12 Nov 2007 22:23:01 +0000 (22:23 +0000)
git-svn-id: svn://localhost/ardour2/trunk@2628 d708f5d6-7413-0410-9779-e7cbd77b26cf

41 files changed:
SConstruct
gtk2_ardour/SConscript
gtk2_ardour/actions.cc
gtk2_ardour/actions.h
gtk2_ardour/ardour-sae.menus
gtk2_ardour/ardour.bindings.in
gtk2_ardour/ardour.menus
gtk2_ardour/ardour2_ui_dark.rc.in
gtk2_ardour/ardour2_ui_default.conf
gtk2_ardour/ardour2_ui_light.rc.in
gtk2_ardour/ardour_ui.cc
gtk2_ardour/audio_region_view.cc
gtk2_ardour/canvas_vars.h
gtk2_ardour/editing_syms.h
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_actions.cc
gtk2_ardour/editor_audio_import.cc
gtk2_ardour/editor_canvas.cc
gtk2_ardour/editor_canvas_events.cc
gtk2_ardour/editor_items.h
gtk2_ardour/editor_keyboard.cc
gtk2_ardour/editor_keys.cc
gtk2_ardour/editor_markers.cc
gtk2_ardour/editor_mixer.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_rulers.cc
gtk2_ardour/editor_selection.cc
gtk2_ardour/location_ui.cc
gtk2_ardour/marker.cc
gtk2_ardour/marker.h
gtk2_ardour/public_editor.h
gtk2_ardour/selection.cc
gtk2_ardour/sfdb_ui.cc
libs/ardour/ardour/location.h
libs/ardour/audioengine.cc
libs/ardour/audioregion.cc
libs/ardour/io.cc
libs/ardour/location.cc
libs/ardour/session.cc

index 25cd2172228bed7949f826298c3505eb4c1727cb..67af088d7fd68ce8f5ead297eac67726b607a025 100644 (file)
@@ -473,6 +473,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 f1309b8c00313e53cfc0d004c403a0d68c12c047..4cf990f816d6fdb3caba168bda1a074690b9ed65 100644 (file)
@@ -50,6 +50,7 @@ gtkardour.Merge ([
     libraries['xml'],
     libraries['xslt'],
     libraries['soundtouch'],
+    libraries['rubberband'],
     libraries['samplerate'],
     libraries['jack'],
     libraries['sysaudio']
index f7609d2712465cb79208562f4c23ddbbbb4b9ad8..023520c17e9c4ec3e3efc434985fce947d55a3ef 100644 (file)
@@ -57,7 +57,7 @@ vector<RefPtr<Gtk::Action> > ActionManager::range_sensitive_actions;
 vector<RefPtr<Gtk::Action> > ActionManager::jack_sensitive_actions;
 vector<RefPtr<Gtk::Action> > ActionManager::jack_opposite_sensitive_actions;
 vector<RefPtr<Gtk::Action> > ActionManager::transport_sensitive_actions;
-vector<RefPtr<Gtk::Action> > ActionManager::edit_cursor_in_region_sensitive_actions;
+vector<RefPtr<Gtk::Action> > ActionManager::edit_point_in_region_sensitive_actions;
 
 RefPtr<UIManager> ActionManager::ui_manager;
 string ActionManager::unbound_string = "--";
index bdad02611002738e4e1cdaf91511d43963e3acf1..66e3ad9eea7530742012d1e0f7685dafd4714207 100644 (file)
@@ -56,7 +56,7 @@ class ActionManager
        static std::vector<Glib::RefPtr<Gtk::Action> > transport_sensitive_actions;
        static std::vector<Glib::RefPtr<Gtk::Action> > jack_sensitive_actions;
        static std::vector<Glib::RefPtr<Gtk::Action> > jack_opposite_sensitive_actions;
-       static std::vector<Glib::RefPtr<Gtk::Action> > edit_cursor_in_region_sensitive_actions;
+       static std::vector<Glib::RefPtr<Gtk::Action> > edit_point_in_region_sensitive_actions;
 
        static void map_some_state (const char* group, const char* action, bool (ARDOUR::Configuration::*get)() const);
        static void toggle_config_state (const char* group, const char* action, bool (ARDOUR::Configuration::*set)(bool), bool (ARDOUR::Configuration::*get)(void) const);
index 511ce3aa0d2763e7cd4985937b3fff4902c99e87..e132329dbcd19fca7d834215bc7ab90970cd0826 100644 (file)
                <menuitem action='editor-delete'/>
                <menuitem action='editor-copy'/>
                <menuitem action='editor-paste'/>
-               <menuitem action='set-edit-cursor'/>
+               <menuitem action='set-edit-point'/>
               <menuitem action='remove-last-capture'/>
                <separator/>       
-               <menu action="EditSelectRangeOptions">
-                   <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-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'/>
                   <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'/>
+                  <menuitem action='align-regions-end-relative'/>
+                  <menuitem action='align-regions-sync'/>
+                  <menuitem action='align-regions-sync-relative'/>
+                   <separator/>       
+                  <menuitem action='set-fade-in-length'/>
+                  <menuitem action='set-fade-out-length'/>
+                   <separator/>       
+                  <menuitem action='trim-from-start'/>
+                  <menuitem action='trim-to-end'/>
+                  <menuitem action='trim-region-to-loop'/>
+                  <menuitem action='trim-region-to-punch'/>
        </menu>
         <menu name='View' action = 'View'>
                <menu name='ZoomFocus' action='ZoomFocus'>
                    <menuitem action='zoom-focus-center'/>
                    <menuitem action='zoom-focus-playhead'/>
                    <menuitem action='zoom-focus-edit'/>
+                   <menuitem action='zoom-focus-mouse'/>
                </menu>
               <menu name='SnapMode' action='SnapMode'>
                   <menuitem action='snap-normal'/>
index c7ead238bbbae4de4d3be508958634e04791241a..2e9b4af1e94f516fa9071a23cd36efd6b2ff9617 100644 (file)
@@ -91,7 +91,7 @@
 ; (gtk_accel_path "<Actions>/Editor/Layering" "")
 ; (gtk_accel_path "<Actions>/JACK/JACKLatency4096" "")
 (gtk_accel_path "<Actions>/Editor/scroll-tracks-up" "Page_Up")
-(gtk_accel_path "<Actions>/Editor/set-edit-cursor" "e")
+(gtk_accel_path "<Actions>/Editor/set-edit-point" "e")
 ; (gtk_accel_path "<Actions>/Editor/Smpte30drop" "")
 ; (gtk_accel_path "<Actions>/Zoom/zoom-focus-edit" "")
 (gtk_accel_path "<Actions>/Editor/playhead-to-previous-region-start" "comma")
 ; (gtk_accel_path "<Actions>/Editor/toggle-xfades-visible" "")
 (gtk_accel_path "<Actions>/Editor/extend-range-to-end-of-region" "rightanglebracket")
 (gtk_accel_path "<Actions>/Editor/scroll-backward" "leftarrow")
-(gtk_accel_path "<Actions>/Editor/start-range" "<Control>KP_Down")
+(gtk_accel_path "<Actions>/Editor/start-range" "F1")
 ; (gtk_accel_path "<Actions>/ShuttleActions/SetShuttleUnitsSemitones" "")
 ; (gtk_accel_path "<Actions>/JACK/JACKLatency128" "")
 ; (gtk_accel_path "<Actions>/Snap/snap-to-beat" "")
 ; (gtk_accel_path "<Actions>/Editor/PullupMinus4Minus1" "")
 (gtk_accel_path "<Actions>/Editor/select-all-after-edit-cursor" "<Shift><Control>e")
 ; (gtk_accel_path "<Actions>/RegionList/SortBySourceFileName" "")
-(gtk_accel_path "<Actions>/Editor/finish-range" "<Control>KP_Up")
+(gtk_accel_path "<Actions>/Editor/finish-range" "F2")
+(gtk_accel_path "<Actions>/Editor/select-range-between-cursors" "F3")
 (gtk_accel_path "<Actions>/Transport/Loop" "l")
 ; (gtk_accel_path "<Actions>/Editor/CrossfadesFull" "")
 (gtk_accel_path "<Actions>/Editor/finish-add-range" "<Shift><Control>KP_Up")
 ; (gtk_accel_path "<Actions>/Snap/snap-to-edit-cursor" "")
 (gtk_accel_path "<Actions>/Editor/temporal-zoom-in" "minus")
 ; (gtk_accel_path "<Actions>/JACK/Latency" "")
-(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-end" "F2")
+(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-end" "<Shift>F2")
 ; (gtk_accel_path "<Actions>/processormenu/rename" "")
 ; (gtk_accel_path "<Actions>/RegionList/rlShowAuto" "")
 (gtk_accel_path "<Actions>/Editor/select-all-before-playhead" "<Control>p")
 ; (gtk_accel_path "<Actions>/Editor/addExistingAudioFiles" "")
 ; (gtk_accel_path "<Actions>/Main/Session" "")
-(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-start" "F1")
+(gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-start" "<Shift>F1")
 ; (gtk_accel_path "<Actions>/Main/AudioFileFormat" "")
 ; (gtk_accel_path "<Actions>/Transport/Transport" "")
 (gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-timefx" "t")
 ; (gtk_accel_path "<Actions>/options/InputAutoConnectManual" "")
 ; (gtk_accel_path "<Actions>/options/MeterHoldLong" "")
 ; (gtk_accel_path "<Actions>/Snap/snap-to-seconds" "")
+(gtk_accel_path "<Actions>/Editor/set-fade-in-length" "slash")
+(gtk_accel_path "<Actions>/Editor/set-fade-out-length" "backslash")
+(gtk_accel_path "<Actions>/Editor/trim-from-start" "<Shift>braceleft")
+(gtk_accel_path "<Actions>/Editor/trim-to-end" "<Shift>braceright")
index 6f11572151df717767f7ac72a4312856cd160b47..54060c06aa57b41a6ba77e55cdee0a26f5e7c623 100644 (file)
                <menuitem action='editor-paste'/>
               <menuitem action='remove-last-capture'/>
                <separator/>       
-               <menu action="EditSelectRangeOptions">
-                   <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-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-range-start'/>
                   <menuitem action='edit-cursor-to-range-end'/>
               </menu>
+<<<<<<< .working
               <menu action='RegionEditOps'>
                    <menuitem action='crop'/>
                    <menuitem action='duplicate-region'/>
                   <menuitem action="nudge-next-forward"/>
                   <menuitem action="nudge-backward"/>
                   <menuitem action="nudge-next-backward"/>
+                   <separator/>       
+                  <menuitem action='align-regions-start'/>
+                  <menuitem action='align-regions-start-relative'/>
+                  <menuitem action='align-regions-end'/>
+                  <menuitem action='align-regions-end-relative'/>
+                  <menuitem action='align-regions-sync'/>
+                  <menuitem action='align-regions-sync-relative'/>
               </menu>
+=======
+>>>>>>> .merge-right.r2626
               <menu name='KeyMouse Actions' action='KeyMouse Actions'>
                        <menuitem action='audition-at-mouse'/>
                                <menuitem action='brush-at-mouse'/>
-                               <menuitem action='set-edit-cursor'/>
+                               <menuitem action='set-edit-point'/>
                                <menuitem action='mute-unmute-region'/>
                        <menuitem action='set-playhead'/>
                        <menuitem action='split-region'/>
                        <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'/>
+                  <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'/>
+                   <menuitem action='insert-region'/>
+                          <menuitem action='normalize-region'/>
+                   <separator/>       
+                  <menuitem action="nudge-forward"/>
+                  <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'/>
+                  <menuitem action='align-regions-end-relative'/>
+                  <menuitem action='align-regions-sync'/>
+                  <menuitem action='align-regions-sync-relative'/>
+                   <separator/>       
+                  <menuitem action='set-fade-in-length'/>
+                  <menuitem action='set-fade-out-length'/>
+                   <separator/>       
+                  <menuitem action='trim-from-start'/>
+                  <menuitem action='trim-to-end'/>
+                  <menuitem action='trim-region-to-loop'/>
+                  <menuitem action='trim-region-to-punch'/>
+       </menu>
         <menu name='View' action = 'View'>
                <menu name='ZoomFocus' action='ZoomFocus'>
                    <menuitem action='zoom-focus-left'/>
                    <menuitem action='zoom-focus-center'/>
                    <menuitem action='zoom-focus-playhead'/>
                    <menuitem action='zoom-focus-edit'/>
+                   <menuitem action='zoom-focus-mouse'/>
                </menu>
               <menu name='SnapMode' action='SnapMode'>
                   <menuitem action='snap-normal'/>
index 50650d7f34d35c4050f5569fc6d335d883b9f20c..b2b5edd2d5b62d7366c1bb0c2805b0432e7463bc 100644 (file)
@@ -1319,7 +1319,7 @@ widget "*AudioClockBBTUpperInfo" style:highest "tempo_meter_clock_display"
 widget "*AudioClockBBTLowerInfo" style:highest "tempo_meter_clock_display"
 widget "*SelectionStartClock" style:highest "default_clock_display"
 widget "*SelectionEndClock" style:highest "default_clock_display"
-widget "*EditCursorClock" style:highest "default_clock_display"
+widget "*EditPointClock" style:highest "default_clock_display"
 widget "*PreRollClock" style:highest "default_clock_display"
 widget "*PostRollClock" style:highest "default_clock_display"
 widget "*NudgeClock" style:highest "default_clock_display"
index 721d8c31167ea0759752624961fbed43f3f68e31..4f41d5b03b86d49b3ebfe820831f429d0627f160 100644 (file)
     <Option name="verbose canvas cursor" value="f4f214bc"/>
     <Option name="marker label" value="000000ff"/>
     <Option name="marker bar separator" value="aaaaaa77"/>
+       <Option name="meterbar" value="666672ff"/>
     <Option name="tempo bar" value="72727fff"/>
-    <Option name="meterbar" value="666672ff"/>
-    <Option name="markerbar" value="7f7f8cff"/>
-    <Option name="rangemarker bar" value="8c8c96ff"/>
-    <Option name="TransportMarkerBar" value="9898a3ff"/>
+       <Option name="rangemarker bar" value="7f7f8cff"/>
+    <Option name="TransportMarkerBar" value="8c8c96ff"/>
+       <Option name="markerbar" value="9898a3ff"/>
     <Option name="RangeDragBarRect" value="969696c6"/>
     <Option name="RangeDragRect" value="82c696c6"/>
     <Option name="TransportDragRect" value="969696c6"/>
@@ -81,7 +81,7 @@
     <Option name="FrameHandle" value="7c00ff96"/>
     <Option name="TrimHandleLocked" value="ea0f0f28"/>
     <Option name="TrimHandle" value="1900ff44"/>
-    <Option name="EditCursor" value="0000ffff"/>
+    <Option name="EditPoint" value="0000ffff"/>
     <Option name="PlayHead" value="ff0000ff"/>
     <Option name="MidiSelectRectOutline" value="5555ffff"/>
     <Option name="MidiSelectRectFill" value="8888ff88"/>
index b485ae14ce22a63b1e91e4157165fb2a71b02680..e5cf578620d4b3e27a6e5c295abbb18f80f842a7 100644 (file)
@@ -1323,7 +1323,7 @@ widget "*AudioClockBBTUpperInfo" style:highest "tempo_meter_clock_display"
 widget "*AudioClockBBTLowerInfo" style:highest "tempo_meter_clock_display"
 widget "*SelectionStartClock" style:highest "default_clock_display"
 widget "*SelectionEndClock" style:highest "default_clock_display"
-widget "*EditCursorClock" style:highest "default_clock_display"
+widget "*EditPointClock" style:highest "default_clock_display"
 widget "*PreRollClock" style:highest "default_clock_display"
 widget "*PostRollClock" style:highest "default_clock_display"
 widget "*NudgeClock" style:highest "default_clock_display"
index 29febd0cdf113aa611a17fe68e90ab3793aa029c..31df7282638930a796e7c27e09762fc0919e17c7 100644 (file)
@@ -1745,7 +1745,7 @@ void
 ARDOUR_UI::update_clocks ()
 {
        if (!editor || !editor->dragging_playhead()) {
-               Clock (session->audible_frame(), false, editor->edit_cursor_position(false)); /* EMIT_SIGNAL */
+               Clock (session->audible_frame(), false, editor->get_preferred_edit_position()); /* EMIT_SIGNAL */
        }
 }
 
@@ -2404,7 +2404,6 @@ ARDOUR_UI::load_session (const string & path, const string & snap_name, string*
                session->set_clean ();
        }
 
-       editor->edit_cursor_position (true);
        enable_screen_updates ();
        flush_pending ();
        retval = 0;
@@ -3009,13 +3008,13 @@ void
 ARDOUR_UI::update_transport_clocks (nframes_t pos)
 {
        if (Config->get_primary_clock_delta_edit_cursor()) {
-               primary_clock.set (pos, false, editor->edit_cursor_position(false), 'p');
+               primary_clock.set (pos, false, editor->get_preferred_edit_position(), 1);
        } else {
                primary_clock.set (pos, 0, true);
        }
 
        if (Config->get_secondary_clock_delta_edit_cursor()) {
-               secondary_clock.set (pos, false, editor->edit_cursor_position(false), 's');
+               secondary_clock.set (pos, false, editor->get_preferred_edit_position(), 2);
        } else {
                secondary_clock.set (pos);
        }
index 0ad6b8af5b7fcc972b20c3a05fa34abcb0bc32c9..5aa60cb639763d784d44706b260422a1fbebb186 100644 (file)
@@ -530,7 +530,7 @@ AudioRegionView::reset_fade_in_shape_width (nframes_t width)
        } else {
                handle_center = 3.0;
        }
-       
+
        fade_in_handle->property_x1() =  handle_center - 3.0;
        fade_in_handle->property_x2() =  handle_center + 3.0;
        
index a6a4e07c7f6f78410525c28d739741c189ea9f60..d3a4d185571d304fe121c993ac61fd6561ea388a 100644 (file)
@@ -78,7 +78,7 @@ CANVAS_VARIABLE(canvasvar_NameHighlightOutline, "NameHighlightOutline")
 CANVAS_VARIABLE(canvasvar_FrameHandle, "FrameHandle")
 CANVAS_VARIABLE(canvasvar_TrimHandleLocked, "TrimHandleLocked")
 CANVAS_VARIABLE(canvasvar_TrimHandle, "TrimHandle")
-CANVAS_VARIABLE(canvasvar_EditCursor, "EditCursor")
+CANVAS_VARIABLE(canvasvar_EditPoint, "EditPoint")
 CANVAS_VARIABLE(canvasvar_PlayHead, "PlayHead")
 CANVAS_VARIABLE(canvasvar_MidiSelectRectOutline, "MidiSelectRectOutline")
 CANVAS_VARIABLE(canvasvar_MidiSelectRectFill, "MidiSelectRectFill")
index 29fd1234a82b97c193f2bd35a9e18d236bc77a08..b48f97c8da15d31e75a89bb53659ef23e53be2fe 100644 (file)
@@ -33,7 +33,7 @@ SNAPTYPE(SnapToAThirdBeat)
 SNAPTYPE(SnapToBeat)
 SNAPTYPE(SnapToBar)
 SNAPTYPE(SnapToMark)
-SNAPTYPE(SnapToEditCursor)
+SNAPTYPE(SnapToEditPoint)
 SNAPTYPE(SnapToRegionStart)
 SNAPTYPE(SnapToRegionEnd)
 SNAPTYPE(SnapToRegionSync)
@@ -87,7 +87,7 @@ IMPORTMODE(ImportAsTapeTrack=3)
 
 // if this is changed, remember to update the string table in sfdb_ui.cc
 IMPORTPOSITION(ImportAtTimestamp=0)
-IMPORTPOSITION(ImportAtEditCursor=1)
+IMPORTPOSITION(ImportAtEditPoint=1)
 IMPORTPOSITION(ImportAtPlayhead=2)
 IMPORTPOSITION(ImportAtStart=3)
 
index bf05cc5485468033df76aae5c3472e89c40e5726..2876153d8f11e9d1c0ad1806707c18d9c5b60a4d 100644 (file)
@@ -125,7 +125,7 @@ static const gchar *_snap_type_strings[] = {
        N_("Beats"),
        N_("Bars"),
        N_("Marks"),
-       N_("Edit Cursor"),
+       N_("Edit Point"),
        N_("Region starts"),
        N_("Region ends"),
        N_("Region syncs"),
@@ -152,7 +152,7 @@ static const gchar *_zoom_focus_strings[] = {
        N_("Center"),
        N_("Playhead"),
        N_("Mouse"),
-       N_("Edit Cursor"),
+       N_("Marker"),
        0
 };
 
@@ -206,7 +206,7 @@ Editor::Editor ()
 
          /* tool bar related */
 
-         edit_cursor_clock (X_("editcursor"), false, X_("EditCursorClock"), true),
+         edit_point_clock (X_("editpoint"), false, X_("EditPointClock"), true),
          zoom_range_clock (X_("zoomrange"), false, X_("ZoomRangeClock"), true, true),
          
          toolbar_selection_clock_table (2,3),
@@ -238,6 +238,7 @@ Editor::Editor ()
        selection->TracksChanged.connect (mem_fun(*this, &Editor::track_selection_changed));
        selection->RegionsChanged.connect (mem_fun(*this, &Editor::region_selection_changed));
        selection->PointsChanged.connect (mem_fun(*this, &Editor::point_selection_changed));
+       selection->MarkersChanged.connect (mem_fun(*this, &Editor::marker_selection_changed));
 
        clicked_regionview = 0;
        clicked_axisview = 0;
@@ -249,7 +250,7 @@ Editor::Editor ()
        drag_info.item = 0;
        current_mixer_strip = 0;
        current_bbt_points = 0;
-
+       
        snap_type_strings =  I18N (_snap_type_strings);
        snap_mode_strings =  I18N (_snap_mode_strings);
        zoom_focus_strings = I18N (_zoom_focus_strings);
@@ -262,7 +263,7 @@ Editor::Editor ()
        set_snap_mode (snap_mode);
 
        _edit_point = EditAtMouse;
-       set_edit_point (_edit_point);
+       set_edit_point_preference (_edit_point);
 
        snap_threshold = 5.0;
        bbt_beat_subdivision = 4;
@@ -317,16 +318,17 @@ Editor::Editor ()
        current_stepping_trackview = 0;
        entered_track = 0;
        entered_regionview = 0;
+       entered_marker = 0;
        clear_entered_track = false;
        _new_regionviews_show_envelope = false;
        current_timestretch = 0;
        in_edit_group_row_change = false;
        last_canvas_frame = 0;
-       edit_cursor = 0;
        playhead_cursor = 0;
        button_release_can_deselect = true;
        canvas_idle_queued = false;
        _dragging_playhead = false;
+       _dragging_edit_point = false;
        _dragging_hscrollbar = false;
 
        scrubbing_direction = 0;
@@ -390,7 +392,7 @@ Editor::Editor ()
        setup_toolbar ();
        setup_midi_toolbar ();
 
-       edit_cursor_clock.ValueChanged.connect (mem_fun(*this, &Editor::edit_cursor_clock_changed));
+       edit_point_clock.ValueChanged.connect (mem_fun(*this, &Editor::edit_point_clock_changed));
        
        ArdourCanvas::Canvas* time_pad = manage(new ArdourCanvas::Canvas());
        ArdourCanvas::SimpleLine* pad_line_1 = manage(new ArdourCanvas::SimpleLine(*time_pad->root(),
@@ -874,7 +876,6 @@ Editor::tie_vertical_scrolling ()
        double y1 = vertical_adjustment.get_value();
 
        playhead_cursor->set_y_axis (y1);
-       edit_cursor->set_y_axis (y1);
        if (logo_item) {
                logo_item->property_y() = y1;
        }
@@ -910,13 +911,25 @@ Editor::instant_save ()
 }
 
 void
-Editor::edit_cursor_clock_changed()
+Editor::edit_point_clock_changed()
 {
-       if (edit_cursor->current_frame != edit_cursor_clock.current_time()) {
-               edit_cursor->set_position (edit_cursor_clock.current_time());
+       if (_dragging_edit_point) {
+               return;
+       }
+
+       if (selection->markers.empty()) {
+               return;
+       }
+
+       bool ignored;
+       Location* loc = find_location_from_marker (selection->markers.front(), ignored);
+
+       if (!loc) {
+               return;
        }
-}
 
+       loc->move_to (edit_point_clock.current_time());
+}
 
 void
 Editor::zoom_adjustment_changed ()
@@ -1167,7 +1180,7 @@ Editor::connect_to_session (Session *t)
 
        edit_groups_changed ();
 
-       edit_cursor_clock.set_session (session);
+       edit_point_clock.set_session (session);
        zoom_range_clock.set_session (session);
        _playlist_selector->set_session (session);
        nudge_clock.set_session (session);
@@ -1575,7 +1588,7 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items)
        MenuList& sync_point_items = sync_point_menu->items();
        sync_point_menu->set_name("ArdourContextMenu");
        
-       sync_point_items.push_back (MenuElem (_("Define"), mem_fun(*this, &Editor::set_region_sync_from_edit_cursor)));
+       sync_point_items.push_back (MenuElem (_("Define"), mem_fun(*this, &Editor::set_region_sync_from_edit_point)));
        sync_point_items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_region_sync)));
 
        items.push_back (MenuElem (_("Sync points"), *sync_point_menu));
@@ -1749,8 +1762,10 @@ Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items)
        MenuList& trim_items = trim_menu->items();
        trim_menu->set_name ("ArdourContextMenu");
        
-       trim_items.push_back (MenuElem (_("Start to edit cursor"), mem_fun(*this, &Editor::trim_region_from_edit_cursor)));
-       trim_items.push_back (MenuElem (_("Edit cursor to end"), mem_fun(*this, &Editor::trim_region_to_edit_cursor)));
+       trim_items.push_back (MenuElem (_("Start to edit point"), mem_fun(*this, &Editor::trim_region_from_edit_point)));
+       trim_items.push_back (MenuElem (_("Edit point to end"), mem_fun(*this, &Editor::trim_region_to_edit_point)));
+       trim_items.push_back (MenuElem (_("Trim To Loop"), mem_fun(*this, &Editor::trim_region_to_loop)));
+       trim_items.push_back (MenuElem (_("Trim To Punch"), mem_fun(*this, &Editor::trim_region_to_punch)));
                             
        items.push_back (MenuElem (_("Trim"), *trim_menu));
        items.push_back (MenuElem (_("Split"), (mem_fun(*this, &Editor::split_region))));
@@ -1847,7 +1862,7 @@ Editor::add_bus_or_audio_track_context_items (Menu_Helpers::MenuList& edit_items
        MenuList& play_items = play_menu->items();
        play_menu->set_name ("ArdourContextMenu");
        
-       play_items.push_back (MenuElem (_("Play from edit cursor"), mem_fun(*this, &Editor::play_from_edit_cursor)));
+       play_items.push_back (MenuElem (_("Play from edit point"), mem_fun(*this, &Editor::play_from_edit_point)));
        play_items.push_back (MenuElem (_("Play from start"), mem_fun(*this, &Editor::play_from_start)));
        add_item_with_sensitivity (play_items, MenuElem (_("Play region"), mem_fun(*this, &Editor::play_selected_region)), one_selected_region);
        
@@ -1879,14 +1894,15 @@ Editor::add_bus_or_audio_track_context_items (Menu_Helpers::MenuList& edit_items
                select_items.push_back (MenuElem (_("Set range to punch range"), mem_fun(*this, &Editor::set_selection_from_punch)));
        }
        
-       select_items.push_back (MenuElem (_("Select all after edit cursor"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), edit_cursor, true)));
-       select_items.push_back (MenuElem (_("Select all before edit cursor"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), edit_cursor, false)));
-       select_items.push_back (MenuElem (_("Select all after playhead"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, true)));
-       select_items.push_back (MenuElem (_("Select all before playhead"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, false)));
+       select_items.push_back (MenuElem (_("Select All After Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_using_edit), true)));
+       select_items.push_back (MenuElem (_("Select All Before Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_using_edit), false)));
+       select_items.push_back (MenuElem (_("Select All After Playhead"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, true)));
+       select_items.push_back (MenuElem (_("Select All Before Playhead"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, false)));
+       select_items.push_back (MenuElem (_("Select All Between Playhead & Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_between), false)));
+       select_items.push_back (MenuElem (_("Select All Within Playhead & Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_between), true)));
+       select_items.push_back (MenuElem (_("Select Range Between Playhead & Edit Point"), mem_fun(*this, &Editor::select_range_between)));
 
-       if (n_audio_tracks) {
-               select_items.push_back (MenuElem (_("Select all between cursors"), bind (mem_fun(*this, &Editor::select_all_selectables_between_cursors), playhead_cursor, edit_cursor)));
-       }
+       select_items.push_back (SeparatorElem());
 
        edit_items.push_back (MenuElem (_("Select"), *select_menu));
 
@@ -1895,6 +1911,10 @@ Editor::add_bus_or_audio_track_context_items (Menu_Helpers::MenuList& edit_items
        Menu *cutnpaste_menu = manage (new Menu);
        MenuList& cutnpaste_items = cutnpaste_menu->items();
        cutnpaste_menu->set_name ("ArdourContextMenu");
+       
+       cutnpaste_items.push_back (MenuElem (_("Cut"), mem_fun(*this, &Editor::cut)));
+       cutnpaste_items.push_back (MenuElem (_("Copy"), mem_fun(*this, &Editor::copy)));
+       cutnpaste_items.push_back (MenuElem (_("Paste"), bind (mem_fun(*this, &Editor::paste), 1.0f)));
 
        add_item_with_sensitivity (cutnpaste_items, MenuElem (_("Cut"), mem_fun(*this, &Editor::cut)), can_cut_copy ());
        
@@ -1913,8 +1933,9 @@ Editor::add_bus_or_audio_track_context_items (Menu_Helpers::MenuList& edit_items
                cutnpaste_items.push_back (MenuElem (_("Paste"), bind (mem_fun(*this, &Editor::paste), 1.0f)));
        }
 
+       edit_items.push_back (SeparatorElem());
        edit_items.push_back (MenuElem (_("Edit"), *cutnpaste_menu));
-               
+
        if (n_audio_tracks) {
 
                Menu *track_menu = manage (new Menu);
@@ -1932,9 +1953,6 @@ Editor::add_bus_or_audio_track_context_items (Menu_Helpers::MenuList& edit_items
                MenuList& nudge_items = nudge_menu->items();
                nudge_menu->set_name ("ArdourContextMenu");
 
-               str = selection->tracks.size() == 1 ? _("Nudge track forward") : _("Nude tracks forward");
-               nudge_items.push_back (MenuElem (str, (bind (mem_fun(*this, &Editor::nudge_selected_tracks), false, true))));
-
                str = selection->tracks.size() == 1 ? _("Nudge track after edit cursor forward") : _("Nudge tracks after edit cursor forward");
                
                nudge_items.push_back (MenuElem (str, (bind (mem_fun(*this, &Editor::nudge_selected_tracks), true, true))));
@@ -2000,7 +2018,7 @@ Editor::set_snap_mode (SnapMode mode)
        instant_save ();
 }
 void
-Editor::set_edit_point (EditPoint ep)
+Editor::set_edit_point_preference (EditPoint ep)
 {
        _edit_point = ep;
        string str = edit_point_strings[(int)ep];
@@ -2061,13 +2079,6 @@ Editor::set_state (const XMLNode& node)
                horizontal_adjustment.set_value (0);
        }
 
-       if (session && (prop = node.property ("edit-cursor"))) {
-               nframes_t pos = atol (prop->value().c_str());
-               edit_cursor->set_position (pos);
-       } else {
-               edit_cursor->set_position (0);
-       }
-
        if ((prop = node.property ("mixer-width"))) {
                editor_mixer_strip_width = Width (string_2_enum (prop->value(), editor_mixer_strip_width));
        }
@@ -2089,7 +2100,7 @@ Editor::set_state (const XMLNode& node)
        }
 
        if ((prop = node.property ("edit-point"))) {
-               set_edit_point ((EditPoint) string_2_enum (prop->value(), _edit_point));
+               set_edit_point_preference ((EditPoint) string_2_enum (prop->value(), _edit_point));
        }
 
        if ((prop = node.property ("mouse-mode"))) {
@@ -2247,8 +2258,6 @@ Editor::get_state ()
 
        snprintf (buf, sizeof (buf), "%" PRIu32, playhead_cursor->current_frame);
        node->add_property ("playhead", buf);
-       snprintf (buf, sizeof (buf), "%" PRIu32, edit_cursor->current_frame);
-       node->add_property ("edit-cursor", buf);
 
        node->add_property ("show-waveforms", _show_waveforms ? "yes" : "no");
        node->add_property ("show-waveforms-recording", _show_waveforms_recording ? "yes" : "no");
@@ -2411,7 +2420,7 @@ Editor::snap_to (nframes64_t& start, int32_t direction, bool for_mark)
                start = session->tempo_map().round_to_beat_subdivision (start, 3);
                break;
 
-       case SnapToEditCursor:
+       case SnapToEditPoint:
                start = get_preferred_edit_position ();
                break;
 
@@ -2674,7 +2683,7 @@ Editor::setup_toolbar ()
        ARDOUR_UI::instance()->tooltips().set_tip (zoom_out_full_button, _("Zoom to Session"));
 
        zoom_focus_selector.set_name ("ZoomFocusSelector");
-       Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Center", FUDGE, 0);
+       Gtkmm2ext::set_size_request_to_display_given_text (zoom_focus_selector, "Playhead", FUDGE, 0);
        set_popdown_strings (zoom_focus_selector, zoom_focus_strings);
        zoom_focus_selector.signal_changed().connect (mem_fun(*this, &Editor::zoom_focus_selection_done));
        ARDOUR_UI::instance()->tooltips().set_tip (zoom_focus_selector, _("Zoom focus"));
@@ -2684,8 +2693,6 @@ Editor::setup_toolbar ()
        zoom_box.pack_start (zoom_in_button, false, false);
        zoom_box.pack_start (zoom_out_full_button, false, false);
 
-       /* Edit Cursor / Snap */
-
        snap_box.set_spacing (1);
        snap_box.set_border_width (2);
 
@@ -2707,7 +2714,7 @@ Editor::setup_toolbar ()
        edit_point_selector.signal_changed().connect (mem_fun(*this, &Editor::edit_point_selection_done));
        ARDOUR_UI::instance()->tooltips().set_tip (edit_point_selector, _("Edit point"));
 
-       snap_box.pack_start (edit_cursor_clock, false, false);
+       snap_box.pack_start (edit_point_clock, false, false);
        snap_box.pack_start (snap_mode_selector, false, false);
        snap_box.pack_start (snap_type_selector, false, false);
        snap_box.pack_start (edit_point_selector, false, false);
@@ -3194,8 +3201,8 @@ Editor::snap_type_selection_done ()
                snaptype = SnapToBar;
        } else if (choice == _("Marks")) {
                snaptype = SnapToMark;
-       } else if (choice == _("Edit Cursor")) {
-               snaptype = SnapToEditCursor;
+       } else if (choice == _("Edit Point")) {
+               snaptype = SnapToEditPoint;
        } else if (choice == _("Region starts")) {
                snaptype = SnapToRegionStart;
        } else if (choice == _("Region ends")) {
@@ -3282,6 +3289,8 @@ Editor::zoom_focus_selection_done ()
                focus_type = ZoomFocusPlayhead;
        } else if (choice == _("Edit")) {
                focus_type = ZoomFocusEdit;
+       } else if (choice == _("Edit Point")) {
+               focus_type = ZoomFocusEdit;
        } else {
                focus_type = ZoomFocusMouse;
        } 
@@ -3978,7 +3987,6 @@ Editor::set_frames_per_unit (double fpu)
        reset_hscrollbar_stepping ();
        reset_scrolling_region ();
        
-       if (edit_cursor) edit_cursor->set_position (edit_cursor->current_frame);
        if (playhead_cursor) playhead_cursor->set_position (playhead_cursor->current_frame);
 
        instant_save ();
@@ -4055,44 +4063,39 @@ Editor::sort_track_selection ()
        selection->tracks.sort (cmp);
 }
 
-nframes_t
-Editor::edit_cursor_position(bool sync)
-{
-       if (sync && edit_cursor->current_frame != edit_cursor_clock.current_time()) {
-               edit_cursor_clock.set(edit_cursor->current_frame, true);
-       }
-
-       return edit_cursor->current_frame;
-}
-
 nframes64_t
-Editor::get_preferred_edit_position() const
+Editor::get_preferred_edit_position()
 {
        bool ignored;
-       nframes64_t where;
+       nframes64_t where = 0;
 
        switch (_edit_point) {
        case EditAtPlayhead:
-               return playhead_cursor->current_frame;
+               where = session->audible_frame();
+               break;
                
        case EditAtSelectedMarker:
                if (!selection->markers.empty()) {
                        bool whocares;
                        Location* loc = find_location_from_marker (selection->markers.front(), whocares);
                        if (loc) {
-                               return loc->start();
+                               where =  loc->start();
+                               break;
                        }
                } 
                /* fallthru */
                
        default:
        case EditAtMouse:
-               if (mouse_frame (where, ignored)) {
-                       return where;
-               } 
+               if (!mouse_frame (where, ignored)) {
+                       /* XXX not right but what can we do ? */
+                       return 0;
+               }
+               snap_to (where);
+               break;
        }
 
-       return -1;
+       return where;
 }
 
 void
@@ -4151,3 +4154,55 @@ Editor::set_punch_range (nframes_t start, nframes_t end, string cmd)
        commit_reversible_command ();
 }
 
+RegionSelection
+Editor::get_regions_at (nframes64_t where, const TrackSelection& ts) const
+{
+       RegionSelection rs;
+       const TrackSelection* tracks;
+
+       if (ts.empty()) {
+               tracks = &track_views;
+       } else {
+               tracks = &ts;
+       }
+
+       for (TrackSelection::const_iterator t = tracks->begin(); t != tracks->end(); ++t) {
+       
+               AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*>(*t);
+
+               if (atv) {
+                       boost::shared_ptr<Diskstream> ds;
+                       boost::shared_ptr<Playlist> pl;
+                       
+                       if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
+
+                               Playlist::RegionList* regions = pl->regions_at ((nframes_t) floor ( (double)where * ds->speed()));
+
+                               for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
+
+                                       RegionView* rv = atv->audio_view()->find_view (*i);
+
+                                       if (rv) {
+                                               rs.push_back (rv);
+                                       }
+                               }
+
+                               delete regions;
+                       }
+               }
+       }
+
+       return rs;
+}
+
+RegionSelection&
+Editor::get_regions_for_action ()
+{
+       if (!selection->regions.empty()) {
+               return selection->regions;
+       } 
+
+       nframes64_t where = get_preferred_edit_position();
+       tmp_regions = get_regions_at (where, selection->tracks);
+       return tmp_regions;
+}
index 9f68929bfbdeba5c10408cd5d4218b1048094fda..2acf76fc6cc58f0e2a896ee0f5f8042b35777e79 100644 (file)
@@ -354,8 +354,7 @@ class Editor : public PublicEditor
        void reset_zoom (double);
        void reposition_and_zoom (nframes_t, double);
 
-       nframes_t edit_cursor_position(bool);
-       nframes64_t get_preferred_edit_position () const;
+       nframes64_t get_preferred_edit_position ();
 
        bool update_mouse_speed ();
        bool decelerate_mouse_speed ();
@@ -417,7 +416,10 @@ class Editor : public PublicEditor
        struct LocationMarkers {
            Marker* start;
            Marker* end;
+           bool    valid;
 
+           LocationMarkers () : start(0), end(0), valid (true) {}
+           
            ~LocationMarkers ();
 
            void hide();
@@ -429,6 +431,7 @@ class Editor : public PublicEditor
 
        LocationMarkers  *find_location_markers (ARDOUR::Location *) const;
        ARDOUR::Location* find_location_from_marker (Marker *, bool& is_start) const;
+       Marker* entered_marker;
 
        typedef std::map<ARDOUR::Location*,LocationMarkers *> LocationMarkerMap;
        LocationMarkerMap location_markers;
@@ -687,7 +690,6 @@ class Editor : public PublicEditor
                              */
 
        Cursor* playhead_cursor;
-       Cursor* edit_cursor;
        ArdourCanvas::Group* cursor_group;
 
        void    cursor_to_next_region_point (Cursor*, ARDOUR::RegionPoint);
@@ -695,8 +697,17 @@ class Editor : public PublicEditor
        void    cursor_to_region_point (Cursor*, ARDOUR::RegionPoint, int32_t dir);
        void    cursor_to_selection_start (Cursor *);
        void    cursor_to_selection_end   (Cursor *);
+
+       void    edit_point_to_next_region_point (ARDOUR::RegionPoint);
+       void    edit_point_to_previous_region_point (ARDOUR::RegionPoint);
+       void    edit_point_to_region_point (ARDOUR::RegionPoint, int32_t dir);
+       void    edit_point_to_selection_start ();
+       void    edit_point_to_selection_end   ();
+
        void    select_all_selectables_using_cursor (Cursor *, bool);
-       void    select_all_selectables_between_cursors (Cursor *, Cursor *);
+       void    select_all_selectables_using_edit (bool);
+       void    select_all_selectables_between (bool within);
+       void    select_range_between ();
 
        boost::shared_ptr<ARDOUR::Region> find_next_region (nframes_t, ARDOUR::RegionPoint, int32_t dir, TrackViewList&, TimeAxisView ** = 0);
 
@@ -955,11 +966,12 @@ 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_cursor ();
+       void set_region_sync_from_edit_point ();
        void remove_region_sync();
-       void align_selection (ARDOUR::RegionPoint, nframes_t position);
-       void align_selection_relative (ARDOUR::RegionPoint point, nframes_t position);
+       void align_selection (ARDOUR::RegionPoint, nframes_t position, const RegionSelection&);
+       void align_selection_relative (ARDOUR::RegionPoint point, nframes_t position, const RegionSelection&);
        void align_region (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes_t position);
        void align_region_internal (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes_t position);
        void remove_selected_regions ();
@@ -988,6 +1000,8 @@ class Editor : public PublicEditor
 
        void reset_focus ();
 
+       void split ();
+
        void cut ();
        void copy ();
        void paste (float times);
@@ -1007,7 +1021,7 @@ class Editor : public PublicEditor
        void rename_region_finished (bool);
 
        void play_from_start ();
-       void play_from_edit_cursor ();
+       void play_from_edit_point ();
        void play_selected_region ();
        void audition_selected_region ();
        void loop_selected_region ();
@@ -1088,7 +1102,7 @@ class Editor : public PublicEditor
        void move_to_end ();
        void goto_frame ();
        void center_playhead ();
-       void center_edit_cursor ();
+       void center_edit_point ();
        void edit_cursor_backward ();
        void edit_cursor_forward ();
        void playhead_backward ();
@@ -1180,6 +1194,8 @@ class Editor : public PublicEditor
 
        void set_fade_in_shape (ARDOUR::AudioRegion::FadeShape);
        void set_fade_out_shape (ARDOUR::AudioRegion::FadeShape);
+       
+       void set_fade_length (bool in);
 
        void set_fade_in_active (bool);
        void set_fade_out_active (bool);
@@ -1191,6 +1207,7 @@ class Editor : public PublicEditor
        void create_region_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
 
        bool _dragging_playhead;
+       bool _dragging_edit_point;
 
        void cursor_drag_motion_callback (ArdourCanvas::Item*, GdkEvent*);
        void cursor_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
@@ -1275,7 +1292,6 @@ class Editor : public PublicEditor
        /* non-public event handlers */
 
        bool canvas_playhead_cursor_event (GdkEvent* event, ArdourCanvas::Item*);
-       bool canvas_edit_cursor_event (GdkEvent* event, ArdourCanvas::Item*);
        bool track_canvas_scroll (GdkEventScroll* event);
 
        bool track_canvas_scroll_event (GdkEventScroll* event);
@@ -1288,24 +1304,15 @@ class Editor : public PublicEditor
        void track_canvas_allocate (Gtk::Allocation alloc);
        bool track_canvas_size_allocated ();
 
-       void set_edit_cursor (GdkEvent* event);
-       void set_playhead_cursor (GdkEvent* event);
+       void set_playhead_cursor ();
 
        void kbd_driver (sigc::slot<void,GdkEvent*>, bool use_track_canvas = true, bool use_time_canvas = true, bool can_select = true);
-       void kbd_set_playhead_cursor ();
-       void kbd_set_edit_cursor ();
        void kbd_mute_unmute_region ();
-       void kbd_split ();
        void kbd_set_sync_position ();
-       void kbd_align (ARDOUR::RegionPoint);
-       void kbd_align_relative (ARDOUR::RegionPoint);
        void kbd_brush ();
        void kbd_audition ();
 
-       void kbd_do_split (GdkEvent*);
        void kbd_do_set_sync_position (GdkEvent* ev);
-       void kbd_do_align (GdkEvent*, ARDOUR::RegionPoint);
-       void kbd_do_align_relative (GdkEvent*, ARDOUR::RegionPoint);
        void kbd_do_brush (GdkEvent*);
        void kbd_do_audition (GdkEvent*);
 
@@ -1355,6 +1362,7 @@ class Editor : public PublicEditor
        void marker_menu_edit ();
        void marker_menu_remove ();
        void marker_menu_rename ();
+       void marker_menu_lock (bool yn);
        void marker_menu_hide ();
        void marker_menu_loop_range ();
        void marker_menu_select_all_selectables_using_range ();
@@ -1418,7 +1426,7 @@ class Editor : public PublicEditor
        void editor_mixer_button_toggled ();
        void editor_list_button_toggled ();
 
-       AudioClock               edit_cursor_clock;
+       AudioClock               edit_point_clock;
        AudioClock               zoom_range_clock;
        Gtk::Button              zoom_in_button;
        Gtk::Button              zoom_out_button;
@@ -1483,7 +1491,7 @@ class Editor : public PublicEditor
 
        void                zoom_adjustment_changed();
 
-       void                edit_cursor_clock_changed();
+       void                edit_point_clock_changed();
        
        void setup_toolbar ();
 
@@ -1519,6 +1527,7 @@ class Editor : public PublicEditor
        void track_selection_changed ();
        void region_selection_changed ();
        void point_selection_changed ();
+       void marker_selection_changed ();
 
        enum SelectionOp {
                CreateSelection,
@@ -1713,8 +1722,11 @@ class Editor : public PublicEditor
        void trim_finished_callback (ArdourCanvas::Item*, GdkEvent*);
        void thaw_region_after_trim (RegionView& rv);
        
-       void trim_region_to_edit_cursor ();
-       void trim_region_from_edit_cursor ();
+       void trim_region_to_edit_point ();
+       void trim_region_from_edit_point ();
+       void trim_region_to_loop ();
+       void trim_region_to_punch ();
+       void trim_region_to_location (const ARDOUR::Location&, const char* cmd);
 
        bool show_gain_after_trim;
 
@@ -2005,11 +2017,24 @@ class Editor : public PublicEditor
 
        Gtk::ComboBoxText edit_point_selector;
 
-       void set_edit_point (Editing::EditPoint ep);
+       void set_edit_point_preference (Editing::EditPoint ep);
+       void set_edit_point ();
        void edit_point_selection_done ();
        void edit_point_chosen (Editing::EditPoint);
        Glib::RefPtr<Gtk::RadioAction> edit_point_action (Editing::EditPoint);
        std::vector<std::string> edit_point_strings;
+
+       void selected_marker_moved (ARDOUR::Location*);
+       sigc::connection edit_point_clock_connection_a;
+       sigc::connection edit_point_clock_connection_b;
+
+       bool get_edit_op_range (nframes64_t& start, nframes64_t& end) const;
+
+       RegionSelection get_regions_at (nframes64_t where, const TrackSelection& ts) const;
+       
+       RegionSelection tmp_regions;
+       
+       RegionSelection& get_regions_for_action ();
 };
 
 #endif /* __ardour_editor_h__ */
index b68f4bf2b79040d35048d91e5c9fece3f1843dbd..5a0542f5d160aa2db45b547d1d5600af047fb6f5 100644 (file)
@@ -45,9 +45,10 @@ Editor::register_actions ()
        /* non-operative menu items for menu bar */
 
        ActionManager::register_action (editor_actions, X_("Edit"), _("Edit"));
-       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 edit cursor"));
+       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"));
        ActionManager::register_action (editor_actions, X_("RegionEditOps"), _("Region operations"));
        ActionManager::register_action (editor_actions, X_("Tools"), _("Tools"));
        ActionManager::register_action (editor_actions, X_("View"), _("View"));
@@ -99,42 +100,47 @@ Editor::register_actions ()
        act = ActionManager::register_action (editor_actions, "playhead-to-previous-region-sync", _("Playhead to Previous Region Sync"), bind (mem_fun(*this, &Editor::cursor_to_previous_region_point), playhead_cursor, RegionPoint (SyncPoint)));
        ActionManager::session_sensitive_actions.push_back (act);
 
-       act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-start", _("Edit Cursor to Next Region Start"), bind (mem_fun(*this, &Editor::cursor_to_next_region_point), edit_cursor, RegionPoint (Start)));
+       act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-start", _("Edit Cursor to Next Region Start"), bind (mem_fun(*this, &Editor::edit_point_to_next_region_point), RegionPoint (Start)));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-end", _("Edit Cursor to Next Region End"), bind (mem_fun(*this, &Editor::cursor_to_next_region_point), edit_cursor, RegionPoint (End)));
+       act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-end", _("Edit Cursor to Next Region End"), bind (mem_fun(*this, &Editor::edit_point_to_next_region_point), RegionPoint (End)));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-sync", _("Edit Cursor to Next Region Sync"), bind (mem_fun(*this, &Editor::cursor_to_next_region_point), edit_cursor, RegionPoint (SyncPoint)));
+       act = ActionManager::register_action (editor_actions, "edit-cursor-to-next-region-sync", _("Edit Cursor to Next Region Sync"), bind (mem_fun(*this, &Editor::edit_point_to_next_region_point), RegionPoint (SyncPoint)));
        ActionManager::session_sensitive_actions.push_back (act);
 
-       act = ActionManager::register_action (editor_actions, "edit-cursor-to-previous-region-start", _("Edit Cursor to Previous Region Start"), bind (mem_fun(*this, &Editor::cursor_to_previous_region_point), edit_cursor, RegionPoint (Start)));
+       act = ActionManager::register_action (editor_actions, "edit-cursor-to-previous-region-start", _("Edit Cursor to Previous Region Start"), bind (mem_fun(*this, &Editor::edit_point_to_previous_region_point), RegionPoint (Start)));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "edit-cursor-to-previous-region-end", _("Edit Cursor to Previous Region End"), bind (mem_fun(*this, &Editor::cursor_to_previous_region_point), edit_cursor, RegionPoint (End)));
+       act = ActionManager::register_action (editor_actions, "edit-cursor-to-previous-region-end", _("Edit Cursor to Previous Region End"), bind (mem_fun(*this, &Editor::edit_point_to_previous_region_point), RegionPoint (End)));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "edit-cursor-to-previous-region-sync", _("Edit Cursor to Previous Region Sync"), bind (mem_fun(*this, &Editor::cursor_to_previous_region_point), edit_cursor, RegionPoint (SyncPoint)));
+       act = ActionManager::register_action (editor_actions, "edit-cursor-to-previous-region-sync", _("Edit Cursor to Previous Region Sync"), bind (mem_fun(*this, &Editor::edit_point_to_previous_region_point), RegionPoint (SyncPoint)));
        ActionManager::session_sensitive_actions.push_back (act);
 
-       act = ActionManager::register_action (editor_actions, "playhead-to-range-start", _("Playhead to Range Start"), bind (mem_fun(*this, &Editor::cursor_to_selection_start), playhead_cursor));
+        act = ActionManager::register_action (editor_actions, "edit-cursor-to-range-start", _("Edit Cursor to Range Start"), mem_fun(*this, &Editor::edit_point_to_selection_start));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "playhead-to-range-end", _("Playhead to Range End"), bind (mem_fun(*this, &Editor::cursor_to_selection_end), playhead_cursor));
+       act = ActionManager::register_action (editor_actions, "edit-cursor-to-range-end", _("Edit Cursor to Range End"), mem_fun(*this, &Editor::edit_point_to_selection_end));
        ActionManager::session_sensitive_actions.push_back (act);
 
-       act = ActionManager::register_action (editor_actions, "edit-cursor-to-range-start", _("Edit Cursor to Range Start"), bind (mem_fun(*this, &Editor::cursor_to_selection_start), edit_cursor));
+       act = ActionManager::register_action (editor_actions, "playhead-to-range-start", _("Playhead to Range Start"), bind (mem_fun(*this, &Editor::cursor_to_selection_start), playhead_cursor));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "edit-cursor-to-range-end", _("Edit Cursor to Range End"), bind (mem_fun(*this, &Editor::cursor_to_selection_end), edit_cursor));
+       act = ActionManager::register_action (editor_actions, "playhead-to-range-end", _("Playhead to Range End"), bind (mem_fun(*this, &Editor::cursor_to_selection_end), playhead_cursor));
        ActionManager::session_sensitive_actions.push_back (act);
 
        act = ActionManager::register_action (editor_actions, "select-all", _("Select All"), bind (mem_fun(*this, &Editor::select_all), Selection::Set));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "select-all-after-edit-cursor", _("Select All After Edit Cursor"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), edit_cursor, true));
+       act = ActionManager::register_action (editor_actions, "select-all-after-edit-cursor", _("Select All After Edit Cursor"), bind (mem_fun(*this, &Editor::select_all_selectables_using_edit), true));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "select-all-before-edit-cursor", _("Select All Before Edit Cursor"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), edit_cursor, false));
+       act = ActionManager::register_action (editor_actions, "select-all-before-edit-cursor", _("Select All Before Edit Cursor"), bind (mem_fun(*this, &Editor::select_all_selectables_using_edit), false));
        ActionManager::session_sensitive_actions.push_back (act);
 
        act = ActionManager::register_action (editor_actions, "select-all-after-playhead", _("Select All After Playhead"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, true));
        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_action (editor_actions, "select-all-before-playhead", _("Select All Before Playhead"), bind (mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, false));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "select-all-between-cursors", _("Select All Between Cursors"), bind (mem_fun(*this, &Editor::select_all_selectables_between_cursors), playhead_cursor, edit_cursor));
+       act = ActionManager::register_action (editor_actions, "select-all-between-cursors", _("Select All Between Playhead & Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_between), false));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "select-all-within-cursors", _("Select All Between Playhead & Edit Point"), bind (mem_fun(*this, &Editor::select_all_selectables_between), true));
+       ActionManager::session_sensitive_actions.push_back (act);
+
+       act = ActionManager::register_action (editor_actions, "select-range-between-cursors", _("Select Range Between Playhead & Edit Point"), mem_fun(*this, &Editor::select_range_between));
        ActionManager::session_sensitive_actions.push_back (act);
 
                act = ActionManager::register_action (editor_actions, "select-all-in-punch-range", _("Select All in Punch Range"), mem_fun(*this, &Editor::select_all_selectables_using_punch));
@@ -182,7 +188,7 @@ Editor::register_actions ()
        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_action (editor_actions, "center-playhead", _("Center Playhead"), mem_fun(*this, &Editor::center_playhead));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "center-edit-cursor", _("Center Edit Cursor"), mem_fun(*this, &Editor::center_edit_cursor));
+       act = ActionManager::register_action (editor_actions, "center-edit-cursor", _("Center Edit Point"), mem_fun(*this, &Editor::center_edit_point));
        ActionManager::session_sensitive_actions.push_back (act);
 
        act = ActionManager::register_action (editor_actions, "scroll-playhead-forward", _("Playhead forward"), bind (mem_fun(*this, &Editor::scroll_playhead), true));;
@@ -195,6 +201,21 @@ Editor::register_actions ()
        act = ActionManager::register_action (editor_actions, "edit-to-playhead", _("Edit to Playhead"), bind (mem_fun(*this, &Editor::cursor_align), false));
        ActionManager::session_sensitive_actions.push_back (act);
 
+
+       act = ActionManager::register_action (editor_actions, "trim-from-start", _("Start to edit point"), mem_fun(*this, &Editor::trim_region_from_edit_point));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "trim-to-end", _("Edit point to end"), mem_fun(*this, &Editor::trim_region_to_edit_point));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "trim-region-to-loop", _("Trim To Loop"), mem_fun(*this, &Editor::trim_region_to_loop));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "trim-region-to-punch", _("Trim To Punch"), mem_fun(*this, &Editor::trim_region_to_punch));
+       ActionManager::session_sensitive_actions.push_back (act);
+       
+       act = ActionManager::register_action (editor_actions, "set-fade-in-length", _("Set Fade In Length"), bind (mem_fun(*this, &Editor::set_fade_length), true));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "set-fade-out-length", _("Set Fade Out Length"), bind (mem_fun(*this, &Editor::set_fade_length), false));
+       ActionManager::session_sensitive_actions.push_back (act);
+
        act = ActionManager::register_action (editor_actions, "align-regions-start", _("Align Regions Start"), bind (mem_fun(*this, &Editor::align), ARDOUR::Start));
        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_action (editor_actions, "align-regions-start-relative", _("Align Regions Start Relative"), bind (mem_fun(*this, &Editor::align_relative), ARDOUR::Start));
@@ -213,17 +234,18 @@ Editor::register_actions ()
         ActionManager::session_sensitive_actions.push_back (act);
         act = ActionManager::register_action (editor_actions, "brush-at-mouse", _("Brush at Mouse"), mem_fun(*this, &Editor::kbd_brush));
         ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "set-edit-cursor", _("Set Edit Cursor"), mem_fun(*this, &Editor::kbd_set_edit_cursor));
-        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_action (editor_actions, "mute-unmute-region", _("Mute/Unmute Region"), mem_fun(*this, &Editor::kbd_mute_unmute_region));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "set-playhead", _("Set Playhead"), mem_fun(*this, &Editor::kbd_set_playhead_cursor));
-       ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "split-region", _("Split Region"), mem_fun(*this, &Editor::kbd_split));
-        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_action (editor_actions, "set-region-sync-position", _("Set Region Sync Position"), mem_fun(*this, &Editor::kbd_set_sync_position));
         ActionManager::session_sensitive_actions.push_back (act);
 
+       act = ActionManager::register_action (editor_actions, "set-playhead", _("Set Playhead"), mem_fun(*this, &Editor::set_playhead_cursor));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "set-edit-point", _("Set Edit Point"), mem_fun(*this, &Editor::set_edit_point));
+       ActionManager::session_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "split-region", _("Split Region"), mem_fun(*this, &Editor::split));
+        ActionManager::session_sensitive_actions.push_back (act);
+
        undo_action = act = ActionManager::register_action (editor_actions, "undo", _("Undo"), bind (mem_fun(*this, &Editor::undo), 1U));
        ActionManager::session_sensitive_actions.push_back (act);
        redo_action = act = ActionManager::register_action (editor_actions, "redo", _("Redo"), bind (mem_fun(*this, &Editor::redo), 1U));
@@ -260,8 +282,8 @@ Editor::register_actions ()
        act = ActionManager::register_action (editor_actions, "insert-chunk", _("Insert Chunk"), bind (mem_fun(*this, &Editor::paste_named_selection), 1.0f));
        ActionManager::session_sensitive_actions.push_back (act);
 
-       act = ActionManager::register_action (editor_actions, "split-at-edit-cursor", _("Split at edit cursor"), mem_fun(*this, &Editor::split_region));
-       ActionManager::edit_cursor_in_region_sensitive_actions.push_back (act);
+       act = ActionManager::register_action (editor_actions, "split-at-edit-cursor", _("Split At Edit Point"), mem_fun(*this, &Editor::split_region));
+       ActionManager::edit_point_in_region_sensitive_actions.push_back (act);
 
        act = ActionManager::register_action (editor_actions, "start-range", _("Start Range"), mem_fun(*this, &Editor::keyboard_selection_begin));
        ActionManager::session_sensitive_actions.push_back (act);
@@ -336,7 +358,7 @@ Editor::register_actions ()
        ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-beat"), _("Snap to beat"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToBeat)));
        ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-bar"), _("Snap to bar"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToBar)));
        ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-mark"), _("Snap to mark"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToMark)));
-       ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-edit-cursor"), _("Snap to edit cursor"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToEditCursor)));
+       ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-edit-cursor"), _("Snap to edit point"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToEditPoint)));
        ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-region-start"), _("Snap to region start"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToRegionStart)));
        ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-region-end"), _("Snap to region end"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToRegionEnd)));
        ActionManager::register_radio_action (snap_actions, snap_choice_group, X_("snap-to-region-sync"), _("Snap to region sync"), (bind (mem_fun(*this, &Editor::snap_type_chosen), Editing::SnapToRegionSync)));
@@ -744,7 +766,7 @@ Editor::snap_type_action (SnapType type)
        case Editing::SnapToMark:
                action = "snap-to-mark";
                break;
-       case Editing::SnapToEditCursor:
+       case Editing::SnapToEditPoint:
                action = "snap-to-edit-cursor";
                break;
        case Editing::SnapToRegionStart:
@@ -880,7 +902,7 @@ Editor::edit_point_chosen (EditPoint ep)
        RefPtr<RadioAction> ract = edit_point_action (ep);
 
        if (ract && ract->get_active()) {
-               set_edit_point (ep);
+               set_edit_point_preference (ep);
        }
 }
 
index b609918f09164615555a608289bcb404b36f5b00..193e98b58aa131a35129561f758f50a67cf30467 100644 (file)
@@ -143,7 +143,7 @@ Editor::external_audio_dialog ()
        nframes64_t where;
 
        switch (pos) {
-       case ImportAtEditCursor:
+       case ImportAtEditPoint:
                where = get_preferred_edit_position ();
                break;
        case ImportAtTimestamp:
@@ -157,10 +157,6 @@ Editor::external_audio_dialog ()
                break;
        }
 
-       if (where < 0) {
-               return;
-       }
-
        SrcQuality quality = sfbrowser->get_src_quality();
 
        if (sfbrowser->copy_files_btn.get_active()) {
@@ -594,7 +590,6 @@ Editor::add_sources (vector<Glib::ustring> paths, SourceList& sources, nframes64
                if (sources[0]->natural_position() != 0) {
                        pos = sources[0]->natural_position();
                } else {
-                       // XXX is this the best alternative ?
                        pos = get_preferred_edit_position ();
                }
        }
index d75384e253fbe3c06ac522001cfe8748df9226a8..40f6b05026822fa92621b6840dd2d941ca3b4111 100644 (file)
@@ -170,9 +170,9 @@ Editor::initialize_canvas ()
        
        meter_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, 0.0);
        tempo_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height);
-       marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 2.0);
-       range_marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 3.0);
-       transport_marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 4.0);
+       range_marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 2.0);
+       transport_marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 3.0);
+       marker_group = new ArdourCanvas::Group (*time_canvas.root(), 0.0, timebar_height * 4.0);
        
        tempo_bar = new ArdourCanvas::SimpleRect (*tempo_group, 0.0, 0.0, max_canvas_coordinate, timebar_height-1.0);
        tempo_bar->property_outline_what() = (0x1 | 0x8);
@@ -262,7 +262,6 @@ Editor::initialize_canvas ()
        double time_width = FLT_MAX/frames_per_unit;
        time_canvas.set_scroll_region(0.0, 0.0, time_width, time_height);
 
-       edit_cursor = new Cursor (*this, &Editor::canvas_edit_cursor_event);
        playhead_cursor = new Cursor (*this, &Editor::canvas_playhead_cursor_event);
 
        initial_ruler_update_required = true;
@@ -322,19 +321,14 @@ Editor::track_canvas_size_allocated ()
        }
 
        zoom_range_clock.set ((nframes_t) floor ((canvas_width * frames_per_unit)));
-       edit_cursor->set_position (edit_cursor->current_frame);
        playhead_cursor->set_position (playhead_cursor->current_frame);
 
        reset_hscrollbar_stepping ();
        reset_scrolling_region ();
 
-       if (edit_cursor) edit_cursor->set_length (canvas_height);
        if (playhead_cursor) playhead_cursor->set_length (canvas_height);
 
-       if (marker_drag_line) {
-               marker_drag_line_points.back().set_y(canvas_height);
-               marker_drag_line->property_points() = marker_drag_line_points;
-       }
+       // EDIT CURSOR XXX set line height for selected markers here
 
        if (range_marker_drag_rect) {
                range_marker_drag_rect->property_y1() = 0.0;
@@ -734,7 +728,6 @@ Editor::canvas_horizontally_scrolled ()
 void
 Editor::color_handler()
 {
-       edit_cursor->canvas_item.property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_EditCursor.get();
        playhead_cursor->canvas_item.property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_PlayHead.get();
        verbose_canvas_cursor->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_VerboseCanvasCursor.get();
        
index a22edea7e0b70dd6191b0272e2e7650cf4cf1c05..ef11f546ef252e19e736f5030b87e5e6540eaea9 100644 (file)
@@ -551,6 +551,8 @@ Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item,
                                        
                                        return canvas_region_view_event (event, rv->get_canvas_group(), rv);
                                } 
+
+                               delete rl;
                        }
                }
        }
@@ -833,12 +835,6 @@ Editor::canvas_playhead_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
        return typed_event (item, event, PlayheadCursorItem);
 }
 
-bool
-Editor::canvas_edit_cursor_event (GdkEvent *event, ArdourCanvas::Item* item)
-{
-       return typed_event (item, event, EditCursorItem);
-}
-
 bool
 Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item)
 {
index 722f458dfdda393debb004350747e3779ca327c6..aa68f37720769af3ff4a09361271c956d353ab4d 100644 (file)
@@ -24,7 +24,6 @@ enum ItemType {
        RegionItem,
        StreamItem,
        PlayheadCursorItem,
-       EditCursorItem,
        MarkerItem,
        MarkerBarItem,
        RangeMarkerBarItem,
index 28b86f53fc6493edbf6b25027f51273694f3ea7c..2912e2f4eeaf4de046737f3f4d78616e776ce801 100644 (file)
 
 #include <ardour/audioregion.h>
 #include <ardour/playlist.h>
+#include <ardour/location.h>
+
 #include <pbd/memento_command.h>
 
 #include "editor.h"
 #include "region_view.h"
 #include "selection.h"
+#include "keyboard.h"
 
 #include "i18n.h"
 
+using namespace ARDOUR;
+
 void
 Editor::kbd_driver (sigc::slot<void,GdkEvent*> theslot, bool use_track_canvas, bool use_time_canvas, bool can_select)
 {
@@ -70,48 +75,6 @@ Editor::kbd_driver (sigc::slot<void,GdkEvent*> theslot, bool use_track_canvas, b
        }
 }
 
-void
-Editor::kbd_set_playhead_cursor ()
-{
-       kbd_driver (mem_fun(*this, &Editor::set_playhead_cursor), true, true, false);
-}
-
-void
-Editor::kbd_set_edit_cursor ()
-{
-       kbd_driver (mem_fun(*this, &Editor::set_edit_cursor), true, true, false);
-}
-
-
-void
-Editor::kbd_do_split (GdkEvent* ev)
-{
-       nframes_t where = event_frame (ev);
-
-       if (entered_regionview) {
-               if (selection->regions.contains (entered_regionview)) {
-                       split_regions_at (where, selection->regions);
-               } else {
-                       RegionSelection s;
-
-                       /* add equivalent regions to the selection that we'll split */
-                       vector<RegionView*> eq;
-                       get_equivalent_regions (entered_regionview, eq);
-                       for (vector<RegionView*>::iterator i = eq.begin(); i != eq.end(); ++i) {
-                               s.add (*i);
-                       }
-                       
-                       split_regions_at (where, s);
-               }
-       }
-}
-
-void
-Editor::kbd_split ()
-{
-       kbd_driver (mem_fun(*this, &Editor::kbd_do_split), true, true, false);
-}
-
 void
 Editor::kbd_mute_unmute_region ()
 {
@@ -136,36 +99,18 @@ Editor::kbd_set_sync_position ()
 void
 Editor::kbd_do_set_sync_position (GdkEvent* ev)
 {
-    nframes_t where = event_frame (ev);
-       snap_to (where);
-
        if (entered_regionview) {
-         set_a_regions_sync_position (entered_regionview->region(), where);
-       }
-}
-
-void
-Editor::kbd_do_align (GdkEvent* ev, ARDOUR::RegionPoint what)
-{
-       align (what);
-}
+               nframes64_t where = event_frame (ev);
+               snap_to (where);
 
-void
-Editor::kbd_align (ARDOUR::RegionPoint what)
-{
-       kbd_driver (bind (mem_fun(*this, &Editor::kbd_do_align), what));
-}
+               set_a_regions_sync_position (entered_regionview->region(), where);
 
-void
-Editor::kbd_do_align_relative (GdkEvent* ev, ARDOUR::RegionPoint what)
-{
-       align (what);
-}
+       } else if (entered_marker) {
 
-void
-Editor::kbd_align_relative (ARDOUR::RegionPoint what)
-{
-       kbd_driver (bind (mem_fun(*this, &Editor::kbd_do_align), what), true, true, false);
+               if (!selection->regions.empty()) {
+                       set_a_regions_sync_position (selection->regions.front()->region(), entered_marker->position());
+               }
+       }
 }
 
 void
index b3081e8c8add34b17ca5d1720c45965c1db540b0..d06b9f85aad8c0e62546fc9e67878af69d352d39 100644 (file)
@@ -41,14 +41,27 @@ using namespace sigc;
 void
 Editor::keyboard_selection_finish (bool add)
 {
+       cerr << "here\n";
+
        if (session && have_pending_keyboard_selection) {
-               begin_reversible_command (_("keyboard selection"));
+
+               nframes64_t end;
+               bool ignored;
+
+               if (session->transport_rolling()) {
+                       end = session->audible_frame();
+               } else {
+                       if (!mouse_frame (end, ignored)) {
+                               return;
+                       }
+               }
+
                if (add) {
-                       selection->add (pending_keyboard_selection_start, session->audible_frame());
+                       selection->add (pending_keyboard_selection_start, end);
                } else {
-                       selection->set (0, pending_keyboard_selection_start, session->audible_frame());
+                       selection->set (0, pending_keyboard_selection_start, end);
                }
-               commit_reversible_command ();
+
                have_pending_keyboard_selection = false;
        }
 }
@@ -57,8 +70,19 @@ void
 Editor::keyboard_selection_begin ()
 {
        if (session) {
-               pending_keyboard_selection_start = session->audible_frame();
-               have_pending_keyboard_selection = true;
+               if (session->transport_rolling()) {
+                       pending_keyboard_selection_start = session->audible_frame();
+                       have_pending_keyboard_selection = true;
+               } else {
+                       bool ignored;
+                       nframes64_t where; // XXX fix me
+
+                       if (mouse_frame (where, ignored)) {
+                               pending_keyboard_selection_start = where;
+                               have_pending_keyboard_selection = true;
+                       }
+                               
+               }
        }
 }
 
index 50bf950054b2308cf5fe59f048c5e928801683f5..75776a7844c02513a1da1f9b353a63e326d70a82 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
@@ -299,6 +331,14 @@ Editor::mouse_add_new_marker (nframes_t where)
                 XMLNode &after = session->locations()->get_state();
                session->add_command (new MementoCommand<Locations>(*(session->locations()), &before, &after));
                session->commit_reversible_command ();
+
+               /* find the marker we just added */
+
+               LocationMarkers *lam = find_location_markers (location);
+               if (lam) {
+                       /* make it the selected marker */
+                       selection->set (lam->start);
+               }
        }
 }
 
@@ -464,17 +504,21 @@ Editor::build_marker_menu (bool start_or_end)
        MenuList& items = markerMenu->items();
        markerMenu->set_name ("ArdourContextMenu");
 
-       items.push_back (MenuElem (_("Locate to Mark"), mem_fun(*this, &Editor::marker_menu_set_playhead)));
-       items.push_back (MenuElem (_("Play from Mark"), mem_fun(*this, &Editor::marker_menu_play_from)));
-       items.push_back (MenuElem (_("Set Mark from Playhead"), mem_fun(*this, &Editor::marker_menu_set_from_playhead)));
+       items.push_back (MenuElem (_("Locate to here"), mem_fun(*this, &Editor::marker_menu_set_playhead)));
+       items.push_back (MenuElem (_("Play from here"), mem_fun(*this, &Editor::marker_menu_play_from)));
+       items.push_back (MenuElem (_("Move Mark to Playhead"), mem_fun(*this, &Editor::marker_menu_set_from_playhead)));
 
        items.push_back (SeparatorElem());
 
-       items.push_back (MenuElem (_("Hide Mark"), mem_fun(*this, &Editor::marker_menu_hide)));
+       items.push_back (MenuElem (_("Hide"), mem_fun(*this, &Editor::marker_menu_hide)));
        if (start_or_end) return;
-       items.push_back (MenuElem (_("Rename Mark"), mem_fun(*this, &Editor::marker_menu_rename)));
-       items.push_back (MenuElem (_("Remove Mark"), mem_fun(*this, &Editor::marker_menu_remove)));
+       items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::marker_menu_rename)));
+       items.push_back (MenuElem (_("Lock"), bind (mem_fun(*this, &Editor::marker_menu_lock), true)));
+       items.push_back (MenuElem (_("Unlock"), bind (mem_fun(*this, &Editor::marker_menu_lock), false)));
+
+       items.push_back (SeparatorElem());
 
+       items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::marker_menu_remove)));
 }
 
 void
@@ -837,6 +881,31 @@ Editor::marker_menu_remove ()
        }
 }
 
+void
+Editor::marker_menu_lock (bool yn)
+{
+
+       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 (yn) {
+               loc->lock();
+       } else {
+               loc->unlock ();
+       }
+}
+
 void
 Editor::marker_menu_rename ()
 {
@@ -994,3 +1063,48 @@ Editor::update_punch_range_view (bool visibility)
 //             gnome_canvas_item_hide (transport_punchout_line);
 //     }
 }
+
+void
+Editor::marker_selection_changed ()
+{
+       for (LocationMarkerMap::iterator i = location_markers.begin(); i != location_markers.end(); ++i) {
+               LocationMarkers* lam = i->second;
+
+               if (lam->start) {
+                       lam->start->hide_line();
+               } 
+
+               if (lam->end) {
+                       lam->end->hide_line();
+               }
+       }
+
+       edit_point_clock_connection_a.disconnect();
+       edit_point_clock_connection_b.disconnect();
+
+       if (selection->markers.empty()) {
+               edit_point_clock.set (0);
+               return;
+       }
+
+       for (MarkerSelection::iterator x = selection->markers.begin(); x != selection->markers.end(); ++x) {
+               (*x)->add_line (cursor_group, canvas_height);
+               (*x)->show_line ();
+       }
+
+       edit_point_clock.set (selection->markers.front()->position());
+
+       bool ignored;
+       Location* loc = find_location_from_marker (selection->markers.front(), ignored);
+
+       if (loc) {
+               edit_point_clock_connection_a = loc->changed.connect (mem_fun (*this, &Editor::selected_marker_moved));
+               edit_point_clock_connection_b = loc->start_changed.connect (mem_fun (*this, &Editor::selected_marker_moved));
+       }
+}
+
+void
+Editor::selected_marker_moved (Location* loc)
+{
+       edit_point_clock.set (loc->start());
+}
index 669297b6e49c8ae775e6a8f88ca48270dc78bede..7264df552d2c0ca4a39034f152cc2ebb26f7596e 100644 (file)
@@ -342,7 +342,10 @@ Editor::session_going_away ()
        named_selection_display.set_model (named_selection_model);
        edit_group_display.set_model (group_model);
 
-       edit_cursor_clock.set_session (0);
+       edit_point_clock_connection_a.disconnect();
+       edit_point_clock_connection_b.disconnect();
+
+       edit_point_clock.set_session (0);
        zoom_range_clock.set_session (0);
        nudge_clock.set_session (0);
 
index 7857082be32fca8b30fd07ecdd25d1d9d369ca63..4a03e96ae55355ed32f603d16b7a4937b3448b48 100644 (file)
@@ -581,7 +581,6 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
                        */
                        
                        switch (item_type) {
-                       case EditCursorItem:
                        case PlayheadCursorItem:
                                start_cursor_grab (item, event);
                                return true;
@@ -1072,7 +1071,6 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
 
                switch (item_type) {
                /* see comments in button_press_handler */
-               case EditCursorItem:
                case PlayheadCursorItem:
                case MarkerItem:
                case GainLineItem:
@@ -1270,7 +1268,6 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
                }
                break;
 
-       case EditCursorItem:
        case PlayheadCursorItem:
                if (is_drawable()) {
                        track_canvas.get_window()->set_cursor (*grabber_cursor);
@@ -1328,6 +1325,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
                if ((marker = static_cast<Marker *> (item->get_data ("marker"))) == 0) {
                        break;
                }
+               entered_marker = marker;
                marker->set_color_rgba (ARDOUR_UI::config()->canvasvar_EnteredMarker.get());
                // fall through
        case MeterMarkerItem:
@@ -1403,7 +1401,6 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
        case RegionViewNameHighlight:
        case StartSelectionTrimItem:
        case EndSelectionTrimItem:
-       case EditCursorItem:
        case PlayheadCursorItem:
 
 #ifdef WITH_CMT
@@ -1454,8 +1451,10 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_
                if ((marker = static_cast<Marker *> (item->get_data ("marker"))) == 0) {
                        break;
                }
-               loc = find_location_from_marker (marker, is_start);
-               if (loc) location_flags_changed (loc, this);
+               entered_marker = 0;
+               if ((loc = find_location_from_marker (marker, is_start)) != 0) {
+                       location_flags_changed (loc, this);
+               }
                // fall through
        case MeterMarkerItem:
        case TempoMarkerItem:
@@ -1598,8 +1597,8 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
                */
                if (!drag_info.move_threshold_passed) {
 
-                       bool x_threshold_passed =  (abs ((nframes64_t) (drag_info.current_pointer_x - drag_info.grab_x)) > 4LL);
-                       bool y_threshold_passed =  (abs ((nframes64_t) (drag_info.current_pointer_y - drag_info.grab_y)) > 4LL);
+                       bool x_threshold_passed =  (::llabs ((nframes64_t) (drag_info.current_pointer_x - drag_info.grab_x)) > 4LL);
+                       bool y_threshold_passed =  (::llabs ((nframes64_t) (drag_info.current_pointer_y - drag_info.grab_y)) > 4LL);
                        
                        drag_info.move_threshold_passed = (x_threshold_passed || y_threshold_passed);
                        
@@ -1617,7 +1616,6 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item
 
        switch (item_type) {
        case PlayheadCursorItem:
-       case EditCursorItem:
        case MarkerItem:
        case ControlPointItem:
        case TempoMarkerItem:
@@ -1803,35 +1801,6 @@ Editor::end_grab (ArdourCanvas::Item* item, GdkEvent* event)
        return did_drag;
 }
 
-void
-Editor::set_edit_cursor (GdkEvent* event)
-{
-       nframes_t pointer_frame = event_frame (event);
-
-       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               if (snap_type != SnapToEditCursor) {
-                       snap_to (pointer_frame);
-               }
-       }
-
-       edit_cursor->set_position (pointer_frame);
-       edit_cursor_clock.set (pointer_frame);
-}
-
-void
-Editor::set_playhead_cursor (GdkEvent* event)
-{
-       nframes_t pointer_frame = event_frame (event);
-
-       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               snap_to (pointer_frame);
-       }
-
-       if (session) {
-               session->request_locate (pointer_frame, session->transport_rolling());
-       }
-}
-
 void
 Editor::start_fade_in_grab (ArdourCanvas::Item* item, GdkEvent* event)
 {
@@ -2102,7 +2071,7 @@ Editor::cursor_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
        }
        
        if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               if (cursor != edit_cursor || snap_type != SnapToEditCursor) {
+               if (cursor == playhead_cursor && snap_type != SnapToEditPoint) {
                        snap_to (adjusted_frame);
                }
        }
@@ -2111,11 +2080,7 @@ Editor::cursor_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 
        cursor->set_position (adjusted_frame);
        
-       if (cursor == edit_cursor) {
-               edit_cursor_clock.set (cursor->current_frame);
-       } else {
-               UpdateAllTransportClocks (cursor->current_frame);
-       }
+       UpdateAllTransportClocks (cursor->current_frame);
 
        show_verbose_time_cursor (cursor->current_frame, 10);
 
@@ -2136,9 +2101,6 @@ Editor::cursor_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                if (session) {
                        session->request_locate (playhead_cursor->current_frame, drag_info.was_rolling);
                }
-       } else if (item == &edit_cursor->canvas_item) {
-               edit_cursor->set_position (edit_cursor->current_frame);
-               edit_cursor_clock.set (edit_cursor->current_frame);
        } 
 }
 
@@ -2180,14 +2142,16 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event)
 
        start_grab (event);
 
+       _dragging_edit_point = true;
+
        drag_info.copied_location = new Location (*location);
        drag_info.pointer_frame_offset = drag_info.grab_frame - (is_start ? location->start() : location->end());       
 
        update_marker_drag_item (location);
 
        if (location->is_mark()) {
-               marker_drag_line->show();
-               marker_drag_line->raise_to_top();
+               // marker_drag_line->show();
+               // marker_drag_line->raise_to_top();
        } else {
                range_marker_drag_rect->show();
                range_marker_drag_rect->raise_to_top();
@@ -2198,6 +2162,23 @@ Editor::start_marker_grab (ArdourCanvas::Item* item, GdkEvent* event)
        } else {
                show_verbose_time_cursor (location->end(), 10);
        }
+
+       Selection::Operation op = Keyboard::selection_type (event->button.state);
+
+       switch (op) {
+       case Selection::Toggle:
+               selection->toggle (marker);
+               break;
+       case Selection::Set:
+               selection->set (marker);
+               break;
+       case Selection::Extend:
+               selection->add (marker);
+               break;
+       case Selection::Add:
+               selection->add (marker);
+               break;
+       }
 }
 
 void
@@ -2210,7 +2191,6 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
        bool is_start;
        bool move_both = false;
 
-
        nframes_t newframe;
        if (drag_info.pointer_frame_offset <= drag_info.current_pointer_frame) {
                newframe = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
@@ -2230,7 +2210,13 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 
        /* call this to find out if its the start or end */
        
-       real_location = find_location_from_marker (marker, is_start);
+       if ((real_location = find_location_from_marker (marker, is_start)) == 0) {
+               return;
+       }
+
+       if (real_location->locked()) {
+               return;
+       }
 
        /* use the copy that we're "dragging" around */
        
@@ -2285,7 +2271,8 @@ Editor::marker_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 
        LocationMarkers* lm = find_location_markers (real_location);
        lm->set_position (copy_location->start(), copy_location->end());
-       
+       edit_point_clock.set (copy_location->start());
+
        show_verbose_time_cursor (newframe, 10);
 }
 
@@ -2296,17 +2283,23 @@ Editor::marker_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event
                marker_drag_motion_callback (item, event);
 
        }
+
+       _dragging_edit_point = false;
        
        Marker* marker = (Marker *) drag_info.data;
        bool is_start;
 
-
        begin_reversible_command ( _("move marker") );
        XMLNode &before = session->locations()->get_state();
        
        Location * location = find_location_from_marker (marker, is_start);
-       
+
        if (location) {
+
+               if (location->locked()) {
+                       return;
+               }
+
                if (location->is_mark()) {
                        location->set_start (drag_info.copied_location->start());
                } else {
@@ -5181,7 +5174,7 @@ Editor::mouse_brush_insert_region (RegionView* rv, nframes_t pos)
        switch (snap_type) {
        case SnapToFrame:
        case SnapToMark:
-       case SnapToEditCursor:
+       case SnapToEditPoint:
                return;
 
        default:
index 7ae7706928ea0e8209653d29eebb2bc7cfbc06b3..30577e11efa80e1948eaf79a34b82e02a8bd0de3 100644 (file)
@@ -157,8 +157,10 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions)
                }
 
                AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*a);
-               if (arv)
+
+               if (arv) {
                        _new_regionviews_show_envelope = arv->envelope_visible();
+               }
                
                if (pl) {
                         XMLNode &before = pl->get_state();
@@ -790,6 +792,153 @@ Editor::cursor_to_selection_end (Cursor *cursor)
        }
 }
 
+void
+Editor::edit_point_to_region_point (RegionPoint point, int32_t dir)
+{
+       boost::shared_ptr<Region> r;
+       nframes_t pos;
+       Location* loc;
+       bool ignored;
+
+       if (!session || selection->markers.empty()) {
+               return;
+       }
+
+       if ((loc = find_location_from_marker (selection->markers.front(), ignored)) == 0) {
+               return;
+       }
+
+       TimeAxisView *ontrack = 0;
+
+       pos = loc->start();
+
+       // so we don't find the current region again..
+       if (dir>0 || pos>0)
+               pos+=dir;
+
+       if (!selection->tracks.empty()) {
+               
+               r = find_next_region (pos, point, dir, selection->tracks, &ontrack);
+               
+       } else {
+               
+               r = find_next_region (pos, point, dir, track_views, &ontrack);
+       }
+
+       if (r == 0) {
+               return;
+       }
+       
+       switch (point){
+       case Start:
+               pos = r->first_frame ();
+               break;
+
+       case End:
+               pos = r->last_frame ();
+               break;
+
+       case SyncPoint:
+               pos = r->adjust_to_sync (r->first_frame());
+               break;  
+       }
+       
+       float speed = 1.0f;
+       AudioTimeAxisView *atav;
+
+       if ( ontrack != 0 && (atav = dynamic_cast<AudioTimeAxisView*>(ontrack)) != 0 ) {
+               if (atav->get_diskstream() != 0) {
+                       speed = atav->get_diskstream()->speed();
+               }
+       }
+
+       pos = track_frame_to_session_frame(pos, speed);
+
+       loc->move_to (pos);
+}
+
+void
+Editor::edit_point_to_next_region_point (RegionPoint point)
+{
+       edit_point_to_region_point (point, 1);
+}
+
+void
+Editor::edit_point_to_previous_region_point (RegionPoint point)
+{
+       edit_point_to_region_point (point, -1);
+}
+
+void
+Editor::edit_point_to_selection_start ()
+{
+       nframes_t pos = 0;
+       Location* loc;
+       bool ignored;
+
+       if (!session || selection->markers.empty()) {
+               return;
+       }
+
+       if ((loc = find_location_from_marker (selection->markers.front(), ignored)) == 0) {
+               return;
+       }
+
+       switch (mouse_mode) {
+       case MouseObject:
+               if (!selection->regions.empty()) {
+                       pos = selection->regions.start();
+               }
+               break;
+
+       case MouseRange:
+               if (!selection->time.empty()) {
+                       pos = selection->time.start ();
+               }
+               break;
+
+       default:
+               return;
+       }
+
+       loc->move_to (pos);
+}
+
+void
+Editor::edit_point_to_selection_end ()
+{
+       nframes_t pos = 0;
+       Location* loc;
+       bool ignored;
+
+       if (!session || selection->markers.empty()) {
+               return;
+       }
+
+       if ((loc = find_location_from_marker (selection->markers.front(), ignored)) == 0) {
+               return;
+       }
+
+       switch (mouse_mode) {
+       case MouseObject:
+               if (!selection->regions.empty()) {
+                       pos = selection->regions.end_frame();
+               }
+               break;
+
+       case MouseRange:
+               if (!selection->time.empty()) {
+                       pos = selection->time.end_frame ();
+               }
+               break;
+
+       default:
+               return;
+       }
+
+       loc->move_to (pos);
+}
+
 void
 Editor::scroll_playhead (bool forward)
 {
@@ -888,12 +1037,33 @@ Editor::playhead_forward ()
 void
 Editor::cursor_align (bool playhead_to_edit)
 {
+       if (!session) {
+               return;
+       }
+
        if (playhead_to_edit) {
-               if (session) {
-                       session->request_locate (get_preferred_edit_position());
+
+               if (selection->markers.empty()) {
+                       return;
                }
+               
+               session->request_locate (selection->markers.front()->position(), session->transport_rolling());
+       
        } else {
-               edit_cursor->set_position (playhead_cursor->current_frame);
+               /* move selected markers to playhead */
+               
+               for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
+                       bool ignored;
+                       
+                       Location* loc = find_location_from_marker (*i, ignored);
+                       
+                       if (loc->is_mark()) {
+                               loc->set_start (playhead_cursor->current_frame);
+                       } else {
+                               loc->set (playhead_cursor->current_frame,
+                                         playhead_cursor->current_frame + loc->length());
+                       }
+               }
        }
 }
 
@@ -925,7 +1095,7 @@ Editor::edit_cursor_backward ()
                pos -= cnt;
        }
        
-       edit_cursor->set_position (pos);
+       // EDIT CURSOR edit_cursor->set_position (pos);
 }
 
 void
@@ -946,8 +1116,8 @@ Editor::edit_cursor_forward ()
                }
        }
 
-       pos = edit_cursor->current_frame;
-       edit_cursor->set_position (pos+cnt);
+       // pos = edit_cursor->current_frame;
+       // EDIT CURSOR edit_cursor->set_position (pos+cnt);
 }
 
 void
@@ -1183,7 +1353,7 @@ Editor::temporal_zoom (gdouble fpu)
                break;
 
        case ZoomFocusEdit:
-               /* try to keep the edit cursor in the center */
+               /* try to keep the edit point in the center */
                if (get_preferred_edit_position() > new_page/2) {
                        leftmost_after_zoom = get_preferred_edit_position() - (new_page/2);
                } else {
@@ -1705,7 +1875,7 @@ Editor::play_from_start ()
 }
 
 void
-Editor::play_from_edit_cursor ()
+Editor::play_from_edit_point ()
 {
        session->request_locate (get_preferred_edit_position(), true);
 }
@@ -2136,16 +2306,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) {
                
                RouteTimeAxisView* rtv;
                
@@ -2166,8 +2357,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"));
@@ -2175,10 +2366,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;
                }
                
@@ -2186,17 +2377,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));
        }
@@ -2312,7 +2503,7 @@ Editor::set_a_regions_sync_position (boost::shared_ptr<Region> region, nframes_t
 
 /** Set the sync position of the selection using the position of the edit cursor */
 void
-Editor::set_region_sync_from_edit_cursor ()
+Editor::set_region_sync_from_edit_point ()
 {
        /* Check that at the edit cursor is in at least one of the selected regions */
        RegionSelection::const_iterator i = selection->regions.begin();
@@ -2323,11 +2514,11 @@ Editor::set_region_sync_from_edit_cursor ()
 
        /* Give the user a hint if not */
        if (i == selection->regions.end()) {
-               error << _("Place the edit cursor at the desired sync point") << endmsg;
+               error << _("Place the edit point at the desired sync point") << endmsg;
                return;
        }
 
-       begin_reversible_command (_("set sync from edit cursor"));
+       begin_reversible_command (_("set sync from edit point"));
        
        for (RegionSelection::iterator j = selection->regions.begin(); j != selection->regions.end(); ++j) {
                boost::shared_ptr<Region> r = (*j)->region();
@@ -2376,13 +2567,31 @@ Editor::naturalize ()
 void
 Editor::align (RegionPoint what)
 {
-       align_selection (what, get_preferred_edit_position());
+       nframes64_t where = get_preferred_edit_position();
+
+       if (!selection->regions.empty()) {
+               align_selection (what, where, selection->regions);
+       } else {
+
+               RegionSelection rs;
+               rs = get_regions_at (where, selection->tracks);
+               align_selection (what, where, rs);
+       }
 }
 
 void
 Editor::align_relative (RegionPoint what)
 {
-       align_selection_relative (what, get_preferred_edit_position());
+       nframes64_t where = get_preferred_edit_position();
+
+       if (!selection->regions.empty()) {
+               align_selection_relative (what, where, selection->regions);
+       } else {
+
+               RegionSelection rs;
+               rs = get_regions_at (where, selection->tracks);
+               align_selection_relative (what, where, rs);
+       }
 }
 
 struct RegionSortByTime {
@@ -2392,9 +2601,9 @@ struct RegionSortByTime {
 };
 
 void
-Editor::align_selection_relative (RegionPoint point, nframes_t position)
+Editor::align_selection_relative (RegionPoint point, nframes_t position, const RegionSelection& rs)
 {
-       if (selection->regions.empty()) {
+       if (rs.empty()) {
                return;
        }
 
@@ -2403,7 +2612,7 @@ Editor::align_selection_relative (RegionPoint point, nframes_t position)
        int dir;
 
        list<RegionView*> sorted;
-       selection->regions.by_position (sorted);
+       rs.by_position (sorted);
        boost::shared_ptr<Region> r ((*sorted.begin())->region());
 
        switch (point) {
@@ -2430,7 +2639,7 @@ Editor::align_selection_relative (RegionPoint point, nframes_t position)
 
        begin_reversible_command (_("align selection (relative)"));
 
-       for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+       for (RegionSelection::const_iterator i = rs.begin(); i != rs.end(); ++i) {
 
                boost::shared_ptr<Region> region ((*i)->region());
 
@@ -2451,15 +2660,15 @@ Editor::align_selection_relative (RegionPoint point, nframes_t position)
 }
 
 void
-Editor::align_selection (RegionPoint point, nframes_t position)
+Editor::align_selection (RegionPoint point, nframes_t position, const RegionSelection& rs)
 {
-       if (selection->regions.empty()) {
+       if (rs.empty()) {
                return;
        }
 
        begin_reversible_command (_("align selection"));
 
-       for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+       for (RegionSelection::const_iterator i = rs.begin(); i != rs.end(); ++i) {
                align_region_internal ((*i)->region(), point, position);
        }
 
@@ -2501,64 +2710,155 @@ Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint poi
 
 /** Trim the end of the selected regions to the position of the edit cursor */
 void
-Editor::trim_region_to_edit_cursor ()
+Editor::trim_region_to_loop ()
 {
-       if (selection->regions.empty()) {
+       Location* loc = session->locations()->auto_loop_location();
+       if (!loc) {
                return;
        }
+       trim_region_to_location (*loc, _("trim to loop"));
+}
 
-       begin_reversible_command (_("trim to edit"));
-       
-       for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
-               boost::shared_ptr<Region> region ((*i)->region());
+void
+Editor::trim_region_to_punch ()
+{
+       Location* loc = session->locations()->auto_punch_location();
+       if (!loc) {
+               return;
+       }
+       trim_region_to_location (*loc, _("trim to punch"));
+}
+void
+Editor::trim_region_to_location (const Location& loc, const char* str)
+{
+       RegionSelection& rs (get_regions_for_action ());
 
-               float speed = 1.0f;
-               RouteTimeAxisView *rtav;
+       begin_reversible_command (str);
 
-               /* XXX I don't think clicked_axisview should be used here! */
-               if ( clicked_axisview != 0 && (rtav = dynamic_cast<RouteTimeAxisView*>(clicked_axisview)) != 0 ) {
-                       if (rtav->get_diskstream() != 0) {
-                               speed = rtav->get_diskstream()->speed();
-                       }
+       for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
+               AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*x);
+
+               if (!arv) {
+                       continue;
+               }
+
+               /* require region to span proposed trim */
+
+               switch (arv->region()->coverage (loc.start(), loc.end())) {
+               case OverlapInternal:
+                       break;
+               default:
+                       continue;
+               }
+                               
+               AudioTimeAxisView* atav = dynamic_cast<AudioTimeAxisView*> (&arv->get_time_axis_view());
+
+               if (!atav) {
+                       return;
+               }
+
+               float speed = 1.0;
+               nframes_t start;
+               nframes_t end;
+
+               if (atav->get_diskstream() != 0) {
+                       speed = atav->get_diskstream()->speed();
                }
                
-               XMLNode &before = region->playlist()->get_state();
-               region->trim_end( session_frame_to_track_frame(get_preferred_edit_position(), speed), this);
-               XMLNode &after = region->playlist()->get_state();
-               session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
+               start = session_frame_to_track_frame (loc.start(), speed);
+               end = session_frame_to_track_frame (loc.end(), speed);
+
+               XMLNode &before = arv->region()->playlist()->get_state();
+               arv->region()->trim_to (start, (end - start), this);
+               XMLNode &after = arv->region()->playlist()->get_state();
+               session->add_command(new MementoCommand<Playlist>(*(arv->region()->playlist()), &before, &after));
        }
-       
+
        commit_reversible_command ();
 }
 
-/** Trim the start of the selected regions to the position of the edit cursor */
 void
-Editor::trim_region_from_edit_cursor ()
+Editor::trim_region_to_edit_point ()
 {
-       if (selection->regions.empty()) {
-               return;
-       }
+       RegionSelection& rs (get_regions_for_action ());
+       nframes64_t where = get_preferred_edit_position();
 
-       begin_reversible_command (_("trim to edit"));
+       begin_reversible_command (_("trim region start to edit point"));
 
-       for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
-               boost::shared_ptr<Region> region ((*i)->region());
+       for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
+               AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*x);
+
+               if (!arv) {
+                       continue;
+               }
+
+               /* require region to cover trim */
+
+               if (!arv->region()->covers (where)) {
+                       continue;
+               }
+
+               AudioTimeAxisView* atav = dynamic_cast<AudioTimeAxisView*> (&arv->get_time_axis_view());
+
+               if (!atav) {
+                       return;
+               }
+
+               float speed = 1.0;
+
+               if (atav->get_diskstream() != 0) {
+                       speed = atav->get_diskstream()->speed();
+               }
+
+               XMLNode &before = arv->region()->playlist()->get_state();
+               arv->region()->trim_end( session_frame_to_track_frame(where, speed), this);
+               XMLNode &after = arv->region()->playlist()->get_state();
+               session->add_command(new MementoCommand<Playlist>(*(arv->region()->playlist()), &before, &after));
+       }
                
-               float speed = 1.0f;
-               RouteTimeAxisView *rtav;
+       commit_reversible_command ();
+}
 
-               /* XXX: not sure about clicked_axisview here */
-               if ( clicked_axisview != 0 && (rtav = dynamic_cast<RouteTimeAxisView*>(clicked_axisview)) != 0 ) {
-                       if (rtav->get_diskstream() != 0) {
-                               speed = rtav->get_diskstream()->speed();
-                       }
+void
+Editor::trim_region_from_edit_point ()
+{
+       RegionSelection& rs (get_regions_for_action ());
+       nframes64_t where = get_preferred_edit_position();
+
+       begin_reversible_command (_("trim region end to edit point"));
+
+       for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
+               AudioRegionView* arv = dynamic_cast<AudioRegionView*> (*x);
+
+               if (!arv) {
+                       continue;
                }
 
-               XMLNode &before = region->playlist()->get_state();
-               region->trim_front ( session_frame_to_track_frame(get_preferred_edit_position(), speed), this);
-               XMLNode &after = region->playlist()->get_state();
-               session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
+               /* require region to cover trim */
+
+               if (!arv->region()->covers (where)) {
+                       continue;
+               }
+
+               AudioTimeAxisView* atav = dynamic_cast<AudioTimeAxisView*> (&arv->get_time_axis_view());
+
+               if (!atav) {
+                       return;
+               }
+
+               float speed = 1.0;
+
+               if (atav->get_diskstream() != 0) {
+                       speed = atav->get_diskstream()->speed();
+               }
+
+               XMLNode &before = arv->region()->playlist()->get_state();
+               arv->region()->trim_front ( session_frame_to_track_frame(where, speed), this);
+               XMLNode &after = arv->region()->playlist()->get_state();
+               session->add_command(new MementoCommand<Playlist>(*(arv->region()->playlist()), &before, &after));
        }
+               
+       commit_reversible_command ();
 }
 
 /** Unfreeze selected routes */
@@ -2758,6 +3058,20 @@ Editor::cut_copy (CutCopyOp op)
        
        cut_buffer->clear ();
 
+       if (entered_marker) {
+
+               /* cut/delete op while pointing at a marker */
+
+               bool ignored;
+               Location* loc = find_location_from_marker (entered_marker, ignored);
+
+               if (session && loc) {
+                       Glib::signal_idle().connect (bind (mem_fun(*this, &Editor::really_remove_marker), loc));
+               }
+
+               return;
+       }
+
        switch (current_mouse_mode()) {
        case MouseObject: 
                if (!selection->regions.empty() || !selection->points.empty()) {
@@ -2782,21 +3096,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:
@@ -2977,7 +3301,15 @@ Editor::cut_copy_regions (CutCopyOp op)
 void
 Editor::cut_copy_ranges (CutCopyOp op)
 {
-       for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+       TrackSelection* ts;
+
+       if (selection->tracks.empty()) {
+               ts = &track_views;
+       } else {
+               ts = &selection->tracks;
+       }
+
+       for (TrackSelection::iterator i = ts->begin(); i != ts->end(); ++i) {
                (*i)->cut_copy_clear (*selection, op);
        }
 }
@@ -3186,15 +3518,13 @@ void
 Editor::center_playhead ()
 {
        float page = canvas_width * frames_per_unit;
-
        center_screen_internal (playhead_cursor->current_frame, page);
 }
 
 void
-Editor::center_edit_cursor ()
+Editor::center_edit_point ()
 {
        float page = canvas_width * frames_per_unit;
-
        center_screen_internal (get_preferred_edit_position(), page);
 }
 
@@ -3210,14 +3540,14 @@ Editor::clear_playlist (boost::shared_ptr<Playlist> playlist)
 }
 
 void
-Editor::nudge_selected_tracks (bool use_edit_cursor, bool forwards)
+Editor::nudge_selected_tracks (bool use_edit, bool forwards)
 {
        boost::shared_ptr<Playlist> playlist; 
        nframes_t distance;
        nframes_t next_distance;
        nframes_t start;
 
-       if (use_edit_cursor) {
+       if (use_edit) {
                start = get_preferred_edit_position();
        } else {
                start = 0;
@@ -3574,6 +3904,68 @@ Editor::toggle_region_opaque ()
        }
 }
 
+void
+Editor::set_fade_length (bool in)
+{
+       /* we need a region to measure the offset from the start */
+
+       RegionView* rv;
+
+       if (entered_regionview) {
+               rv = entered_regionview;
+       } else if (!selection->regions.empty()) {
+               rv = selection->regions.front();
+       } else {
+               return;
+       }
+
+       nframes64_t pos = get_preferred_edit_position();
+       nframes_t len;
+       char* cmd;
+
+       if (in) {
+               if (pos <= rv->region()->position()) {
+                       /* can't do it */
+                       return;
+               }
+               len = pos - rv->region()->position();
+               cmd = _("set fade in length");
+       } else {
+               if (pos >= rv->region()->last_frame()) {
+                       /* can't do it */
+                       return;
+               }
+               len = rv->region()->last_frame() - pos;
+               cmd = _("set fade out length");
+       }
+
+       begin_reversible_command (cmd);
+
+       RegionSelection& rs (get_regions_for_action());
+
+       for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
+               AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
+
+               if (!tmp) {
+                       return;
+               }
+
+               boost::shared_ptr<AutomationList> alist = tmp->audio_region()->fade_in();
+               XMLNode &before = alist->get_state();
+
+               if (in) {
+                       tmp->audio_region()->set_fade_in_length (len);
+               } else {
+                       tmp->audio_region()->set_fade_out_length (len);
+               }
+               
+               XMLNode &after = alist->get_state();
+               session->add_command(new MementoCommand<AutomationList>(*alist.get(), &before, &after));
+       }
+
+       commit_reversible_command ();
+}
+
 void
 Editor::set_fade_in_shape (AudioRegion::FadeShape shape)
 {
@@ -3687,3 +4079,68 @@ Editor::update_xfade_visibility ()
                }
        }
 }
+
+void
+Editor::set_edit_point ()
+{
+       nframes64_t where;
+       bool ignored;
+
+       if (!mouse_frame (where, ignored)) {
+               return;
+       }
+       
+       snap_to (where);
+
+       if (selection->markers.empty()) {
+               
+               mouse_add_new_marker (where);
+
+       } else {
+               bool ignored;
+
+               Location* loc = find_location_from_marker (selection->markers.front(), ignored);
+
+               if (loc) {
+                       loc->move_to (where);
+               }
+       }
+}
+
+void
+Editor::set_playhead_cursor ()
+{
+       if (entered_marker) {
+               session->request_locate (entered_marker->position(), session->transport_rolling());
+       } else {
+               nframes64_t where;
+               bool ignored;
+
+               if (!mouse_frame (where, ignored)) {
+                       return;
+               }
+                       
+               snap_to (where);
+               
+               if (session) {
+                       session->request_locate (where, session->transport_rolling());
+               }
+       }
+}
+
+void
+Editor::split ()
+{
+       nframes64_t where = get_preferred_edit_position();
+
+       if (!selection->regions.empty()) {
+               
+               split_regions_at (where, selection->regions);
+
+       } else {
+               
+               RegionSelection rs;
+               rs = get_regions_at (where, selection->tracks);
+               split_regions_at (where, rs);
+       }
+}
index 72e70955cdc1db7ea5fa1f1826760abf571a0735..4eb684c48ab5bebc5bf6c6158a47b6e5bf037e0b 100644 (file)
@@ -164,12 +164,10 @@ Editor::ruler_button_press (GdkEventButton* ev)
                break;
 
        case 2:
-               /* edit cursor */
-               if (snap_type != Editing::SnapToEditCursor) {
+               /* edit point */
+               if (snap_type != Editing::SnapToEditPoint) {
                        snap_to (where);
                }
-               edit_cursor->set_position (where);
-               edit_cursor_clock.set (where);
                break;
 
        default:
@@ -207,12 +205,10 @@ Editor::ruler_button_release (GdkEventButton* ev)
                break;
 
        case 2:
-               /* edit cursor */
-               if (snap_type != Editing::SnapToEditCursor) {
+               /* edit point */
+               if (snap_type != Editing::SnapToEditPoint) {
                        snap_to (where);
                }
-               edit_cursor->set_position (where);
-               edit_cursor_clock.set (where);
                break;
 
        case 3:
@@ -301,8 +297,8 @@ Editor::ruler_mouse_motion (GdkEventMotion* ev)
                break;
 
        case 2:
-               /* edit cursor */
-               cursor = edit_cursor;
+               /* edit point */
+               // EDIT CURSOR XXX do something useful
                break;
 
        default:
@@ -312,9 +308,7 @@ Editor::ruler_mouse_motion (GdkEventMotion* ev)
        if (cursor) {
                cursor->set_position (where);
                
-               if (cursor == edit_cursor) {
-                       edit_cursor_clock.set (where);
-               } else if (cursor == playhead_cursor) {
+               if (cursor == playhead_cursor) {
                        UpdateAllTransportClocks (cursor->current_frame);
                }
        }
@@ -668,20 +662,6 @@ Editor::update_ruler_visibility ()
                tempo_group->hide();
        }
        
-       if (ruler_shown[ruler_time_marker]) {
-               lab_children.push_back (Element(mark_label, PACK_SHRINK, PACK_START));
-               old_unit_pos = marker_group->property_y();
-               if (tbpos != old_unit_pos) {
-                       marker_group->move ( 0.0, tbpos - old_unit_pos);
-               }
-               marker_group->show();
-               tbpos += timebar_height;
-               visible_timebars++;
-       }
-       else {
-               marker_group->hide();
-       }
-       
        if (ruler_shown[ruler_time_range_marker]) {
                lab_children.push_back (Element(range_mark_label, PACK_SHRINK, PACK_START));
                old_unit_pos = range_marker_group->property_y();
@@ -710,6 +690,20 @@ Editor::update_ruler_visibility ()
                transport_marker_group->hide();
        }
        
+       if (ruler_shown[ruler_time_marker]) {
+               lab_children.push_back (Element(mark_label, PACK_SHRINK, PACK_START));
+               old_unit_pos = marker_group->property_y();
+               if (tbpos != old_unit_pos) {
+                       marker_group->move ( 0.0, tbpos - old_unit_pos);
+               }
+               marker_group->show();
+               tbpos += timebar_height;
+               visible_timebars++;
+       }
+       else {
+               marker_group->hide();
+       }
+       
        time_canvas_vbox.set_size_request (-1, (int)(timebar_height * visible_timebars));
        time_canvas_event_box.queue_resize();
        compute_fixed_ruler_scale();
index 12ca558ea46936e9ed177f5d222309e5f01c6911..554f5c341d4372fadc1d7cff8a9587726fb27ad7 100644 (file)
@@ -969,25 +969,45 @@ Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after)
 }
 
 void
-Editor::select_all_selectables_between_cursors (Cursor *cursor, Cursor *other_cursor)
+Editor::select_all_selectables_using_edit (bool after)
 {
         nframes_t start;
        nframes_t end;
        list<Selectable *> touched;
-       bool  other_cursor_is_first = cursor->current_frame > other_cursor->current_frame;
 
-       if (cursor->current_frame == other_cursor->current_frame) {
-               return;
+       if (after) {
+               begin_reversible_command (_("select all after edit"));
+               start = get_preferred_edit_position();
+               end = session->current_end_frame();
+       } else {
+               if ((end = get_preferred_edit_position()) > 1) {
+                       begin_reversible_command (_("select all before edit"));
+                       start = 0;
+                       end -= 1;
+               } else {
+                       return;
+               }
        }
 
-       begin_reversible_command (_("select all between cursors"));
-       if (other_cursor_is_first) {
-               start = other_cursor->current_frame;
-               end = cursor->current_frame - 1;
-               
-       } else {
-               start = cursor->current_frame;
-               end = other_cursor->current_frame - 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);
+       commit_reversible_command ();
+}
+
+void
+Editor::select_all_selectables_between (bool within)
+{
+        nframes64_t start;
+       nframes64_t end;
+       list<Selectable *> touched;
+
+       if (!get_edit_op_range (start, end)) {
+               return;
        }
        
        for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
@@ -996,7 +1016,85 @@ Editor::select_all_selectables_between_cursors (Cursor *cursor, Cursor *other_cu
                }
                (*iter)->get_selectables (start, end, 0, DBL_MAX, touched);
        }
+
        selection->set (touched);
-       commit_reversible_command ();
 }
 
+void
+Editor::select_range_between ()
+{
+        nframes64_t start;
+       nframes64_t end;
+       
+       if (!get_edit_op_range (start, end)) {
+               return;
+       }
+
+       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:
+                       if (selection->markers.empty()) {
+                               /* use mouse + playhead */
+                               start = m;
+                               end = session->audible_frame();
+                       } else {
+                               /* use playhead + selected marker */
+                               start = session->audible_frame();
+                               end = selection->markers.front()->position();
+                       }
+                       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 false;
+       }
+
+       if (start > end) {
+               swap (start, end);
+       }
+
+       return true;
+}
index e306110f152d9cc22e0fb3727e6d0f6111f4fffd..b9dea243134ddaaea1c95ca975a629be8344bb5d 100644 (file)
@@ -294,6 +294,10 @@ LocationEditRow::set_location (Location *loc)
 
        }
 
+       start_clock.set_sensitive (!location->locked());
+       end_clock.set_sensitive (!location->locked());
+       length_clock.set_sensitive (!location->locked());
+
        start_changed_connection = location->start_changed.connect (mem_fun(*this, &LocationEditRow::start_changed));
        end_changed_connection = location->end_changed.connect (mem_fun(*this, &LocationEditRow::end_changed));
        name_changed_connection = location->name_changed.connect (mem_fun(*this, &LocationEditRow::name_changed));
@@ -573,6 +577,10 @@ LocationEditRow::location_changed (ARDOUR::Location *loc)
        end_clock.set (location->end());
        length_clock.set (location->length());
 
+       start_clock.set_sensitive (!location->locked());
+       end_clock.set_sensitive (!location->locked());
+       length_clock.set_sensitive (!location->locked());
+
        i_am_the_modifier--;
 
 }
index a0f91d2a2a37709b70b8ec7a49e371a1fc08448e..de2ceb554e45c6be46abbe7259b9efa0683ce8fa 100644 (file)
@@ -252,9 +252,9 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con
        delete font;
        
        if (annotate_left) {
-         text->property_x() = -(text->property_text_width());
+               text->property_x() = -(text->property_text_width());
        } else {
-         text->property_x() = label_offset;
+               text->property_x() = label_offset;
        }
        text->property_y() = 0.0;
        text->property_anchor() = Gtk::ANCHOR_NW;
@@ -268,14 +268,66 @@ Marker::Marker (PublicEditor& ed, ArdourCanvas::Group& parent, guint32 rgba, con
                group->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_marker_event), mark, this));
        }
 
+       line = 0;
+       line_points = 0;
+
 }
 
 Marker::~Marker ()
 {
+       drop_references ();
+
        /* destroying the parent group destroys its contents, namely any polygons etc. that we added */
        delete text;
        delete mark;
        delete points;
+
+       if (line) {
+               delete line;
+               delete line_points;
+       }
+}
+
+void
+Marker::add_line (ArdourCanvas::Group* group, double initial_height)
+{
+       if (!line) {
+
+               line_points = new ArdourCanvas::Points ();
+               line_points->push_back (Gnome::Art::Point (unit_position + shift, 0.0));
+               line_points->push_back (Gnome::Art::Point (unit_position + shift, initial_height));                     
+               
+               line = new ArdourCanvas::Line (*group);
+               line->property_width_pixels() = 1;
+               line->property_points() = *line_points;
+               line->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_EditPoint.get();
+               line->property_first_arrowhead() = TRUE;
+               line->property_last_arrowhead() = TRUE;
+               line->property_arrow_shape_a() = 11.0;
+               line->property_arrow_shape_b() = 0.0;
+               line->property_arrow_shape_c() = 9.0;
+
+               line->signal_event().connect (bind (mem_fun (editor, &PublicEditor::canvas_marker_event), mark, this));
+       }
+
+       show_line ();
+}
+
+void
+Marker::show_line ()
+{
+       if (line) {
+               line->raise_to_top();
+               line->show ();
+       }
+}
+
+void 
+Marker::hide_line ()
+{
+       if (line) {
+               line->hide ();
+       }
 }
 
 ArdourCanvas::Item&
@@ -301,6 +353,12 @@ Marker::set_position (nframes_t frame)
        group->move (new_unit_position - unit_position, 0.0);
        frame_position = frame;
        unit_position = new_unit_position;
+
+       if (line) {
+               (*line_points)[0].set_x (unit_position + shift);
+               (*line_points)[1].set_x (unit_position + shift);
+               line->property_points() = *line_points;
+       }
 }
 
 void
index 7865004d54e15de0a509f1fad2b397014e07ee8f..5ffd6c5dd16448710cbe85871ae4a30d389cca7a 100644 (file)
@@ -23,7 +23,7 @@
 #include <string>
 #include <glib.h>
 #include <ardour/ardour.h>
-#include <sigc++/signal.h>
+#include <pbd/destructible.h>
 
 #include "canvas.h"
 
@@ -34,7 +34,7 @@ namespace ARDOUR {
 
 class PublicEditor;
 
-class Marker : public sigc::trackable
+class Marker : public PBD::Destructible
 {
   public:
        enum Type {
@@ -57,9 +57,15 @@ class Marker : public sigc::trackable
 
        ArdourCanvas::Item& the_item() const;
 
+       void add_line (ArdourCanvas::Group*, double initial_height);
+       void show_line ();
+       void hide_line ();
+
        void set_position (nframes_t);
        void set_name (const string&);
        void set_color_rgba (uint32_t rgba);
+       
+       nframes64_t position() const { return frame_position; }
 
        void hide ();
        void show ();
@@ -73,11 +79,13 @@ class Marker : public sigc::trackable
        ArdourCanvas::Polygon *mark;
        ArdourCanvas::Text *text;
        ArdourCanvas::Points *points;
+       ArdourCanvas::Line *line;
+       ArdourCanvas::Points *line_points;
 
-       double    unit_position;
-       nframes_t frame_position;
-       unsigned char      shift; /* should be double, but its always small and integral */
-       Type      _type;
+       double        unit_position;
+       nframes64_t   frame_position;
+       unsigned char shift; /* should be double, but its always small and integral */
+       Type         _type;
        
        void reposition ();
 };
index f32c0565e3c1345fcf3f1564235e4a7e87f953d0..3410dc025af3077b91b6999478cb8e097546e8b2 100644 (file)
@@ -85,7 +85,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        PublicEditor ();
        virtual ~PublicEditor ();
 
-       typedef list<TimeAxisView *> TrackViewList;
+       typedef TrackSelection TrackViewList;
 
        /** @return Singleton PublicEditor instance */
        static PublicEditor& instance () { return *_instance; }
@@ -252,7 +252,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        virtual void remove_last_capture () = 0;
        virtual void maximise_editing_space () = 0;
        virtual void restore_editing_space () = 0;
-       virtual nframes_t edit_cursor_position (bool sync) = 0;
+       virtual nframes64_t get_preferred_edit_position () = 0;
 
 #ifdef WITH_CMT
        virtual void add_imageframe_time_axis(const std::string & track_name, void*)  = 0;
index c6bb5c37af1a52f03c0d103fff176a4ae2dab814..f1511c6ffa452249691b8dc6a92fc1593857b967 100644 (file)
@@ -741,11 +741,17 @@ Selection::remove (Marker* m)
        }
 }
 
-
 void
 Selection::add (Marker* m)
 {
        if (find (markers.begin(), markers.end(), m) == markers.end()) {
+
+               /* disambiguate which remove() for the compiler */
+               
+               void (Selection::*pmf)(Marker*) = &Selection::remove;
+
+               m->GoingAway.connect (bind (mem_fun (*this, pmf), m));
+
                markers.push_back (m);
                MarkersChanged();
        }
index 3bde6c98f1496bb971f6bbd73dc6a8a7a617ff16..ae8209e9da471f4692f05fb6bd76f6d911379629 100644 (file)
@@ -989,7 +989,7 @@ SoundFileOmega::SoundFileOmega (Gtk::Window& parent, string title, ARDOUR::Sessi
 
        str.clear ();
        str.push_back (_("use file timestamp"));
-       str.push_back (_("at edit cursor"));
+       str.push_back (_("at edit point"));
        str.push_back (_("at playhead"));
        str.push_back (_("at session start"));
        set_popdown_strings (where_combo, str);
@@ -1125,8 +1125,8 @@ SoundFileOmega::get_position() const
 
        if (str == _("use file timestamp")) {
                return ImportAtTimestamp;
-       } else if (str == _("at edit cursor")) {
-               return ImportAtEditCursor;
+       } else if (str == _("at edit point")) {
+               return ImportAtEditPoint;
        } else if (str == _("at playhead")) {
                return ImportAtPlayhead;
        } else {
index 6625b7dbf5b384307a5954952a86814aa4f1fbc6..5ffb716598d61be6cd222d2c8551ffcbba5f64cd 100644 (file)
@@ -62,26 +62,34 @@ class Location : public PBD::StatefulDestructible
                : _name (name),
                _start (sample_start),
                _end (sample_end),
-               _flags (bits) { }
+               _flags (bits),
+               _locked (false) { }
        
        Location () {
                _start = 0;
                _end = 0;
                _flags = Flags (0);
+               _locked = false;
        }
 
        Location (const Location& other);
        Location (const XMLNode&);
        Location* operator= (const Location& other);
 
-       nframes_t start() { return _start; }
-       nframes_t end() { return _end; }
-       nframes_t length() { return _end - _start; }
+       bool locked() const { return _locked; }
+       void lock() { _locked = true; changed (this); }
+       void unlock() { _locked = false; changed (this); }
+       
+       nframes_t start() const  { return _start; }
+       nframes_t end() const { return _end; }
+       nframes_t length() const { return _end - _start; }
 
        int set_start (nframes_t s);
        int set_end (nframes_t e);
        int set (nframes_t start, nframes_t end);
 
+       int move_to (nframes_t pos);
+
        const string& name() { return _name; }
        void set_name (const string &str) { _name = str; name_changed(this); }
 
@@ -124,6 +132,7 @@ class Location : public PBD::StatefulDestructible
        nframes_t     _start;
        nframes_t     _end;
        Flags         _flags;
+       bool          _locked;
 
        void set_mark (bool yn);
        bool set_flag_internal (bool yn, Flags flag);
@@ -136,7 +145,7 @@ class Locations : public PBD::StatefulDestructible
 
        Locations ();
        ~Locations ();
-
+       
        void add (Location *, bool make_current = false);
        void remove (Location *);
        void clear ();
@@ -182,8 +191,8 @@ class Locations : public PBD::StatefulDestructible
 
   private:
 
-       LocationList       locations;
-       Location          *current_location;
+       LocationList         locations;
+       Location            *current_location;
        mutable Glib::Mutex  lock;
 
        int set_current_unlocked (Location *);
index c77f1b9fd8f84aa2c72367117a0203534c94163c..91ff8b8d35efb67ec16a682c24ed6ef18d99b783 100644 (file)
@@ -566,6 +566,8 @@ AudioEngine::register_output_port (DataType type, const string& portname, bool p
 int          
 AudioEngine::unregister_port (Port& port)
 {
+       /* caller must hold process lock */
+
        if (!_running) { 
                /* probably happening when the engine has been halted by JACK,
                   in which case, there is nothing we can do here.
index 91654643d93d7665b633307d34797a1b82c3a42f..8034f3ddacf5963b4517fca7c4407583b62424d2 100644 (file)
@@ -812,6 +812,10 @@ AudioRegion::set_fade_out (FadeShape shape, nframes_t len)
 void
 AudioRegion::set_fade_in_length (nframes_t len)
 {
+       if (len > _length) {
+               len = _length - 1;
+       }
+
        bool changed = _fade_in->extend_to (len);
 
        if (changed) {
@@ -823,13 +827,16 @@ AudioRegion::set_fade_in_length (nframes_t len)
 void
 AudioRegion::set_fade_out_length (nframes_t len)
 {
+       if (len > _length) {
+               len = _length - 1;
+       }
+
        bool changed =  _fade_out->extend_to (len);
 
        if (changed) {
                _flags = Flag (_flags & ~DefaultFadeOut);
+               send_change (FadeOutChanged);
        }
-
-       send_change (FadeOutChanged);
 }
 
 void
index f64528aa52337d369d5c199454fb91c4113efa6f..fdb2e0f5cd7bc05d2b57029bd88a17eac828e898 100644 (file)
@@ -199,12 +199,11 @@ IO::IO (Session& s, const XMLNode& node, DataType dt)
 
 IO::~IO ()
 {
-       cerr << "Deleting IO called " << _name << endl;
-
        Glib::Mutex::Lock guard (m_meter_signal_lock);
-       
        Glib::Mutex::Lock lm (io_lock);
 
+       BLOCK_PROCESS_CALLBACK ();
+
        for (PortSet::iterator i = _inputs.begin(); i != _inputs.end(); ++i) {
                _session.engine().unregister_port (*i);
        }
index 093c6cf8fcd98d3aa0d0f1e2fc6ef9c37f5bb2fd..0da75810ca4fd4c1661f89b031b2ea9c59fd7d98 100644 (file)
@@ -52,6 +52,10 @@ Location::Location (const Location& other)
 
        _flags = Flags (_flags & ~IsStart);
        _flags = Flags (_flags & ~IsEnd);
+
+       /* copy is not locked even if original was */
+
+       _locked = false;
 }
 
 Location::Location (const XMLNode& node)
@@ -73,6 +77,10 @@ Location::operator= (const Location& other)
        _end = other._end;
        _flags = other._flags;
 
+       /* copy is not locked even if original was */
+
+       _locked = false;
+
        /* "changed" not emitted on purpose */
        
        return this;
@@ -81,6 +89,10 @@ Location::operator= (const Location& other)
 int
 Location::set_start (nframes_t s)
 {
+       if (_locked) {
+               return -1;
+       }
+
        if (is_mark()) {
                if (_start != s) {
 
@@ -117,6 +129,10 @@ Location::set_start (nframes_t s)
 int
 Location::set_end (nframes_t e)
 {
+       if (_locked) {
+               return -1;
+       }
+
        if (is_mark()) {
                if (_start != e) {
                        _start = e;
@@ -140,6 +156,10 @@ Location::set_end (nframes_t e)
 int
 Location::set (nframes_t start, nframes_t end)
 {
+       if (_locked) {
+               return -1;
+       }
+
        if (is_mark() && start != end) {
                return -1;
        } else if (((is_auto_punch() || is_auto_loop()) && start >= end) || (start > end)) {
@@ -158,6 +178,23 @@ Location::set (nframes_t start, nframes_t end)
        return 0;
 }
 
+int
+Location::move_to (nframes_t pos) 
+{
+       if (_locked) {
+               return -1;
+       }
+
+       if (_start != pos) {
+               _start = pos;
+               _end = _start + length();
+               
+               changed (this); /* EMIT SIGNAL */
+       }
+       
+       return 0;
+}
+
 void
 Location::set_hidden (bool yn, void *src)
 {
@@ -284,6 +321,7 @@ Location::get_state (void)
        snprintf (buf, sizeof (buf), "%u", end());
        node->add_property ("end", buf);
        node->add_property ("flags", enum_2_string (_flags));
+       node->add_property ("locked", (_locked ? "yes" : "no"));
 
        return *node;
 }
@@ -343,6 +381,12 @@ Location::set_state (const XMLNode& node)
                
        _flags = Flags (string_2_enum (prop->value(), _flags));
 
+       if ((prop = node.property ("locked")) != 0) {
+               _locked = (prop->value() == "yes");
+       } else {
+               _locked = false;
+       }
+
        for (cd_iter = cd_list.begin(); cd_iter != cd_list.end(); ++cd_iter) {
                  
                  cd_node = *cd_iter;
index a664ca44c7d5345efb391e9f73a9b1962d6348d3..e155800d23e044b7b9ff093f9c09095ed9a3efd4 100644 (file)
@@ -2113,13 +2113,8 @@ Session::remove_route (shared_ptr<Route> route)
 
        /* try to cause everyone to drop their references */
 
-       cerr << "pre drop, Route now has " << route.use_count() << " refs\n";
-       cerr << "sig has " << route->GoingAway.size() << endl;
-
        route->drop_references ();
 
-       cerr << "route dangling refs = " << route.use_count() << endl;
-
        /* save the new state of the world */
 
        if (save_state (_current_snapshot_name)) {