Merged with trunk R1393.
authorDavid Robillard <d@drobilla.net>
Sun, 28 Jan 2007 17:44:13 +0000 (17:44 +0000)
committerDavid Robillard <d@drobilla.net>
Sun, 28 Jan 2007 17:44:13 +0000 (17:44 +0000)
git-svn-id: svn://localhost/ardour2/branches/midi@1395 d708f5d6-7413-0410-9779-e7cbd77b26cf

85 files changed:
.cvsignore [deleted file]
SConstruct
ardour.rc.in
gtk2_ardour/SConscript
gtk2_ardour/actions.cc
gtk2_ardour/analysis_window.cc
gtk2_ardour/ardev_common.sh [deleted file]
gtk2_ardour/ardour.bindings
gtk2_ardour/ardour.menus
gtk2_ardour/ardour2_ui.rc
gtk2_ardour/ardour_ui.h
gtk2_ardour/ardour_ui_ed.cc
gtk2_ardour/ardour_ui_options.cc
gtk2_ardour/audio_clock.cc
gtk2_ardour/audio_region_view.cc
gtk2_ardour/audio_region_view.h
gtk2_ardour/audio_streamview.cc
gtk2_ardour/automation_line.cc
gtk2_ardour/automation_selectable.h
gtk2_ardour/automation_time_axis.cc
gtk2_ardour/editor.cc
gtk2_ardour/editor.h
gtk2_ardour/editor_actions.cc
gtk2_ardour/editor_audio_import.cc
gtk2_ardour/editor_export_audio.cc
gtk2_ardour/editor_keyboard.cc
gtk2_ardour/editor_mixer.cc
gtk2_ardour/editor_mouse.cc
gtk2_ardour/editor_ops.cc
gtk2_ardour/editor_region_list.cc
gtk2_ardour/editor_selection.cc [new file with mode: 0644]
gtk2_ardour/gain_meter.cc
gtk2_ardour/ladspa_pluginui.cc
gtk2_ardour/main.cc
gtk2_ardour/po/de_DE.po
gtk2_ardour/public_editor.h
gtk2_ardour/region_selection.cc
gtk2_ardour/region_selection.h
gtk2_ardour/selection.cc
gtk2_ardour/selection.h
gtk2_ardour/sfdb_ui.cc
gtk2_ardour/time_axis_view_item.h
libs/ardour/SConscript
libs/ardour/ardour/audiofilesource.h
libs/ardour/ardour/audioregion.h
libs/ardour/ardour/configuration_variable.h
libs/ardour/ardour/configuration_vars.h
libs/ardour/ardour/coreaudiosource.h
libs/ardour/ardour/crossfade.h
libs/ardour/ardour/session.h
libs/ardour/ardour/sndfilesource.h
libs/ardour/ardour/source_factory.h
libs/ardour/audiofilesource.cc
libs/ardour/audioregion.cc
libs/ardour/configuration.cc
libs/ardour/control_protocol_manager.cc
libs/ardour/coreaudiosource.cc
libs/ardour/crossfade.cc
libs/ardour/destructive_filesource.cc
libs/ardour/io.cc
libs/ardour/midi_region.cc
libs/ardour/panner.cc
libs/ardour/playlist.cc
libs/ardour/route.cc
libs/ardour/session.cc
libs/ardour/session_command.cc
libs/ardour/session_state.cc
libs/ardour/sndfilesource.cc
libs/ardour/source_factory.cc
libs/midi++2/alsa_sequencer_midiport.cc
libs/midi++2/midi++/alsa_sequencer.h
libs/pbd/whitespace.cc
svn_revision.h
tools/ARDOUR/SourceInfoLoader.pm [new file with mode: 0644]
tools/Spotlight Importer/English.lproj/InfoPlist.strings [new file with mode: 0644]
tools/Spotlight Importer/English.lproj/schema.strings [new file with mode: 0644]
tools/Spotlight Importer/GetMetadataForFile.c [new file with mode: 0644]
tools/Spotlight Importer/Info.plist [new file with mode: 0644]
tools/Spotlight Importer/Spotlight Importer.xcodeproj/project.pbxproj [new file with mode: 0644]
tools/Spotlight Importer/main.c [new file with mode: 0644]
tools/Spotlight Importer/schema.xml [new file with mode: 0644]
tools/osx_packaging/app_build.rb
tools/osx_packaging/ardour2_mac_ui.rc
tools/session_exchange.py [new file with mode: 0755]
tools/synthesize_sources.pl [new file with mode: 0755]

diff --git a/.cvsignore b/.cvsignore
deleted file mode 100644 (file)
index 140c335..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-.sconf_temp
-.sconsign.dblite
-ardour.rc
-config.log
-scache.conf
-.gdb_history
-docs/
index f129793dd6299cac1eacf85ac7e4d9a86ecd39c6..0a58a465967651089469ba427f7d97963a783fa7 100644 (file)
@@ -16,7 +16,7 @@ import SCons.Node.FS
 SConsignFile()
 EnsureSConsVersion(0, 96)
 
-ardour_version = '2.0beta10'
+ardour_version = '2.0beta11.1'
 
 subst_dict = { }
 
@@ -659,7 +659,8 @@ opt_flags[:0] = [
     "-O3",
     "-fomit-frame-pointer",
     "-ffast-math",
-    "-fstrength-reduce"
+    "-fstrength-reduce",
+    "-fno-strict-aliasing"
     ]
 
 if env['DEBUG'] == 1:
index a8c8b74bfd3513acef0ce94db6ccfe48e1eb9085..ab34ae29d4dbcf5ca857ddfc7bf620c704e4ff2e 100644 (file)
@@ -31,7 +31,7 @@
     <Option name="quieten-at-speed" value="1.000000"/>
     <Option name="use-vst" value="yes"/>
     <Option name="use-tranzport" value="yes"/>
-    <Option name="destructive-xfade-msecs" value="500"/>
+    <Option name="destructive-xfade-msecs" value="20"/>
   </Config>
   <extra>
     <Keyboard edit-button="3" edit-modifier="4" delete-button="3" delete-modifier="1" snap-modifier="32"/>
index dfd94ea5af50eba7d40b142fac8394583d0b0ebb..4dfe0b732293f142cf11882ec37954d10d91fc08 100644 (file)
@@ -136,6 +136,7 @@ editor_region_list.cc
 editor_route_list.cc
 editor_rulers.cc
 editor_scrub.cc
+editor_selection.cc
 editor_selection_list.cc
 editor_tempodisplay.cc
 editor_timefx.cc
@@ -326,6 +327,7 @@ env.Alias ('tarball', env.Distribute (env['DISTTREE'],
                                       [ 'SConscript',
                                         'i18n.h', 'gettext.h',
                                        'ardour.sh.in',
+                                       'ardev_common.sh.in',
                                         'ardour2_ui.rc', 'splash.png',
                                         'ardour.menus', 'ardour.bindings', 'ardour.colors',
                                        'editor_xpms'
index 2fe305cf84b8e07e52fe641f75fcd6d0e1e29fd7..d38287858248d8c707c1626bce5f082cbad9d063 100644 (file)
@@ -266,7 +266,7 @@ ActionManager::toggle_config_state (const char* group, const char* action, bool
                
                if (tact) {
                        bool x = (Config->*get)();
-
+                       
                        if (x != tact->get_active()) {
                                (Config->*set) (!x);
                        }
index 3752726c046085688f8914d01de3cb16323ac478..dd749d2bb112a06a9f01f515528b81b8fecd1100 100644 (file)
@@ -226,7 +226,6 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
                TimeSelection ts = s.time;
                RegionSelection ars = s.regions;
        
-       
                for (TrackSelection::iterator i = s.tracks.begin(); i != s.tracks.end(); ++i) {
                        boost::shared_ptr<AudioPlaylist> pl
                                = boost::dynamic_pointer_cast<AudioPlaylist>((*i)->playlist());
@@ -278,7 +277,7 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
                                
                                TimeAxisView *current_axis = (*i);
                                
-                               for (std::set<RegionView *>::iterator j = ars.begin(); j != ars.end(); ++j) {
+                               for (RegionSelection::iterator j = ars.begin(); j != ars.end(); ++j) {
                                        // Check that the region is actually audio (so we can analyze it)
                                        AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*j);
                                        if (!arv)
diff --git a/gtk2_ardour/ardev_common.sh b/gtk2_ardour/ardev_common.sh
deleted file mode 100755 (executable)
index 3cef225..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-cd `dirname "$0"`/..
-
-#export G_DEBUG=fatal_criticals
-
-export ARDOUR_PATH=gtk2_ardour/icons:gtk2_ardour/pixmaps:gtk2_ardour
-export GTK_PATH=libs/clearlooks
-
-
-export LD_LIBRARY_PATH=libs/surfaces/control_protocol:libs/ardour:libs/midi++2:libs/pbd:libs/soundtouch:libs/gtkmm2ext:libs/sigc++2:libs/glibmm2:libs/gtkmm2/atk:libs/gtkmm2/pango:libs/gtkmm2/gdk:libs/gtkmm2/gtk:libs/libgnomecanvasmm:libs/libsndfile:libs/appleutility:$LD_LIBRARY_PATH
-
-# DYLD_LIBRARY_PATH is for darwin.
-export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
-# For the internal clearlooks engine
-export GTK_PATH=$PWD/libs/clearlooks:~/.ardour2
-
-EXECUTABLE=gtk2_ardour/ardour-2.0beta10
index 03ff5ae3312acf07c7ee6751dafc0e09eb7f4722..3c7afcde6ce7f10346fd769d42a48ad771f62b56 100644 (file)
@@ -1,4 +1,4 @@
-; ardour-2.0beta10 GtkAccelMap rc-file         -*- scheme -*-
+; ardour-2.0beta11.1 GtkAccelMap rc-file         -*- scheme -*-
 ; this file is an automated accelerator map dump
 ;
 ; (gtk_accel_path "<Actions>/RegionList/RegionListSort" "")
@@ -62,7 +62,7 @@
 ; (gtk_accel_path "<Actions>/Main/AudioFileFormatData" "")
 ; (gtk_accel_path "<Actions>/options/MeterFalloffFastest" "")
 (gtk_accel_path "<Actions>/Editor/audition-at-mouse" "period")
-(gtk_accel_path "<Actions>/Transport/Forward" "<Control>Right")
+(gtk_accel_path "<Actions>/Transport/Forward" "<Control>rightarrow")
 ; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-seconds" "")
 ; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-frame" "")
 ; (gtk_accel_path "<Actions>/Main/ExportSelection" "")
@@ -70,9 +70,9 @@
 (gtk_accel_path "<Actions>/Editor/editor-paste" "<Control>v")
 (gtk_accel_path "<Actions>/Editor/scroll-tracks-down" "Page_Down")
 ; (gtk_accel_path "<Actions>/Snap/snap-to-smpte-minutes" "")
+; (gtk_accel_path "<Actions>/Main/FlushWastebasket" "")
 (gtk_accel_path "<Actions>/Editor/normalize-region" "n")
 (gtk_accel_path "<Actions>/Editor/nudge-forward" "KP_Add")
-; (gtk_accel_path "<Actions>/Main/FlushWastebasket" "")
 ; (gtk_accel_path "<Actions>/RegionList/SortByRegionEndinFile" "")
 ; (gtk_accel_path "<Actions>/Editor/ToggleMeasureVisibility" "")
 ; (gtk_accel_path "<Actions>/Zoom/zoom-focus-center" "")
@@ -99,6 +99,7 @@
 ; (gtk_accel_path "<Actions>/Editor/addExternalAudioAsTapeTrack" "")
 ; (gtk_accel_path "<Actions>/redirectmenu/paste" "")
 ; (gtk_accel_path "<Actions>/Editor/Smpte25" "")
+; (gtk_accel_path "<Actions>/options/RegionEquivalentsOverlap" "")
 ; (gtk_accel_path "<Actions>/Main/MeteringFallOffRate" "")
 ; (gtk_accel_path "<Actions>/options/UseHardwareMonitoring" "")
 ; (gtk_accel_path "<Actions>/Editor/Smpte24" "")
 (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/ToggleTranzportSurface" "")
 ; (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/RegionEditOps" "")
 ; (gtk_accel_path "<Actions>/Editor/snap-magnetic" "")
 ; (gtk_accel_path "<Actions>/Editor/playhead-to-range-end" "")
+(gtk_accel_path "<Actions>/Editor/scroll-playhead-forward" "<Shift>rightarrow")
 (gtk_accel_path "<Actions>/Editor/align-regions-sync-relative" "a")
 ; (gtk_accel_path "<Actions>/Editor/EditSelectRegionOptions" "")
 (gtk_accel_path "<Actions>/Editor/crop" "c")
 ; (gtk_accel_path "<Actions>/Editor/MeterFalloff" "")
 ; (gtk_accel_path "<Actions>/RegionList/rlRemove" "")
 (gtk_accel_path "<Actions>/Transport/GotoStart" "Home")
+(gtk_accel_path "<Actions>/Editor/scroll-playhead-backward" "<Shift>leftarrow")
 (gtk_accel_path "<Actions>/Editor/split-region" "s")
 ; (gtk_accel_path "<Actions>/Transport/ToggleAutoInput" "")
 ; (gtk_accel_path "<Actions>/Snap/snap-to-thirtyseconds" "")
 ; (gtk_accel_path "<Actions>/options/MeterFalloffMedium" "")
 (gtk_accel_path "<Actions>/Editor/toggle-follow-playhead" "f")
 ; (gtk_accel_path "<Actions>/Main/SaveTemplate" "")
+(gtk_accel_path "<Actions>/Transport/TransitionToRoll" "<Control>uparrow")
 ; (gtk_accel_path "<Actions>/RegionList/SortByRegionStartinFile" "")
 ; (gtk_accel_path "<Actions>/options/GainReduceFastTransport" "")
 ; (gtk_accel_path "<Actions>/Common/ToggleInspector" "")
 ; (gtk_accel_path "<Actions>/Main/Session" "")
 (gtk_accel_path "<Actions>/Editor/edit-cursor-to-range-start" "F1")
 ; (gtk_accel_path "<Actions>/Main/AudioFileFormat" "")
-(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-timefx" "t")
 ; (gtk_accel_path "<Actions>/Transport/Transport" "")
+(gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-timefx" "t")
 ; (gtk_accel_path "<Actions>/RegionList/SortByRegionName" "")
 ; (gtk_accel_path "<Actions>/Main/KeyMouse Actions" "")
 (gtk_accel_path "<Actions>/MouseMode/set-mouse-mode-gain" "g")
 ; (gtk_accel_path "<Actions>/Snap/snap-to-frame" "")
 ; (gtk_accel_path "<Actions>/Editor/SnapTo" "")
+(gtk_accel_path "<Actions>/Transport/TransitionToReverse" "<Control>downarrow")
 ; (gtk_accel_path "<Actions>/Editor/Crossfades" "")
 ; (gtk_accel_path "<Actions>/Editor/PullupPlus4" "")
 (gtk_accel_path "<Actions>/Editor/add-location-from-playhead" "KP_Enter")
 ; (gtk_accel_path "<Actions>/options/FileHeaderFormatWAVE64" "")
 (gtk_accel_path "<Actions>/Editor/brush-at-mouse" "<Control>b")
 ; (gtk_accel_path "<Actions>/RegionList/rlShowAll" "")
-(gtk_accel_path "<Actions>/Transport/Rewind" "<Control>Left")
+(gtk_accel_path "<Actions>/Transport/Rewind" "<Control>leftarrow")
 ; (gtk_accel_path "<Actions>/RegionList/SortByRegionTimestamp" "")
 ; (gtk_accel_path "<Actions>/options/VerifyRemoveLastCapture" "")
 ; (gtk_accel_path "<Actions>/options/OutputAutoConnectPhysical" "")
index cf56e2ad9fe4c5d906032f26b73606bbe4b41c11..040c6464c1ba5c16fe18c1a8554e92779a503d34 100644 (file)
@@ -47,6 +47,9 @@
               <separator/>
                <menuitem action='Record'/>
                <separator/> 
+               <menuitem action='TransitionToRoll'/>
+               <menuitem action='TransitionToReverse'/>
+               <separator/> 
                <menuitem action='jump-forward-to-mark'/>
                <menuitem action='jump-backward-to-mark'/>
                <menuitem action='add-location-from-playhead'/>
                <menuitem action='scroll-forward'/>
                <menuitem action='scroll-backward'/>
               <separator/>
+               <menuitem action='scroll-playhead-forward'/>
+               <menuitem action='scroll-playhead-backward'/>
+              <separator/>
                <menuitem action='ToggleWaveformVisibility'/>
                <menuitem action='ToggleWaveformsWhileRecording'/>
                <menuitem action='ToggleMeasureVisibility'/>
                <menuitem action='StopPluginsWithTransport'/>
                <menuitem action='DoNotRunPluginsWhileRecording'/>
                <menuitem action='LatchedRecordEnable'/>
+               <menuitem action='RegionEquivalentsOverlap'/>
                <separator/>
                <menuitem action='VerifyRemoveLastCapture'/>
                <menuitem action='StopRecordingOnXrun'/>
index a450e6d7dc94f633b2ffba0aea8f457be8cff4b7..7d033680761a6a5f55ea017415d523dd1489bd5e 100644 (file)
@@ -323,6 +323,17 @@ style "ardour_adjusters" = "default_buttons_menus"
        bg[ACTIVE] = { 0.06, 0.06, 0.06 }
 }
 
+style "editor_hscrollbar" = "ardour_adjusters"
+{
+       #
+       # special case: we want this scrollbar to be as tall as the
+       # zoom focus selector combobox. scrollbars don't expand to
+        # fill the space available to them, so we have to explicitly
+       # make it bigger.
+       # 
+       GtkRange::slider_width = 27
+}
+
 style "ardour_progressbars" = "default_buttons_menus"
 { 
   bg[NORMAL] = { 0, 0, 0 }
@@ -1372,6 +1383,7 @@ widget "*PanningLinkDirectionButton.*" style "very_small_button"
 widget "*ChannelCountSelector" style "medium_bold_entry"
 widget "*ChannelCountSelector.GtkArrow" style "default_buttons_menus"
 widget "*RegionListWholeFile" style "treeview_parent_node"
+widget "*EditorHScrollbar" style "editor_hscrollbar"
 
 class "GtkWidget" style "default_base"
 class "GtkScrollbar" style "ardour_adjusters"
index 92f2cc103d9187c800c463ea99004b74fd9fab56..45a795dec38320ebd6fd2a5363a7c88f5d360bd5 100644 (file)
@@ -659,6 +659,7 @@ class ARDOUR_UI : public Gtkmm2ext::UI
        void toggle_GainReduceFastTransport();
        void toggle_LatchedSolo();
        void toggle_LatchedRecordEnable ();
+       void toggle_RegionEquivalentsOverlap ();
 
        void mtc_port_changed ();
        void map_solo_model ();
index df2fda78c94de70556ec8c9185a0096851f59477..b6e31d12d821ac098114e0566270ef6b391ffd66 100644 (file)
@@ -237,6 +237,22 @@ ARDOUR_UI::install_actions ()
        ActionManager::register_action (transport_actions, X_("ToggleRollForgetCapture"), _("Stop + Forget Capture"), bind (mem_fun(*editor, &PublicEditor::toggle_playback), true));
        ActionManager::session_sensitive_actions.push_back (act);
        ActionManager::transport_sensitive_actions.push_back (act);
+
+       /* these two behave as follows:
+
+          - if transport speed != 1.0 or != -1.0, change speed to 1.0 or -1.0 (respectively)
+          - otherwise do nothing
+       */
+
+       ActionManager::register_action (transport_actions, X_("TransitionToRoll"), _("Transition To Roll"), bind (mem_fun (*editor, &PublicEditor::transition_to_rolling), true));
+       ActionManager::session_sensitive_actions.push_back (act);
+       ActionManager::session_sensitive_actions.push_back (act);
+
+       ActionManager::register_action (transport_actions, X_("TransitionToReverse"), _("Transition To Reverse"), bind (mem_fun (*editor, &PublicEditor::transition_to_rolling), false));
+       ActionManager::session_sensitive_actions.push_back (act);
+       ActionManager::session_sensitive_actions.push_back (act);
+
+
        act = ActionManager::register_action (transport_actions, X_("Loop"), _("Play Loop Range"), mem_fun(*this, &ARDOUR_UI::toggle_session_auto_loop));
        ActionManager::session_sensitive_actions.push_back (act);
        ActionManager::transport_sensitive_actions.push_back (act);
@@ -387,6 +403,7 @@ ARDOUR_UI::install_actions ()
        ActionManager::register_toggle_action (option_actions, X_("StopTransportAtEndOfSession"), _("Stop transport at session end"), mem_fun (*this, &ARDOUR_UI::toggle_StopTransportAtEndOfSession));
        ActionManager::register_toggle_action (option_actions, X_("GainReduceFastTransport"), _("-12dB gain reduce ffwd/rewind"), mem_fun (*this, &ARDOUR_UI::toggle_GainReduceFastTransport));
        ActionManager::register_toggle_action (option_actions, X_("LatchedRecordEnable"), _("Rec-enable stays engaged at stop"), mem_fun (*this, &ARDOUR_UI::toggle_LatchedRecordEnable));
+       ActionManager::register_toggle_action (option_actions, X_("RegionEquivalentsOverlap"), _("Region equivalents overlap"), mem_fun (*this, &ARDOUR_UI::toggle_RegionEquivalentsOverlap));
 
        act = ActionManager::register_toggle_action (option_actions, X_("DoNotRunPluginsWhileRecording"), _("Do not run plugins while recording"), mem_fun (*this, &ARDOUR_UI::toggle_DoNotRunPluginsWhileRecording));
        ActionManager::session_sensitive_actions.push_back (act);
index d0f523481f24485ffd8cc87414dee302c8aeda58..5674d6dee1099e8da27b024ca721544341b9ee06 100644 (file)
@@ -19,6 +19,7 @@
 */
 
 #include <pbd/convert.h>
+#include <pbd/stacktrace.h>
 
 #include <gtkmm2ext/utils.h>
 
@@ -101,6 +102,9 @@ ARDOUR_UI::set_native_file_header_format (HeaderFormat hf)
        case AIFF:
                action = X_("FileHeaderFormatAIFF");
                break;
+       default:
+               fatal << string_compose (_("programming error: %1"), "illegal file header format in ::set_native_file_header_format") << endmsg;
+               /*NOTREACHED*/  
        }
 
        Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
@@ -125,6 +129,9 @@ ARDOUR_UI::set_native_file_data_format (SampleFormat sf)
        case FormatInt24:
                action = X_("FileDataFormat24bit");
                break;
+       default:
+               fatal << string_compose (_("programming error: %1"), "illegal file data format in ::set_native_file_data_format") << endmsg;
+               /*NOTREACHED*/
        }
 
        Glib::RefPtr<Action> act = ActionManager::get_action ("options", action);
@@ -340,6 +347,12 @@ ARDOUR_UI::toggle_LatchedRecordEnable()
        ActionManager::toggle_config_state ("options", "LatchedRecordEnable", &Configuration::set_latched_record_enable, &Configuration::get_latched_record_enable);
 }
 
+void
+ARDOUR_UI::toggle_RegionEquivalentsOverlap()
+{
+       ActionManager::toggle_config_state ("options", "RegionEquivalentsOverlap", &Configuration::set_use_overlap_equivalency, &Configuration::get_use_overlap_equivalency);
+}
+
 void
 ARDOUR_UI::toggle_DoNotRunPluginsWhileRecording()
 {
@@ -737,6 +750,8 @@ ARDOUR_UI::set_meter_falloff (MeterFalloff val)
 void
 ARDOUR_UI::parameter_changed (const char* parameter_name)
 {
+       ENSURE_GUI_THREAD (bind (mem_fun (*this, &ARDOUR_UI::parameter_changed), parameter_name));
+
 #define PARAM_IS(x) (!strcmp (parameter_name, (x)))
        
        if (PARAM_IS ("slave-source")) {
@@ -846,7 +861,10 @@ ARDOUR_UI::parameter_changed (const char* parameter_name)
                        primary_clock.set (0, true);
                        secondary_clock.set (0, true);
                }
+       } else if (PARAM_IS ("use-overlap-equivalency")) {
+               ActionManager::map_some_state ("options", "RegionEquivalentsOverlap", &Configuration::get_use_overlap_equivalency);
        }
+                          
 
 #undef PARAM_IS
 }
index 66822289c2870e7073fa00b4a324b76cf058bcd8..481e91b09a052779c4c77c45edbf84e2ce872fe1 100644 (file)
@@ -768,6 +768,17 @@ AudioClock::field_key_release_event (GdkEventKey *ev, Field field)
                                // Check SMPTE fields for sanity (may also adjust fields)
                                smpte_sanitize_display();
                                break;
+                       case Bars:
+                       case Beats:
+                       case Ticks:
+                               // Bars or beats should never be 0
+                               if (atoi(bars_label.get_text()) == 0) {
+                                       bars_label.set_text("001");
+                               }
+                               if (atoi(beats_label.get_text()) == 0) {
+                                       beats_label.set_text("01");
+                               }
+                               break;
                        default:
                                break;
                        }
index e91dd529e3a0de171fbab4d74d0bf591ec6c6f83..4bded299b443408c1a6310fddcdca26156b59915 100644 (file)
@@ -247,55 +247,6 @@ AudioRegionView::fade_out_changed ()
 {
        reset_fade_out_shape ();
 }
-
-void
-AudioRegionView::set_fade_in_shape (AudioRegion::FadeShape shape)
-{
-       AutomationList& alist = audio_region()->fade_in();
-       XMLNode& before (alist.get_state());
-       trackview.session().begin_reversible_command ("fade in shape");
-       audio_region()->set_fade_in_shape (shape);
-       XMLNode& after (alist.get_state());
-       trackview.session().add_command (new MementoCommand<AutomationList>(alist, &before, &after));
-       trackview.session().commit_reversible_command ();
-}
-
-void
-AudioRegionView::set_fade_out_shape (AudioRegion::FadeShape shape)
-{
-       AutomationList& alist = audio_region()->fade_out();
-       XMLNode& before (alist.get_state());
-       trackview.session().begin_reversible_command ("fade out shape");
-       audio_region()->set_fade_out_shape (shape);
-       XMLNode& after (alist.get_state());
-       trackview.session().add_command (new MementoCommand<AutomationList>(alist, &before, &after));
-       trackview.session().commit_reversible_command ();
-}
-
-void
-AudioRegionView::set_fade_in_active (bool yn)
-{
-       AutomationList& alist = audio_region()->fade_in();
-       XMLNode& before (alist.get_state());
-       trackview.session().begin_reversible_command ("fade in shape");
-       audio_region()->set_fade_in_active (yn);
-       XMLNode& after (alist.get_state());
-       trackview.session().add_command (new MementoCommand<AutomationList>(alist, &before, &after));
-       trackview.session().commit_reversible_command ();
-}
-
-void
-AudioRegionView::set_fade_out_active (bool yn)
-{
-       AutomationList& alist = audio_region()->fade_out();
-       XMLNode& before (alist.get_state());
-       trackview.session().begin_reversible_command ("fade out shape");
-       audio_region()->set_fade_out_active (yn);
-       XMLNode& after (alist.get_state());
-       trackview.session().add_command (new MementoCommand<AutomationList>(alist, &before, &after));
-       trackview.session().commit_reversible_command ();
-}
-
 void
 AudioRegionView::fade_in_active_changed ()
 {
@@ -808,7 +759,7 @@ AudioRegionView::create_waves ()
        for (uint32_t n = 0; n < nchans; ++n) {
                tmp_waves.push_back (0);
        }
-       
+
        for (uint32_t n = 0; n < nchans; ++n) {
                
                if (n >= audio_region()->n_channels()) {
@@ -899,7 +850,7 @@ AudioRegionView::create_one_wave (uint32_t which, bool direct)
                        break;
                }
        }
-       
+
        if (n == nwaves && waves.empty()) {
                /* all waves are ready */
                tmp_waves.resize(nwaves);
index 1d51cb7172b852ab94926574aa387e2ba6aa6cfb..a59972b807c90e903735a4ff9f700d7f6aa69ad0 100644 (file)
@@ -93,10 +93,6 @@ class AudioRegionView : public RegionView
        
        void reset_fade_in_shape_width (nframes_t);
        void reset_fade_out_shape_width (nframes_t);
-       void set_fade_in_active (bool);
-       void set_fade_out_active (bool);
-       void set_fade_in_shape (ARDOUR::AudioRegion::FadeShape);
-       void set_fade_out_shape (ARDOUR::AudioRegion::FadeShape);
 
        virtual void entered ();
        virtual void exited ();
index d0898d32f4fc5a48bf850d002eeeb138a5ab9661..d12fa70fed539fee78c95f0d3c0d009e7bfda9c8 100644 (file)
@@ -48,6 +48,8 @@
 #include "utils.h"
 #include "color.h"
 
+#include "i18n.h"
+
 using namespace ARDOUR;
 using namespace PBD;
 using namespace Editing;
@@ -129,7 +131,7 @@ AudioStreamView::set_amplitude_above_axis (gdouble app)
 void
 AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wait_for_waves)
 {
-       AudioRegionView *region_view;
+       AudioRegionView *region_view = 0;
 
        ENSURE_GUI_THREAD (bind (mem_fun (*this, &AudioStreamView::add_region_view), r));
 
@@ -166,6 +168,10 @@ AudioStreamView::add_region_view_internal (boost::shared_ptr<Region> r, bool wai
                region_view = new TapeAudioRegionView (canvas_group, _trackview, region, 
                                                       _samples_per_unit, region_color);
                break;
+       default:
+               fatal << string_compose (_("programming error: %1"), "illegal track mode in ::add_region_view_internal") << endmsg;
+               /*NOTREACHED*/
+
        }
 
        region_view->init (region_color, wait_for_waves);
index 1dc62f1f42682eabf3240a31c1cfd00f1ab4b4fe..55986898555fdf5c3f19e48e3a42518a0343cd2d 100644 (file)
@@ -642,11 +642,10 @@ AutomationLine::determine_visible_control_points (ALPoints& points)
  
                if (view_index && pi != npoints && /* not the first, not the last */
                    (((this_rx == prev_rx) && (this_ry == prev_ry)) || /* same point */
-                    (this_rx == prev_rx) || /* identical x coordinate */
                     (((this_rx - prev_rx) < (box_size + 2)) &&  /* not identical, but still too close horizontally */
-                     ((abs ((int)(this_ry - prev_ry)) < (int) (box_size + 2)))))) { /* too close vertically */
+                     (abs ((int)(this_ry - prev_ry)) < (int) (box_size + 2))))) { /* too close vertically */
                        continue;
-               }
+               } 
 
                /* ok, we should display this point */
 
index 5b7f4d57055eafb38a7772b98ad0d67aeeb0faeb..2ce8f29a701ef4bb0a3c0a23ed53fadc503e2042 100644 (file)
@@ -16,6 +16,14 @@ struct AutomationSelectable : public Selectable
 
     AutomationSelectable (nframes_t s, nframes_t e, double l, double h, TimeAxisView& atv)
            : start (s), end (e), low_fract (l), high_fract (h), track (atv) {}
+
+    bool operator== (const AutomationSelectable& other) {
+           return start == other.start &&
+                   end == other.end &&
+                   low_fract == other.low_fract &&
+                   high_fract == other.high_fract &&
+                   &track == &other.track;
+    }
 };
 
 #endif /* __ardour_gtk_automation_selectable_h__ */
index 776dff37f21c8e49b815342e96b8ff2708ac2fa3..c3f53d266c5740ea6d119a9ee1bda5852cad1c56 100644 (file)
@@ -573,7 +573,7 @@ AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointS
                case Cut:
                        if ((what_we_got = alist.cut ((*i).start, (*i).end)) != 0) {
                                editor.get_cut_buffer().add (what_we_got);
-                               _session.add_command (new MementoCommand<AutomationList>(alist, &before, &alist.get_state()));
+                               _session.add_command (new MementoCommand<AutomationList>(alist, new XMLNode (before), &alist.get_state()));
                                ret = true;
                        }
                        break;
@@ -585,7 +585,7 @@ AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointS
                        
                case Clear:
                        if ((what_we_got = alist.cut ((*i).start, (*i).end)) != 0) {
-                               _session.add_command (new MementoCommand<AutomationList>(alist, &before, &alist.get_state()));
+                               _session.add_command (new MementoCommand<AutomationList>(alist, new XMLNode (before), &alist.get_state()));
                                delete what_we_got;
                                what_we_got = 0;
                                ret = true;
@@ -593,7 +593,9 @@ AutomationTimeAxisView::cut_copy_clear_objects_one (AutomationLine& line, PointS
                        break;
                }
        }
-               
+
+       delete &before;
+
        if (what_we_got) {
                for (AutomationList::iterator x = what_we_got->begin(); x != what_we_got->end(); ++x) {
                        double foo = (*x)->value;
index a80de0a8f41e5539c8b4f08a7600734dd64b65c8..0f77f157f63f78cc228697ac2b68515c4d737f10 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <pbd/convert.h>
 #include <pbd/error.h>
+#include <pbd/stacktrace.h>
 #include <pbd/memento_command.h>
 
 #include <gtkmm/image.h>
@@ -359,6 +360,8 @@ Editor::Editor (AudioEngine& eng)
        edit_hscrollbar.signal_button_release_event().connect (mem_fun(*this, &Editor::hscrollbar_button_release));
        edit_hscrollbar.signal_size_allocate().connect (mem_fun(*this, &Editor::hscrollbar_allocate));
 
+       edit_hscrollbar.set_name ("EditorHScrollbar");
+
        build_cursors ();
        setup_toolbar ();
 
@@ -1230,35 +1233,35 @@ Editor::popup_fade_context_menu (int button, int32_t time, ArdourCanvas::Item* i
        case FadeInItem:
        case FadeInHandleItem:
                if (arv->audio_region()->fade_in_active()) {
-                       items.push_back (MenuElem (_("Deactivate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_active), false)));
+                       items.push_back (MenuElem (_("Deactivate"), bind (mem_fun (*this, &Editor::set_fade_in_active), false)));
                } else {
-                       items.push_back (MenuElem (_("Activate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_active), true)));
+                       items.push_back (MenuElem (_("Activate"), bind (mem_fun (*this, &Editor::set_fade_in_active), true)));
                }
                
                items.push_back (SeparatorElem());
                
-               items.push_back (MenuElem (_("Linear"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_shape), AudioRegion::Linear)));
-               items.push_back (MenuElem (_("Slowest"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_shape), AudioRegion::LogB)));
-               items.push_back (MenuElem (_("Slow"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_shape), AudioRegion::Fast)));
-               items.push_back (MenuElem (_("Fast"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_shape), AudioRegion::LogA)));
-               items.push_back (MenuElem (_("Fastest"), bind (mem_fun (*arv, &AudioRegionView::set_fade_in_shape), AudioRegion::Slow)));
+               items.push_back (MenuElem (_("Linear"), bind (mem_fun (*this, &Editor::set_fade_in_shape), AudioRegion::Linear)));
+               items.push_back (MenuElem (_("Slowest"), bind (mem_fun (*this, &Editor::set_fade_in_shape), AudioRegion::LogB)));
+               items.push_back (MenuElem (_("Slow"), bind (mem_fun (*this, &Editor::set_fade_in_shape), AudioRegion::Fast)));
+               items.push_back (MenuElem (_("Fast"), bind (mem_fun (*this, &Editor::set_fade_in_shape), AudioRegion::LogA)));
+               items.push_back (MenuElem (_("Fastest"), bind (mem_fun (*this, &Editor::set_fade_in_shape), AudioRegion::Slow)));
                break;
 
        case FadeOutItem:
        case FadeOutHandleItem:
                if (arv->audio_region()->fade_out_active()) {
-                       items.push_back (MenuElem (_("Deactivate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_active), false)));
+                       items.push_back (MenuElem (_("Deactivate"), bind (mem_fun (*this, &Editor::set_fade_out_active), false)));
                } else {
-                       items.push_back (MenuElem (_("Activate"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_active), true)));
+                       items.push_back (MenuElem (_("Activate"), bind (mem_fun (*this, &Editor::set_fade_out_active), true)));
                }
                
                items.push_back (SeparatorElem());
                
-               items.push_back (MenuElem (_("Linear"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_shape), AudioRegion::Linear)));
-               items.push_back (MenuElem (_("Slowest"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_shape), AudioRegion::Fast)));
-               items.push_back (MenuElem (_("Slow"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_shape), AudioRegion::LogB)));
-               items.push_back (MenuElem (_("Fast"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_shape), AudioRegion::LogA)));
-               items.push_back (MenuElem (_("Fastest"), bind (mem_fun (*arv, &AudioRegionView::set_fade_out_shape), AudioRegion::Slow)));
+               items.push_back (MenuElem (_("Linear"), bind (mem_fun (*this, &Editor::set_fade_out_shape), AudioRegion::Linear)));
+               items.push_back (MenuElem (_("Slowest"), bind (mem_fun (*this, &Editor::set_fade_out_shape), AudioRegion::Fast)));
+               items.push_back (MenuElem (_("Slow"), bind (mem_fun (*this, &Editor::set_fade_out_shape), AudioRegion::LogB)));
+               items.push_back (MenuElem (_("Fast"), bind (mem_fun (*this, &Editor::set_fade_out_shape), AudioRegion::LogA)));
+               items.push_back (MenuElem (_("Fastest"), bind (mem_fun (*this, &Editor::set_fade_out_shape), AudioRegion::Slow)));
 
                break;
 
@@ -1606,7 +1609,7 @@ Editor::add_region_context_items (AudioStreamView* sv, boost::shared_ptr<Region>
           become selected.
        */
 
-       // region_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
+       region_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
 
        items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
        items.push_back (MenuElem (_("Raise to top layer"), mem_fun(*this, &Editor::raise_region_to_top)));
@@ -2541,7 +2544,7 @@ Editor::setup_toolbar ()
        zoom_out_full_button.add (*(manage (new Image (::get_icon("zoom_full")))));
        zoom_out_full_button.signal_clicked().connect (mem_fun(*this, &Editor::temporal_zoom_session));
        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, "Edit Cursor", FUDGE, 0);
        set_popdown_strings (zoom_focus_selector, zoom_focus_strings);
@@ -2777,543 +2780,6 @@ Editor::commit_reversible_command ()
        }
 }
 
-struct TrackViewByPositionSorter
-{
-    bool operator() (const TimeAxisView* a, const TimeAxisView *b) {
-           return a->y_position < b->y_position;
-    }
-};
-
-bool
-Editor::extend_selection_to_track (TimeAxisView& view)
-{
-       if (selection->selected (&view)) {
-               /* already selected, do nothing */
-               return false;
-       }
-
-       if (selection->tracks.empty()) {
-
-               if (!selection->selected (&view)) {
-                       selection->set (&view);
-                       return true;
-               } else {
-                       return false;
-               }
-       } 
-
-       /* something is already selected, so figure out which range of things to add */
-       
-       TrackViewList to_be_added;
-       TrackViewList sorted = track_views;
-       TrackViewByPositionSorter cmp;
-       bool passed_clicked = false;
-       bool forwards;
-
-       sorted.sort (cmp);
-
-       if (!selection->selected (&view)) {
-               to_be_added.push_back (&view);
-       }
-
-       /* figure out if we should go forward or backwards */
-
-       for (TrackViewList::iterator i = sorted.begin(); i != sorted.end(); ++i) {
-
-               if ((*i) == &view) {
-                       passed_clicked = true;
-               }
-
-               if (selection->selected (*i)) {
-                       if (passed_clicked) {
-                               forwards = true;
-                       } else {
-                               forwards = false;
-                       }
-                       break;
-               }
-       }
-                       
-       passed_clicked = false;
-
-       if (forwards) {
-
-               for (TrackViewList::iterator i = sorted.begin(); i != sorted.end(); ++i) {
-                                       
-                       if ((*i) == &view) {
-                               passed_clicked = true;
-                               continue;
-                       }
-                                       
-                       if (passed_clicked) {
-                               if ((*i)->hidden()) {
-                                       continue;
-                               }
-                               if (selection->selected (*i)) {
-                                       break;
-                               } else if (!(*i)->hidden()) {
-                                       to_be_added.push_back (*i);
-                               }
-                       }
-               }
-
-       } else {
-
-               for (TrackViewList::reverse_iterator r = sorted.rbegin(); r != sorted.rend(); ++r) {
-                                       
-                       if ((*r) == &view) {
-                               passed_clicked = true;
-                               continue;
-                       }
-                                       
-                       if (passed_clicked) {
-                                               
-                               if ((*r)->hidden()) {
-                                       continue;
-                               }
-                                               
-                               if (selection->selected (*r)) {
-                                       break;
-                               } else if (!(*r)->hidden()) {
-                                       to_be_added.push_back (*r);
-                               }
-                       }
-               }
-       }
-                       
-       if (!to_be_added.empty()) {
-               selection->add (to_be_added);
-               return true;
-       }
-       
-       return false;
-}
-
-
-bool
-Editor::set_selected_track (TimeAxisView& view, Selection::Operation op, bool no_remove)
-{
-       bool commit = false;
-
-       switch (op) {
-       case Selection::Toggle:
-               if (selection->selected (&view)) {
-                       if (!no_remove) {
-                               selection->remove (&view);
-                               commit = true;
-                       }
-               } else {
-                       selection->add (&view);
-                       commit = false;
-               }
-               break;
-
-       case Selection::Add:
-               if (!selection->selected (&view)) {
-                       selection->add (&view);
-                       commit = true;
-               }
-               break;
-
-       case Selection::Set:
-               if (selection->selected (&view) && selection->tracks.size() == 1) {
-                       /* no commit necessary */
-               } else {
-                       selection->set (&view);
-                       commit = true;
-               }
-               break;
-               
-       case Selection::Extend:
-               commit = extend_selection_to_track (view);
-               break;
-       }
-
-       return commit;
-}
-
-bool
-Editor::set_selected_track_from_click (Selection::Operation op, bool no_remove)
-{
-       if (!clicked_routeview) {
-               return false;
-       }
-       
-       return set_selected_track (*clicked_routeview, op, no_remove);
-}
-
-bool
-Editor::set_selected_control_point_from_click (Selection::Operation op, bool no_remove)
-{
-       if (!clicked_control_point) {
-               return false;
-       }
-
-       /* select this point and any others that it represents */
-
-       double y1, y2;
-       nframes_t x1, x2;
-
-       x1 = pixel_to_frame (clicked_control_point->get_x() - 10);
-       x2 = pixel_to_frame (clicked_control_point->get_x() + 10);
-       y1 = clicked_control_point->get_x() - 10;
-       y2 = clicked_control_point->get_y() + 10;
-
-       return select_all_within (x1, x2, y1, y2, op);
-}
-
-void
-Editor::get_relevant_tracks (set<RouteTimeAxisView*>& relevant_tracks)
-{
-       /* step one: get all selected tracks and all tracks in the relevant edit groups */
-
-       for (TrackSelection::iterator ti = selection->tracks.begin(); ti != selection->tracks.end(); ++ti) {
-
-               RouteTimeAxisView* atv = dynamic_cast<RouteTimeAxisView*>(*ti);
-
-               if (!atv) {
-                       continue;
-               }
-
-               RouteGroup* group = atv->route()->edit_group();
-
-               if (group && group->is_active()) {
-                       
-                       /* active group for this track, loop over all tracks and get every member of the group */
-
-                       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-                               
-                               RouteTimeAxisView* tatv;
-                               
-                               if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
-                                       
-                                       if (tatv->route()->edit_group() == group) {
-                                               relevant_tracks.insert (tatv);
-                                       }
-                               }
-                       }
-               } else {
-                       relevant_tracks.insert (atv);
-               }
-       }
-}
-
-void
-Editor::mapover_tracks (slot<void,RouteTimeAxisView&,uint32_t> sl)
-{
-       set<RouteTimeAxisView*> relevant_tracks;
-
-       get_relevant_tracks (relevant_tracks);
-
-       uint32_t sz = relevant_tracks.size();
-
-       for (set<RouteTimeAxisView*>::iterator ati = relevant_tracks.begin(); ati != relevant_tracks.end(); ++ati) {
-               sl (**ati, sz);
-       }
-}
-
-void
-Editor::mapped_set_selected_regionview_from_click (RouteTimeAxisView& tv, uint32_t ignored, 
-                                                  RegionView* basis, vector<RegionView*>* all_equivs)
-{
-       boost::shared_ptr<Playlist> pl;
-       vector<boost::shared_ptr<Region> > results;
-       RegionView* marv;
-       boost::shared_ptr<Diskstream> ds;
-
-       if ((ds = tv.get_diskstream()) == 0) {
-               /* bus */
-               return;
-       }
-
-       if (&tv == &basis->get_time_axis_view()) {
-               /* looking in same track as the original */
-               return;
-       }
-
-       
-       if ((pl = ds->playlist()) != 0) {
-               pl->get_equivalent_regions (basis->region(), results);
-       }
-       
-       for (vector<boost::shared_ptr<Region> >::iterator ir = results.begin(); ir != results.end(); ++ir) {
-               if ((marv = tv.view()->find_view (*ir)) != 0) {
-                       all_equivs->push_back (marv);
-               }
-       }
-}
-
-bool
-Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, bool no_track_remove)
-{
-       vector<RegionView*> all_equivalent_regions;
-       bool commit = false;
-
-       if (!clicked_regionview || !clicked_routeview) {
-               return false;
-       }
-
-       if (op == Selection::Toggle || op == Selection::Set) {
-               
-               mapover_tracks (bind (mem_fun (*this, &Editor::mapped_set_selected_regionview_from_click), 
-                                           clicked_regionview, &all_equivalent_regions));
-               
-               
-               /* add clicked regionview since we skipped all other regions in the same track as the one it was in */
-               
-               all_equivalent_regions.push_back (clicked_regionview);
-               
-               switch (op) {
-               case Selection::Toggle:
-                       
-                       if (clicked_regionview->get_selected()) {
-                               if (press) {
-
-                                       /* whatever was clicked was selected already; do nothing here but allow
-                                          the button release to deselect it
-                                       */
-
-                                       button_release_can_deselect = true;
-
-                               } else {
-
-                                       if (button_release_can_deselect) {
-
-                                               /* just remove this one region, but only on a permitted button release */
-
-                                               selection->remove (clicked_regionview);
-                                               commit = true;
-
-                                               /* no more deselect action on button release till a new press
-                                                  finds an already selected object.
-                                               */
-
-                                               button_release_can_deselect = false;
-                                       }
-                               } 
-
-                       } else {
-
-                               if (press) {
-                                       /* add all the equivalent regions, but only on button press */
-                                       
-                                       if (!all_equivalent_regions.empty()) {
-                                               commit = true;
-                                       }
-                                       
-                                       for (vector<RegionView*>::iterator i = all_equivalent_regions.begin(); i != all_equivalent_regions.end(); ++i) {
-                                               selection->add (*i);
-                                       }
-                               } 
-                       }
-                       break;
-                       
-               case Selection::Set:
-                       if (!clicked_regionview->get_selected()) {
-                               selection->set (all_equivalent_regions);
-                               commit = true;
-                       } else {
-                               /* no commit necessary: clicked on an already selected region */
-                               goto out;
-                       }
-                       break;
-
-               default:
-                       /* silly compiler */
-                       break;
-               }
-
-       } else if (op == Selection::Extend) {
-
-               list<Selectable*> results;
-               nframes_t last_frame;
-               nframes_t first_frame;
-
-               /* 1. find the last selected regionview in the track that was clicked in */
-
-               last_frame = 0;
-               first_frame = max_frames;
-
-               for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
-                       if (&(*x)->get_time_axis_view() == &clicked_regionview->get_time_axis_view()) {
-
-                               if ((*x)->region()->last_frame() > last_frame) {
-                                       last_frame = (*x)->region()->last_frame();
-                               }
-
-                               if ((*x)->region()->first_frame() < first_frame) {
-                                       first_frame = (*x)->region()->first_frame();
-                               }
-                       }
-               }
-
-               /* 2. figure out the boundaries for our search for new objects */
-
-               switch (clicked_regionview->region()->coverage (first_frame, last_frame)) {
-               case OverlapNone:
-                       if (last_frame < clicked_regionview->region()->first_frame()) {
-                               first_frame = last_frame;
-                               last_frame = clicked_regionview->region()->last_frame();
-                       } else {
-                               last_frame = first_frame;
-                               first_frame = clicked_regionview->region()->first_frame();
-                       }
-                       break;
-
-               case OverlapExternal:
-                       if (last_frame < clicked_regionview->region()->first_frame()) {
-                               first_frame = last_frame;
-                               last_frame = clicked_regionview->region()->last_frame();
-                       } else {
-                               last_frame = first_frame;
-                               first_frame = clicked_regionview->region()->first_frame();
-                       }
-                       break;
-
-               case OverlapInternal:
-                       if (last_frame < clicked_regionview->region()->first_frame()) {
-                               first_frame = last_frame;
-                               last_frame = clicked_regionview->region()->last_frame();
-                       } else {
-                               last_frame = first_frame;
-                               first_frame = clicked_regionview->region()->first_frame();
-                       }
-                       break;
-
-               case OverlapStart:
-               case OverlapEnd:
-                       /* nothing to do except add clicked region to selection, since it
-                          overlaps with the existing selection in this track.
-                       */
-                       break;
-               }
-
-               /* 2. find all selectable objects (regionviews in this case) between that one and the end of the
-                     one that was clicked.
-               */
-
-               set<RouteTimeAxisView*> relevant_tracks;
-               
-               get_relevant_tracks (relevant_tracks);
-               
-               for (set<RouteTimeAxisView*>::iterator t = relevant_tracks.begin(); t != relevant_tracks.end(); ++t) {
-                       (*t)->get_selectables (first_frame, last_frame, -1.0, -1.0, results);
-               }
-               
-               /* 3. convert to a vector of audio regions */
-
-               vector<RegionView*> regions;
-               
-               for (list<Selectable*>::iterator x = results.begin(); x != results.end(); ++x) {
-                       RegionView* arv;
-
-                       if ((arv = dynamic_cast<RegionView*>(*x)) != 0) {
-                               regions.push_back (arv);
-                       }
-               }
-
-               if (!regions.empty()) {
-                       selection->add (regions);
-                       commit = true;
-               }
-       }
-
-  out:
-       return commit;
-}
-
-void
-Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> region, Selection::Operation op)
-{
-       vector<RegionView*> all_equivalent_regions;
-
-       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-               
-               RouteTimeAxisView* tatv;
-               
-               if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
-                       
-                       boost::shared_ptr<Playlist> pl;
-                       vector<boost::shared_ptr<Region> > results;
-                       RegionView* marv;
-                       boost::shared_ptr<Diskstream> ds;
-                       
-                       if ((ds = tatv->get_diskstream()) == 0) {
-                               /* bus */
-                               continue;
-                       }
-                       
-                       if ((pl = (ds->playlist())) != 0) {
-                               pl->get_region_list_equivalent_regions (region, results);
-                       }
-                       
-                       for (vector<boost::shared_ptr<Region> >::iterator ir = results.begin(); ir != results.end(); ++ir) {
-                               if ((marv = tatv->view()->find_view (*ir)) != 0) {
-                                       all_equivalent_regions.push_back (marv);
-                               }
-                       }
-                       
-               }
-       }
-       
-       begin_reversible_command (_("set selected regions"));
-       
-       switch (op) {
-       case Selection::Toggle:
-               /* XXX this is not correct */
-               selection->toggle (all_equivalent_regions);
-               break;
-       case Selection::Set:
-               selection->set (all_equivalent_regions);
-               break;
-       case Selection::Extend:
-               selection->add (all_equivalent_regions);
-               break;
-       case Selection::Add:
-               selection->add (all_equivalent_regions);
-               break;
-       }
-
-       commit_reversible_command () ;
-}
-
-bool
-Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv, boost::weak_ptr<Region> weak_r)
-{
-       RegionView* rv;
-       boost::shared_ptr<Region> r (weak_r.lock());
-
-       if (!r) {
-               return true;
-       }
-
-       boost::shared_ptr<AudioRegion> ar;
-
-       if ((ar = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
-               return true;
-       }
-
-       if ((rv = sv->find_view (ar)) == 0) {
-               return true;
-       }
-
-       /* don't reset the selection if its something other than 
-          a single other region.
-       */
-
-       if (selection->regions.size() > 1) {
-               return true;
-       }
-       
-       begin_reversible_command (_("set selected regions"));
-       
-       selection->set (rv);
-
-       commit_reversible_command () ;
-
-       return true;
-}
-
 void
 Editor::set_edit_group_solo (Route& route, bool yn)
 {
@@ -3571,82 +3037,16 @@ Editor::edit_controls_button_release (GdkEventButton* ev)
        return TRUE;
 }
 
-void
-Editor::track_selection_changed ()
-{
-       switch (selection->tracks.size()){
-       case 0:
-               break;
-       default:
-               set_selected_mixer_strip (*(selection->tracks.front()));
-               break;
-       }
-
-       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-               (*i)->set_selected (false);
-               if (mouse_mode == MouseRange) {
-                       (*i)->hide_selection ();
-               }
-       }
-
-       for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
-               (*i)->set_selected (true);
-               if (mouse_mode == MouseRange) {
-                       (*i)->show_selection (selection->time);
-               }
-       }
-}
-
-void
-Editor::time_selection_changed ()
-{
-       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-               (*i)->hide_selection ();
-       }
-
-       if (selection->tracks.empty()) {
-               for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-                       (*i)->show_selection (selection->time);
-               }
-       } else {
-               for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
-                       (*i)->show_selection (selection->time);
-               }
-       }
-
-       if (selection->time.empty()) {
-               ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
-       } else {
-               ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, true);
-       }
-}
-
-void
-Editor::region_selection_changed ()
-{
-       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-               (*i)->set_selected_regionviews (selection->regions);
-       }
-}
-
-void
-Editor::point_selection_changed ()
-{
-       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-               (*i)->set_selected_points (selection->points);
-       }
-}
-
 gint
 Editor::mouse_select_button_release (GdkEventButton* ev)
 {
        /* this handles just right-clicks */
 
        if (ev->button != 3) {
-               return FALSE;
+               return false;
        }
 
-       return TRUE;
+       return true;
 }
 
 Editor::TrackViewList *
@@ -4293,3 +3693,17 @@ Editor::idle_visual_changer ()
 
        return 0;
 }
+
+struct EditorOrderTimeAxisSorter {
+    bool operator() (const TimeAxisView* a, const TimeAxisView* b) const {
+           return a->order < b->order;
+    }
+};
+       
+void
+Editor::sort_track_selection ()
+{
+       EditorOrderTimeAxisSorter cmp;
+       selection->tracks.sort (cmp);
+}
+
index 80fa2ff4dfecb23ff7ea310940c43ac8464de206..b0eaa83fd9004246fc4a173c0a4bdbd2fbcb5d0d 100644 (file)
@@ -44,7 +44,7 @@
 #include <ardour/session.h>
 #include <ardour/tempo.h>
 #include <ardour/location.h>
-#include <ardour/region.h>
+#include <ardour/audioregion.h>
 
 #include "audio_clock.h"
 #include "gtk-custom-ruler.h"
@@ -171,6 +171,7 @@ class Editor : public PublicEditor
        void separate_region_from_selection ();
        void separate_regions_using_location (ARDOUR::Location&);
        void toggle_playback (bool with_abort);
+       void transition_to_rolling (bool forward);
 
        /* undo related */
 
@@ -419,12 +420,15 @@ class Editor : public PublicEditor
        CrossfadeView*     clicked_crossfadeview;
        ControlPoint*      clicked_control_point;
 
+       void sort_track_selection ();
+
        void get_relevant_tracks (std::set<RouteTimeAxisView*>& relevant_tracks);
+       void get_equivalent_regions (RegionView* rv, std::vector<RegionView*>&);
        void mapover_tracks (sigc::slot<void,RouteTimeAxisView&,uint32_t> sl);
 
        /* functions to be passed to mapover_tracks(), possibly with sigc::bind()-supplied arguments */
 
-       void mapped_set_selected_regionview_from_click (RouteTimeAxisView&, uint32_t, RegionView*, vector<RegionView*>*);
+       void mapped_get_equivalent_regions (RouteTimeAxisView&, uint32_t, RegionView*, vector<RegionView*>*);
        void mapped_use_new_playlist (RouteTimeAxisView&, uint32_t);
        void mapped_use_copy_playlist (RouteTimeAxisView&, uint32_t);
        void mapped_clear_playlist (RouteTimeAxisView&, uint32_t);
@@ -439,7 +443,7 @@ class Editor : public PublicEditor
        bool set_selected_track (TimeAxisView&, Selection::Operation op = Selection::Set, bool no_remove=false);
 
        bool set_selected_control_point_from_click (Selection::Operation op = Selection::Set, bool no_remove=false);
-       bool set_selected_track_from_click (Selection::Operation op = Selection::Set, bool no_remove=false);
+       bool set_selected_track_from_click (bool press, Selection::Operation op = Selection::Set, bool no_remove=false);
        bool set_selected_regionview_from_click (bool press, Selection::Operation op = Selection::Set, bool no_track_remove=false);
 
        void set_selected_regionview_from_region_list (boost::shared_ptr<ARDOUR::Region> region, Selection::Operation op = Selection::Set);
@@ -904,6 +908,8 @@ class Editor : public PublicEditor
        void align_relative (ARDOUR::RegionPoint);
        void naturalize ();
 
+       void reset_focus ();
+
        void cut ();
        void copy ();
        void paste (float times);
@@ -992,6 +998,7 @@ class Editor : public PublicEditor
        void edit_cursor_forward ();
        void playhead_backward ();
        void playhead_forward ();
+       void scroll_playhead (bool forward);
        void scroll_backward (float pages=0.8f);
        void scroll_forward (float pages=0.8f);
        void scroll_tracks_down ();
@@ -1065,6 +1072,12 @@ class Editor : public PublicEditor
        void fade_out_drag_motion_callback (ArdourCanvas::Item*, GdkEvent*);
        void fade_in_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
        void fade_out_drag_finished_callback (ArdourCanvas::Item*, GdkEvent*);
+
+       void set_fade_in_shape (ARDOUR::AudioRegion::FadeShape);
+       void set_fade_out_shape (ARDOUR::AudioRegion::FadeShape);
+
+       void set_fade_in_active (bool);
+       void set_fade_out_active (bool);
        
        std::set<boost::shared_ptr<ARDOUR::Playlist> > motion_frozen_playlists;
        void region_drag_motion_callback (ArdourCanvas::Item*, GdkEvent*);
index f99a828203bfe5b20c5a111902e3969dd5aa915a..138fa8510e8cda7e48783c0e98e59f3762e22d62 100644 (file)
@@ -164,10 +164,12 @@ Editor::register_actions ()
        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));
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "playhead-forward", _("Playhead Forward"), mem_fun(*this, &Editor::playhead_forward));
+
+       act = ActionManager::register_action (editor_actions, "scroll-playhead-forward", _("Playhead forward"), bind (mem_fun(*this, &Editor::scroll_playhead), true));;
        ActionManager::session_sensitive_actions.push_back (act);
-       act = ActionManager::register_action (editor_actions, "playhead-backward", _("Playhead Backward"), mem_fun(*this, &Editor::playhead_backward));
+       act = ActionManager::register_action (editor_actions, "scroll-playhead-backward", _("Playhead Backward"), bind (mem_fun(*this, &Editor::scroll_playhead), false));
        ActionManager::session_sensitive_actions.push_back (act);
+
        act = ActionManager::register_action (editor_actions, "playhead-to-edit", _("Playhead to Edit"), bind (mem_fun(*this, &Editor::cursor_align), true));
        ActionManager::session_sensitive_actions.push_back (act);
        act = ActionManager::register_action (editor_actions, "edit-to-playhead", _("Edit to Playhead"), bind (mem_fun(*this, &Editor::cursor_align), false));
@@ -1084,3 +1086,9 @@ Editor::parameter_changed (const char* parameter_name)
 
 #undef PARAM_IS
 }
+
+void
+Editor::reset_focus ()
+{
+       track_canvas.grab_focus();
+}
index 48edb52756d8d8626a241bbf79c79b1221ae3c74..a7d7d0de967ff7e11fe4d78cef0dc38545a4f386 100644 (file)
@@ -130,6 +130,8 @@ Editor::do_embed (vector<ustring> paths, bool split, ImportMode mode, AudioTrack
        vector<ustring>::iterator a;
 
        for (a = paths.begin(); a != paths.end(); ) {
+
+               cerr << "Considering embed of " << (*a) << endl;
        
                Glib::ustring path = *a;
                Glib::ustring pair_base;
@@ -264,12 +266,12 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, bool split, bool multiple_fi
        boost::shared_ptr<AudioFileSource> source;
        SourceList sources;
        boost::shared_ptr<AudioRegion> region;
-       string idspec;
        string linked_path;
        SoundFileInfo finfo;
        ustring region_name;
        uint32_t input_chan = 0;
        uint32_t output_chan = 0;
+       int ret = 0;
 
        track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
        ARDOUR_UI::instance()->flush_pending ();
@@ -301,7 +303,7 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, bool split, bool multiple_fi
                
                if (!AudioFileSource::get_soundfile_info (path, finfo, error_msg)) {
                        error << string_compose(_("Editor: cannot open file \"%1\", (%2)"), selection, error_msg ) << endmsg;
-                       return 0;
+                       goto out;
                }
                
                if (check_sample_rate  && (finfo.samplerate != (int) session->frame_rate())) {
@@ -311,27 +313,47 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, bool split, bool multiple_fi
                                choices.push_back (_("Cancel entire import"));
                                choices.push_back (_("Don't embed it"));
                                choices.push_back (_("Embed all without questions"));
+                       
+                               Gtkmm2ext::Choice rate_choice (
+                                       string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path),
+                                       choices, false);
+                               
+                               int resx = rate_choice.run ();
+                               
+                               switch (resx) {
+                               case 0: /* stop a multi-file import */
+                               case 1: /* don't import this one */
+                                       ret = -1;
+                                       goto out;
+                               case 2: /* do it, and the rest without asking */
+                                       check_sample_rate = false;
+                                       break;
+                               case 3: /* do it */
+                                       break;
+                               default:
+                                       ret = -2;
+                                       goto out;
+                               }
                        } else {
                                choices.push_back (_("Cancel"));
-                       }
-                       
-                       choices.push_back (_("Embed it anyway"));
+                               choices.push_back (_("Embed it anyway"));
                        
-                       Gtkmm2ext::Choice rate_choice (
-                               string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path),
-                               choices, false);
-                       
-                       switch (rate_choice.run()) {
-                       case 0: /* stop a multi-file import */
-                       case 1: /* don't import this one */
-                               return -1;
-                       case 2: /* do it, and the rest without asking */
-                               check_sample_rate = false;
-                               break;
-                       case 3: /* do it */
-                               break;
-                       default:
-                               return -2;
+                               Gtkmm2ext::Choice rate_choice (
+                                       string_compose (_("%1\nThis audiofile's sample rate doesn't match the session sample rate!"), path),
+                                       choices, false);
+                               
+                               int resx = rate_choice.run ();
+                               
+                               switch (resx) {
+                               case 0: /* don't import */
+                                       ret = -1;
+                                       goto out;
+                               case 1: /* do it */
+                                       break;
+                               default:
+                                       ret = -2;
+                                       goto out;
+                               }
                        }
                }
                
@@ -341,18 +363,16 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, bool split, bool multiple_fi
                /* make the proper number of channels in the region */
                
                input_chan += finfo.channels;
-       
+
                for (int n = 0; n < finfo.channels; ++n)
                {
-                       idspec = path;
-                       idspec += string_compose(":%1", n);
-                       
                        try {
                                source = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable 
-                                                                                      (DataType::AUDIO, *session, idspec, 
+                                                                                      (DataType::AUDIO, *session, path,  n,
                                                                                        (mode == ImportAsTapeTrack ? 
                                                                                         AudioFileSource::Destructive : 
                                                                                         AudioFileSource::Flag (0))));
+
                                sources.push_back(source);
                        } 
                        
@@ -377,7 +397,7 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, bool split, bool multiple_fi
        
        region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, 0, sources[0]->length(), region_name, 0,
                                                                                  Region::Flag (Region::DefaultFlags|Region::WholeFile|Region::External)));
-       
+
        if (Config->get_output_auto_connect() & AutoConnectMaster) {
                output_chan = (session->master_out() ? session->master_out()->n_inputs().get(DataType::AUDIO) : input_chan);
        } else {
@@ -388,7 +408,7 @@ Editor::embed_sndfile (vector<Glib::ustring> paths, bool split, bool multiple_fi
        
   out:
        track_canvas.get_window()->set_cursor (*current_canvas_cursor);
-       return 0;
+       return ret;
 }
 
 int
index 43977f157770f6b3f1ac3c08226c7b15bd2fb2fd..ce7de29aa1aa28e7d7f69977104ba198e2fc541c 100644 (file)
@@ -210,7 +210,7 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
                
                        
                        try {
-                               fs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (DataType::AUDIO, *session, path, AudioFileSource::Flag (0)));
+                               fs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (DataType::AUDIO, *session, path, false, session->frame_rate()));
                        }
                        
                        catch (failed_constructor& err) {
@@ -258,6 +258,7 @@ Editor::write_region (string path, boost::shared_ptr<AudioRegion> region)
        
        for (vector<boost::shared_ptr<AudioFileSource> >::iterator src = sources.begin(); src != sources.end(); ++src) {
                (*src)->update_header (0, *now, tnow);
+               (*src)->mark_immutable ();
        }
 
        return true;
@@ -343,7 +344,7 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list
                path = s;
                
                try {
-                       fs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (DataType::AUDIO, *session, path, AudioFileSource::Flag (0)));
+                       fs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createWritable (DataType::AUDIO, *session, path, false, session->frame_rate()));
                }
                
                catch (failed_constructor& err) {
@@ -416,8 +417,9 @@ Editor::write_audio_range (AudioPlaylist& playlist, const ChanCount& count, list
        time (&tnow);
        now = localtime (&tnow);
 
-       for (uint32_t n=0; n < channels; ++n) {
-               sources[n]->update_header (0, *now, tnow);
+       for (vector<boost::shared_ptr<AudioFileSource> >::iterator s = sources.begin(); s != sources.end(); ++s) {
+               (*s)->update_header (0, *now, tnow);
+               (*s)->mark_immutable ();
                // do we need to ref it again?
        }
        
index cdea9d22720706b33c5f1a710450950a8a8dd058..bfe61eae5cc165577bee12fd3d585297b57c61e0 100644 (file)
@@ -82,7 +82,7 @@ Editor::kbd_do_split (GdkEvent* ev)
        nframes_t where = event_frame (ev);
 
        if (entered_regionview) {
-               if (selection->regions.find (entered_regionview) != selection->regions.end()) {
+               if (selection->regions.contains (entered_regionview)) {
                        split_regions_at (where, selection->regions);
                } else {
                        RegionSelection s;
index bdb934e8e0c59c0755822516f655904f19f7066e..0e8901b88175e8c4c307e3ba87dd191a8107ce0c 100644 (file)
@@ -77,6 +77,9 @@ Editor::show_editor_mixer (bool yn)
                                }
 
                        } else {
+
+                               sort_track_selection ();
+
                                for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
                                        AudioTimeAxisView* atv;
 
index 01ea203c61227e3a28475d9c15efff65ddb694d7..a7095d9e090f70a7aad0def54fd01d2f22601640 100644 (file)
@@ -291,8 +291,6 @@ void
 Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type)
 {
        bool commit = false;
-       bool c1; 
-       bool c2;
 
        /* in object/audition/timefx mode, any button press sets
           the selection if the object can be selected. this is a
@@ -309,6 +307,16 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
                
                return;
        }
+
+       if (event->type == GDK_BUTTON_PRESS || event->type == GDK_BUTTON_RELEASE) {
+
+               if ((event->button.state & Keyboard::RelevantModifierKeyMask) && event->button.button != 1) {
+                       
+                       /* no selection action on modified button-2 or button-3 events */
+                       
+                       return;
+               }
+       }
            
        Selection::Operation op = Keyboard::selection_type (event->button.state);
        bool press = (event->type == GDK_BUTTON_PRESS);
@@ -317,35 +325,33 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
 
        switch (item_type) {
        case RegionItem:
-               /* XXX make tying track/region selection optional */
-               c1 = set_selected_track_from_click (op, true);
-               c2 = set_selected_regionview_from_click (press, op, true);
-               commit = (c1 || c2);
+               commit = set_selected_regionview_from_click (press, op, true);
                break;
                
        case RegionViewNameHighlight:
        case RegionViewName:
-               /* XXX make tying track/region selection optional */
-               c1 = set_selected_track_from_click (op, true);
-               c2 = set_selected_regionview_from_click (press, op, true);
-               commit = (c1 || c2);
+               commit = set_selected_regionview_from_click (press, op, true);
+               break;
+
+       case FadeInHandleItem:
+       case FadeInItem:
+       case FadeOutHandleItem:
+       case FadeOutItem:
+               commit = set_selected_regionview_from_click (press, op, true);
                break;
                
        case GainAutomationControlPointItem:
        case PanAutomationControlPointItem:
        case RedirectAutomationControlPointItem:
-               /* XXX make tying track/region selection optional */
-               c1 = set_selected_track_from_click (op, true);
-               c2 = set_selected_control_point_from_click (op, false);
-               commit = (c1 || c2);
+               commit = set_selected_control_point_from_click (op, false);
                break;
                
        case StreamItem:
-               commit = set_selected_track_from_click (op, true);
+               // commit = set_selected_track_from_click (press, op, true);
                break;
                    
        case AutomationTrackItem:
-               commit = set_selected_track_from_click (op, true);
+               commit = set_selected_track_from_click (press, op, true);
                break;
                
        default:
@@ -364,7 +370,7 @@ Editor::button_selection (ArdourCanvas::Item* item, GdkEvent* event, ItemType it
                case StreamItem:
                case RegionItem:
                case AutomationTrackItem:
-                       commit = set_selected_track_from_click (op, true);
+                       commit = set_selected_track_from_click (true, op, true);
                        break;
 
                default:
@@ -500,10 +506,9 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp
                        break;
                        
                case MouseObject:
-                       if (Keyboard::modifier_state_contains (event->button.state, 
-                                                              Keyboard::ModifierMask(Keyboard::Control|Keyboard::Alt))
-                               && event->type == GDK_BUTTON_PRESS) {
-
+                       if (Keyboard::modifier_state_contains (event->button.state, Keyboard::ModifierMask(Keyboard::Control|Keyboard::Alt)) &&
+                           event->type == GDK_BUTTON_PRESS) {
+                               
                                start_rubberband_select (item, event);
 
                        } else if (event->type == GDK_BUTTON_PRESS) {
@@ -1765,7 +1770,7 @@ Editor::fade_in_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
        nframes_t pos;
        nframes_t fade_length;
 
-       if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
+       if ((int32_t)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
        }
        else {
@@ -1775,16 +1780,26 @@ Editor::fade_in_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
        if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
                snap_to (pos);
        }
-       
+
        if (pos < (arv->region()->position() + 64)) {
                fade_length = 64; // this should be a minimum defined somewhere
        } else if (pos > arv->region()->last_frame()) {
                fade_length = arv->region()->length();
        } else {
                fade_length = pos - arv->region()->position();
-       }
+       }               
+       /* mapover the region selection */
+
+       for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+
+               AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*i);
+               
+               if (!tmp) {
+                       continue;
+               }
        
-       arv->reset_fade_in_shape_width (fade_length);
+               tmp->reset_fade_in_shape_width (fade_length);
+       }
 
        show_verbose_duration_cursor (arv->region()->position(),  arv->region()->position() + fade_length, 10);
 
@@ -1794,43 +1809,46 @@ Editor::fade_in_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event)
 void
 Editor::fade_in_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* event)
 {
-       if (drag_info.first_move) return;
-
        AudioRegionView* arv = static_cast<AudioRegionView*>(drag_info.data);
        nframes_t pos;
        nframes_t fade_length;
 
-       if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
+       if (drag_info.first_move) return;
+
+       if ((int32_t)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
                pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
-       }
-       else {
+       } else {
                pos = 0;
        }
 
-       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-               snap_to (pos);
-       }
-
        if (pos < (arv->region()->position() + 64)) {
                fade_length = 64; // this should be a minimum defined somewhere
-       }
-       else if (pos > arv->region()->last_frame()) {
+       } else if (pos > arv->region()->last_frame()) {
                fade_length = arv->region()->length();
-       }
-       else {
+       } else {
                fade_length = pos - arv->region()->position();
        }
-
+               
        begin_reversible_command (_("change fade in length"));
-       AutomationList& alist = arv->audio_region()->fade_in();
-        XMLNode &before = alist.get_state();
 
-       arv->audio_region()->set_fade_in_length (fade_length);
+       for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+
+               AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*i);
+               
+               if (!tmp) {
+                       continue;
+               }
+       
+               AutomationList& alist = tmp->audio_region()->fade_in();
+               XMLNode &before = alist.get_state();
+
+               tmp->audio_region()->set_fade_in_length (fade_length);
+               
+               XMLNode &after = alist.get_state();
+               session->add_command(new MementoCommand<AutomationList>(alist, &before, &after));
+       }
 
-        XMLNode &after = alist.get_state();
-        session->add_command(new MementoCommand<AutomationList>(alist, &before, &after));
        commit_reversible_command ();
-       fade_in_drag_motion_callback (item, event);
 }
 
 void
@@ -1869,7 +1887,7 @@ Editor::fade_out_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event
        if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
                snap_to (pos);
        }
-
+       
        if (pos > (arv->region()->last_frame() - 64)) {
                fade_length = 64; // this should really be a minimum fade defined somewhere
        }
@@ -1879,8 +1897,19 @@ Editor::fade_out_drag_motion_callback (ArdourCanvas::Item* item, GdkEvent* event
        else {
                fade_length = arv->region()->last_frame() - pos;
        }
+               
+       /* mapover the region selection */
+
+       for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+
+               AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*i);
+               
+               if (!tmp) {
+                       continue;
+               }
        
-       arv->reset_fade_out_shape_width (fade_length);
+               tmp->reset_fade_out_shape_width (fade_length);
+       }
 
        show_verbose_duration_cursor (arv->region()->last_frame() - fade_length, arv->region()->last_frame(), 10);
 
@@ -1918,16 +1947,25 @@ Editor::fade_out_drag_finished_callback (ArdourCanvas::Item* item, GdkEvent* eve
        }
 
        begin_reversible_command (_("change fade out length"));
-       AutomationList& alist = arv->audio_region()->fade_out();
-        XMLNode &before = alist.get_state();
 
-       arv->audio_region()->set_fade_out_length (fade_length);
+       for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
 
-        XMLNode &after = alist.get_state();
-        session->add_command(new MementoCommand<AutomationList>(alist, &before, &after));
-       commit_reversible_command ();
+               AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*i);
+               
+               if (!tmp) {
+                       continue;
+               }
+       
+               AutomationList& alist = tmp->audio_region()->fade_out();
+               XMLNode &before = alist.get_state();
+               
+               tmp->audio_region()->set_fade_out_length (fade_length);
+
+               XMLNode &after = alist.get_state();
+               session->add_command(new MementoCommand<AutomationList>(alist, &before, &after));
+       }
 
-       fade_out_drag_motion_callback (item, event);
+       commit_reversible_command ();
 }
 
 void
@@ -2709,8 +2747,6 @@ Editor::start_region_grab (ArdourCanvas::Item* item, GdkEvent* event)
 void
 Editor::start_region_copy_grab (ArdourCanvas::Item* item, GdkEvent* event)
 {
-       cerr << "start region copy grab, selected regions = " << selection->regions.size() << endl;
-
        if (selection->regions.empty() || clicked_regionview == 0) {
                return;
        }
@@ -4651,16 +4687,15 @@ Editor::drag_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event)
                return;
        }
 
-//     if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
-//             snap_to (drag_info.current_pointer_frame);
-               
-//             if (drag_info.first_move) {
-//                     snap_to (drag_info.grab_frame);
-//             }
-//     }
-               
+       if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
+               if (drag_info.first_move) {
+                       snap_to (drag_info.grab_frame);
+               } 
+               snap_to (drag_info.current_pointer_frame);
+       }
 
        /* base start and end on initial click position */
+
        if (drag_info.current_pointer_frame < drag_info.grab_frame) {
                start = drag_info.current_pointer_frame;
                end = drag_info.grab_frame;
@@ -4672,8 +4707,7 @@ Editor::drag_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event)
        if (drag_info.current_pointer_y < drag_info.grab_y) {
                y1 = drag_info.current_pointer_y;
                y2 = drag_info.grab_y;
-       }
-       else {
+       } else {
                y2 = drag_info.current_pointer_y;
                y1 = drag_info.grab_y;
        }
@@ -4720,7 +4754,7 @@ Editor::end_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event)
                Selection::Operation op = Keyboard::selection_type (event->button.state);
                bool commit;
 
-               begin_reversible_command (_("select regions"));
+               begin_reversible_command (_("rubberband selection"));
 
                if (drag_info.grab_frame < drag_info.last_pointer_frame) {
                        commit = select_all_within (drag_info.grab_frame, drag_info.last_pointer_frame, y1, y2, op);
@@ -4733,6 +4767,7 @@ Editor::end_rubberband_select (ArdourCanvas::Item* item, GdkEvent* event)
                }
                
        } else {
+               selection->clear_tracks();
                selection->clear_regions();
                selection->clear_points ();
                selection->clear_lines ();
index aff997a1252b637ef8a9dd88e434a583892e3623..3a2658c204edff514a6927e4fa46bba7013372d0 100644 (file)
@@ -756,6 +756,39 @@ Editor::cursor_to_selection_end (Cursor *cursor)
        }
 }
 
+void
+Editor::scroll_playhead (bool forward)
+{
+       nframes_t pos = playhead_cursor->current_frame;
+       nframes_t delta = (nframes_t) floor (current_page_frames() / 0.8);
+
+       if (forward) {
+               if (pos == max_frames) {
+                       return;
+               }
+
+               if (pos < max_frames - delta) {
+                       pos += delta ;
+               } else {
+                       pos = max_frames;
+               } 
+
+       } else {
+
+               if (pos == 0) {
+                       return;
+               } 
+
+               if (pos > delta) {
+                       pos -= delta;
+               } else {
+                       pos = 0;
+               }
+       }
+
+       session->request_locate (pos);
+}
+
 void
 Editor::playhead_backward ()
 {
@@ -1257,311 +1290,6 @@ Editor::add_location_from_audio_region ()
        session->commit_reversible_command ();
 }
 
-void
-Editor::select_all_in_track (Selection::Operation op)
-{
-       list<Selectable *> touched;
-
-       if (!clicked_axisview) {
-               return;
-       }
-       
-       clicked_axisview->get_selectables (0, max_frames, 0, DBL_MAX, touched);
-
-       switch (op) {
-       case Selection::Toggle:
-               selection->add (touched);
-               break;
-       case Selection::Set:
-               selection->set (touched);
-               break;
-       case Selection::Extend:
-               /* not defined yet */
-               break;
-       case Selection::Add:
-               selection->add (touched);
-               break;
-       }
-}
-
-void
-Editor::select_all (Selection::Operation op)
-{
-       list<Selectable *> touched;
-       
-       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
-               if ((*iter)->hidden()) {
-                       continue;
-               }
-               (*iter)->get_selectables (0, max_frames, 0, DBL_MAX, touched);
-       }
-       begin_reversible_command (_("select all"));
-       switch (op) {
-       case Selection::Add:
-       case Selection::Toggle:
-               selection->add (touched);
-               break;
-       case Selection::Set:
-               selection->set (touched);
-               break;
-       case Selection::Extend:
-               /* not defined yet */
-               break;
-       }
-       commit_reversible_command ();
-}
-
-void
-Editor::invert_selection_in_track ()
-{
-       list<Selectable *> touched;
-
-       if (!clicked_axisview) {
-               return;
-       }
-       
-       clicked_axisview->get_inverted_selectables (*selection, touched);
-       selection->set (touched);
-}
-
-void
-Editor::invert_selection ()
-{
-       list<Selectable *> touched;
-       
-       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
-               if ((*iter)->hidden()) {
-                       continue;
-               }
-               (*iter)->get_inverted_selectables (*selection, touched);
-       }
-
-       selection->set (touched);
-}
-
-bool
-Editor::select_all_within (nframes_t start, nframes_t end, double top, double bot, Selection::Operation op)
-{
-       list<Selectable *> touched;
-       
-       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
-               if ((*iter)->hidden()) {
-                       continue;
-               }
-               (*iter)->get_selectables (start, end, top, bot, touched);
-       }
-
-       cerr << "select all within found " << touched.size() << endl;
-
-       begin_reversible_command (_("select all within"));
-       switch (op) {
-       case Selection::Add:
-       case Selection::Toggle:
-               cerr << "toggle\n";
-               selection->add (touched);
-               break;
-       case Selection::Set:
-               cerr << "set\n";
-               selection->set (touched);
-               break;
-       case Selection::Extend:
-               cerr << "extend\n";
-               /* not defined yet */
-               break;
-       }
-
-       cerr << "selection now has " << selection->points.size() << endl;
-
-       commit_reversible_command ();
-       return !touched.empty();
-}
-
-void
-Editor::set_selection_from_audio_region ()
-{
-       if (selection->regions.empty()) {
-               return;
-       }
-
-       RegionView* rv = *(selection->regions.begin());
-       boost::shared_ptr<Region> region = rv->region();
-       
-       begin_reversible_command (_("set selection from region"));
-       selection->set (0, region->position(), region->last_frame());
-       commit_reversible_command ();
-
-       set_mouse_mode (Editing::MouseRange, false);
-}
-
-void
-Editor::set_selection_from_punch()
-{
-       Location* location;
-
-       if ((location = session->locations()->auto_punch_location()) == 0)  {
-               return;
-       }
-
-       set_selection_from_range (*location);
-}
-
-void
-Editor::set_selection_from_loop()
-{
-       Location* location;
-
-       if ((location = session->locations()->auto_loop_location()) == 0)  {
-               return;
-       }
-       set_selection_from_range (*location);
-}
-
-void
-Editor::set_selection_from_range (Location& loc)
-{
-       begin_reversible_command (_("set selection from range"));
-       selection->set (0, loc.start(), loc.end());
-       commit_reversible_command ();
-
-       set_mouse_mode (Editing::MouseRange, false);
-}
-
-void
-Editor::select_all_selectables_using_time_selection ()
-{
-       list<Selectable *> touched;
-
-       if (selection->time.empty()) {
-               return;
-       }
-
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
-
-       if (end - start < 1)  {
-               return;
-       }
-
-       for (TrackViewList::iterator iter = selection->tracks.begin(); iter != selection->tracks.end(); ++iter) {
-               if ((*iter)->hidden()) {
-                       continue;
-               }
-               (*iter)->get_selectables (start, end - 1, 0, DBL_MAX, touched);
-       }
-
-       begin_reversible_command (_("select all from range"));
-       selection->set (touched);
-       commit_reversible_command ();
-}
-
-
-void
-Editor::select_all_selectables_using_punch()
-{
-       Location* location = session->locations()->auto_punch_location();
-       list<Selectable *> touched;
-
-       if (location == 0 || (location->end() - location->start() <= 1))  {
-               return;
-       }
-
-       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
-               if ((*iter)->hidden()) {
-                       continue;
-               }
-               (*iter)->get_selectables (location->start(), location->end() - 1, 0, DBL_MAX, touched);
-       }
-       begin_reversible_command (_("select all from punch"));
-       selection->set (touched);
-       commit_reversible_command ();
-
-}
-
-void
-Editor::select_all_selectables_using_loop()
-{
-       Location* location = session->locations()->auto_loop_location();
-       list<Selectable *> touched;
-
-       if (location == 0 || (location->end() - location->start() <= 1))  {
-               return;
-       }
-
-       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
-               if ((*iter)->hidden()) {
-                       continue;
-               }
-               (*iter)->get_selectables (location->start(), location->end() - 1, 0, DBL_MAX, touched);
-       }
-       begin_reversible_command (_("select all from loop"));
-       selection->set (touched);
-       commit_reversible_command ();
-
-}
-
-void
-Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after)
-{
-        nframes_t start;
-       nframes_t end;
-       list<Selectable *> touched;
-
-       if (after) {
-               begin_reversible_command (_("select all after cursor"));
-               start = cursor->current_frame ;
-               end = session->current_end_frame();
-       } else {
-               if (cursor->current_frame > 0) {
-                       begin_reversible_command (_("select all before cursor"));
-                       start = 0;
-                       end = cursor->current_frame - 1;
-               } else {
-                       return;
-               }
-       }
-
-       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_cursors (Cursor *cursor, Cursor *other_cursor)
-{
-        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;
-       }
-
-       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::amplitude_zoom_step (bool in)
 {
@@ -1855,6 +1583,30 @@ Editor::edit_envelope ()
 
 /* PLAYBACK */
 
+void
+Editor::transition_to_rolling (bool fwd)
+{
+       if (!session) {
+               return;
+       }
+
+       switch (Config->get_slave_source()) {
+       case None:
+       case JACK:
+               break;
+       default:
+               /* transport controlled by the master */
+               return;
+       }
+
+       if (session->is_auditioning()) {
+               session->cancel_audition ();
+               return;
+       }
+       
+       session->request_transport_speed (fwd ? 1.0f : -1.0f);
+}
+
 void
 Editor::toggle_playback (bool with_abort)
 {
@@ -2166,6 +1918,8 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<AudioRegion> >& n
        nframes_t start = selection->time[clicked_selection].start;
        nframes_t end = selection->time[clicked_selection].end;
        
+       sort_track_selection ();
+
        for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
 
                boost::shared_ptr<AudioRegion> current;
@@ -2196,17 +1950,22 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<AudioRegion> >& n
 void
 Editor::split_multichannel_region ()
 {
-       vector<AudioRegion*> v;
-
-       AudioRegionView* clicked_arv = dynamic_cast<AudioRegionView*>(clicked_regionview);
-       
-       if (!clicked_arv || clicked_arv->audio_region()->n_channels() < 2) {
+       if (selection->regions.empty()) {
                return;
        }
 
-       clicked_arv->audio_region()->separate_by_channel (*session, v);
+       vector<boost::shared_ptr<AudioRegion> > v;
+
+       for (list<RegionView*>::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
 
-       /* nothing else to do, really */
+               AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*x);
+               
+               if (!arv || arv->audio_region()->n_channels() < 2) {
+                       continue;
+               }
+
+               (arv)->audio_region()->separate_by_channel (*session, v);
+       }
 }
 
 void
@@ -2229,6 +1988,8 @@ Editor::separate_region_from_selection ()
 
        boost::shared_ptr<Playlist> playlist;
                
+       sort_track_selection ();
+
        for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
 
                AudioTimeAxisView* atv;
@@ -2337,6 +2098,8 @@ Editor::crop_region_to_selection ()
 
        } else {
                
+               sort_track_selection ();
+
                for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
 
                        RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(*i);
@@ -2949,21 +2712,37 @@ struct lt_playlist {
     }
 };
        
+struct PlaylistMapping { 
+    TimeAxisView* tv;
+    boost::shared_ptr<Playlist> pl;
+
+    PlaylistMapping (TimeAxisView* tvp) : tv (tvp) {}
+};
+
 void
 Editor::cut_copy_regions (CutCopyOp op)
-{
-        typedef std::map<boost::shared_ptr<AudioPlaylist>,boost::shared_ptr<AudioPlaylist> > PlaylistMapping;
-       PlaylistMapping pmap;
-       nframes_t first_position = max_frames;
+{      
+       /* we can't use a std::map here because the ordering is important, and we can't trivially sort
+          a map when we want ordered access to both elements. i think.
+       */
+
+       vector<PlaylistMapping> pmap;
 
+       nframes_t first_position = max_frames;
+       
        set<PlaylistState, lt_playlist> freezelist;
        pair<set<PlaylistState, lt_playlist>::iterator,bool> insert_result;
+       
+       /* get ordering correct before we cut/copy */
+       
+       selection->regions.sort_by_position_and_track ();
 
        for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+
                first_position = min ((*x)->region()->position(), first_position);
 
                if (op == Cut || op == Clear) {
-                       boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>((*x)->region()->playlist());
+                       boost::shared_ptr<Playlist> pl = (*x)->region()->playlist();
 
                        if (pl) {
 
@@ -2972,67 +2751,94 @@ Editor::cut_copy_regions (CutCopyOp op)
                                before.before = &pl->get_state();
                                
                                insert_result = freezelist.insert (before);
-
+                               
                                if (insert_result.second) {
                                        pl->freeze ();
                                }
                        }
                }
+
+               TimeAxisView* tv = &(*x)->get_trackview();
+               vector<PlaylistMapping>::iterator z;
+
+               for (z = pmap.begin(); z != pmap.end(); ++z) {
+                       if ((*z).tv == tv) {
+                               break;
+                       }
+               }
+               
+               if (z == pmap.end()) {
+                       pmap.push_back (PlaylistMapping (tv));
+               }
        }
 
        for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ) {
 
-               boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>((*x)->region()->playlist());
-               boost::shared_ptr<AudioPlaylist> npl;
+               boost::shared_ptr<Playlist> pl = (*x)->region()->playlist();
+               
+               if (!pl) {
+                       /* impossible, but this handles it for the future */
+                       continue;
+               }
+
+               TimeAxisView& tv = (*x)->get_trackview();
+               boost::shared_ptr<Playlist> npl;
                RegionSelection::iterator tmp;
                
                tmp = x;
                ++tmp;
 
-               if (pl) {
-
-                       PlaylistMapping::iterator pi = pmap.find (pl);
-                       
-                       if (pi == pmap.end()) {
-                               // FIXME
-                               npl = boost::dynamic_pointer_cast<AudioPlaylist> (PlaylistFactory::create (DataType::AUDIO, *session, "cutlist", true));
-                               npl->freeze();
-                               pmap[pl] = npl;
-                       } else {
-                               npl = pi->second;
-                       }
-
-                       // FIXME
-                       boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion>((*x)->region());
-                       switch (op) {
-                       case Cut:
-                               if (!ar) break;
-
-                               npl->add_region (RegionFactory::create (ar), (*x)->region()->position() - first_position);
-                               pl->remove_region (((*x)->region()));
-                               break;
-
-                       case Copy:
-                               if (!ar) break;
-
-                               npl->add_region (RegionFactory::create (ar), (*x)->region()->position() - first_position);
-                               break;
-
-                       case Clear:
-                               pl->remove_region (((*x)->region()));
+               vector<PlaylistMapping>::iterator z;
+               
+               for (z = pmap.begin(); z != pmap.end(); ++z) {
+                       if ((*z).tv == &tv) {
                                break;
                        }
                }
+               
+               assert (z != pmap.end());
+               
+               if (!(*z).pl) {
+                       npl = PlaylistFactory::create (pl->data_type(), *session, "cutlist", true);
+                       npl->freeze();
+                       (*z).pl = npl;
+               } else {
+                       npl = (*z).pl;
+               }
+               
+               boost::shared_ptr<Region> r = (*x)->region();
+               
+               switch (op) {
+               case Cut:
+                       if (!r) break;
+                       
+                       npl->add_region (RegionFactory::create (r), r->position() - first_position);
+                       pl->remove_region (r);
+                       break;
+                       
+               case Copy:
+                       if (!r) break;
+                       
+                       npl->add_region (RegionFactory::create (r), r->position() - first_position);
+                       break;
+                       
+               case Clear:
+                       pl->remove_region (r);
+                       break;
+               }
 
                x = tmp;
        }
-
+       
        list<boost::shared_ptr<Playlist> > foo;
-
-       for (PlaylistMapping::iterator i = pmap.begin(); i != pmap.end(); ++i) {
-               foo.push_back (i->second);
+       
+       /* the pmap is in the same order as the tracks in which selected regions occured */
+       
+       for (vector<PlaylistMapping>::iterator i = pmap.begin(); i != pmap.end(); ++i) {
+               (*i).pl->thaw();
+               foo.push_back ((*i).pl);
        }
-
+       
        if (!foo.empty()) {
                cut_buffer->set (foo);
        }
@@ -3096,15 +2902,19 @@ Editor::paste_internal (nframes_t position, float times)
        TrackSelection::iterator i;
        size_t nth;
 
+       /* get everything in the correct order */
+
+       sort_track_selection ();
+
        for (nth = 0, i = selection->tracks.begin(); i != selection->tracks.end(); ++i, ++nth) {
-               
+
                /* undo/redo is handled by individual tracks */
 
                if ((*i)->paste (position, times, *cut_buffer, nth)) {
                        commit = true;
                }
        }
-
+       
        if (commit) {
                commit_reversible_command ();
        }
@@ -3130,6 +2940,8 @@ Editor::paste_named_selection (float times)
        chunk = ns->playlists.begin();
                
        begin_reversible_command (_("paste chunk"));
+       
+       sort_track_selection ();
 
        for (t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
                
@@ -3242,8 +3054,6 @@ Editor::reset_point_selection ()
 {
        /* reset all selected points to the relevant default value */
 
-       cerr << "point selection has " << selection->points.size() << " entries\n";
-       
        for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
                
                AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>(&(*i).track);
@@ -3610,3 +3420,99 @@ Editor::toggle_region_opaque ()
                }
        }
 }
+
+void
+Editor::set_fade_in_shape (AudioRegion::FadeShape shape)
+{
+       begin_reversible_command (_("set fade in shape"));
+
+       for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+               AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
+
+               if (!tmp) {
+                       return;
+               }
+
+               AutomationList& alist = tmp->audio_region()->fade_in();
+               XMLNode &before = alist.get_state();
+
+               tmp->audio_region()->set_fade_in_shape (shape);
+               
+               XMLNode &after = alist.get_state();
+               session->add_command(new MementoCommand<AutomationList>(alist, &before, &after));
+       }
+
+       commit_reversible_command ();
+}
+
+void
+Editor::set_fade_out_shape (AudioRegion::FadeShape shape)
+{
+       begin_reversible_command (_("set fade out shape"));
+
+       for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+               AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
+
+               if (!tmp) {
+                       return;
+               }
+
+               AutomationList& alist = tmp->audio_region()->fade_out();
+               XMLNode &before = alist.get_state();
+
+               tmp->audio_region()->set_fade_out_shape (shape);
+               
+               XMLNode &after = alist.get_state();
+               session->add_command(new MementoCommand<AutomationList>(alist, &before, &after));
+       }
+
+       commit_reversible_command ();
+}
+
+void
+Editor::set_fade_in_active (bool yn)
+{
+       begin_reversible_command (_("set fade in active"));
+
+       for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+               AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
+
+               if (!tmp) {
+                       return;
+               }
+
+
+               boost::shared_ptr<AudioRegion> ar (tmp->audio_region());
+
+               XMLNode &before = ar->get_state();
+
+               ar->set_fade_in_active (yn);
+               
+               XMLNode &after = ar->get_state();
+               session->add_command(new MementoCommand<AudioRegion>(*ar, &before, &after));
+       }
+}
+
+void
+Editor::set_fade_out_active (bool yn)
+{
+       begin_reversible_command (_("set fade out active"));
+
+       for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+               AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
+
+               if (!tmp) {
+                       return;
+               }
+
+               boost::shared_ptr<AudioRegion> ar (tmp->audio_region());
+
+               XMLNode &before = ar->get_state();
+
+               ar->set_fade_out_active (yn);
+               
+               XMLNode &after = ar->get_state();
+               session->add_command(new MementoCommand<AudioRegion>(*ar, &before, &after));
+       }
+}
+
index 97512c06e86a460e915fcc0211e6a4aa03da8735..5bf704f649851d70c0d9382984eec669387c0aaa 100644 (file)
@@ -50,7 +50,6 @@ using namespace Editing;
 void
 Editor::handle_region_removed (boost::weak_ptr<Region> wregion)
 {
-       cerr << "removed region\n";
        ENSURE_GUI_THREAD (mem_fun (*this, &Editor::redisplay_regions));
        redisplay_regions ();
 }
diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc
new file mode 100644 (file)
index 0000000..c1f5636
--- /dev/null
@@ -0,0 +1,1011 @@
+/*
+    Copyright (C) 2000-2006 Paul Davis 
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+    $Id: editor.cc 1353 2007-01-18 03:06:15Z paul $
+*/
+
+#include <pbd/stacktrace.h>
+
+#include <ardour/diskstream.h>
+#include <ardour/playlist.h>
+#include <ardour/route_group.h>
+
+#include "editor.h"
+#include "actions.h"
+#include "audio_time_axis.h"
+#include "audio_region_view.h"
+#include "audio_streamview.h"
+#include "automation_line.h"
+
+#include "i18n.h"
+
+using namespace std;
+using namespace sigc;
+using namespace ARDOUR;
+using namespace PBD;
+using namespace Gtk;
+using namespace Glib;
+using namespace Gtkmm2ext;
+using namespace Editing;
+
+struct TrackViewByPositionSorter
+{
+    bool operator() (const TimeAxisView* a, const TimeAxisView *b) {
+           return a->y_position < b->y_position;
+    }
+};
+
+bool
+Editor::extend_selection_to_track (TimeAxisView& view)
+{
+       if (selection->selected (&view)) {
+               /* already selected, do nothing */
+               return false;
+       }
+
+       if (selection->tracks.empty()) {
+
+               if (!selection->selected (&view)) {
+                       selection->set (&view);
+                       return true;
+               } else {
+                       return false;
+               }
+       } 
+
+       /* something is already selected, so figure out which range of things to add */
+       
+       TrackViewList to_be_added;
+       TrackViewList sorted = track_views;
+       TrackViewByPositionSorter cmp;
+       bool passed_clicked = false;
+       bool forwards = true;
+
+       sorted.sort (cmp);
+
+       if (!selection->selected (&view)) {
+               to_be_added.push_back (&view);
+       }
+
+       /* figure out if we should go forward or backwards */
+
+       for (TrackViewList::iterator i = sorted.begin(); i != sorted.end(); ++i) {
+
+               if ((*i) == &view) {
+                       passed_clicked = true;
+               }
+
+               if (selection->selected (*i)) {
+                       if (passed_clicked) {
+                               forwards = true;
+                       } else {
+                               forwards = false;
+                       }
+                       break;
+               }
+       }
+                       
+       passed_clicked = false;
+
+       if (forwards) {
+
+               for (TrackViewList::iterator i = sorted.begin(); i != sorted.end(); ++i) {
+                                       
+                       if ((*i) == &view) {
+                               passed_clicked = true;
+                               continue;
+                       }
+                                       
+                       if (passed_clicked) {
+                               if ((*i)->hidden()) {
+                                       continue;
+                               }
+                               if (selection->selected (*i)) {
+                                       break;
+                               } else if (!(*i)->hidden()) {
+                                       to_be_added.push_back (*i);
+                               }
+                       }
+               }
+
+       } else {
+
+               for (TrackViewList::reverse_iterator r = sorted.rbegin(); r != sorted.rend(); ++r) {
+                                       
+                       if ((*r) == &view) {
+                               passed_clicked = true;
+                               continue;
+                       }
+                                       
+                       if (passed_clicked) {
+                                               
+                               if ((*r)->hidden()) {
+                                       continue;
+                               }
+                                               
+                               if (selection->selected (*r)) {
+                                       break;
+                               } else if (!(*r)->hidden()) {
+                                       to_be_added.push_back (*r);
+                               }
+                       }
+               }
+       }
+                       
+       if (!to_be_added.empty()) {
+               selection->add (to_be_added);
+               return true;
+       }
+       
+       return false;
+}
+
+
+bool
+Editor::set_selected_track (TimeAxisView& view, Selection::Operation op, bool no_remove)
+{
+       bool commit = false;
+
+       switch (op) {
+       case Selection::Toggle:
+               if (selection->selected (&view)) {
+                       if (!no_remove) {
+                               selection->remove (&view);
+                               commit = true;
+                       }
+               } else {
+                       selection->add (&view);
+                       commit = false;
+               }
+               break;
+
+       case Selection::Add:
+               if (!selection->selected (&view)) {
+                       selection->add (&view);
+                       commit = true;
+               }
+               break;
+
+       case Selection::Set:
+               if (selection->selected (&view) && selection->tracks.size() == 1) {
+                       /* no commit necessary */
+               } else {
+                       
+                       /* reset track selection if there is only 1 other track
+                          selected OR if no_remove is not set (its there to 
+                          prevent deselecting a multi-track selection
+                          when clicking on an already selected track
+                          for some reason.
+                       */
+
+                       if (selection->tracks.empty()) {
+                               selection->set (&view);
+                               commit = true;
+                       } else if (selection->tracks.size() == 1 || !no_remove) {
+                               selection->set (&view);
+                               commit = true;
+                       }
+               }
+               break;
+               
+       case Selection::Extend:
+               commit = extend_selection_to_track (view);
+               break;
+       }
+
+       return commit;
+}
+
+bool
+Editor::set_selected_track_from_click (bool press, Selection::Operation op, bool no_remove)
+{
+       if (!clicked_routeview) {
+               return false;
+       }
+       
+       if (!press) {
+               return false;
+       }
+
+       return set_selected_track (*clicked_routeview, op, no_remove);
+}
+
+bool
+Editor::set_selected_control_point_from_click (Selection::Operation op, bool no_remove)
+{
+       if (!clicked_control_point) {
+               return false;
+       }
+
+       /* select this point and any others that it represents */
+
+       double y1, y2;
+       nframes_t x1, x2;
+
+       x1 = pixel_to_frame (clicked_control_point->get_x() - 10);
+       x2 = pixel_to_frame (clicked_control_point->get_x() + 10);
+       y1 = clicked_control_point->get_x() - 10;
+       y2 = clicked_control_point->get_y() + 10;
+
+       return select_all_within (x1, x2, y1, y2, op);
+}
+
+void
+Editor::get_relevant_tracks (set<RouteTimeAxisView*>& relevant_tracks)
+{
+       /* step one: get all selected tracks and all tracks in the relevant edit groups */
+
+       for (TrackSelection::iterator ti = selection->tracks.begin(); ti != selection->tracks.end(); ++ti) {
+
+               RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(*ti);
+
+               if (!rtv) {
+                       continue;
+               }
+
+               RouteGroup* group = rtv->route()->edit_group();
+
+               if (group && group->is_active()) {
+                       
+                       /* active group for this track, loop over all tracks and get every member of the group */
+
+                       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+                               
+                               RouteTimeAxisView* trtv;
+                               
+                               if ((trtv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
+                                       
+                                       if (trtv->route()->edit_group() == group) {
+                                               relevant_tracks.insert (trtv);
+                                       }
+                               }
+                       }
+               } else {
+                       relevant_tracks.insert (rtv);
+               }
+       }
+}
+
+void
+Editor::mapover_tracks (slot<void,RouteTimeAxisView&,uint32_t> sl)
+{
+       set<RouteTimeAxisView*> relevant_tracks;
+
+       get_relevant_tracks (relevant_tracks);
+
+       uint32_t sz = relevant_tracks.size();
+
+       for (set<RouteTimeAxisView*>::iterator rti = relevant_tracks.begin(); rti != relevant_tracks.end(); ++rti) {
+               sl (**rti, sz);
+       }
+}
+
+void
+Editor::mapped_get_equivalent_regions (RouteTimeAxisView& tv, uint32_t ignored, RegionView* basis, vector<RegionView*>* all_equivs)
+{
+       boost::shared_ptr<Playlist> pl;
+       vector<boost::shared_ptr<Region> > results;
+       RegionView* marv;
+       boost::shared_ptr<Diskstream> ds;
+
+       if ((ds = tv.get_diskstream()) == 0) {
+               /* bus */
+               return;
+       }
+
+       if (&tv == &basis->get_time_axis_view()) {
+               /* looking in same track as the original */
+               return;
+       }
+
+       if ((pl = ds->playlist()) != 0) {
+               pl->get_equivalent_regions (basis->region(), results);
+       }
+
+       for (vector<boost::shared_ptr<Region> >::iterator ir = results.begin(); ir != results.end(); ++ir) {
+               if ((marv = tv.view()->find_view (*ir)) != 0) {
+                       all_equivs->push_back (marv);
+               }
+       }
+}
+
+void
+Editor::get_equivalent_regions (RegionView* basis, vector<RegionView*>& equivalent_regions)
+{
+       mapover_tracks (bind (mem_fun (*this, &Editor::mapped_get_equivalent_regions), basis, &equivalent_regions));
+       
+       /* add clicked regionview since we skipped all other regions in the same track as the one it was in */
+       
+       equivalent_regions.push_back (basis);
+}
+
+bool
+Editor::set_selected_regionview_from_click (bool press, Selection::Operation op, bool no_track_remove)
+{
+       vector<RegionView*> all_equivalent_regions;
+       bool commit = false;
+
+       if (!clicked_regionview || !clicked_routeview) {
+               return false;
+       }
+
+       if (press) {
+               button_release_can_deselect = false;
+       } 
+
+       if (op == Selection::Toggle || op == Selection::Set) {
+
+
+               switch (op) {
+               case Selection::Toggle:
+                       
+                       if (clicked_regionview->get_selected()) {
+                               if (press) {
+
+                                       /* whatever was clicked was selected already; do nothing here but allow
+                                          the button release to deselect it
+                                       */
+
+                                       button_release_can_deselect = true;
+
+                               } else {
+
+                                       if (button_release_can_deselect) {
+
+                                               /* just remove this one region, but only on a permitted button release */
+
+                                               selection->remove (clicked_regionview);
+                                               commit = true;
+
+                                               /* no more deselect action on button release till a new press
+                                                  finds an already selected object.
+                                               */
+
+                                               button_release_can_deselect = false;
+                                       }
+                               } 
+
+                       } else {
+
+                               if (press) {
+
+                                       if (selection->selected (clicked_routeview)) {
+                                               get_equivalent_regions (clicked_regionview, all_equivalent_regions);
+                                       } else {
+                                               all_equivalent_regions.push_back (clicked_regionview);
+                                       }
+
+                                       /* add all the equivalent regions, but only on button press */
+                                       
+
+
+                                       if (!all_equivalent_regions.empty()) {
+                                               commit = true;
+                                       }
+
+                                       selection->add (all_equivalent_regions);
+                               } 
+                       }
+                       break;
+                       
+               case Selection::Set:
+                       if (!clicked_regionview->get_selected()) {
+
+                               if (selection->selected (clicked_routeview)) {
+                                       get_equivalent_regions (clicked_regionview, all_equivalent_regions);
+                               } else {
+                                       all_equivalent_regions.push_back (clicked_regionview);
+                               }
+
+                               selection->set (all_equivalent_regions);
+                               commit = true;
+                       } else {
+                               /* no commit necessary: clicked on an already selected region */
+                               goto out;
+                       }
+                       break;
+
+               default:
+                       /* silly compiler */
+                       break;
+               }
+
+       } else if (op == Selection::Extend) {
+
+               list<Selectable*> results;
+               nframes_t last_frame;
+               nframes_t first_frame;
+
+               /* 1. find the last selected regionview in the track that was clicked in */
+
+               last_frame = 0;
+               first_frame = max_frames;
+
+               for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+                       if (&(*x)->get_time_axis_view() == &clicked_regionview->get_time_axis_view()) {
+
+                               if ((*x)->region()->last_frame() > last_frame) {
+                                       last_frame = (*x)->region()->last_frame();
+                               }
+
+                               if ((*x)->region()->first_frame() < first_frame) {
+                                       first_frame = (*x)->region()->first_frame();
+                               }
+                       }
+               }
+
+               /* 2. figure out the boundaries for our search for new objects */
+
+               switch (clicked_regionview->region()->coverage (first_frame, last_frame)) {
+               case OverlapNone:
+                       if (last_frame < clicked_regionview->region()->first_frame()) {
+                               first_frame = last_frame;
+                               last_frame = clicked_regionview->region()->last_frame();
+                       } else {
+                               last_frame = first_frame;
+                               first_frame = clicked_regionview->region()->first_frame();
+                       }
+                       break;
+
+               case OverlapExternal:
+                       if (last_frame < clicked_regionview->region()->first_frame()) {
+                               first_frame = last_frame;
+                               last_frame = clicked_regionview->region()->last_frame();
+                       } else {
+                               last_frame = first_frame;
+                               first_frame = clicked_regionview->region()->first_frame();
+                       }
+                       break;
+
+               case OverlapInternal:
+                       if (last_frame < clicked_regionview->region()->first_frame()) {
+                               first_frame = last_frame;
+                               last_frame = clicked_regionview->region()->last_frame();
+                       } else {
+                               last_frame = first_frame;
+                               first_frame = clicked_regionview->region()->first_frame();
+                       }
+                       break;
+
+               case OverlapStart:
+               case OverlapEnd:
+                       /* nothing to do except add clicked region to selection, since it
+                          overlaps with the existing selection in this track.
+                       */
+                       break;
+               }
+
+               /* 2. find all selectable objects (regionviews in this case) between that one and the end of the
+                     one that was clicked.
+               */
+
+               set<RouteTimeAxisView*> relevant_tracks;
+               
+               get_relevant_tracks (relevant_tracks);
+
+               for (set<RouteTimeAxisView*>::iterator t = relevant_tracks.begin(); t != relevant_tracks.end(); ++t) {
+                       (*t)->get_selectables (first_frame, last_frame, -1.0, -1.0, results);
+               }
+               
+               /* 3. convert to a vector of audio regions */
+
+               vector<RegionView*> regions;
+               
+               for (list<Selectable*>::iterator x = results.begin(); x != results.end(); ++x) {
+                       RegionView* arv;
+
+                       if ((arv = dynamic_cast<RegionView*>(*x)) != 0) {
+                               regions.push_back (arv);
+                       }
+               }
+
+               if (!regions.empty()) {
+                       selection->add (regions);
+                       commit = true;
+               }
+       }
+
+  out:
+       return commit;
+}
+
+void
+Editor::set_selected_regionview_from_region_list (boost::shared_ptr<Region> region, Selection::Operation op)
+{
+       vector<RegionView*> all_equivalent_regions;
+
+       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+               
+               RouteTimeAxisView* tatv;
+               
+               if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
+                       
+                       boost::shared_ptr<Playlist> pl;
+                       vector<boost::shared_ptr<Region> > results;
+                       RegionView* marv;
+                       boost::shared_ptr<Diskstream> ds;
+                       
+                       if ((ds = tatv->get_diskstream()) == 0) {
+                               /* bus */
+                               continue;
+                       }
+                       
+                       if ((pl = (ds->playlist())) != 0) {
+                               pl->get_region_list_equivalent_regions (region, results);
+                       }
+                       
+                       for (vector<boost::shared_ptr<Region> >::iterator ir = results.begin(); ir != results.end(); ++ir) {
+                               if ((marv = tatv->view()->find_view (*ir)) != 0) {
+                                       all_equivalent_regions.push_back (marv);
+                               }
+                       }
+                       
+               }
+       }
+       
+       begin_reversible_command (_("set selected regions"));
+       
+       switch (op) {
+       case Selection::Toggle:
+               /* XXX this is not correct */
+               selection->toggle (all_equivalent_regions);
+               break;
+       case Selection::Set:
+               selection->set (all_equivalent_regions);
+               break;
+       case Selection::Extend:
+               selection->add (all_equivalent_regions);
+               break;
+       case Selection::Add:
+               selection->add (all_equivalent_regions);
+               break;
+       }
+
+       commit_reversible_command () ;
+}
+
+bool
+Editor::set_selected_regionview_from_map_event (GdkEventAny* ev, StreamView* sv, boost::weak_ptr<Region> weak_r)
+{
+       RegionView* rv;
+       boost::shared_ptr<Region> r (weak_r.lock());
+
+       if (!r) {
+               return true;
+       }
+
+       boost::shared_ptr<AudioRegion> ar;
+
+       if ((ar = boost::dynamic_pointer_cast<AudioRegion> (r)) == 0) {
+               return true;
+       }
+
+       if ((rv = sv->find_view (ar)) == 0) {
+               return true;
+       }
+
+       /* don't reset the selection if its something other than 
+          a single other region.
+       */
+
+       if (selection->regions.size() > 1) {
+               return true;
+       }
+       
+       begin_reversible_command (_("set selected regions"));
+       
+       selection->set (rv);
+
+       commit_reversible_command () ;
+
+       return true;
+}
+
+void
+Editor::track_selection_changed ()
+{
+       switch (selection->tracks.size()){
+       case 0:
+               break;
+       default:
+               set_selected_mixer_strip (*(selection->tracks.front()));
+               break;
+       }
+
+       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+               (*i)->set_selected (false);
+               if (mouse_mode == MouseRange) {
+                       (*i)->hide_selection ();
+               }
+       }
+
+       for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+               (*i)->set_selected (true);
+               if (mouse_mode == MouseRange) {
+                       (*i)->show_selection (selection->time);
+               }
+       }
+}
+
+void
+Editor::time_selection_changed ()
+{
+       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+               (*i)->hide_selection ();
+       }
+
+       if (selection->tracks.empty()) {
+               for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+                       (*i)->show_selection (selection->time);
+               }
+       } else {
+               for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+                       (*i)->show_selection (selection->time);
+               }
+       }
+
+       if (selection->time.empty()) {
+               ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, false);
+       } else {
+               ActionManager::set_sensitive (ActionManager::time_selection_sensitive_actions, true);
+       }
+}
+
+void
+Editor::region_selection_changed ()
+{
+       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+               (*i)->set_selected_regionviews (selection->regions);
+       }
+}
+
+void
+Editor::point_selection_changed ()
+{
+       for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+               (*i)->set_selected_points (selection->points);
+       }
+}
+
+void
+Editor::select_all_in_track (Selection::Operation op)
+{
+       list<Selectable *> touched;
+
+       if (!clicked_routeview) {
+               return;
+       }
+       
+       clicked_routeview->get_selectables (0, max_frames, 0, DBL_MAX, touched);
+
+       switch (op) {
+       case Selection::Toggle:
+               selection->add (touched);
+               break;
+       case Selection::Set:
+               selection->set (touched);
+               break;
+       case Selection::Extend:
+               /* meaningless, because we're selecting everything */
+               break;
+       case Selection::Add:
+               selection->add (touched);
+               break;
+       }
+}
+
+void
+Editor::select_all (Selection::Operation op)
+{
+       list<Selectable *> touched;
+       
+       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+               if ((*iter)->hidden()) {
+                       continue;
+               }
+               (*iter)->get_selectables (0, max_frames, 0, DBL_MAX, touched);
+       }
+       begin_reversible_command (_("select all"));
+       switch (op) {
+       case Selection::Add:
+               selection->add (touched);
+               break;
+       case Selection::Toggle:
+               selection->add (touched);
+               break;
+       case Selection::Set:
+               selection->set (touched);
+               break;
+       case Selection::Extend:
+               /* meaningless, because we're selecting everything */
+               break;
+       }
+       commit_reversible_command ();
+}
+
+void
+Editor::invert_selection_in_track ()
+{
+       list<Selectable *> touched;
+
+       if (!clicked_routeview) {
+               return;
+       }
+       
+       clicked_routeview->get_inverted_selectables (*selection, touched);
+       selection->set (touched);
+}
+
+void
+Editor::invert_selection ()
+{
+       list<Selectable *> touched;
+       
+       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+               if ((*iter)->hidden()) {
+                       continue;
+               }
+               (*iter)->get_inverted_selectables (*selection, touched);
+       }
+
+       selection->set (touched);
+}
+
+bool
+Editor::select_all_within (nframes_t start, nframes_t end, double top, double bot, Selection::Operation op)
+{
+       list<Selectable*> touched;
+       list<Selectable*>::size_type n = 0;
+       TrackViewList touched_tracks;
+
+       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+               if ((*iter)->hidden()) {
+                       continue;
+               }
+
+               n = touched.size();
+
+               (*iter)->get_selectables (start, end, top, bot, touched);
+
+               if (n != touched.size()) {
+                       touched_tracks.push_back (*iter);
+               }
+       }
+
+       if (!touched_tracks.empty()) {
+               switch (op) {
+               case Selection::Add:
+                       selection->add (touched_tracks);
+                       break;
+               case Selection::Toggle:
+                       selection->toggle (touched_tracks);
+                       break;
+               case Selection::Set:
+                       selection->set (touched_tracks);
+                       break;
+               case Selection::Extend:
+                       /* not defined yet */
+                       break;
+               }
+       }
+               
+       begin_reversible_command (_("select all within"));
+       switch (op) {
+       case Selection::Add:
+               selection->add (touched);
+               break;
+       case Selection::Toggle:
+               selection->toggle (touched);
+               break;
+       case Selection::Set:
+               selection->set (touched);
+               break;
+       case Selection::Extend:
+               /* not defined yet */
+               break;
+       }
+
+       commit_reversible_command ();
+       return !touched.empty();
+}
+
+void
+Editor::set_selection_from_audio_region ()
+{
+       if (selection->regions.empty()) {
+               return;
+       }
+
+       RegionView* rv = *(selection->regions.begin());
+       boost::shared_ptr<Region> region = rv->region();
+       
+       begin_reversible_command (_("set selection from region"));
+       selection->set (0, region->position(), region->last_frame());
+       commit_reversible_command ();
+
+       set_mouse_mode (Editing::MouseRange, false);
+}
+
+void
+Editor::set_selection_from_punch()
+{
+       Location* location;
+
+       if ((location = session->locations()->auto_punch_location()) == 0)  {
+               return;
+       }
+
+       set_selection_from_range (*location);
+}
+
+void
+Editor::set_selection_from_loop()
+{
+       Location* location;
+
+       if ((location = session->locations()->auto_loop_location()) == 0)  {
+               return;
+       }
+       set_selection_from_range (*location);
+}
+
+void
+Editor::set_selection_from_range (Location& loc)
+{
+       begin_reversible_command (_("set selection from range"));
+       selection->set (0, loc.start(), loc.end());
+       commit_reversible_command ();
+
+       set_mouse_mode (Editing::MouseRange, false);
+}
+
+void
+Editor::select_all_selectables_using_time_selection ()
+{
+       list<Selectable *> touched;
+
+       if (selection->time.empty()) {
+               return;
+       }
+
+       nframes_t start = selection->time[clicked_selection].start;
+       nframes_t end = selection->time[clicked_selection].end;
+
+       if (end - start < 1)  {
+               return;
+       }
+
+       for (TrackViewList::iterator iter = selection->tracks.begin(); iter != selection->tracks.end(); ++iter) {
+               if ((*iter)->hidden()) {
+                       continue;
+               }
+               (*iter)->get_selectables (start, end - 1, 0, DBL_MAX, touched);
+       }
+
+       begin_reversible_command (_("select all from range"));
+       selection->set (touched);
+       commit_reversible_command ();
+}
+
+
+void
+Editor::select_all_selectables_using_punch()
+{
+       Location* location = session->locations()->auto_punch_location();
+       list<Selectable *> touched;
+
+       if (location == 0 || (location->end() - location->start() <= 1))  {
+               return;
+       }
+
+       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+               if ((*iter)->hidden()) {
+                       continue;
+               }
+               (*iter)->get_selectables (location->start(), location->end() - 1, 0, DBL_MAX, touched);
+       }
+       begin_reversible_command (_("select all from punch"));
+       selection->set (touched);
+       commit_reversible_command ();
+
+}
+
+void
+Editor::select_all_selectables_using_loop()
+{
+       Location* location = session->locations()->auto_loop_location();
+       list<Selectable *> touched;
+
+       if (location == 0 || (location->end() - location->start() <= 1))  {
+               return;
+       }
+
+       for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
+               if ((*iter)->hidden()) {
+                       continue;
+               }
+               (*iter)->get_selectables (location->start(), location->end() - 1, 0, DBL_MAX, touched);
+       }
+       begin_reversible_command (_("select all from loop"));
+       selection->set (touched);
+       commit_reversible_command ();
+
+}
+
+void
+Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after)
+{
+        nframes_t start;
+       nframes_t end;
+       list<Selectable *> touched;
+
+       if (after) {
+               begin_reversible_command (_("select all after cursor"));
+               start = cursor->current_frame ;
+               end = session->current_end_frame();
+       } else {
+               if (cursor->current_frame > 0) {
+                       begin_reversible_command (_("select all before cursor"));
+                       start = 0;
+                       end = cursor->current_frame - 1;
+               } else {
+                       return;
+               }
+       }
+
+       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_cursors (Cursor *cursor, Cursor *other_cursor)
+{
+        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;
+       }
+
+       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 ();
+}
+
index cedded1d9b16ca3e4d6585548fcdd3263d75980e..2d7cd5883ef92ecd5e3981ce895285bf824453df 100644 (file)
@@ -40,6 +40,7 @@
 #include "logmeter.h"
 #include "gui_thread.h"
 #include "keyboard.h"
+#include "public_editor.h"
 
 #include <ardour/session.h>
 #include <ardour/route.h>
@@ -567,7 +568,11 @@ GainMeter::gain_activated ()
 
                f = min (f, 6.0f);
 
-               _io->set_gain (dB_to_coefficient (f), this);
+               _io->set_gain (dB_to_coefficient(f), this);
+
+               if (gain_display.has_focus()) {
+                       PublicEditor::instance().reset_focus();
+               }
        }
 }
 
index 51fc20c457b85ac8f23a0be68382d2fc032f6cf7..6aaea06a7ea0aaeacb3b73c139b325c4ae00b3a7 100644 (file)
@@ -196,7 +196,7 @@ LadspaPluginUI::build ()
                                        frame->add (*box);
                                        hpacker.pack_start(*frame,true,true);
 
-                                       x = 0;
+                                       x = 1;
                                }
                        }
 
index 51a29bbb1727fddf6d963926793cbc90c6cd7689..e7ede36b39ee9f558fde5d05e1aa6199cddc2776 100644 (file)
@@ -367,6 +367,11 @@ int main (int argc, char *argv[])
        gtk_set_locale ();
 
        (void) bindtextdomain (PACKAGE, LOCALEDIR);
+       /* our i18n translations are all in UTF-8, so make sure
+          that even if the user locale doesn't specify UTF-8,
+          we use that when handling them.
+       */
+       (void) bind_textdomain_codeset (PACKAGE,"UTF-8");
        (void) textdomain (PACKAGE);
 
        pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, 0);
index f8ac19f833b6d92b970bc4b98d2cb6d29c3e392d..20e3cdc0b79844ee528013879071e87cf1e5d812 100644 (file)
@@ -8,7 +8,7 @@ msgstr ""
 "Project-Id-Version: gtk-ardour 0.347.2\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2006-11-24 00:48+0100\n"
-"PO-Revision-Date: 2006-12-04 13:34+0100\n"
+"PO-Revision-Date: 2007-01-18 13:04+0100\n"
 "Last-Translator: Sebastian Arnold <mail@sebastian-arnold.net>\n"
 "Language-Team: Deutsch <de@li.org>\n"
 "MIME-Version: 1.0\n"
@@ -16,6 +16,8 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Generator: KBabel 0.9.6\n"
+"X-Poedit-Language: German\n"
+"X-Poedit-Country: GERMANY\n"
 
 #: gtk2_ardour/about.cc:121
 msgid "Paul Davis"
@@ -125,14 +127,22 @@ msgstr ""
 msgid "Robert Jordens"
 msgstr ""
 
-#: gtk2_ardour/about.cc:152
+#: gtk2_ardour/about.cc:148
+msgid "Brian Ahr"
+msgstr ""
+
+#: gtk2_ardour/about.cc:149
+msgid "Nimal Ratnayake"
+msgstr ""
+
+#: gtk2_ardour/about.cc:154
 msgid ""
 "French:\n"
 "\tAlain Fréhel <alain.frehel@free.fr>\n"
 "\tChristophe Combelles <ccomb@free.fr>\n"
 msgstr ""
 
-#: gtk2_ardour/about.cc:153
+#: gtk2_ardour/about.cc:155
 msgid ""
 "German:\n"
 "\tKarsten Petersen <kapet@kapet.de>\n"
@@ -141,53 +151,53 @@ msgstr ""
 "\tKarsten Petersen <kapet@kapet.de>\n"
 "\tSebastian Arnold <linux@sebastian-arnold.net>\n"
 
-#: gtk2_ardour/about.cc:154
+#: gtk2_ardour/about.cc:156
 msgid ""
 "Italian:\n"
 "\tFilippo Pappalardo <filippo@email.it>\n"
 msgstr ""
 
-#: gtk2_ardour/about.cc:155
+#: gtk2_ardour/about.cc:157
 msgid ""
 "Portuguese:\n"
 "\tRui Nuno Capela <rncbc@rncbc.org>\n"
 msgstr ""
 
-#: gtk2_ardour/about.cc:156
+#: gtk2_ardour/about.cc:158
 msgid ""
 "Brazilian Portuguese:\n"
 "\tAlexander da Franca Fernandes <alexander@nautae.eti.br>\n"
 "\tChris Ross <chris@tebibyte.org>\n"
 msgstr ""
 
-#: gtk2_ardour/about.cc:158
+#: gtk2_ardour/about.cc:160
 msgid ""
 "Spanish:\n"
 "\t Alex Krohn <alexkrohn@fastmail.fm>\n"
 msgstr ""
 
-#: gtk2_ardour/about.cc:159
+#: gtk2_ardour/about.cc:161
 msgid ""
 "Russian:\n"
 "\t Igor Blinov <pitstop@nm.ru>\n"
 msgstr ""
 
-#: gtk2_ardour/about.cc:187
+#: gtk2_ardour/about.cc:189
 msgid "Copyright (C) 1999-2006 Paul Davis\n"
 msgstr ""
 
-#: gtk2_ardour/about.cc:188
+#: gtk2_ardour/about.cc:190
 msgid ""
 "Ardour comes with ABSOLUTELY NO WARRANTY\n"
 "This is free software, and you are welcome to redistribute it\n"
 "under certain conditions; see the file COPYING for details.\n"
 msgstr ""
 
-#: gtk2_ardour/about.cc:193
+#: gtk2_ardour/about.cc:195
 msgid "visit http://www.ardour.org/"
 msgstr ""
 
-#: gtk2_ardour/about.cc:194
+#: gtk2_ardour/about.cc:196
 msgid ""
 "%1\n"
 "(built from revision %2)"
@@ -201,11 +211,11 @@ msgstr "die UI Definitionsdatei ist falsch formatiert"
 
 #: gtk2_ardour/actions.cc:79
 msgid "Ardour menu definition file not found"
-msgstr "Konnte die Ardour Menü-Definition nicht finden"
+msgstr "Konnte die ardour Menü-Definition nicht finden"
 
 #: gtk2_ardour/actions.cc:83
 msgid "ardour will not work without a valid ardour.menus file"
-msgstr "Ardour benötigt eine gültige ardour.menus Datei"
+msgstr "ardour benötigt eine gültige ardour.menus Datei"
 
 #: gtk2_ardour/actions.cc:235
 msgid "programmer error: %1 %2"
@@ -247,12 +257,12 @@ msgstr "Manuell"
 
 #: gtk2_ardour/add_route_dialog.cc:52
 #: gtk2_ardour/add_route_dialog.cc:177
-#: gtk2_ardour/editor.cc:126
-#: gtk2_ardour/editor.cc:3485
-#: gtk2_ardour/editor_actions.cc:286
+#: gtk2_ardour/editor.cc:127
+#: gtk2_ardour/editor.cc:3549
+#: gtk2_ardour/editor_actions.cc:288
 #: gtk2_ardour/time_axis_view.cc:586
 msgid "Normal"
-msgstr "Normal"
+msgstr "Einrasten"
 
 #: gtk2_ardour/add_route_dialog.cc:53
 #: gtk2_ardour/add_route_dialog.cc:179
@@ -261,7 +271,7 @@ msgstr ""
 
 #: gtk2_ardour/add_route_dialog.cc:62
 msgid "ardour: add track/bus"
-msgstr "Ardour: Füge Spur/Bus hinzu"
+msgstr "ardour: Füge Spur/Bus hinzu"
 
 #: gtk2_ardour/add_route_dialog.cc:63
 #: gtk2_ardour/editor_route_list.cc:71
@@ -274,7 +284,7 @@ msgid "Busses"
 msgstr "Busse"
 
 #: gtk2_ardour/add_route_dialog.cc:96
-#: gtk2_ardour/plugin_ui.cc:150
+#: gtk2_ardour/plugin_ui.cc:151
 msgid "Add"
 msgstr "Hinzufügen"
 
@@ -286,19 +296,19 @@ msgstr "Name für Mixer-Vorlage"
 msgid "Channel Configuration"
 msgstr "Kanaleinstellungen"
 
-#: gtk2_ardour/ardour_ui.cc:106
+#: gtk2_ardour/ardour_ui.cc:108
 msgid ""
 "pre\n"
 "roll"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:107
+#: gtk2_ardour/ardour_ui.cc:109
 msgid ""
 "post\n"
 "roll"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:115
+#: gtk2_ardour/ardour_ui.cc:117
 msgid ""
 "time\n"
 "master"
@@ -306,53 +316,53 @@ msgstr ""
 "Time\n"
 "Master"
 
-#: gtk2_ardour/ardour_ui.cc:117
+#: gtk2_ardour/ardour_ui.cc:119
 msgid "% "
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:119
-#: gtk2_ardour/ardour_ui_ed.cc:275
+#: gtk2_ardour/ardour_ui.cc:121
+#: gtk2_ardour/ardour_ui_ed.cc:274
 msgid "Punch In"
 msgstr "Punch In"
 
-#: gtk2_ardour/ardour_ui.cc:120
-#: gtk2_ardour/ardour_ui_ed.cc:278
+#: gtk2_ardour/ardour_ui.cc:122
+#: gtk2_ardour/ardour_ui_ed.cc:277
 msgid "Punch Out"
 msgstr "Punch Out"
 
-#: gtk2_ardour/ardour_ui.cc:121
-#: gtk2_ardour/ardour_ui_ed.cc:290
+#: gtk2_ardour/ardour_ui.cc:123
+#: gtk2_ardour/ardour_ui_ed.cc:289
 msgid "Auto Return"
 msgstr "Auto Return"
 
-#: gtk2_ardour/ardour_ui.cc:122
+#: gtk2_ardour/ardour_ui.cc:124
 msgid "Autuo Play"
 msgstr "Auto Play"
 
-#: gtk2_ardour/ardour_ui.cc:123
-#: gtk2_ardour/ardour_ui_ed.cc:284
+#: gtk2_ardour/ardour_ui.cc:125
+#: gtk2_ardour/ardour_ui_ed.cc:283
 msgid "Auto Input"
 msgstr "Auto Input"
 
-#: gtk2_ardour/ardour_ui.cc:124
-#: gtk2_ardour/ardour_ui_ed.cc:281
-#: gtk2_ardour/option_editor.cc:128
+#: gtk2_ardour/ardour_ui.cc:126
+#: gtk2_ardour/ardour_ui_ed.cc:280
+#: gtk2_ardour/option_editor.cc:126
 msgid "Click"
 msgstr "Click"
 
-#: gtk2_ardour/ardour_ui.cc:125
+#: gtk2_ardour/ardour_ui.cc:127
 msgid "AUDITION"
 msgstr "VORHÖREN"
 
-#: gtk2_ardour/ardour_ui.cc:126
+#: gtk2_ardour/ardour_ui.cc:128
 msgid "SOLO"
 msgstr "SOLO"
 
-#: gtk2_ardour/ardour_ui.cc:370
+#: gtk2_ardour/ardour_ui.cc:371
 msgid "quit"
 msgstr "Beenden"
 
-#: gtk2_ardour/ardour_ui.cc:379
+#: gtk2_ardour/ardour_ui.cc:380
 msgid ""
 "Ardour was unable to save your session.\n"
 "\n"
@@ -360,37 +370,37 @@ msgid ""
 "\n"
 "\"Just quit\" option."
 msgstr ""
-"Ardour konnte die Sitzung nicht speichern.\n"
+"ardour konnte das Projekt nicht speichern.\n"
 "\n"
 "Wenn Sie trotzdem beenden wollen, wählen Sie bitte\n"
 "\n"
 "\"Trotzdem beenden\"."
 
-#: gtk2_ardour/ardour_ui.cc:398
+#: gtk2_ardour/ardour_ui.cc:404
 msgid "ardour: save session?"
-msgstr "Ardour: Sitzung speichern?"
+msgstr "ardour: Projekt speichern?"
 
-#: gtk2_ardour/ardour_ui.cc:405
+#: gtk2_ardour/ardour_ui.cc:411
 msgid "Don't %1"
 msgstr "Nicht %1"
 
-#: gtk2_ardour/ardour_ui.cc:407
+#: gtk2_ardour/ardour_ui.cc:413
 msgid "Just %1"
 msgstr "%1 ohne zu Speichern"
 
-#: gtk2_ardour/ardour_ui.cc:409
+#: gtk2_ardour/ardour_ui.cc:415
 msgid "Save and %1"
 msgstr "Speichern und %1"
 
-#: gtk2_ardour/ardour_ui.cc:421
+#: gtk2_ardour/ardour_ui.cc:427
 msgid "session"
-msgstr "Sitzung"
+msgstr "Projekt"
 
-#: gtk2_ardour/ardour_ui.cc:423
+#: gtk2_ardour/ardour_ui.cc:429
 msgid "snapshot"
 msgstr "Schnappschuss..."
 
-#: gtk2_ardour/ardour_ui.cc:425
+#: gtk2_ardour/ardour_ui.cc:431
 msgid ""
 "The %1\"%2\"\n"
 "has not been saved.\n"
@@ -400,7 +410,7 @@ msgid ""
 "\n"
 "What do you want to do?"
 msgstr ""
-"Die Sitzung %1\"%2\"\n"
+"Das Projekt %1\"%2\"\n"
 "wurde nicht gespeichert.\n"
 "\n"
 "Alle Ã„nderungen werden verloren\n"
@@ -408,80 +418,80 @@ msgstr ""
 "\n"
 "Was wollen Sie machen?"
 
-#: gtk2_ardour/ardour_ui.cc:439
+#: gtk2_ardour/ardour_ui.cc:445
 msgid "Prompter"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:498
+#: gtk2_ardour/ardour_ui.cc:505
 #, c-format
 msgid "disconnected"
 msgstr "getrennt"
 
-#: gtk2_ardour/ardour_ui.cc:505
+#: gtk2_ardour/ardour_ui.cc:512
 #, c-format
 msgid "%.1f kHz / %4.1f msecs"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:509
+#: gtk2_ardour/ardour_ui.cc:516
 #, c-format
 msgid "%u kHz / %4.1f msecs"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:522
+#: gtk2_ardour/ardour_ui.cc:529
 #, c-format
 msgid "DSP: %.1f%%"
-msgstr "CPU Auslastung: %.1f%%"
+msgstr "CPU: %.1f%%"
 
-#: gtk2_ardour/ardour_ui.cc:532
+#: gtk2_ardour/ardour_ui.cc:539
 #, c-format
 msgid "Buffers p:%<PRIu32>%% c:%<PRIu32>%%"
 msgstr "Buffer p:%<PRIu32>%% c:%<PRIu32>%%"
 
-#: gtk2_ardour/ardour_ui.cc:560
+#: gtk2_ardour/ardour_ui.cc:567
 msgid "Disk: 24hrs+"
 msgstr "Platz: >24 Stunden"
 
-#: gtk2_ardour/ardour_ui.cc:580
+#: gtk2_ardour/ardour_ui.cc:587
 #, c-format
 msgid "Disk: %02dh:%02dm:%02ds"
-msgstr "Platz: %02dh:%02dm:%02ds"
+msgstr "HD: %02dh:%02dm:%02ds"
 
-#: gtk2_ardour/ardour_ui.cc:619
+#: gtk2_ardour/ardour_ui.cc:626
 msgid "programming error: impossible control method"
 msgstr "Programmierfehler: ungültige Kontrollmethode"
 
-#: gtk2_ardour/ardour_ui.cc:727
+#: gtk2_ardour/ardour_ui.cc:734
 #: gtk2_ardour/new_session_dialog.cc:355
 msgid "Recent Sessions"
-msgstr "Zuletzt verwendete Sitzungen"
+msgstr "Zuletzt verwendete Projekte"
 
-#: gtk2_ardour/ardour_ui.cc:820
+#: gtk2_ardour/ardour_ui.cc:827
 msgid "open session"
-msgstr "Sitzung Ã¶ffnen"
+msgstr "Projekt Ã¶ffnen"
 
-#: gtk2_ardour/ardour_ui.cc:826
+#: gtk2_ardour/ardour_ui.cc:833
 msgid "Ardour sessions"
-msgstr "Ardour-Sitzungen"
+msgstr "ardour-Projekte"
 
-#: gtk2_ardour/ardour_ui.cc:859
+#: gtk2_ardour/ardour_ui.cc:866
 msgid "Patience is a virtue.\n"
 msgstr "Geduld ist eine Tugend.\n"
 
-#: gtk2_ardour/ardour_ui.cc:869
+#: gtk2_ardour/ardour_ui.cc:876
 msgid "You cannot add a track or bus without a session already loaded."
-msgstr "Sie können erst Spuren oder Busse hinzufügen, wenn eine Sitzung geladen wurde."
+msgstr "Sie können erst Spuren oder Busse hinzufügen, wenn ein Projekt geladen wurde."
 
-#: gtk2_ardour/ardour_ui.cc:879
-#: gtk2_ardour/ardour_ui.cc:891
+#: gtk2_ardour/ardour_ui.cc:886
+#: gtk2_ardour/ardour_ui.cc:898
 msgid "could not create a new audio track"
 msgstr "Konnte neue Spur nicht erstellen."
 
-#: gtk2_ardour/ardour_ui.cc:881
-#: gtk2_ardour/ardour_ui.cc:893
+#: gtk2_ardour/ardour_ui.cc:888
+#: gtk2_ardour/ardour_ui.cc:900
 msgid "could not create %1 new audio tracks"
 msgstr "Konnte %1 neue Spuren nicht erstellen."
 
-#: gtk2_ardour/ardour_ui.cc:913
+#: gtk2_ardour/ardour_ui.cc:920
 msgid ""
 "There are insufficient JACK ports available\n"
 "to create a new track or bus.\n"
@@ -490,11 +500,11 @@ msgid ""
 msgstr ""
 "Es sind nicht genügend JACK Ports verfügbar\n"
 "um neue Spuren oder Busse zu erstellen.\n"
-"Speichern Sie Ihre Sitzung und starten Sie\n"
-"Ardour sowie JACK mit einer größeren\n"
+"Speichern Sie Ihr Projekt und starten Sie\n"
+"ardour sowie JACK mit einer größeren\n"
 "Anzahl Ports erneut."
 
-#: gtk2_ardour/ardour_ui.cc:1033
+#: gtk2_ardour/ardour_ui.cc:1040
 msgid ""
 "Please create 1 or more track\n"
 "before trying to record.\n"
@@ -502,9 +512,9 @@ msgid ""
 msgstr ""
 "Bitte fügen Sie mindestens eine weitere Spur hinzu,\n"
 "bevor Sie aufnehmen.\n"
-"Weitere Einstellungen finden Sie im Sitzungsmenü."
+"Weitere Einstellungen finden Sie im Projektmenü."
 
-#: gtk2_ardour/ardour_ui.cc:1253
+#: gtk2_ardour/ardour_ui.cc:1260
 msgid ""
 "JACK has either been shutdown or it\n"
 "disconnected Ardour because Ardour\n"
@@ -512,75 +522,66 @@ msgid ""
 "session and/or try to reconnect to JACK ."
 msgstr ""
 "JACK wurde entweder beendet oder\n"
-"hat Ardour getrennt weil Ardour nicht\n"
-"schnell genug war. Sie sollten die Sitzung\n"
-"speichern versuchen, erneut zu JACK zu verbinden."
+"hat ardour getrennt weil Ardour nicht\n"
+"schnell genug war. Sie sollten versuchen,\n"
+"das Projekt zu speichern und erneut mit JACK zu verbinden."
 
-#: gtk2_ardour/ardour_ui.cc:1270
-msgid "Unable to create all required ports"
-msgstr "Ardour konnte nicht alle benötigten Ports erstellen."
-
-#: gtk2_ardour/ardour_ui.cc:1278
+#: gtk2_ardour/ardour_ui.cc:1277
 #, fuzzy
 msgid "Unable to start the session running"
-msgstr "Konnte die aktuelle Sitzung nicht starten"
+msgstr "Konnte das aktuelle Projekt nicht starten"
 
-#: gtk2_ardour/ardour_ui.cc:1384
-#: gtk2_ardour/ardour_ui.cc:1403
-#: gtk2_ardour/audio_clock.cc:448
+#: gtk2_ardour/ardour_ui.cc:1377
+#: gtk2_ardour/ardour_ui.cc:1396
+#: gtk2_ardour/audio_clock.cc:462
 msgid "none"
 msgstr "keine"
 
-#: gtk2_ardour/ardour_ui.cc:1393
-#: gtk2_ardour/ardour_ui.cc:1412
+#: gtk2_ardour/ardour_ui.cc:1386
+#: gtk2_ardour/ardour_ui.cc:1405
 msgid "off"
 msgstr "aus"
 
-#: gtk2_ardour/ardour_ui.cc:1435
+#: gtk2_ardour/ardour_ui.cc:1428
 msgid "Name of New Snapshot"
 msgstr "Name für neuen Schnappschuss"
 
-#: gtk2_ardour/ardour_ui.cc:1581
+#: gtk2_ardour/ardour_ui.cc:1574
 msgid "Name for mix template:"
 msgstr "Name für Mixer-Vorlage"
 
-#: gtk2_ardour/ardour_ui.cc:1582
+#: gtk2_ardour/ardour_ui.cc:1575
 msgid "-template"
 msgstr "Vorlage"
 
-#: gtk2_ardour/ardour_ui.cc:1703
+#: gtk2_ardour/ardour_ui.cc:1696
 msgid ""
 "This session\n"
 "%1\n"
 "already exists. Do you want to open it?"
 msgstr ""
-"Die Sitzung\n"
+"Das Projekt\n"
 "%1\n"
 "existiert bereits. Wollen Sie sie Ã¶ffnen?"
 
-#: gtk2_ardour/ardour_ui.cc:1713
-#, fuzzy
-msgid "existing_session"
-msgstr "Stellen"
-
-#: gtk2_ardour/ardour_ui.cc:1819
+#: gtk2_ardour/ardour_ui.cc:1813
 msgid ""
 "You do not have write access to this session.\n"
 "This prevents the session from being loaded."
 msgstr ""
-"Sie haben keinen Schreibzugriff auf diese Sitzung.\n"
-"Dadurch kann die Sitzung nicht geladen werden."
+"Sie haben keinen Schreibzugriff auf dieses Projekt.\n"
+"Dadurch kann das Projekt nicht geladen werden."
 
-#: gtk2_ardour/ardour_ui.cc:1832
-#: gtk2_ardour/ardour_ui.cc:1889
+#: gtk2_ardour/ardour_ui.cc:1825
+#: gtk2_ardour/ardour_ui.cc:1874
 msgid "Session \"%1 (snapshot %2)\" did not load successfully"
-msgstr "Sitzung  \"%1 (Schnappschuss %2)\" konnte nicht geladen werden."
+msgstr "Projekt  \"%1 (Schnappschuss %2)\" konnte nicht geladen werden."
 
-#: gtk2_ardour/ardour_ui.cc:1948
+#: gtk2_ardour/ardour_ui.cc:1933
 msgid "No audio files were ready for cleanup"
 msgstr "Keine Audiodateien zum Aufräumen vorhanden"
 
-#: gtk2_ardour/ardour_ui.cc:1952
+#: gtk2_ardour/ardour_ui.cc:1937
 msgid ""
 "If this seems suprising, \n"
 "check for any existing snapshots.\n"
@@ -588,25 +589,25 @@ msgid ""
 "require some unused files to continue to exist."
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:1961
+#: gtk2_ardour/ardour_ui.cc:1946
 msgid "ardour: cleanup"
-msgstr "Ardour: Aufräumen"
+msgstr "ardour: Aufräumen"
 
-#: gtk2_ardour/ardour_ui.cc:1997
-#: gtk2_ardour/ardour_ui.cc:2003
+#: gtk2_ardour/ardour_ui.cc:1982
+#: gtk2_ardour/ardour_ui.cc:1988
 msgid "files were"
 msgstr "folgenden Dateien wurden"
 
-#: gtk2_ardour/ardour_ui.cc:1999
-#: gtk2_ardour/ardour_ui.cc:2005
+#: gtk2_ardour/ardour_ui.cc:1984
+#: gtk2_ardour/ardour_ui.cc:1990
 msgid "file was"
 msgstr "folgende Datei wurde"
 
-#: gtk2_ardour/ardour_ui.cc:2046
+#: gtk2_ardour/ardour_ui.cc:2031
 msgid "Are you sure you want to cleanup?"
 msgstr "Sind Sie sicher, dass Sie aufräumen wollen?"
 
-#: gtk2_ardour/ardour_ui.cc:2051
+#: gtk2_ardour/ardour_ui.cc:2036
 msgid ""
 "Cleanup is a destructive operation.\n"
 "ALL undo/redo information will be lost if you cleanup.\n"
@@ -616,25 +617,20 @@ msgstr ""
 "Sämtliche Wiederherstellungsinformationen gehen verloren, wenn Sie aufräumen.\n"
 "Nach dem Aufräumen werden alle nicht benötigten Audiodateien in einen \"dead sounds\" Ordner verschoben."
 
-#: gtk2_ardour/ardour_ui.cc:2057
+#: gtk2_ardour/ardour_ui.cc:2042
 msgid "Clean Up"
 msgstr "Aufräumen"
 
-#: gtk2_ardour/ardour_ui.cc:2060
+#: gtk2_ardour/ardour_ui.cc:2045
 #, fuzzy
 msgid "CleanupDialog"
 msgstr "leeren"
 
-#: gtk2_ardour/ardour_ui.cc:2061
-#, fuzzy
-msgid "ardour_cleanup"
-msgstr "Ardour: Uhr"
-
-#: gtk2_ardour/ardour_ui.cc:2080
+#: gtk2_ardour/ardour_ui.cc:2065
 msgid "cleaned files"
 msgstr "aufgeräumte Dateien"
 
-#: gtk2_ardour/ardour_ui.cc:2081
+#: gtk2_ardour/ardour_ui.cc:2066
 msgid ""
 "The following %1 %2 not in use and \n"
 "have been moved to:\n"
@@ -651,11 +647,11 @@ msgstr ""
 "Wenn Sie den Müll leeren werden weitere\n"
 "%4 %5byte Speicherplatz frei.\n"
 
-#: gtk2_ardour/ardour_ui.cc:2106
+#: gtk2_ardour/ardour_ui.cc:2091
 msgid "deleted file"
 msgstr "gelöschte Datei"
 
-#: gtk2_ardour/ardour_ui.cc:2107
+#: gtk2_ardour/ardour_ui.cc:2092
 msgid ""
 "The following %1 %2 deleted from\n"
 "%3,\n"
@@ -665,11 +661,11 @@ msgstr ""
 "%3,\n"
 "und machten %4 %5byte Speicherplatz frei"
 
-#: gtk2_ardour/ardour_ui.cc:2223
+#: gtk2_ardour/ardour_ui.cc:2208
 msgid "Recording was stopped because your system could not keep up."
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:2234
+#: gtk2_ardour/ardour_ui.cc:2219
 msgid ""
 "The disk system on your computer\n"
 "was not able to keep up with Ardour.\n"
@@ -678,7 +674,7 @@ msgid ""
 "quickly enough to keep up with recording.\n"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:2253
+#: gtk2_ardour/ardour_ui.cc:2238
 msgid ""
 "The disk system on your computer\n"
 "was not able to keep up with Ardour.\n"
@@ -687,7 +683,7 @@ msgid ""
 "quickly enough to keep up with playback.\n"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:2279
+#: gtk2_ardour/ardour_ui.cc:2264
 msgid ""
 "This session appears to have been in\n"
 "middle of recording when ardour or\n"
@@ -698,19 +694,19 @@ msgid ""
 "what you would like to do.\n"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:2289
+#: gtk2_ardour/ardour_ui.cc:2274
 msgid "Recover from crash"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:2290
+#: gtk2_ardour/ardour_ui.cc:2275
 msgid "Ignore crash data"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:2308
+#: gtk2_ardour/ardour_ui.cc:2293
 msgid "Could not disconnect from JACK"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui.cc:2321
+#: gtk2_ardour/ardour_ui.cc:2306
 msgid "Could not reconnect to JACK"
 msgstr ""
 
@@ -752,11 +748,11 @@ msgstr "Bereich/Auswahl wiedergeben"
 
 #: gtk2_ardour/ardour_ui2.cc:298
 msgid "Go to start of session"
-msgstr "An den Anfang der Sitzung springen"
+msgstr "Zum Anfang des Projekts springen"
 
 #: gtk2_ardour/ardour_ui2.cc:299
 msgid "Go to end of session"
-msgstr "Ans Ende der Sitzung springen"
+msgstr "Zum Ende des Projekts springen"
 
 #: gtk2_ardour/ardour_ui2.cc:300
 msgid "Play loop range"
@@ -792,7 +788,7 @@ msgstr ""
 
 #: gtk2_ardour/ardour_ui2.cc:308
 msgid "Does Ardour control the time?"
-msgstr "Bestimmt Ardour die Time?"
+msgstr "Bestimmt ardour die Time?"
 
 #: gtk2_ardour/ardour_ui2.cc:309
 msgid "Shuttle speed control"
@@ -807,15 +803,15 @@ msgstr "Geschwindigkeitsanzeige als Prozent oder Halbtöne einstellen"
 msgid "Current transport speed"
 msgstr "Geschwindigkeitsanzeige"
 
-#: gtk2_ardour/ardour_ui2.cc:334
+#: gtk2_ardour/ardour_ui2.cc:331
 msgid "Primary clock"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui2.cc:335
+#: gtk2_ardour/ardour_ui2.cc:332
 msgid "secondary clock"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui2.cc:366
+#: gtk2_ardour/ardour_ui2.cc:363
 msgid ""
 "When active, something is soloed.\n"
 "Click to de-solo everything"
@@ -823,7 +819,7 @@ msgstr ""
 "Wird aktiv, wenn eine Spur Solo läuft.\n"
 "Schaltet bei Klick Solo aus."
 
-#: gtk2_ardour/ardour_ui2.cc:367
+#: gtk2_ardour/ardour_ui2.cc:364
 msgid ""
 "When active, auditioning is taking place\n"
 "Click to stop the audition"
@@ -831,49 +827,48 @@ msgstr ""
 "Wird beim Vorhören aktiv.\n"
 "Klicken stoppt das Vorhören."
 
-#: gtk2_ardour/ardour_ui2.cc:395
-#: gtk2_ardour/ardour_ui2.cc:826
-#: gtk2_ardour/ardour_ui2.cc:882
-#: gtk2_ardour/ardour_ui_options.cc:804
+#: gtk2_ardour/ardour_ui2.cc:392
+#: gtk2_ardour/ardour_ui2.cc:823
+#: gtk2_ardour/ardour_ui2.cc:879
+#: gtk2_ardour/ardour_ui_options.cc:811
 msgid "sprung"
 msgstr "Feder"
 
-#: gtk2_ardour/ardour_ui2.cc:396
-#: gtk2_ardour/ardour_ui2.cc:828
-#: gtk2_ardour/ardour_ui_options.cc:815
+#: gtk2_ardour/ardour_ui2.cc:393
+#: gtk2_ardour/ardour_ui2.cc:825
+#: gtk2_ardour/ardour_ui_options.cc:822
 msgid "wheel"
 msgstr "Drehrad"
 
-#: gtk2_ardour/ardour_ui2.cc:602
+#: gtk2_ardour/ardour_ui2.cc:599
 msgid "Maximum speed"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui2.cc:838
-#: gtk2_ardour/ardour_ui2.cc:861
+#: gtk2_ardour/ardour_ui2.cc:835
+#: gtk2_ardour/ardour_ui2.cc:858
 msgid "stop"
 msgstr "Stop"
 
-#: gtk2_ardour/ardour_ui2.cc:880
+#: gtk2_ardour/ardour_ui2.cc:877
 msgid "-0.55"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_dialogs.cc:146
-#: gtk2_ardour/playlist_selector.cc:70
+#: gtk2_ardour/ardour_ui_dependents.cc:85
+msgid "Ardour key bindings file not found at \"%1\" or contains errors."
+msgstr ""
+
+#: gtk2_ardour/ardour_ui_dialogs.cc:149
+#: gtk2_ardour/playlist_selector.cc:69
 msgid "close"
 msgstr "Schließen"
 
-#: gtk2_ardour/ardour_ui_dialogs.cc:353
-#: gtk2_ardour/ardour_ui_ed.cc:192
-msgid "Sound File Browser"
-msgstr "Audio-Browser"
-
 #: gtk2_ardour/ardour_ui_ed.cc:77
 msgid "Session"
-msgstr "Sitzung"
+msgstr "Projekt"
 
 #: gtk2_ardour/ardour_ui_ed.cc:78
 #: gtk2_ardour/ardour_ui_ed.cc:138
-#: gtk2_ardour/editor.cc:1713
+#: gtk2_ardour/editor.cc:1622
 #: gtk2_ardour/export_dialog.cc:348
 #: gtk2_ardour/export_dialog.cc:1057
 #: gtk2_ardour/export_dialog.cc:1061
@@ -885,7 +880,7 @@ msgid "Cleanup"
 msgstr "Aufräumen"
 
 #: gtk2_ardour/ardour_ui_ed.cc:80
-#: gtk2_ardour/option_editor.cc:125
+#: gtk2_ardour/option_editor.cc:123
 msgid "Sync"
 msgstr ""
 
@@ -931,13 +926,13 @@ msgid "Hold Time"
 msgstr "Pegelanzeige halten"
 
 #: gtk2_ardour/ardour_ui_ed.cc:95
-#: gtk2_ardour/route_time_axis.cc:1288
-#: gtk2_ardour/new_session_dialog.cc:600
+#: gtk2_ardour/route_time_axis.cc:1308
+#: gtk2_ardour/new_session_dialog.cc:612
 msgid "New"
 msgstr "Neu..."
 
 #: gtk2_ardour/ardour_ui_ed.cc:97
-#: gtk2_ardour/new_session_dialog.cc:587
+#: gtk2_ardour/new_session_dialog.cc:599
 msgid "Open"
 msgstr "Öffnen..."
 
@@ -947,7 +942,7 @@ msgstr "Zuletzt verwendet..."
 
 #: gtk2_ardour/ardour_ui_ed.cc:99
 #: gtk2_ardour/io_selector.cc:60
-#: gtk2_ardour/io_selector.cc:749
+#: gtk2_ardour/io_selector.cc:748
 #: gtk2_ardour/connection_editor.cc:59
 msgid "Close"
 msgstr "Schließen"
@@ -971,7 +966,7 @@ msgstr "Als Vorlage Speichern..."
 
 #: gtk2_ardour/ardour_ui_ed.cc:127
 msgid "Export session to audiofile..."
-msgstr "Exportiere Sitzung als Audio-Datei..."
+msgstr "Exportiere Projekt als Audio-Datei..."
 
 #: gtk2_ardour/ardour_ui_ed.cc:130
 msgid "Export selection to audiofile..."
@@ -1031,467 +1026,478 @@ msgstr "Editor anzeigen"
 msgid "Show Mixer"
 msgstr "Mixer anzeigen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:193
+#: gtk2_ardour/ardour_ui_ed.cc:192
 msgid "Options Editor"
-msgstr "Optionen"
+msgstr "Einstellungen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:194
+#: gtk2_ardour/ardour_ui_ed.cc:193
 msgid "Track/Bus Inspector"
 msgstr "Verbindungen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:196
+#: gtk2_ardour/ardour_ui_ed.cc:195
 #: gtk2_ardour/connection_editor.cc:147
 #: gtk2_ardour/connection_editor.cc:148
 msgid "Connections"
 msgstr "Verbindungen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:198
+#: gtk2_ardour/ardour_ui_ed.cc:197
 msgid "Locations"
-msgstr "Lokatoren"
+msgstr "Positionen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:200
+#: gtk2_ardour/ardour_ui_ed.cc:199
 msgid "Big Clock"
 msgstr "Große Uhr"
 
-#: gtk2_ardour/ardour_ui_ed.cc:202
+#: gtk2_ardour/ardour_ui_ed.cc:201
 msgid "About"
-msgstr "Ãœber Ardour..."
+msgstr "Ãœber ardour..."
 
-#: gtk2_ardour/ardour_ui_ed.cc:203
+#: gtk2_ardour/ardour_ui_ed.cc:202
 msgid "Colors"
 msgstr "Farben"
 
-#: gtk2_ardour/ardour_ui_ed.cc:205
+#: gtk2_ardour/ardour_ui_ed.cc:204
 msgid "Add Audio Track"
 msgstr "Audiospur hinzufügen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:207
+#: gtk2_ardour/ardour_ui_ed.cc:206
 msgid "Add Audio Bus"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:209
+#: gtk2_ardour/ardour_ui_ed.cc:208
 msgid "Save"
 msgstr "Speichern"
 
-#: gtk2_ardour/ardour_ui_ed.cc:211
-#: gtk2_ardour/editor_actions.cc:256
+#: gtk2_ardour/ardour_ui_ed.cc:210
+#: gtk2_ardour/editor_actions.cc:258
 msgid "Remove Last Capture"
 msgstr "Letzte Aufnahme entfernen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:218
+#: gtk2_ardour/ardour_ui_ed.cc:217
 msgid "Transport"
 msgstr "Transport"
 
-#: gtk2_ardour/ardour_ui_ed.cc:224
+#: gtk2_ardour/ardour_ui_ed.cc:223
 #: gtk2_ardour/sfdb_ui.cc:60
 msgid "Stop"
 msgstr "Stop"
 
-#: gtk2_ardour/ardour_ui_ed.cc:227
+#: gtk2_ardour/ardour_ui_ed.cc:226
 msgid "Roll"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:231
+#: gtk2_ardour/ardour_ui_ed.cc:230
 msgid "Start/Stop"
 msgstr "Start/Stop"
 
-#: gtk2_ardour/ardour_ui_ed.cc:234
+#: gtk2_ardour/ardour_ui_ed.cc:233
 msgid "Stop + Forget Capture"
 msgstr "Stop + Aufnahme verwerfen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:237
+#: gtk2_ardour/ardour_ui_ed.cc:236
 msgid "Play Loop Range"
 msgstr "Schleife wiedergeben"
 
-#: gtk2_ardour/ardour_ui_ed.cc:240
+#: gtk2_ardour/ardour_ui_ed.cc:239
 msgid "Play Selection"
 msgstr "Auswahl wiedergeben"
 
-#: gtk2_ardour/ardour_ui_ed.cc:244
+#: gtk2_ardour/ardour_ui_ed.cc:243
 msgid "Enable Record"
 msgstr "Aufnahme aktivieren"
 
-#: gtk2_ardour/ardour_ui_ed.cc:247
+#: gtk2_ardour/ardour_ui_ed.cc:246
 msgid "Rewind"
 msgstr "Rückwärts"
 
-#: gtk2_ardour/ardour_ui_ed.cc:250
+#: gtk2_ardour/ardour_ui_ed.cc:249
 msgid "Rewind (Slow)"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:253
+#: gtk2_ardour/ardour_ui_ed.cc:252
 msgid "Rewind (Fast)"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:256
+#: gtk2_ardour/ardour_ui_ed.cc:255
 msgid "Forward"
 msgstr "Vorwärts"
 
-#: gtk2_ardour/ardour_ui_ed.cc:259
+#: gtk2_ardour/ardour_ui_ed.cc:258
 msgid "Forward (Slow)"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:262
+#: gtk2_ardour/ardour_ui_ed.cc:261
 msgid "Forward (Fast)"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:265
+#: gtk2_ardour/ardour_ui_ed.cc:264
 msgid "Goto Zero"
 msgstr "Zum Nullpunkt springen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:268
+#: gtk2_ardour/ardour_ui_ed.cc:267
 msgid "Goto Start"
 msgstr "Zum Anfang springen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:271
+#: gtk2_ardour/ardour_ui_ed.cc:270
 msgid "Goto End"
 msgstr "Zum Ende Springen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:287
+#: gtk2_ardour/ardour_ui_ed.cc:286
 msgid "Auto Play"
 msgstr "Auto Play"
 
-#: gtk2_ardour/ardour_ui_ed.cc:294
+#: gtk2_ardour/ardour_ui_ed.cc:293
 msgid "Sync startup to video"
 msgstr "Mit Video synchronisieren"
 
-#: gtk2_ardour/ardour_ui_ed.cc:295
+#: gtk2_ardour/ardour_ui_ed.cc:294
 msgid "Time master"
 msgstr "Time Master"
 
-#: gtk2_ardour/ardour_ui_ed.cc:298
+#: gtk2_ardour/ardour_ui_ed.cc:297
 msgid "Toggle Record Enable Track1"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:300
+#: gtk2_ardour/ardour_ui_ed.cc:299
 msgid "Toggle Record Enable Track2"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:302
+#: gtk2_ardour/ardour_ui_ed.cc:301
 msgid "Toggle Record Enable Track3"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:304
+#: gtk2_ardour/ardour_ui_ed.cc:303
 msgid "Toggle Record Enable Track4"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:306
+#: gtk2_ardour/ardour_ui_ed.cc:305
 msgid "Toggle Record Enable Track5"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:308
+#: gtk2_ardour/ardour_ui_ed.cc:307
 msgid "Toggle Record Enable Track6"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:310
+#: gtk2_ardour/ardour_ui_ed.cc:309
 msgid "Toggle Record Enable Track7"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:312
+#: gtk2_ardour/ardour_ui_ed.cc:311
 msgid "Toggle Record Enable Track8"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:314
+#: gtk2_ardour/ardour_ui_ed.cc:313
 msgid "Toggle Record Enable Track9"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:316
+#: gtk2_ardour/ardour_ui_ed.cc:315
 msgid "Toggle Record Enable Track10"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:318
+#: gtk2_ardour/ardour_ui_ed.cc:317
 msgid "Toggle Record Enable Track11"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:320
+#: gtk2_ardour/ardour_ui_ed.cc:319
 msgid "Toggle Record Enable Track12"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:322
+#: gtk2_ardour/ardour_ui_ed.cc:321
 msgid "Toggle Record Enable Track13"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:324
+#: gtk2_ardour/ardour_ui_ed.cc:323
 msgid "Toggle Record Enable Track14"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:326
+#: gtk2_ardour/ardour_ui_ed.cc:325
 msgid "Toggle Record Enable Track15"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:328
+#: gtk2_ardour/ardour_ui_ed.cc:327
 msgid "Toggle Record Enable Track16"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:330
+#: gtk2_ardour/ardour_ui_ed.cc:329
 msgid "Toggle Record Enable Track17"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:332
+#: gtk2_ardour/ardour_ui_ed.cc:331
 msgid "Toggle Record Enable Track18"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:334
+#: gtk2_ardour/ardour_ui_ed.cc:333
 msgid "Toggle Record Enable Track19"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:336
+#: gtk2_ardour/ardour_ui_ed.cc:335
 msgid "Toggle Record Enable Track20"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:338
+#: gtk2_ardour/ardour_ui_ed.cc:337
 msgid "Toggle Record Enable Track21"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:340
+#: gtk2_ardour/ardour_ui_ed.cc:339
 msgid "Toggle Record Enable Track22"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:342
+#: gtk2_ardour/ardour_ui_ed.cc:341
 msgid "Toggle Record Enable Track23"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:344
+#: gtk2_ardour/ardour_ui_ed.cc:343
 msgid "Toggle Record Enable Track24"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:346
+#: gtk2_ardour/ardour_ui_ed.cc:345
 msgid "Toggle Record Enable Track25"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:348
+#: gtk2_ardour/ardour_ui_ed.cc:347
 msgid "Toggle Record Enable Track26"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:350
+#: gtk2_ardour/ardour_ui_ed.cc:349
 msgid "Toggle Record Enable Track27"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:352
+#: gtk2_ardour/ardour_ui_ed.cc:351
 msgid "Toggle Record Enable Track28"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:354
+#: gtk2_ardour/ardour_ui_ed.cc:353
 msgid "Toggle Record Enable Track29"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:356
+#: gtk2_ardour/ardour_ui_ed.cc:355
 msgid "Toggle Record Enable Track30"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:358
+#: gtk2_ardour/ardour_ui_ed.cc:357
 msgid "Toggle Record Enable Track31"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:360
+#: gtk2_ardour/ardour_ui_ed.cc:359
 msgid "Toggle Record Enable Track32"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:365
+#: gtk2_ardour/ardour_ui_ed.cc:364
 msgid "Percentage"
 msgstr "Prozent"
 
-#: gtk2_ardour/ardour_ui_ed.cc:366
+#: gtk2_ardour/ardour_ui_ed.cc:365
 msgid "Semitones"
 msgstr "Halbtöne"
 
-#: gtk2_ardour/ardour_ui_ed.cc:370
+#: gtk2_ardour/ardour_ui_ed.cc:369
 msgid "Send MTC"
 msgstr "MTC senden"
 
-#: gtk2_ardour/ardour_ui_ed.cc:372
+#: gtk2_ardour/ardour_ui_ed.cc:371
 msgid "Send MMC"
 msgstr "MMC senden"
 
-#: gtk2_ardour/ardour_ui_ed.cc:374
+#: gtk2_ardour/ardour_ui_ed.cc:373
 msgid "Use MMC"
 msgstr "Benutze MMC"
 
-#: gtk2_ardour/ardour_ui_ed.cc:376
+#: gtk2_ardour/ardour_ui_ed.cc:375
 msgid "Send MIDI feedback"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:378
+#: gtk2_ardour/ardour_ui_ed.cc:377
 msgid "Use MIDI control"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:381
+#: gtk2_ardour/ardour_ui_ed.cc:380
 msgid "Stop plugins with transport"
 msgstr "Plugins mit Transport stoppen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:382
+#: gtk2_ardour/ardour_ui_ed.cc:381
 msgid "Verify remove last capture"
 msgstr "Verwerfen der letzten Aufnahme bestätigen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:383
+#: gtk2_ardour/ardour_ui_ed.cc:382
 msgid "Stop recording on xrun"
 msgstr "Aufnahme bei XRUN stoppen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:384
+#: gtk2_ardour/ardour_ui_ed.cc:383
 msgid "Stop transport at session end"
-msgstr "Transport am Ende der Sitzung stoppen"
+msgstr "Transport am Ende des Projekts stoppen"
 
-#: gtk2_ardour/ardour_ui_ed.cc:385
+#: gtk2_ardour/ardour_ui_ed.cc:384
 msgid "-12dB gain reduce ffwd/rewind"
 msgstr "Beim Spulen Pegel um -12dB absenken"
 
-#: gtk2_ardour/ardour_ui_ed.cc:386
+#: gtk2_ardour/ardour_ui_ed.cc:385
 msgid "Rec-enable stays engaged at stop"
 msgstr "Aufnahmestatus bleibt nach Stop erhalten"
 
-#: gtk2_ardour/ardour_ui_ed.cc:388
+#: gtk2_ardour/ardour_ui_ed.cc:387
 msgid "Do not run plugins while recording"
 msgstr "Plugins während der Aufnahme daktivieren"
 
-#: gtk2_ardour/ardour_ui_ed.cc:391
+#: gtk2_ardour/ardour_ui_ed.cc:390
 msgid "Latched solo"
 msgstr "Latch Solo"
 
-#: gtk2_ardour/ardour_ui_ed.cc:399
-#: gtk2_ardour/ardour_ui_ed.cc:407
-#: gtk2_ardour/audio_clock.cc:1800
-#: gtk2_ardour/gain_meter.cc:159
+#: gtk2_ardour/ardour_ui_ed.cc:398
+#: gtk2_ardour/ardour_ui_ed.cc:406
+#: gtk2_ardour/audio_clock.cc:1839
+#: gtk2_ardour/gain_meter.cc:160
 #: gtk2_ardour/ladspa_pluginui.cc:330
 #: gtk2_ardour/ladspa_pluginui.cc:573
-#: gtk2_ardour/panner_ui.cc:87
+#: gtk2_ardour/panner_ui.cc:89
 msgid "Off"
 msgstr "Aus"
 
-#: gtk2_ardour/ardour_ui_ed.cc:400
-#: gtk2_ardour/editor.cc:1334
-#: gtk2_ardour/editor.cc:1351
+#: gtk2_ardour/ardour_ui_ed.cc:399
+#: gtk2_ardour/editor.cc:1243
+#: gtk2_ardour/editor.cc:1260
 msgid "Slowest"
 msgstr "Sehr langsam"
 
-#: gtk2_ardour/ardour_ui_ed.cc:401
-#: gtk2_ardour/editor.cc:1335
-#: gtk2_ardour/editor.cc:1352
+#: gtk2_ardour/ardour_ui_ed.cc:400
+#: gtk2_ardour/editor.cc:1244
+#: gtk2_ardour/editor.cc:1261
 msgid "Slow"
 msgstr "Langsam"
 
-#: gtk2_ardour/ardour_ui_ed.cc:402
-#: gtk2_ardour/ardour_ui_ed.cc:409
+#: gtk2_ardour/ardour_ui_ed.cc:401
+#: gtk2_ardour/ardour_ui_ed.cc:408
 msgid "Medium"
 msgstr "Mittel"
 
-#: gtk2_ardour/ardour_ui_ed.cc:403
-#: gtk2_ardour/editor.cc:1336
-#: gtk2_ardour/editor.cc:1353
+#: gtk2_ardour/ardour_ui_ed.cc:402
+#: gtk2_ardour/editor.cc:1245
+#: gtk2_ardour/editor.cc:1262
 msgid "Fast"
 msgstr "Schnell"
 
-#: gtk2_ardour/ardour_ui_ed.cc:404
+#: gtk2_ardour/ardour_ui_ed.cc:403
 msgid "Faster"
 msgstr "Schneller"
 
-#: gtk2_ardour/ardour_ui_ed.cc:405
-#: gtk2_ardour/editor.cc:1337
-#: gtk2_ardour/editor.cc:1354
+#: gtk2_ardour/ardour_ui_ed.cc:404
+#: gtk2_ardour/editor.cc:1246
+#: gtk2_ardour/editor.cc:1263
 msgid "Fastest"
 msgstr "Schnellstmöglich"
 
-#: gtk2_ardour/ardour_ui_ed.cc:408
+#: gtk2_ardour/ardour_ui_ed.cc:407
 #: gtk2_ardour/editor_actions.cc:58
 msgid "Short"
 msgstr "Kurz"
 
-#: gtk2_ardour/ardour_ui_ed.cc:410
+#: gtk2_ardour/ardour_ui_ed.cc:409
 msgid "Long"
 msgstr "Lange"
 
-#: gtk2_ardour/ardour_ui_ed.cc:428
+#: gtk2_ardour/ardour_ui_ed.cc:427
 msgid "Hardware monitoring"
 msgstr "Hardware Monitoring"
 
-#: gtk2_ardour/ardour_ui_ed.cc:429
+#: gtk2_ardour/ardour_ui_ed.cc:428
 msgid "Software monitoring"
 msgstr "Software Monitoring"
 
-#: gtk2_ardour/ardour_ui_ed.cc:430
+#: gtk2_ardour/ardour_ui_ed.cc:429
 msgid "External monitoring"
 msgstr "Externes Monitoring"
 
-#: gtk2_ardour/ardour_ui_ed.cc:434
+#: gtk2_ardour/ardour_ui_ed.cc:433
 msgid "Solo in-place"
 msgstr "Solo-In-Place"
 
-#: gtk2_ardour/ardour_ui_ed.cc:436
+#: gtk2_ardour/ardour_ui_ed.cc:435
 msgid "Solo via bus"
 msgstr "Solo Ã¼ber Bus"
 
-#: gtk2_ardour/ardour_ui_ed.cc:441
+#: gtk2_ardour/ardour_ui_ed.cc:440
 msgid "Auto-connect inputs to physical inputs"
 msgstr "Eingänge automatisch mit Soundkarteneingängen verbinden"
 
-#: gtk2_ardour/ardour_ui_ed.cc:443
+#: gtk2_ardour/ardour_ui_ed.cc:442
 msgid "Manually connect inputs"
 msgstr "Eingänge manuell verbinden"
 
-#: gtk2_ardour/ardour_ui_ed.cc:448
+#: gtk2_ardour/ardour_ui_ed.cc:447
 msgid "Auto-connect outputs to physical outs"
 msgstr "Ausgänge automatisch mit Soundkartenausgängen verbinden"
 
-#: gtk2_ardour/ardour_ui_ed.cc:450
+#: gtk2_ardour/ardour_ui_ed.cc:449
 msgid "Auto-connect outputs to master bus"
 msgstr "Ausgänge automatisch mit Master-Bus verbinden"
 
-#: gtk2_ardour/ardour_ui_ed.cc:452
+#: gtk2_ardour/ardour_ui_ed.cc:451
 msgid "Manually connect outputs"
 msgstr "Ausgänge manuell verbinden"
 
-#: gtk2_ardour/ardour_ui_ed.cc:547
+#: gtk2_ardour/ardour_ui_ed.cc:549
 #: gtk2_ardour/ladspa_pluginui.cc:168
 msgid "Controls"
 msgstr "Steuerelemente"
 
-#: gtk2_ardour/ardour_ui_ed.cc:551
+#: gtk2_ardour/ardour_ui_ed.cc:553
 msgid "Feedback"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_ed.cc:631
+#: gtk2_ardour/ardour_ui_ed.cc:633
 msgid "ardour: clock"
-msgstr "Ardour: Uhr"
+msgstr "ardour: Uhr"
+
+#: gtk2_ardour/ardour_ui_options.cc:106
+#: gtk2_ardour/ardour_ui_options.cc:133
+#: gtk2_ardour/editor_actions.cc:725
+#: gtk2_ardour/editor_actions.cc:953
+#: gtk2_ardour/editor_actions.cc:966
+#: gtk2_ardour/editor_actions.cc:1030
+#: gtk2_ardour/sfdb_ui.cc:524
+#: gtk2_ardour/audio_streamview.cc:173
+msgid "programming error: %1"
+msgstr ""
 
-#: gtk2_ardour/ardour_ui_options.cc:205
+#: gtk2_ardour/ardour_ui_options.cc:212
 msgid "programming error: unknown solo model in ARDOUR_UI::set_solo_model: %1"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_options.cc:239
+#: gtk2_ardour/ardour_ui_options.cc:246
 msgid "programming error: unknown monitor model in ARDOUR_UI::set_monitor_model: %1"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_options.cc:492
+#: gtk2_ardour/ardour_ui_options.cc:499
 msgid "programming error: unknown file header format passed to ARDOUR_UI::map_file_data_format: %1"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_options.cc:524
+#: gtk2_ardour/ardour_ui_options.cc:531
 msgid "programming error: unknown file data format passed to ARDOUR_UI::map_file_data_format: %1"
 msgstr ""
 
-#: gtk2_ardour/ardour_ui_options.cc:826
+#: gtk2_ardour/ardour_ui_options.cc:833
 msgid "ST"
 msgstr ""
 
-#: gtk2_ardour/audio_clock.cc:1796
-#: gtk2_ardour/editor.cc:180
+#: gtk2_ardour/audio_clock.cc:1835
+#: gtk2_ardour/editor.cc:181
 msgid "Timecode"
 msgstr "Timecode"
 
-#: gtk2_ardour/audio_clock.cc:1797
-#: gtk2_ardour/editor.cc:179
-#: gtk2_ardour/editor_rulers.cc:386
+#: gtk2_ardour/audio_clock.cc:1836
+#: gtk2_ardour/editor.cc:180
+#: gtk2_ardour/editor_rulers.cc:388
 msgid "Bars:Beats"
 msgstr "Takte:Schläge"
 
-#: gtk2_ardour/audio_clock.cc:1798
+#: gtk2_ardour/audio_clock.cc:1837
 msgid "Minutes:Seconds"
 msgstr "Minuten:Sekunden"
 
-#: gtk2_ardour/audio_clock.cc:1799
+#: gtk2_ardour/audio_clock.cc:1838
 msgid "Audio Frames"
 msgstr ""
 
-#: gtk2_ardour/audio_clock.cc:1802
+#: gtk2_ardour/audio_clock.cc:1841
 msgid "Mode"
 msgstr "Modus"
 
@@ -1516,7 +1522,7 @@ msgid "p"
 msgstr "w"
 
 #: gtk2_ardour/route_time_axis.cc:93
-#: gtk2_ardour/automation_time_axis.cc:33
+#: gtk2_ardour/automation_time_axis.cc:36
 #: gtk2_ardour/visual_time_axis.cc:74
 msgid "h"
 msgstr "h"
@@ -1543,11 +1549,11 @@ msgid "Solo"
 msgstr "Solo"
 
 #: gtk2_ardour/route_time_axis.cc:159
-#: gtk2_ardour/editor.cc:1637
-#: gtk2_ardour/editor.cc:1727
+#: gtk2_ardour/editor.cc:1546
+#: gtk2_ardour/editor.cc:1636
 #: gtk2_ardour/mixer_strip.cc:85
 #: gtk2_ardour/mixer_strip.cc:432
-#: gtk2_ardour/panner_ui.cc:417
+#: gtk2_ardour/panner_ui.cc:430
 msgid "Mute"
 msgstr "Mute"
 
@@ -1601,7 +1607,7 @@ msgid "Plugins"
 msgstr "Plugins"
 
 #: gtk2_ardour/route_time_axis.cc:416
-#: gtk2_ardour/automation_time_axis.cc:425
+#: gtk2_ardour/automation_time_axis.cc:430
 #: gtk2_ardour/imageframe_time_axis.cc:255
 #: gtk2_ardour/marker_time_axis.cc:211
 msgid "Height"
@@ -1640,7 +1646,7 @@ msgid "Tape mode"
 msgstr "Tape-Modus"
 
 #: gtk2_ardour/route_time_axis.cc:477
-#: gtk2_ardour/editor.cc:478
+#: gtk2_ardour/editor.cc:483
 #: gtk2_ardour/editor_actions.cc:61
 #: gtk2_ardour/mixer_strip.cc:991
 #: gtk2_ardour/mixer_ui.cc:109
@@ -1648,9 +1654,9 @@ msgid "Active"
 msgstr "Aktiv"
 
 #: gtk2_ardour/route_time_axis.cc:482
-#: gtk2_ardour/editor.cc:1817
-#: gtk2_ardour/editor_actions.cc:326
-#: gtk2_ardour/editor_markers.cc:511
+#: gtk2_ardour/editor.cc:1726
+#: gtk2_ardour/editor_actions.cc:328
+#: gtk2_ardour/editor_markers.cc:527
 #: gtk2_ardour/imageframe_time_axis.cc:259
 #: gtk2_ardour/location_ui.cc:58
 #: gtk2_ardour/marker_time_axis.cc:215
@@ -1660,195 +1666,204 @@ msgstr "Löschen"
 
 #: gtk2_ardour/route_time_axis.cc:508
 #: gtk2_ardour/route_time_axis.cc:563
-#: gtk2_ardour/route_time_axis.cc:826
-#: gtk2_ardour/editor_actions.cc:1034
+#: gtk2_ardour/route_time_axis.cc:828
+#: gtk2_ardour/editor_actions.cc:1017
 msgid "programming error: %1 %2"
 msgstr ""
 
-#: gtk2_ardour/route_time_axis.cc:850
+#: gtk2_ardour/route_time_axis.cc:852
 msgid "Name for playlist"
 msgstr "Name für Wiedergabeliste"
 
-#: gtk2_ardour/route_time_axis.cc:852
-#: gtk2_ardour/route_time_axis.cc:1285
-#: gtk2_ardour/editor_markers.cc:830
-#: gtk2_ardour/editor_mouse.cc:4732
+#: gtk2_ardour/route_time_axis.cc:854
+#: gtk2_ardour/route_time_axis.cc:1305
+#: gtk2_ardour/editor_markers.cc:852
+#: gtk2_ardour/editor_mouse.cc:4799
 #: gtk2_ardour/imageframe_time_axis.cc:248
 #: gtk2_ardour/marker_time_axis.cc:208
 #: gtk2_ardour/mixer_strip.cc:989
-#: gtk2_ardour/redirect_box.cc:752
-#: gtk2_ardour/redirect_box.cc:1075
+#: gtk2_ardour/redirect_box.cc:823
+#: gtk2_ardour/redirect_box.cc:1149
 #: gtk2_ardour/route_ui.cc:760
 #: gtk2_ardour/visual_time_axis.cc:331
 msgid "Rename"
 msgstr "Umbenennen"
 
-#: gtk2_ardour/route_time_axis.cc:894
-#: gtk2_ardour/route_time_axis.cc:935
+#: gtk2_ardour/route_time_axis.cc:896
+#: gtk2_ardour/route_time_axis.cc:942
 msgid "Name for Playlist"
 msgstr "Name für Playlist"
 
-#: gtk2_ardour/route_time_axis.cc:1118
+#: gtk2_ardour/route_time_axis.cc:1133
+#: gtk2_ardour/visual_time_axis.cc:341
 #: gtk2_ardour/visual_time_axis.cc:388
-msgid "a track already exists with that name"
+msgid "A track already exists with that name"
 msgstr ""
 
-#: gtk2_ardour/route_time_axis.cc:1289
+#: gtk2_ardour/route_time_axis.cc:1309
 msgid "New Copy"
 msgstr "Neue Kopie"
 
-#: gtk2_ardour/route_time_axis.cc:1291
+#: gtk2_ardour/route_time_axis.cc:1311
 msgid "Clear Current"
 msgstr ""
 
-#: gtk2_ardour/route_time_axis.cc:1294
+#: gtk2_ardour/route_time_axis.cc:1314
 msgid "Select from all ..."
 msgstr ""
 
-#: gtk2_ardour/route_time_axis.cc:1494
-#: gtk2_ardour/editor.cc:1359
-#: gtk2_ardour/selection.cc:642
+#: gtk2_ardour/route_time_axis.cc:1520
+#: gtk2_ardour/editor.cc:1268
+#: gtk2_ardour/selection.cc:646
+#: gtk2_ardour/selection.cc:685
 msgid "programming error: "
 msgstr ""
 
-#: gtk2_ardour/audio_time_axis.cc:221
+#: gtk2_ardour/audio_time_axis.cc:222
 msgid "Fader"
 msgstr "Fader"
 
-#: gtk2_ardour/audio_time_axis.cc:226
+#: gtk2_ardour/audio_time_axis.cc:227
 msgid "Pan"
 msgstr ""
 
-#: gtk2_ardour/audio_time_axis.cc:241
+#: gtk2_ardour/audio_time_axis.cc:242
 msgid "Hide all crossfades"
 msgstr "Alle Crossfades verbergen"
 
-#: gtk2_ardour/audio_time_axis.cc:242
+#: gtk2_ardour/audio_time_axis.cc:243
 msgid "Show all crossfades"
 msgstr "Alle Crossfades zeigen"
 
-#: gtk2_ardour/audio_time_axis.cc:249
+#: gtk2_ardour/audio_time_axis.cc:250
 msgid "Show waveforms"
 msgstr "Wellenformen zeigen"
 
-#: gtk2_ardour/audio_time_axis.cc:257
+#: gtk2_ardour/audio_time_axis.cc:260
 msgid "Traditional"
 msgstr "Traditionell"
 
-#: gtk2_ardour/audio_time_axis.cc:260
+#: gtk2_ardour/audio_time_axis.cc:263
 msgid "Rectified"
 msgstr "Gleichgerichtet"
 
-#: gtk2_ardour/audio_time_axis.cc:263
+#: gtk2_ardour/audio_time_axis.cc:270
+#: gtk2_ardour/editor.cc:1242
+#: gtk2_ardour/editor.cc:1259
+msgid "Linear"
+msgstr ""
+
+#: gtk2_ardour/audio_time_axis.cc:273
+msgid "Logarithmic"
+msgstr ""
+
+#: gtk2_ardour/audio_time_axis.cc:290
 msgid "Waveform"
 msgstr "Wellenform"
 
-#: gtk2_ardour/audio_time_axis.cc:323
+#: gtk2_ardour/audio_time_axis.cc:362
 msgid "gain"
 msgstr ""
 
-#: gtk2_ardour/audio_time_axis.cc:363
+#: gtk2_ardour/audio_time_axis.cc:402
 msgid "pan"
 msgstr ""
 
-#: gtk2_ardour/automation_line.cc:801
-#, fuzzy
+#: gtk2_ardour/automation_line.cc:795
 msgid "automation event move"
-msgstr "Stellen"
+msgstr "Automationspunkt bewegen"
 
-#: gtk2_ardour/automation_line.cc:803
-#, fuzzy
+#: gtk2_ardour/automation_line.cc:797
 msgid "automation range drag"
-msgstr "Stellen"
+msgstr "Automationsbereich bewegen"
 
-#: gtk2_ardour/automation_line.cc:1028
+#: gtk2_ardour/automation_line.cc:1022
 #: gtk2_ardour/region_gain_line.cc:64
-#, fuzzy
 msgid "remove control point"
-msgstr "Synchronisationspunkt entfernen"
+msgstr "Automationspunkt entfernen"
 
-#: gtk2_ardour/automation_time_axis.cc:34
-#: gtk2_ardour/editor_ops.cc:2834
+#: gtk2_ardour/automation_time_axis.cc:37
+#: gtk2_ardour/editor_ops.cc:2936
 msgid "clear"
-msgstr "leeren"
+msgstr "Leeren"
 
-#: gtk2_ardour/automation_time_axis.cc:70
+#: gtk2_ardour/automation_time_axis.cc:78
 msgid "track height"
 msgstr "Anzeigehöhe"
 
-#: gtk2_ardour/automation_time_axis.cc:71
+#: gtk2_ardour/automation_time_axis.cc:79
 msgid "automation state"
 msgstr "Automationsmodus"
 
-#: gtk2_ardour/automation_time_axis.cc:72
+#: gtk2_ardour/automation_time_axis.cc:80
 msgid "clear track"
 msgstr "Verbindungen entfernen"
 
-#: gtk2_ardour/automation_time_axis.cc:73
+#: gtk2_ardour/automation_time_axis.cc:81
 msgid "hide track"
 msgstr "Diese Spur verbergen"
 
-#: gtk2_ardour/automation_time_axis.cc:182
-#: gtk2_ardour/automation_time_axis.cc:211
-#: gtk2_ardour/automation_time_axis.cc:436
+#: gtk2_ardour/automation_time_axis.cc:187
+#: gtk2_ardour/automation_time_axis.cc:216
+#: gtk2_ardour/automation_time_axis.cc:441
 msgid "Manual"
 msgstr "Manuell"
 
-#: gtk2_ardour/automation_time_axis.cc:184
-#: gtk2_ardour/automation_time_axis.cc:222
-#: gtk2_ardour/automation_time_axis.cc:440
-#: gtk2_ardour/editor.cc:1894
-#: gtk2_ardour/editor.cc:1975
-#: gtk2_ardour/gain_meter.cc:161
+#: gtk2_ardour/automation_time_axis.cc:189
+#: gtk2_ardour/automation_time_axis.cc:227
+#: gtk2_ardour/automation_time_axis.cc:445
+#: gtk2_ardour/editor.cc:1804
+#: gtk2_ardour/editor.cc:1885
+#: gtk2_ardour/gain_meter.cc:162
 #: gtk2_ardour/ladspa_pluginui.cc:333
 #: gtk2_ardour/ladspa_pluginui.cc:575
-#: gtk2_ardour/panner_ui.cc:89
+#: gtk2_ardour/panner_ui.cc:91
 #: gtk2_ardour/sfdb_ui.cc:59
 msgid "Play"
 msgstr "Wiedergabe"
 
-#: gtk2_ardour/automation_time_axis.cc:186
-#: gtk2_ardour/automation_time_axis.cc:233
-#: gtk2_ardour/automation_time_axis.cc:444
-#: gtk2_ardour/gain_meter.cc:163
+#: gtk2_ardour/automation_time_axis.cc:191
+#: gtk2_ardour/automation_time_axis.cc:238
+#: gtk2_ardour/automation_time_axis.cc:449
+#: gtk2_ardour/gain_meter.cc:164
 #: gtk2_ardour/ladspa_pluginui.cc:336
 #: gtk2_ardour/ladspa_pluginui.cc:577
-#: gtk2_ardour/panner_ui.cc:91
+#: gtk2_ardour/panner_ui.cc:93
 msgid "Write"
 msgstr "Schreiben"
 
-#: gtk2_ardour/automation_time_axis.cc:188
-#: gtk2_ardour/automation_time_axis.cc:244
-#: gtk2_ardour/automation_time_axis.cc:448
-#: gtk2_ardour/gain_meter.cc:165
+#: gtk2_ardour/automation_time_axis.cc:193
+#: gtk2_ardour/automation_time_axis.cc:249
+#: gtk2_ardour/automation_time_axis.cc:453
+#: gtk2_ardour/gain_meter.cc:166
 #: gtk2_ardour/ladspa_pluginui.cc:339
 #: gtk2_ardour/ladspa_pluginui.cc:579
-#: gtk2_ardour/panner_ui.cc:93
+#: gtk2_ardour/panner_ui.cc:95
 msgid "Touch"
 msgstr "Berühren"
 
-#: gtk2_ardour/automation_time_axis.cc:255
+#: gtk2_ardour/automation_time_axis.cc:260
 #: gtk2_ardour/ladspa_pluginui.cc:342
 msgid "???"
 msgstr ""
 
-#: gtk2_ardour/automation_time_axis.cc:269
+#: gtk2_ardour/automation_time_axis.cc:274
 msgid "clear automation"
 msgstr "Verbindungen entfernen"
 
-#: gtk2_ardour/automation_time_axis.cc:427
-#: gtk2_ardour/editor_actions.cc:324
+#: gtk2_ardour/automation_time_axis.cc:432
+#: gtk2_ardour/editor_actions.cc:326
 msgid "Hide"
 msgstr "Verbergen"
 
-#: gtk2_ardour/automation_time_axis.cc:429
+#: gtk2_ardour/automation_time_axis.cc:434
 #: gtk2_ardour/crossfade_edit.cc:79
-#: gtk2_ardour/redirect_box.cc:1067
+#: gtk2_ardour/redirect_box.cc:1141
 #: gtk2_ardour/connection_editor.cc:57
 msgid "Clear"
-msgstr "leeren"
+msgstr "Leeren"
 
-#: gtk2_ardour/automation_time_axis.cc:452
+#: gtk2_ardour/automation_time_axis.cc:457
 msgid "State"
 msgstr "Automationssmodus"
 
@@ -2012,63 +2027,60 @@ msgid "cannot open color definition file %1: %2"
 msgstr ""
 
 #: gtk2_ardour/crossfade_edit.cc:76
-#, fuzzy
 msgid "ardour: x-fade edit"
-msgstr "Ardour: Editor"
+msgstr "ardour: Crossfade Editor"
 
 #: gtk2_ardour/crossfade_edit.cc:80
-#: gtk2_ardour/panner_ui.cc:433
-#, fuzzy
+#: gtk2_ardour/panner_ui.cc:446
 msgid "Reset"
-msgstr "bestmöglich"
+msgstr "Zurücksetzen"
 
 #: gtk2_ardour/crossfade_edit.cc:81
 msgid "Fade"
-msgstr ""
+msgstr "Fade"
 
 #: gtk2_ardour/crossfade_edit.cc:82
 msgid "Out (dry)"
-msgstr ""
+msgstr "Out (dry)"
 
 #: gtk2_ardour/crossfade_edit.cc:83
-#, fuzzy
 msgid "Out"
-msgstr "Ausgänge"
+msgstr "Out"
 
 #: gtk2_ardour/crossfade_edit.cc:84
 msgid "In (dry)"
-msgstr ""
+msgstr "In (dry)"
 
 #: gtk2_ardour/crossfade_edit.cc:85
 msgid "In"
-msgstr ""
+msgstr "In"
 
 #: gtk2_ardour/crossfade_edit.cc:87
 msgid "With Pre-roll"
-msgstr ""
+msgstr "mit Pre-Roll"
 
 #: gtk2_ardour/crossfade_edit.cc:88
 msgid "With Post-roll"
-msgstr ""
+msgstr "mit Post-Roll"
 
 #: gtk2_ardour/crossfade_edit.cc:96
 msgid "Fade In"
-msgstr ""
+msgstr "Fade In"
 
 #: gtk2_ardour/crossfade_edit.cc:97
 msgid "Fade Out"
-msgstr ""
+msgstr "Fade Out"
 
 #: gtk2_ardour/crossfade_edit.cc:173
-#: gtk2_ardour/editor.cc:1712
-#: gtk2_ardour/editor_actions.cc:322
-#: gtk2_ardour/option_editor.cc:129
+#: gtk2_ardour/editor.cc:1621
+#: gtk2_ardour/editor_actions.cc:324
+#: gtk2_ardour/option_editor.cc:127
 msgid "Audition"
 msgstr "Vorhören"
 
-#: gtk2_ardour/editor.cc:102
-#: gtk2_ardour/editor.cc:3469
-#: gtk2_ardour/editor_actions.cc:400
+#: gtk2_ardour/editor.cc:103
+#: gtk2_ardour/editor.cc:3533
+#: gtk2_ardour/editor_actions.cc:402
 #: gtk2_ardour/export_dialog.cc:76
 #: gtk2_ardour/export_dialog.cc:90
 #: gtk2_ardour/export_dialog.cc:891
@@ -2077,111 +2089,111 @@ msgstr "Vorhören"
 msgid "None"
 msgstr "Kein"
 
-#: gtk2_ardour/editor.cc:103
-#: gtk2_ardour/editor.cc:3457
+#: gtk2_ardour/editor.cc:104
+#: gtk2_ardour/editor.cc:3521
 msgid "CD Frames"
 msgstr "CD-Frames"
 
-#: gtk2_ardour/editor.cc:104
-#: gtk2_ardour/editor.cc:3459
+#: gtk2_ardour/editor.cc:105
+#: gtk2_ardour/editor.cc:3523
 msgid "SMPTE Frames"
 msgstr "SMPTE-Frames"
 
-#: gtk2_ardour/editor.cc:105
-#: gtk2_ardour/editor.cc:3461
+#: gtk2_ardour/editor.cc:106
+#: gtk2_ardour/editor.cc:3525
 msgid "SMPTE Seconds"
 msgstr "SMPTE-Sekunden"
 
-#: gtk2_ardour/editor.cc:106
-#: gtk2_ardour/editor.cc:3463
+#: gtk2_ardour/editor.cc:107
+#: gtk2_ardour/editor.cc:3527
 msgid "SMPTE Minutes"
 msgstr "SMPTE-Minuten"
 
-#: gtk2_ardour/editor.cc:107
-#: gtk2_ardour/editor.cc:3465
+#: gtk2_ardour/editor.cc:108
+#: gtk2_ardour/editor.cc:3529
 msgid "Seconds"
 msgstr "Sekunden"
 
-#: gtk2_ardour/editor.cc:108
-#: gtk2_ardour/editor.cc:3467
+#: gtk2_ardour/editor.cc:109
+#: gtk2_ardour/editor.cc:3531
 msgid "Minutes"
 msgstr "Minuten"
 
-#: gtk2_ardour/editor.cc:109
-#: gtk2_ardour/editor.cc:3439
+#: gtk2_ardour/editor.cc:110
+#: gtk2_ardour/editor.cc:3503
 msgid "Beats/32"
-msgstr "Zweiunddreißigstel"
+msgstr "Schläge / 32"
 
-#: gtk2_ardour/editor.cc:110
-#: gtk2_ardour/editor.cc:3437
+#: gtk2_ardour/editor.cc:111
+#: gtk2_ardour/editor.cc:3501
 msgid "Beats/16"
-msgstr "Sechzehntel"
+msgstr "Schläge / 16"
 
-#: gtk2_ardour/editor.cc:111
-#: gtk2_ardour/editor.cc:3435
+#: gtk2_ardour/editor.cc:112
+#: gtk2_ardour/editor.cc:3499
 msgid "Beats/8"
-msgstr "Achtel"
+msgstr "Schläge / 8"
 
-#: gtk2_ardour/editor.cc:112
-#: gtk2_ardour/editor.cc:3433
+#: gtk2_ardour/editor.cc:113
+#: gtk2_ardour/editor.cc:3497
 msgid "Beats/4"
-msgstr "Viertel"
+msgstr "Schläge / 4"
 
-#: gtk2_ardour/editor.cc:113
-#: gtk2_ardour/editor.cc:3431
+#: gtk2_ardour/editor.cc:114
+#: gtk2_ardour/editor.cc:3495
 msgid "Beats/3"
-msgstr "Vierteltriolen"
+msgstr "Schläge / 3"
 
-#: gtk2_ardour/editor.cc:114
-#: gtk2_ardour/editor.cc:3441
+#: gtk2_ardour/editor.cc:115
+#: gtk2_ardour/editor.cc:3505
 msgid "Beats"
 msgstr "Schläge"
 
-#: gtk2_ardour/editor.cc:115
-#: gtk2_ardour/editor.cc:3443
+#: gtk2_ardour/editor.cc:116
+#: gtk2_ardour/editor.cc:3507
 msgid "Bars"
 msgstr "Takte"
 
-#: gtk2_ardour/editor.cc:116
-#: gtk2_ardour/editor.cc:3445
+#: gtk2_ardour/editor.cc:117
+#: gtk2_ardour/editor.cc:3509
 msgid "Marks"
 msgstr "Marker"
 
-#: gtk2_ardour/editor.cc:117
-#: gtk2_ardour/editor.cc:136
-#: gtk2_ardour/editor.cc:3447
-#: gtk2_ardour/editor.cc:3512
+#: gtk2_ardour/editor.cc:118
+#: gtk2_ardour/editor.cc:137
+#: gtk2_ardour/editor.cc:3511
+#: gtk2_ardour/editor.cc:3576
 msgid "Edit Cursor"
 msgstr "Editierzeiger"
 
-#: gtk2_ardour/editor.cc:118
-#: gtk2_ardour/editor.cc:3449
+#: gtk2_ardour/editor.cc:119
+#: gtk2_ardour/editor.cc:3513
 msgid "Region starts"
 msgstr "Regionen-Anfang"
 
-#: gtk2_ardour/editor.cc:119
-#: gtk2_ardour/editor.cc:3451
+#: gtk2_ardour/editor.cc:120
+#: gtk2_ardour/editor.cc:3515
 msgid "Region ends"
 msgstr "Regionen-Ende"
 
-#: gtk2_ardour/editor.cc:120
-#: gtk2_ardour/editor.cc:3455
+#: gtk2_ardour/editor.cc:121
+#: gtk2_ardour/editor.cc:3519
 msgid "Region syncs"
 msgstr "Regionen-Sync"
 
-#: gtk2_ardour/editor.cc:121
-#: gtk2_ardour/editor.cc:3453
+#: gtk2_ardour/editor.cc:122
+#: gtk2_ardour/editor.cc:3517
 msgid "Region bounds"
 msgstr "Regionen-Grenzen"
 
-#: gtk2_ardour/editor.cc:127
-#: gtk2_ardour/editor.cc:3487
-#: gtk2_ardour/editor_actions.cc:287
+#: gtk2_ardour/editor.cc:128
+#: gtk2_ardour/editor.cc:3551
+#: gtk2_ardour/editor_actions.cc:289
 msgid "Magnetic"
 msgstr "Magnetisch"
 
-#: gtk2_ardour/editor.cc:132
-#: gtk2_ardour/editor.cc:3504
+#: gtk2_ardour/editor.cc:133
+#: gtk2_ardour/editor.cc:3568
 #: gtk2_ardour/export_dialog.cc:138
 #: gtk2_ardour/export_dialog.cc:154
 #: gtk2_ardour/export_dialog.cc:1066
@@ -2189,67 +2201,67 @@ msgstr "Magnetisch"
 msgid "Left"
 msgstr "Links"
 
-#: gtk2_ardour/editor.cc:133
-#: gtk2_ardour/editor.cc:3506
+#: gtk2_ardour/editor.cc:134
+#: gtk2_ardour/editor.cc:3570
 #: gtk2_ardour/export_dialog.cc:139
 #: gtk2_ardour/export_dialog.cc:155
 msgid "Right"
 msgstr "Rechts"
 
-#: gtk2_ardour/editor.cc:134
-#: gtk2_ardour/editor.cc:3508
+#: gtk2_ardour/editor.cc:135
+#: gtk2_ardour/editor.cc:3572
 msgid "Center"
 msgstr "Mitte"
 
-#: gtk2_ardour/editor.cc:135
-#: gtk2_ardour/editor.cc:3510
+#: gtk2_ardour/editor.cc:136
+#: gtk2_ardour/editor.cc:3574
 msgid "Playhead"
 msgstr "Positionszeiger"
 
-#: gtk2_ardour/editor.cc:178
+#: gtk2_ardour/editor.cc:179
 msgid "Mins:Secs"
 msgstr "Min:Sek"
 
-#: gtk2_ardour/editor.cc:181
-#: gtk2_ardour/editor_rulers.cc:380
+#: gtk2_ardour/editor.cc:182
+#: gtk2_ardour/editor_rulers.cc:382
 msgid "Frames"
 msgstr "Frames"
 
-#: gtk2_ardour/editor.cc:182
-#: gtk2_ardour/editor_rulers.cc:400
+#: gtk2_ardour/editor.cc:183
+#: gtk2_ardour/editor_rulers.cc:402
 msgid "Tempo"
 msgstr "Tempo"
 
-#: gtk2_ardour/editor.cc:183
-#: gtk2_ardour/editor_rulers.cc:394
+#: gtk2_ardour/editor.cc:184
+#: gtk2_ardour/editor_rulers.cc:396
 msgid "Meter"
 msgstr "Taktart"
 
-#: gtk2_ardour/editor.cc:184
-#: gtk2_ardour/editor_rulers.cc:406
+#: gtk2_ardour/editor.cc:185
+#: gtk2_ardour/editor_rulers.cc:408
 msgid "Location Markers"
 msgstr "Positionsmarker"
 
-#: gtk2_ardour/editor.cc:185
-#: gtk2_ardour/editor_rulers.cc:412
+#: gtk2_ardour/editor.cc:186
+#: gtk2_ardour/editor_rulers.cc:414
 msgid "Range Markers"
 msgstr "Bereiche"
 
-#: gtk2_ardour/editor.cc:186
-#: gtk2_ardour/editor_rulers.cc:418
+#: gtk2_ardour/editor.cc:187
+#: gtk2_ardour/editor_rulers.cc:420
 msgid "Loop/Punch Ranges"
 msgstr "Schleifen/Punch-Bereiche"
 
-#: gtk2_ardour/editor.cc:204
+#: gtk2_ardour/editor.cc:205
 msgid "mode"
 msgstr "Modus"
 
-#: gtk2_ardour/editor.cc:205
+#: gtk2_ardour/editor.cc:206
 msgid "automation"
 msgstr ""
 
-#: gtk2_ardour/editor.cc:453
-#: gtk2_ardour/editor.cc:479
+#: gtk2_ardour/editor.cc:458
+#: gtk2_ardour/editor.cc:484
 #: gtk2_ardour/editor_actions.cc:63
 #: gtk2_ardour/mixer_ui.cc:84
 #: gtk2_ardour/mixer_ui.cc:110
@@ -2257,573 +2269,549 @@ msgstr ""
 msgid "Show"
 msgstr "Anzeigen"
 
-#: gtk2_ardour/editor.cc:454
-#: gtk2_ardour/editor.cc:477
+#: gtk2_ardour/editor.cc:459
+#: gtk2_ardour/editor.cc:482
 #, fuzzy
 msgid "Name"
 msgstr "Umbenennen"
 
-#: gtk2_ardour/editor.cc:553
-#: gtk2_ardour/editor.cc:619
+#: gtk2_ardour/editor.cc:557
+#: gtk2_ardour/editor.cc:624
 msgid "Regions"
 msgstr "Regionen"
 
-#: gtk2_ardour/editor.cc:592
-#: gtk2_ardour/editor.cc:631
+#: gtk2_ardour/editor.cc:596
+#: gtk2_ardour/editor.cc:636
 msgid "Chunks"
 msgstr "Teile"
 
-#: gtk2_ardour/editor.cc:622
+#: gtk2_ardour/editor.cc:627
 msgid "Tracks/Busses"
 msgstr "Spuren/Busse"
 
-#: gtk2_ardour/editor.cc:625
+#: gtk2_ardour/editor.cc:630
 msgid "Snapshots"
 msgstr "Schnapschüsse"
 
-#: gtk2_ardour/editor.cc:628
+#: gtk2_ardour/editor.cc:633
 msgid "Edit Groups"
 msgstr "Bearbeitungsgruppen"
 
-#: gtk2_ardour/editor.cc:679
+#: gtk2_ardour/editor.cc:684
 msgid "Nudge Region/Selection Forwards"
 msgstr "Region/Auswahl schrittweise nach vorne"
 
-#: gtk2_ardour/editor.cc:680
+#: gtk2_ardour/editor.cc:685
 msgid "Nudge Region/Selection Backwards"
 msgstr "Region/Auswahl schrittweise nach hinten"
 
-#: gtk2_ardour/editor.cc:687
-#: gtk2_ardour/editor_mixer.cc:299
+#: gtk2_ardour/editor.cc:713
+#: gtk2_ardour/editor_mixer.cc:318
 msgid "ardour: editor"
-msgstr "Ardour: Editor"
+msgstr "ardour: Editor"
 
-#: gtk2_ardour/editor.cc:688
-#, fuzzy
-msgid "ardour_editor"
-msgstr "Ardour: Editor"
-
-#: gtk2_ardour/editor.cc:1093
+#: gtk2_ardour/editor.cc:1010
 msgid "ardour: editor: "
-msgstr "Ardour: Editor: "
+msgstr "ardour: Editor: "
 
-#: gtk2_ardour/editor.cc:1166
-#: gtk2_ardour/editor.cc:1175
-#: gtk2_ardour/editor_markers.cc:874
+#: gtk2_ardour/editor.cc:1090
+#: gtk2_ardour/editor.cc:1099
+#: gtk2_ardour/editor_markers.cc:896
 msgid "Loop"
 msgstr "Schleife"
 
-#: gtk2_ardour/editor.cc:1180
-#: gtk2_ardour/editor.cc:1189
-#: gtk2_ardour/editor_markers.cc:902
+#: gtk2_ardour/editor.cc:1104
+#: gtk2_ardour/editor.cc:1113
+#: gtk2_ardour/editor_markers.cc:924
 msgid "Punch"
 msgstr ""
 
-#: gtk2_ardour/editor.cc:1314
-#: gtk2_ardour/editor_mouse.cc:1748
+#: gtk2_ardour/editor.cc:1223
+#: gtk2_ardour/editor_mouse.cc:1760
 msgid "programming error: fade in canvas item has no regionview data pointer!"
 msgstr ""
 
-#: gtk2_ardour/editor.cc:1326
-#: gtk2_ardour/editor.cc:1343
-#: gtk2_ardour/redirect_box.cc:1083
+#: gtk2_ardour/editor.cc:1235
+#: gtk2_ardour/editor.cc:1252
+#: gtk2_ardour/redirect_box.cc:1157
 msgid "Deactivate"
 msgstr "Deaktivieren"
 
-#: gtk2_ardour/editor.cc:1328
-#: gtk2_ardour/editor.cc:1345
-#: gtk2_ardour/redirect_box.cc:1081
+#: gtk2_ardour/editor.cc:1237
+#: gtk2_ardour/editor.cc:1254
+#: gtk2_ardour/redirect_box.cc:1155
 msgid "Activate"
 msgstr "Aktivieren"
 
-#: gtk2_ardour/editor.cc:1333
-#: gtk2_ardour/editor.cc:1350
-msgid "Linear"
-msgstr ""
-
-#: gtk2_ardour/editor.cc:1466
-#: gtk2_ardour/editor.cc:1474
+#: gtk2_ardour/editor.cc:1375
+#: gtk2_ardour/editor.cc:1383
 msgid "Freeze"
 msgstr "Einfrieren"
 
-#: gtk2_ardour/editor.cc:1470
+#: gtk2_ardour/editor.cc:1379
 msgid "Unfreeze"
 msgstr "Auftauen"
 
-#: gtk2_ardour/editor.cc:1639
+#: gtk2_ardour/editor.cc:1548
 msgid "Unmute"
 msgstr "Unmute"
 
-#: gtk2_ardour/editor.cc:1643
-#: gtk2_ardour/editor.cc:1939
+#: gtk2_ardour/editor.cc:1552
+#: gtk2_ardour/editor.cc:1849
 #: gtk2_ardour/editor_actions.cc:28
-#: gtk2_ardour/editor_markers.cc:510
+#: gtk2_ardour/editor_markers.cc:526
 #: gtk2_ardour/mixer_strip.cc:515
 #: gtk2_ardour/mixer_strip.cc:577
-#: gtk2_ardour/redirect_box.cc:1089
+#: gtk2_ardour/redirect_box.cc:1163
 msgid "Edit"
 msgstr "Bearbeiten"
 
-#: gtk2_ardour/editor.cc:1648
+#: gtk2_ardour/editor.cc:1557
 msgid "Convert to short"
 msgstr ""
 
-#: gtk2_ardour/editor.cc:1650
+#: gtk2_ardour/editor.cc:1559
 msgid "Convert to full"
 msgstr ""
 
-#: gtk2_ardour/editor.cc:1661
+#: gtk2_ardour/editor.cc:1570
 msgid "Crossfade"
 msgstr "Crossfade"
 
-#: gtk2_ardour/editor.cc:1704
+#: gtk2_ardour/editor.cc:1613
 msgid "Popup region editor"
 msgstr "Regioneneditor Ã¶ffnen"
 
-#: gtk2_ardour/editor.cc:1705
+#: gtk2_ardour/editor.cc:1614
 msgid "Raise to top layer"
 msgstr "Region ganz nach oben"
 
-#: gtk2_ardour/editor.cc:1706
+#: gtk2_ardour/editor.cc:1615
 msgid "Lower to bottom layer"
 msgstr "Region ganz nach unten"
 
-#: gtk2_ardour/editor.cc:1708
+#: gtk2_ardour/editor.cc:1617
 msgid "Define sync point"
 msgstr "Synchronisationspunkt definieren"
 
-#: gtk2_ardour/editor.cc:1709
+#: gtk2_ardour/editor.cc:1618
 msgid "Remove sync point"
 msgstr "Synchronisationspunkt entfernen"
 
-#: gtk2_ardour/editor.cc:1714
+#: gtk2_ardour/editor.cc:1623
 msgid "Bounce"
 msgstr "Bounce"
 
-#: gtk2_ardour/editor.cc:1717
+#: gtk2_ardour/editor.cc:1626
 msgid "Analyze region"
 msgstr "Analysiere Region"
 
-#: gtk2_ardour/editor.cc:1722
+#: gtk2_ardour/editor.cc:1631
 msgid "Lock"
 msgstr "Sperren"
 
-#: gtk2_ardour/editor.cc:1732
+#: gtk2_ardour/editor.cc:1641
 msgid "Opaque"
 msgstr "Deckend"
 
-#: gtk2_ardour/editor.cc:1738
+#: gtk2_ardour/editor.cc:1647
 msgid "Original position"
 msgstr "Ursprungsposition"
 
-#: gtk2_ardour/editor.cc:1750
+#: gtk2_ardour/editor.cc:1659
 msgid "Reset Envelope"
 msgstr "Lautstärkekurve zurücksetzen"
 
-#: gtk2_ardour/editor.cc:1752
+#: gtk2_ardour/editor.cc:1661
 msgid "Envelope Visible"
 msgstr "Lautstärkekurve sichtbar"
 
-#: gtk2_ardour/editor.cc:1759
+#: gtk2_ardour/editor.cc:1668
 msgid "Envelope Active"
 msgstr "Lautstärkekurve aktiv"
 
-#: gtk2_ardour/editor.cc:1769
+#: gtk2_ardour/editor.cc:1678
 msgid "DeNormalize"
 msgstr "Ardour: Region "
 
-#: gtk2_ardour/editor.cc:1771
+#: gtk2_ardour/editor.cc:1680
 msgid "Normalize"
 msgstr "Normalisieren"
 
-#: gtk2_ardour/editor.cc:1774
+#: gtk2_ardour/editor.cc:1683
 msgid "Reverse"
 msgstr "Rückwärts"
 
-#: gtk2_ardour/editor.cc:1780
+#: gtk2_ardour/editor.cc:1689
+#: gtk2_ardour/editor.cc:1771
 msgid "Add Range Markers"
 msgstr "Bereichsmarker einfügen"
 
-#: gtk2_ardour/editor.cc:1781
+#: gtk2_ardour/editor.cc:1690
 msgid "Set Range Selection"
 msgstr "Bereich auswählen"
 
-#: gtk2_ardour/editor.cc:1790
+#: gtk2_ardour/editor.cc:1699
 msgid "Nudge fwd"
 msgstr "Schritt nach vorne"
 
-#: gtk2_ardour/editor.cc:1791
+#: gtk2_ardour/editor.cc:1700
 msgid "Nudge bwd"
 msgstr "Schritt nach hinten"
 
-#: gtk2_ardour/editor.cc:1792
+#: gtk2_ardour/editor.cc:1701
 msgid "Nudge fwd by capture offset"
 msgstr "Schritt nach vorne um Aufnahme-Offset"
 
-#: gtk2_ardour/editor.cc:1793
+#: gtk2_ardour/editor.cc:1702
 msgid "Nudge bwd by capture offset"
 msgstr "Schritt nach hinten um Aufnahme-Offset"
 
-#: gtk2_ardour/editor.cc:1795
-#: gtk2_ardour/editor.cc:1959
-#: gtk2_ardour/editor.cc:2015
+#: gtk2_ardour/editor.cc:1704
+#: gtk2_ardour/editor.cc:1869
+#: gtk2_ardour/editor.cc:1925
 msgid "Nudge"
 msgstr "Verschieben"
 
-#: gtk2_ardour/editor.cc:1802
+#: gtk2_ardour/editor.cc:1711
 msgid "Start to edit cursor"
 msgstr "Von Anfang bis Editierzeiger"
 
-#: gtk2_ardour/editor.cc:1803
+#: gtk2_ardour/editor.cc:1712
 msgid "Edit cursor to end"
 msgstr "Von Editierzeiger bis Ende"
 
-#: gtk2_ardour/editor.cc:1805
-#: gtk2_ardour/gain_meter.cc:168
-#: gtk2_ardour/gain_meter.cc:848
-#: gtk2_ardour/panner_ui.cc:96
-#: gtk2_ardour/panner_ui.cc:793
+#: gtk2_ardour/editor.cc:1714
+#: gtk2_ardour/gain_meter.cc:169
+#: gtk2_ardour/gain_meter.cc:873
+#: gtk2_ardour/panner_ui.cc:98
+#: gtk2_ardour/panner_ui.cc:806
 msgid "Trim"
 msgstr "Abschneiden"
 
-#: gtk2_ardour/editor.cc:1808
+#: gtk2_ardour/editor.cc:1717
 msgid "Split"
 msgstr "Teilen"
 
-#: gtk2_ardour/editor.cc:1811
+#: gtk2_ardour/editor.cc:1720
 msgid "Make mono regions"
 msgstr "Zu Mono-Regionen umwandeln"
 
-#: gtk2_ardour/editor.cc:1814
+#: gtk2_ardour/editor.cc:1723
 msgid "Duplicate"
 msgstr "Duplizieren"
 
-#: gtk2_ardour/editor.cc:1815
+#: gtk2_ardour/editor.cc:1724
 msgid "Fill Track"
 msgstr "Spur auffüllen"
 
-#: gtk2_ardour/editor.cc:1847
+#: gtk2_ardour/editor.cc:1756
 #, fuzzy
 msgid "Play range"
 msgstr "Bereich"
 
-#: gtk2_ardour/editor.cc:1848
+#: gtk2_ardour/editor.cc:1757
 #, fuzzy
 msgid "Loop range"
 msgstr "Bereich"
 
-#: gtk2_ardour/editor.cc:1852
+#: gtk2_ardour/editor.cc:1761
 msgid "Analyze range"
 msgstr "Bereich analysieren"
 
-#: gtk2_ardour/editor.cc:1856
-#, fuzzy
+#: gtk2_ardour/editor.cc:1765
 msgid "Separate range to track"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr "Bereich als Spur"
 
-#: gtk2_ardour/editor.cc:1857
-#, fuzzy
+#: gtk2_ardour/editor.cc:1766
 msgid "Separate range to region list"
-msgstr "Auswahl zu Schleife machen"
+msgstr "Bereich zur Regionenliste hinzufügen"
 
-#: gtk2_ardour/editor.cc:1860
-#, fuzzy
+#: gtk2_ardour/editor.cc:1769
 msgid "Select all in range"
-msgstr "Auswahl"
+msgstr "Alles im Bereich auswählen"
 
-#: gtk2_ardour/editor.cc:1862
-#: gtk2_ardour/editor.cc:1907
+#: gtk2_ardour/editor.cc:1772
+#: gtk2_ardour/editor.cc:1817
 msgid "Set range to loop range"
 msgstr "Ausgewählten Bereich als Schleife"
 
-#: gtk2_ardour/editor.cc:1863
-#: gtk2_ardour/editor.cc:1908
+#: gtk2_ardour/editor.cc:1773
+#: gtk2_ardour/editor.cc:1818
 msgid "Set range to punch range"
 msgstr "Ausgewählten Bereich als Punch-Bereich"
 
-#: gtk2_ardour/editor.cc:1865
+#: gtk2_ardour/editor.cc:1775
 msgid "Crop region to range"
 msgstr "Regionen-Editor Ã¶ffnen"
 
-#: gtk2_ardour/editor.cc:1866
-#, fuzzy
+#: gtk2_ardour/editor.cc:1776
 msgid "Fill range with region"
-msgstr "Region erstellen"
+msgstr "Bereich mit Region ausfüllen"
 
-#: gtk2_ardour/editor.cc:1867
-#, fuzzy
+#: gtk2_ardour/editor.cc:1777
 msgid "Duplicate range"
-msgstr "Duplizieren"
+msgstr "Bereich Duplizieren"
 
-#: gtk2_ardour/editor.cc:1868
-#, fuzzy
+#: gtk2_ardour/editor.cc:1778
 msgid "Create chunk from range"
-msgstr "Auswahl zu Abschnitt machen"
+msgstr "Abschnitt aus Bereich erstellen..."
 
-#: gtk2_ardour/editor.cc:1870
-#, fuzzy
+#: gtk2_ardour/editor.cc:1780
 msgid "Bounce range"
-msgstr "Bereich"
+msgstr "Bereich Bouncen"
 
-#: gtk2_ardour/editor.cc:1871
-#, fuzzy
+#: gtk2_ardour/editor.cc:1781
 msgid "Export range"
-msgstr "Name für Region:"
+msgstr "Bereich exportieren..."
 
-#: gtk2_ardour/editor.cc:1873
-#, fuzzy
+#: gtk2_ardour/editor.cc:1783
 msgid "Range"
 msgstr "Bereich"
 
-#: gtk2_ardour/editor.cc:1888
-#: gtk2_ardour/editor.cc:1973
+#: gtk2_ardour/editor.cc:1798
+#: gtk2_ardour/editor.cc:1883
 msgid "Play from edit cursor"
 msgstr "Wiedergabe ab Editierzeiger"
 
-#: gtk2_ardour/editor.cc:1889
-#: gtk2_ardour/editor.cc:1974
+#: gtk2_ardour/editor.cc:1799
+#: gtk2_ardour/editor.cc:1884
 msgid "Play from start"
 msgstr "Wiedergabe ab Anfang"
 
-#: gtk2_ardour/editor.cc:1890
+#: gtk2_ardour/editor.cc:1800
 msgid "Play region"
 msgstr "Region wiedergeben"
 
-#: gtk2_ardour/editor.cc:1892
+#: gtk2_ardour/editor.cc:1802
 msgid "Loop Region"
 msgstr "Region in Schleife wiedergeben"
 
-#: gtk2_ardour/editor.cc:1902
-#: gtk2_ardour/editor.cc:1983
+#: gtk2_ardour/editor.cc:1812
+#: gtk2_ardour/editor.cc:1893
 msgid "Select All in track"
 msgstr "Alles in Spur auswählen"
 
-#: gtk2_ardour/editor.cc:1903
-#: gtk2_ardour/editor.cc:1984
-#: gtk2_ardour/redirect_box.cc:1077
+#: gtk2_ardour/editor.cc:1813
+#: gtk2_ardour/editor.cc:1894
+#: gtk2_ardour/redirect_box.cc:1151
 msgid "Select All"
 msgstr "Alles Auswählen"
 
-#: gtk2_ardour/editor.cc:1904
-#: gtk2_ardour/editor.cc:1985
+#: gtk2_ardour/editor.cc:1814
+#: gtk2_ardour/editor.cc:1895
 msgid "Invert selection in track"
 msgstr "Auswahl in Spur umkehren"
 
-#: gtk2_ardour/editor.cc:1905
-#: gtk2_ardour/editor.cc:1986
+#: gtk2_ardour/editor.cc:1815
+#: gtk2_ardour/editor.cc:1896
 msgid "Invert selection"
 msgstr "Auswahl umkehren"
 
-#: gtk2_ardour/editor.cc:1910
-#: gtk2_ardour/editor.cc:1988
+#: gtk2_ardour/editor.cc:1820
+#: gtk2_ardour/editor.cc:1898
 msgid "Select all after edit cursor"
 msgstr "Alles nach Editierzeiger auswählen"
 
-#: gtk2_ardour/editor.cc:1911
-#: gtk2_ardour/editor.cc:1989
+#: gtk2_ardour/editor.cc:1821
+#: gtk2_ardour/editor.cc:1899
 msgid "Select all before edit cursor"
 msgstr "Alles vor Editierzeiger auswählen"
 
-#: gtk2_ardour/editor.cc:1912
-#: gtk2_ardour/editor.cc:1990
+#: gtk2_ardour/editor.cc:1822
+#: gtk2_ardour/editor.cc:1900
 msgid "Select all after playhead"
 msgstr "Alles nach Positionszeiger auswählen"
 
-#: gtk2_ardour/editor.cc:1913
-#: gtk2_ardour/editor.cc:1991
+#: gtk2_ardour/editor.cc:1823
+#: gtk2_ardour/editor.cc:1901
 msgid "Select all before playhead"
 msgstr "Alles vor Positionszeiger auswählen"
 
-#: gtk2_ardour/editor.cc:1914
+#: gtk2_ardour/editor.cc:1824
 msgid "Select all between cursors"
 msgstr "Alles zwischen Zeigern auswählen"
 
-#: gtk2_ardour/editor.cc:1917
-#: gtk2_ardour/editor.cc:1993
+#: gtk2_ardour/editor.cc:1827
+#: gtk2_ardour/editor.cc:1903
 msgid "Select"
 msgstr "Auswahl"
 
-#: gtk2_ardour/editor.cc:1925
-#: gtk2_ardour/editor.cc:2001
-#: gtk2_ardour/editor_actions.cc:215
-#: gtk2_ardour/redirect_box.cc:1070
+#: gtk2_ardour/editor.cc:1835
+#: gtk2_ardour/editor.cc:1911
+#: gtk2_ardour/editor_actions.cc:217
+#: gtk2_ardour/redirect_box.cc:1144
 msgid "Cut"
 msgstr "Ausschneiden"
 
-#: gtk2_ardour/editor.cc:1926
-#: gtk2_ardour/editor.cc:2002
-#: gtk2_ardour/editor_actions.cc:220
-#: gtk2_ardour/redirect_box.cc:1072
+#: gtk2_ardour/editor.cc:1836
+#: gtk2_ardour/editor.cc:1912
+#: gtk2_ardour/editor_actions.cc:222
+#: gtk2_ardour/redirect_box.cc:1146
 msgid "Copy"
 msgstr "Kopieren"
 
-#: gtk2_ardour/editor.cc:1927
+#: gtk2_ardour/editor.cc:1837
 msgid "Paste at edit cursor"
 msgstr "Am Editierzeiger einfügen"
 
-#: gtk2_ardour/editor.cc:1928
+#: gtk2_ardour/editor.cc:1838
 msgid "Paste at mouse"
 msgstr "An Mausposition einfügen"
 
-#: gtk2_ardour/editor.cc:1932
+#: gtk2_ardour/editor.cc:1842
 msgid "Align"
 msgstr "Ausrichten"
 
-#: gtk2_ardour/editor.cc:1933
+#: gtk2_ardour/editor.cc:1843
 msgid "Align Relative"
 msgstr "Relativ ausrichten"
 
-#: gtk2_ardour/editor.cc:1937
+#: gtk2_ardour/editor.cc:1847
 msgid "Insert chunk"
 msgstr "Abschnitt einfügen"
 
-#: gtk2_ardour/editor.cc:1944
+#: gtk2_ardour/editor.cc:1854
 msgid "Insert Selected Region"
 msgstr "Ausgewählte Region einfügen"
 
-#: gtk2_ardour/editor.cc:1945
+#: gtk2_ardour/editor.cc:1855
 msgid "Insert Existing Audio"
 msgstr "Audio importieren..."
 
-#: gtk2_ardour/editor.cc:1954
-#: gtk2_ardour/editor.cc:2010
+#: gtk2_ardour/editor.cc:1864
+#: gtk2_ardour/editor.cc:1920
 msgid "Nudge entire track fwd"
 msgstr "Gesamte Spur schrittweise nach vorne"
 
-#: gtk2_ardour/editor.cc:1955
-#: gtk2_ardour/editor.cc:2011
+#: gtk2_ardour/editor.cc:1865
+#: gtk2_ardour/editor.cc:1921
 msgid "Nudge track after edit cursor fwd"
 msgstr "Spur nach Editierzeiger schrittweise nach vorne"
 
-#: gtk2_ardour/editor.cc:1956
-#: gtk2_ardour/editor.cc:2012
+#: gtk2_ardour/editor.cc:1866
+#: gtk2_ardour/editor.cc:1922
 msgid "Nudge entire track bwd"
 msgstr "Gesamte Spur schrittweise nach hinten"
 
-#: gtk2_ardour/editor.cc:1957
-#: gtk2_ardour/editor.cc:2013
+#: gtk2_ardour/editor.cc:1867
+#: gtk2_ardour/editor.cc:1923
 msgid "Nudge track after edit cursor bwd"
 msgstr "Spur nach Editierzeiger schrittweise nach hinten"
 
-#: gtk2_ardour/editor.cc:2003
-#: gtk2_ardour/editor_actions.cc:222
-#: gtk2_ardour/redirect_box.cc:1074
+#: gtk2_ardour/editor.cc:1913
+#: gtk2_ardour/editor_actions.cc:224
+#: gtk2_ardour/redirect_box.cc:1148
 msgid "Paste"
 msgstr "Einfügen"
 
-#: gtk2_ardour/editor.cc:2566
+#: gtk2_ardour/editor.cc:2498
 msgid "Select/Move Objects"
 msgstr "Objekte auswählen/verschieben"
 
-#: gtk2_ardour/editor.cc:2567
+#: gtk2_ardour/editor.cc:2499
 msgid "Select/Move Ranges"
 msgstr "Bereiche auswählen/verschieben"
 
-#: gtk2_ardour/editor.cc:2568
+#: gtk2_ardour/editor.cc:2500
 msgid "Draw Gain Automation"
-msgstr "Lautstärkeautomation zeichnen"
+msgstr "Lautstärkekurve zeichnen"
 
-#: gtk2_ardour/editor.cc:2569
+#: gtk2_ardour/editor.cc:2501
 msgid "Select Zoom Range"
 msgstr "Zoombereich auswählen"
 
-#: gtk2_ardour/editor.cc:2570
+#: gtk2_ardour/editor.cc:2502
 msgid "Stretch/Shrink Regions"
 msgstr "Regionen vergrößern/verkleinern (Time-Stretch)"
 
-#: gtk2_ardour/editor.cc:2571
+#: gtk2_ardour/editor.cc:2503
 msgid "Listen to Specific Regions"
 msgstr "Ausgewählte Regionen vorhören"
 
-#: gtk2_ardour/editor.cc:2600
+#: gtk2_ardour/editor.cc:2533
 #: gtk2_ardour/editor_actions.cc:143
 msgid "Zoom In"
 msgstr "Vergrößern"
 
-#: gtk2_ardour/editor.cc:2605
+#: gtk2_ardour/editor.cc:2539
 #: gtk2_ardour/editor_actions.cc:141
 msgid "Zoom Out"
 msgstr "Verkleinern"
 
-#: gtk2_ardour/editor.cc:2610
+#: gtk2_ardour/editor.cc:2545
 #: gtk2_ardour/editor_actions.cc:145
 msgid "Zoom to Session"
-msgstr "Auf ganze Sitzung zoomen"
+msgstr "Auf ganzes Projekt zoomen"
 
-#: gtk2_ardour/editor.cc:2617
-msgid ""
-"Current Zoom Range\n"
-"(Width of visible area)"
-msgstr ""
-
-#: gtk2_ardour/editor.cc:2623
+#: gtk2_ardour/editor.cc:2551
 msgid "Zoom focus"
 msgstr "Zoom-Mittelpunkt"
 
-#: gtk2_ardour/editor.cc:2637
+#: gtk2_ardour/editor.cc:2567
 msgid "Unit to snap cursors and ranges to"
 msgstr ""
 
-#: gtk2_ardour/editor.cc:3217
-#: gtk2_ardour/editor.cc:3266
+#: gtk2_ardour/editor.cc:3281
+#: gtk2_ardour/editor.cc:3330
 #, fuzzy
 msgid "set selected regions"
 msgstr "Auswahl zu Schleife machen"
 
-#: gtk2_ardour/editor.cc:3306
-#: gtk2_ardour/editor_actions.cc:205
+#: gtk2_ardour/editor.cc:3370
+#: gtk2_ardour/editor_actions.cc:207
 msgid "Undo"
 msgstr "Rückgängig"
 
-#: gtk2_ardour/editor.cc:3308
+#: gtk2_ardour/editor.cc:3372
 msgid "Undo (%1)"
 msgstr "Rückgängig (%1)"
 
-#: gtk2_ardour/editor.cc:3315
-#: gtk2_ardour/editor_actions.cc:207
+#: gtk2_ardour/editor.cc:3379
+#: gtk2_ardour/editor_actions.cc:209
 msgid "Redo"
 msgstr "Wiederherstellen"
 
-#: gtk2_ardour/editor.cc:3317
+#: gtk2_ardour/editor.cc:3381
 msgid "Redo (%1)"
 msgstr "Wiederherstellen (%1)"
 
-#: gtk2_ardour/editor.cc:3338
+#: gtk2_ardour/editor.cc:3402
 msgid "Duplicate how many times?"
 msgstr "Wie häufig duplizieren?"
 
-#: gtk2_ardour/editor.cc:3416
+#: gtk2_ardour/editor.cc:3480
 #, fuzzy
 msgid "Splice Edit"
 msgstr "Teilen"
 
-#: gtk2_ardour/editor.cc:3418
+#: gtk2_ardour/editor.cc:3482
 msgid "Slide Edit"
 msgstr ""
 
-#: gtk2_ardour/editor.cc:3828
+#: gtk2_ardour/editor.cc:3904
 msgid ""
 "Playlist %1 is currently unused.\n"
 "If left alone, no audio files used by it will be cleaned.\n"
 "If deleted, audio files used by it alone by will cleaned."
 msgstr ""
 
-#: gtk2_ardour/editor.cc:3836
+#: gtk2_ardour/editor.cc:3914
 msgid "Delete playlist"
 msgstr "Wiedergabeliste löschen"
 
-#: gtk2_ardour/editor.cc:3837
+#: gtk2_ardour/editor.cc:3915
 msgid "Keep playlist"
 msgstr "Wiedergabeliste beibehalten"
 
-#: gtk2_ardour/editor.cc:3838
-#: gtk2_ardour/editor_audio_import.cc:239
-#: gtk2_ardour/editor_ops.cc:1973
+#: gtk2_ardour/editor.cc:3916
+#: gtk2_ardour/editor_audio_import.cc:315
+#: gtk2_ardour/editor_ops.cc:2063
 #: gtk2_ardour/editor_timefx.cc:72
 #: gtk2_ardour/export_dialog.cc:969
 #: gtk2_ardour/io_selector.cc:61
-#: gtk2_ardour/io_selector.cc:750
-#: gtk2_ardour/redirect_box.cc:901
+#: gtk2_ardour/io_selector.cc:749
+#: gtk2_ardour/redirect_box.cc:975
 #: gtk2_ardour/tempo_dialog.cc:20
 #: gtk2_ardour/tempo_dialog.cc:37
 #: gtk2_ardour/tempo_dialog.cc:202
@@ -2832,15 +2820,15 @@ msgstr "Wiedergabeliste beibehalten"
 msgid "Cancel"
 msgstr "Abbrechen"
 
-#: gtk2_ardour/editor.cc:4041
+#: gtk2_ardour/editor.cc:4120
 msgid "new playlists"
 msgstr "Neue Wiedergabelisten"
 
-#: gtk2_ardour/editor.cc:4049
+#: gtk2_ardour/editor.cc:4128
 msgid "copy playlists"
 msgstr "Wiedergabelisten kopieren"
 
-#: gtk2_ardour/editor.cc:4057
+#: gtk2_ardour/editor.cc:4136
 msgid "clear playlists"
 msgstr ""
 
@@ -2881,9 +2869,8 @@ msgid "Meter falloff"
 msgstr "Abfall der Pegelanzeigen"
 
 #: gtk2_ardour/editor_actions.cc:39
-#, fuzzy
 msgid "Crossfades"
-msgstr "Ardour: Editor"
+msgstr "ardour: Editor"
 
 #: gtk2_ardour/editor_actions.cc:40
 msgid "Monitoring"
@@ -2990,7 +2977,7 @@ msgid "Edit Cursor to Range End"
 msgstr "Editierzeiger zum Ende der Auswahl"
 
 #: gtk2_ardour/editor_actions.cc:106
-#: gtk2_ardour/editor_ops.cc:1292
+#: gtk2_ardour/editor_ops.cc:1331
 msgid "select all"
 msgstr "Alle Regionen auswählen"
 
@@ -3087,539 +3074,548 @@ msgstr "Ansicht am Positionszeiger zentrieren"
 msgid "Center Edit Cursor"
 msgstr "Editierzeiger zentrieren"
 
-#: gtk2_ardour/editor_actions.cc:167
-msgid "Playhead Forward"
+#: gtk2_ardour/editor_actions.cc:168
+msgid "Playhead forward"
 msgstr "Positionszeiger vorwärts"
 
-#: gtk2_ardour/editor_actions.cc:169
+#: gtk2_ardour/editor_actions.cc:170
 msgid "Playhead Backward"
 msgstr "Positionszeiger rückwärts"
 
-#: gtk2_ardour/editor_actions.cc:171
+#: gtk2_ardour/editor_actions.cc:173
 msgid "Playhead to Edit"
 msgstr "Positionszeiger zum Editierzeiger setzen"
 
-#: gtk2_ardour/editor_actions.cc:173
+#: gtk2_ardour/editor_actions.cc:175
 msgid "Edit to Playhead"
 msgstr "Editierzeiger zum Positionszeiger setzen"
 
-#: gtk2_ardour/editor_actions.cc:176
+#: gtk2_ardour/editor_actions.cc:178
 #, fuzzy
 msgid "Align Regions Start"
 msgstr "Regionen"
 
-#: gtk2_ardour/editor_actions.cc:178
+#: gtk2_ardour/editor_actions.cc:180
 #, fuzzy
 msgid "Align Regions Start Relative"
 msgstr "nach Anfang der Region in der Datei"
 
-#: gtk2_ardour/editor_actions.cc:180
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:182
 msgid "Align Regions End"
-msgstr "Ardour: Region"
+msgstr "ardour: Region"
 
-#: gtk2_ardour/editor_actions.cc:182
+#: gtk2_ardour/editor_actions.cc:184
 msgid "Align Regions End Relative"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:185
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:187
 msgid "Align Regions Sync"
-msgstr "Ardour: Region"
+msgstr "ardour: Region"
 
-#: gtk2_ardour/editor_actions.cc:187
+#: gtk2_ardour/editor_actions.cc:189
 msgid "Align Regions Sync Relative"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:190
+#: gtk2_ardour/editor_actions.cc:192
 msgid "Audition at Mouse"
 msgstr "An Mauszeigerposition vorhören"
 
-#: gtk2_ardour/editor_actions.cc:192
+#: gtk2_ardour/editor_actions.cc:194
 msgid "Brush at Mouse"
 msgstr "Pinsel an Mausposition (Brush)"
 
-#: gtk2_ardour/editor_actions.cc:194
+#: gtk2_ardour/editor_actions.cc:196
 msgid "Set Edit Cursor"
 msgstr "Editierzeiger setzen"
 
-#: gtk2_ardour/editor_actions.cc:196
+#: gtk2_ardour/editor_actions.cc:198
 msgid "Mute/Unmute Region"
 msgstr "Region Mute/Unmute"
 
-#: gtk2_ardour/editor_actions.cc:198
+#: gtk2_ardour/editor_actions.cc:200
 msgid "Set Playhead"
 msgstr "Positionszeiger setzen"
 
-#: gtk2_ardour/editor_actions.cc:200
+#: gtk2_ardour/editor_actions.cc:202
 msgid "Split Region"
 msgstr "Region teilen (Split)"
 
-#: gtk2_ardour/editor_actions.cc:202
+#: gtk2_ardour/editor_actions.cc:204
 msgid "Set Region Sync Position"
 msgstr "Sync-Position der Region setzen"
 
-#: gtk2_ardour/editor_actions.cc:210
+#: gtk2_ardour/editor_actions.cc:212
 #, fuzzy
 msgid "Export Session"
 msgstr "Name für Region:"
 
-#: gtk2_ardour/editor_actions.cc:212
+#: gtk2_ardour/editor_actions.cc:214
 #, fuzzy
 msgid "Export Range"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#: gtk2_ardour/editor_actions.cc:218
+#: gtk2_ardour/editor_actions.cc:220
 #: gtk2_ardour/connection_editor.cc:56
 msgid "Delete"
 msgstr "Löschen"
 
-#: gtk2_ardour/editor_actions.cc:224
+#: gtk2_ardour/editor_actions.cc:226
 msgid "Duplicate Region"
 msgstr "Duplizieren"
 
-#: gtk2_ardour/editor_actions.cc:226
+#: gtk2_ardour/editor_actions.cc:228
 #, fuzzy
 msgid "Duplicate Range"
 msgstr "Duplizieren"
 
-#: gtk2_ardour/editor_actions.cc:228
+#: gtk2_ardour/editor_actions.cc:230
 msgid "Insert Region"
 msgstr "Einfügen"
 
-#: gtk2_ardour/editor_actions.cc:230
+#: gtk2_ardour/editor_actions.cc:232
 msgid "Reverse Region"
 msgstr "Rückwärts"
 
-#: gtk2_ardour/editor_actions.cc:232
+#: gtk2_ardour/editor_actions.cc:234
 msgid "Normalize Region"
 msgstr "Normalisieren"
 
-#: gtk2_ardour/editor_actions.cc:234
+#: gtk2_ardour/editor_actions.cc:236
 msgid "crop"
 msgstr "Abschneiden"
 
-#: gtk2_ardour/editor_actions.cc:236
-#, fuzzy
+#: gtk2_ardour/editor_actions.cc:238
 msgid "Insert Chunk"
 msgstr "Abschnitt einfügen"
 
-#: gtk2_ardour/editor_actions.cc:239
+#: gtk2_ardour/editor_actions.cc:241
 #, fuzzy
 msgid "Split at edit cursor"
 msgstr "Wiedergabe ab Cursor"
 
-#: gtk2_ardour/editor_actions.cc:242
+#: gtk2_ardour/editor_actions.cc:244
 msgid "Start Range"
 msgstr "Bereich anfangen"
 
-#: gtk2_ardour/editor_actions.cc:244
+#: gtk2_ardour/editor_actions.cc:246
 msgid "Finish Range"
 msgstr "Bereich beenden"
 
-#: gtk2_ardour/editor_actions.cc:246
+#: gtk2_ardour/editor_actions.cc:248
 msgid "Finish add Range"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:249
+#: gtk2_ardour/editor_actions.cc:251
 msgid "Extend Range to End of Region"
 msgstr "Bereich vergrößern bis zum Ende der Region "
 
-#: gtk2_ardour/editor_actions.cc:251
+#: gtk2_ardour/editor_actions.cc:253
 msgid "Extend Range to Start of Region"
 msgstr "Bereich vergrößern bis zum Anfang der Region "
 
-#: gtk2_ardour/editor_actions.cc:254
+#: gtk2_ardour/editor_actions.cc:256
 msgid "Follow Playhead"
 msgstr "Positionszeiger folgen"
 
-#: gtk2_ardour/editor_actions.cc:262
+#: gtk2_ardour/editor_actions.cc:264
 msgid "Zoom Focus Left"
 msgstr "Am linken Rand ausrichten"
 
-#: gtk2_ardour/editor_actions.cc:264
+#: gtk2_ardour/editor_actions.cc:266
 msgid "Zoom Focus Right"
 msgstr "Am rechten Rand ausrichten"
 
-#: gtk2_ardour/editor_actions.cc:266
+#: gtk2_ardour/editor_actions.cc:268
 msgid "Zoom Focus Center"
 msgstr "Zentriert ausrichten"
 
-#: gtk2_ardour/editor_actions.cc:268
+#: gtk2_ardour/editor_actions.cc:270
 msgid "Zoom Focus Playhead"
 msgstr "Am Positionszeiger ausrichten"
 
-#: gtk2_ardour/editor_actions.cc:270
+#: gtk2_ardour/editor_actions.cc:272
 msgid "Zoom Focus Edit"
 msgstr "Am Editierzeiger ausrichten"
 
-#: gtk2_ardour/editor_actions.cc:276
+#: gtk2_ardour/editor_actions.cc:278
 msgid "Object Tool"
 msgstr "Objektwerkzeug"
 
-#: gtk2_ardour/editor_actions.cc:277
+#: gtk2_ardour/editor_actions.cc:279
 msgid "Range Tool"
 msgstr "Bereich-Werkzeug (Range)"
 
-#: gtk2_ardour/editor_actions.cc:278
+#: gtk2_ardour/editor_actions.cc:280
 msgid "Gain Tool"
 msgstr "Lautstärkewerkzeug (Gain)"
 
-#: gtk2_ardour/editor_actions.cc:279
+#: gtk2_ardour/editor_actions.cc:281
 msgid "Zoom Tool"
 msgstr "Zoom-Werkzeug"
 
-#: gtk2_ardour/editor_actions.cc:280
+#: gtk2_ardour/editor_actions.cc:282
 msgid "Timefx Tool"
 msgstr "Zeit-Werkzeug (Time)"
 
-#: gtk2_ardour/editor_actions.cc:282
+#: gtk2_ardour/editor_actions.cc:284
 msgid "Snap To"
 msgstr "Raster"
 
-#: gtk2_ardour/editor_actions.cc:283
+#: gtk2_ardour/editor_actions.cc:285
 msgid "Snap Mode"
 msgstr "Einrastmodus"
 
-#: gtk2_ardour/editor_actions.cc:292
+#: gtk2_ardour/editor_actions.cc:294
 msgid "Snap to frame"
 msgstr "An Frames einrasten"
 
-#: gtk2_ardour/editor_actions.cc:293
+#: gtk2_ardour/editor_actions.cc:295
 msgid "Snap to cd frame"
 msgstr "An CD-Frames einrasten"
 
-#: gtk2_ardour/editor_actions.cc:294
+#: gtk2_ardour/editor_actions.cc:296
 msgid "Snap to SMPTE frame"
 msgstr "An SMPTE-Frames einrasten"
 
-#: gtk2_ardour/editor_actions.cc:295
+#: gtk2_ardour/editor_actions.cc:297
 msgid "Snap to SMPTE seconds"
 msgstr "An SMPTE-Sekunden einrasten"
 
-#: gtk2_ardour/editor_actions.cc:296
+#: gtk2_ardour/editor_actions.cc:298
 msgid "Snap to SMPTE minutes"
 msgstr "An SMPTE-Minuten einrasten"
 
-#: gtk2_ardour/editor_actions.cc:297
+#: gtk2_ardour/editor_actions.cc:299
 msgid "Snap to seconds"
 msgstr "An Sekunden einrasten"
 
-#: gtk2_ardour/editor_actions.cc:298
+#: gtk2_ardour/editor_actions.cc:300
 msgid "Snap to minutes"
 msgstr "An Minuten einrasten"
 
-#: gtk2_ardour/editor_actions.cc:299
+#: gtk2_ardour/editor_actions.cc:301
 msgid "Snap to thirtyseconds"
 msgstr "An halben Minuten einrasten"
 
-#: gtk2_ardour/editor_actions.cc:300
+#: gtk2_ardour/editor_actions.cc:302
 msgid "Snap to asixteenthbeat"
 msgstr "An Sechzehnteln einrasten"
 
-#: gtk2_ardour/editor_actions.cc:301
+#: gtk2_ardour/editor_actions.cc:303
 msgid "Snap to eighths"
 msgstr "An Achteln einrasten"
 
-#: gtk2_ardour/editor_actions.cc:302
+#: gtk2_ardour/editor_actions.cc:304
 msgid "Snap to quarters"
 msgstr "An Vierteln einrasten"
 
-#: gtk2_ardour/editor_actions.cc:303
+#: gtk2_ardour/editor_actions.cc:305
 msgid "Snap to thirds"
 msgstr "An Triolen einrasten"
 
-#: gtk2_ardour/editor_actions.cc:304
+#: gtk2_ardour/editor_actions.cc:306
 msgid "Snap to beat"
 msgstr "An Schlägen einrasten"
 
-#: gtk2_ardour/editor_actions.cc:305
+#: gtk2_ardour/editor_actions.cc:307
 msgid "Snap to bar"
 msgstr "An Takten einrasten"
 
-#: gtk2_ardour/editor_actions.cc:306
+#: gtk2_ardour/editor_actions.cc:308
 msgid "Snap to mark"
 msgstr "An Markern einrasten"
 
-#: gtk2_ardour/editor_actions.cc:307
+#: gtk2_ardour/editor_actions.cc:309
 msgid "Snap to edit cursor"
 msgstr "Am Editierzeiger einrasten"
 
-#: gtk2_ardour/editor_actions.cc:308
+#: gtk2_ardour/editor_actions.cc:310
 msgid "Snap to region start"
 msgstr "Am Anfang der Regionen einrasten"
 
-#: gtk2_ardour/editor_actions.cc:309
+#: gtk2_ardour/editor_actions.cc:311
 msgid "Snap to region end"
 msgstr "Am Ende der Regionen einrasten"
 
-#: gtk2_ardour/editor_actions.cc:310
+#: gtk2_ardour/editor_actions.cc:312
 msgid "Snap to region sync"
 msgstr "Am Sync der Regionen einrasten"
 
-#: gtk2_ardour/editor_actions.cc:311
+#: gtk2_ardour/editor_actions.cc:313
 msgid "Snap to region boundary"
 msgstr "An Grenzen der Regionen einrasten"
 
-#: gtk2_ardour/editor_actions.cc:320
+#: gtk2_ardour/editor_actions.cc:322
 msgid "Sort"
 msgstr "Sortieren"
 
-#: gtk2_ardour/editor_actions.cc:328
+#: gtk2_ardour/editor_actions.cc:330
 msgid "Show all"
 msgstr "Alle zeigen"
 
-#: gtk2_ardour/editor_actions.cc:329
+#: gtk2_ardour/editor_actions.cc:331
 msgid "Show automatic regions"
 msgstr "Automatische Regionen zeigen"
 
-#: gtk2_ardour/editor_actions.cc:331
+#: gtk2_ardour/editor_actions.cc:333
 msgid "Ascending"
 msgstr "aufsteigend"
 
-#: gtk2_ardour/editor_actions.cc:333
+#: gtk2_ardour/editor_actions.cc:335
 msgid "Descending"
 msgstr "absteigend"
 
-#: gtk2_ardour/editor_actions.cc:336
+#: gtk2_ardour/editor_actions.cc:338
 msgid "By Region Name"
 msgstr "nach Name der Region"
 
-#: gtk2_ardour/editor_actions.cc:338
+#: gtk2_ardour/editor_actions.cc:340
 msgid "By Region Length"
 msgstr "nach Länge der Region"
 
-#: gtk2_ardour/editor_actions.cc:340
+#: gtk2_ardour/editor_actions.cc:342
 msgid "By Region Position"
 msgstr "nach Position der Region"
 
-#: gtk2_ardour/editor_actions.cc:342
+#: gtk2_ardour/editor_actions.cc:344
 msgid "By Region Timestamp"
 msgstr "nach Zeitstempel der Region"
 
-#: gtk2_ardour/editor_actions.cc:344
+#: gtk2_ardour/editor_actions.cc:346
 msgid "By Region Start in File"
 msgstr "nach Anfang der Region in der Datei"
 
-#: gtk2_ardour/editor_actions.cc:346
+#: gtk2_ardour/editor_actions.cc:348
 msgid "By Region End in File"
 msgstr "nach Ende der Region in der Datei"
 
-#: gtk2_ardour/editor_actions.cc:348
+#: gtk2_ardour/editor_actions.cc:350
 msgid "By Source File Name"
 msgstr "nach Namen der Quelldatei"
 
-#: gtk2_ardour/editor_actions.cc:350
+#: gtk2_ardour/editor_actions.cc:352
 msgid "By Source File Length"
 msgstr "nach Länge der Quelldatei"
 
-#: gtk2_ardour/editor_actions.cc:352
+#: gtk2_ardour/editor_actions.cc:354
 msgid "By Source File Creation Date"
 msgstr "nach Erstellungsdatum der Quelldatei"
 
-#: gtk2_ardour/editor_actions.cc:354
+#: gtk2_ardour/editor_actions.cc:356
 msgid "By Source Filesystem"
 msgstr "nach Dateisystem der Quelle"
 
-#: gtk2_ardour/editor_actions.cc:360
+#: gtk2_ardour/editor_actions.cc:362
 msgid "Add External Audio"
 msgstr "Audio importieren..."
 
-#: gtk2_ardour/editor_actions.cc:362
+#: gtk2_ardour/editor_actions.cc:364
 msgid "as Region(s)"
 msgstr "als Region(en)..."
 
-#: gtk2_ardour/editor_actions.cc:364
+#: gtk2_ardour/editor_actions.cc:366
 msgid "as Tracks"
 msgstr "als neue Spur(en)..."
 
-#: gtk2_ardour/editor_actions.cc:366
+#: gtk2_ardour/editor_actions.cc:368
 msgid "as Tape Tracks"
 msgstr "als neue Tape-Spur(en)..."
 
-#: gtk2_ardour/editor_actions.cc:368
+#: gtk2_ardour/editor_actions.cc:370
 msgid "to Tracks"
 msgstr "in vorhandene Spuren..."
 
-#: gtk2_ardour/editor_actions.cc:371
+#: gtk2_ardour/editor_actions.cc:373
 msgid "Show Waveforms"
 msgstr "Wellenformen zeigen"
 
-#: gtk2_ardour/editor_actions.cc:372
+#: gtk2_ardour/editor_actions.cc:374
 msgid "Show Waveforms While Recording"
 msgstr "Wellenformen beim Aufnehmen zeigen"
 
-#: gtk2_ardour/editor_actions.cc:373
+#: gtk2_ardour/editor_actions.cc:375
 msgid "Show Measures"
 msgstr "Takte zeigen"
 
-#: gtk2_ardour/editor_actions.cc:377
+#: gtk2_ardour/editor_actions.cc:379
 msgid "Later is Higher"
 msgstr "Neuste nach oben"
 
-#: gtk2_ardour/editor_actions.cc:378
+#: gtk2_ardour/editor_actions.cc:380
 msgid "Most Recently Moved/Added is Higher"
 msgstr "Zuletzt bewegte/hinzugefügte nach oben"
 
-#: gtk2_ardour/editor_actions.cc:379
+#: gtk2_ardour/editor_actions.cc:381
 msgid "Most Recently Added is Higher"
 msgstr "Zuletzt hinzugefügte nach oben"
 
-#: gtk2_ardour/editor_actions.cc:383
+#: gtk2_ardour/editor_actions.cc:385
 msgid "23.976"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:384
+#: gtk2_ardour/editor_actions.cc:386
 msgid "24"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:385
+#: gtk2_ardour/editor_actions.cc:387
 msgid "24.976"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:386
+#: gtk2_ardour/editor_actions.cc:388
 msgid "25"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:387
+#: gtk2_ardour/editor_actions.cc:389
 msgid "29.97"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:388
+#: gtk2_ardour/editor_actions.cc:390
 msgid "29.97 drop"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:389
+#: gtk2_ardour/editor_actions.cc:391
 msgid "30"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:390
+#: gtk2_ardour/editor_actions.cc:392
 msgid "30 drop"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:391
+#: gtk2_ardour/editor_actions.cc:393
 msgid "59.94"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:392
+#: gtk2_ardour/editor_actions.cc:394
 msgid "60"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:396
+#: gtk2_ardour/editor_actions.cc:398
 msgid "+4.1667% + 0.1%"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:397
+#: gtk2_ardour/editor_actions.cc:399
 msgid "+4.1667%"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:398
+#: gtk2_ardour/editor_actions.cc:400
 msgid "+4.1667% - 0.1%"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:399
+#: gtk2_ardour/editor_actions.cc:401
 msgid "+ 0.1%"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:401
+#: gtk2_ardour/editor_actions.cc:403
 msgid "- 0.1%"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:402
+#: gtk2_ardour/editor_actions.cc:404
 msgid "-4.1667% + 0.1%"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:403
+#: gtk2_ardour/editor_actions.cc:405
 msgid "-4.1667%"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:404
+#: gtk2_ardour/editor_actions.cc:406
 msgid "-4.1667% - 0.1%"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:408
+#: gtk2_ardour/editor_actions.cc:410
 msgid "80 per frame"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:409
+#: gtk2_ardour/editor_actions.cc:411
 msgid "100 per frame"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:529
-msgid "programming error: Unexpected SMPTE value (%1, drop = %2) in update_smpte_mode.  Menu is probably wrong."
-msgstr ""
-
-#: gtk2_ardour/editor_actions.cc:708
-#: gtk2_ardour/editor_actions.cc:753
-#: gtk2_ardour/editor_actions.cc:764
-#: gtk2_ardour/editor_actions.cc:808
-#: gtk2_ardour/editor_actions.cc:818
+#: gtk2_ardour/editor_actions.cc:714
+#: gtk2_ardour/editor_actions.cc:759
+#: gtk2_ardour/editor_actions.cc:770
+#: gtk2_ardour/editor_actions.cc:814
+#: gtk2_ardour/editor_actions.cc:824
 msgid "programming error: %1: %2"
 msgstr ""
 
-#: gtk2_ardour/editor_actions.cc:719
-#: gtk2_ardour/editor_actions.cc:970
-#: gtk2_ardour/editor_actions.cc:983
-#: gtk2_ardour/editor_actions.cc:1047
-#: gtk2_ardour/sfdb_ui.cc:454
-msgid "programming error: %1"
-msgstr ""
-
-#: gtk2_ardour/editor_actions.cc:1002
+#: gtk2_ardour/editor_actions.cc:985
 msgid "Configuraton is using unhandled subframes per frame value: %1"
 msgstr ""
 
-#: gtk2_ardour/editor_audio_import.cc:75
+#: gtk2_ardour/editor_audio_import.cc:76
 #, fuzzy
 msgid "You can't import or embed an audiofile until you have a session loaded."
-msgstr "Sie können keine Audio-Daten importieren, solange keine Sitzung geladen ist."
+msgstr "Sie können keine Audio-Daten importieren, solange kein Projekt geladen ist."
 
-#: gtk2_ardour/editor_audio_import.cc:80
+#: gtk2_ardour/editor_audio_import.cc:81
 msgid "Add existing audio to session"
 msgstr "Audio importieren"
 
-#: gtk2_ardour/editor_audio_import.cc:145
+#: gtk2_ardour/editor_audio_import.cc:166
+msgid "Import as a %1 region"
+msgstr ""
+
+#: gtk2_ardour/editor_audio_import.cc:167
+#, fuzzy
+msgid "multichannel"
+msgstr "Kanäle"
+
+#: gtk2_ardour/editor_audio_import.cc:167
+#: gtk2_ardour/export_dialog.cc:84
+msgid "stereo"
+msgstr ""
+
+#: gtk2_ardour/editor_audio_import.cc:168
 #, fuzzy
+msgid "Import as multiple regions"
+msgstr "Auswahl zu Schleife machen"
+
+#: gtk2_ardour/editor_audio_import.cc:170
+msgid ""
+"Paired files detected (%1, %2 ...).\n"
+"Do you want to:"
+msgstr ""
+
+#: gtk2_ardour/editor_audio_import.cc:216
 msgid "ardour: importing %1"
-msgstr "Ardour: Exportieren"
+msgstr "ardour: Importiere %1"
 
-#: gtk2_ardour/editor_audio_import.cc:149
+#: gtk2_ardour/editor_audio_import.cc:220
 msgid "Cancel Import"
 msgstr "Importieren Abbrechen"
 
-#: gtk2_ardour/editor_audio_import.cc:227
+#: gtk2_ardour/editor_audio_import.cc:303
 msgid "Editor: cannot open file \"%1\", (%2)"
 msgstr ""
 
-#: gtk2_ardour/editor_audio_import.cc:235
+#: gtk2_ardour/editor_audio_import.cc:311
 #, fuzzy
 msgid "Cancel entire import"
 msgstr "Importieren Abbrechen"
 
-#: gtk2_ardour/editor_audio_import.cc:236
+#: gtk2_ardour/editor_audio_import.cc:312
 #, fuzzy
 msgid "Don't embed it"
 msgstr "Ohne %1"
 
-#: gtk2_ardour/editor_audio_import.cc:237
+#: gtk2_ardour/editor_audio_import.cc:313
 msgid "Embed all without questions"
 msgstr ""
 
-#: gtk2_ardour/editor_audio_import.cc:242
+#: gtk2_ardour/editor_audio_import.cc:318
 msgid "Embed it anyway"
 msgstr ""
 
-#: gtk2_ardour/editor_audio_import.cc:245
+#: gtk2_ardour/editor_audio_import.cc:321
 msgid ""
 "%1\n"
 "This audiofile's sample rate doesn't match the session sample rate!"
 msgstr ""
 
-#: gtk2_ardour/editor_audio_import.cc:282
+#: gtk2_ardour/editor_audio_import.cc:360
 msgid "could not open %1"
 msgstr "Konnte \"%s\" nicht Ã¶ffnen."
 
-#: gtk2_ardour/editor_audio_import.cc:331
+#: gtk2_ardour/editor_audio_import.cc:407
 #, fuzzy
 msgid "insert sndfile"
 msgstr "Stille einfügen"
@@ -3629,28 +3625,27 @@ msgid "VerboseCanvasCursor"
 msgstr ""
 
 #: gtk2_ardour/editor_edit_groups.cc:53
-#: gtk2_ardour/mixer_ui.cc:754
+#: gtk2_ardour/mixer_ui.cc:751
 msgid "Activate All"
 msgstr "Alle aktivieren"
 
 #: gtk2_ardour/editor_edit_groups.cc:54
-#: gtk2_ardour/mixer_ui.cc:755
+#: gtk2_ardour/mixer_ui.cc:752
 msgid "Disable All"
 msgstr "Alle deaktivieren"
 
 #: gtk2_ardour/editor_edit_groups.cc:56
-#: gtk2_ardour/mixer_ui.cc:757
+#: gtk2_ardour/mixer_ui.cc:754
 msgid "Add group"
 msgstr "Gruppe hinzufügen"
 
 #: gtk2_ardour/editor_edit_groups.cc:229
-#: gtk2_ardour/mixer_ui.cc:988
-#, fuzzy
+#: gtk2_ardour/mixer_ui.cc:985
 msgid "unnamed"
-msgstr "Umbenennen"
+msgstr "unbenannt"
 
 #: gtk2_ardour/editor_edit_groups.cc:258
-#: gtk2_ardour/mixer_ui.cc:852
+#: gtk2_ardour/mixer_ui.cc:849
 msgid "-all-"
 msgstr "-alle-"
 
@@ -3668,13 +3663,13 @@ msgid ""
 "Create 1 or more ranges by dragging the mouse in the range bar"
 msgstr ""
 
-#: gtk2_ardour/editor_imageframe.cc:625
-#: gtk2_ardour/editor_imageframe.cc:655
+#: gtk2_ardour/editor_imageframe.cc:623
+#: gtk2_ardour/editor_imageframe.cc:653
 msgid "programming error: no ImageFrameView selected"
 msgstr ""
 
-#: gtk2_ardour/editor_imageframe.cc:848
-#: gtk2_ardour/editor_imageframe.cc:870
+#: gtk2_ardour/editor_imageframe.cc:846
+#: gtk2_ardour/editor_imageframe.cc:868
 msgid "programming error: no MarkerView selected"
 msgstr ""
 
@@ -3688,142 +3683,136 @@ msgstr "Name für Region:"
 msgid "keyboard selection"
 msgstr "Auswahl zu Abschnitt machen"
 
-#: gtk2_ardour/editor_markers.cc:293
-#: gtk2_ardour/editor_ops.cc:1213
-#: gtk2_ardour/editor_ops.cc:1227
-#: gtk2_ardour/editor_ops.cc:1246
-#: gtk2_ardour/location_ui.cc:776
+#: gtk2_ardour/editor_markers.cc:295
+#: gtk2_ardour/editor_ops.cc:1249
+#: gtk2_ardour/editor_ops.cc:1266
+#: gtk2_ardour/editor_ops.cc:1285
+#: gtk2_ardour/location_ui.cc:779
 msgid "add marker"
 msgstr ""
 
-#: gtk2_ardour/editor_markers.cc:309
-#: gtk2_ardour/editor_markers.cc:383
-#: gtk2_ardour/editor_markers.cc:555
-#: gtk2_ardour/editor_markers.cc:573
-#: gtk2_ardour/editor_markers.cc:592
-#: gtk2_ardour/editor_markers.cc:611
-#: gtk2_ardour/editor_markers.cc:641
-#: gtk2_ardour/editor_markers.cc:669
-#: gtk2_ardour/editor_markers.cc:697
-#: gtk2_ardour/editor_markers.cc:735
-#: gtk2_ardour/editor_markers.cc:762
-#: gtk2_ardour/editor_markers.cc:785
-#: gtk2_ardour/editor_markers.cc:804
-#: gtk2_ardour/editor_mouse.cc:2031
-#: gtk2_ardour/editor_mouse.cc:4331
+#: gtk2_ardour/editor_markers.cc:311
+#: gtk2_ardour/editor_markers.cc:375
+#: gtk2_ardour/editor_markers.cc:551
+#: gtk2_ardour/editor_markers.cc:569
+#: gtk2_ardour/editor_markers.cc:588
+#: gtk2_ardour/editor_markers.cc:607
+#: gtk2_ardour/editor_markers.cc:637
+#: gtk2_ardour/editor_markers.cc:665
+#: gtk2_ardour/editor_markers.cc:693
+#: gtk2_ardour/editor_markers.cc:732
+#: gtk2_ardour/editor_markers.cc:757
+#: gtk2_ardour/editor_markers.cc:784
+#: gtk2_ardour/editor_markers.cc:807
+#: gtk2_ardour/editor_markers.cc:826
+#: gtk2_ardour/editor_mouse.cc:2080
+#: gtk2_ardour/editor_mouse.cc:4395
 msgid "programming error: marker canvas item has no marker object pointer!"
 msgstr ""
 
-#: gtk2_ardour/editor_markers.cc:333
+#: gtk2_ardour/editor_markers.cc:325
 #: gtk2_ardour/location_ui.cc:657
 msgid "remove marker"
 msgstr "Marker entfernen"
 
-#: gtk2_ardour/editor_markers.cc:461
+#: gtk2_ardour/editor_markers.cc:466
 msgid "Locate to Mark"
 msgstr "Positionszeiger zu Marker setzen"
 
-#: gtk2_ardour/editor_markers.cc:462
+#: gtk2_ardour/editor_markers.cc:467
 msgid "Play from Mark"
 msgstr "Wiedergabe ab Marker"
 
-#: gtk2_ardour/editor_markers.cc:463
+#: gtk2_ardour/editor_markers.cc:468
 msgid "Set Mark from Playhead"
 msgstr "Marker am Positionszeiger setzen"
 
-#: gtk2_ardour/editor_markers.cc:467
-msgid "Rename Mark"
-msgstr "Marker umbenennen"
-
-#: gtk2_ardour/editor_markers.cc:468
+#: gtk2_ardour/editor_markers.cc:472
 msgid "Hide Mark"
 msgstr "Marker verbergen"
 
-#: gtk2_ardour/editor_markers.cc:469
+#: gtk2_ardour/editor_markers.cc:474
+msgid "Rename Mark"
+msgstr "Marker umbenennen"
+
+#: gtk2_ardour/editor_markers.cc:475
 msgid "Remove Mark"
 msgstr "Marker entfernen"
 
-#: gtk2_ardour/editor_markers.cc:482
-#: gtk2_ardour/editor_markers.cc:538
+#: gtk2_ardour/editor_markers.cc:493
 msgid "Locate to Range Mark"
 msgstr "Positionszeiger zu Bereichsmarker"
 
-#: gtk2_ardour/editor_markers.cc:483
-#: gtk2_ardour/editor_markers.cc:539
+#: gtk2_ardour/editor_markers.cc:494
 msgid "Play from Range Mark"
 msgstr "Wiedergabe ab Bereichsmarker"
 
-#: gtk2_ardour/editor_markers.cc:484
+#: gtk2_ardour/editor_markers.cc:496
+msgid "Play Range"
+msgstr "Bereich wiedergeben"
+
+#: gtk2_ardour/editor_markers.cc:497
 msgid "Loop Range"
 msgstr "Bereich in Schleife wiedergeben"
 
-#: gtk2_ardour/editor_markers.cc:485
-#: gtk2_ardour/editor_markers.cc:540
+#: gtk2_ardour/editor_markers.cc:499
 msgid "Set Range Mark from Playhead"
 msgstr "Bereichsmarker zum Positionszeiger verschieben"
 
-#: gtk2_ardour/editor_markers.cc:486
-#: gtk2_ardour/editor_markers.cc:541
+#: gtk2_ardour/editor_markers.cc:500
 msgid "Set Range from Range Selection"
 msgstr "Bereichsmarker zum Auswahlbereich verschieben"
 
-#: gtk2_ardour/editor_markers.cc:490
-msgid "Rename Range"
-msgstr "Bereich umbenennen"
-
-#: gtk2_ardour/editor_markers.cc:491
-#: gtk2_ardour/editor_markers.cc:543
+#: gtk2_ardour/editor_markers.cc:504
 msgid "Hide Range"
 msgstr "Bereich verbergen"
 
-#: gtk2_ardour/editor_markers.cc:492
+#: gtk2_ardour/editor_markers.cc:506
+msgid "Rename Range"
+msgstr "Bereich umbenennen"
+
+#: gtk2_ardour/editor_markers.cc:507
 msgid "Remove Range"
 msgstr "Bereich entfernen"
 
-#: gtk2_ardour/editor_markers.cc:496
-#: gtk2_ardour/editor_markers.cc:545
+#: gtk2_ardour/editor_markers.cc:512
 msgid "Separate Regions in Range"
 msgstr "Regionen an Bereichsgrenzen teilen"
 
-#: gtk2_ardour/editor_markers.cc:497
-#: gtk2_ardour/editor_markers.cc:546
+#: gtk2_ardour/editor_markers.cc:513
 msgid "Select All in Range"
 msgstr "Alles im Bereich auswählen"
 
-#: gtk2_ardour/editor_markers.cc:523
+#: gtk2_ardour/editor_markers.cc:539
 msgid "Set Loop Range"
 msgstr "Schleife erstellen"
 
-#: gtk2_ardour/editor_markers.cc:524
+#: gtk2_ardour/editor_markers.cc:540
 msgid "Set Punch Range"
 msgstr "Punch-Bereich erstellen"
 
-#: gtk2_ardour/editor_markers.cc:818
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:840
 msgid "New Name:"
 msgstr "Neuer Name: "
 
-#: gtk2_ardour/editor_markers.cc:821
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:843
 msgid "ardour: rename mark"
-msgstr "Ardour: Region umbenennen"
+msgstr "ardour: Marker umbenennen"
 
-#: gtk2_ardour/editor_markers.cc:823
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:845
 msgid "ardour: rename range"
-msgstr "Ardour: Region umbenennen"
+msgstr "ardour: Bereich umbenennen"
 
-#: gtk2_ardour/editor_markers.cc:843
+#: gtk2_ardour/editor_markers.cc:865
 #, fuzzy
 msgid "rename marker"
 msgstr "Feld entfernen"
 
-#: gtk2_ardour/editor_markers.cc:869
-#, fuzzy
+#: gtk2_ardour/editor_markers.cc:891
 msgid "set loop range"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr ""
 
-#: gtk2_ardour/editor_markers.cc:897
+#: gtk2_ardour/editor_markers.cc:919
 #, fuzzy
 msgid "set punch range"
 msgstr "Ausgewählten Bereich wiedergeben"
@@ -3833,154 +3822,150 @@ msgid "Editor::event_frame() used on unhandled event type %1"
 msgstr ""
 
 #: gtk2_ardour/editor_mouse.cc:315
-#, fuzzy
 msgid "select on click"
-msgstr "Auswahl"
+msgstr "Auswählen durch Klicken"
 
-#: gtk2_ardour/editor_mouse.cc:1596
+#: gtk2_ardour/editor_mouse.cc:1608
 msgid "programming error: start_grab called without drag item"
 msgstr ""
 
-#: gtk2_ardour/editor_mouse.cc:1820
+#: gtk2_ardour/editor_mouse.cc:1835
 msgid "change fade in length"
 msgstr ""
 
-#: gtk2_ardour/editor_mouse.cc:1842
+#: gtk2_ardour/editor_mouse.cc:1867
 msgid "programming error: fade out canvas item has no regionview data pointer!"
 msgstr ""
 
-#: gtk2_ardour/editor_mouse.cc:1916
-#, fuzzy
+#: gtk2_ardour/editor_mouse.cc:1952
 msgid "change fade out length"
-msgstr "Ardour: Editor"
+msgstr "Fade-Out verändern"
 
-#: gtk2_ardour/editor_mouse.cc:1939
+#: gtk2_ardour/editor_mouse.cc:1984
 msgid "programming error: cursor canvas item has no cursor data pointer!"
 msgstr ""
 
-#: gtk2_ardour/editor_mouse.cc:2166
+#: gtk2_ardour/editor_mouse.cc:2215
 msgid "move marker"
 msgstr "Marker bewegen"
 
-#: gtk2_ardour/editor_mouse.cc:2194
-#: gtk2_ardour/editor_mouse.cc:2225
+#: gtk2_ardour/editor_mouse.cc:2243
+#: gtk2_ardour/editor_mouse.cc:2274
 #: gtk2_ardour/editor_tempodisplay.cc:492
 msgid "programming error: meter marker canvas item has no marker object pointer!"
 msgstr ""
 
-#: gtk2_ardour/editor_mouse.cc:2293
-#, fuzzy
+#: gtk2_ardour/editor_mouse.cc:2342
 msgid "copy meter mark"
-msgstr "Ardour: Region umbenennen"
+msgstr "Taktmarker kopieren"
 
-#: gtk2_ardour/editor_mouse.cc:2304
+#: gtk2_ardour/editor_mouse.cc:2353
 msgid "move meter mark"
 msgstr "Taktwechsel bewegen"
 
-#: gtk2_ardour/editor_mouse.cc:2320
-#: gtk2_ardour/editor_mouse.cc:2353
+#: gtk2_ardour/editor_mouse.cc:2369
+#: gtk2_ardour/editor_mouse.cc:2402
 #: gtk2_ardour/editor_tempodisplay.cc:355
 #: gtk2_ardour/editor_tempodisplay.cc:439
 #: gtk2_ardour/editor_tempodisplay.cc:458
 msgid "programming error: tempo marker canvas item has no marker object pointer!"
 msgstr ""
 
-#: gtk2_ardour/editor_mouse.cc:2325
-#: gtk2_ardour/editor_mouse.cc:2358
+#: gtk2_ardour/editor_mouse.cc:2374
+#: gtk2_ardour/editor_mouse.cc:2407
 #: gtk2_ardour/editor_tempodisplay.cc:360
 #: gtk2_ardour/editor_tempodisplay.cc:444
 msgid "programming error: marker for tempo is not a tempo marker!"
 msgstr ""
 
-#: gtk2_ardour/editor_mouse.cc:2425
-#, fuzzy
+#: gtk2_ardour/editor_mouse.cc:2474
 msgid "copy tempo mark"
-msgstr "Ardour: Region umbenennen"
+msgstr "Tempomarker kopieren"
 
-#: gtk2_ardour/editor_mouse.cc:2436
+#: gtk2_ardour/editor_mouse.cc:2485
 msgid "move tempo mark"
 msgstr "Tempowechsel bewegen"
 
-#: gtk2_ardour/editor_mouse.cc:2451
-#: gtk2_ardour/editor_mouse.cc:2470
-#: gtk2_ardour/editor_mouse.cc:2483
+#: gtk2_ardour/editor_mouse.cc:2500
+#: gtk2_ardour/editor_mouse.cc:2519
+#: gtk2_ardour/editor_mouse.cc:2532
 msgid "programming error: control point canvas item has no control point object pointer!"
 msgstr ""
 
-#: gtk2_ardour/editor_mouse.cc:2589
+#: gtk2_ardour/editor_mouse.cc:2638
 msgid "programming error: line canvas item has no line pointer!"
 msgstr ""
 
-#: gtk2_ardour/editor_mouse.cc:2698
+#: gtk2_ardour/editor_mouse.cc:2747
 msgid "move region(s)"
 msgstr "Region(en) bewegen"
 
-#: gtk2_ardour/editor_mouse.cc:2762
+#: gtk2_ardour/editor_mouse.cc:2811
 #, fuzzy
 msgid "Drag region brush"
 msgstr "Ardour: Region"
 
-#: gtk2_ardour/editor_mouse.cc:2784
+#: gtk2_ardour/editor_mouse.cc:2833
 msgid "Drag region copy"
 msgstr ""
 
-#: gtk2_ardour/editor_mouse.cc:3648
+#: gtk2_ardour/editor_mouse.cc:3712
 #, fuzzy
 msgid "selection grab"
 msgstr "Auswahl"
 
-#: gtk2_ardour/editor_mouse.cc:3690
+#: gtk2_ardour/editor_mouse.cc:3754
 #, fuzzy
 msgid "cancel selection"
 msgstr "Auswahl wiedergeben"
 
-#: gtk2_ardour/editor_mouse.cc:3800
+#: gtk2_ardour/editor_mouse.cc:3864
 #, fuzzy
 msgid "range selection"
 msgstr "Auswahl wiedergeben"
 
-#: gtk2_ardour/editor_mouse.cc:3816
+#: gtk2_ardour/editor_mouse.cc:3880
 #, fuzzy
 msgid "trim selection start"
 msgstr "Auswahl zu Abschnitt machen"
 
-#: gtk2_ardour/editor_mouse.cc:3832
+#: gtk2_ardour/editor_mouse.cc:3896
 #, fuzzy
 msgid "trim selection end"
 msgstr "Auswahl zu Abschnitt machen"
 
-#: gtk2_ardour/editor_mouse.cc:3849
+#: gtk2_ardour/editor_mouse.cc:3913
 msgid "move selection"
 msgstr "Auswahl bewegen"
 
-#: gtk2_ardour/editor_mouse.cc:4240
+#: gtk2_ardour/editor_mouse.cc:4304
 msgid "Start point trim"
 msgstr ""
 
-#: gtk2_ardour/editor_mouse.cc:4272
+#: gtk2_ardour/editor_mouse.cc:4336
 msgid "End point trim"
 msgstr ""
 
-#: gtk2_ardour/editor_mouse.cc:4315
+#: gtk2_ardour/editor_mouse.cc:4379
 #, fuzzy
 msgid "trimmed region"
 msgstr "Ardour: Region"
 
-#: gtk2_ardour/editor_mouse.cc:4457
+#: gtk2_ardour/editor_mouse.cc:4522
 #, fuzzy
 msgid "new range marker"
 msgstr "Ardour: Region umbenennen"
 
-#: gtk2_ardour/editor_mouse.cc:4701
+#: gtk2_ardour/editor_mouse.cc:4767
 #, fuzzy
 msgid "select regions"
 msgstr "Auswahl zu Schleife machen"
 
-#: gtk2_ardour/editor_mouse.cc:4730
+#: gtk2_ardour/editor_mouse.cc:4797
 msgid "Name for region:"
 msgstr "Name für Region:"
 
-#: gtk2_ardour/editor_mouse.cc:4794
+#: gtk2_ardour/editor_mouse.cc:4861
 #, fuzzy
 msgid "timestretch"
 msgstr "Ardour: Mixer"
@@ -4012,7 +3997,7 @@ msgid "this region"
 msgstr "Name für Region:"
 
 #: gtk2_ardour/editor_ops.cc:180
-#: gtk2_ardour/editor_ops.cc:3293
+#: gtk2_ardour/editor_ops.cc:3444
 #: gtk2_ardour/route_ui.cc:736
 #: gtk2_ardour/visual_time_axis.cc:283
 msgid "No, do nothing."
@@ -4024,7 +4009,7 @@ msgid "Yes, destroy them."
 msgstr "Ja, entfernen."
 
 #: gtk2_ardour/editor_ops.cc:185
-#: gtk2_ardour/editor_ops.cc:3294
+#: gtk2_ardour/editor_ops.cc:3445
 #, fuzzy
 msgid "Yes, destroy it."
 msgstr "Ja, entfernen."
@@ -4046,216 +4031,206 @@ msgstr ""
 msgid "build_region_boundary_cache called with snap_type = %1"
 msgstr ""
 
-#: gtk2_ardour/editor_ops.cc:1350
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:1413
 msgid "select all within"
-msgstr "Auswahl"
+msgstr "Alle im Bereich auswählen"
 
-#: gtk2_ardour/editor_ops.cc:1383
+#: gtk2_ardour/editor_ops.cc:1443
 #, fuzzy
 msgid "set selection from region"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#: gtk2_ardour/editor_ops.cc:1416
+#: gtk2_ardour/editor_ops.cc:1476
 #, fuzzy
 msgid "set selection from range"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#: gtk2_ardour/editor_ops.cc:1446
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:1506
 msgid "select all from range"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr "Alle im Bereich auswählen"
 
-#: gtk2_ardour/editor_ops.cc:1468
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:1528
 msgid "select all from punch"
-msgstr "Auswahl"
+msgstr "Alle im Punch-Bereich auswählen"
 
-#: gtk2_ardour/editor_ops.cc:1490
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:1550
 msgid "select all from loop"
-msgstr "Auswahl"
+msgstr "Alle im Loop-Bereich auswählen"
 
-#: gtk2_ardour/editor_ops.cc:1504
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:1564
 msgid "select all after cursor"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Alle nach Positionszeiger auswählen"
 
-#: gtk2_ardour/editor_ops.cc:1509
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:1569
 msgid "select all before cursor"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Alle vor Positionszeiger auswählen"
 
-#: gtk2_ardour/editor_ops.cc:1539
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:1599
 msgid "select all between cursors"
-msgstr "Wiedergabe ab Cursor"
+msgstr "Alle zwischen den Zeigern auswählen"
 
-#: gtk2_ardour/editor_ops.cc:1670
+#: gtk2_ardour/editor_ops.cc:1732
 msgid "clear markers"
 msgstr ""
 
-#: gtk2_ardour/editor_ops.cc:1683
+#: gtk2_ardour/editor_ops.cc:1745
 msgid "clear ranges"
 msgstr "Verbindungen entfernen"
 
-#: gtk2_ardour/editor_ops.cc:1703
+#: gtk2_ardour/editor_ops.cc:1765
 msgid "clear locations"
 msgstr "Verbindungen entfernen"
 
-#: gtk2_ardour/editor_ops.cc:1754
+#: gtk2_ardour/editor_ops.cc:1840
 #, fuzzy
 msgid "insert dragged region"
 msgstr "Ardour: Region"
 
-#: gtk2_ardour/editor_ops.cc:1797
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:1887
 msgid "insert region"
-msgstr "Name für Region:"
+msgstr "Region einfügen"
 
-#: gtk2_ardour/editor_ops.cc:1972
+#: gtk2_ardour/editor_ops.cc:2062
 #: gtk2_ardour/io_selector.cc:60
-#: gtk2_ardour/io_selector.cc:749
+#: gtk2_ardour/io_selector.cc:748
 #: gtk2_ardour/connection_editor.cc:86
 msgid "OK"
 msgstr ""
 
-#: gtk2_ardour/editor_ops.cc:1979
+#: gtk2_ardour/editor_ops.cc:2069
 msgid "ardour: rename region"
-msgstr "Ardour: Region umbenennen"
+msgstr "ardour: Region umbenennen"
 
-#: gtk2_ardour/editor_ops.cc:2204
-#: gtk2_ardour/editor_ops.cc:2257
+#: gtk2_ardour/editor_ops.cc:2298
+#: gtk2_ardour/editor_ops.cc:2351
 #, fuzzy
 msgid "separate"
 msgstr "Ausgewählten Bereich wiedergeben"
 
-#: gtk2_ardour/editor_ops.cc:2322
+#: gtk2_ardour/editor_ops.cc:2418
 #, fuzzy
 msgid "trim to selection"
 msgstr "Auswahl zu Abschnitt machen"
 
-#: gtk2_ardour/editor_ops.cc:2363
+#: gtk2_ardour/editor_ops.cc:2459
 msgid "region fill"
 msgstr ""
 
-#: gtk2_ardour/editor_ops.cc:2427
+#: gtk2_ardour/editor_ops.cc:2523
 #, fuzzy
 msgid "fill selection"
 msgstr "Auswahl zu Schleife machen"
 
-#: gtk2_ardour/editor_ops.cc:2448
+#: gtk2_ardour/editor_ops.cc:2544
 msgid "Programming error. that region doesn't cover that position"
 msgstr ""
 
-#: gtk2_ardour/editor_ops.cc:2451
+#: gtk2_ardour/editor_ops.cc:2547
 #, fuzzy
 msgid "set region sync position"
 msgstr "Regionen"
 
-#: gtk2_ardour/editor_ops.cc:2467
+#: gtk2_ardour/editor_ops.cc:2563
 msgid "Place the edit cursor at the desired sync point"
 msgstr "Positionieren sie den Arbeits-Cursor am gewünschten Synchronisationspunkt"
 
-#: gtk2_ardour/editor_ops.cc:2472
+#: gtk2_ardour/editor_ops.cc:2568
 #, fuzzy
 msgid "set sync from edit cursor"
 msgstr "Wiedergabe ab Cursor"
 
-#: gtk2_ardour/editor_ops.cc:2485
+#: gtk2_ardour/editor_ops.cc:2581
 #, fuzzy
 msgid "remove sync"
 msgstr "Synchronisationspunkt entfernen"
 
-#: gtk2_ardour/editor_ops.cc:2500
+#: gtk2_ardour/editor_ops.cc:2596
 #, fuzzy
 msgid "naturalize"
 msgstr "Ardour: Region"
 
-#: gtk2_ardour/editor_ops.cc:2565
+#: gtk2_ardour/editor_ops.cc:2661
 msgid "align selection (relative)"
 msgstr ""
 
-#: gtk2_ardour/editor_ops.cc:2594
+#: gtk2_ardour/editor_ops.cc:2690
 #, fuzzy
 msgid "align selection"
 msgstr "Auswahl zu Schleife machen"
 
-#: gtk2_ardour/editor_ops.cc:2606
+#: gtk2_ardour/editor_ops.cc:2702
 #, fuzzy
 msgid "align region"
 msgstr "Ardour: Region"
 
-#: gtk2_ardour/editor_ops.cc:2654
-#: gtk2_ardour/editor_ops.cc:2680
+#: gtk2_ardour/editor_ops.cc:2750
+#: gtk2_ardour/editor_ops.cc:2776
 msgid "trim to edit"
 msgstr ""
 
-#: gtk2_ardour/editor_ops.cc:2732
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:2828
 msgid "ardour: freeze"
-msgstr "Ardour: "
+msgstr "ardour: Einfrieren"
 
-#: gtk2_ardour/editor_ops.cc:2737
+#: gtk2_ardour/editor_ops.cc:2833
 msgid "Cancel Freeze"
 msgstr "Einfrieren abbrechen"
 
-#: gtk2_ardour/editor_ops.cc:2774
+#: gtk2_ardour/editor_ops.cc:2876
 #, fuzzy
 msgid "bounce range"
 msgstr "Bereich"
 
-#: gtk2_ardour/editor_ops.cc:2828
+#: gtk2_ardour/editor_ops.cc:2930
 #, fuzzy
 msgid "cut"
 msgstr "Ausschneiden"
 
-#: gtk2_ardour/editor_ops.cc:2831
+#: gtk2_ardour/editor_ops.cc:2933
 #, fuzzy
 msgid "copy"
 msgstr "Kopieren"
 
-#: gtk2_ardour/editor_ops.cc:2844
+#: gtk2_ardour/editor_ops.cc:2946
 #, fuzzy
 msgid " objects"
 msgstr "Objekt"
 
-#: gtk2_ardour/editor_ops.cc:2870
+#: gtk2_ardour/editor_ops.cc:2972
 #, fuzzy
 msgid " range"
 msgstr "Bereich"
 
-#: gtk2_ardour/editor_ops.cc:3050
+#: gtk2_ardour/editor_ops.cc:3197
 #, fuzzy
 msgid "paste"
 msgstr "Einfügen"
 
-#: gtk2_ardour/editor_ops.cc:3088
-#, fuzzy
+#: gtk2_ardour/editor_ops.cc:3239
 msgid "paste chunk"
-msgstr "Abschnitt erzeugen:"
+msgstr "Abschnitt einfügen"
 
-#: gtk2_ardour/editor_ops.cc:3129
+#: gtk2_ardour/editor_ops.cc:3282
 #, fuzzy
 msgid "duplicate region"
 msgstr "Auswahl zu Schleife machen"
 
-#: gtk2_ardour/editor_ops.cc:3174
+#: gtk2_ardour/editor_ops.cc:3327
 #, fuzzy
 msgid "duplicate selection"
 msgstr "Auswahl zu Schleife machen"
 
-#: gtk2_ardour/editor_ops.cc:3232
+#: gtk2_ardour/editor_ops.cc:3383
 #, fuzzy
 msgid "clear playlist"
 msgstr "Name für Schnappschuß"
 
-#: gtk2_ardour/editor_ops.cc:3262
+#: gtk2_ardour/editor_ops.cc:3413
 #, fuzzy
 msgid "nudge track"
 msgstr "Stille einfügen"
 
-#: gtk2_ardour/editor_ops.cc:3290
+#: gtk2_ardour/editor_ops.cc:3441
 #, fuzzy
 msgid ""
 "Do you really want to destroy the last capture?\n"
@@ -4264,28 +4239,44 @@ msgstr ""
 "Wollen Sie wirklich die Spur \"%1\" löschen?\n"
 "(Kann nicht rückgängig gemacht werden!)"
 
-#: gtk2_ardour/editor_ops.cc:3318
+#: gtk2_ardour/editor_ops.cc:3469
 #, fuzzy
 msgid "normalize"
 msgstr "Ardour: Region"
 
-#: gtk2_ardour/editor_ops.cc:3371
+#: gtk2_ardour/editor_ops.cc:3522
 #, fuzzy
 msgid "reverse regions"
 msgstr "Name für Region:"
 
-#: gtk2_ardour/editor_ops.cc:3484
+#: gtk2_ardour/editor_ops.cc:3635
 #, fuzzy
 msgid "reset region gain"
 msgstr "Name für Region:"
 
-#: gtk2_ardour/editor_region_list.cc:103
-#: gtk2_ardour/editor_region_list.cc:108
-#: gtk2_ardour/editor_region_list.cc:111
-#: gtk2_ardour/location_ui.cc:57
+#: gtk2_ardour/editor_ops.cc:3724
+msgid "set fade in shape"
+msgstr ""
+
+#: gtk2_ardour/editor_ops.cc:3748
 #, fuzzy
+msgid "set fade out shape"
+msgstr "Ardour: Editor"
+
+#: gtk2_ardour/editor_ops.cc:3772
+msgid "set fade in active"
+msgstr ""
+
+#: gtk2_ardour/editor_ops.cc:3796
+msgid "set fade out active"
+msgstr ""
+
+#: gtk2_ardour/editor_region_list.cc:104
+#: gtk2_ardour/editor_region_list.cc:110
+#: gtk2_ardour/editor_region_list.cc:113
+#: gtk2_ardour/location_ui.cc:57
 msgid "Hidden"
-msgstr "Verbergen"
+msgstr "Versteckt"
 
 #: gtk2_ardour/editor_route_list.cc:100
 #: gtk2_ardour/editor_route_list.cc:101
@@ -4294,32 +4285,32 @@ msgid "editor"
 msgstr ""
 
 #: gtk2_ardour/editor_route_list.cc:317
-#: gtk2_ardour/mixer_ui.cc:717
+#: gtk2_ardour/mixer_ui.cc:714
 msgid "Show All"
 msgstr "Alles zeigen"
 
 #: gtk2_ardour/editor_route_list.cc:318
-#: gtk2_ardour/mixer_ui.cc:718
+#: gtk2_ardour/mixer_ui.cc:715
 msgid "Hide All"
 msgstr "Alle verbergen"
 
 #: gtk2_ardour/editor_route_list.cc:319
-#: gtk2_ardour/mixer_ui.cc:719
+#: gtk2_ardour/mixer_ui.cc:716
 msgid "Show All Audio Tracks"
 msgstr "Zeige alle Audio-Spuren"
 
 #: gtk2_ardour/editor_route_list.cc:320
-#: gtk2_ardour/mixer_ui.cc:720
+#: gtk2_ardour/mixer_ui.cc:717
 msgid "Hide All Audio Tracks"
 msgstr "Verberge alle Audio-Spuren"
 
 #: gtk2_ardour/editor_route_list.cc:321
-#: gtk2_ardour/mixer_ui.cc:721
+#: gtk2_ardour/mixer_ui.cc:718
 msgid "Show All Audio Busses"
 msgstr "Zeige alle Audio-Busse"
 
 #: gtk2_ardour/editor_route_list.cc:322
-#: gtk2_ardour/mixer_ui.cc:722
+#: gtk2_ardour/mixer_ui.cc:719
 msgid "Hide All Audio Busses"
 msgstr "Verberge alle Audio-Busse"
 
@@ -4331,45 +4322,57 @@ msgstr "Neuer Positionsmarker"
 msgid "Clear all locations"
 msgstr "Alle Positionsmarker entfernen"
 
-#: gtk2_ardour/editor_rulers.cc:344
+#: gtk2_ardour/editor_rulers.cc:340
+#, fuzzy
+msgid "Unhide locations"
+msgstr "Verbindungen entfernen"
+
+#: gtk2_ardour/editor_rulers.cc:345
 msgid "Clear all ranges"
 msgstr "Alle Bereiche entfernen"
 
-#: gtk2_ardour/editor_rulers.cc:353
+#: gtk2_ardour/editor_rulers.cc:346
+#, fuzzy
+msgid "Unhide ranges"
+msgstr "Bereich verbergen"
+
+#: gtk2_ardour/editor_rulers.cc:355
 msgid "New Tempo"
 msgstr "Tempowechsel einfügen..."
 
-#: gtk2_ardour/editor_rulers.cc:354
+#: gtk2_ardour/editor_rulers.cc:356
 msgid "Clear tempo"
 msgstr "Tempo zurücksetzen"
 
-#: gtk2_ardour/editor_rulers.cc:359
+#: gtk2_ardour/editor_rulers.cc:361
 msgid "New Meter"
 msgstr "Taktwechsel einfügen..."
 
-#: gtk2_ardour/editor_rulers.cc:360
+#: gtk2_ardour/editor_rulers.cc:362
 msgid "Clear meter"
 msgstr "Taktart zurücksetzen"
 
-#: gtk2_ardour/editor_rulers.cc:368
+#: gtk2_ardour/editor_rulers.cc:370
 #, fuzzy
 msgid "Min:Secs"
 msgstr "Min:Sek"
 
-#: gtk2_ardour/editor_selection_list.cc:108
-#, fuzzy
+#: gtk2_ardour/editor_selection_list.cc:180
 msgid "Name for Chunk:"
 msgstr "Name für Abschnitt:"
 
-#: gtk2_ardour/editor_selection_list.cc:111
-#, fuzzy
+#: gtk2_ardour/editor_selection_list.cc:183
 msgid "Create Chunk"
-msgstr "Abschnitt erzeugen:"
+msgstr "Abschnitt erzeugen"
 
-#: gtk2_ardour/editor_selection_list.cc:111
+#: gtk2_ardour/editor_selection_list.cc:183
 msgid "Forget it"
 msgstr "Abbrechen"
 
+#: gtk2_ardour/editor_selection_list.cc:206
+msgid "No selectable material found in the currently selected time range"
+msgstr ""
+
 #: gtk2_ardour/editor_tempodisplay.cc:272
 #: gtk2_ardour/editor_tempodisplay.cc:315
 #, fuzzy
@@ -4416,9 +4419,8 @@ msgid "Skip Anti-aliasing"
 msgstr ""
 
 #: gtk2_ardour/editor_timefx.cc:57
-#, fuzzy
 msgid "ardour: timestretch"
-msgstr "Ardour: Mixer"
+msgstr "ardour: Time-Stretch"
 
 #: gtk2_ardour/editor_timefx.cc:58
 msgid "TimeStretchDialog"
@@ -4522,10 +4524,6 @@ msgstr ""
 msgid "Triangular"
 msgstr "dreieckig"
 
-#: gtk2_ardour/export_dialog.cc:84
-msgid "stereo"
-msgstr ""
-
 #: gtk2_ardour/export_dialog.cc:85
 #: gtk2_ardour/export_dialog.cc:484
 #: gtk2_ardour/export_dialog.cc:1053
@@ -4586,8 +4584,8 @@ msgid "Export to File"
 msgstr "Als Audiodatei exportieren"
 
 #: gtk2_ardour/export_dialog.cc:111
-#: gtk2_ardour/option_editor.cc:82
-#: gtk2_ardour/option_editor.cc:83
+#: gtk2_ardour/option_editor.cc:80
+#: gtk2_ardour/option_editor.cc:81
 msgid "Browse"
 msgstr "Durchsuchen"
 
@@ -4597,12 +4595,7 @@ msgstr "Alle Spuren..."
 
 #: gtk2_ardour/export_dialog.cc:123
 msgid "ardour: export"
-msgstr "Ardour: Exportieren"
-
-#: gtk2_ardour/export_dialog.cc:124
-#, fuzzy
-msgid "ardour_export"
-msgstr "Ardour: Exportieren"
+msgstr "ardour: Exportieren"
 
 #: gtk2_ardour/export_dialog.cc:137
 #: gtk2_ardour/export_dialog.cc:153
@@ -4612,14 +4605,12 @@ msgid "Output"
 msgstr "Ausgang"
 
 #: gtk2_ardour/export_dialog.cc:631
-#, fuzzy
 msgid "Editor: cannot open \"%1\" as export file for CD toc file"
-msgstr "Editor: Kann \"%1\" nicht Ã¶ffnen um CD Track Markierungen zu exportieren."
+msgstr "Editor: Kann \"%1\" nicht nicht zum Export für CD-Inhaltsverzeichnis (TOC) Ã¶ffnen."
 
 #: gtk2_ardour/export_dialog.cc:757
-#, fuzzy
 msgid "Editor: cannot open \"%1\" as export file for CD cue file"
-msgstr "Editor: Kann \"%1\" nicht Ã¶ffnen um CD Track Markierungen zu exportieren."
+msgstr "Editor: Kann \"%1\" nicht zum Export für CD CUE-Datei Ã¶ffnen."
 
 #: gtk2_ardour/export_dialog.cc:776
 msgid "WAV"
@@ -4663,52 +4654,58 @@ msgstr ""
 msgid "add gain automation event"
 msgstr "Stellen"
 
-#: gtk2_ardour/gain_meter.cc:112
-#: gtk2_ardour/gain_meter.cc:328
-#: gtk2_ardour/gain_meter.cc:504
-#: gtk2_ardour/gain_meter.cc:571
+#: gtk2_ardour/gain_meter.cc:113
+#: gtk2_ardour/gain_meter.cc:331
+#: gtk2_ardour/gain_meter.cc:512
+#: gtk2_ardour/gain_meter.cc:583
 msgid "-inf"
 msgstr ""
 
-#: gtk2_ardour/gain_meter.cc:123
+#: gtk2_ardour/gain_meter.cc:124
 msgid "Fader automation mode"
 msgstr "Fader Automationsmodus"
 
-#: gtk2_ardour/gain_meter.cc:124
+#: gtk2_ardour/gain_meter.cc:125
 #, fuzzy
 msgid "Fader automation type"
 msgstr "Stellen"
 
-#: gtk2_ardour/gain_meter.cc:169
-#: gtk2_ardour/gain_meter.cc:852
-#: gtk2_ardour/panner_ui.cc:97
-#: gtk2_ardour/panner_ui.cc:797
+#: gtk2_ardour/gain_meter.cc:170
+#: gtk2_ardour/gain_meter.cc:877
+#: gtk2_ardour/panner_ui.cc:99
+#: gtk2_ardour/panner_ui.cc:810
 msgid "Abs"
 msgstr ""
 
-#: gtk2_ardour/gain_meter.cc:482
+#: gtk2_ardour/gain_meter.cc:490
 msgid "-Inf"
 msgstr ""
 
-#: gtk2_ardour/gain_meter.cc:816
+#: gtk2_ardour/gain_meter.cc:693
+#: gtk2_ardour/gain_meter.cc:708
+#, fuzzy
+msgid "meter point change"
+msgstr "Bereich"
+
+#: gtk2_ardour/gain_meter.cc:841
 #: gtk2_ardour/mixer_strip.cc:749
-#: gtk2_ardour/panner_ui.cc:761
+#: gtk2_ardour/panner_ui.cc:774
 #, fuzzy
 msgid "O"
 msgstr "ODER"
 
-#: gtk2_ardour/gain_meter.cc:819
-#: gtk2_ardour/panner_ui.cc:764
+#: gtk2_ardour/gain_meter.cc:844
+#: gtk2_ardour/panner_ui.cc:777
 msgid "P"
 msgstr ""
 
-#: gtk2_ardour/gain_meter.cc:822
-#: gtk2_ardour/panner_ui.cc:767
+#: gtk2_ardour/gain_meter.cc:847
+#: gtk2_ardour/panner_ui.cc:780
 msgid "T"
 msgstr ""
 
-#: gtk2_ardour/gain_meter.cc:825
-#: gtk2_ardour/panner_ui.cc:770
+#: gtk2_ardour/gain_meter.cc:850
+#: gtk2_ardour/panner_ui.cc:783
 msgid "W"
 msgstr ""
 
@@ -4817,10 +4814,9 @@ msgid "Rename Track"
 msgstr "Umbenennen"
 
 #: gtk2_ardour/io_selector.cc:62
-#: gtk2_ardour/io_selector.cc:751
+#: gtk2_ardour/io_selector.cc:750
 #: gtk2_ardour/connection_editor.cc:61
 #: gtk2_ardour/connection_editor.cc:110
-#, fuzzy
 msgid "Rescan"
 msgstr "Auffrischen"
 
@@ -4834,7 +4830,6 @@ msgstr "%1 Ausgang"
 
 #: gtk2_ardour/io_selector.cc:144
 #: gtk2_ardour/route_params_ui.cc:103
-#, fuzzy
 msgid "Inputs"
 msgstr "Eingänge"
 
@@ -4867,14 +4862,14 @@ msgstr "Alle trennen"
 msgid "Available connections"
 msgstr "Verfügbare Verbindungen"
 
-#: gtk2_ardour/io_selector.cc:550
-#: gtk2_ardour/io_selector.cc:561
+#: gtk2_ardour/io_selector.cc:549
+#: gtk2_ardour/io_selector.cc:560
 msgid "There are no more JACK ports available."
 msgstr "Es sind keine weiteren JACK Ports verfügbar."
 
-#: gtk2_ardour/io_selector.cc:755
+#: gtk2_ardour/io_selector.cc:754
 msgid "ardour: "
-msgstr "Ardour: "
+msgstr "ardour: "
 
 #: gtk2_ardour/keyboard.cc:299
 msgid "KeyboardTarget: keyname \"%1\" is unknown."
@@ -4886,7 +4881,7 @@ msgstr "Ihr System ist falsch konfiguriert. Die NumLock-Taste nutzt \"%1\" als M
 
 #: gtk2_ardour/keyboard.cc:533
 msgid "Your system generates \"%1\" when the NumLock key is pressed. This can cause problems when editing so Ardour will use %2 to mean Meta rather than %1"
-msgstr "Ihr System generiert \"%1\" wenn NumLock gedrückt wird. Dies kann zu Problemen führen. Ardour wird deshalb als Meta-Taste %2 an Stelle von %1 benutzen."
+msgstr "Ihr System generiert \"%1\" wenn NumLock gedrückt wird. Dies kann zu Problemen führen. ardour wird deshalb als Meta-Taste %2 an Stelle von %1 benutzen."
 
 #: gtk2_ardour/keyboard.cc:594
 msgid "You have %1 keys bound to \"mod1\""
@@ -4945,9 +4940,8 @@ msgid "Pre-Emphasis"
 msgstr ""
 
 #: gtk2_ardour/location_ui.cc:571
-#, fuzzy
 msgid "Add New Location"
-msgstr "Stellen"
+msgstr "Neue Position hinzufügen"
 
 #: gtk2_ardour/location_ui.cc:572
 msgid "Add New Range"
@@ -4955,65 +4949,55 @@ msgstr "Neuen Bereich hinzufügen"
 
 #: gtk2_ardour/location_ui.cc:576
 msgid "ardour: locations"
-msgstr ""
-
-#: gtk2_ardour/location_ui.cc:577
-#, fuzzy
-msgid "ardour_locations"
-msgstr "Ardour: Verbindungen"
+msgstr "ardour: Positionen"
 
 #: gtk2_ardour/location_ui.cc:605
-#, fuzzy
 msgid "Location (CD Index) Markers"
-msgstr "Stellen"
+msgstr "Positionsmarker (CD Index)"
 
 #: gtk2_ardour/location_ui.cc:625
 msgid "Range (CD Track) Markers"
-msgstr ""
+msgstr "Bereiche (CD Tracks)"
 
-#: gtk2_ardour/location_ui.cc:793
+#: gtk2_ardour/location_ui.cc:798
 #, fuzzy
 msgid "add range marker"
 msgstr "Ardour: Region umbenennen"
 
-#: gtk2_ardour/main.cc:73
+#: gtk2_ardour/main.cc:74
 msgid "ardour is killing itself for a clean exit\n"
 msgstr ""
 
-#: gtk2_ardour/main.cc:82
-msgid "stopping user interface\n"
-msgstr "Stoppe Benutzeroberfläche\n"
-
-#: gtk2_ardour/main.cc:101
+#: gtk2_ardour/main.cc:100
 #, c-format
 msgid "%d(%d): received signal %d\n"
 msgstr ""
 
-#: gtk2_ardour/main.cc:181
+#: gtk2_ardour/main.cc:180
 msgid "cannot become new process group leader (%1)"
 msgstr ""
 
-#: gtk2_ardour/main.cc:208
+#: gtk2_ardour/main.cc:207
 msgid "cannot setup signal handling for %1"
 msgstr ""
 
-#: gtk2_ardour/main.cc:219
+#: gtk2_ardour/main.cc:218
 msgid "cannot set default signal mask (%1)"
 msgstr ""
 
-#: gtk2_ardour/main.cc:249
+#: gtk2_ardour/main.cc:248
 msgid ""
 "Without a UI style file, ardour will look strange.\n"
 " Please set ARDOUR2_UI_RC to point to a valid UI style file"
 msgstr ""
-"Ohne UI-Definitionsdatei wird Ardour merkwürdig aussehen.\n"
+"Ohne UI-Definitionsdatei wird ardour merkwürdig aussehen.\n"
 " Bitte setzen Sie ARDOUR_UI_RC auf eine gültige UI-Definitionsdatei"
 
-#: gtk2_ardour/main.cc:270
+#: gtk2_ardour/main.cc:269
 msgid "Ardour could not connect to JACK."
-msgstr "Ardour konnte nicht zu JACK verbinden."
+msgstr "ardour konnte nicht zu JACK verbinden."
 
-#: gtk2_ardour/main.cc:274
+#: gtk2_ardour/main.cc:273
 msgid ""
 "There are several possible reasons:\n"
 "\n"
@@ -5031,11 +5015,11 @@ msgstr ""
 "\n"
 "Betrachten Sie bitte diese Möglichkeiten und starten Sie JACK neu, wenn dies notwendig sein sollte."
 
-#: gtk2_ardour/main.cc:316
+#: gtk2_ardour/main.cc:315
 msgid "could not load command line session \"%1\""
-msgstr "Konnte die per Kommandozeile Ã¼bergebene Sitzung nicht laden: \"%1\""
+msgstr "Konnte das per Kommandozeile Ã¼bergebene Projekt nicht laden: \"%1\""
 
-#: gtk2_ardour/main.cc:324
+#: gtk2_ardour/main.cc:323
 msgid ""
 "\n"
 "\n"
@@ -5044,59 +5028,58 @@ msgid ""
 msgstr ""
 "\n"
 "\n"
-"Es existiert keine Sitzung mit dem namen \"%1\".\n"
-"Um sie von der Kommandozeile aus zu erstellen, starten Sie Ardour mit \"ardour --new %1"
+"Es existiert kein Projekt mit dem Namen \"%1\".\n"
+"Um sie von der Kommandozeile aus zu erstellen, starten Sie ardour mit \"ardour --new %1"
 
-#: gtk2_ardour/main.cc:385
+#: gtk2_ardour/main.cc:390
 msgid "Ardour/GTK "
 msgstr ""
 
-#: gtk2_ardour/main.cc:387
+#: gtk2_ardour/main.cc:392
 msgid ""
 "\n"
 "   (built using "
 msgstr ""
 
-#: gtk2_ardour/main.cc:390
+#: gtk2_ardour/main.cc:395
 msgid " and GCC version "
 msgstr ""
 
-#: gtk2_ardour/main.cc:400
+#: gtk2_ardour/main.cc:405
 msgid "Copyright (C) 1999-2006 Paul Davis"
 msgstr ""
 
-#: gtk2_ardour/main.cc:401
+#: gtk2_ardour/main.cc:406
 msgid "Some portions Copyright (C) Steve Harris, Ari Johnson, Brett Viren, Joel Baker"
 msgstr ""
 
-#: gtk2_ardour/main.cc:403
+#: gtk2_ardour/main.cc:408
 msgid "Ardour comes with ABSOLUTELY NO WARRANTY"
-msgstr "Achtung: Es gibt zu Ardour KEINERLEI Gewährleistung!"
+msgstr ""
 
-#: gtk2_ardour/main.cc:404
+#: gtk2_ardour/main.cc:409
 msgid "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
 msgstr ""
 
-#: gtk2_ardour/main.cc:405
+#: gtk2_ardour/main.cc:410
 msgid "This is free software, and you are welcome to redistribute it "
 msgstr "Dies ist freie Software und Sie dürfen sie gerne weiterverbreiten,"
 
-#: gtk2_ardour/main.cc:406
-#, fuzzy
+#: gtk2_ardour/main.cc:411
 msgid "under certain conditions; see the source for copying conditions."
-msgstr "solange Sie sich an die Spielregeln aus der Datei COPYING halten."
+msgstr "solange Sie sich an die Bedingungen, die in der Datei COPYING aufgeführt sind halten."
 
-#: gtk2_ardour/main.cc:416
+#: gtk2_ardour/main.cc:418
 msgid "could not create ARDOUR GUI"
 msgstr ""
 
-#: gtk2_ardour/main.cc:433
+#: gtk2_ardour/main.cc:442
 msgid "Could not connect to JACK server as  \"%1\""
 msgstr "Konnte nicht zu JACK Server als \"%1\" verbinden"
 
-#: gtk2_ardour/main.cc:443
+#: gtk2_ardour/main.cc:449
 msgid "could not initialize Ardour."
-msgstr "Konnte Ardour nicht initialisieren."
+msgstr "Konnte ardour nicht initialisieren."
 
 #: gtk2_ardour/marker.cc:244
 #, fuzzy
@@ -5193,7 +5176,7 @@ msgstr ""
 
 #: gtk2_ardour/mixer_strip.cc:503
 #: gtk2_ardour/mixer_strip.cc:569
-#: gtk2_ardour/redirect_box.cc:1012
+#: gtk2_ardour/redirect_box.cc:1086
 msgid "Not connected to JACK - no I/O changes are possible"
 msgstr "Nicht mit Jack verbunden - es sind keine Ã„nderungen an Ein-/Ausgängen möglich"
 
@@ -5216,9 +5199,8 @@ msgid "*Comments*"
 msgstr ""
 
 #: gtk2_ardour/mixer_strip.cc:848
-#, fuzzy
 msgid ": comment editor"
-msgstr "Der Editor konnte nicht initialisiert werden."
+msgstr "Kommentare bearbeiten"
 
 #: gtk2_ardour/mixer_strip.cc:943
 msgid "Grp"
@@ -5240,25 +5222,20 @@ msgstr "Spur"
 msgid "Group"
 msgstr "Gruppe"
 
-#: gtk2_ardour/mixer_ui.cc:209
-#: gtk2_ardour/mixer_ui.cc:389
+#: gtk2_ardour/mixer_ui.cc:206
+#: gtk2_ardour/mixer_ui.cc:386
 msgid "ardour: mixer"
-msgstr "Ardour: Mixer"
+msgstr "ardour: Mixer"
 
-#: gtk2_ardour/mixer_ui.cc:210
-#, fuzzy
-msgid "ardour_mixer"
-msgstr "Ardour: Mixer"
-
-#: gtk2_ardour/mixer_ui.cc:361
+#: gtk2_ardour/mixer_ui.cc:358
 msgid "ardour: mixer: "
-msgstr "Ardour: Mixer: "
+msgstr "ardour: Mixer: "
 
-#: gtk2_ardour/mixer_ui.cc:592
+#: gtk2_ardour/mixer_ui.cc:589
 msgid "signal"
 msgstr "Signal"
 
-#: gtk2_ardour/mixer_ui.cc:741
+#: gtk2_ardour/mixer_ui.cc:738
 msgid "track display list item for renamed strip not found!"
 msgstr ""
 
@@ -5271,7 +5248,6 @@ msgstr "Umbenennen"
 #: gtk2_ardour/new_session_dialog.cc:46
 #: gtk2_ardour/new_session_dialog.cc:47
 #: gtk2_ardour/new_session_dialog.cc:48
-#: gtk2_ardour/sfdb_ui.cc:172
 msgid "channels"
 msgstr "Kanäle"
 
@@ -5338,194 +5314,187 @@ msgstr "Durchsuchen:"
 
 #: gtk2_ardour/new_session_dialog.cc:335
 msgid "New Session"
-msgstr "Neue Sitzung"
+msgstr "Neues Projekt"
 
 #: gtk2_ardour/new_session_dialog.cc:337
 msgid "Open Session"
-msgstr "Sitzung Ã¶ffnen"
+msgstr "Projekt Ã¶ffnen"
 
 #: gtk2_ardour/new_session_dialog.cc:342
 msgid "ardour: session control"
-msgstr "Ardour: Neue Sitzung"
+msgstr "ardour: Neues Projekt"
 
-#: gtk2_ardour/new_session_dialog.cc:371
+#: gtk2_ardour/new_session_dialog.cc:383
 msgid "select template"
 msgstr "Vorlage auswählen"
 
-#: gtk2_ardour/new_session_dialog.cc:377
-#, fuzzy
+#: gtk2_ardour/new_session_dialog.cc:389
 msgid "select session file"
-msgstr "Auswahl zu Schleife machen"
+msgstr "Projektdatei auswählen"
 
-#: gtk2_ardour/new_session_dialog.cc:386
+#: gtk2_ardour/new_session_dialog.cc:398
 #, fuzzy
 msgid "select directory"
 msgstr "Auswahl zu Schleife machen"
 
-#: gtk2_ardour/option_editor.cc:75
+#: gtk2_ardour/option_editor.cc:73
 msgid "SMPTE offset is negative"
 msgstr "Negatives SMPTE-Offset"
 
-#: gtk2_ardour/option_editor.cc:101
-#, fuzzy
+#: gtk2_ardour/option_editor.cc:99
 msgid "ardour: options editor"
-msgstr "Ardour: Einstellungen"
-
-#: gtk2_ardour/option_editor.cc:102
-#, fuzzy
-msgid "ardour_option_editor"
-msgstr "Ardour: Einstellungen"
+msgstr "ardour: Einstellungen"
 
-#: gtk2_ardour/option_editor.cc:126
+#: gtk2_ardour/option_editor.cc:124
 msgid "Paths/Files"
 msgstr "Pfade"
 
-#: gtk2_ardour/option_editor.cc:127
+#: gtk2_ardour/option_editor.cc:125
 msgid "Kbd/Mouse"
 msgstr "Tastatur/Maus"
 
-#: gtk2_ardour/option_editor.cc:130
+#: gtk2_ardour/option_editor.cc:128
 msgid "Layers & Fades"
 msgstr "Layer & Fades"
 
-#: gtk2_ardour/option_editor.cc:134
+#: gtk2_ardour/option_editor.cc:132
 msgid "MIDI"
 msgstr "MIDI"
 
-#: gtk2_ardour/option_editor.cc:222
+#: gtk2_ardour/option_editor.cc:220
 msgid "session RAID path"
-msgstr "Sitzungsverzeichnis (RAID)"
+msgstr "Projektverzeichnis (RAID)"
 
-#: gtk2_ardour/option_editor.cc:227
-msgid "Soundfile Search Paths"
-msgstr "Suchpfade für Audiodateien"
-
-#: gtk2_ardour/option_editor.cc:252
-#: gtk2_ardour/option_editor.cc:258
-#: gtk2_ardour/option_editor.cc:670
-#: gtk2_ardour/option_editor.cc:697
+#: gtk2_ardour/option_editor.cc:236
+#: gtk2_ardour/option_editor.cc:242
+#: gtk2_ardour/option_editor.cc:652
+#: gtk2_ardour/option_editor.cc:672
 msgid "internal"
 msgstr "intern"
 
-#: gtk2_ardour/option_editor.cc:271
+#: gtk2_ardour/option_editor.cc:255
 msgid "Short crossfade length (msecs)"
 msgstr "Länge für kurze Crossfades (ms)"
 
-#: gtk2_ardour/option_editor.cc:283
+#: gtk2_ardour/option_editor.cc:267
 msgid "Destructive crossfade length (msecs)"
 msgstr "Länge für destruktive Crossfades (ms)"
 
-#: gtk2_ardour/option_editor.cc:343
+#: gtk2_ardour/option_editor.cc:327
 msgid "SMPTE Offset"
 msgstr "SMPTE Offset"
 
-#: gtk2_ardour/option_editor.cc:410
-#: gtk2_ardour/option_editor.cc:417
-#: gtk2_ardour/option_editor.cc:420
-#: gtk2_ardour/option_editor.cc:565
+#: gtk2_ardour/option_editor.cc:394
+#: gtk2_ardour/option_editor.cc:401
+#: gtk2_ardour/option_editor.cc:404
+#: gtk2_ardour/option_editor.cc:552
 #, fuzzy
 msgid "online"
 msgstr "Verbindungen"
 
-#: gtk2_ardour/option_editor.cc:417
-#: gtk2_ardour/option_editor.cc:418
-#: gtk2_ardour/option_editor.cc:562
+#: gtk2_ardour/option_editor.cc:401
+#: gtk2_ardour/option_editor.cc:402
+#: gtk2_ardour/option_editor.cc:549
 msgid "offline"
 msgstr ""
 
-#: gtk2_ardour/option_editor.cc:617
+#: gtk2_ardour/option_editor.cc:605
 msgid "Choose Click"
 msgstr ""
 
-#: gtk2_ardour/option_editor.cc:636
+#: gtk2_ardour/option_editor.cc:624
 msgid "Choose Click Emphasis"
 msgstr ""
 
-#: gtk2_ardour/option_editor.cc:750
+#: gtk2_ardour/option_editor.cc:724
 msgid "Click audio file"
 msgstr "Audiodatei für Click"
 
-#: gtk2_ardour/option_editor.cc:756
+#: gtk2_ardour/option_editor.cc:730
 msgid "Click emphasis audiofile"
 msgstr "Audiodatei für betonten Click "
 
-#: gtk2_ardour/option_editor.cc:793
+#: gtk2_ardour/option_editor.cc:767
 msgid ""
 "The auditioner is a dedicated mixer strip used\n"
 "for listening to specific regions outside the context\n"
 "of the overall mix. It can be connected just like any\n"
 "other mixer strip."
 msgstr ""
+"Der Vorhör-Bus ist ein spezieller Mixer-Kanal,\n"
+"mit dem ausgewählte Regionen unabhängig\n"
+"vom Gesamt-Mix abgehört werden können.\n"
+"Dieser Bus lässt sich wie jeder andere Mixer-Kanal\n"
+"verbinden."
 
-#: gtk2_ardour/option_editor.cc:866
+#: gtk2_ardour/option_editor.cc:840
 msgid "Edit using"
 msgstr "Bearbeiten mit"
 
-#: gtk2_ardour/option_editor.cc:873
-#: gtk2_ardour/option_editor.cc:900
+#: gtk2_ardour/option_editor.cc:847
+#: gtk2_ardour/option_editor.cc:874
 msgid "+ button"
 msgstr "und Maustaste"
 
-#: gtk2_ardour/option_editor.cc:893
+#: gtk2_ardour/option_editor.cc:867
 msgid "Delete using"
 msgstr "Entfernen mit"
 
-#: gtk2_ardour/option_editor.cc:920
+#: gtk2_ardour/option_editor.cc:894
 msgid "Ignore snap using"
 msgstr "Einrasten Ã¼bergehen mit"
 
-#: gtk2_ardour/opts.cc:46
+#: gtk2_ardour/opts.cc:47
 msgid "Usage: "
 msgstr "Aufruf:"
 
-#: gtk2_ardour/opts.cc:47
+#: gtk2_ardour/opts.cc:48
 msgid "  -v, --version                    Show version information\n"
 msgstr "  -v, --version                    Versionsinformation ausgeben\n"
 
-#: gtk2_ardour/opts.cc:48
+#: gtk2_ardour/opts.cc:49
 msgid "  -h, --help                       Print this message\n"
 msgstr "  -h, --help                       Diese Hinweise\n"
 
-#: gtk2_ardour/opts.cc:49
+#: gtk2_ardour/opts.cc:50
 msgid "  -b, --bindings                   Print all possible keyboard binding names\n"
 msgstr "  -b, --bindings                   Alle möglichen Tastenzuweisungsnamen ausgeben\n"
 
-#: gtk2_ardour/opts.cc:50
+#: gtk2_ardour/opts.cc:51
 #, fuzzy
 msgid "  -n, --show-splash                Show splash screen\n"
 msgstr "  -h, --help                       Diese Hinweise\n"
 
-#: gtk2_ardour/opts.cc:51
+#: gtk2_ardour/opts.cc:52
 #, fuzzy
 msgid "  -c, --name  name                 Use a specific jack client name, default is ardour\n"
 msgstr "  -U, --ui-rcfile=FILENAME         Dateiname für UI Einstellungen\n"
 
-#: gtk2_ardour/opts.cc:52
+#: gtk2_ardour/opts.cc:53
 #, fuzzy
 msgid "  -N, --new session-name           Create a new session from the command line\n"
-msgstr "  [session-name]                   Name der zu ladenden Sitzung\n"
+msgstr "  [session-name]                   Name des zu ladenden Projekts\n"
 
-#: gtk2_ardour/opts.cc:53
-msgid "  -o, --use-hw-optimizations        Try to use h/w specific optimizations\n"
+#: gtk2_ardour/opts.cc:54
+msgid "  -O, --no-hw-optimizations        Disable h/w specific optimizations\n"
 msgstr ""
 
-#: gtk2_ardour/opts.cc:55
+#: gtk2_ardour/opts.cc:56
 #, fuzzy
 msgid "  -V, --novst                      Do not use VST support\n"
 msgstr "  -h, --help                       Diese Hinweise\n"
 
-#: gtk2_ardour/opts.cc:57
+#: gtk2_ardour/opts.cc:58
 msgid "  [session-name]                   Name of session to load\n"
-msgstr "  [session-name]                   Name der zu ladenden Sitzung\n"
+msgstr "  [session-name]                   Name des zu ladenden Projekts\n"
 
-#: gtk2_ardour/opts.cc:58
+#: gtk2_ardour/opts.cc:59
 msgid "  -C, --curvetest filename         Curve algorithm debugger\n"
 msgstr ""
 
-#: gtk2_ardour/opts.cc:59
-#, fuzzy
-msgid "  -g, --gtktheme                   Allow GTK to load a theme\n"
-msgstr "  -h, --help                       Diese Hinweise\n"
+#: gtk2_ardour/opts.cc:60
+msgid "  -k, --keybindings filename       Name of key bindings to load (default is ~/.ardour2/ardour.bindings)\n"
+msgstr ""
 
 #: gtk2_ardour/pan_automation_time_axis.cc:70
 msgid "You need to select which line to edit"
@@ -5537,74 +5506,72 @@ msgid "add pan automation event"
 msgstr "Stellen"
 
 #: gtk2_ardour/panner2d.cc:589
-#: gtk2_ardour/panner_ui.cc:425
-#: gtk2_ardour/plugin_ui.cc:151
+#: gtk2_ardour/panner_ui.cc:438
+#: gtk2_ardour/plugin_ui.cc:152
 msgid "Bypass"
 msgstr "Bypass"
 
-#: gtk2_ardour/panner_ui.cc:56
-#: gtk2_ardour/panner_ui.cc:223
+#: gtk2_ardour/panner_ui.cc:58
+#: gtk2_ardour/panner_ui.cc:225
 #, fuzzy
 msgid "link"
 msgstr "leer"
 
-#: gtk2_ardour/panner_ui.cc:67
+#: gtk2_ardour/panner_ui.cc:69
 msgid "Pan automation mode"
 msgstr "Pan-Automationsmodus"
 
-#: gtk2_ardour/panner_ui.cc:68
+#: gtk2_ardour/panner_ui.cc:70
 #, fuzzy
 msgid "Pan automation type"
 msgstr "Stellen"
 
-#: gtk2_ardour/panner_ui.cc:79
+#: gtk2_ardour/panner_ui.cc:81
 msgid "panning link control"
 msgstr "Pan-Regler gruppieren"
 
-#: gtk2_ardour/panner_ui.cc:81
+#: gtk2_ardour/panner_ui.cc:83
 msgid "panning link direction"
 msgstr "Richtung der Gruppierung"
 
-#: gtk2_ardour/panner_ui.cc:233
+#: gtk2_ardour/panner_ui.cc:235
 msgid "L"
 msgstr "L"
 
-#: gtk2_ardour/panner_ui.cc:328
+#: gtk2_ardour/panner_ui.cc:341
 #, c-format
 msgid "panner for channel %zu"
 msgstr "Pan-Regler für Kanal %zu"
 
-#: gtk2_ardour/panner_ui.cc:435
+#: gtk2_ardour/panner_ui.cc:448
 #, fuzzy
 msgid "Reset all"
 msgstr "bestmöglich"
 
 #: gtk2_ardour/playlist_selector.cc:52
-#, fuzzy
 msgid "ardour: playlists"
-msgstr "Ardour: Plugins"
+msgstr "ardour: Wiedergabelisten"
 
 #: gtk2_ardour/playlist_selector.cc:59
 msgid "Playlists grouped by track"
 msgstr ""
 
-#: gtk2_ardour/playlist_selector.cc:98
-#, fuzzy
+#: gtk2_ardour/playlist_selector.cc:107
 msgid "ardour: playlist for "
-msgstr "Ardour: Editor: "
+msgstr "ardour: Wiedergabeliste für "
 
-#: gtk2_ardour/playlist_selector.cc:114
+#: gtk2_ardour/playlist_selector.cc:123
 #, fuzzy
 msgid "Other tracks"
 msgstr "Stille einfügen"
 
-#: gtk2_ardour/playlist_selector.cc:130
+#: gtk2_ardour/playlist_selector.cc:140
 msgid "unassigned"
 msgstr ""
 
 #: gtk2_ardour/plugin_selector.cc:43
 msgid "ardour: plugins"
-msgstr "Ardour: Plugins"
+msgstr "ardour: Plugins"
 
 #: gtk2_ardour/plugin_selector.cc:56
 msgid "Available LADSPA Plugins"
@@ -5663,11 +5630,11 @@ msgstr ""
 msgid "unknown type of editor-supplying plugin (note: no VST support in this version of ardour)"
 msgstr ""
 
-#: gtk2_ardour/plugin_ui.cc:171
+#: gtk2_ardour/plugin_ui.cc:172
 msgid "Plugin preset %1 not found"
 msgstr "Plugin Preset %1 nicht gefunden"
 
-#: gtk2_ardour/plugin_ui.cc:181
+#: gtk2_ardour/plugin_ui.cc:182
 #, fuzzy
 msgid "Name of New Preset:"
 msgstr "Name für neue Verbindung:"
@@ -5681,15 +5648,15 @@ msgstr ""
 msgid "add automation event to "
 msgstr "Stellen"
 
-#: gtk2_ardour/redirect_box.cc:226
+#: gtk2_ardour/redirect_box.cc:235
 msgid "New send"
 msgstr ""
 
-#: gtk2_ardour/redirect_box.cc:227
+#: gtk2_ardour/redirect_box.cc:236
 msgid "Show send controls"
 msgstr ""
 
-#: gtk2_ardour/redirect_box.cc:386
+#: gtk2_ardour/redirect_box.cc:417
 msgid ""
 "You attempted to add a plugin (%1).\n"
 "The plugin has %2 inputs\n"
@@ -5700,7 +5667,7 @@ msgid ""
 "part of the signal."
 msgstr ""
 
-#: gtk2_ardour/redirect_box.cc:398
+#: gtk2_ardour/redirect_box.cc:429
 msgid ""
 "You attempted to add a plugin (%1).\n"
 "The plugin has %2 inputs\n"
@@ -5712,7 +5679,7 @@ msgid ""
 "support this type of configuration."
 msgstr ""
 
-#: gtk2_ardour/redirect_box.cc:411
+#: gtk2_ardour/redirect_box.cc:442
 msgid ""
 "You attempted to add a plugin (%1).\n"
 "\n"
@@ -5725,35 +5692,35 @@ msgid ""
 "Ardour does not understand what to do in such situations.\n"
 msgstr ""
 
-#: gtk2_ardour/redirect_box.cc:499
+#: gtk2_ardour/redirect_box.cc:539
 msgid "Pre-fader inserts, sends & plugins:"
 msgstr ""
 
-#: gtk2_ardour/redirect_box.cc:502
+#: gtk2_ardour/redirect_box.cc:542
 msgid "Post-fader inserts, sends & plugins:"
 msgstr "Post-Fader Inserts, Sends & Plugins:"
 
-#: gtk2_ardour/redirect_box.cc:650
+#: gtk2_ardour/redirect_box.cc:708
 msgid ""
 "You cannot reorder this set of redirects\n"
 "in that way because the inputs and\n"
 "outputs do not work correctly."
 msgstr ""
 
-#: gtk2_ardour/redirect_box.cc:750
+#: gtk2_ardour/redirect_box.cc:821
 #, fuzzy
 msgid "rename redirect"
 msgstr "Ardour: Region umbenennen"
 
-#: gtk2_ardour/redirect_box.cc:824
-#: gtk2_ardour/redirect_box.cc:872
+#: gtk2_ardour/redirect_box.cc:897
+#: gtk2_ardour/redirect_box.cc:946
 msgid ""
 "Copying the set of redirects on the clipboard failed,\n"
 "probably because the I/O configuration of the plugins\n"
 "could not match the configuration of this track."
 msgstr ""
 
-#: gtk2_ardour/redirect_box.cc:894
+#: gtk2_ardour/redirect_box.cc:968
 #, fuzzy
 msgid ""
 "Do you really want to remove all redirects from this track?\n"
@@ -5762,7 +5729,7 @@ msgstr ""
 "Wollen Sie wirklich die Spur \"%1\" löschen?\n"
 "(Kann nicht rückgängig gemacht werden!)"
 
-#: gtk2_ardour/redirect_box.cc:897
+#: gtk2_ardour/redirect_box.cc:971
 #, fuzzy
 msgid ""
 "Do you really want to remove all redirects from this bus?\n"
@@ -5771,47 +5738,46 @@ msgstr ""
 "Wollen Sie wirklich die Spur \"%1\" löschen?\n"
 "(Kann nicht rückgängig gemacht werden!)"
 
-#: gtk2_ardour/redirect_box.cc:902
+#: gtk2_ardour/redirect_box.cc:976
 msgid "Yes, remove them all"
 msgstr "Ja, alle löschen"
 
-#: gtk2_ardour/redirect_box.cc:938
-#, fuzzy
+#: gtk2_ardour/redirect_box.cc:1012
 msgid "ardour: %1"
-msgstr "Ardour: "
+msgstr "ardour: %1"
 
-#: gtk2_ardour/redirect_box.cc:1060
+#: gtk2_ardour/redirect_box.cc:1134
 msgid "New Plugin ..."
 msgstr "Plugin einfügen..."
 
-#: gtk2_ardour/redirect_box.cc:1062
+#: gtk2_ardour/redirect_box.cc:1136
 msgid "New Insert"
 msgstr "Insert einfügen"
 
-#: gtk2_ardour/redirect_box.cc:1064
+#: gtk2_ardour/redirect_box.cc:1138
 msgid "New Send ..."
 msgstr "Send einfügen..."
 
-#: gtk2_ardour/redirect_box.cc:1078
+#: gtk2_ardour/redirect_box.cc:1152
 msgid "Deselect All"
 msgstr "Nichts auswählen"
 
-#: gtk2_ardour/redirect_box.cc:1085
+#: gtk2_ardour/redirect_box.cc:1159
 msgid "Activate all"
 msgstr "Alle aktivieren"
 
-#: gtk2_ardour/redirect_box.cc:1086
+#: gtk2_ardour/redirect_box.cc:1160
 msgid "Deactivate all"
 msgstr "Alle deaktivieren"
 
-#: gtk2_ardour/redirect_box.cc:1263
+#: gtk2_ardour/redirect_box.cc:1339
 #, fuzzy
 msgid "ardour: %1: %2 (by %3)"
 msgstr "Ardour: "
 
 #: gtk2_ardour/audio_region_editor.cc:47
 msgid "NAME:"
-msgstr "NAME:"
+msgstr "Name:"
 
 #: gtk2_ardour/audio_region_editor.cc:48
 msgid "play"
@@ -5823,39 +5789,35 @@ msgstr ""
 
 #: gtk2_ardour/audio_region_editor.cc:82
 msgid "START:"
-msgstr "BEGINN:"
+msgstr "Beginn:"
 
 #: gtk2_ardour/audio_region_editor.cc:84
 msgid "END:"
-msgstr "ENDE:"
+msgstr "Ende:"
 
 #: gtk2_ardour/audio_region_editor.cc:86
 msgid "LENGTH:"
-msgstr "L��NGE:"
+msgstr "L��ngess:"
 
 #: gtk2_ardour/audio_region_editor.cc:122
 msgid "ardour: region "
-msgstr "Ardour: Region"
+msgstr "ardour: Region"
 
 #: gtk2_ardour/audio_region_editor.cc:202
-#, fuzzy
 msgid "change region start position"
-msgstr "Regionen"
+msgstr "Startposition der Region Ã¤ndern"
 
 #: gtk2_ardour/audio_region_editor.cc:219
-#, fuzzy
 msgid "change region end position"
-msgstr "Regionen"
+msgstr "Endposition der Region Ã¤ndern"
 
 #: gtk2_ardour/audio_region_editor.cc:240
-#, fuzzy
 msgid "change region length"
-msgstr "Ardour: Editor"
+msgstr "Länge der Region verändern"
 
-#: gtk2_ardour/audio_region_view.cc:937
-#, fuzzy
+#: gtk2_ardour/audio_region_view.cc:890
 msgid "add gain control point"
-msgstr "Synchronisationspunkt entfernen"
+msgstr "Lautstärkekurve bearbeiten"
 
 #: gtk2_ardour/route_params_ui.cc:85
 msgid "Tracks/Buses"
@@ -5874,11 +5836,6 @@ msgstr ""
 msgid "ardour: track/bus inspector"
 msgstr "Ardour: Editor"
 
-#: gtk2_ardour/route_params_ui.cc:141
-#, fuzzy
-msgid "ardour_route_parameters"
-msgstr "Ardour: Route"
-
 #: gtk2_ardour/route_params_ui.cc:202
 msgid "route display list item for renamed route not found!"
 msgstr ""
@@ -5956,7 +5913,7 @@ msgstr ""
 #: gtk2_ardour/route_ui.cc:655
 #: gtk2_ardour/visual_time_axis.cc:242
 msgid "ardour: color selection"
-msgstr "Ardour: Farbe auswählen"
+msgstr "ardour: Farbe auswählen"
 
 #: gtk2_ardour/route_ui.cc:731
 msgid ""
@@ -5983,116 +5940,128 @@ msgid "Yes, remove it."
 msgstr "Ja, entfernen."
 
 #: gtk2_ardour/route_ui.cc:758
-#, fuzzy
 msgid "New Name: "
 msgstr "Neuer Name: "
 
 #: gtk2_ardour/sfdb_ui.cc:61
-msgid "Add Field..."
-msgstr "Feld hinzufügen..."
-
-#: gtk2_ardour/sfdb_ui.cc:62
-msgid "Remove Field"
-msgstr "Feld entfernen"
+msgid "Apply"
+msgstr "Ãœbernehmen"
 
-#: gtk2_ardour/sfdb_ui.cc:65
+#: gtk2_ardour/sfdb_ui.cc:67
 msgid "Soundfile Info"
-msgstr ""
+msgstr "Eigenschaften der Audiodatei"
 
-#: gtk2_ardour/sfdb_ui.cc:84
-msgid "Field"
-msgstr "Feld"
+#: gtk2_ardour/sfdb_ui.cc:70
+msgid "comma seperated tags"
+msgstr "Stichworte (durch Komma getrennt)"
 
-#: gtk2_ardour/sfdb_ui.cc:85
-msgid "Value"
-msgstr "Wert"
+#: gtk2_ardour/sfdb_ui.cc:128
+msgid "Length: n/a"
+msgstr "Länge: n/a"
 
-#: gtk2_ardour/sfdb_ui.cc:139
+#: gtk2_ardour/sfdb_ui.cc:129
+msgid "Format: n/a"
+msgstr "Format: n/a"
+
+#: gtk2_ardour/sfdb_ui.cc:130
+msgid "Channels: n/a"
+msgstr "Channels: n/a"
+
+#: gtk2_ardour/sfdb_ui.cc:131
+msgid "Samplerate: n/a"
+msgstr "Samplerate: n/a"
+
+#: gtk2_ardour/sfdb_ui.cc:132
+msgid "Timecode: n/a"
+msgstr "Timecode: n/a"
+
+#: gtk2_ardour/sfdb_ui.cc:142
 msgid "Length: %1"
-msgstr ""
+msgstr "Länge: %1"
 
-#: gtk2_ardour/sfdb_ui.cc:145
-#, fuzzy
+#: gtk2_ardour/sfdb_ui.cc:144
 msgid "Channels: %1"
-msgstr "Kanäle"
+msgstr "Kanäle: %1"
 
-#: gtk2_ardour/sfdb_ui.cc:148
-#, fuzzy
+#: gtk2_ardour/sfdb_ui.cc:145
 msgid "Samplerate: %1"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr "Samplerate: %1"
 
-#: gtk2_ardour/sfdb_ui.cc:151
-#, fuzzy
+#: gtk2_ardour/sfdb_ui.cc:146
 msgid "Timecode: %1"
-msgstr "Timecode"
-
-#: gtk2_ardour/sfdb_ui.cc:172
-#, fuzzy
-msgid "samplerate"
-msgstr "Ausgewählten Bereich wiedergeben"
+msgstr "Timecode: %1"
 
-#: gtk2_ardour/sfdb_ui.cc:173
-#, fuzzy
-msgid "resolution"
-msgstr "Auswahl wiedergeben"
-
-#: gtk2_ardour/sfdb_ui.cc:173
-#, fuzzy
-msgid "format"
-msgstr "Anschluß"
-
-#: gtk2_ardour/sfdb_ui.cc:194
+#: gtk2_ardour/sfdb_ui.cc:186
 msgid "Could not read file: %1 (%2)."
-msgstr ""
+msgstr "Konnte Datei nicht lesen: %1 (%2)."
 
-#: gtk2_ardour/sfdb_ui.cc:212
+#: gtk2_ardour/sfdb_ui.cc:204
 msgid "Could not access soundfile: "
-msgstr ""
+msgstr "Konnte auf Audiodatei nicht zugreifen: "
 
-#: gtk2_ardour/sfdb_ui.cc:260
-#, fuzzy
-msgid "Name for Field"
-msgstr "Name für Region:"
+#: gtk2_ardour/sfdb_ui.cc:253
+msgid "SoundFileBox: Could not tokenize string: "
+msgstr ""
 
-#: gtk2_ardour/sfdb_ui.cc:327
+#: gtk2_ardour/sfdb_ui.cc:273
 msgid "Add to Region list"
 msgstr "Zur Liste der Regionen hinzufügen"
 
-#: gtk2_ardour/sfdb_ui.cc:328
+#: gtk2_ardour/sfdb_ui.cc:274
 msgid "Add to selected Track(s)"
 msgstr "Zu ausgewählten Spuren hinzufügen"
 
-#: gtk2_ardour/sfdb_ui.cc:329
+#: gtk2_ardour/sfdb_ui.cc:275
 msgid "Add as new Track(s)"
 msgstr "Als neue Spur(en) hinzufügen"
 
-#: gtk2_ardour/sfdb_ui.cc:330
+#: gtk2_ardour/sfdb_ui.cc:276
 msgid "Add as new Tape Track(s)"
 msgstr "Als neue Tape-Spuren hinzufügen"
 
-#: gtk2_ardour/sfdb_ui.cc:372
+#: gtk2_ardour/sfdb_ui.cc:285
+msgid "Search"
+msgstr "Suchen"
+
+#: gtk2_ardour/sfdb_ui.cc:300
+msgid "Paths"
+msgstr "Pfade"
+
+#: gtk2_ardour/sfdb_ui.cc:302
+msgid "Files"
+msgstr "Dateien"
+
+#: gtk2_ardour/sfdb_ui.cc:303
+msgid "Tags"
+msgstr "Stichworte"
+
+#: gtk2_ardour/sfdb_ui.cc:362
+msgid "SoundFileBrowser: Could not tokenize string: "
+msgstr ""
+
+#: gtk2_ardour/sfdb_ui.cc:420
 msgid "Split Channels"
 msgstr "Kanäle aufteilen"
 
-#: gtk2_ardour/sfdb_ui.cc:379
+#: gtk2_ardour/sfdb_ui.cc:423
 msgid "Create a region for each channel"
 msgstr "Erstellt aus jedem Kanal eine eigene Region"
 
-#: gtk2_ardour/sfdb_ui.cc:381
+#: gtk2_ardour/sfdb_ui.cc:425
 msgid "Embed"
 msgstr "Einbetten"
 
-#: gtk2_ardour/sfdb_ui.cc:383
+#: gtk2_ardour/sfdb_ui.cc:427
 msgid "Link to an external file"
-msgstr "Bettet eine externe Datei ein, ohne sie zu ins Verzeichnis der Sitzung zu importieren"
+msgstr "Bettet eine externe Datei ein, ohne sie zu ins Verzeichnis des Projekts zu importieren"
 
-#: gtk2_ardour/sfdb_ui.cc:387
+#: gtk2_ardour/sfdb_ui.cc:429
 msgid "Import"
 msgstr "Importieren"
 
-#: gtk2_ardour/sfdb_ui.cc:389
+#: gtk2_ardour/sfdb_ui.cc:431
 msgid "Copy a file to the session folder"
-msgstr "Kopiert eine Datei in das Verzeichnis der Sitzung"
+msgstr "Kopiert eine Datei in das Verzeichnis des Projekts"
 
 #: gtk2_ardour/tempo_dialog.cc:18
 #: gtk2_ardour/tempo_dialog.cc:35
@@ -6199,7 +6168,7 @@ msgstr "Kleiner"
 msgid "Small"
 msgstr "Klein"
 
-#: gtk2_ardour/time_axis_view.cc:902
+#: gtk2_ardour/time_axis_view.cc:903
 msgid "unknown track height name \"%1\" in XML GUI information"
 msgstr ""
 
@@ -6215,16 +6184,16 @@ msgstr ""
 msgid "programming error: request for non-existent audio range (%1)!"
 msgstr ""
 
-#: gtk2_ardour/utils.cc:106
-#: gtk2_ardour/utils.cc:149
+#: gtk2_ardour/utils.cc:118
+#: gtk2_ardour/utils.cc:161
 msgid "bad XPM header %1"
 msgstr ""
 
-#: gtk2_ardour/utils.cc:331
+#: gtk2_ardour/utils.cc:285
 msgid "missing RGBA style for \"%1\""
 msgstr ""
 
-#: gtk2_ardour/utils.cc:513
+#: gtk2_ardour/utils.cc:467
 msgid "cannot find icon image for %1"
 msgstr ""
 
@@ -6240,13 +6209,9 @@ msgstr ""
 msgid "new name: "
 msgstr "Neuer Name: "
 
-#: gtk2_ardour/visual_time_axis.cc:341
-msgid "A track already exists with that name"
-msgstr ""
-
 #: gtk2_ardour/connection_editor.cc:51
 msgid "ardour: connections"
-msgstr "Ardour: Verbindungen"
+msgstr "ardour: Verbindungen"
 
 #: gtk2_ardour/connection_editor.cc:52
 msgid "Input Connections"
@@ -6257,18 +6222,15 @@ msgid "Output Connections"
 msgstr "Verbindungen der Ausgänge"
 
 #: gtk2_ardour/connection_editor.cc:54
-#, fuzzy
 msgid "New Input"
 msgstr "Neuer Eingang"
 
 #: gtk2_ardour/connection_editor.cc:55
-#, fuzzy
 msgid "New Output"
 msgstr "Neuer Ausgang"
 
 #: gtk2_ardour/connection_editor.cc:58
 #: gtk2_ardour/connection_editor.cc:101
-#, fuzzy
 msgid "Add Port"
 msgstr "Port hinzufügen"
 
index a47ac606e80df65a6a73a1e9bfe0a34bd8cd2c74..5821110b6cd202e53dc2914cf0a8234ad2c7946a 100644 (file)
@@ -87,6 +87,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
        virtual void new_region_from_selection () = 0;
        virtual void separate_region_from_selection () = 0;
        virtual void toggle_playback (bool with_abort) = 0;
+       virtual void transition_to_rolling (bool fwd) = 0;
        virtual nframes_t unit_to_frame (double unit) = 0;
        virtual double frame_to_unit (nframes_t frame) = 0;
        virtual double frame_to_unit (double frame) = 0;
@@ -144,6 +145,8 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulThingWithGoingAway
 
        Glib::RefPtr<Gtk::ActionGroup> editor_actions;
 
+       virtual void reset_focus() = 0;
+
        virtual bool canvas_control_point_event (GdkEvent* event,ArdourCanvas::Item*, ControlPoint*) = 0;
        virtual bool canvas_line_event (GdkEvent* event,ArdourCanvas::Item*, AutomationLine*) = 0;
        virtual bool canvas_selection_rect_event (GdkEvent* event,ArdourCanvas::Item*, SelectionRect*) = 0;
index a418b1de23623944edcdc4f08fa74c7bcc9f645e..34810691f5c33e3f1cc678b9dc056daa0f6f55bc 100644 (file)
 
 #include "region_view.h"
 #include "region_selection.h"
+#include "time_axis_view.h"
 
 using namespace ARDOUR;
 using namespace PBD;
 using namespace sigc;
 
 
-bool 
-RegionComparator::operator() (const RegionView* a, const RegionView* b) const
-{
-       if (a == b) {
-               return false;
-       } else {
-               return a < b;
-       }
-}
-
 RegionSelection::RegionSelection ()
 {
        _current_start = 0;
@@ -46,9 +37,8 @@ RegionSelection::RegionSelection ()
 
 RegionSelection::RegionSelection (const RegionSelection& other)
 {
-
        for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
-               add (*i, false);
+               add (*i);
        }
        _current_start = other._current_start;
        _current_end = other._current_end;
@@ -64,7 +54,7 @@ RegionSelection::operator= (const RegionSelection& other)
                clear_all();
                
                for (RegionSelection::const_iterator i = other.begin(); i != other.end(); ++i) {
-                       add (*i, false);
+                       add (*i);
                }
 
                _current_start = other._current_start;
@@ -83,17 +73,17 @@ RegionSelection::clear_all()
        _current_end = 0;
 }
 
-bool RegionSelection::contains (RegionView* rv)
+bool RegionSelection::contains (RegionView* rv) const
 {
-       return this->find (rv) != end();
+       return find (begin(), end(), rv) != end();
 }
 
-void
-RegionSelection::add (RegionView* rv, bool dosort)
+bool
+RegionSelection::add (RegionView* rv)
 {
        if (contains (rv)) {
                /* we already have it */
-               return;
+               return false;
        }
 
        rv->RegionViewGoingAway.connect (mem_fun(*this, &RegionSelection::remove_it));
@@ -106,11 +96,13 @@ RegionSelection::add (RegionView* rv, bool dosort)
                _current_end = rv->region()->last_frame();
        }
        
-       insert (rv);
+       push_back (rv);
 
        // add to layer sorted list
+
        add_to_layer (rv);
-       
+
+       return true;
 }
 
 void
@@ -124,7 +116,7 @@ RegionSelection::remove (RegionView* rv)
 {
        RegionSelection::iterator i;
 
-       if ((i = this->find (rv)) != end()) {
+       if ((i = find (begin(), end(), rv)) != end()) {
 
                erase (i);
 
@@ -198,7 +190,7 @@ RegionSelection::add_to_layer (RegionView * rv)
 }
 
 struct RegionSortByTime {
-    bool operator() (const RegionView* a, const RegionView* b) {
+    bool operator() (const RegionView* a, const RegionView* b) const {
            return a->region()->position() < b->region()->position();
     }
 };
@@ -217,3 +209,49 @@ RegionSelection::by_position (list<RegionView*>& foo) const
        foo.sort (sorter);
        return;
 }
+
+struct RegionSortByTrack {
+    bool operator() (const RegionView* a, const RegionView* b) const {
+           
+           /* really, track and position */
+
+           if (a->get_trackview().order == b->get_trackview().order) {
+                   return a->region()->position() < b->region()->position();
+           } else {
+                   return a->get_trackview().order < b->get_trackview().order;
+           }
+    }
+};
+       
+void
+RegionSelection::by_track (list<RegionView*>& foo) const
+{
+       list<RegionView*>::const_iterator i;
+       RegionSortByTrack sorter;
+
+       for (i = _bylayer.begin(); i != _bylayer.end(); ++i) {
+               foo.push_back (*i);
+       }
+
+       foo.sort (sorter);
+       return;
+}
+
+void
+RegionSelection::sort_by_position_and_track ()
+{
+       RegionSortByTrack sorter;
+       sort (sorter);
+}
+
+bool
+RegionSelection::involves (const TimeAxisView& tv) const
+{
+       for (RegionSelection::const_iterator i = begin(); i != end(); ++i) {
+               if (&(*i)->get_trackview() == &tv) {
+                       return true;
+               }
+       }
+       return false;
+}
+       
index 7e1d3b0835fb621a7d8e33aa2bb274842d97bc62..6b5ae9c0fbf98a5a772d2d950623be66458d7c07 100644 (file)
@@ -29,11 +29,7 @@ using std::set;
 
 class RegionView;
 
-struct RegionComparator {
-    bool operator() (const RegionView* a, const RegionView* b) const;
-};
-
-class RegionSelection : public set<RegionView*, RegionComparator>, public sigc::trackable
+class RegionSelection : public std::list<RegionView*>, public sigc::trackable
 {
   public:
        RegionSelection();
@@ -41,9 +37,12 @@ class RegionSelection : public set<RegionView*, RegionComparator>, public sigc::
 
        RegionSelection& operator= (const RegionSelection&);
 
-       void add (RegionView*, bool dosort = true);
+       bool add (RegionView*);
        bool remove (RegionView*);
-       bool contains (RegionView*);
+       void sort_by_position_and_track ();
+
+       bool contains (RegionView*) const;
+       bool involves (const TimeAxisView&) const;
 
        void clear_all();
        
@@ -51,14 +50,15 @@ class RegionSelection : public set<RegionView*, RegionComparator>, public sigc::
                return _current_start;
        }
 
-       /* collides with list<>::end */
+       /* "end" collides with list<>::end */
 
        nframes_t end_frame () const { 
                return _current_end;
        }
 
-       const list<RegionView *> & by_layer() const { return _bylayer; }
-       void  by_position (list<RegionView*>&) const;
+       const std::list<RegionView *>& by_layer() const { return _bylayer; }
+       void  by_position (std::list<RegionView*>&) const;
+       void  by_track (std::list<RegionView*>&) const;
        
   private:
        void remove_it (RegionView*);
index 38a0cdd8e2d429910c2008d148244339d2300acd..8a34752cddde583560a30a10567b4fdc69647df8 100644 (file)
@@ -209,9 +209,9 @@ Selection::toggle (RegionView* r)
        RegionSelection::iterator i;
 
        if ((i = find (regions.begin(), regions.end(), r)) == regions.end()) {
-               regions.add (r);
+               add (r);
        } else {
-               regions.erase (i);
+               remove (*i);
        }
 
        RegionsChanged ();
@@ -224,9 +224,9 @@ Selection::toggle (vector<RegionView*>& r)
 
        for (vector<RegionView*>::iterator x = r.begin(); x != r.end(); ++x) {
                if ((i = find (regions.begin(), regions.end(), (*x))) == regions.end()) {
-                       regions.add ((*x));
+                       add ((*x));
                } else {
-                       regions.erase (i);
+                       remove (*x);
                }
        }
 
@@ -322,6 +322,7 @@ Selection::add (RegionView* r)
 {
        if (find (regions.begin(), regions.end(), r) == regions.end()) {
                regions.add (r);
+               add (&r->get_trackview());
                RegionsChanged ();
        }
 }
@@ -333,8 +334,10 @@ Selection::add (vector<RegionView*>& v)
 
        for (vector<RegionView*>::iterator i = v.begin(); i != v.end(); ++i) {
                if (find (regions.begin(), regions.end(), (*i)) == regions.end()) {
-                       regions.add ((*i));
-                       changed = true;
+                       changed = regions.add ((*i));
+                       if (changed) {
+                               add (&(*i)->get_trackview());
+                       }
                }
        }
 
@@ -461,8 +464,13 @@ Selection::remove (const list<boost::shared_ptr<Playlist> >& pllist)
 void
 Selection::remove (RegionView* r)
 {
-       regions.remove (r);
-       RegionsChanged ();
+       if (regions.remove (r)) {
+               RegionsChanged ();
+       }
+
+       if (!regions.involves (r->get_trackview())) {
+               remove (&r->get_trackview());
+       }
 }
 
 
@@ -537,12 +545,14 @@ void
 Selection::set (RegionView* r)
 {
        clear_regions ();
+       clear_tracks ();
        add (r);
 }
 
 void
 Selection::set (vector<RegionView*>& v)
 {
+       clear_tracks ();
        clear_regions ();
        // make sure to deselect any automation selections
        clear_points();
@@ -616,6 +626,52 @@ Selection::empty ()
                ;
 }
 
+void
+Selection::toggle (const vector<AutomationSelectable*>& autos)
+{
+       for (vector<AutomationSelectable*>::const_iterator x = autos.begin(); x != autos.end(); ++x) {
+               if ((*x)->get_selected()) {
+                       points.remove (**x);
+               } else {
+                       points.push_back (**x);
+               }
+
+               delete *x;
+       }
+
+       PointsChanged (); /* EMIT SIGNAL */
+}
+
+void
+Selection::toggle (list<Selectable*>& selectables)
+{
+       RegionView* rv;
+       AutomationSelectable* as;
+       vector<RegionView*> rvs;
+       vector<AutomationSelectable*> autos;
+
+       for (std::list<Selectable*>::iterator i = selectables.begin(); i != selectables.end(); ++i) {
+               if ((rv = dynamic_cast<RegionView*> (*i)) != 0) {
+                       rvs.push_back (rv);
+               } else if ((as = dynamic_cast<AutomationSelectable*> (*i)) != 0) {
+                       autos.push_back (as);
+               } else {
+                       fatal << _("programming error: ")
+                             << X_("unknown selectable type passed to Selection::toggle()")
+                             << endmsg;
+                       /*NOTREACHED*/
+               }
+       }
+
+       if (!rvs.empty()) {
+               toggle (rvs);
+       } 
+
+       if (!autos.empty()) {
+               toggle (autos);
+       } 
+}
+
 void
 Selection::set (list<Selectable*>& selectables)
 {
@@ -640,7 +696,7 @@ Selection::add (list<Selectable*>& selectables)
                        autos.push_back (as);
                } else {
                        fatal << _("programming error: ")
-                             << X_("unknown selectable type passed to Selection::set()")
+                             << X_("unknown selectable type passed to Selection::add()")
                              << endmsg;
                        /*NOTREACHED*/
                }
@@ -669,7 +725,6 @@ Selection::add (vector<AutomationSelectable*>& autos)
 {
        for (vector<AutomationSelectable*>::iterator i = autos.begin(); i != autos.end(); ++i) {
                points.push_back (**i);
-               delete *i;
        }
 
        PointsChanged ();
index a2997cd7b55ee83bfbfc876feef5d0c09ab0b0e1..5422888536fdb0efe1ee92ea9f9bebed57339851 100644 (file)
@@ -92,49 +92,52 @@ class Selection : public sigc::trackable
        bool selected (TimeAxisView*);
        bool selected (RegionView*);
 
-       void set (list<Selectable*>&);
-       void add (list<Selectable*>&);
+       void set (std::list<Selectable*>&);
+       void add (std::list<Selectable*>&);
+       void toggle (std::list<Selectable*>&);
        
        void set (TimeAxisView*);
-       void set (const list<TimeAxisView*>&);
+       void set (const std::list<TimeAxisView*>&);
        void set (RegionView*);
        void set (std::vector<RegionView*>&);
        long set (TimeAxisView*, nframes_t, nframes_t);
        void set (ARDOUR::AutomationList*);
        void set (boost::shared_ptr<ARDOUR::Playlist>);
-       void set (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
+       void set (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
        void set (boost::shared_ptr<ARDOUR::Redirect>);
        void set (AutomationSelectable*);
 
        void toggle (TimeAxisView*);
-       void toggle (const list<TimeAxisView*>&);
+       void toggle (const std::list<TimeAxisView*>&);
        void toggle (RegionView*);
        void toggle (std::vector<RegionView*>&);
        long toggle (nframes_t, nframes_t);
        void toggle (ARDOUR::AutomationList*);
        void toggle (boost::shared_ptr<ARDOUR::Playlist>);
-       void toggle (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
+       void toggle (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
        void toggle (boost::shared_ptr<ARDOUR::Redirect>);
+       void toggle (const std::vector<AutomationSelectable*>&);
 
        void add (TimeAxisView*);
-       void add (const list<TimeAxisView*>&);
+       void add (const std::list<TimeAxisView*>&);
        void add (RegionView*);
        void add (std::vector<RegionView*>&);
        long add (nframes_t, nframes_t);
        void add (ARDOUR::AutomationList*);
        void add (boost::shared_ptr<ARDOUR::Playlist>);
-       void add (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
+       void add (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
        void add (boost::shared_ptr<ARDOUR::Redirect>);
        
        void remove (TimeAxisView*);
-       void remove (const list<TimeAxisView*>&);
+       void remove (const std::list<TimeAxisView*>&);
        void remove (RegionView*);
        void remove (uint32_t selection_id);
        void remove (nframes_t, nframes_t);
        void remove (ARDOUR::AutomationList*);
        void remove (boost::shared_ptr<ARDOUR::Playlist>);
-       void remove (const list<boost::shared_ptr<ARDOUR::Playlist> >&);
+       void remove (const std::list<boost::shared_ptr<ARDOUR::Playlist> >&);
        void remove (boost::shared_ptr<ARDOUR::Redirect>);
+       void remove (const list<Selectable*>&);
 
        void replace (uint32_t time_index, nframes_t start, nframes_t end);
        
index 6751fc311cf83d2996e8d31c2c8930e613e2b994..f18b543e0ca424dd694b8bf49d21eba1a0cf733e 100644 (file)
@@ -197,7 +197,7 @@ SoundFileBox::play_btn_clicked ()
                
                for (int n = 0; n < sf_info.channels; ++n) {
                        try {
-                               afs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (DataType::AUDIO, *_session, path+":"+string_compose("%1", n), AudioFileSource::Flag (0)));
+                               afs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (DataType::AUDIO, *_session, path, n, AudioFileSource::Flag (0)));
                                srclist.push_back(afs);
 
                        } catch (failed_constructor& err) {
index e27b944e2a6c59597301c1b50ea183ef96edbd1f..80d917704187a75cdc7ba9ad2d670d712c36d6d9 100644 (file)
@@ -232,6 +232,11 @@ class TimeAxisViewItem : public Selectable
     ArdourCanvas::Text* get_name_text();
 
 
+    /**
+     * Returns the time axis that this item is upon
+     */
+    TimeAxisView& get_trackview() const { return trackview; }
+
     /**
      * Sets the samples per unit of this item.
      * this item is used to determine the relative visual size and position of this item
index 68d9112cafe3fc404710519275efeabf0a1bc926..878b41e82af04094599c27f0d6081b13bc992099 100644 (file)
@@ -44,7 +44,6 @@ buffer_set.cc
 meter.cc
 amp.cc
 panner.cc
-destructive_filesource.cc
 audiofilesource.cc
 audiofilter.cc
 audioregion.cc
index c1dc7d1e930b9bbe7b51b96c34a12628033e2a2b..0e1caf5245a9b42a832087e66fd06f42d36407d6 100644 (file)
@@ -101,6 +101,10 @@ class AudioFileSource : public AudioSource {
        bool destructive() const { return (_flags & Destructive); }
        virtual bool set_destructive (bool yn) { return false; }
 
+       Flag flags() const { return _flags; }
+
+       void mark_immutable ();
+
        /* this should really be protected, but C++ is getting stricter
           and creating slots from protected member functions is starting
           to cause issues.
@@ -125,12 +129,12 @@ class AudioFileSource : public AudioSource {
 
        int init (string idstr, bool must_exist);
 
-       uint16_t       channel;
        string        _path;
        Flag          _flags;
        string        _take_id;
        int64_t       timeline_position;
        bool           file_is_new;
+       uint16_t       channel;
 
        bool          _is_embedded;
        static bool determine_embeddedness(string path);
index 53c7e68b824f31c6c760b230b449a30b38011326..e3c5db561dd7e936106e9e58a525a8396a9d2bbc 100644 (file)
@@ -112,7 +112,7 @@ class AudioRegion : public Region
        void set_envelope_active (bool yn);
        void set_default_envelope ();
 
-       int separate_by_channel (ARDOUR::Session&, vector<AudioRegion*>&) const;
+       int separate_by_channel (ARDOUR::Session&, vector<boost::shared_ptr<AudioRegion> >&) const;
 
        /* filter */
 
index 6f0a8a35718ff80a3002a98b488ffba8369316fc..8710369a6431b4af4fd78de3970fda9ead1d3585 100644 (file)
@@ -27,9 +27,13 @@ class ConfigVariableBase {
        virtual void add_to_node (XMLNode& node) = 0;
        virtual bool set_from_node (const XMLNode& node, Owner owner) = 0;
 
+
   protected:
        std::string _name;
        Owner _owner;
+
+       void notify ();
+       void miss ();
 };
 
 template<class T>
@@ -41,10 +45,12 @@ class ConfigVariable : public ConfigVariableBase
 
        virtual bool set (T val, Owner owner) {
                if (val == value) {
+                       miss ();
                        return false;
                }
                value = val;
                _owner = (ConfigVariableBase::Owner)(_owner |owner);
+               notify ();
                return true;
        }
 
@@ -55,6 +61,7 @@ class ConfigVariable : public ConfigVariableBase
        void add_to_node (XMLNode& node) {
                std::stringstream ss;
                ss << value;
+               cerr << "Config variable " << _name << " stored as " << ss.str() << endl;
                XMLNode* child = new XMLNode ("Option");
                child->add_property ("name", _name);
                child->add_property ("value", ss.str());
index c520477c551608c549ecd3d6e8ccfee114919d5d..703352b3050f6841460911303a5bcb55f422b6f7 100644 (file)
@@ -36,7 +36,6 @@ CONFIG_VARIABLE (HeaderFormat, native_file_header_format,  "native-file-header-f
 
 CONFIG_VARIABLE (uint32_t, osc_port, "osc-port", 3819)
 CONFIG_VARIABLE (bool, use_osc, "use-osc", true)
-CONFIG_VARIABLE (bool, use_overlap_equivalency, "use-overlap-equivalency", true)
 
 /* crossfades */
 
@@ -115,6 +114,7 @@ CONFIG_VARIABLE (bool, no_new_session_dialog, "no-new-session-dialog", false)
 CONFIG_VARIABLE (bool, use_vst, "use-vst", true)
 CONFIG_VARIABLE (uint32_t, subframes_per_frame, "subframes-per-frame", 100)
 CONFIG_VARIABLE (uint32_t, saved_history_depth, "save-history-depth", 100)
+CONFIG_VARIABLE (bool, use_overlap_equivalency, "use-overlap-equivalency", false)
 
 /* BWAV */
 
index bd69c78e180d29ec1285d6bdcd8d409bc9da2b59..63c50d7cfb7bd22cf34a0b69dfdc2bd29af76d1c 100644 (file)
@@ -29,7 +29,7 @@ namespace ARDOUR {
 class CoreAudioSource : public AudioFileSource {
   public:
        CoreAudioSource (ARDOUR::Session&, const XMLNode&);
-       CoreAudioSource (ARDOUR::Session&, const string& path_plus_channel, Flag);
+       CoreAudioSource (ARDOUR::Session&, const string& path, int chn, Flag);
        ~CoreAudioSource ();
 
        float sample_rate() const;
index 62ab1f775da65324a3afe81602710ef0cc9a9992..3eafed818cf60dc03edcdbeac6d6bf9101c55c96 100644 (file)
@@ -167,8 +167,6 @@ class Crossfade : public PBD::StatefulDestructible, public boost::enable_shared_
        void initialize ();
        int  compute (boost::shared_ptr<ARDOUR::AudioRegion>, boost::shared_ptr<ARDOUR::AudioRegion>, CrossfadeModel);
        bool update ();
-
-       void member_changed (ARDOUR::Change);
 };
 
 
index 1c1ea9e62c254b4927170fe9ebf50c40a5c95241..63fa608499bb4d69960a6845f4021d1993513304 100644 (file)
@@ -1702,7 +1702,6 @@ class Session : public PBD::StatefulDestructible
 
        void config_changed (const char*);
 
-       void add_control_protocol (const ControlProtocolInfo* const, XMLNode*);
        XMLNode& get_control_protocol_state ();
        
 };
index 1d07f6888ded2a1e064b4e91f3c92a5eb2d3419c..a5000a4b63dcf4adc15243527e59fe4d2ee7040b 100644 (file)
@@ -31,7 +31,7 @@ class SndFileSource : public AudioFileSource {
   public:
        /* constructor to be called for existing external-to-session files */
 
-       SndFileSource (Session&, std::string path, Flag flags);
+       SndFileSource (Session&, std::string path, int chn, Flag flags);
 
        /* constructor to be called for new in-session files */
 
@@ -78,7 +78,7 @@ class SndFileSource : public AudioFileSource {
        mutable float *interleave_buf;
        mutable nframes_t interleave_bufsize;
 
-       void init (string str);
+       void init ();
        int open();
        void close();
        int setup_broadcast_info (nframes_t when, struct tm&, time_t);
index be1551f518f8eb6488a1ff9cc919f9f3aec4767f..b69645b031e5b1795f45918506ef892ea209ee97 100644 (file)
@@ -22,7 +22,7 @@ class SourceFactory {
        static boost::shared_ptr<Source> create (Session&, const XMLNode& node);
 
        // MIDI sources will have to be hacked in here somehow
-       static boost::shared_ptr<Source> createReadable (DataType type, Session&, std::string idstr, AudioFileSource::Flag flags, bool announce = true);
+       static boost::shared_ptr<Source> createReadable (DataType type, Session&, std::string path, int chn, AudioFileSource::Flag flags, bool announce = true);
        static boost::shared_ptr<Source> createWritable (DataType type, Session&, std::string name, bool destructive, nframes_t rate, bool announce = true);
 
   private:
index af41094748a4af635ce8169877e8187ec6c8b610..fa38cca0a0643bd0b1d579a20bd2838e4fe6b6a5 100644 (file)
@@ -63,20 +63,22 @@ uint64_t           AudioFileSource::header_position_offset = 0;
 /* XXX maybe this too */
 char   AudioFileSource::bwf_serial_number[13] = "000000000000";
 
-AudioFileSource::AudioFileSource (Session& s, string idstr, Flag flags)
-       : AudioSource (s, idstr), _flags (flags)
+AudioFileSource::AudioFileSource (Session& s, string path, Flag flags)
+       : AudioSource (s, path), _flags (flags),
+         channel (0)
 {
        /* constructor used for existing external to session files. file must exist already */
-       _is_embedded = AudioFileSource::determine_embeddedness (idstr);
+       _is_embedded = AudioFileSource::determine_embeddedness (path);
 
-       if (init (idstr, true)) {
+       if (init (path, true)) {
                throw failed_constructor ();
        }
 
 }
 
 AudioFileSource::AudioFileSource (Session& s, std::string path, Flag flags, SampleFormat samp_format, HeaderFormat hdr_format)
-       : AudioSource (s, path), _flags (flags)
+       : AudioSource (s, path), _flags (flags),
+         channel (0)
 {
        /* constructor used for new internal-to-session files. file cannot exist */
        _is_embedded = false;
@@ -88,6 +90,7 @@ AudioFileSource::AudioFileSource (Session& s, std::string path, Flag flags, Samp
 
 AudioFileSource::AudioFileSource (Session& s, const XMLNode& node)
        : AudioSource (s, node), _flags (Flag (Writable|CanRename))
+          /* channel is set in set_state() */
 {
        /* constructor used for existing internal-to-session files. file must exist */
 
@@ -195,7 +198,10 @@ XMLNode&
 AudioFileSource::get_state ()
 {
        XMLNode& root (AudioSource::get_state());
-       root.add_property ("flags", enum_2_string (_flags));
+       char buf[32];
+       root.add_property (X_("flags"), enum_2_string (_flags));
+       snprintf (buf, sizeof (buf), "%d", channel);
+       root.add_property (X_("channel"), buf);
        return root;
 }
 
@@ -209,15 +215,18 @@ AudioFileSource::set_state (const XMLNode& node)
        }
 
        if ((prop = node.property (X_("flags"))) != 0) {
-
                _flags = Flag (string_2_enum (prop->value(), _flags));
-
        } else {
-
                _flags = Flag (0);
 
        }
 
+       if ((prop = node.property (X_("channel"))) != 0) {
+               channel = atoi (prop->value());
+       } else {
+               channel = 0;
+       }
+
        if ((prop = node.property (X_("name"))) != 0) {
                _is_embedded = AudioFileSource::determine_embeddedness (prop->value());
        } else {
@@ -537,8 +546,7 @@ AudioFileSource::is_empty (Session& s, string path)
 {
        bool ret = false;
        
-       boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (
-               SourceFactory::createReadable (DataType::AUDIO, s, path, NoPeakFile, false));
+       boost::shared_ptr<AudioFileSource> afs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createReadable (DataType::AUDIO, s, path, 0, NoPeakFile, false));
 
        if (afs) {
                ret = (afs->length() == 0);
@@ -579,3 +587,9 @@ AudioFileSource::safe_file_extension(string file)
 #endif // HAVE_COREAUDIO
                file.rfind(".voc") == string::npos);
 }
+
+void
+AudioFileSource::mark_immutable ()
+{
+       _flags = Flag (_flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename));
+}
index 8b533deda3922a9e4ff4214de51db53754ea05b9..38f8ed3652dc966cd6137952a412054a58ddda09 100644 (file)
@@ -42,6 +42,7 @@
 #include <ardour/audiofilter.h>
 #include <ardour/audiofilesource.h>
 #include <ardour/destructive_filesource.h>
+#include <ardour/region_factory.h>
 
 #include "i18n.h"
 #include <locale.h>
@@ -327,7 +328,7 @@ AudioRegion::_read_at (const SourceList& srcs, Sample *buf, Sample *mixdown_buff
                       nframes_t position, nframes_t cnt, 
                       uint32_t chan_n, nframes_t read_frames, nframes_t skip_frames) const
 {
-       //cerr << _name << "._read_at(" << position << ") - " << _position << endl;
+       cerr << _name << "._read_at(" << position << ") - " << _position << endl;
 
        nframes_t internal_offset;
        nframes_t buf_offset;
@@ -901,25 +902,44 @@ AudioRegion::recompute_at_start ()
 }
 
 int
-AudioRegion::separate_by_channel (Session& session, vector<AudioRegion*>& v) const
+AudioRegion::separate_by_channel (Session& session, vector<boost::shared_ptr<AudioRegion> >& v) const
 {
        SourceList srcs;
        string new_name;
+       int n;
 
-       for (SourceList::const_iterator i = _master_sources.begin(); i != _master_sources.end(); ++i) {
+       if (_sources.size() < 2) {
+               return 0;
+       }
+
+       n = 0;
+
+       for (SourceList::const_iterator i = _sources.begin(); i != _sources.end(); ++i) {
 
                srcs.clear ();
                srcs.push_back (*i);
 
-               /* generate a new name */
-               
-               if (session.region_name (new_name, _name)) {
-                       return -1;
+               new_name = _name;
+
+               if (_sources.size() == 2) {
+                       if (n == 0) {
+                               new_name += "-L";
+                       } else {
+                               new_name += "-R";
+                       }
+               } else {
+                       new_name += '-';
+                       new_name += ('0' + n + 1);
                }
 
                /* create a copy with just one source */
 
-               v.push_back (new AudioRegion (srcs, _start, _length, new_name, _layer, _flags));
+               boost::shared_ptr<Region> r = RegionFactory::create (srcs, _start, _length, new_name, _layer, _flags);
+               boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
+
+               v.push_back (ar);
+               
+               ++n;
        }
 
        return 0;
index eb3d8794472932bb0f195ddefb89027c4d4d3838..a0f2b5e036139ea7a1452c54d02b334e916b2768 100644 (file)
@@ -317,3 +317,16 @@ Configuration::map_parameters (sigc::slot<void,const char*> theSlot)
 #undef  CONFIG_VARIABLE
 #undef  CONFIG_VARIABLE_SPECIAL        
 }
+
+void
+ConfigVariableBase::notify ()
+{
+       // placeholder for any debugging desired when a config variable is modified
+}
+
+void
+ConfigVariableBase::miss ()
+{
+       // placeholder for any debugging desired when a config variable 
+       // is set but to the same value as it already has
+}
index de177d0e3d91c115e2a2854b94f3e6c0a7a9a337..72f56794d727bd17c0a2b44543456420953f9c75 100644 (file)
@@ -324,10 +324,25 @@ ControlProtocolManager::get_state (void)
        Glib::Mutex::Lock lm (protocols_lock);
 
        for (list<ControlProtocolInfo*>::iterator i = control_protocol_info.begin(); i != control_protocol_info.end(); ++i) {
-               XMLNode* child = new XMLNode (X_("Protocol"));
-               child->add_property (X_("name"), (*i)->name);
-               child->add_property (X_("active"), (*i)->protocol ? "yes" : "no");
-               root->add_child_nocopy (*child);
+
+               XMLNode * child;
+
+               if ((*i)->protocol) {
+                       child = &((*i)->protocol->get_state());
+                       child->add_property (X_("active"), "yes");
+                       // should we update (*i)->state here?  probably.
+                       root->add_child_nocopy (*child);
+               }
+               else if ((*i)->state) {
+                       // keep ownership clear
+                       root->add_child_copy (*(*i)->state);
+               }
+               else {
+                       child = new XMLNode (X_("Protocol"));
+                       child->add_property (X_("name"), (*i)->name);
+                       child->add_property (X_("active"), "no");
+                       root->add_child_nocopy (*child);
+               }
        }
 
        return *root;
index 3c81b18fd4fb2ee129a8d230d4fb180f75e234b6..572fd9ef81eb8502ac16043e654afc77823a87bf 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <pbd/error.h>
 #include <ardour/coreaudiosource.h>
+#include <ardour/utils.h>
 
 #include <appleutility/CAAudioFile.h>
 #include <appleutility/CAStreamBasicDescription.h>
@@ -33,33 +34,22 @@ using namespace PBD;
 CoreAudioSource::CoreAudioSource (Session& s, const XMLNode& node)
        : AudioFileSource (s, node)
 {
-       init (_name);
+       init ();
 }
 
-CoreAudioSource::CoreAudioSource (Session& s, const string& idstr, Flag flags)
-       : AudioFileSource(s, idstr, flags)
+CoreAudioSource::CoreAudioSource (Session& s, const string& path, int chn, Flag flags)
+       : AudioFileSource(s, path, flags),
 {
-       init (idstr);
+       channel = chn;
+       init ();
 }
 
 void 
-CoreAudioSource::init (string idstr)
+CoreAudioSource::init ()
 {
-       string::size_type pos;
-
        tmpbuf = 0;
        tmpbufsize = 0;
 
-       _name = idstr;
-
-       if ((pos = idstr.find_last_of (':')) == string::npos) {
-               channel = 0;
-               _path = idstr;
-       } else {
-               channel = atoi (idstr.substr (pos+1).c_str());
-               _path = idstr.substr (0, pos);
-       }
-
        cerr << "CoreAudioSource::init() " << name() << endl;
        
        /* note that we temporarily truncated _id at the colon */
index bd5f908380e0f7dc3d5aa56ef1ebc5648f51d88a..66d1e099dadc408daf36c916112a08d04e0cd499 100644 (file)
@@ -225,9 +225,6 @@ Crossfade::initialize ()
        _fade_in.add (_length, 1.0);
        _fade_in.thaw ();
 
-       // _in->StateChanged.connect (sigc::mem_fun (*this, &Crossfade::member_changed));
-       // _out->StateChanged.connect (sigc::mem_fun (*this, &Crossfade::member_changed));
-
        overlap_type = _in->coverage (_out->position(), _out->last_frame());
        layer_relation = (int32_t) (_in->layer() - _out->layer());
 }      
@@ -597,26 +594,6 @@ Crossfade::compute (boost::shared_ptr<AudioRegion> a, boost::shared_ptr<AudioReg
        return 0;
 }
 
-void
-Crossfade::member_changed (Change what_changed)
-{
-       Change what_we_care_about = Change (Region::MuteChanged|
-                                           Region::LayerChanged|
-                                           BoundsChanged);
-
-       if (what_changed & what_we_care_about) {
-               try { 
-                       if (what_changed & what_we_care_about) {
-                               refresh ();
-                       }
-               }
-
-               catch (NoCrossfadeHere& err) {
-                       // relax, Invalidated inside refresh()
-               }
-       }
-}
-
 XMLNode&
 Crossfade::get_state () 
 {
index fcd85bfe8f117b6bd5fb50f16e3b0f88464cc3c5..5eada195cd48be02e04a5f7ef1012f9b3bf03111 100644 (file)
@@ -410,7 +410,7 @@ DestructiveFileSource::handle_header_position_change ()
 }
 
 void
-DestructiveFileSource::set_timeline_position (int64_t)
+DestructiveFileSource::set_timeline_position (int64_t pos)
 {
        //destructive track timeline postion does not change except at instantion or when header_position_offset (session start) changes
 }
index 7ed6158b850aff72d751c9468077727762bf92f8..b7472781a80ae2c5fb7fa3ca51182f61bda89f32 100644 (file)
@@ -1354,8 +1354,10 @@ IO::set_state (const XMLNode& node)
                        set_automation_state (*(*iter)->children().front());
                }
 
-               if ((*iter)->name() == X_("gaincontrol")) {
-                       _gain_control.set_state (**iter);
+               if ((*iter)->name() == X_("controllable")) {
+                       if ((prop = (*iter)->property("name")) != 0 && prop->value() == "gaincontrol") {
+                               _gain_control.set_state (**iter);
+                       }
                }
        }
 
index d33d19ce67d33e5ae594dc12b62efc7ccc9bc35e..cc914cac3867e10d2e67e10939d793ddcfa26785 100644 (file)
@@ -129,7 +129,7 @@ MidiRegion::_read_at (const SourceList& srcs, MidiRingBuffer& dst,
                       uint32_t chan_n, jack_nframes_t read_frames, jack_nframes_t skip_frames) const
 {
 
-       //cerr << _name << "._read_at(" << position << ") - " << _position << endl;
+       cerr << _name << "._read_at(" << position << ") - " << _position << endl;
 
        jack_nframes_t internal_offset = 0;
        jack_nframes_t src_offset      = 0;
index c69bd844022acc765ec94f9e27b2ed3bb9883697..8ba662aaf454c99427f31333d9abe82a4627a2fc 100644 (file)
@@ -545,9 +545,10 @@ EqualPowerStereoPanner::set_state (const XMLNode& node)
 
        for (XMLNodeConstIterator iter = node.children().begin(); iter != node.children().end(); ++iter) {
 
-               if ((*iter)->name() == X_("panner")) {
-
-                       _control.set_state (**iter);
+               if ((*iter)->name() == X_("controllable")) {
+                       if ((prop = (*iter)->property("name")) != 0 && prop->value() == "panner") {
+                               _control.set_state (**iter);
+                       }
 
                } else if ((*iter)->name() == X_("Automation")) {
 
index 099b4dabbbe23c23a17561749074fedc2c6cb341..db84b015bbc999d0a44e4bf7a7f26e98bea0c0a1 100644 (file)
@@ -606,11 +606,15 @@ Playlist::remove_region_internal (boost::shared_ptr<Region>region)
 void
 Playlist::get_equivalent_regions (boost::shared_ptr<Region> other, vector<boost::shared_ptr<Region> >& results)
 {
-       for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
-               if (Config->get_use_overlap_equivalency()) {
+       if (Config->get_use_overlap_equivalency()) {
+               for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
                        if ((*i)->overlap_equivalent (other)) {
                                results.push_back ((*i));
-                       } else if ((*i)->equivalent (other)) {
+                       }
+               }
+       } else {
+               for (RegionList::iterator i = regions.begin(); i != regions.end(); ++i) {
+                       if ((*i)->equivalent (other)) {
                                results.push_back ((*i));
                        }
                }
index a2bc65407ca6e73a43db976fa871edad30a9dc48..d41574183124ddf5318667a66991b911e1595549 100644 (file)
@@ -1647,13 +1647,19 @@ Route::_set_state (const XMLNode& node, bool call_base)
                        _comment = cmt->content();
 
                } else if (child->name() == X_("extra")) {
+
                        _extra_xml = new XMLNode (*child);
-               } else if (child->name() == X_("solo")) {
-                       _solo_control.set_state (*child);
-                       _session.add_controllable (&_solo_control);
-               } else if (child->name() == X_("mute")) {
-                       _mute_control.set_state (*child);
-                       _session.add_controllable (&_mute_control);
+
+               } else if (child->name() == X_("controllable") && (prop = child->property("name")) != 0) {
+                       
+                       if (prop->value() == "solo") {
+                               _solo_control.set_state (*child);
+                               _session.add_controllable (&_solo_control);
+                       }
+                       else if (prop->value() == "mute") {
+                               _mute_control.set_state (*child);
+                               _session.add_controllable (&_mute_control);
+                       }
                }
        }
 
index c4a5e5fe0a6c68c00c387ec847b2493c182cbb3b..764b25dc9ba9003e381060d54bc96e068f8bba03 100644 (file)
@@ -382,7 +382,6 @@ Session::Session (AudioEngine &eng,
                if (master_out_channels) {
                        shared_ptr<Route> r (new Route (*this, _("master"), -1, master_out_channels, -1, master_out_channels, Route::MasterOut));
                        r->set_remote_control_id (control_id);
-                       cerr << "master bus has remote control ID " << r->remote_control_id() << endl;
                         
                        rl.push_back (r);
                } else {
@@ -410,6 +409,8 @@ Session::Session (AudioEngine &eng,
 
        _state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
 
+       Config->ParameterChanged.connect (mem_fun (*this, &Session::config_changed));
+
        if (was_dirty) {
                DirtyChanged (); /* EMIT SIGNAL */
        }
@@ -1793,6 +1794,10 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod
                                
                                track->set_control_outs (cports);
                        }
+
+                       // assert (current_thread != RT_thread)
+                       
+                       track->audio_diskstream()->non_realtime_input_change();
                        
                        track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes));
                        track->set_remote_control_id (control_id);
@@ -3163,14 +3168,16 @@ Session::midi_path_from_name (string name)
 
                for (i = session_dirs.begin(); i != session_dirs.end(); ++i) {
 
+                       spath = (*i).path;
+
                        // FIXME: different directory from audio?
-                       spath = (*i).path + sound_dir_name + "/" + legalized;
+                       spath += sound_dir(false) + "/" + legalized;
 
                        snprintf (buf, sizeof(buf), "%s-%u.mid", spath.c_str(), cnt);
 
-                       if (access (buf, F_OK) == 0) {
+                       if (g_file_test (buf, G_FILE_TEST_EXISTS)) {
                                existing++;
-                       }
+                       } 
                }
 
                if (existing == 0) {
@@ -3191,6 +3198,7 @@ Session::midi_path_from_name (string name)
 
        // FIXME: different directory than audio?
        spath = discover_best_sound_dir ();
+       spath += '/';
 
        string::size_type pos = foo.find_last_of ('/');
        
@@ -3618,7 +3626,7 @@ Session::remove_redirect (Redirect* redirect)
 nframes_t
 Session::available_capture_duration ()
 {
-       float sample_bytes_on_disk;
+       float sample_bytes_on_disk = 4.0; // keep gcc happy
 
        switch (Config->get_native_file_data_format()) {
        case FormatFloat:
index 9d054c22fd1228da42107c6834eec3fa5ac5f08e..7cf52b741ff4835022d77d298aa85bc053ca4a8c 100644 (file)
@@ -30,7 +30,7 @@ Session::memento_command_factory(XMLNode *n)
 {
     PBD::ID id;
     XMLNode *before = 0, *after = 0;
-    XMLNode *child;
+    XMLNode *child = 0;
 
     /* get id */
     id = PBD::ID(n->property("obj_id")->value());
index 37f7b2c32f6db69d7e08c903bc71cc4bbf8279f4..c8a81be4d48ffded9f3c5f01e028e041a55ffec1 100644 (file)
@@ -1059,19 +1059,7 @@ XMLNode&
 Session::get_control_protocol_state ()
 {
        ControlProtocolManager& cpm (ControlProtocolManager::instance());
-       XMLNode* node = new XMLNode (X_("ControlProtocols"));
-
-       cpm.foreach_known_protocol (bind (mem_fun (*this, &Session::add_control_protocol), node));
-       
-       return *node;
-}
-
-void
-Session::add_control_protocol (const ControlProtocolInfo* const cpi, XMLNode* node)
-{
-       if (cpi->protocol) {
-               node->add_child_nocopy (cpi->protocol->get_state());
-       }
+       return cpm.get_state();
 }
 
 int
index 8e90eac6ab1be8bbc1b634c57cba47af8da8eceb..2885240a5193cee69a5c745ccc10d39ed9ff9322 100644 (file)
@@ -48,30 +48,34 @@ const AudioFileSource::Flag SndFileSource::default_writable_flags = AudioFileSou
 SndFileSource::SndFileSource (Session& s, const XMLNode& node)
        : AudioFileSource (s, node)
 {
-       init (_name);
+       init ();
+
+       cerr << "SndFileSource @ " << _path << " channel = " << channel << endl;
 
        if (open()) {
                throw failed_constructor ();
        }
 }
 
-SndFileSource::SndFileSource (Session& s, string idstr, Flag flags)
-                                       /* files created this way are never writable or removable */
-       : AudioFileSource (s, idstr, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
+SndFileSource::SndFileSource (Session& s, string path, int chn, Flag flags)
+          /* files created this way are never writable or removable */
+       : AudioFileSource (s, path, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy)))
 {
-       init (idstr);
+       channel = chn;
+
+       init ();
 
        if (open()) {
                throw failed_constructor ();
        }
 }
 
-SndFileSource::SndFileSource (Session& s, string idstr, SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags)
-       : AudioFileSource (s, idstr, flags, sfmt, hf)
+SndFileSource::SndFileSource (Session& s, string path, SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags)
+       : AudioFileSource (s, path, flags, sfmt, hf)
 {
        int fmt = 0;
 
-       init (idstr);
+       init ();
 
        /* this constructor is used to construct new files, not open
           existing ones.
@@ -174,9 +178,8 @@ SndFileSource::SndFileSource (Session& s, string idstr, SampleFormat sfmt, Heade
 }
 
 void 
-SndFileSource::init (string idstr)
+SndFileSource::init ()
 {
-       string::size_type pos;
        string file;
 
        // lets try to keep the object initalizations here at the top
@@ -186,20 +189,10 @@ SndFileSource::init (string idstr)
        sf = 0;
        _broadcast_info = 0;
 
-       string tmp_name;
-
-       if ((pos = idstr.find_last_of (':')) == string::npos) {
-               channel = 0;
-               tmp_name = idstr;
-       } else {
-               channel = atoi (idstr.substr (pos+1).c_str());
-               tmp_name = idstr.substr (0, pos);
-       }
-
        if (is_embedded()) {
-               _name = tmp_name;
+               _name = _path;
        } else {
-               _name = Glib::path_get_basename (tmp_name);
+               _name = Glib::path_get_basename (_path);
        }
 
        /* although libsndfile says we don't need to set this,
@@ -385,6 +378,7 @@ nframes_t
 SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt)
 {
        if (!writable()) {
+               warning << string_compose (_("attempt to write a non-writable audio file source (%1)"), _path) << endmsg;
                return 0;
        }
 
@@ -440,6 +434,7 @@ SndFileSource::destructive_write_unlocked (Sample* data, nframes_t cnt)
        nframes_t old_file_pos;
 
        if (!writable()) {
+               warning << string_compose (_("attempt to write a non-writable audio file source (%1)"), _path) << endmsg;
                return 0;
        }
 
@@ -563,6 +558,7 @@ int
 SndFileSource::flush_header ()
 {
        if (!writable() || (sf == 0)) {
+               warning << string_compose (_("attempt to flush a non-writable audio file source (%1)"), _path) << endmsg;
                return -1;
        }
        return (sf_command (sf, SFC_UPDATE_HEADER_NOW, 0, 0) != SF_TRUE);
@@ -572,6 +568,7 @@ int
 SndFileSource::setup_broadcast_info (nframes_t when, struct tm& now, time_t tnow)
 {
        if (!writable()) {
+               warning << string_compose (_("attempt to store broadcast info in a non-writable audio file source (%1)"), _path) << endmsg;
                return -1;
        }
 
index ad01bf617170fefc5e08d0c829389cecf935207d..560bf03e7f5eb802063c1f3636300f2af88e3fe7 100644 (file)
@@ -131,14 +131,13 @@ SourceFactory::create (Session& s, const XMLNode& node)
 
 #ifdef HAVE_COREAUDIO
 boost::shared_ptr<Source>
-SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFileSource::Flag flags, bool announce)
+SourceFactory::createReadable (DataType type, Session& s, string path, int chn, AudioFileSource::Flag flags, bool announce)
 {
        if (type == DataType::AUDIO) {
-
                if (!(flags & Destructive)) {
 
                        try {
-                               boost::shared_ptr<Source> ret (new CoreAudioSource (s, idstr, flags));
+                               boost::shared_ptr<Source> ret (new CoreAudioSource (s, path, chn, flags));
                                if (setup_peakfile (ret)) {
                                        return boost::shared_ptr<Source>();
                                }
@@ -149,7 +148,7 @@ SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFil
                        }
 
                        catch (failed_constructor& err) {
-                               boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
+                               boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags));
                                if (setup_peakfile (ret)) {
                                        return boost::shared_ptr<Source>();
                                }
@@ -161,7 +160,7 @@ SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFil
 
                } else {
 
-                       boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
+                       boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags));
                        if (setup_peakfile (ret)) {
                                return boost::shared_ptr<Source>();
                        }
@@ -171,6 +170,7 @@ SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFil
                        return ret;
                }
 
+               return boost::shared_ptr<Source>();
        } else if (type == DataType::MIDI) {
 
                boost::shared_ptr<Source> ret (new SMFSource (s, node));
@@ -187,11 +187,11 @@ SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFil
 #else
 
 boost::shared_ptr<Source>
-SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFileSource::Flag flags, bool announce)
+SourceFactory::createReadable (DataType type, Session& s, string path, int chn, AudioFileSource::Flag flags, bool announce)
 {
        if (type == DataType::AUDIO) {
-
-               boost::shared_ptr<Source> ret (new SndFileSource (s, idstr, flags));
+       
+               boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags));
 
                if (setup_peakfile (ret)) {
                        return boost::shared_ptr<Source>();
@@ -203,10 +203,11 @@ SourceFactory::createReadable (DataType type, Session& s, string idstr, AudioFil
 
                return ret;
 
+
        } else if (type == DataType::MIDI) {
 
                // FIXME: flags?
-               boost::shared_ptr<Source> ret (new SMFSource (s, idstr, SMFSource::Flag(0)));
+               boost::shared_ptr<Source> ret (new SMFSource (s, path, SMFSource::Flag(0)));
 
                if (announce) {
                        SourceCreated (ret);
index 1a758b275dfc714aed8066eecaa5e81a1a036a34..c748bbece0dfd2fecf2149303f969557a78c8330 100644 (file)
@@ -21,6 +21,9 @@
 #include <fcntl.h>
 #include <cerrno>
 
+#include <pbd/failed_constructor.h>
+#include <pbd/error.h>
+
 #include <midi++/types.h>
 #include <midi++/alsa_sequencer.h>
 #include <midi++/port_request.h>
 #define TR_VAL(v)
 #endif
 
-
-
-
 using namespace std;
 using namespace MIDI;
+using namespace PBD;
+
+snd_seq_t* ALSA_SequencerMidiPort::seq = 0;
 
 ALSA_SequencerMidiPort::ALSA_SequencerMidiPort (PortRequest &req)
        : Port (req)
-       , seq (0)
        , decoder (0) 
        , encoder (0) 
+       , port_id (-1)
 {
        TR_FN();
        int err;
-       if (0 <= (err = CreatePorts (req)) &&
-           0 <= (err = snd_midi_event_new (1024, &decoder)) && // Length taken from ARDOUR::Session::midi_read ()
-           0 <= (err = snd_midi_event_new (64, &encoder))) {   // Length taken from ARDOUR::Session::mmc_buffer
-               snd_midi_event_init (decoder);
-               snd_midi_event_init (encoder);
-               _ok = true;
-               req.status = PortRequest::OK;
-       } else
-               req.status = PortRequest::Unknown;
+
+       if (!seq && init_client (req.devname) < 0) {
+               _ok = false; 
+
+       } else {
+               
+               if (0 <= (err = CreatePorts (req)) &&
+                   0 <= (err = snd_midi_event_new (1024, &decoder)) && // Length taken from ARDOUR::Session::midi_read ()
+                   0 <= (err = snd_midi_event_new (64, &encoder))) {   // Length taken from ARDOUR::Session::mmc_buffer
+                       snd_midi_event_init (decoder);
+                       snd_midi_event_init (encoder);
+                       _ok = true;
+                       req.status = PortRequest::OK;
+               } else {
+                       req.status = PortRequest::Unknown;
+               }
+       }
 }
 
 ALSA_SequencerMidiPort::~ALSA_SequencerMidiPort ()
 {
-       if (decoder)
+       if (decoder) {
                snd_midi_event_free (decoder);
-       if (encoder)
+       }
+       if (encoder) {
                snd_midi_event_free (encoder);
-       if (seq)
-               snd_seq_close (seq);
+       }
+       if (port_id >= 0) {
+               snd_seq_delete_port (seq, port_id);
+       }
 }
 
-int ALSA_SequencerMidiPort::selectable () const
+int 
+ALSA_SequencerMidiPort::selectable () const
 {
        struct pollfd pfd[1];
        if (0 <= snd_seq_poll_descriptors (seq, pfd, 1, POLLIN | POLLOUT)) {
@@ -118,7 +133,12 @@ int ALSA_SequencerMidiPort::write (byte *msg, size_t msglen, timestamp_t timesta
        return totwritten;
 }
 
+<<<<<<< .working
 int ALSA_SequencerMidiPort::read (byte *buf, size_t max, timestamp_t timestamp)
+=======
+int 
+ALSA_SequencerMidiPort::read (byte *buf, size_t max)
+>>>>>>> .merge-right.r1393
 {
        TR_FN();
        int err;
@@ -142,27 +162,49 @@ int ALSA_SequencerMidiPort::read (byte *buf, size_t max, timestamp_t timestamp)
        return -ENOENT == err ? 0 : err;
 }
 
-int ALSA_SequencerMidiPort::CreatePorts (PortRequest &req)
+int 
+ALSA_SequencerMidiPort::CreatePorts (PortRequest &req)
 {
        int err;
-       if (0 <= (err = snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, 
-                                    (req.mode & O_NONBLOCK) ? SND_SEQ_NONBLOCK : 0))) {
-               snd_seq_set_client_name (seq, req.devname);
-               unsigned int caps = 0;
-               if (req.mode == O_WRONLY  ||  req.mode == O_RDWR)
-                       caps |= SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE;
-               if (req.mode == O_RDONLY  ||  req.mode == O_RDWR)
-                       caps |= SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ;
-               err = snd_seq_create_simple_port (seq, req.tagname, caps, SND_SEQ_PORT_TYPE_MIDI_GENERIC);
-               if (err >= 0) {
-                       port_id = err;
-                       snd_seq_ev_clear (&SEv);
-                       snd_seq_ev_set_source (&SEv, port_id);
-                       snd_seq_ev_set_subs (&SEv);
-                       snd_seq_ev_set_direct (&SEv);
-               } else 
-                       snd_seq_close (seq);
+       unsigned int caps = 0;
+
+       if (req.mode == O_WRONLY  ||  req.mode == O_RDWR)
+               caps |= SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE;
+       if (req.mode == O_RDONLY  ||  req.mode == O_RDWR)
+               caps |= SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ;
+       
+       if (0 <= (err = snd_seq_create_simple_port (seq, req.tagname, caps, SND_SEQ_PORT_TYPE_MIDI_GENERIC))) {
+               
+               port_id = err;
+
+               snd_seq_ev_clear (&SEv);
+               snd_seq_ev_set_source (&SEv, port_id);
+               snd_seq_ev_set_subs (&SEv);
+               snd_seq_ev_set_direct (&SEv);
+               
+               return 0;
        }
+
        return err;
 }
 
+int
+ALSA_SequencerMidiPort::init_client (std::string name)
+{
+       static bool called = false;
+
+       if (called) {
+               return -1;
+       }
+
+       called = true;
+
+       if (snd_seq_open (&seq, "default", SND_SEQ_OPEN_DUPLEX, 0) >= 0) {
+               snd_seq_set_client_name (seq, name.c_str());
+               return 0;
+       } else {
+               warning << "The ALSA MIDI system is not available. No ports based on it will be created"
+                       << endmsg;
+               return -1;
+       }
+}
index cb02ed961c0ad1df9f471fe5ad1f1709747f2ee4..a4b4ba856f161b37826d1999c9fa4e0a2e443e1f 100644 (file)
@@ -48,12 +48,14 @@ class ALSA_SequencerMidiPort : public Port
        int read (byte *buf, size_t max, timestamp_t timestamp);
 
   private:
-       snd_seq_t *seq;
        snd_midi_event_t *decoder, *encoder;
        int port_id;
        snd_seq_event_t SEv;
+
        int CreatePorts(PortRequest &req);
 
+       static int init_client (std::string name);
+       static snd_seq_t* seq;
 };
 
 }; /* namespace MIDI */
index a719fb169f2af983150620c8f56da841a036a2b3..9568c1781c694de71d4a0720990c235346c88254 100644 (file)
@@ -9,7 +9,7 @@ strip_whitespace_edges (string& str)
 {   
     string::size_type i; 
     string::size_type len;    
-    string::size_type s;
+    string::size_type s = 0;
                                    
     len = str.length();
 
index cddf78e774c9fb4e8f69302726960290069c24fa..abd97e056583743ddaf42c6badd9230c9ef6a630 100644 (file)
@@ -1,4 +1,4 @@
 #ifndef __ardour_svn_revision_h__
 #define __ardour_svn_revision_h__
-static const char* ardour_svn_revision = "1266";
+static const char* ardour_svn_revision = "1345";
 #endif
diff --git a/tools/ARDOUR/SourceInfoLoader.pm b/tools/ARDOUR/SourceInfoLoader.pm
new file mode 100644 (file)
index 0000000..ec327d9
--- /dev/null
@@ -0,0 +1,75 @@
+package ARDOUR::SourceInfoLoader;
+
+
+use XML::Handler::Subs;
+
+@ISA = qw( XML::Handler::Subs );
+
+$VERSION = 1.0;
+
+
+sub new {
+       my ($type, $sessionName) = @_;
+
+       my $self = $type->SUPER::new();
+       
+       $self->{SessionName} = $sessionName;
+       $self->{InRegions} = 0;
+       %self->{Sources} = {};
+
+       
+       return $self;
+}
+
+sub start_element {
+       my $self = shift;
+       my $element = shift;
+
+       my $atts = $element->{Attributes};
+
+       if ( $element->{Name} eq "Source") {
+               if ( ! -f "interchange/".$sessionName."/audiofiles/".$atts->{name}) {
+                       $atts->{calculated_length} = 1;
+                       $self->{Sources}->{$atts->{id}} = $atts;
+               }
+       }
+
+       
+       if ( $self->{InRegions} eq 1 && $element->{Name} eq "Region") {
+               #print "Looking at region ".$atts->{id}."\n";
+               my $num = 0;
+
+               my $region_length = $atts->{length};
+               while ( $atts->{"source-".$num} ne "" ) {
+
+                       if ($region_length > $self->{Sources}->{$atts->{"source-".$num}}->{calculated_length} ) {
+                               $self->{Sources}->{$atts->{"source-".$num}}->{calculated_length} = $region_length;
+                       }
+
+                       $num++;
+               }
+       }
+
+       if ( $element->{Name} eq "Regions") {
+               $self->{InRegions} = 1;
+               #print "In regions\n";
+       }
+
+
+}
+
+sub end_element {
+       my $self = shift;
+       my $element = shift;
+
+       if ( $element->{Name} eq "Regions") {
+               $self->{InRegions} = 0;
+               #print "Out of regions\n";
+       }
+
+}
+
+1;
+
+
+
diff --git a/tools/Spotlight Importer/English.lproj/InfoPlist.strings b/tools/Spotlight Importer/English.lproj/InfoPlist.strings
new file mode 100644 (file)
index 0000000..cafcc33
Binary files /dev/null and b/tools/Spotlight Importer/English.lproj/InfoPlist.strings differ
diff --git a/tools/Spotlight Importer/English.lproj/schema.strings b/tools/Spotlight Importer/English.lproj/schema.strings
new file mode 100644 (file)
index 0000000..1577efd
Binary files /dev/null and b/tools/Spotlight Importer/English.lproj/schema.strings differ
diff --git a/tools/Spotlight Importer/GetMetadataForFile.c b/tools/Spotlight Importer/GetMetadataForFile.c
new file mode 100644 (file)
index 0000000..6b12614
--- /dev/null
@@ -0,0 +1,56 @@
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreServices/CoreServices.h> 
+
+/* -----------------------------------------------------------------------------
+   Step 1
+   Set the UTI types the importer supports
+  
+   Modify the CFBundleDocumentTypes entry in Info.plist to contain
+   an array of Uniform Type Identifiers (UTI) for the LSItemContentTypes 
+   that your importer can handle
+  
+   ----------------------------------------------------------------------------- */
+
+/* -----------------------------------------------------------------------------
+   Step 2 
+   Implement the GetMetadataForFile function
+  
+   Implement the GetMetadataForFile function below to scrape the relevant
+   metadata from your document and return it as a CFDictionary using standard keys
+   (defined in MDItem.h) whenever possible.
+   ----------------------------------------------------------------------------- */
+
+/* -----------------------------------------------------------------------------
+   Step 3 (optional) 
+   If you have defined new attributes, update the schema.xml file
+  
+   Edit the schema.xml file to include the metadata keys that your importer returns.
+   Add them to the <allattrs> and <displayattrs> elements.
+  
+   Add any custom types that your importer requires to the <attributes> element
+  
+   <attribute name="com_mycompany_metadatakey" type="CFString" multivalued="true"/>
+  
+   ----------------------------------------------------------------------------- */
+
+
+
+/* -----------------------------------------------------------------------------
+    Get metadata attributes from file
+   
+   This function's job is to extract useful information your file format supports
+   and return it as a dictionary
+   ----------------------------------------------------------------------------- */
+
+Boolean GetMetadataForFile(void* thisInterface, 
+                          CFMutableDictionaryRef attributes, 
+                          CFStringRef contentTypeUTI,
+                          CFStringRef pathToFile)
+{
+    /* Pull any available metadata from the file at the specified path */
+    /* Return the attribute keys and attribute values in the dict */
+    /* Return TRUE if successful, FALSE if there was no data provided */
+    
+    #warning To complete your importer please implement the function GetMetadataForFile in GetMetadataForFile.c
+    return FALSE;
+}
diff --git a/tools/Spotlight Importer/Info.plist b/tools/Spotlight Importer/Info.plist
new file mode 100644 (file)
index 0000000..da11c8d
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+
+       <!--
+       If your application does not already define a UTI, you may want to declare it
+       here, so that your documents are recognized by systems which do not have your
+       application installed.
+
+       To export this declaration, fill in the fields with your application's 
+       information, and uncomment the block of XML.
+       -->
+       
+       <!--
+       <key>UTExportedTypeDeclarations</key>
+       <array>
+               <dict>
+                       <key>UTTypeIdentifier</key>
+                       <string>org.ardour.yourUTI</string>
+                       <key>UTTypeReferenceURL</key>
+                       <string>http://www.ardour.org</string>
+                       <key>UTTypeDescription</key>
+                       <string>Your Document Kind String</string>
+                       <key>UTTypeConformsTo</key>
+                       <array>
+                               <string>public.data</string>
+                               <string>public.content</string>
+                       </array>
+                       <key>UTTypeTagSpecification</key>
+                       <dict>
+                               <key>com.apple.ostype</key>
+                               <string>XXXX</string>
+                               <key>public.filename-extension</key>
+                               <array>
+                                       <string>xxxx</string>
+                               </array>
+                       </dict>
+               </dict>
+       </array>
+       -->
+
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleDocumentTypes</key>
+       <array>
+               <dict>
+                       <key>CFBundleTypeRole</key>
+                       <string>MDImporter</string>
+                       <key>LSItemContentTypes</key>
+                       <array>
+                               <string>SUPPORTED_UTI_TYPE</string>
+                       </array>
+               </dict>
+       </array>
+       <key>CFBundleExecutable</key>
+       <string>${EXECUTABLE_NAME}</string>
+       <key>CFBundleName</key>
+       <string>${PRODUCT_NAME}</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>com.apple.yourcfbundle</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleVersion</key>
+       <string>1.0</string>
+       <key>CFPlugInDynamicRegisterFunction</key>
+       <string></string>
+       <key>CFPlugInDynamicRegistration</key>
+       <string>NO</string>
+       <key>CFPlugInFactories</key>
+       <dict>
+               <key>D77F8126-18F0-4ADE-917C-4A234A5590B9</key>
+               <string>MetadataImporterPluginFactory</string>
+       </dict>
+       <key>CFPlugInTypes</key>
+       <dict>
+               <key>8B08C4BF-415B-11D8-B3F9-0003936726FC</key>
+               <array>
+                       <string>D77F8126-18F0-4ADE-917C-4A234A5590B9</string>
+               </array>
+       </dict>
+       <key>CFPlugInUnloadFunction</key>
+       <string></string>
+</dict>
+</plist>
diff --git a/tools/Spotlight Importer/Spotlight Importer.xcodeproj/project.pbxproj b/tools/Spotlight Importer/Spotlight Importer.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..39ee943
--- /dev/null
@@ -0,0 +1,275 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 42;
+       objects = {
+
+/* Begin PBXBuildFile section */
+               2C05A19C06CAA52B00D84F6F /* GetMetadataForFile.c in Sources */ = {isa = PBXBuildFile; fileRef = 2C05A19B06CAA52B00D84F6F /* GetMetadataForFile.c */; };
+               8D576312048677EA00EA77CD /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 08FB77B6FE84183AC02AAC07 /* main.c */; settings = {ATTRIBUTES = (); }; };
+               8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */; };
+               8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8D5B49A704867FD3000E48DA /* InfoPlist.strings */; };
+               C86B05270671AA6E00DD9006 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C86B05260671AA6E00DD9006 /* CoreServices.framework */; };
+               C88FB7D8067446EC006EBB30 /* schema.xml in Resources */ = {isa = PBXBuildFile; fileRef = C88FB7D7067446EC006EBB30 /* schema.xml */; };
+               C88FB7E40674480E006EBB30 /* schema.strings in Resources */ = {isa = PBXBuildFile; fileRef = C88FB7E30674480E006EBB30 /* schema.strings */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+               089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+               08FB77B6FE84183AC02AAC07 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = "<group>"; };
+               0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
+               2C05A19B06CAA52B00D84F6F /* GetMetadataForFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = GetMetadataForFile.c; sourceTree = "<group>"; };
+               8D576316048677EA00EA77CD /* Spotlight Importer.mdimporter */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Spotlight Importer.mdimporter"; sourceTree = BUILT_PRODUCTS_DIR; };
+               8D576317048677EA00EA77CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
+               C86B05260671AA6E00DD9006 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
+               C88FB7D7067446EC006EBB30 /* schema.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = schema.xml; sourceTree = "<group>"; };
+               C88FB7DB0674470F006EBB30 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/schema.strings; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               8D576313048677EA00EA77CD /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               8D576314048677EA00EA77CD /* CoreFoundation.framework in Frameworks */,
+                               C86B05270671AA6E00DD9006 /* CoreServices.framework in Frameworks */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               089C166AFE841209C02AAC07 /* Spotlight Importer */ = {
+                       isa = PBXGroup;
+                       children = (
+                               08FB77AFFE84173DC02AAC07 /* Source */,
+                               089C167CFE841241C02AAC07 /* Resources */,
+                               089C1671FE841209C02AAC07 /* External Frameworks and Libraries */,
+                               19C28FB6FE9D52B211CA2CBB /* Products */,
+                       );
+                       name = "Spotlight Importer";
+                       sourceTree = "<group>";
+               };
+               089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C86B05260671AA6E00DD9006 /* CoreServices.framework */,
+                               0AA1909FFE8422F4C02AAC07 /* CoreFoundation.framework */,
+                       );
+                       name = "External Frameworks and Libraries";
+                       sourceTree = "<group>";
+               };
+               089C167CFE841241C02AAC07 /* Resources */ = {
+                       isa = PBXGroup;
+                       children = (
+                               C88FB7E30674480E006EBB30 /* schema.strings */,
+                               C88FB7D7067446EC006EBB30 /* schema.xml */,
+                               8D576317048677EA00EA77CD /* Info.plist */,
+                               8D5B49A704867FD3000E48DA /* InfoPlist.strings */,
+                       );
+                       name = Resources;
+                       sourceTree = "<group>";
+               };
+               08FB77AFFE84173DC02AAC07 /* Source */ = {
+                       isa = PBXGroup;
+                       children = (
+                               2C05A19B06CAA52B00D84F6F /* GetMetadataForFile.c */,
+                               08FB77B6FE84183AC02AAC07 /* main.c */,
+                       );
+                       name = Source;
+                       sourceTree = "<group>";
+               };
+               19C28FB6FE9D52B211CA2CBB /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               8D576316048677EA00EA77CD /* Spotlight Importer.mdimporter */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+               8D57630E048677EA00EA77CD /* Headers */ = {
+                       isa = PBXHeadersBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXNativeTarget section */
+               8D57630D048677EA00EA77CD /* Spotlight Importer */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 70138C840896BE9A00968C2F /* Build configuration list for PBXNativeTarget "Spotlight Importer" */;
+                       buildPhases = (
+                               8D57630E048677EA00EA77CD /* Headers */,
+                               8D57630F048677EA00EA77CD /* Resources */,
+                               8D576311048677EA00EA77CD /* Sources */,
+                               8D576313048677EA00EA77CD /* Frameworks */,
+                               8D576315048677EA00EA77CD /* Rez */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = "Spotlight Importer";
+                       productInstallPath = /Library/Spotlight;
+                       productName = "Spotlight Importer";
+                       productReference = 8D576316048677EA00EA77CD /* Spotlight Importer.mdimporter */;
+                       productType = "com.apple.product-type.bundle";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               089C1669FE841209C02AAC07 /* Project object */ = {
+                       isa = PBXProject;
+                       buildConfigurationList = 70138C880896BE9A00968C2F /* Build configuration list for PBXProject "Spotlight Importer" */;
+                       hasScannedForEncodings = 1;
+                       mainGroup = 089C166AFE841209C02AAC07 /* Spotlight Importer */;
+                       projectDirPath = "";
+                       targets = (
+                               8D57630D048677EA00EA77CD /* Spotlight Importer */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+               8D57630F048677EA00EA77CD /* Resources */ = {
+                       isa = PBXResourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */,
+                               C88FB7D8067446EC006EBB30 /* schema.xml in Resources */,
+                               C88FB7E40674480E006EBB30 /* schema.strings in Resources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXRezBuildPhase section */
+               8D576315048677EA00EA77CD /* Rez */ = {
+                       isa = PBXRezBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXRezBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+               8D576311048677EA00EA77CD /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               8D576312048677EA00EA77CD /* main.c in Sources */,
+                               2C05A19C06CAA52B00D84F6F /* GetMetadataForFile.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+               8D5B49A704867FD3000E48DA /* InfoPlist.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               089C167EFE841241C02AAC07 /* English */,
+                       );
+                       name = InfoPlist.strings;
+                       sourceTree = "<group>";
+               };
+               C88FB7E30674480E006EBB30 /* schema.strings */ = {
+                       isa = PBXVariantGroup;
+                       children = (
+                               C88FB7DB0674470F006EBB30 /* English */,
+                       );
+                       name = schema.strings;
+                       sourceTree = "<group>";
+               };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+               70138C850896BE9A00968C2F /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               GCC_PRECOMPILE_PREFIX_HEADER = NO;
+                               INFOPLIST_FILE = Info.plist;
+                               INSTALL_PATH = /Library/Spotlight;
+                               LIBRARY_STYLE = Bundle;
+                               PRODUCT_NAME = "Spotlight Importer";
+                               WRAPPER_EXTENSION = mdimporter;
+                               ZERO_LINK = YES;
+                       };
+                       name = Debug;
+               };
+               70138C860896BE9A00968C2F /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = (
+                                       ppc,
+                                       i386,
+                               );
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
+                               GCC_MODEL_TUNING = G5;
+                               GCC_PRECOMPILE_PREFIX_HEADER = NO;
+                               INFOPLIST_FILE = Info.plist;
+                               INSTALL_PATH = /Library/Spotlight;
+                               LIBRARY_STYLE = Bundle;
+                               PRODUCT_NAME = "Spotlight Importer";
+                               WRAPPER_EXTENSION = mdimporter;
+                       };
+                       name = Release;
+               };
+               70138C890896BE9A00968C2F /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               PREBINDING = NO;
+                               SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+                       };
+                       name = Debug;
+               };
+               70138C8A0896BE9A00968C2F /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               PREBINDING = NO;
+                               SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               70138C840896BE9A00968C2F /* Build configuration list for PBXNativeTarget "Spotlight Importer" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               70138C850896BE9A00968C2F /* Debug */,
+                               70138C860896BE9A00968C2F /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               70138C880896BE9A00968C2F /* Build configuration list for PBXProject "Spotlight Importer" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               70138C890896BE9A00968C2F /* Debug */,
+                               70138C8A0896BE9A00968C2F /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = 089C1669FE841209C02AAC07 /* Project object */;
+}
diff --git a/tools/Spotlight Importer/main.c b/tools/Spotlight Importer/main.c
new file mode 100644 (file)
index 0000000..77a2c02
--- /dev/null
@@ -0,0 +1,225 @@
+//
+//  main.c
+//  Spotlight Importer
+//
+//  Created by Taybin on 1/24/07.
+//  Copyright (c) 2007 Penguin Sounds. All rights reserved.
+//
+
+
+
+
+
+//==============================================================================
+//
+//     DO NO MODIFY THE CONTENT OF THIS FILE
+//
+//     This file contains the generic CFPlug-in code necessary for your importer
+//     To complete your importer implement the function in GetMetadataForFile.c
+//
+//==============================================================================
+
+
+
+
+
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFPlugInCOM.h>
+#include <CoreServices/CoreServices.h>
+
+// -----------------------------------------------------------------------------
+//     constants
+// -----------------------------------------------------------------------------
+
+
+#define PLUGIN_ID "D77F8126-18F0-4ADE-917C-4A234A5590B9"
+
+//
+// Below is the generic glue code for all plug-ins.
+//
+// You should not have to modify this code aside from changing
+// names if you decide to change the names defined in the Info.plist
+//
+
+
+// -----------------------------------------------------------------------------
+//     typedefs
+// -----------------------------------------------------------------------------
+
+// The import function to be implemented in GetMetadataForFile.c
+Boolean GetMetadataForFile(void *thisInterface, 
+                          CFMutableDictionaryRef attributes, 
+                          CFStringRef contentTypeUTI,
+                          CFStringRef pathToFile);
+                          
+// The layout for an instance of MetaDataImporterPlugIn 
+typedef struct __MetadataImporterPluginType
+{
+    MDImporterInterfaceStruct *conduitInterface;
+    CFUUIDRef                 factoryID;
+    UInt32                    refCount;
+} MetadataImporterPluginType;
+
+// -----------------------------------------------------------------------------
+//     prototypes
+// -----------------------------------------------------------------------------
+//     Forward declaration for the IUnknown implementation.
+//
+
+MetadataImporterPluginType  *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID);
+void                      DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance);
+HRESULT                   MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv);
+void                     *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID);
+ULONG                     MetadataImporterPluginAddRef(void *thisInstance);
+ULONG                     MetadataImporterPluginRelease(void *thisInstance);
+// -----------------------------------------------------------------------------
+//     testInterfaceFtbl       definition
+// -----------------------------------------------------------------------------
+//     The TestInterface function table.
+//
+
+static MDImporterInterfaceStruct testInterfaceFtbl = {
+    NULL,
+    MetadataImporterQueryInterface,
+    MetadataImporterPluginAddRef,
+    MetadataImporterPluginRelease,
+    GetMetadataForFile
+};
+
+
+// -----------------------------------------------------------------------------
+//     AllocMetadataImporterPluginType
+// -----------------------------------------------------------------------------
+//     Utility function that allocates a new instance.
+//      You can do some initial setup for the importer here if you wish
+//      like allocating globals etc...
+//
+MetadataImporterPluginType *AllocMetadataImporterPluginType(CFUUIDRef inFactoryID)
+{
+    MetadataImporterPluginType *theNewInstance;
+
+    theNewInstance = (MetadataImporterPluginType *)malloc(sizeof(MetadataImporterPluginType));
+    memset(theNewInstance,0,sizeof(MetadataImporterPluginType));
+
+        /* Point to the function table */
+    theNewInstance->conduitInterface = &testInterfaceFtbl;
+
+        /*  Retain and keep an open instance refcount for each factory. */
+    theNewInstance->factoryID = CFRetain(inFactoryID);
+    CFPlugInAddInstanceForFactory(inFactoryID);
+
+        /* This function returns the IUnknown interface so set the refCount to one. */
+    theNewInstance->refCount = 1;
+    return theNewInstance;
+}
+
+// -----------------------------------------------------------------------------
+//     DeallocSpotlight_ImporterMDImporterPluginType
+// -----------------------------------------------------------------------------
+//     Utility function that deallocates the instance when
+//     the refCount goes to zero.
+//      In the current implementation importer interfaces are never deallocated
+//      but implement this as this might change in the future
+//
+void DeallocMetadataImporterPluginType(MetadataImporterPluginType *thisInstance)
+{
+    CFUUIDRef theFactoryID;
+
+    theFactoryID = thisInstance->factoryID;
+    free(thisInstance);
+    if (theFactoryID){
+        CFPlugInRemoveInstanceForFactory(theFactoryID);
+        CFRelease(theFactoryID);
+    }
+}
+
+// -----------------------------------------------------------------------------
+//     MetadataImporterQueryInterface
+// -----------------------------------------------------------------------------
+//     Implementation of the IUnknown QueryInterface function.
+//
+HRESULT MetadataImporterQueryInterface(void *thisInstance,REFIID iid,LPVOID *ppv)
+{
+    CFUUIDRef interfaceID;
+
+    interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault,iid);
+
+    if (CFEqual(interfaceID,kMDImporterInterfaceID)){
+            /* If the Right interface was requested, bump the ref count,
+             * set the ppv parameter equal to the instance, and
+             * return good status.
+             */
+        ((MetadataImporterPluginType*)thisInstance)->conduitInterface->AddRef(thisInstance);
+        *ppv = thisInstance;
+        CFRelease(interfaceID);
+        return S_OK;
+    }else{
+        if (CFEqual(interfaceID,IUnknownUUID)){
+                /* If the IUnknown interface was requested, same as above. */
+            ((MetadataImporterPluginType*)thisInstance )->conduitInterface->AddRef(thisInstance);
+            *ppv = thisInstance;
+            CFRelease(interfaceID);
+            return S_OK;
+        }else{
+                /* Requested interface unknown, bail with error. */
+            *ppv = NULL;
+            CFRelease(interfaceID);
+            return E_NOINTERFACE;
+        }
+    }
+}
+
+// -----------------------------------------------------------------------------
+//     MetadataImporterPluginAddRef
+// -----------------------------------------------------------------------------
+//     Implementation of reference counting for this type. Whenever an interface
+//     is requested, bump the refCount for the instance. NOTE: returning the
+//     refcount is a convention but is not required so don't rely on it.
+//
+ULONG MetadataImporterPluginAddRef(void *thisInstance)
+{
+    ((MetadataImporterPluginType *)thisInstance )->refCount += 1;
+    return ((MetadataImporterPluginType*) thisInstance)->refCount;
+}
+
+// -----------------------------------------------------------------------------
+// SampleCMPluginRelease
+// -----------------------------------------------------------------------------
+//     When an interface is released, decrement the refCount.
+//     If the refCount goes to zero, deallocate the instance.
+//
+ULONG MetadataImporterPluginRelease(void *thisInstance)
+{
+    ((MetadataImporterPluginType*)thisInstance)->refCount -= 1;
+    if (((MetadataImporterPluginType*)thisInstance)->refCount == 0){
+        DeallocMetadataImporterPluginType((MetadataImporterPluginType*)thisInstance );
+        return 0;
+    }else{
+        return ((MetadataImporterPluginType*) thisInstance )->refCount;
+    }
+}
+
+// -----------------------------------------------------------------------------
+//     Spotlight_ImporterMDImporterPluginFactory
+// -----------------------------------------------------------------------------
+//     Implementation of the factory function for this type.
+//
+void *MetadataImporterPluginFactory(CFAllocatorRef allocator,CFUUIDRef typeID)
+{
+    MetadataImporterPluginType *result;
+    CFUUIDRef                 uuid;
+
+        /* If correct type is being requested, allocate an
+         * instance of TestType and return the IUnknown interface.
+         */
+    if (CFEqual(typeID,kMDImporterTypeID)){
+        uuid = CFUUIDCreateFromString(kCFAllocatorDefault,CFSTR(PLUGIN_ID));
+        result = AllocMetadataImporterPluginType(uuid);
+        CFRelease(uuid);
+        return result;
+    }
+        /* If the requested type is incorrect, return NULL. */
+    return NULL;
+}
+
diff --git a/tools/Spotlight Importer/schema.xml b/tools/Spotlight Importer/schema.xml
new file mode 100644 (file)
index 0000000..2b4099b
--- /dev/null
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schema version="1.0" xmlns="http://www.apple.com/metadata"
+                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+                      xsi:schemaLocation="http://www.apple.com/metadata file:///System/Library/Frameworks/CoreServices.framework/Frameworks/Metadata.framework/Resources/MetadataSchema.xsd">
+    <note>
+        Custom attributes that this metadata importer supports.  Below
+       is an example of a multivalued string attribute.  Other types
+       are CFNumber, CFDate, CFBoolean and CFData.                   
+    </note>
+    <attributes>
+        <attribute name="com_Foo_YourAttrName" multivalued="true" type="CFString"/>
+    </attributes>
+
+    <types>
+        <type name="SUPPORTED_UTI_TYPE">
+            <note>
+               The keys that this metadata importer handles.
+            </note>
+            <allattrs>
+           com_Foo_YourAttrName
+            </allattrs>
+            <displayattrs>
+           com_Foo_YourAttrName
+            </displayattrs>
+        </type>
+    </types>
+</schema>
+
index 4cab63503497e6b4c65896cabc378d69b20d345b..48d3837368089f6eff253f1a077466bf94469d29 100755 (executable)
@@ -3,7 +3,7 @@
 # Ruby script for pulling together a MacOSX app bundle.
 
 # it will be either powerpc or i386
-versionline = `grep -m 1 '^version =' ../../SConstruct`
+versionline = `grep -m 1 '^ardour_version =' ../../SConstruct`
 version = versionline.split(" = ")[1].chomp().slice(1..-2)
 $stdout.printf("Version is %s\n", version)
 
@@ -57,7 +57,7 @@ end
 odir = Dir.getwd
 Dir.chdir("../..")
 
-result = `otool -L gtk2_ardour/ardour.bin`
+result = `otool -L gtk2_ardour/ardour-#{version}`
 results = result.split("\n")
 results.delete_at(0)
 
@@ -101,12 +101,12 @@ end
 
 Dir.chdir(odir)
 
-# copy ardour.bin to bindir/ardour
+# copy ardour binary to bindir/ardour
 
 
-if File.exist?("../../gtk2_ardour/ardour.bin") then
+if File.exist?("../../gtk2_ardour/ardour-#{version}") then
    $stdout.print("Copying bin to #{bindir} ...\n");
-   `cp ../../gtk2_ardour/ardour.bin #{bindir}/ardour`
+   `cp ../../gtk2_ardour/ardour-#{version} #{bindir}/ardour`
 end
 
 `cp ../../libs/surfaces/*/*.dylib #{libdir}/surfaces`
index ad456c305f9b395121e40c65858c2a190ec65e25..e01f2eb3574b099c0ef4768d8720c1fbb205f946 100644 (file)
@@ -323,6 +323,17 @@ style "ardour_adjusters" = "default_buttons_menus"
        bg[ACTIVE] = { 0.06, 0.06, 0.06 }
 }
 
+style "editor_hscrollbar" = "ardour_adjusters"
+{
+       #
+       # special case: we want this scrollbar to be as tall as the
+       # zoom focus selector combobox. scrollbars don't expand to
+        # fill the space available to them, so we have to explicitly
+       # make it bigger.
+       # 
+       GtkRange::slider_width = 27
+}
+
 style "ardour_progressbars" = "default_buttons_menus"
 { 
   bg[NORMAL] = { 0, 0, 0 }
@@ -658,27 +669,44 @@ style "edit_group_3"
        bg[SELECTED] = { 0.93, 0.34, 0.08 }
 }
 
-style "region_list_display" = "small_bold_text"
+style "treeview_parent_node"
 {
-       fg[NORMAL] = { 0.80, 0.80, 0.80 }
-       fg[ACTIVE] = { 0.80, 0.80, 0.80 }
-       fg[SELECTED] = { 0.70, 0.70, 0.70 }
-       bg[NORMAL] = { 0, 0, 0 }
-       bg[ACTIVE] = { 0, 0, 0 }
-       bg[SELECTED] = { 0, 0, 0 }
-       base[NORMAL] = { 0, 0, 0 }
-       base[ACTIVE] = { 0, 1, 0 }
-       base[INSENSITIVE] = { 0, 0, 0 }
-       base[SELECTED] = { 0.80, 0.80, 0.80 }
+       # specifies *just* the color used for whole file rows when not selected
+       fg[NORMAL] = { 0.0, 0.6, 0.85 }
+}
+
+style "treeview_display" = "small_bold_text"
+{
+       # expander arrow border and DnD "icon" text
+       fg[NORMAL] = { 0.8, 0.8, 0.8 } 
+
+       # background with no rows or no selection, plus
+       # expander arrow core and DnD "icon" background
+       base[NORMAL] = { 0.20, 0.20, 0.25 }
+
+       # selected row bg when window does not have focus (including during DnD)
+       base[ACTIVE] = { 0.0, 0.60, 0.60 }    
+
+       # selected row bg when window has focus
+       base[SELECTED] = { 0, 0.75, 0.75 }
+
+       # row text when in normal state and not a parent
+       text[NORMAL] = { 0.80, 0.80, 0.80 }
+
+       # selected row text with window focus
+       text[SELECTED] = { 0, 1.0, 1.0 }  
+
+       # selected row text without window focus (including during DnD)
+       text[ACTIVE] = { 0, 1.0, 1.0 }  
 }
 
 style "main_canvas_area"
 {
-       bg[NORMAL] = { 0.20, 0.20, 0.25 }
-       bg[ACTIVE] = { 0.20, 0.20, 0.25 }
-       bg[INSENSITIVE] = { 0.20, 0.20, 0.25 }
-       bg[SELECTED] = { 0.20, 0.20, 0.25 }
-       bg[PRELIGHT] = { 0.20, 0.20, 0.25 }
+       bg[NORMAL] = { 0.30, 0.30, 0.34 }
+       bg[ACTIVE] = { 0.30, 0.30, 0.34 }
+       bg[INSENSITIVE] = { 0.30, 0.30, 0.34 }
+       bg[SELECTED] = { 0.30, 0.30, 0.34 }
+       bg[PRELIGHT] = { 0.30, 0.30, 0.34 }
 }
 
 style "track_controls_inactive"
@@ -955,13 +983,13 @@ style "pan_slider"
 
        fg[NORMAL] = { 0.22, 0.73, 0.22 }
        fg[ACTIVE] = { 0.22, 0.73, 0.22 }
-       fg[INSENSITIVE] = {0.22, 0.53, 0.22 }
+       fg[INSENSITIVE] = {0.22, 0.53, 0.22 } 
        fg[SELECTED] = { 0.67, 0.23, 0.22 }
        fg[PRELIGHT] = { 0.67, 0.23, 0.22 }
 
        bg[NORMAL] = { 0.05, 0.05, 0.05 }
        bg[ACTIVE] = { 0, 0, 0 }
-       bg[INSENSITIVE] = {0.12, 0.19, 0.25 }
+       bg[INSENSITIVE] = {0.12, 0.19, 0.25 } 
        bg[SELECTED] = { 0, 0, 0 }
        bg[PRELIGHT] = { 0, 0, 0 }
 
@@ -975,17 +1003,12 @@ style "pan_slider"
 
        base[NORMAL] = { 0.80, 0.80, 0.80 }
        base[ACTIVE] =  { 0.80, 0.80, 0.80 }
-       base[INSENSITIVE] = {0.32, 0.39, 0.45 } # matches default_base
+       base[INSENSITIVE] = {0.6, 0.6, 0.6 }
        base[SELECTED] = { 0.80, 0.80, 0.80 }
        base[PRELIGHT] = { 0.80, 0.80, 0.80 }
 
 }
 
-style "region_list_whole_file"
-{
-       fg[NORMAL] = { 0.4, 0.4, 0.9 }
-}
-
 style "ardour_button" ="default_buttons_menus"
 {
        xthickness = 1
@@ -1162,7 +1185,6 @@ widget "*EditorTrackNameDisplay" style "track_name_display"
 widget "*EditorTrackNameDisplay*" style "track_name_display"
 widget "*EditorActiveTrackNameDisplay" style "active_track_name_display"
 widget "*EditorActiveTrackNameDisplay*" style "active_track_name_display"
-widget "*EditorRegionList" style "region_list_display"
 widget "*CrossfadeEditAuditionButton" style "red_when_active"
 widget "*CrossfadeEditAuditionButton*" style "red_when_active"
 widget "*CrossfadeEditCurveButton" style "red_when_active"
@@ -1197,19 +1219,19 @@ widget "*ParameterValueDisplay" style "medium_bold_entry"
 widget "*PluginUIClickBox" style "medium_bold_entry"
 widget "*PluginUIClickBox*" style "medium_bold_entry"
 widget "*PluginSlider" style "plugin_slider"
-widget "*TrackListDisplay" style "track_list_display"
-widget "*TrackListDisplay.*" style "small_bold_text"
-widget "*EditGroupList" style "track_list_display"
-widget "*RegionListDisplay" style "small_bold_entry"
-widget "*RegionListDisplay.*" style "small_bold_text"
 widget "*RedirectSelector" style "redirect_list_display"
 widget "*RedirectSelector.*" style "redirect_list_display"
+widget "*EditGroupDisplay" style "treeview_display"
+widget "*TrackListDisplay" style "treeview_display"
+widget "*RegionListDisplay" style "treeview_display"
+widget "*NamedSelectionDisplay" style "treeview_display"
+widget "*SnapshotDisplay" style "treeview_display"
 widget "*MixerTrackCommentArea" style "option_entry"
 widget "*MixerPanZone" style "pan_zone"
-widget "*MixerTrackDisplayList" style "track_list_display"
-widget "*MixerSnapshotDisplayList" style "track_list_display"
-widget "*MixerAuxDisplayList" style "track_list_display"
-widget "*MixerGroupList" style "track_list_display"
+widget "*MixerTrackDisplayList" style "treeview_display"
+widget "*MixerSnapshotDisplayList" style "treeview_display"
+widget "*MixerAuxDisplayList" style "treeview_display"
+widget "*MixerGroupList" style "treeview_display"
 widget "*RegionEditorLabel" style "medium_text"
 widget "*RegionEditorSmallLabel" style "small_text"
 widget "*RegionEditorEntry" style "medium_entry"
@@ -1336,7 +1358,8 @@ widget "*PanningLinkDirectionButton" style "very_small_button"
 widget "*PanningLinkDirectionButton.*" style "very_small_button"
 widget "*ChannelCountSelector" style "medium_bold_entry"
 widget "*ChannelCountSelector.GtkArrow" style "default_buttons_menus"
-widget "*RegionListWholeFile" style "region_list_whole_file"
+widget "*RegionListWholeFile" style "treeview_parent_node"
+widget "*EditorHScrollbar" style "editor_hscrollbar"
 
 class "GtkWidget" style "default_base"
 class "GtkScrollbar" style "ardour_adjusters"
diff --git a/tools/session_exchange.py b/tools/session_exchange.py
new file mode 100755 (executable)
index 0000000..825476c
--- /dev/null
@@ -0,0 +1,856 @@
+#! /usr/bin/python
+
+# Session Exchange
+# By Taybin Rutkin
+# Copyright 2004-2005, under the GPL
+
+VERSION='0.1.2'
+
+#twisted libraries
+from twisted.internet import gtk2reactor
+gtk2reactor.install()
+from twisted.internet import reactor, protocol
+import twisted.internet.error
+
+#pygtk libraries
+import gobject
+import gtk
+
+#standard python2.2 libraries
+import getopt
+import os
+import os.path
+import re
+import shelve
+import string
+import sys
+import xml.dom.minidom
+
+def get_header_size(filename):
+       size = 0
+       file = open(filename, 'r')
+       while True:
+               chunk = file.read(4)
+               size += 4
+               if chunk == "data":
+                       file.close()
+                       return size + 4 #include the size chunk after "data"
+               if not chunk:
+                       file.close()
+                       return None
+
+def append_empty_data(self, filename, size):
+       file = open(filename, 'a')
+       file.seek(size-1)
+       file.write('\x00')
+       file.close()
+       
+def get_sound_list(snapshot):
+       doc = xml.dom.minidom.parse(snapshot)
+       
+       regionlist = []
+       playlists_tag = doc.getElementsByTagName('Playlists')
+       playlists = playlists_tag[0].getElementsByTagName('Playlist')
+       for play in playlists:
+               regions = play.getElementsByTagName('Region')
+               for region in regions:
+                       regionlist.append(region.getAttribute('source-0'))
+                       regionlist.append(region.getAttribute('source-1'))
+                       regionlist.append(region.getAttribute('source-2'))
+                       regionlist.append(region.getAttribute('source-3'))
+                       regionlist.append(region.getAttribute('source-4'))
+                       regionlist.append(region.getAttribute('source-5'))
+       
+       sourcelist = {}
+       sources = doc.getElementsByTagName('Source')
+       for source in sources:
+               sourcelist[source.getAttribute('id')] = str(source.getAttribute('name'))
+
+       soundlist = []
+       for id in regionlist:
+               if sourcelist.has_key(id):
+                       soundlist.append(sourcelist[id])
+       
+       return soundlist
+
+def raise_error(string, parent):
+       dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+       gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, string)
+       
+       dialog.run()
+       dialog.destroy()
+
+class Data(object):
+       def delete_snap(self, session, collab, snap):
+               sessions = self._data['sessions']
+               sessions[session]['collabs'][collab]['snaps'].remove(snap)
+               self._data['sessions'] = sessions
+       
+       def delete_collab(self,session, collab):
+               sessions = self._data['sessions']
+               del sessions[session]['collabs'][collab]
+               self._data['sessions'] = sessions
+       
+       def delete_session(self, session):
+               sessions = self._data['sessions']
+               del sessions[session]
+               self._data['sessions'] = sessions
+       
+       def add_snap(self, session_name, collab_name, snap_name):
+               sessions = self._data['sessions']
+               sessions[session_name]['collabs'][collab_name]['snaps'].append(snap_name)
+               sessions[session_name]['collabs'][collab_name]['snaps'].sort()
+               self._data['sessions'] = sessions
+               
+               g_display.update_snap_view()
+       
+       def add_collab(self, session_name, collab_name, ip_address, port):
+               sessions = self._data['sessions']
+               sessions[session_name]['collabs'][collab_name] = {}
+               sessions[session_name]['collabs'][collab_name]['snaps'] = []
+               sessions[session_name]['collabs'][collab_name]['sounds'] = []
+               sessions[session_name]['collabs'][collab_name]['ip'] = ip_address
+               sessions[session_name]['collabs'][collab_name]['port'] = port
+               self._data['sessions'] = sessions
+               
+               client = ExchangeClientFactory(session_name, collab_name, None, self.debug_mode)
+               reactor.connectTCP(ip_address, port, client)
+               g_display.show_status("connecting")
+               
+               g_display.update_collab_view()
+       
+       def add_session(self, session_path):
+               sessions = self._data['sessions']
+               
+               session_name = session_path[session_path.rfind('/', 0, len(session_path)-2)+1: -1]
+               sessions[session_name] = {}
+               sessions[session_name]['path'] = session_path 
+               sessions[session_name]['collabs'] = {}
+               sessions[session_name]['collabs'][self._data['user']] = {}
+               sessions[session_name]['collabs'][self._data['user']]['snaps'] = []
+               sessions[session_name]['collabs'][self._data['user']]['sounds'] = []
+               
+               self._data['sessions'] = sessions
+               
+               self.rescan_session(session_name)
+
+       def rescan_session(self, session_name):
+               sessions = self._data['sessions']
+               
+               session_path = sessions[session_name]['path']
+               sessions[session_name]['collabs'][self._data['user']]['snaps'] = self._scan_snapshots(session_path)
+               sessions[session_name]['collabs'][self._data['user']]['sounds'] = self._scan_sounds(session_path)
+               
+               self._data['sessions'] = sessions
+               
+               g_display.update_snap_view()
+               
+               print self._data['sessions']
+       
+       def create_session(self, session_path):
+               try:
+                       os.mkdir(session_path)
+                       os.mkdir(session_path+"/sounds")
+               except OSError:
+                       raise_error("Could not create session directory", g_display.window)
+                       return
+               
+               sessions = self._data['sessions']
+               
+               session_name = session_path[session_path.rfind('/', 0, len(session_path)-2)+1: ]
+               sessions[session_name] = {}
+               sessions[session_name]['path'] = session_path
+               sessions[session_name]['collabs'] = {}
+               sessions[session_name]['collabs'][self._data['user']] = {}
+               sessions[session_name]['collabs'][self._data['user']]['snaps'] = []
+               sessions[session_name]['collabs'][self._data['user']]['sounds'] = []
+               
+               self._data['sessions'] = sessions
+               print self._data['sessions']
+       
+       def get_session_path(self, session):
+               sessions = self._data['sessions']
+               return sessions[session]['path']
+       
+       def get_user(self):
+               return self._data['user']
+       
+       def set_user(self, username):
+               self._data['user'] = username
+       
+       def get_collab_ip(self, session, collab):
+               sessions = self._data['sessions']
+               return sessions[session]['collabs'][collab]['ip']
+       
+       def close(self):
+               self._data.close()
+       
+       def get_sessions(self):
+               sessions = self._data['sessions']
+               sess = sessions.keys()
+               sess.sort()
+               return sess
+       
+       def get_collabs(self, session):
+               if session:
+                       sessions = self._data['sessions']
+                       collabs = sessions[session]['collabs'].keys()
+                       collabs.sort()
+                       return collabs
+               else:
+                       return []
+       
+       def get_snaps(self, session, collab):
+               if session and collab:
+                       sessions = self._data['sessions']
+                       snaps = sessions[session]['collabs'][collab]['snaps']
+                       snaps.sort()
+                       return snaps
+               else:
+                       return []
+       
+       def get_sounds(self, session, collab):
+               if session and collab:
+                       sessions = self._data['sessions']
+                       sounds = sessions[session]['collabs'][self._data['user']]['sounds']
+                       sounds.sort()
+                       return sounds
+               else:
+                       return []
+               
+       def _scan_snapshots(self, session):
+               snaps = []
+               files = os.listdir(session)
+               pattern = re.compile(r'\.ardour$')
+               for file in files:
+                       if pattern.search(file):
+                               snaps.append(file[0:-7])
+                               print file[0:-7]
+               return snaps
+       
+       def _scan_sounds(self, session):
+               sounds = []
+               files = os.listdir(session+'/sounds')
+               pattern = re.compile(r'\.peak$')
+               for file in files:
+                       if not pattern.search(file):
+                               sounds.append(file)
+               return sounds
+       
+       def __init__(self, *args):
+               self._data = shelve.open(os.path.expanduser('~/.session_exchange'), 'c')
+               self.port = 8970
+               self.debug_mode = False
+               if len(self._data.keys()) < 1:
+                       self._data['sessions'] = {}
+                       self._data['user'] = ''
+               
+               self._collabs = {}
+
+from twisted.protocols.basic import FileSender
+class FileSenderLimited(FileSender):
+       def beginFileTransfer(self, file, consumer, limit, transform = None):
+               self.file = file
+               self.consumer = consumer
+               self.CHUNK_SIZE = limit
+               self.transform = transform
+               
+               self.consumer.registerProducer(self, False)
+               self.deferred = defer.Deferred()
+               return self.deferred
+       
+       def resumeProducing(self):
+               chunk = ''
+               chunk = self.file.read(self.CHUNK_SIZE)
+               
+               if self.transform:
+                       chunk = self.transform(chunk)
+
+               self.consumer.write(chunk)
+               self.lastSent = chunk[-1]
+               self.file = None
+               self.consumer.unregisterProducer()
+               self.deferred.callback(self.lastSent)
+               self.deferred = None
+
+from twisted.protocols.basic import LineReceiver
+class ExchangeServer (LineReceiver):
+       def __init__(self):
+               self.state = "IDLE"
+       
+       def error(self, message):
+               self.sendLine("ERROR")
+               self.sendLine(message)
+               self.transport.loseConnection()
+       
+       def connectionLost(self, reason):
+               print "server: connection lost: ", reason
+       
+       def connectionMade(self):
+               print "server: connection made"
+       
+       def lineReceived(self, data):
+               print "server: ", data
+               
+               if self.state == "SESSION":
+                       if g_data.get_sessions().count(data):
+                               self.session_name = data
+                               self.state = "IDLE"
+                               self.sendLine("OK")
+                       else:
+                               self.error(data + " doesn't exist on server")
+               elif self.state == "SNAPSHOT":
+                       if g_data.get_snaps(self.session_name, g_data.get_user()).count(data):
+                               filename = g_data.get_session_path(self.session_name)+data+'.ardour'
+                               print filename
+                               self.sendLine(str(os.stat(filename).st_size))
+                               self.sendLine("OK")
+                               self.file = open(filename, 'r')
+                               file_sender = FileSender()
+                               cb = file_sender.beginFileTransfer(self.file, self.transport)
+                               cb.addCallback(self.file_done)
+                       else:
+                               self.error("snapshot: " + data + " doesn't exist on server")
+               elif self.state == "SOUNDFILE" or self.state == "SOUNDFILE_HEADER":
+                       if g_data.get_sounds(self.session_name, g_data.get_user()).count(data):
+                               filename = g_data.get_session_path(self.session_name)+"/sounds/"+data
+                               print filename
+                               if self.state == "SOUNDFILE":
+                                       self.sendLine(str(os.stat(filename).st_size))
+                               else:   #SOUNDFILE_HEADER
+                                       header_size = get_header_size(filename)
+                                       if header_size:
+                                               self.sendLine(str(header_size))
+                                       else:
+                                               self.error('soundfile: ' + data + 'doesn\'t have "data" chunk')
+                               self.sendLine("OK")
+                               self.file = open(filename, 'r')
+                               if self.state == "SOUNDFILE":
+                                       file_sender = FileSender()
+                                       cb = file_sender.beginFileTransfer(self.file, self.transport)
+                               else:   # SOUNDFILE_HEADER
+                                       file_sender = FileSenderLimited()
+                                       cb = file_sender.beginFileTransfer(self.file, self.transport, header_size)
+                               cb.addCallback(self.file_done)
+                       else:
+                               self.error("soundfile: " + data + "doesn't exist on server")
+               elif self.state == "SOUNDFILE_SIZE":
+                       if g_data.get_sounds(self.session_name, g_data.get_user()).count(data):
+                               filename = g_data.get_session_path(self.session_name)+"/sounds/"+data
+                               print filename
+                               self.sendLine(str(os.stat(filename).st_size))
+                               self.state = "IDLE"
+               elif data == "SESSION":
+                       self.state = "SESSION"
+               elif data == "SNAPS":
+                       self.state = "SNAPS"
+                       for snap in g_data.get_snaps(self.session_name, g_data.get_user()):
+                               self.sendLine(snap)
+                       self.sendLine("OK")
+                       self.state = "IDLE"
+               elif data == "SNAPSHOT":
+                       self.state = "SNAPSHOT"
+               elif data == "SOUNDFILE":
+                       self.state = "SOUNDFILE"
+               elif data == "SOUNDFILE_HEADER":
+                       self.state = "SOUNDFILE_HEADER"
+               elif data == "SOUNDFILE_SIZE":
+                       self.state = "SOUNDFILE_SIZE"
+       
+       def file_done(self, data):
+               print "server: file done"
+               self.file.close()
+               self.state = "IDLE"
+       
+class ExchangeServerFactory(protocol.ServerFactory):
+       protocol = ExchangeServer
+       
+       def __init__(self):
+               pass
+
+class ExchangeClient (LineReceiver):
+       def __init__(self, session_name, collab_name, snap_name, debug_mode):
+               self.session_name = session_name
+               self.collab_name = collab_name
+               self.snap_name = snap_name
+               self.debug_mode = debug_mode
+               self.state = "IDLE"
+       
+       def connectionLost(self, reason):
+               g_display.show_status("Connection lost")
+       
+       def connectionMade(self):
+               g_display.show_status("Connection made")
+               self.state = "SESSION"
+               self.sendLine("SESSION")
+               self.sendLine(self.session_name)
+       
+       def rawDataReceived(self, data):
+               self.file.write(data)
+               self.received += len(data)
+               print self.received, self.filesize
+               if self.received >= self.filesize:
+                       self.setLineMode()
+                       self.file.close()
+                       g_data.rescan_session(self.session_name)
+                       if self.state == "SNAPSHOT":
+                               self.sounds = get_sound_list(self.filename)
+                               if len(self.sounds):
+                                       self.sound_index = 0
+                                       if self.debug_mode:
+                                               self.state = "SOUNDFILE_HEADER"
+                                               self.sendLine("SOUNDFILE_HEADER")
+                                       else:
+                                               self.state = "SOUNDFILE"
+                                               self.sendLine("SOUNDFILE")
+                                       self.sendLine(self.sounds[self.sound_index])
+                               else:
+                                       self.transport.loseConnection()
+                       elif self.state == "SOUNDFILE":
+                               self.sound_index += 1
+                               if self.sound_index > len(self.sounds)-1:
+                                       self.transport.loseConnection()
+                               else:
+                                       self.sendLine("SOUNDFILE")
+                                       self.sendLine(self.sounds[self.sound_index])
+                       elif self.state == "SOUNDFILE_HEADER":
+                               self.state = "SOUNDFILE_SIZE"
+                               self.sendLine("SOUNDFILE_SIZE")
+                               self.sendLine(self.sounds[self.sound_index])
+       
+       def lineReceived(self, data):
+               print "client: ", data
+               
+               if data == "ERROR":
+                       self.state = "ERROR"
+               elif data == "OK":
+                       if self.state == "SESSION":
+                               if self.snap_name:
+                                       self.state = "SNAPSHOT"
+                                       self.sendLine("SNAPSHOT")
+                                       self.sendLine(self.snap_name)
+                               else:
+                                       self.state = "SNAPS"
+                                       self.sendLine("SNAPS")
+                       elif self.state == "SNAPS":
+                               self.transport.loseConnection()
+                       elif self.state == "SNAPSHOT":
+                               self.setRawMode()
+                               self.filename = g_data.get_session_path(self.session_name)+'/'+self.snap_name+'.ardour'
+                               self.file = open(self.filename, 'w')
+                               self.received = 0
+                       elif self.state == "SOUNDFILE" or self.state == "SOUNDFILE_HEADER":
+                               self.setRawMode()
+                               self.filename = g_data.get_session_path(self.session_name)+'/sounds/'+self.sounds[self.sound_index]
+                               self.file = open(self.filename, 'w')
+                               self.received = 0
+               elif self.state == "ERROR":
+                       raise_error(data, g_display.window)
+               elif self.state == "SNAPS":
+                       g_data.add_snap(self.session_name, self.collab_name, data)
+               elif self.state == "SNAPSHOT":
+                       self.filesize = int(data)
+               elif self.state == "SOUNDFILE":
+                       self.filesize = int(data)
+               elif self.state == "SOUNDFILE_HEADER":
+                       self.filesize = int(data)
+               elif self.state == "SOUNDFILE_SIZE":
+                       append_empty_data(self.filename, int(data))
+                       self.sound_index += 1
+                       if self.sound_index > len(self.sounds)-1:
+                               self.transport.loseConnection()
+                       else:
+                               self.state = "SOUNDFILE_HEADER"
+                               self.sendLine("SOUNDFILE_HEADER")
+                               self.sendLine(self.sounds[self.sound_index])
+
+class ExchangeClientFactory(protocol.ClientFactory):
+       def buildProtocol(self, addr):
+               return ExchangeClient(self.session_name, self.collab_name, self.snap_name, self.debug_mode)
+       
+       def clientConnectionFailed(self, connector, reason):
+               raise_error('Connection failed: ' + reason.getErrorMessage(), g_display.window)
+               g_display.show_status('Connection failed')
+       
+       def __init__(self, session_name, collab_name, snap_name, debug_mode):
+               self.session_name = session_name
+               self.collab_name = collab_name
+               self.snap_name = snap_name
+               self.debug_mode = debug_mode
+
+class HelperWin(object):
+       def delete_me(self, window):
+               self = 0
+
+class Preferences(HelperWin):
+       def __init__(self):
+               self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+               self.window.set_title('Preferences')
+               self.window.connect('destroy', self.delete_me)
+               self.window.set_position(gtk.WIN_POS_MOUSE)
+               
+               main_box = gtk.VBox()
+               self.window.add(main_box)
+               
+               hbox1 = gtk.HBox()
+               label1 = gtk.Label("User")
+               self.user = gtk.Entry()
+               self.user.set_text(g_data.get_user())
+               hbox1.pack_start(label1)
+               hbox1.pack_start(self.user)
+               main_box.pack_start(hbox1)
+               
+               ok_btn = gtk.Button("Ok")
+               ok_btn.connect('clicked', self.ok_clicked)
+               main_box.pack_start(ok_btn)
+               
+               self.window.show_all()
+               
+       def ok_clicked(self, btn):
+               g_data.set_user(self.user.get_text())
+               self.window.hide_all()
+               
+       def show_all(self):
+               self.window.show_all()
+
+class AddCollaborator(HelperWin):
+       def __init__(self, session):
+               self.session_name = session
+               
+               self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+               self.window.set_title('Fetch Session')
+               self.window.connect('destroy', self.delete_me)
+               self.window.set_position(gtk.WIN_POS_MOUSE)
+               
+               main_box = gtk.VBox()
+               self.window.add(main_box)
+               
+               hbox0 = gtk.HBox()
+               label0 = gtk.Label("Collaborator")
+               self.collab = gtk.Entry()
+               self.collab.connect('key-release-event', self.key_press)
+               hbox0.pack_start(label0)
+               hbox0.pack_start(self.collab)
+               main_box.pack_start(hbox0)
+               
+               hbox1 = gtk.HBox()
+               label1 = gtk.Label("IP Address")
+               self.address = gtk.Entry()
+               self.address.connect('key-release-event', self.key_press)
+               hbox1.pack_start(label1)
+               hbox1.pack_start(self.address)
+               main_box.pack_start(hbox1)
+               
+               hbox2 = gtk.HBox()
+               label2 = gtk.Label("Port Number")
+               self.port = gtk.Entry()
+               self.port.connect('key-release-event', self.key_press)
+               self.port.set_text(str(g_data.port))
+               hbox2.pack_start(label2)
+               hbox2.pack_start(self.port)
+               main_box.pack_start(hbox2)
+               
+               hbox3 = gtk.HBox()
+               label3 = gtk.Label("Username")
+               label3.set_sensitive(False)
+               self.username = gtk.Entry()
+               self.username.set_sensitive(False)
+               hbox3.pack_start(label3)
+               hbox3.pack_start(self.username)
+               main_box.pack_start(hbox3)
+               
+               hbox4 = gtk.HBox()
+               label4 = gtk.Label("Password")
+               label4.set_sensitive(False)
+               self.password = gtk.Entry()
+               self.password.set_sensitive(False)
+               hbox4.pack_start(label4)
+               hbox4.pack_start(self.password)
+               main_box.pack_start(hbox4)
+               
+               self.ok_btn = gtk.Button(gtk.STOCK_OK)
+               self.ok_btn.set_use_stock(True)
+               self.ok_btn.connect('clicked', self.ok_clicked)
+               self.ok_btn.set_sensitive(False)
+               main_box.pack_start(self.ok_btn)
+               
+               self.window.show_all()
+       
+       def key_press(self, event, data):
+               if self.collab.get_text() and self.address.get_text() and self.port.get_text():
+                       self.ok_btn.set_sensitive(True)
+               else:
+                       self.ok_btn.set_sensitive(False)
+               return True
+       
+       def ok_clicked(self, btn):
+               self.window.hide_all()
+               g_data.add_collab(self.session_name, self.collab.get_text(), self.address.get_text(), int(self.port.get_text()))
+               self.collab.set_text('')
+               self.address.set_text('')
+               self.port.set_text('')
+               self.username.set_text('')
+               self.password.set_text('')
+       
+       def show_all(self):
+               self.window.show_all()
+
+class ArdourShareWindow(object):
+       def menuitem_cb(self, window, action, widget):
+               print self, window, action, widget
+       
+       def add_collaborator_cb(self, window, action, widget):
+               if self.session:
+                       self.add_session = AddCollaborator(self.session)
+       
+       def fetch_snapshot_cb(self, window, action, widget):
+               if self.session and self.collab and self.collab != g_data.get_user():
+                       client = ExchangeClientFactory(self.session, self.collab, self.snap, g_data.debug_mode)
+                       reactor.connectTCP(g_data.get_collab_ip(self.session, self.collab), g_data.port, client)
+       
+       def preferences_cb(self, window, action, widget):
+               self.preferences = Preferences()
+       
+       def add_session_ok_file_btn_clicked(self, w):
+               filename = self.file_sel.get_filename()
+               if filename.endswith(".ardour"):
+                       g_data.add_session(filename[0:filename.rfind("/")+1])
+                       self.update_session_view()
+               else:
+                       raise_error("Not an Ardour session", self.window)
+               self.file_sel.destroy()
+       
+       def add_session_cb(self, window, action, widget):
+               if g_data.get_user():
+                       self.file_sel = gtk.FileSelection("Add Session...")
+                       self.file_sel.ok_button.connect("clicked", self.add_session_ok_file_btn_clicked)
+                       self.file_sel.cancel_button.connect("clicked", lambda w: self.file_sel.destroy())
+                       self.file_sel.connect("destroy", lambda w: self.file_sel.destroy())
+                       self.file_sel.show()
+               else:
+                       raise_error("Set the user name in the preferences first", self.window)
+       
+       def create_session_cb(self, window, action, widget):
+               if g_data.get_user():
+                       self.file_sel = gtk.FileSelection("Create Session...")
+                       self.file_sel.ok_button.connect("clicked", self.create_file_ok_btn_clicked)
+                       self.file_sel.cancel_button.connect("clicked", lambda w: self.file_sel.destroy())
+                       self.file_sel.connect("destroy", lambda w: self.file_sel.destroy())
+                       self.file_sel.show()
+               else:
+                       raise_error("Set the user name in the preferences first", self.window)
+       
+       def create_file_ok_btn_clicked(self, w):
+               filename = self.file_sel.get_filename()
+               if len(filename) > 0:
+                       g_data.create_session(filename)
+                       self.update_session_view()
+               else:
+                       raise_error("Not an Ardour session", self.window)
+               self.file_sel.destroy()
+       
+       def update_session_view(self):
+               self.session_model.clear()
+               for session in g_data.get_sessions():
+                       self.session_model.set(self.session_model.append(), 0, session)
+       
+       def update_collab_view(self):
+               self.collab_model.clear()
+               for collab in g_data.get_collabs(self.session):
+                       self.collab_model.set(self.collab_model.append(), 0, collab)
+       
+       def update_snap_view(self):
+               self.snap_model.clear()
+               for snap in g_data.get_snaps(self.session, self.collab):
+                       self.snap_model.set(self.snap_model.append(), 0, snap)
+       
+       def cb_session_selection_changed(self, selection_object):
+               selected = []
+               selection_object.selected_foreach(lambda model, path, iter, sel = selected: sel.append(path))
+               for x in selected:
+                       self.session = self.session_model[x][0]
+               self.selected_type = "session"
+               self.update_collab_view()
+       
+       def cb_collab_selection_changed(self, selection_object):
+               selected = []
+               selection_object.selected_foreach(lambda model, path, iter, sel = selected: sel.append(path))
+               for x in selected:
+                       self.collab = self.collab_model[x][0]
+               self.selected_type = "collab"
+               self.update_snap_view()
+       
+       def cb_snap_selection_changed(self, selection_object):
+               selected = []
+               selection_object.selected_foreach(lambda model, path, iter, sel = selected: sel.append(path))
+               for x in selected:
+                       self.snap = self.snap_model[x][0]
+               self.selected_type = "snap"
+       
+       def delete_cb(self, window, action, widget):
+               if self.selected_type == "session":
+                       g_data.delete_session(self.session)
+                       self.session = ""
+                       self.collab = ""
+                       self.snap = ""
+               elif self.selected_type == "collab":
+                       g_data.delete_collab(self.session, self.collab)
+                       self.collab = ""
+                       self.snap = ""
+               elif self.selected_type == "snap":
+                       g_data.delete_snap(self.session, self.collab, self.snap)
+                       self.snap = ""
+               
+               self.update_session_view()
+               self.update_collab_view()
+               self.update_snap_view()
+               self.selected_type = ""
+               
+       def show_status(self, text):
+               mid = self.status_bar.push(self._status_cid, text)
+               if self._status_mid:
+                       self.status_bar.remove(self._status_cid, self._status_mid)
+               self._status_mid = mid
+       
+       def __init__(self):
+               self.selected_type = ""
+               self.session = ""
+               self.collab = g_data.get_user()
+               self.snap = ""
+               
+               self.preferences = 0
+               self.add_collab = 0
+               self.add_session = 0
+               
+               self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+               self.window.set_title('Session Exchange')
+               self.window.set_size_request(400, 200)
+               self.window.connect('destroy', lambda win: gtk.main_quit())
+               self.window.set_position(gtk.WIN_POS_MOUSE)
+               
+               accel_group = gtk.AccelGroup()
+               self.window.add_accel_group(accel_group)
+               
+               main_box = gtk.VBox()
+               self.window.add(main_box)
+               
+               menu_items = (
+                       ('/_File',            None,         None,             0, '<Branch>'),
+                       ('/File/_Add Session...','<control>A', self.add_session_cb, 0, ''),
+                       ('/File/Create _Session...', '<control>S', self.create_session_cb, 0, ''),
+                       ('/File/sep1',        None,         None,             0, '<Separator>'),
+                       ('/File/_Quit',       '<control>Q', gtk.main_quit,     0, '<StockItem>', gtk.STOCK_QUIT),
+                       ('/_Edit',            None,         None,             0, '<Branch>' ),
+                       ('/Edit/Cu_t',        '<control>X', self.menuitem_cb, 0, '<StockItem>', gtk.STOCK_CUT),
+                       ('/Edit/_Copy',       '<control>C', self.menuitem_cb, 0, '<StockItem>', gtk.STOCK_COPY),
+                       ('/Edit/_Paste',      '<control>V', self.menuitem_cb, 0, '<StockItem>', gtk.STOCK_PASTE),
+                       ('/Edit/_Delete',     None,         self.delete_cb, 0, '<StockItem>', gtk.STOCK_DELETE),
+                       ('/Edit/sep1',        None,         None,             0, '<Separator>'),
+                       ('/Edit/Add Colla_borator...','<control>B', self.add_collaborator_cb,0,''),
+                       ('/Edit/_Fetch Snapshot','<control>F', self.fetch_snapshot_cb,0,''),
+                       ('/Edit/sep1',        None,         None,             0, '<Separator>'),
+                       ('/Edit/_Preferences...','<control>P', self.preferences_cb, 0, '')
+               )
+               
+               #need to hold a reference to the item_factory or the menubar will disappear.
+               self.item_factory = gtk.ItemFactory(gtk.MenuBar, '<main>', accel_group)
+               self.item_factory.create_items(menu_items, self.window)
+               main_box.pack_start(self.item_factory.get_widget('<main>'), gtk.FALSE)
+               
+               pane1 = gtk.HPaned()
+               pane2 = gtk.HPaned()
+               pane1.pack2(pane2, gtk.TRUE, gtk.FALSE)
+               
+               scroll1 = gtk.ScrolledWindow()
+               scroll1.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+               pane1.pack1(scroll1, gtk.TRUE, gtk.FALSE)
+               scroll2 = gtk.ScrolledWindow()
+               scroll2.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+               pane2.pack1(scroll2, gtk.TRUE, gtk.FALSE)
+               scroll3 = gtk.ScrolledWindow()
+               scroll3.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+               pane2.pack2(scroll3, gtk.TRUE, gtk.FALSE)
+               
+               self.session_model = gtk.ListStore(gobject.TYPE_STRING)
+               view1 = gtk.TreeView(self.session_model)
+               column1 = gtk.TreeViewColumn('Sessions', gtk.CellRendererText(), text=0)
+               view1.append_column(column1)
+               self.session_selection = view1.get_selection()
+               self.session_selection.connect("changed", self.cb_session_selection_changed)
+               scroll1.add(view1)
+               
+               self.update_session_view()
+               
+               self.collab_model = gtk.ListStore(gobject.TYPE_STRING)
+               view2 = gtk.TreeView(self.collab_model)
+               column2 = gtk.TreeViewColumn('Collaborators', gtk.CellRendererText(), text=0)
+               view2.append_column(column2)
+               self.collab_selection = view2.get_selection()
+               self.collab_selection.connect("changed", self.cb_collab_selection_changed)
+               scroll2.add(view2)
+               
+               self.snap_model = gtk.ListStore(gobject.TYPE_STRING)
+               view3 = gtk.TreeView(self.snap_model)
+               column3 = gtk.TreeViewColumn('Snapshots', gtk.CellRendererText(), text=0)
+               view3.append_column(column3)
+               self.snap_selection = view3.get_selection()
+               self.snap_selection.connect("changed", self.cb_snap_selection_changed)
+               scroll3.add(view3)
+               
+               main_box.pack_start(pane1, gtk.TRUE, gtk.TRUE)
+               
+               self.status_bar = gtk.Statusbar()
+               main_box.pack_start(self.status_bar, gtk.FALSE)
+               self._status_cid = self.status_bar.get_context_id('display')
+               self._status_mid = ''
+               
+               self.window.show_all()
+
+def print_help():
+       print """
+       -h, --help
+       -n, --no-server          Only act as a client
+       -p, --port <port number> Defaults to 8970
+       -d, --debug              Infers audio files.  For debugging Ardour.
+       -v, --version            Version
+       """
+       sys.exit(2)
+
+def main():
+       try:
+               opts, args = getopt.getopt(sys.argv[1:], "hp:ndv", ["help", "port=", "no-server", "debug", "version"])
+       except getopt.GetoptError:
+               print_help()
+       
+       server = True
+       for o, a in opts:
+               if o in ("-h", "--help"):
+                       print_help()
+               if o in ("-d", "--debug"):
+                       g_display.window.set_title('Session Exchange: Debug Mode')
+                       g_data.debug_mode = True
+               if o in ("-p", "--port"):
+                       g_data.port = int(a)
+               if o in ("-n", "--no-server"):
+                       server = False
+               if o in ("-v", "--version"):
+                       print VERSION
+                       sys.exit(2)
+       
+       if (server):
+               try:
+                       reactor.listenTCP(g_data.port, ExchangeServerFactory())
+               except twisted.internet.error.CannotListenError:
+                       print "Can not listen on a port number under 1024 unless run as root"
+                       sys.exit(2)
+
+       reactor.run()
+
+       g_data.close()
+
+# global objects
+g_data = Data()
+g_display = ArdourShareWindow()
+
+if __name__ == '__main__':
+       main()
diff --git a/tools/synthesize_sources.pl b/tools/synthesize_sources.pl
new file mode 100755 (executable)
index 0000000..ebb903c
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/env perl
+# Ardour session synthesizer
+# (c)Sampo Savolainen 2007
+#
+# GPL
+# This reads an Ardour session file and creates zero-signal source files
+# for each missing source file. The length of each file is determined
+# by how far regions using that source file go into the sample data.
+
+use XML::Parser::PerlSAX;
+use XML::Handler::XMLWriter;
+use IO::Handle;
+
+use ARDOUR::SourceInfoLoader;
+
+
+my ($samplerate, $sessionName) = @ARGV;
+
+if ( ! -d $sessionName || ! -f $sessionName."/".$sessionName.".ardour" ) {
+       print "usage: synthesize_sources.pl samplerate [session name, the name must match the directory and the .ardour file in it]\n";
+       exit;
+}
+
+my $sessionFile = $sessionName."/".$sessionName.".ardour";
+
+
+my $handler = new ARDOUR::SourceInfoLoader($sessionName);
+
+my $parser = XML::Parser::PerlSAX->new( Handler => $handler );
+
+$parser->parse(Source => { SystemId => $sessionFile });
+
+if ( ! -d $sessionName."/interchange" ) {
+       mkdir $sessionName."/interchange/" || die "couldn't create ".$sessionName."/interchange";
+}
+
+if ( ! -d $sessionName."/interchange/".$sessionName ) {
+       mkdir $sessionName."/interchange/".$sessionName || die "couldn't create ".$sessionName."/interchange/".$sessionName;
+}
+
+if ( ! -d $sessionName."/interchange/".$sessionName."/audiofiles" ) {
+       mkdir $sessionName."/interchange/".$sessionName."/audiofiles" || die "couldn't create ".$sessionName."/interchange/".$sessionName."/audiofiles";
+}
+
+if ( ! -d $sessionName."/peaks") {
+       mkdir $sessionName."/peaks/" || die "couldn't create ".$sessionName."/peaks";
+}
+
+my $audioFileDirectory = $sessionName."/interchange/".$sessionName."/audiofiles";
+
+my %sources = %{$handler->{Sources}};
+
+foreach my $tmp (keys %sources) {
+       
+       print "Generating ".$audioFileDirectory."/".$sources{$tmp}->{name}.".wav\n";
+
+       system("sox", 
+              "-t", "raw",        # /dev/zero is raw :)
+              "-r", $samplerate,  # set sample rate
+              "-c", "1",          # 1 channel
+              "-b",               # input in bytes
+              "-s",               # signed
+              "/dev/zero",        # input signal
+
+              "-w",               # output 16 bit
+              "-t", "wav",        # format wav
+              $audioFileDirectory."/".$sources{$tmp}->{name}, # filename
+              "trim", "0", $sources{$tmp}->{calculated_length}."s" # trim silence to wanted sample amount
+              );
+
+
+}
+
+
+