diff --git a/.cvsignore b/.cvsignore
deleted file mode 100644
index 140c335ccc..0000000000
--- a/.cvsignore
+++ /dev/null
@@ -1,7 +0,0 @@
-.sconf_temp
-.sconsign.dblite
-ardour.rc
-config.log
-scache.conf
-.gdb_history
-docs/
diff --git a/SConstruct b/SConstruct
index f129793dd6..0a58a46596 100644
--- a/SConstruct
+++ b/SConstruct
@@ -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:
diff --git a/ardour.rc.in b/ardour.rc.in
index a8c8b74bfd..ab34ae29d4 100644
--- a/ardour.rc.in
+++ b/ardour.rc.in
@@ -31,7 +31,7 @@
-
+
diff --git a/gtk2_ardour/SConscript b/gtk2_ardour/SConscript
index dfd94ea5af..4dfe0b7322 100644
--- a/gtk2_ardour/SConscript
+++ b/gtk2_ardour/SConscript
@@ -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'
diff --git a/gtk2_ardour/actions.cc b/gtk2_ardour/actions.cc
index 2fe305cf84..d382878582 100644
--- a/gtk2_ardour/actions.cc
+++ b/gtk2_ardour/actions.cc
@@ -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);
}
diff --git a/gtk2_ardour/analysis_window.cc b/gtk2_ardour/analysis_window.cc
index 3752726c04..dd749d2bb1 100644
--- a/gtk2_ardour/analysis_window.cc
+++ b/gtk2_ardour/analysis_window.cc
@@ -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 pl
= boost::dynamic_pointer_cast((*i)->playlist());
@@ -278,7 +277,7 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
TimeAxisView *current_axis = (*i);
- for (std::set::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(*j);
if (!arv)
diff --git a/gtk2_ardour/ardev_common.sh b/gtk2_ardour/ardev_common.sh
deleted file mode 100755
index 3cef2254d2..0000000000
--- a/gtk2_ardour/ardev_common.sh
+++ /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
diff --git a/gtk2_ardour/ardour.bindings b/gtk2_ardour/ardour.bindings
index 03ff5ae331..3c7afcde6c 100644
--- a/gtk2_ardour/ardour.bindings
+++ b/gtk2_ardour/ardour.bindings
@@ -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 "/RegionList/RegionListSort" "")
@@ -62,7 +62,7 @@
; (gtk_accel_path "/Main/AudioFileFormatData" "")
; (gtk_accel_path "/options/MeterFalloffFastest" "")
(gtk_accel_path "/Editor/audition-at-mouse" "period")
-(gtk_accel_path "/Transport/Forward" "Right")
+(gtk_accel_path "/Transport/Forward" "rightarrow")
; (gtk_accel_path "/Snap/snap-to-smpte-seconds" "")
; (gtk_accel_path "/Snap/snap-to-smpte-frame" "")
; (gtk_accel_path "/Main/ExportSelection" "")
@@ -70,9 +70,9 @@
(gtk_accel_path "/Editor/editor-paste" "v")
(gtk_accel_path "/Editor/scroll-tracks-down" "Page_Down")
; (gtk_accel_path "/Snap/snap-to-smpte-minutes" "")
+; (gtk_accel_path "/Main/FlushWastebasket" "")
(gtk_accel_path "/Editor/normalize-region" "n")
(gtk_accel_path "/Editor/nudge-forward" "KP_Add")
-; (gtk_accel_path "/Main/FlushWastebasket" "")
; (gtk_accel_path "/RegionList/SortByRegionEndinFile" "")
; (gtk_accel_path "/Editor/ToggleMeasureVisibility" "")
; (gtk_accel_path "/Zoom/zoom-focus-center" "")
@@ -99,6 +99,7 @@
; (gtk_accel_path "/Editor/addExternalAudioAsTapeTrack" "")
; (gtk_accel_path "/redirectmenu/paste" "")
; (gtk_accel_path "/Editor/Smpte25" "")
+; (gtk_accel_path "/options/RegionEquivalentsOverlap" "")
; (gtk_accel_path "/Main/MeteringFallOffRate" "")
; (gtk_accel_path "/options/UseHardwareMonitoring" "")
; (gtk_accel_path "/Editor/Smpte24" "")
@@ -111,12 +112,14 @@
(gtk_accel_path "/Editor/extend-range-to-end-of-region" "rightanglebracket")
(gtk_accel_path "/Editor/scroll-backward" "leftarrow")
(gtk_accel_path "/Editor/start-range" "KP_Down")
+; (gtk_accel_path "/Editor/ToggleTranzportSurface" "")
; (gtk_accel_path "/ShuttleActions/SetShuttleUnitsSemitones" "")
; (gtk_accel_path "/JACK/JACKLatency128" "")
; (gtk_accel_path "/Snap/snap-to-beat" "")
; (gtk_accel_path "/Editor/RegionEditOps" "")
; (gtk_accel_path "/Editor/snap-magnetic" "")
; (gtk_accel_path "/Editor/playhead-to-range-end" "")
+(gtk_accel_path "/Editor/scroll-playhead-forward" "rightarrow")
(gtk_accel_path "/Editor/align-regions-sync-relative" "a")
; (gtk_accel_path "/Editor/EditSelectRegionOptions" "")
(gtk_accel_path "/Editor/crop" "c")
@@ -124,6 +127,7 @@
; (gtk_accel_path "/Editor/MeterFalloff" "")
; (gtk_accel_path "/RegionList/rlRemove" "")
(gtk_accel_path "/Transport/GotoStart" "Home")
+(gtk_accel_path "/Editor/scroll-playhead-backward" "leftarrow")
(gtk_accel_path "/Editor/split-region" "s")
; (gtk_accel_path "/Transport/ToggleAutoInput" "")
; (gtk_accel_path "/Snap/snap-to-thirtyseconds" "")
@@ -170,6 +174,7 @@
; (gtk_accel_path "/options/MeterFalloffMedium" "")
(gtk_accel_path "/Editor/toggle-follow-playhead" "f")
; (gtk_accel_path "/Main/SaveTemplate" "")
+(gtk_accel_path "/Transport/TransitionToRoll" "uparrow")
; (gtk_accel_path "/RegionList/SortByRegionStartinFile" "")
; (gtk_accel_path "/options/GainReduceFastTransport" "")
; (gtk_accel_path "/Common/ToggleInspector" "")
@@ -202,13 +207,14 @@
; (gtk_accel_path "/Main/Session" "")
(gtk_accel_path "/Editor/edit-cursor-to-range-start" "F1")
; (gtk_accel_path "/Main/AudioFileFormat" "")
-(gtk_accel_path "/MouseMode/set-mouse-mode-timefx" "t")
; (gtk_accel_path "/Transport/Transport" "")
+(gtk_accel_path "/MouseMode/set-mouse-mode-timefx" "t")
; (gtk_accel_path "/RegionList/SortByRegionName" "")
; (gtk_accel_path "/Main/KeyMouse Actions" "")
(gtk_accel_path "/MouseMode/set-mouse-mode-gain" "g")
; (gtk_accel_path "/Snap/snap-to-frame" "")
; (gtk_accel_path "/Editor/SnapTo" "")
+(gtk_accel_path "/Transport/TransitionToReverse" "downarrow")
; (gtk_accel_path "/Editor/Crossfades" "")
; (gtk_accel_path "/Editor/PullupPlus4" "")
(gtk_accel_path "/Editor/add-location-from-playhead" "KP_Enter")
@@ -261,7 +267,7 @@
; (gtk_accel_path "/options/FileHeaderFormatWAVE64" "")
(gtk_accel_path "/Editor/brush-at-mouse" "b")
; (gtk_accel_path "/RegionList/rlShowAll" "")
-(gtk_accel_path "/Transport/Rewind" "Left")
+(gtk_accel_path "/Transport/Rewind" "leftarrow")
; (gtk_accel_path "/RegionList/SortByRegionTimestamp" "")
; (gtk_accel_path "/options/VerifyRemoveLastCapture" "")
; (gtk_accel_path "/options/OutputAutoConnectPhysical" "")
diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus
index cf56e2ad9f..040c6464c1 100644
--- a/gtk2_ardour/ardour.menus
+++ b/gtk2_ardour/ardour.menus
@@ -47,6 +47,9 @@
+
+
+
@@ -203,6 +206,9 @@
+
+
+
@@ -334,6 +340,7 @@
+
diff --git a/gtk2_ardour/ardour2_ui.rc b/gtk2_ardour/ardour2_ui.rc
index a450e6d7dc..7d03368076 100644
--- a/gtk2_ardour/ardour2_ui.rc
+++ b/gtk2_ardour/ardour2_ui.rc
@@ -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"
diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h
index 92f2cc103d..45a795dec3 100644
--- a/gtk2_ardour/ardour_ui.h
+++ b/gtk2_ardour/ardour_ui.h
@@ -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 ();
diff --git a/gtk2_ardour/ardour_ui_ed.cc b/gtk2_ardour/ardour_ui_ed.cc
index df2fda78c9..b6e31d12d8 100644
--- a/gtk2_ardour/ardour_ui_ed.cc
+++ b/gtk2_ardour/ardour_ui_ed.cc
@@ -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);
diff --git a/gtk2_ardour/ardour_ui_options.cc b/gtk2_ardour/ardour_ui_options.cc
index d0f523481f..5674d6dee1 100644
--- a/gtk2_ardour/ardour_ui_options.cc
+++ b/gtk2_ardour/ardour_ui_options.cc
@@ -19,6 +19,7 @@
*/
#include
+#include
#include
@@ -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 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 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
}
diff --git a/gtk2_ardour/audio_clock.cc b/gtk2_ardour/audio_clock.cc
index 66822289c2..481e91b09a 100644
--- a/gtk2_ardour/audio_clock.cc
+++ b/gtk2_ardour/audio_clock.cc
@@ -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;
}
diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc
index e91dd529e3..4bded299b4 100644
--- a/gtk2_ardour/audio_region_view.cc
+++ b/gtk2_ardour/audio_region_view.cc
@@ -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(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(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(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(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);
diff --git a/gtk2_ardour/audio_region_view.h b/gtk2_ardour/audio_region_view.h
index 1d51cb7172..a59972b807 100644
--- a/gtk2_ardour/audio_region_view.h
+++ b/gtk2_ardour/audio_region_view.h
@@ -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 ();
diff --git a/gtk2_ardour/audio_streamview.cc b/gtk2_ardour/audio_streamview.cc
index d0898d32f4..d12fa70fed 100644
--- a/gtk2_ardour/audio_streamview.cc
+++ b/gtk2_ardour/audio_streamview.cc
@@ -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 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 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);
diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc
index 1dc62f1f42..5598689855 100644
--- a/gtk2_ardour/automation_line.cc
+++ b/gtk2_ardour/automation_line.cc
@@ -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 */
diff --git a/gtk2_ardour/automation_selectable.h b/gtk2_ardour/automation_selectable.h
index 5b7f4d5705..2ce8f29a70 100644
--- a/gtk2_ardour/automation_selectable.h
+++ b/gtk2_ardour/automation_selectable.h
@@ -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__ */
diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc
index 776dff37f2..c3f53d266c 100644
--- a/gtk2_ardour/automation_time_axis.cc
+++ b/gtk2_ardour/automation_time_axis.cc
@@ -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(alist, &before, &alist.get_state()));
+ _session.add_command (new MementoCommand(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(alist, &before, &alist.get_state()));
+ _session.add_command (new MementoCommand(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;
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index a80de0a8f4..0f77f157f6 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -28,6 +28,7 @@
#include
#include
+#include
#include
#include
@@ -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
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_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr(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& 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(*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 (*i)) != 0) {
-
- if (tatv->route()->edit_group() == group) {
- relevant_tracks.insert (tatv);
- }
- }
- }
- } else {
- relevant_tracks.insert (atv);
- }
- }
-}
-
-void
-Editor::mapover_tracks (slot sl)
-{
- set relevant_tracks;
-
- get_relevant_tracks (relevant_tracks);
-
- uint32_t sz = relevant_tracks.size();
-
- for (set::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* all_equivs)
-{
- boost::shared_ptr pl;
- vector > results;
- RegionView* marv;
- boost::shared_ptr 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 >::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 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::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 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 relevant_tracks;
-
- get_relevant_tracks (relevant_tracks);
-
- for (set::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 regions;
-
- for (list::iterator x = results.begin(); x != results.end(); ++x) {
- RegionView* arv;
-
- if ((arv = dynamic_cast(*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, Selection::Operation op)
-{
- vector all_equivalent_regions;
-
- for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
-
- RouteTimeAxisView* tatv;
-
- if ((tatv = dynamic_cast (*i)) != 0) {
-
- boost::shared_ptr pl;
- vector > results;
- RegionView* marv;
- boost::shared_ptr ds;
-
- if ((ds = tatv->get_diskstream()) == 0) {
- /* bus */
- continue;
- }
-
- if ((pl = (ds->playlist())) != 0) {
- pl->get_region_list_equivalent_regions (region, results);
- }
-
- for (vector >::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 weak_r)
-{
- RegionView* rv;
- boost::shared_ptr r (weak_r.lock());
-
- if (!r) {
- return true;
- }
-
- boost::shared_ptr ar;
-
- if ((ar = boost::dynamic_pointer_cast (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);
+}
+
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 80fa2ff4df..b0eaa83fd9 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -44,7 +44,7 @@
#include
#include
#include
-#include
+#include
#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& relevant_tracks);
+ void get_equivalent_regions (RegionView* rv, std::vector&);
void mapover_tracks (sigc::slot 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*);
+ void mapped_get_equivalent_regions (RouteTimeAxisView&, uint32_t, RegionView*, vector*);
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 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 > motion_frozen_playlists;
void region_drag_motion_callback (ArdourCanvas::Item*, GdkEvent*);
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index f99a828203..138fa8510e 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -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();
+}
diff --git a/gtk2_ardour/editor_audio_import.cc b/gtk2_ardour/editor_audio_import.cc
index 48edb52756..a7d7d0de96 100644
--- a/gtk2_ardour/editor_audio_import.cc
+++ b/gtk2_ardour/editor_audio_import.cc
@@ -130,6 +130,8 @@ Editor::do_embed (vector paths, bool split, ImportMode mode, AudioTrack
vector::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 paths, bool split, bool multiple_fi
boost::shared_ptr source;
SourceList sources;
boost::shared_ptr 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 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 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 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 (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 paths, bool split, bool multiple_fi
region = boost::dynamic_pointer_cast (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 paths, bool split, bool multiple_fi
out:
track_canvas.get_window()->set_cursor (*current_canvas_cursor);
- return 0;
+ return ret;
}
int
diff --git a/gtk2_ardour/editor_export_audio.cc b/gtk2_ardour/editor_export_audio.cc
index 43977f1577..ce7de29aa1 100644
--- a/gtk2_ardour/editor_export_audio.cc
+++ b/gtk2_ardour/editor_export_audio.cc
@@ -210,7 +210,7 @@ Editor::write_region (string path, boost::shared_ptr region)
try {
- fs = boost::dynamic_pointer_cast (SourceFactory::createReadable (DataType::AUDIO, *session, path, AudioFileSource::Flag (0)));
+ fs = boost::dynamic_pointer_cast (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 region)
for (vector >::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 (SourceFactory::createReadable (DataType::AUDIO, *session, path, AudioFileSource::Flag (0)));
+ fs = boost::dynamic_pointer_cast (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 >::iterator s = sources.begin(); s != sources.end(); ++s) {
+ (*s)->update_header (0, *now, tnow);
+ (*s)->mark_immutable ();
// do we need to ref it again?
}
diff --git a/gtk2_ardour/editor_keyboard.cc b/gtk2_ardour/editor_keyboard.cc
index cdea9d2272..bfe61eae5c 100644
--- a/gtk2_ardour/editor_keyboard.cc
+++ b/gtk2_ardour/editor_keyboard.cc
@@ -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;
diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc
index bdb934e8e0..0e8901b881 100644
--- a/gtk2_ardour/editor_mixer.cc
+++ b/gtk2_ardour/editor_mixer.cc
@@ -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;
diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc
index 01ea203c61..a7095d9e09 100644
--- a/gtk2_ardour/editor_mouse.cc
+++ b/gtk2_ardour/editor_mouse.cc
@@ -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 (*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(drag_info.data);
nframes_t pos;
nframes_t fade_length;
- if ((long)drag_info.current_pointer_frame > drag_info.pointer_frame_offset) {
- pos = drag_info.current_pointer_frame - drag_info.pointer_frame_offset;
- }
- else {
- pos = 0;
- }
+ if (drag_info.first_move) return;
- if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
- snap_to (pos);
+ 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 {
+ pos = 0;
}
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 (*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(alist, &before, &after));
+ }
- XMLNode &after = alist.get_state();
- session->add_command(new MementoCommand(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 (*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) {
+
+ AudioRegionView* tmp = dynamic_cast (*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(alist, &before, &after));
+ }
- XMLNode &after = alist.get_state();
- session->add_command(new MementoCommand(alist, &before, &after));
commit_reversible_command ();
-
- fade_out_drag_motion_callback (item, event);
}
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 ();
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index aff997a125..3a2658c204 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -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 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 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 touched;
-
- if (!clicked_axisview) {
- return;
- }
-
- clicked_axisview->get_inverted_selectables (*selection, touched);
- selection->set (touched);
-}
-
-void
-Editor::invert_selection ()
-{
- list 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 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 = 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 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 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 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 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 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 >& 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 current;
@@ -2196,17 +1950,22 @@ Editor::create_region_from_selection (vector >& n
void
Editor::split_multichannel_region ()
{
- vector v;
-
- AudioRegionView* clicked_arv = dynamic_cast(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 > v;
- /* nothing else to do, really */
+ for (list::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+
+ AudioRegionView* arv = dynamic_cast(*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;
+ 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(*i);
@@ -2949,21 +2712,37 @@ struct lt_playlist {
}
};
+struct PlaylistMapping {
+ TimeAxisView* tv;
+ boost::shared_ptr pl;
+
+ PlaylistMapping (TimeAxisView* tvp) : tv (tvp) {}
+};
+
void
Editor::cut_copy_regions (CutCopyOp op)
-{
- typedef std::map,boost::shared_ptr > 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 pmap;
+
+ nframes_t first_position = max_frames;
+
set freezelist;
pair::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 pl = boost::dynamic_pointer_cast((*x)->region()->playlist());
+ boost::shared_ptr 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::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 pl = boost::dynamic_pointer_cast((*x)->region()->playlist());
- boost::shared_ptr npl;
+ boost::shared_ptr pl = (*x)->region()->playlist();
+
+ if (!pl) {
+ /* impossible, but this handles it for the future */
+ continue;
+ }
+
+ TimeAxisView& tv = (*x)->get_trackview();
+ boost::shared_ptr npl;
RegionSelection::iterator tmp;
tmp = x;
++tmp;
- if (pl) {
-
- PlaylistMapping::iterator pi = pmap.find (pl);
+ vector::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 r = (*x)->region();
+
+ switch (op) {
+ case Cut:
+ if (!r) break;
- if (pi == pmap.end()) {
- // FIXME
- npl = boost::dynamic_pointer_cast (PlaylistFactory::create (DataType::AUDIO, *session, "cutlist", true));
- npl->freeze();
- pmap[pl] = npl;
- } else {
- npl = pi->second;
- }
-
- // FIXME
- boost::shared_ptr ar = boost::dynamic_pointer_cast((*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()));
- 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 > 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::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(&(*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 (*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(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 (*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(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 (*x);
+
+ if (!tmp) {
+ return;
+ }
+
+
+ boost::shared_ptr 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(*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 (*x);
+
+ if (!tmp) {
+ return;
+ }
+
+ boost::shared_ptr 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(*ar, &before, &after));
+ }
+}
+
diff --git a/gtk2_ardour/editor_region_list.cc b/gtk2_ardour/editor_region_list.cc
index 97512c06e8..5bf704f649 100644
--- a/gtk2_ardour/editor_region_list.cc
+++ b/gtk2_ardour/editor_region_list.cc
@@ -50,7 +50,6 @@ using namespace Editing;
void
Editor::handle_region_removed (boost::weak_ptr 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
index 0000000000..c1f563658b
--- /dev/null
+++ b/gtk2_ardour/editor_selection.cc
@@ -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
+
+#include
+#include
+#include
+
+#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& 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(*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 (*i)) != 0) {
+
+ if (trtv->route()->edit_group() == group) {
+ relevant_tracks.insert (trtv);
+ }
+ }
+ }
+ } else {
+ relevant_tracks.insert (rtv);
+ }
+ }
+}
+
+void
+Editor::mapover_tracks (slot sl)
+{
+ set relevant_tracks;
+
+ get_relevant_tracks (relevant_tracks);
+
+ uint32_t sz = relevant_tracks.size();
+
+ for (set::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* all_equivs)
+{
+ boost::shared_ptr pl;
+ vector