ardour
editor.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2000-2009 Paul Davis
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 
18 */
19 
20 /* Note: public Editor methods are documented in public_editor.h */
21 
22 #include <stdint.h>
23 #include <unistd.h>
24 #include <cstdlib>
25 #include <cmath>
26 #include <string>
27 #include <algorithm>
28 #include <map>
29 
30 #include "ardour_ui.h"
31 /*
32  * ardour_ui.h include was moved to the top of the list
33  * due to a conflicting definition of 'Style' between
34  * Apple's MacTypes.h and BarController.
35  */
36 
37 #include <boost/none.hpp>
38 
39 #include <sigc++/bind.h>
40 
41 #include "pbd/convert.h"
42 #include "pbd/error.h"
43 #include "pbd/enumwriter.h"
44 #include "pbd/memento_command.h"
45 #include "pbd/unknown_type.h"
46 #include "pbd/unwind.h"
47 #include "pbd/stacktrace.h"
48 #include "pbd/timersub.h"
49 
50 #include <glibmm/miscutils.h>
51 #include <glibmm/uriutils.h>
52 #include <gtkmm/image.h>
53 #include <gdkmm/color.h>
54 #include <gdkmm/bitmap.h>
55 
56 #include <gtkmm/menu.h>
57 #include <gtkmm/menuitem.h>
58 
59 #include "gtkmm2ext/bindings.h"
61 #include "gtkmm2ext/gtk_ui.h"
62 #include "gtkmm2ext/tearoff.h"
63 #include "gtkmm2ext/utils.h"
64 #include "gtkmm2ext/window_title.h"
65 #include "gtkmm2ext/choice.h"
67 
68 #include "ardour/audio_track.h"
69 #include "ardour/audioengine.h"
70 #include "ardour/audioregion.h"
71 #include "ardour/lmath.h"
72 #include "ardour/location.h"
73 #include "ardour/profile.h"
74 #include "ardour/route_group.h"
76 #include "ardour/tempo.h"
77 #include "ardour/utils.h"
78 
79 #include "canvas/debug.h"
80 #include "canvas/text.h"
81 
82 #include "control_protocol/control_protocol.h"
83 
84 #include "actions.h"
85 #include "analysis_window.h"
86 #include "audio_clock.h"
87 #include "audio_region_view.h"
88 #include "audio_streamview.h"
89 #include "audio_time_axis.h"
90 #include "automation_time_axis.h"
91 #include "bundle_manager.h"
92 #include "crossfade_edit.h"
93 #include "debug.h"
94 #include "editing.h"
95 #include "editor.h"
96 #include "editor_cursors.h"
97 #include "editor_drag.h"
98 #include "editor_group_tabs.h"
99 #include "editor_locations.h"
100 #include "editor_regions.h"
101 #include "editor_route_groups.h"
102 #include "editor_routes.h"
103 #include "editor_snapshots.h"
104 #include "editor_summary.h"
105 #include "global_port_matrix.h"
106 #include "gui_object.h"
107 #include "gui_thread.h"
108 #include "keyboard.h"
109 #include "marker.h"
110 #include "midi_region_view.h"
111 #include "midi_time_axis.h"
112 #include "mixer_strip.h"
113 #include "mixer_ui.h"
114 #include "mouse_cursors.h"
115 #include "note_base.h"
116 #include "playlist_selector.h"
117 #include "public_editor.h"
119 #include "rgb_macros.h"
120 #include "rhythm_ferret.h"
121 #include "selection.h"
122 #include "sfdb_ui.h"
123 #include "tempo_lines.h"
124 #include "time_axis_view.h"
125 #include "timers.h"
126 #include "utils.h"
127 #include "verbose_cursor.h"
128 
129 #include "i18n.h"
130 
131 using namespace std;
132 using namespace ARDOUR;
133 using namespace ARDOUR_UI_UTILS;
134 using namespace PBD;
135 using namespace Gtk;
136 using namespace Glib;
137 using namespace Gtkmm2ext;
138 using namespace Editing;
139 
141 using PBD::atoi;
142 using Gtkmm2ext::Keyboard;
143 
144 double Editor::timebar_height = 15.0;
145 
146 static const gchar *_snap_type_strings[] = {
147  N_("CD Frames"),
148  N_("TC Frames"),
149  N_("TC Seconds"),
150  N_("TC Minutes"),
151  N_("Seconds"),
152  N_("Minutes"),
153  N_("Beats/128"),
154  N_("Beats/64"),
155  N_("Beats/32"),
156  N_("Beats/28"),
157  N_("Beats/24"),
158  N_("Beats/20"),
159  N_("Beats/16"),
160  N_("Beats/14"),
161  N_("Beats/12"),
162  N_("Beats/10"),
163  N_("Beats/8"),
164  N_("Beats/7"),
165  N_("Beats/6"),
166  N_("Beats/5"),
167  N_("Beats/4"),
168  N_("Beats/3"),
169  N_("Beats/2"),
170  N_("Beats"),
171  N_("Bars"),
172  N_("Marks"),
173  N_("Region starts"),
174  N_("Region ends"),
175  N_("Region syncs"),
176  N_("Region bounds"),
177  0
178 };
179 
180 static const gchar *_snap_mode_strings[] = {
181  N_("No Grid"),
182  N_("Grid"),
183  N_("Magnetic"),
184  0
185 };
186 
187 static const gchar *_edit_point_strings[] = {
188  N_("Playhead"),
189  N_("Marker"),
190  N_("Mouse"),
191  0
192 };
193 
194 static const gchar *_edit_mode_strings[] = {
195  N_("Slide"),
196  N_("Splice"),
197  N_("Ripple"),
198  N_("Lock"),
199  0
200 };
201 
202 static const gchar *_zoom_focus_strings[] = {
203  N_("Left"),
204  N_("Right"),
205  N_("Center"),
206  N_("Playhead"),
207  N_("Mouse"),
208  N_("Edit point"),
209  0
210 };
211 
212 #ifdef USE_RUBBERBAND
213 static const gchar *_rb_opt_strings[] = {
214  N_("Mushy"),
215  N_("Smooth"),
216  N_("Balanced multitimbral mixture"),
217  N_("Unpitched percussion with stable notes"),
218  N_("Crisp monophonic instrumental"),
219  N_("Unpitched solo percussion"),
220  N_("Resample without preserving pitch"),
221  0
222 };
223 #endif
224 
225 #define COMBO_TRIANGLE_WIDTH 25 // ArdourButton _diameter (11) + 2 * arrow-padding (2*2) + 2 * text-padding (2*5)
226 
227 static void
228 pane_size_watcher (Paned* pane)
229 {
230  /* if the handle of a pane vanishes into (at least) the tabs of a notebook,
231  it is:
232 
233  X: hard to access
234  Quartz: impossible to access
235 
236  so stop that by preventing it from ever getting too narrow. 35
237  pixels is basically a rough guess at the tab width.
238 
239  ugh.
240  */
241 
242  int max_width_of_lhs = GTK_WIDGET(pane->gobj())->allocation.width - 35;
243 
244  gint pos = pane->get_position ();
245 
246  if (pos > max_width_of_lhs) {
247  pane->set_position (max_width_of_lhs);
248  }
249 }
250 
252  : _join_object_range_state (JOIN_OBJECT_RANGE_NONE)
253 
254  , _mouse_changed_selection (false)
255  /* time display buttons */
256  , minsec_label (_("Mins:Secs"))
257  , bbt_label (_("Bars:Beats"))
258  , timecode_label (_("Timecode"))
259  , samples_label (_("Samples"))
260  , tempo_label (_("Tempo"))
261  , meter_label (_("Meter"))
262  , mark_label (_("Location Markers"))
263  , range_mark_label (_("Range Markers"))
264  , transport_mark_label (_("Loop/Punch Ranges"))
265  , cd_mark_label (_("CD Markers"))
266  , videotl_label (_("Video Timeline"))
267  , edit_packer (4, 4, true)
268 
269  /* the values here don't matter: layout widgets
270  reset them as needed.
271  */
272 
273  , vertical_adjustment (0.0, 0.0, 10.0, 400.0)
274  , horizontal_adjustment (0.0, 0.0, 1e16)
275  , unused_adjustment (0.0, 0.0, 10.0, 400.0)
276 
277  , controls_layout (unused_adjustment, vertical_adjustment)
278 
279  /* tool bar related */
280 
281  , toolbar_selection_clock_table (2,3)
282  , _mouse_mode_tearoff (0)
283  , automation_mode_button (_("mode"))
284  , _zoom_tearoff (0)
285  , _tools_tearoff (0)
286 
287  , _toolbar_viewport (*manage (new Gtk::Adjustment (0, 0, 1e10)), *manage (new Gtk::Adjustment (0, 0, 1e10)))
288  , selection_op_cmd_depth (0)
289  , selection_op_history_it (0)
290 
291  /* nudge */
292 
293  , nudge_clock (new AudioClock (X_("nudge"), false, X_("nudge"), true, false, true))
294  , meters_running(false)
295  , _pending_locate_request (false)
296  , _pending_initial_locate (false)
297  , _last_cut_copy_source_track (0)
298 
299  , _region_selection_change_updates_region_list (true)
300  , _following_mixer_selection (false)
301  , _control_point_toggled_on_press (false)
302  , _stepping_axis_view (0)
303 {
304  constructed = false;
305 
306  /* we are a singleton */
307 
309 
310  _have_idled = false;
311 
312  selection = new Selection (this);
313  cut_buffer = new Selection (this);
315  selection_op_history.clear();
316  before.clear();
317 
318  clicked_regionview = 0;
319  clicked_axisview = 0;
320  clicked_routeview = 0;
322  last_update_frame = 0;
323  last_paste_pos = 0;
324  paste_count = 0;
325  _drags = new DragManager (this);
326  lock_dialog = 0;
327  ruler_dialog = 0;
329  tempo_lines = 0;
330 
336 #ifdef USE_RUBBERBAND
337  rb_opt_strings = I18N (_rb_opt_strings);
338  rb_current_opt = 4;
339 #endif
340 
347 
348  snap_threshold = 5.0;
354  logo_item = 0;
355 
356  analysis_window = 0;
357 
359  _show_measures = true;
360  _maximised = false;
361  show_gain_after_trim = false;
362 
364  _follow_playhead = true;
365  _stationary_playhead = false;
366  editor_ruler_menu = 0;
367  no_ruler_shown_update = false;
368  marker_menu = 0;
369  range_marker_menu = 0;
370  marker_menu_item = 0;
378  temp_location = 0;
379  leftmost_frame = 0;
381  entered_track = 0;
382  entered_regionview = 0;
383  entered_marker = 0;
384  clear_entered_track = false;
385  current_timefx = 0;
386  playhead_cursor = 0;
388  _dragging_playhead = false;
389  _dragging_edit_point = false;
390  select_new_marker = false;
391  rhythm_ferret = 0;
393  no_save_visual = false;
394  resize_idle_id = -1;
395  within_track_canvas = false;
396 
398 
399  sfbrowser = 0;
400 
401  location_marker_color = ARDOUR_UI::config()->color ("location marker");
402  location_range_color = ARDOUR_UI::config()->color ("location range");
403  location_cd_marker_color = ARDOUR_UI::config()->color ("location cd marker");
404  location_loop_color = ARDOUR_UI::config()->color ("location loop");
405  location_punch_color = ARDOUR_UI::config()->color ("location punch");
406 
407  zoom_focus = ZoomFocusPlayhead;
408  _edit_point = EditAtMouse;
410 
411  samples_per_pixel = 2048; /* too early to use reset_zoom () */
412 
413  timebar_height = std::max(12., ceil (15. * ARDOUR_UI::ui_scale));
416 
417  _scroll_callbacks = 0;
418 
419  bbt_label.set_name ("EditorRulerLabel");
420  bbt_label.set_size_request (-1, (int)timebar_height);
421  bbt_label.set_alignment (1.0, 0.5);
422  bbt_label.set_padding (5,0);
423  bbt_label.hide ();
424  bbt_label.set_no_show_all();
425  minsec_label.set_name ("EditorRulerLabel");
426  minsec_label.set_size_request (-1, (int)timebar_height);
427  minsec_label.set_alignment (1.0, 0.5);
428  minsec_label.set_padding (5,0);
429  minsec_label.hide ();
430  minsec_label.set_no_show_all();
431  timecode_label.set_name ("EditorRulerLabel");
432  timecode_label.set_size_request (-1, (int)timebar_height);
433  timecode_label.set_alignment (1.0, 0.5);
434  timecode_label.set_padding (5,0);
435  timecode_label.hide ();
436  timecode_label.set_no_show_all();
437  samples_label.set_name ("EditorRulerLabel");
438  samples_label.set_size_request (-1, (int)timebar_height);
439  samples_label.set_alignment (1.0, 0.5);
440  samples_label.set_padding (5,0);
441  samples_label.hide ();
442  samples_label.set_no_show_all();
443 
444  tempo_label.set_name ("EditorRulerLabel");
445  tempo_label.set_size_request (-1, (int)timebar_height);
446  tempo_label.set_alignment (1.0, 0.5);
447  tempo_label.set_padding (5,0);
448  tempo_label.hide();
449  tempo_label.set_no_show_all();
450 
451  meter_label.set_name ("EditorRulerLabel");
452  meter_label.set_size_request (-1, (int)timebar_height);
453  meter_label.set_alignment (1.0, 0.5);
454  meter_label.set_padding (5,0);
455  meter_label.hide();
456  meter_label.set_no_show_all();
457 
458  if (Profile->get_trx()) {
459  mark_label.set_text (_("Markers"));
460  }
461  mark_label.set_name ("EditorRulerLabel");
462  mark_label.set_size_request (-1, (int)timebar_height);
463  mark_label.set_alignment (1.0, 0.5);
464  mark_label.set_padding (5,0);
465  mark_label.hide();
466  mark_label.set_no_show_all();
467 
468  cd_mark_label.set_name ("EditorRulerLabel");
469  cd_mark_label.set_size_request (-1, (int)timebar_height);
470  cd_mark_label.set_alignment (1.0, 0.5);
471  cd_mark_label.set_padding (5,0);
472  cd_mark_label.hide();
473  cd_mark_label.set_no_show_all();
474 
475  videotl_bar_height = 4;
476  videotl_label.set_name ("EditorRulerLabel");
477  videotl_label.set_size_request (-1, (int)timebar_height * videotl_bar_height);
478  videotl_label.set_alignment (1.0, 0.5);
479  videotl_label.set_padding (5,0);
480  videotl_label.hide();
481  videotl_label.set_no_show_all();
482 
483  range_mark_label.set_name ("EditorRulerLabel");
484  range_mark_label.set_size_request (-1, (int)timebar_height);
485  range_mark_label.set_alignment (1.0, 0.5);
486  range_mark_label.set_padding (5,0);
487  range_mark_label.hide();
488  range_mark_label.set_no_show_all();
489 
490  transport_mark_label.set_name ("EditorRulerLabel");
491  transport_mark_label.set_size_request (-1, (int)timebar_height);
492  transport_mark_label.set_alignment (1.0, 0.5);
493  transport_mark_label.set_padding (5,0);
494  transport_mark_label.hide();
495  transport_mark_label.set_no_show_all();
496 
498 
499  CairoWidget::set_focus_handler (sigc::mem_fun (*this, &Editor::reset_focus));
500 
501  _summary = new EditorSummary (this);
502 
503  selection->TimeChanged.connect (sigc::mem_fun(*this, &Editor::time_selection_changed));
504  selection->TracksChanged.connect (sigc::mem_fun(*this, &Editor::track_selection_changed));
505 
507 
508  selection->PointsChanged.connect (sigc::mem_fun(*this, &Editor::point_selection_changed));
509  selection->MarkersChanged.connect (sigc::mem_fun(*this, &Editor::marker_selection_changed));
510 
511  edit_controls_vbox.set_spacing (0);
512  vertical_adjustment.signal_value_changed().connect (sigc::mem_fun(*this, &Editor::tie_vertical_scrolling), true);
513  _track_canvas->signal_map_event().connect (sigc::mem_fun (*this, &Editor::track_canvas_map_handler));
514 
515  HBox* h = manage (new HBox);
516  _group_tabs = new EditorGroupTabs (this);
517  if (!ARDOUR::Profile->get_trx()) {
518  h->pack_start (*_group_tabs, PACK_SHRINK);
519  }
520  h->pack_start (edit_controls_vbox);
521  controls_layout.add (*h);
522 
523  controls_layout.set_name ("EditControlsBase");
524  controls_layout.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK|Gdk::SCROLL_MASK);
525  controls_layout.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::edit_controls_button_release));
526  controls_layout.signal_scroll_event().connect (sigc::mem_fun(*this, &Editor::control_layout_scroll), false);
527 
528  _cursors = new MouseCursors;
529  _cursors->set_cursor_set (ARDOUR_UI::config()->get_icon_set());
530  cerr << "Set cursor set to " << ARDOUR_UI::config()->get_icon_set() << endl;
531 
532  /* Push default cursor to ever-present bottom of cursor stack. */
534 
535  ArdourCanvas::GtkCanvas* time_pad = manage (new ArdourCanvas::GtkCanvas ());
536 
537  ArdourCanvas::Line* pad_line_1 = new ArdourCanvas::Line (time_pad->root());
538  pad_line_1->set (ArdourCanvas::Duple (0.0, 1.0), ArdourCanvas::Duple (100.0, 1.0));
539  pad_line_1->set_outline_color (0xFF0000FF);
540  pad_line_1->show();
541 
542  // CAIROCANVAS
543  time_pad->show();
544 
545  edit_packer.set_col_spacings (0);
546  edit_packer.set_row_spacings (0);
547  edit_packer.set_homogeneous (false);
548  edit_packer.set_border_width (0);
549  edit_packer.set_name ("EditorWindow");
550 
552  time_bars_event_box.set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
553  time_bars_event_box.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::ruler_label_button_release));
554 
555  /* labels for the time bars */
556  edit_packer.attach (time_bars_event_box, 0, 1, 0, 1, FILL, SHRINK, 0, 0);
557  /* track controls */
558  edit_packer.attach (controls_layout, 0, 1, 1, 2, FILL, FILL|EXPAND, 0, 0);
559  /* canvas */
560  edit_packer.attach (*_track_canvas_viewport, 1, 2, 0, 2, FILL|EXPAND, FILL|EXPAND, 0, 0);
561 
562  bottom_hbox.set_border_width (2);
563  bottom_hbox.set_spacing (3);
564 
565  _route_groups = new EditorRouteGroups (this);
566  _routes = new EditorRoutes (this);
567  _regions = new EditorRegions (this);
568  _snapshots = new EditorSnapshots (this);
569  _locations = new EditorLocations (this);
570 
571  /* these are static location signals */
572 
573  Location::start_changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
574  Location::end_changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
575  Location::changed.connect (*this, invalidator (*this), boost::bind (&Editor::location_changed, this, _1), gui_context());
576 
577  add_notebook_page (_("Regions"), _regions->widget ());
578  add_notebook_page (_("Tracks & Busses"), _routes->widget ());
579  add_notebook_page (_("Snapshots"), _snapshots->widget ());
580  add_notebook_page (_("Track & Bus Groups"), _route_groups->widget ());
581  add_notebook_page (_("Ranges & Marks"), _locations->widget ());
582 
583  _the_notebook.set_show_tabs (true);
584  _the_notebook.set_scrollable (true);
585  _the_notebook.popup_disable ();
586  _the_notebook.set_tab_pos (Gtk::POS_RIGHT);
587  _the_notebook.show_all ();
588 
589  _notebook_shrunk = false;
590 
592 
593  Button* summary_arrows_left_left = manage (new Button);
594  summary_arrows_left_left->add (*manage (new Arrow (ARROW_LEFT, SHADOW_NONE)));
595  summary_arrows_left_left->signal_pressed().connect (sigc::hide_return (sigc::bind (sigc::mem_fun (*this, &Editor::scroll_press), LEFT)));
596  summary_arrows_left_left->signal_released().connect (sigc::mem_fun (*this, &Editor::scroll_release));
597 
598  Button* summary_arrows_left_right = manage (new Button);
599  summary_arrows_left_right->add (*manage (new Arrow (ARROW_RIGHT, SHADOW_NONE)));
600  summary_arrows_left_right->signal_pressed().connect (sigc::hide_return (sigc::bind (sigc::mem_fun (*this, &Editor::scroll_press), RIGHT)));
601  summary_arrows_left_right->signal_released().connect (sigc::mem_fun (*this, &Editor::scroll_release));
602 
603  VBox* summary_arrows_left = manage (new VBox);
604  summary_arrows_left->pack_start (*summary_arrows_left_left);
605  summary_arrows_left->pack_start (*summary_arrows_left_right);
606 
607  Button* summary_arrows_right_up = manage (new Button);
608  summary_arrows_right_up->add (*manage (new Arrow (ARROW_UP, SHADOW_NONE)));
609  summary_arrows_right_up->signal_pressed().connect (sigc::hide_return (sigc::bind (sigc::mem_fun (*this, &Editor::scroll_press), UP)));
610  summary_arrows_right_up->signal_released().connect (sigc::mem_fun (*this, &Editor::scroll_release));
611 
612  Button* summary_arrows_right_down = manage (new Button);
613  summary_arrows_right_down->add (*manage (new Arrow (ARROW_DOWN, SHADOW_NONE)));
614  summary_arrows_right_down->signal_pressed().connect (sigc::hide_return (sigc::bind (sigc::mem_fun (*this, &Editor::scroll_press), DOWN)));
615  summary_arrows_right_down->signal_released().connect (sigc::mem_fun (*this, &Editor::scroll_release));
616 
617  VBox* summary_arrows_right = manage (new VBox);
618  summary_arrows_right->pack_start (*summary_arrows_right_up);
619  summary_arrows_right->pack_start (*summary_arrows_right_down);
620 
621  Frame* summary_frame = manage (new Frame);
622  summary_frame->set_shadow_type (Gtk::SHADOW_ETCHED_IN);
623 
624  summary_frame->add (*_summary);
625  summary_frame->show ();
626 
627  _summary_hbox.pack_start (*summary_arrows_left, false, false);
628  _summary_hbox.pack_start (*summary_frame, true, true);
629  _summary_hbox.pack_start (*summary_arrows_right, false, false);
630 
631  if (!ARDOUR::Profile->get_trx()) {
633  }
634 
635  edit_pane.pack1 (editor_summary_pane, true, true);
636  if (!ARDOUR::Profile->get_trx()) {
637  edit_pane.pack2 (_the_notebook, false, true);
638  }
639 
640  editor_summary_pane.signal_size_allocate().connect (sigc::bind (sigc::mem_fun (*this, &Editor::pane_allocation_handler), static_cast<Paned*> (&editor_summary_pane)));
641 
642  /* XXX: editor_summary_pane might need similar to the edit_pane */
643 
644  edit_pane.signal_size_allocate().connect (sigc::bind (sigc::mem_fun(*this, &Editor::pane_allocation_handler), static_cast<Paned*> (&edit_pane)));
645 
646  Glib::PropertyProxy<int> proxy = edit_pane.property_position();
647  proxy.signal_changed().connect (bind (sigc::ptr_fun (pane_size_watcher), static_cast<Paned*> (&edit_pane)));
648 
649  top_hbox.pack_start (toolbar_frame);
650 
651  HBox *hbox = manage (new HBox);
652  hbox->pack_start (edit_pane, true, true);
653 
654  global_vpacker.pack_start (top_hbox, false, false);
655  global_vpacker.pack_start (*hbox, true, true);
656 
657  global_hpacker.pack_start (global_vpacker, true, true);
658 
659  set_name ("EditorWindow");
660  add_accel_group (ActionManager::ui_manager->get_accel_group());
661 
662  status_bar_hpacker.show ();
663 
664  vpacker.pack_end (status_bar_hpacker, false, false);
665  vpacker.pack_end (global_hpacker, true, true);
666 
667  /* register actions now so that set_state() can find them and set toggles/checks etc */
668 
669  register_actions ();
670  /* when we start using our own keybinding system for the editor, this
671  * will be uncommented
672  */
673  // load_bindings ();
674 
675  setup_toolbar ();
676 
679  _snap_type = SnapToBeat;
681  _snap_mode = SnapOff;
683  set_mouse_mode (MouseObject, true);
688  set_edit_point_preference (EditAtMouse, true);
689 
691  _playlist_selector->signal_delete_event().connect (sigc::bind (sigc::ptr_fun (just_hide_it), static_cast<Window *> (_playlist_selector)));
692 
693  RegionView::RegionViewGoingAway.connect (*this, invalidator (*this), boost::bind (&Editor::catch_vanishing_regionview, this, _1), gui_context());
694 
695  /* nudge stuff */
696 
697  nudge_forward_button.set_name ("nudge button");
698  nudge_forward_button.set_image(::get_icon("nudge_right"));
699 
700  nudge_backward_button.set_name ("nudge button");
701  nudge_backward_button.set_image(::get_icon("nudge_left"));
702 
703  fade_context_menu.set_name ("ArdourContextMenu");
704 
705  /* icons, titles, WM stuff */
706 
707  list<Glib::RefPtr<Gdk::Pixbuf> > window_icons;
708  Glib::RefPtr<Gdk::Pixbuf> icon;
709 
710  if ((icon = ::get_icon ("ardour_icon_16px")) != 0) {
711  window_icons.push_back (icon);
712  }
713  if ((icon = ::get_icon ("ardour_icon_22px")) != 0) {
714  window_icons.push_back (icon);
715  }
716  if ((icon = ::get_icon ("ardour_icon_32px")) != 0) {
717  window_icons.push_back (icon);
718  }
719  if ((icon = ::get_icon ("ardour_icon_48px")) != 0) {
720  window_icons.push_back (icon);
721  }
722  if (!window_icons.empty()) {
723  // set_icon_list (window_icons);
724  set_default_icon_list (window_icons);
725  }
726 
727  WindowTitle title(Glib::get_application_name());
728  title += _("Editor");
729  set_title (title.get_string());
730  set_wmclass (X_("ardour_editor"), PROGRAM_NAME);
731 
732  add (vpacker);
733  add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK);
734 
735  signal_configure_event().connect (sigc::mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::configure_handler));
736  signal_delete_event().connect (sigc::mem_fun (*ARDOUR_UI::instance(), &ARDOUR_UI::exit_on_main_window_close));
737 
739 
740  /* allow external control surfaces/protocols to do various things */
741 
742  ControlProtocol::ZoomToSession.connect (*this, invalidator (*this), boost::bind (&Editor::temporal_zoom_session, this), gui_context());
743  ControlProtocol::ZoomIn.connect (*this, invalidator (*this), boost::bind (&Editor::temporal_zoom_step, this, false), gui_context());
744  ControlProtocol::ZoomOut.connect (*this, invalidator (*this), boost::bind (&Editor::temporal_zoom_step, this, true), gui_context());
745  ControlProtocol::Undo.connect (*this, invalidator (*this), boost::bind (&Editor::undo, this, true), gui_context());
746  ControlProtocol::Redo.connect (*this, invalidator (*this), boost::bind (&Editor::redo, this, true), gui_context());
747  ControlProtocol::ScrollTimeline.connect (*this, invalidator (*this), boost::bind (&Editor::control_scroll, this, _1), gui_context());
748  ControlProtocol::StepTracksUp.connect (*this, invalidator (*this), boost::bind (&Editor::control_step_tracks_up, this), gui_context());
749  ControlProtocol::StepTracksDown.connect (*this, invalidator (*this), boost::bind (&Editor::control_step_tracks_down, this), gui_context());
750  ControlProtocol::GotoView.connect (*this, invalidator (*this), boost::bind (&Editor::control_view, this, _1), gui_context());
751  ControlProtocol::CloseDialog.connect (*this, invalidator (*this), Keyboard::close_current_dialog, gui_context());
752  ControlProtocol::VerticalZoomInAll.connect (*this, invalidator (*this), boost::bind (&Editor::control_vertical_zoom_in_all, this), gui_context());
753  ControlProtocol::VerticalZoomOutAll.connect (*this, invalidator (*this), boost::bind (&Editor::control_vertical_zoom_out_all, this), gui_context());
754  ControlProtocol::VerticalZoomInSelected.connect (*this, invalidator (*this), boost::bind (&Editor::control_vertical_zoom_in_selected, this), gui_context());
755  ControlProtocol::VerticalZoomOutSelected.connect (*this, invalidator (*this), boost::bind (&Editor::control_vertical_zoom_out_selected, this), gui_context());
756 
757  ControlProtocol::AddRouteToSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_select, this, _1, Selection::Add), gui_context());
758  ControlProtocol::RemoveRouteFromSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_select, this, _1, Selection::Toggle), gui_context());
759  ControlProtocol::SetRouteSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_select, this, _1, Selection::Set), gui_context());
760  ControlProtocol::ToggleRouteSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_select, this, _1, Selection::Toggle), gui_context());
761  ControlProtocol::ClearRouteSelection.connect (*this, invalidator (*this), boost::bind (&Editor::control_unselect, this), gui_context());
762 
763  BasicUI::AccessAction.connect (*this, invalidator (*this), boost::bind (&Editor::access_action, this, _1, _2), gui_context());
764 
765  /* problematic: has to return a value and thus cannot be x-thread */
766 
767  Session::AskAboutPlaylistDeletion.connect_same_thread (*this, boost::bind (&Editor::playlist_deletion_dialog, this, _1));
768 
769  Config->ParameterChanged.connect (*this, invalidator (*this), boost::bind (&Editor::parameter_changed, this, _1), gui_context());
770  ARDOUR_UI::config()->ParameterChanged.connect (sigc::mem_fun (*this, &Editor::ui_parameter_changed));
771 
772  TimeAxisView::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&Editor::timeaxisview_deleted, this, _1), gui_context());
773 
774  _ignore_region_action = false;
777 
778  _ignore_follow_edits = false;
779 
780  _show_marker_lines = false;
781 
782  /* Button bindings */
783 
785 
786  XMLNode* node = button_settings();
787  if (node) {
788  for (XMLNodeList::const_iterator i = node->children().begin(); i != node->children().end(); ++i) {
789  button_bindings->load (**i);
790  }
791  }
792 
793  constructed = true;
794 
795  /* grab current parameter state */
796  boost::function<void (string)> pc (boost::bind (&Editor::ui_parameter_changed, this, _1));
798 
800 
801  instant_save ();
802 }
803 
805 {
806  delete button_bindings;
807  delete _routes;
808  delete _route_groups;
809  delete _track_canvas_viewport;
810  delete _drags;
811  delete nudge_clock;
812 }
813 
814 XMLNode*
816 {
818  XMLNode* node = find_named_node (*settings, X_("Buttons"));
819 
820  if (!node) {
821  node = new XMLNode (X_("Buttons"));
822  }
823 
824  return node;
825 }
826 
827 void
828 Editor::add_toplevel_menu (Container& cont)
829 {
830  vpacker.pack_start (cont, false, false);
831  cont.show_all ();
832 }
833 
834 void
836 {
837  if(ARDOUR::Profile->get_mixbus()) {
838  global_vpacker.pack_start (cont, false, false);
839  global_vpacker.reorder_child (cont, 0);
840  cont.show_all ();
841  } else {
842  vpacker.pack_start (cont, false, false);
843  }
844 }
845 
846 bool
848 {
849  return ((current_mouse_mode() == Editing::MouseObject) && smart_mode_action->get_active());
850 }
851 
852 void
854 {
855  /* note: the selection will take care of the vanishing
856  audioregionview by itself.
857  */
858 
859  if (_drags->active() && _drags->have_item (rv->get_canvas_group()) && !_drags->ending()) {
860  _drags->abort ();
861  }
862 
863  if (clicked_regionview == rv) {
864  clicked_regionview = 0;
865  }
866 
867  if (entered_regionview == rv) {
869  }
870 
873  }
874 }
875 
876 void
878 {
879  if (rv == entered_regionview) {
880  return;
881  }
882 
883  if (entered_regionview) {
885  }
886 
887  entered_regionview = rv;
888 
889  if (entered_regionview != 0) {
891  }
892 
894  /* This RegionView entry might have changed what region actions
895  are allowed, so sensitize them all in case a key is pressed.
896  */
898  }
899 }
900 
901 void
903 {
904  if (entered_track) {
905  entered_track->exited ();
906  }
907 
908  entered_track = tav;
909 
910  if (entered_track) {
912  }
913 }
914 
915 void
917 {
918  if (!is_visible ()) {
919  DisplaySuspender ds;
920  show_all ();
921 
922  /* XXX: this is a bit unfortunate; it would probably
923  be nicer if we could just call show () above rather
924  than needing the show_all ()
925  */
926 
927  /* re-hide stuff if necessary */
929  parameter_changed ("show-summary");
930  parameter_changed ("show-group-tabs");
931  parameter_changed ("show-zoom-tools");
932 
933  /* now reset all audio_time_axis heights, because widgets might need
934  to be re-hidden
935  */
936 
937  TimeAxisView *tv;
938 
939  for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
940  tv = (static_cast<TimeAxisView*>(*i));
941  tv->reset_height ();
942  }
943 
944  if (current_mixer_strip) {
946  current_mixer_strip->parameter_changed ("mixer-element-visibility");
947  }
948  }
949 
950  present ();
951 }
952 
953 void
955 {
956  if (!constructed || !ARDOUR_UI::instance()->session_loaded) {
957  return;
958  }
959 
960  if (_session) {
962  } else {
964  }
965 }
966 
967 void
969 {
970  tav_zoom_smooth (false, true);
971 }
972 
973 void
975 {
976  tav_zoom_smooth (true, true);
977 }
978 
979 void
981 {
982  tav_zoom_smooth (false, false);
983 }
984 
985 void
987 {
988  tav_zoom_smooth (true, false);
989 }
990 
991 void
992 Editor::control_view (uint32_t view)
993 {
994  goto_visual_state (view);
995 }
996 
997 void
999 {
1000  selection->clear_tracks ();
1001 }
1002 
1003 void
1005 {
1006  /* handles the (static) signal from the ControlProtocol class that
1007  * requests setting the selected track to a given RID
1008  */
1009 
1010  if (!_session) {
1011  return;
1012  }
1013 
1015 
1016  if (!r) {
1017  return;
1018  }
1019 
1021 
1022  if (tav) {
1023  switch (op) {
1024  case Selection::Add:
1025  selection->add (tav);
1026  break;
1027  case Selection::Toggle:
1028  selection->toggle (tav);
1029  break;
1030  case Selection::Extend:
1031  break;
1032  case Selection::Set:
1033  selection->set (tav);
1034  break;
1035  }
1036  } else {
1037  selection->clear_tracks ();
1038  }
1039 }
1040 
1041 void
1043 {
1045 }
1046 
1047 void
1049 {
1051 }
1052 
1053 void
1054 Editor::control_scroll (float fraction)
1055 {
1056  ENSURE_GUI_THREAD (*this, &Editor::control_scroll, fraction)
1057 
1058  if (!_session) {
1059  return;
1060  }
1061 
1062  double step = fraction * current_page_samples();
1063 
1064  /*
1065  _control_scroll_target is an optional<T>
1066 
1067  it acts like a pointer to an framepos_t, with
1068  a operator conversion to boolean to check
1069  that it has a value could possibly use
1070  playhead_cursor->current_frame to store the
1071  value and a boolean in the class to know
1072  when it's out of date
1073  */
1074 
1075  if (!_control_scroll_target) {
1077  _dragging_playhead = true;
1078  }
1079 
1080  if ((fraction < 0.0f) && (*_control_scroll_target <= (framepos_t) fabs(step))) {
1082  } else if ((fraction > 0.0f) && (max_framepos - *_control_scroll_target < step)) {
1083  *_control_scroll_target = max_framepos - (current_page_samples()*2); // allow room for slop in where the PH is on the screen
1084  } else {
1085  *_control_scroll_target += (framepos_t) trunc (step);
1086  }
1087 
1088  /* move visuals, we'll catch up with it later */
1089 
1092 
1094  /* try to center PH in window */
1096  } else {
1097  reset_x_origin (0);
1098  }
1099 
1100  /*
1101  Now we do a timeout to actually bring the session to the right place
1102  according to the playhead. This is to avoid reading disk buffers on every
1103  call to control_scroll, which is driven by ScrollTimeline and therefore
1104  probably by a control surface wheel which can generate lots of events.
1105  */
1106  /* cancel the existing timeout */
1107 
1108  control_scroll_connection.disconnect ();
1109 
1110  /* add the next timeout */
1111 
1112  control_scroll_connection = Glib::signal_timeout().connect (sigc::bind (sigc::mem_fun (*this, &Editor::deferred_control_scroll), *_control_scroll_target), 250);
1113 }
1114 
1115 bool
1117 {
1119  // reset for next stream
1120  _control_scroll_target = boost::none;
1121  _dragging_playhead = false;
1122  return false;
1123 }
1124 
1125 void
1126 Editor::access_action (std::string action_group, std::string action_item)
1127 {
1128  if (!_session) {
1129  return;
1130  }
1131 
1132  ENSURE_GUI_THREAD (*this, &Editor::access_action, action_group, action_item)
1133 
1134  RefPtr<Action> act;
1135  act = ActionManager::get_action( action_group.c_str(), action_item.c_str() );
1136 
1137  if (act) {
1138  act->activate();
1139  }
1140 }
1141 
1142 void
1144 {
1145  Window::on_realize ();
1146  Realized ();
1147 
1148  if (ARDOUR_UI::config()->get_lock_gui_after_seconds()) {
1150  }
1151 
1152  signal_event().connect (sigc::mem_fun (*this, &Editor::generic_event_handler));
1153 }
1154 
1155 void
1157 {
1158  /* check if we should lock the GUI every 30 seconds */
1159 
1160  Glib::signal_timeout().connect (sigc::mem_fun (*this, &Editor::lock_timeout_callback), 30 * 1000);
1161 }
1162 
1163 bool
1165 {
1166  switch (ev->type) {
1167  case GDK_BUTTON_PRESS:
1168  case GDK_BUTTON_RELEASE:
1169  case GDK_MOTION_NOTIFY:
1170  case GDK_KEY_PRESS:
1171  case GDK_KEY_RELEASE:
1172  gettimeofday (&last_event_time, 0);
1173  break;
1174 
1175  case GDK_LEAVE_NOTIFY:
1176  switch (ev->crossing.detail) {
1177  case GDK_NOTIFY_UNKNOWN:
1178  case GDK_NOTIFY_INFERIOR:
1179  case GDK_NOTIFY_ANCESTOR:
1180  break;
1181  case GDK_NOTIFY_VIRTUAL:
1182  case GDK_NOTIFY_NONLINEAR:
1183  case GDK_NOTIFY_NONLINEAR_VIRTUAL:
1184  /* leaving window, so reset focus, thus ending any and
1185  all text entry operations.
1186  */
1187  reset_focus();
1188  break;
1189  }
1190  break;
1191 
1192  default:
1193  break;
1194  }
1195 
1196  return false;
1197 }
1198 
1199 bool
1201 {
1202  struct timeval now, delta;
1203 
1204  gettimeofday (&now, 0);
1205 
1206  timersub (&now, &last_event_time, &delta);
1207 
1208  if (delta.tv_sec > (time_t) ARDOUR_UI::config()->get_lock_gui_after_seconds()) {
1209  lock ();
1210  /* don't call again. Returning false will effectively
1211  disconnect us from the timer callback.
1212 
1213  unlock() will call start_lock_event_timing() to get things
1214  started again.
1215  */
1216  return false;
1217  }
1218 
1219  return true;
1220 }
1221 
1222 void
1224 {
1226 
1227  if (_session == 0) {
1228  return;
1229  }
1230 
1231  if (_follow_playhead) {
1232  center_screen (frame);
1233  }
1234 
1235  playhead_cursor->set_position (frame);
1236 }
1237 
1238 void
1240 {
1242 
1243  /* if we're off the page, then scroll.
1244  */
1245 
1246  if (frame < leftmost_frame || frame >= leftmost_frame + page) {
1247  center_screen_internal (frame, page);
1248  }
1249 }
1250 
1251 void
1253 {
1254  page /= 2;
1255 
1256  if (frame > page) {
1257  frame -= (framepos_t) page;
1258  } else {
1259  frame = 0;
1260  }
1261 
1262  reset_x_origin (frame);
1263 }
1264 
1265 
1266 void
1268 {
1270 
1271  if (_session) {
1272  bool dirty = _session->dirty();
1273 
1274  string session_name;
1275 
1276  if (_session->snap_name() != _session->name()) {
1277  session_name = _session->snap_name();
1278  } else {
1279  session_name = _session->name();
1280  }
1281 
1282  if (dirty) {
1283  session_name = "*" + session_name;
1284  }
1285 
1286  WindowTitle title(session_name);
1287  title += Glib::get_application_name();
1288  set_title (title.get_string());
1289  } else {
1290  /* ::session_going_away() will have taken care of it */
1291  }
1292 }
1293 
1294 void
1296 {
1297  SessionHandlePtr::set_session (t);
1298 
1299  if (!_session) {
1300  return;
1301  }
1302 
1312 
1313  if (rhythm_ferret) {
1315  }
1316 
1317  if (analysis_window) {
1319  }
1320 
1321  if (sfbrowser) {
1323  }
1324 
1326 
1327  /* Make sure we have auto loop and auto punch ranges */
1328 
1330  if (loc != 0) {
1331  loc->set_name (_("Loop"));
1332  }
1333 
1335  if (loc != 0) {
1336  // force name
1337  loc->set_name (_("Punch"));
1338  }
1339 
1341 
1342  /* This must happen after refresh_location_display(), as (amongst other things) we restore
1343  the selected Marker; this needs the LocationMarker list to be available.
1344  */
1346  set_state (*node, Stateful::loading_state_version);
1347 
1348  /* catch up with the playhead */
1349 
1351  _pending_initial_locate = true;
1352 
1353  update_title ();
1354 
1355  /* These signals can all be emitted by a non-GUI thread. Therefore the
1356  handlers for them must not attempt to directly interact with the GUI,
1357  but use PBD::Signal<T>::connect() which accepts an event loop
1358  ("context") where the handler will be asked to run.
1359  */
1360 
1363  _session->PositionChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::map_position_change, this, _1), gui_context());
1364  _session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&Editor::add_routes, this, _1), gui_context());
1365  _session->DirtyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::update_title, this), gui_context());
1366  _session->tempo_map().PropertyChanged.connect (_session_connections, invalidator (*this), boost::bind (&Editor::tempo_map_changed, this, _1), gui_context());
1367  _session->Located.connect (_session_connections, invalidator (*this), boost::bind (&Editor::located, this), gui_context());
1369  _session->StateSaved.connect (_session_connections, invalidator (*this), boost::bind (&Editor::session_state_saved, this, _1), gui_context());
1370  _session->locations()->added.connect (_session_connections, invalidator (*this), boost::bind (&Editor::add_new_location, this, _1), gui_context());
1371  _session->locations()->removed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::location_gone, this, _1), gui_context());
1373  _session->history().Changed.connect (_session_connections, invalidator (*this), boost::bind (&Editor::history_changed, this), gui_context());
1374 
1375  playhead_cursor->show ();
1376 
1377  boost::function<void (string)> pc (boost::bind (&Editor::parameter_changed, this, _1));
1378  Config->map_parameters (pc);
1380 
1382  //tempo_map_changed (PropertyChange (0));
1384 
1385  for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
1386  (static_cast<TimeAxisView*>(*i))->set_samples_per_pixel (samples_per_pixel);
1387  }
1388 
1390  sigc::mem_fun (*this, &Editor::super_rapid_screen_update)
1391  );
1392 
1393  switch (_snap_type) {
1394  case SnapToRegionStart:
1395  case SnapToRegionEnd:
1396  case SnapToRegionSync:
1397  case SnapToRegionBoundary:
1399  break;
1400 
1401  default:
1402  break;
1403  }
1404 
1405  /* register for undo history */
1408 
1409  ActionManager::ui_manager->signal_pre_activate().connect (sigc::mem_fun (*this, &Editor::action_pre_activated));
1410 
1412 }
1413 
1414 void
1415 Editor::action_pre_activated (Glib::RefPtr<Action> const & a)
1416 {
1417  if (a->get_name() == "RegionMenu") {
1418  /* When the main menu's region menu is opened, we setup the actions so that they look right
1419  in the menu. I can't find a way of getting a signal when this menu is subsequently closed,
1420  so we resensitize all region actions when the entered regionview or the region selection
1421  changes. HOWEVER we can't always resensitize on entered_regionview change because that
1422  happens after the region context menu is opened. So we set a flag here, too.
1423 
1424  What a carry on :(
1425  */
1428  }
1429 }
1430 
1431 void
1432 Editor::fill_xfade_menu (Menu_Helpers::MenuList& items, bool start)
1433 {
1434  using namespace Menu_Helpers;
1435 
1436  void (Editor::*emf)(FadeShape);
1437  std::map<ARDOUR::FadeShape,Gtk::Image*>* images;
1438 
1439  if (start) {
1440  images = &_xfade_in_images;
1442  } else {
1443  images = &_xfade_out_images;
1445  }
1446 
1447  items.push_back (
1448  ImageMenuElem (
1449  _("Linear (for highly correlated material)"),
1450  *(*images)[FadeLinear],
1451  sigc::bind (sigc::mem_fun (*this, emf), FadeLinear)
1452  )
1453  );
1454 
1455  dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
1456 
1457  items.push_back (
1458  ImageMenuElem (
1459  _("Constant power"),
1460  *(*images)[FadeConstantPower],
1461  sigc::bind (sigc::mem_fun (*this, emf), FadeConstantPower)
1462  ));
1463 
1464  dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
1465 
1466  items.push_back (
1467  ImageMenuElem (
1468  _("Symmetric"),
1469  *(*images)[FadeSymmetric],
1470  sigc::bind (sigc::mem_fun (*this, emf), FadeSymmetric)
1471  )
1472  );
1473 
1474  dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
1475 
1476  items.push_back (
1477  ImageMenuElem (
1478  _("Slow"),
1479  *(*images)[FadeSlow],
1480  sigc::bind (sigc::mem_fun (*this, emf), FadeSlow)
1481  ));
1482 
1483  dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
1484 
1485  items.push_back (
1486  ImageMenuElem (
1487  _("Fast"),
1488  *(*images)[FadeFast],
1489  sigc::bind (sigc::mem_fun (*this, emf), FadeFast)
1490  ));
1491 
1492  dynamic_cast<ImageMenuItem*>(&items.back())->set_always_show_image ();
1493 }
1494 
1496 void
1497 Editor::popup_xfade_in_context_menu (int button, int32_t time, ArdourCanvas::Item* item, ItemType /*item_type*/)
1498 {
1499  using namespace Menu_Helpers;
1500  AudioRegionView* arv = dynamic_cast<AudioRegionView*> ((RegionView*)item->get_data ("regionview"));
1501  if (!arv) {
1502  return;
1503  }
1504 
1505  MenuList& items (xfade_in_context_menu.items());
1506  items.clear ();
1507 
1508  if (arv->audio_region()->fade_in_active()) {
1509  items.push_back (MenuElem (_("Deactivate"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_active), false)));
1510  } else {
1511  items.push_back (MenuElem (_("Activate"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_in_active), true)));
1512  }
1513 
1514  items.push_back (SeparatorElem());
1515  fill_xfade_menu (items, true);
1516 
1517  xfade_in_context_menu.popup (button, time);
1518 }
1519 
1521 void
1522 Editor::popup_xfade_out_context_menu (int button, int32_t time, ArdourCanvas::Item* item, ItemType /*item_type*/)
1523 {
1524  using namespace Menu_Helpers;
1525  AudioRegionView* arv = dynamic_cast<AudioRegionView*> ((RegionView*)item->get_data ("regionview"));
1526  if (!arv) {
1527  return;
1528  }
1529 
1530  MenuList& items (xfade_out_context_menu.items());
1531  items.clear ();
1532 
1533  if (arv->audio_region()->fade_out_active()) {
1534  items.push_back (MenuElem (_("Deactivate"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_active), false)));
1535  } else {
1536  items.push_back (MenuElem (_("Activate"), sigc::bind (sigc::mem_fun (*this, &Editor::set_fade_out_active), true)));
1537  }
1538 
1539  items.push_back (SeparatorElem());
1540  fill_xfade_menu (items, false);
1541 
1542  xfade_out_context_menu.popup (button, time);
1543 }
1544 
1545 void
1546 Editor::popup_track_context_menu (int button, int32_t time, ItemType item_type, bool with_selection)
1547 {
1548  using namespace Menu_Helpers;
1549  Menu* (Editor::*build_menu_function)();
1550  Menu *menu;
1551 
1552  switch (item_type) {
1553  case RegionItem:
1554  case RegionViewName:
1556  case LeftFrameHandle:
1557  case RightFrameHandle:
1558  if (with_selection) {
1559  build_menu_function = &Editor::build_track_selection_context_menu;
1560  } else {
1561  build_menu_function = &Editor::build_track_region_context_menu;
1562  }
1563  break;
1564 
1565  case SelectionItem:
1566  if (with_selection) {
1567  build_menu_function = &Editor::build_track_selection_context_menu;
1568  } else {
1569  build_menu_function = &Editor::build_track_context_menu;
1570  }
1571  break;
1572 
1573  case StreamItem:
1574  if (clicked_routeview->track()) {
1575  build_menu_function = &Editor::build_track_context_menu;
1576  } else {
1577  build_menu_function = &Editor::build_track_bus_context_menu;
1578  }
1579  break;
1580 
1581  default:
1582  /* probably shouldn't happen but if it does, we don't care */
1583  return;
1584  }
1585 
1586  menu = (this->*build_menu_function)();
1587  menu->set_name ("ArdourContextMenu");
1588 
1589  /* now handle specific situations */
1590 
1591  switch (item_type) {
1592  case RegionItem:
1593  case RegionViewName:
1595  case LeftFrameHandle:
1596  case RightFrameHandle:
1597  if (!with_selection) {
1601  } else {
1603  }
1604  }
1607  region_edit_menu_split_multichannel_item->set_sensitive (true);
1608  } else {
1609  region_edit_menu_split_multichannel_item->set_sensitive (false);
1610  }
1611  }
1612  }
1613  break;
1614 
1615  case SelectionItem:
1616  break;
1617 
1618  case StreamItem:
1619  break;
1620 
1621  default:
1622  /* probably shouldn't happen but if it does, we don't care */
1623  return;
1624  }
1625 
1626  if (item_type != SelectionItem && clicked_routeview && clicked_routeview->audio_track()) {
1627 
1628  /* Bounce to disk */
1629 
1630  using namespace Menu_Helpers;
1631  MenuList& edit_items = menu->items();
1632 
1633  edit_items.push_back (SeparatorElem());
1634 
1635  switch (clicked_routeview->audio_track()->freeze_state()) {
1636  case AudioTrack::NoFreeze:
1637  edit_items.push_back (MenuElem (_("Freeze"), sigc::mem_fun(*this, &Editor::freeze_route)));
1638  break;
1639 
1640  case AudioTrack::Frozen:
1641  edit_items.push_back (MenuElem (_("Unfreeze"), sigc::mem_fun(*this, &Editor::unfreeze_route)));
1642  break;
1643 
1644  case AudioTrack::UnFrozen:
1645  edit_items.push_back (MenuElem (_("Freeze"), sigc::mem_fun(*this, &Editor::freeze_route)));
1646  break;
1647  }
1648 
1649  }
1650 
1651  if (item_type == StreamItem && clicked_routeview) {
1653  }
1654 
1655  /* When the region menu is opened, we setup the actions so that they look right
1656  in the menu.
1657  */
1660 
1661  menu->signal_hide().connect (sigc::bind (sigc::mem_fun (*this, &Editor::sensitize_all_region_actions), true));
1662  menu->popup (button, time);
1663 }
1664 
1665 Menu*
1667 {
1668  using namespace Menu_Helpers;
1669 
1670  MenuList& edit_items = track_context_menu.items();
1671  edit_items.clear();
1672 
1673  add_dstream_context_items (edit_items);
1674  return &track_context_menu;
1675 }
1676 
1677 Menu*
1679 {
1680  using namespace Menu_Helpers;
1681 
1682  MenuList& edit_items = track_context_menu.items();
1683  edit_items.clear();
1684 
1685  add_bus_context_items (edit_items);
1686  return &track_context_menu;
1687 }
1688 
1689 Menu*
1691 {
1692  using namespace Menu_Helpers;
1693  MenuList& edit_items = track_region_context_menu.items();
1694  edit_items.clear();
1695 
1696  /* we've just cleared the track region context menu, so the menu that these
1697  two items were on will have disappeared; stop them dangling.
1698  */
1701 
1702  RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (clicked_axisview);
1703 
1704  if (rtv) {
1707 
1708  if ((tr = rtv->track())) {
1709  add_region_context_items (edit_items, tr);
1710  }
1711  }
1712 
1713  add_dstream_context_items (edit_items);
1714 
1715  return &track_region_context_menu;
1716 }
1717 
1718 void
1720 {
1721  if (analysis_window == 0) {
1723 
1724  if (_session != 0)
1726 
1727  analysis_window->show_all();
1728  }
1729 
1732 
1733  analysis_window->present();
1734 }
1735 
1736 void
1738 {
1739  if (analysis_window == 0) {
1741 
1742  if (_session != 0)
1744 
1745  analysis_window->show_all();
1746  }
1747 
1750 
1751  analysis_window->present();
1752 }
1753 
1754 Menu*
1756 {
1757  using namespace Menu_Helpers;
1758  MenuList& edit_items = track_selection_context_menu.items();
1759  edit_items.clear ();
1760 
1761  add_selection_context_items (edit_items);
1762  // edit_items.push_back (SeparatorElem());
1763  // add_dstream_context_items (edit_items);
1764 
1766 }
1767 
1768 void
1769 Editor::add_region_context_items (Menu_Helpers::MenuList& edit_items, boost::shared_ptr<Track> track)
1770 {
1771  using namespace Menu_Helpers;
1772 
1773  /* OK, stick the region submenu at the top of the list, and then add
1774  the standard items.
1775  */
1776 
1778 
1779  string::size_type pos = 0;
1780  string menu_item_name = (rs.size() == 1) ? rs.front()->region()->name() : _("Selected Regions");
1781 
1782  /* we have to hack up the region name because "_" has a special
1783  meaning for menu titles.
1784  */
1785 
1786  while ((pos = menu_item_name.find ("_", pos)) != string::npos) {
1787  menu_item_name.replace (pos, 1, "__");
1788  pos += 2;
1789  }
1790 
1791  if (_popup_region_menu_item == 0) {
1792  _popup_region_menu_item = new MenuItem (menu_item_name);
1793  _popup_region_menu_item->set_submenu (*dynamic_cast<Menu*> (ActionManager::get_widget (X_("/PopupRegionMenu"))));
1794  _popup_region_menu_item->show ();
1795  } else {
1796  _popup_region_menu_item->set_label (menu_item_name);
1797  }
1798 
1799  /* No latering allowed in later is higher layering model */
1800  RefPtr<Action> act = ActionManager::get_action (X_("EditorMenu"), X_("RegionMenuLayering"));
1801  if (act && Config->get_layer_model() == LaterHigher) {
1802  act->set_sensitive (false);
1803  } else if (act) {
1804  act->set_sensitive (true);
1805  }
1806 
1808 
1809  edit_items.push_back (*_popup_region_menu_item);
1810  if (Config->get_layer_model() == Manual && track->playlist()->count_regions_at (position) > 1 && (layering_order_editor == 0 || !layering_order_editor->is_visible ())) {
1811  edit_items.push_back (*manage (_region_actions->get_action ("choose-top-region-context-menu")->create_menu_item ()));
1812  }
1813  edit_items.push_back (SeparatorElem());
1814 }
1815 
1819 void
1820 Editor::add_selection_context_items (Menu_Helpers::MenuList& edit_items)
1821 {
1822  using namespace Menu_Helpers;
1823 
1824  edit_items.push_back (MenuElem (_("Play Range"), sigc::mem_fun(*this, &Editor::play_selection)));
1825  edit_items.push_back (MenuElem (_("Loop Range"), sigc::bind (sigc::mem_fun(*this, &Editor::set_loop_from_selection), true)));
1826 
1827  edit_items.push_back (SeparatorElem());
1828  edit_items.push_back (MenuElem (_("Zoom to Range"), sigc::bind (sigc::mem_fun(*this, &Editor::temporal_zoom_selection), false)));
1829 
1830  edit_items.push_back (SeparatorElem());
1831  edit_items.push_back (MenuElem (_("Spectral Analysis"), sigc::mem_fun(*this, &Editor::analyze_range_selection)));
1832 
1833  edit_items.push_back (SeparatorElem());
1834 
1835  edit_items.push_back (
1836  MenuElem (
1837  _("Move Range Start to Previous Region Boundary"),
1838  sigc::bind (sigc::mem_fun (*this, &Editor::move_range_selection_start_or_end_to_region_boundary), false, false)
1839  )
1840  );
1841 
1842  edit_items.push_back (
1843  MenuElem (
1844  _("Move Range Start to Next Region Boundary"),
1845  sigc::bind (sigc::mem_fun (*this, &Editor::move_range_selection_start_or_end_to_region_boundary), false, true)
1846  )
1847  );
1848 
1849  edit_items.push_back (
1850  MenuElem (
1851  _("Move Range End to Previous Region Boundary"),
1852  sigc::bind (sigc::mem_fun (*this, &Editor::move_range_selection_start_or_end_to_region_boundary), true, false)
1853  )
1854  );
1855 
1856  edit_items.push_back (
1857  MenuElem (
1858  _("Move Range End to Next Region Boundary"),
1859  sigc::bind (sigc::mem_fun (*this, &Editor::move_range_selection_start_or_end_to_region_boundary), true, true)
1860  )
1861  );
1862 
1863  edit_items.push_back (SeparatorElem());
1864  edit_items.push_back (MenuElem (_("Separate"), mem_fun(*this, &Editor::separate_region_from_selection)));
1865  edit_items.push_back (MenuElem (_("Convert to Region in Region List"), sigc::mem_fun(*this, &Editor::new_region_from_selection)));
1866 
1867  edit_items.push_back (SeparatorElem());
1868  edit_items.push_back (MenuElem (_("Select All in Range"), sigc::mem_fun(*this, &Editor::select_all_selectables_using_time_selection)));
1869 
1870  edit_items.push_back (SeparatorElem());
1871  edit_items.push_back (MenuElem (_("Set Loop from Selection"), sigc::bind (sigc::mem_fun(*this, &Editor::set_loop_from_selection), false)));
1872  edit_items.push_back (MenuElem (_("Set Punch from Selection"), sigc::mem_fun(*this, &Editor::set_punch_from_selection)));
1873  edit_items.push_back (MenuElem (_("Set Session Start/End from Selection"), sigc::mem_fun(*this, &Editor::set_session_extents_from_selection)));
1874 
1875  edit_items.push_back (SeparatorElem());
1876  edit_items.push_back (MenuElem (_("Add Range Markers"), sigc::mem_fun (*this, &Editor::add_location_from_selection)));
1877 
1878  edit_items.push_back (SeparatorElem());
1879  edit_items.push_back (MenuElem (_("Crop Region to Range"), sigc::mem_fun(*this, &Editor::crop_region_to_selection)));
1880  edit_items.push_back (MenuElem (_("Fill Range with Region"), sigc::mem_fun(*this, &Editor::region_fill_selection)));
1881  edit_items.push_back (MenuElem (_("Duplicate Range"), sigc::bind (sigc::mem_fun(*this, &Editor::duplicate_range), false)));
1882 
1883  edit_items.push_back (SeparatorElem());
1884  edit_items.push_back (MenuElem (_("Consolidate Range"), sigc::bind (sigc::mem_fun(*this, &Editor::bounce_range_selection), true, false)));
1885  edit_items.push_back (MenuElem (_("Consolidate Range With Processing"), sigc::bind (sigc::mem_fun(*this, &Editor::bounce_range_selection), true, true)));
1886  edit_items.push_back (MenuElem (_("Bounce Range to Region List"), sigc::bind (sigc::mem_fun(*this, &Editor::bounce_range_selection), false, false)));
1887  edit_items.push_back (MenuElem (_("Bounce Range to Region List With Processing"), sigc::bind (sigc::mem_fun(*this, &Editor::bounce_range_selection), false, true)));
1888  edit_items.push_back (MenuElem (_("Export Range..."), sigc::mem_fun(*this, &Editor::export_selection)));
1889  if (ARDOUR_UI::instance()->video_timeline->get_duration() > 0) {
1890  edit_items.push_back (MenuElem (_("Export Video Range..."), sigc::bind (sigc::mem_fun(*(ARDOUR_UI::instance()), &ARDOUR_UI::export_video), true)));
1891  }
1892 }
1893 
1894 
1895 void
1896 Editor::add_dstream_context_items (Menu_Helpers::MenuList& edit_items)
1897 {
1898  using namespace Menu_Helpers;
1899 
1900  /* Playback */
1901 
1902  Menu *play_menu = manage (new Menu);
1903  MenuList& play_items = play_menu->items();
1904  play_menu->set_name ("ArdourContextMenu");
1905 
1906  play_items.push_back (MenuElem (_("Play From Edit Point"), sigc::mem_fun(*this, &Editor::play_from_edit_point)));
1907  play_items.push_back (MenuElem (_("Play From Start"), sigc::mem_fun(*this, &Editor::play_from_start)));
1908  play_items.push_back (MenuElem (_("Play Region"), sigc::mem_fun(*this, &Editor::play_selected_region)));
1909  play_items.push_back (SeparatorElem());
1910  play_items.push_back (MenuElem (_("Loop Region"), sigc::bind (sigc::mem_fun (*this, &Editor::set_loop_from_region), true)));
1911 
1912  edit_items.push_back (MenuElem (_("Play"), *play_menu));
1913 
1914  /* Selection */
1915 
1916  Menu *select_menu = manage (new Menu);
1917  MenuList& select_items = select_menu->items();
1918  select_menu->set_name ("ArdourContextMenu");
1919 
1920  select_items.push_back (MenuElem (_("Select All in Track"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_in_track), Selection::Set)));
1921  select_items.push_back (MenuElem (_("Select All Objects"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_objects), Selection::Set)));
1922  select_items.push_back (MenuElem (_("Invert Selection in Track"), sigc::mem_fun(*this, &Editor::invert_selection_in_track)));
1923  select_items.push_back (MenuElem (_("Invert Selection"), sigc::mem_fun(*this, &Editor::invert_selection)));
1924  select_items.push_back (SeparatorElem());
1925  select_items.push_back (MenuElem (_("Set Range to Loop Range"), sigc::mem_fun(*this, &Editor::set_selection_from_loop)));
1926  select_items.push_back (MenuElem (_("Set Range to Punch Range"), sigc::mem_fun(*this, &Editor::set_selection_from_punch)));
1927  select_items.push_back (MenuElem (_("Set Range to Selected Regions"), sigc::mem_fun(*this, &Editor::set_selection_from_region)));
1928  select_items.push_back (SeparatorElem());
1929  select_items.push_back (MenuElem (_("Select All After Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_edit), true)));
1930  select_items.push_back (MenuElem (_("Select All Before Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_edit), false)));
1931  select_items.push_back (MenuElem (_("Select All After Playhead"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, true)));
1932  select_items.push_back (MenuElem (_("Select All Before Playhead"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, false)));
1933  select_items.push_back (MenuElem (_("Select All Between Playhead and Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_between), false)));
1934  select_items.push_back (MenuElem (_("Select All Within Playhead and Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_between), true)));
1935  select_items.push_back (MenuElem (_("Select Range Between Playhead and Edit Point"), sigc::mem_fun(*this, &Editor::select_range_between)));
1936 
1937  edit_items.push_back (MenuElem (_("Select"), *select_menu));
1938 
1939  /* Cut-n-Paste */
1940 
1941  Menu *cutnpaste_menu = manage (new Menu);
1942  MenuList& cutnpaste_items = cutnpaste_menu->items();
1943  cutnpaste_menu->set_name ("ArdourContextMenu");
1944 
1945  cutnpaste_items.push_back (MenuElem (_("Cut"), sigc::mem_fun(*this, &Editor::cut)));
1946  cutnpaste_items.push_back (MenuElem (_("Copy"), sigc::mem_fun(*this, &Editor::copy)));
1947  cutnpaste_items.push_back (MenuElem (_("Paste"), sigc::bind (sigc::mem_fun(*this, &Editor::paste), 1.0f, true)));
1948 
1949  cutnpaste_items.push_back (SeparatorElem());
1950 
1951  cutnpaste_items.push_back (MenuElem (_("Align"), sigc::bind (sigc::mem_fun (*this, &Editor::align_regions), ARDOUR::SyncPoint)));
1952  cutnpaste_items.push_back (MenuElem (_("Align Relative"), sigc::bind (sigc::mem_fun (*this, &Editor::align_regions_relative), ARDOUR::SyncPoint)));
1953 
1954  edit_items.push_back (MenuElem (_("Edit"), *cutnpaste_menu));
1955 
1956  /* Adding new material */
1957 
1958  edit_items.push_back (SeparatorElem());
1959  edit_items.push_back (MenuElem (_("Insert Selected Region"), sigc::bind (sigc::mem_fun(*this, &Editor::insert_region_list_selection), 1.0f)));
1960  edit_items.push_back (MenuElem (_("Insert Existing Media"), sigc::bind (sigc::mem_fun(*this, &Editor::add_external_audio_action), ImportToTrack)));
1961 
1962  /* Nudge track */
1963 
1964  Menu *nudge_menu = manage (new Menu());
1965  MenuList& nudge_items = nudge_menu->items();
1966  nudge_menu->set_name ("ArdourContextMenu");
1967 
1968  edit_items.push_back (SeparatorElem());
1969  nudge_items.push_back (MenuElem (_("Nudge Entire Track Later"), (sigc::bind (sigc::mem_fun(*this, &Editor::nudge_track), false, true))));
1970  nudge_items.push_back (MenuElem (_("Nudge Track After Edit Point Later"), (sigc::bind (sigc::mem_fun(*this, &Editor::nudge_track), true, true))));
1971  nudge_items.push_back (MenuElem (_("Nudge Entire Track Earlier"), (sigc::bind (sigc::mem_fun(*this, &Editor::nudge_track), false, false))));
1972  nudge_items.push_back (MenuElem (_("Nudge Track After Edit Point Earlier"), (sigc::bind (sigc::mem_fun(*this, &Editor::nudge_track), true, false))));
1973 
1974  edit_items.push_back (MenuElem (_("Nudge"), *nudge_menu));
1975 }
1976 
1977 void
1978 Editor::add_bus_context_items (Menu_Helpers::MenuList& edit_items)
1979 {
1980  using namespace Menu_Helpers;
1981 
1982  /* Playback */
1983 
1984  Menu *play_menu = manage (new Menu);
1985  MenuList& play_items = play_menu->items();
1986  play_menu->set_name ("ArdourContextMenu");
1987 
1988  play_items.push_back (MenuElem (_("Play From Edit Point"), sigc::mem_fun(*this, &Editor::play_from_edit_point)));
1989  play_items.push_back (MenuElem (_("Play From Start"), sigc::mem_fun(*this, &Editor::play_from_start)));
1990  edit_items.push_back (MenuElem (_("Play"), *play_menu));
1991 
1992  /* Selection */
1993 
1994  Menu *select_menu = manage (new Menu);
1995  MenuList& select_items = select_menu->items();
1996  select_menu->set_name ("ArdourContextMenu");
1997 
1998  select_items.push_back (MenuElem (_("Select All in Track"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_in_track), Selection::Set)));
1999  select_items.push_back (MenuElem (_("Select All Objects"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_objects), Selection::Set)));
2000  select_items.push_back (MenuElem (_("Invert Selection in Track"), sigc::mem_fun(*this, &Editor::invert_selection_in_track)));
2001  select_items.push_back (MenuElem (_("Invert Selection"), sigc::mem_fun(*this, &Editor::invert_selection)));
2002  select_items.push_back (SeparatorElem());
2003  select_items.push_back (MenuElem (_("Select All After Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_edit), true)));
2004  select_items.push_back (MenuElem (_("Select All Before Edit Point"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_edit), false)));
2005  select_items.push_back (MenuElem (_("Select All After Playhead"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, true)));
2006  select_items.push_back (MenuElem (_("Select All Before Playhead"), sigc::bind (sigc::mem_fun(*this, &Editor::select_all_selectables_using_cursor), playhead_cursor, false)));
2007 
2008  edit_items.push_back (MenuElem (_("Select"), *select_menu));
2009 
2010  /* Cut-n-Paste */
2011 
2012  Menu *cutnpaste_menu = manage (new Menu);
2013  MenuList& cutnpaste_items = cutnpaste_menu->items();
2014  cutnpaste_menu->set_name ("ArdourContextMenu");
2015 
2016  cutnpaste_items.push_back (MenuElem (_("Cut"), sigc::mem_fun(*this, &Editor::cut)));
2017  cutnpaste_items.push_back (MenuElem (_("Copy"), sigc::mem_fun(*this, &Editor::copy)));
2018  cutnpaste_items.push_back (MenuElem (_("Paste"), sigc::bind (sigc::mem_fun(*this, &Editor::paste), 1.0f, true)));
2019 
2020  Menu *nudge_menu = manage (new Menu());
2021  MenuList& nudge_items = nudge_menu->items();
2022  nudge_menu->set_name ("ArdourContextMenu");
2023 
2024  edit_items.push_back (SeparatorElem());
2025  nudge_items.push_back (MenuElem (_("Nudge Entire Track Later"), (sigc::bind (sigc::mem_fun(*this, &Editor::nudge_track), false, true))));
2026  nudge_items.push_back (MenuElem (_("Nudge Track After Edit Point Later"), (sigc::bind (sigc::mem_fun(*this, &Editor::nudge_track), true, true))));
2027  nudge_items.push_back (MenuElem (_("Nudge Entire Track Earlier"), (sigc::bind (sigc::mem_fun(*this, &Editor::nudge_track), false, false))));
2028  nudge_items.push_back (MenuElem (_("Nudge Track After Edit Point Earlier"), (sigc::bind (sigc::mem_fun(*this, &Editor::nudge_track), true, false))));
2029 
2030  edit_items.push_back (MenuElem (_("Nudge"), *nudge_menu));
2031 }
2032 
2033 SnapType
2035 {
2036  return _snap_type;
2037 }
2038 
2039 SnapMode
2041 {
2042  return _snap_mode;
2043 }
2044 
2045 void
2047 {
2048  unsigned int snap_ind = (unsigned int)st;
2049 
2050  if (internal_editing()) {
2051  internal_snap_type = st;
2052  } else {
2054  }
2055 
2056  _snap_type = st;
2057 
2058  if (snap_ind > snap_type_strings.size() - 1) {
2059  snap_ind = 0;
2060  _snap_type = (SnapType)snap_ind;
2061  }
2062 
2063  string str = snap_type_strings[snap_ind];
2064 
2065  if (str != snap_type_selector.get_text()) {
2067  }
2068 
2069  instant_save ();
2070 
2071  switch (_snap_type) {
2072  case SnapToBeatDiv128:
2073  case SnapToBeatDiv64:
2074  case SnapToBeatDiv32:
2075  case SnapToBeatDiv28:
2076  case SnapToBeatDiv24:
2077  case SnapToBeatDiv20:
2078  case SnapToBeatDiv16:
2079  case SnapToBeatDiv14:
2080  case SnapToBeatDiv12:
2081  case SnapToBeatDiv10:
2082  case SnapToBeatDiv8:
2083  case SnapToBeatDiv7:
2084  case SnapToBeatDiv6:
2085  case SnapToBeatDiv5:
2086  case SnapToBeatDiv4:
2087  case SnapToBeatDiv3:
2088  case SnapToBeatDiv2: {
2089  ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin;
2090  ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end;
2091 
2093  current_bbt_points_begin, current_bbt_points_end);
2095  current_bbt_points_begin, current_bbt_points_end);
2096  update_tempo_based_rulers (current_bbt_points_begin, current_bbt_points_end);
2097  break;
2098  }
2099 
2100  case SnapToRegionStart:
2101  case SnapToRegionEnd:
2102  case SnapToRegionSync:
2103  case SnapToRegionBoundary:
2105  break;
2106 
2107  default:
2108  /* relax */
2109  break;
2110  }
2111 
2112  redisplay_tempo (false);
2113 
2114  SnapChanged (); /* EMIT SIGNAL */
2115 }
2116 
2117 void
2119 {
2120  string str = snap_mode_strings[(int)mode];
2121 
2122  if (internal_editing()) {
2123  internal_snap_mode = mode;
2124  } else {
2125  pre_internal_snap_mode = mode;
2126  }
2127 
2128  _snap_mode = mode;
2129 
2130  if (str != snap_mode_selector.get_text ()) {
2132  }
2133 
2134  instant_save ();
2135 }
2136 void
2138 {
2139  bool changed = (_edit_point != ep);
2140 
2141  _edit_point = ep;
2142  if (Profile->get_mixbus())
2143  if (ep == EditAtSelectedMarker)
2144  ep = EditAtPlayhead;
2145 
2146  string str = edit_point_strings[(int)ep];
2147  if (str != edit_point_selector.get_text ()) {
2149  }
2150 
2152 
2153  if (!force && !changed) {
2154  return;
2155  }
2156 
2157  const char* action=NULL;
2158 
2159  switch (_edit_point) {
2160  case EditAtPlayhead:
2161  action = "edit-at-playhead";
2162  break;
2163  case EditAtSelectedMarker:
2164  action = "edit-at-marker";
2165  break;
2166  case EditAtMouse:
2167  action = "edit-at-mouse";
2168  break;
2169  }
2170 
2171  Glib::RefPtr<Action> act = ActionManager::get_action ("Editor", action);
2172  if (act) {
2173  Glib::RefPtr<RadioAction>::cast_dynamic(act)->set_active (true);
2174  }
2175 
2176  framepos_t foo;
2177  bool in_track_canvas;
2178 
2179  if (!mouse_frame (foo, in_track_canvas)) {
2180  in_track_canvas = false;
2181  }
2182 
2183  reset_canvas_action_sensitivity (in_track_canvas);
2184 
2185  instant_save ();
2186 }
2187 
2188 int
2189 Editor::set_state (const XMLNode& node, int /*version*/)
2190 {
2191  const XMLProperty* prop;
2192  XMLNode* geometry;
2193  int x, y;
2194  Gdk::Geometry g;
2195 
2196  set_id (node);
2197 
2198  g.base_width = default_width;
2199  g.base_height = default_height;
2200  x = 1;
2201  y = 1;
2202 
2203  if ((geometry = find_named_node (node, "geometry")) != 0) {
2204 
2205  XMLProperty* prop;
2206 
2207  if ((prop = geometry->property("x_size")) == 0) {
2208  prop = geometry->property ("x-size");
2209  }
2210  if (prop) {
2211  g.base_width = atoi(prop->value());
2212  }
2213  if ((prop = geometry->property("y_size")) == 0) {
2214  prop = geometry->property ("y-size");
2215  }
2216  if (prop) {
2217  g.base_height = atoi(prop->value());
2218  }
2219 
2220  if ((prop = geometry->property ("x_pos")) == 0) {
2221  prop = geometry->property ("x-pos");
2222  }
2223  if (prop) {
2224  x = atoi (prop->value());
2225 
2226  }
2227  if ((prop = geometry->property ("y_pos")) == 0) {
2228  prop = geometry->property ("y-pos");
2229  }
2230  if (prop) {
2231  y = atoi (prop->value());
2232  }
2233  }
2234 
2235  set_default_size (g.base_width, g.base_height);
2236  move (x, y);
2237 
2238  if (_session && (prop = node.property ("playhead"))) {
2239  framepos_t pos;
2240  sscanf (prop->value().c_str(), "%" PRIi64, &pos);
2241  if (pos >= 0) {
2243  } else {
2244  warning << _("Playhead position stored with a negative value - ignored (use zero instead)") << endmsg;
2246  }
2247  } else {
2249  }
2250 
2251  if ((prop = node.property ("mixer-width"))) {
2253  }
2254 
2255  if ((prop = node.property ("zoom-focus"))) {
2257  }
2258 
2259  if ((prop = node.property ("zoom"))) {
2260  /* older versions of ardour used floating point samples_per_pixel */
2261  double f = PBD::atof (prop->value());
2262  reset_zoom (llrintf (f));
2263  } else {
2265  }
2266 
2267  if ((prop = node.property ("visible-track-count"))) {
2269  }
2270 
2271  if ((prop = node.property ("snap-to"))) {
2273  }
2274 
2275  if ((prop = node.property ("snap-mode"))) {
2277  }
2278 
2279  if ((prop = node.property ("internal-snap-to"))) {
2281  }
2282 
2283  if ((prop = node.property ("internal-snap-mode"))) {
2285  }
2286 
2287  if ((prop = node.property ("pre-internal-snap-to"))) {
2289  }
2290 
2291  if ((prop = node.property ("pre-internal-snap-mode"))) {
2293  }
2294 
2295  if ((prop = node.property ("mouse-mode"))) {
2296  MouseMode m = str2mousemode(prop->value());
2297  set_mouse_mode (m, true);
2298  } else {
2299  set_mouse_mode (MouseObject, true);
2300  }
2301 
2302  if ((prop = node.property ("left-frame")) != 0) {
2303  framepos_t pos;
2304  if (sscanf (prop->value().c_str(), "%" PRId64, &pos) == 1) {
2305  if (pos < 0) {
2306  pos = 0;
2307  }
2308  reset_x_origin (pos);
2309  }
2310  }
2311 
2312  if ((prop = node.property ("y-origin")) != 0) {
2313  reset_y_origin (atof (prop->value ()));
2314  }
2315 
2316  if ((prop = node.property ("join-object-range"))) {
2317  RefPtr<Action> act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-object-range"));
2318  bool yn = string_is_affirmative (prop->value());
2319  if (act) {
2320  RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
2321  tact->set_active (!yn);
2322  tact->set_active (yn);
2323  }
2324  set_mouse_mode(mouse_mode, true);
2325  }
2326 
2327  if ((prop = node.property ("edit-point"))) {
2329  }
2330 
2331  if ((prop = node.property ("show-measures"))) {
2332  bool yn = string_is_affirmative (prop->value());
2333  _show_measures = yn;
2334  }
2335 
2336  if ((prop = node.property ("follow-playhead"))) {
2337  bool yn = string_is_affirmative (prop->value());
2338  set_follow_playhead (yn);
2339  }
2340 
2341  if ((prop = node.property ("stationary-playhead"))) {
2342  bool yn = string_is_affirmative (prop->value());
2344  }
2345 
2346  if ((prop = node.property ("region-list-sort-type"))) {
2347  RegionListSortType st;
2349  }
2350 
2351  if ((prop = node.property ("show-editor-mixer"))) {
2352 
2353  Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("show-editor-mixer"));
2354  assert (act);
2355 
2356  Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
2357  bool yn = string_is_affirmative (prop->value());
2358 
2359  /* do it twice to force the change */
2360 
2361  tact->set_active (!yn);
2362  tact->set_active (yn);
2363  }
2364 
2365  if ((prop = node.property ("show-editor-list"))) {
2366 
2367  Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("show-editor-list"));
2368  assert (act);
2369 
2370  Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
2371  bool yn = string_is_affirmative (prop->value());
2372 
2373  /* do it twice to force the change */
2374 
2375  tact->set_active (!yn);
2376  tact->set_active (yn);
2377  }
2378 
2379  if ((prop = node.property (X_("editor-list-page")))) {
2380  _the_notebook.set_current_page (atoi (prop->value ()));
2381  }
2382 
2383  if ((prop = node.property (X_("show-marker-lines")))) {
2384  Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("show-marker-lines"));
2385  assert (act);
2386  Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic (act);
2387  bool yn = string_is_affirmative (prop->value ());
2388 
2389  tact->set_active (!yn);
2390  tact->set_active (yn);
2391  }
2392 
2393  XMLNodeList children = node.children ();
2394  for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
2395  selection->set_state (**i, Stateful::current_state_version);
2396  _regions->set_state (**i);
2397  }
2398 
2399  if ((prop = node.property ("maximised"))) {
2400  bool yn = string_is_affirmative (prop->value());
2401  Glib::RefPtr<Action> act = ActionManager::get_action (X_("Common"), X_("ToggleMaximalEditor"));
2402  assert (act);
2403  Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
2404  bool fs = tact && tact->get_active();
2405  if (yn ^ fs) {
2406  ActionManager::do_action ("Common", "ToggleMaximalEditor");
2407  }
2408  }
2409 
2410  if ((prop = node.property ("nudge-clock-value"))) {
2411  framepos_t f;
2412  sscanf (prop->value().c_str(), "%" PRId64, &f);
2413  nudge_clock->set (f);
2414  } else {
2416  nudge_clock->set (_session->frame_rate() * 5, true);
2417  }
2418 
2419  {
2420  /* apply state
2421  * Not all properties may have been in XML, but
2422  * those that are linked to a private variable may need changing
2423  */
2424  RefPtr<Action> act;
2425  bool yn;
2426 
2427  act = ActionManager::get_action (X_("Editor"), X_("ToggleMeasureVisibility"));
2428  if (act) {
2429  yn = _show_measures;
2430  RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
2431  /* do it twice to force the change */
2432  tact->set_active (!yn);
2433  tact->set_active (yn);
2434  }
2435 
2436  act = ActionManager::get_action (X_("Editor"), X_("toggle-follow-playhead"));
2437  yn = _follow_playhead;
2438  if (act) {
2439  RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
2440  if (tact->get_active() != yn) {
2441  tact->set_active (yn);
2442  }
2443  }
2444 
2445  act = ActionManager::get_action (X_("Editor"), X_("toggle-stationary-playhead"));
2446  yn = _stationary_playhead;
2447  if (act) {
2448  RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
2449  if (tact->get_active() != yn) {
2450  tact->set_active (yn);
2451  }
2452  }
2453  }
2454 
2455  return 0;
2456 }
2457 
2458 XMLNode&
2460 {
2461  XMLNode* node = new XMLNode ("Editor");
2462  char buf[32];
2463 
2464  id().print (buf, sizeof (buf));
2465  node->add_property ("id", buf);
2466 
2467  if (is_realized()) {
2468  Glib::RefPtr<Gdk::Window> win = get_window();
2469 
2470  int x, y, width, height;
2471  win->get_root_origin(x, y);
2472  win->get_size(width, height);
2473 
2474  XMLNode* geometry = new XMLNode ("geometry");
2475 
2476  snprintf(buf, sizeof(buf), "%d", width);
2477  geometry->add_property("x-size", string(buf));
2478  snprintf(buf, sizeof(buf), "%d", height);
2479  geometry->add_property("y-size", string(buf));
2480  snprintf(buf, sizeof(buf), "%d", x);
2481  geometry->add_property("x-pos", string(buf));
2482  snprintf(buf, sizeof(buf), "%d", y);
2483  geometry->add_property("y-pos", string(buf));
2484  snprintf(buf,sizeof(buf), "%d",gtk_paned_get_position (static_cast<Paned*>(&edit_pane)->gobj()));
2485  geometry->add_property("edit-horizontal-pane-pos", string(buf));
2486  geometry->add_property("notebook-shrunk", _notebook_shrunk ? "1" : "0");
2487  snprintf(buf,sizeof(buf), "%d",gtk_paned_get_position (static_cast<Paned*>(&editor_summary_pane)->gobj()));
2488  geometry->add_property("edit-vertical-pane-pos", string(buf));
2489 
2490  node->add_child_nocopy (*geometry);
2491  }
2492 
2494 
2495  node->add_property ("zoom-focus", enum_2_string (zoom_focus));
2496 
2497  snprintf (buf, sizeof(buf), "%" PRId64, samples_per_pixel);
2498  node->add_property ("zoom", buf);
2499  node->add_property ("snap-to", enum_2_string (_snap_type));
2500  node->add_property ("snap-mode", enum_2_string (_snap_mode));
2501  node->add_property ("internal-snap-to", enum_2_string (internal_snap_type));
2502  node->add_property ("internal-snap-mode", enum_2_string (internal_snap_mode));
2503  node->add_property ("pre-internal-snap-to", enum_2_string (pre_internal_snap_type));
2504  node->add_property ("pre-internal-snap-mode", enum_2_string (pre_internal_snap_mode));
2505  node->add_property ("edit-point", enum_2_string (_edit_point));
2506  snprintf (buf, sizeof(buf), "%d", _visible_track_count);
2507  node->add_property ("visible-track-count", buf);
2508 
2509  snprintf (buf, sizeof (buf), "%" PRIi64, playhead_cursor->current_frame ());
2510  node->add_property ("playhead", buf);
2511  snprintf (buf, sizeof (buf), "%" PRIi64, leftmost_frame);
2512  node->add_property ("left-frame", buf);
2513  snprintf (buf, sizeof (buf), "%f", vertical_adjustment.get_value ());
2514  node->add_property ("y-origin", buf);
2515 
2516  node->add_property ("show-measures", _show_measures ? "yes" : "no");
2517  node->add_property ("maximised", _maximised ? "yes" : "no");
2518  node->add_property ("follow-playhead", _follow_playhead ? "yes" : "no");
2519  node->add_property ("stationary-playhead", _stationary_playhead ? "yes" : "no");
2520  node->add_property ("region-list-sort-type", enum_2_string (_regions->sort_type ()));
2521  node->add_property ("mouse-mode", enum2str(mouse_mode));
2522  node->add_property ("join-object-range", smart_mode_action->get_active () ? "yes" : "no");
2523 
2524  Glib::RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("show-editor-mixer"));
2525  if (act) {
2526  Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
2527  node->add_property (X_("show-editor-mixer"), tact->get_active() ? "yes" : "no");
2528  }
2529 
2530  act = ActionManager::get_action (X_("Editor"), X_("show-editor-list"));
2531  if (act) {
2532  Glib::RefPtr<ToggleAction> tact = Glib::RefPtr<ToggleAction>::cast_dynamic(act);
2533  node->add_property (X_("show-editor-list"), tact->get_active() ? "yes" : "no");
2534  }
2535 
2536  snprintf (buf, sizeof (buf), "%d", _the_notebook.get_current_page ());
2537  node->add_property (X_("editor-list-page"), buf);
2538 
2539  if (button_bindings) {
2540  XMLNode* bb = new XMLNode (X_("Buttons"));
2541  button_bindings->save (*bb);
2542  node->add_child_nocopy (*bb);
2543  }
2544 
2545  node->add_property (X_("show-marker-lines"), _show_marker_lines ? "yes" : "no");
2546 
2547  node->add_child_nocopy (selection->get_state ());
2548  node->add_child_nocopy (_regions->get_state ());
2549 
2550  snprintf (buf, sizeof (buf), "%" PRId64, nudge_clock->current_duration());
2551  node->add_property ("nudge-clock-value", buf);
2552 
2553  return *node;
2554 }
2555 
2564 std::pair<TimeAxisView *, double>
2565 Editor::trackview_by_y_position (double y, bool trackview_relative_offset) const
2566 {
2567  if (!trackview_relative_offset) {
2568  y -= _trackview_group->canvas_origin().y;
2569  }
2570 
2571  if (y < 0) {
2572  return std::make_pair ( (TimeAxisView *) 0, 0);
2573  }
2574 
2575  for (TrackViewList::const_iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
2576 
2577  std::pair<TimeAxisView*, double> const r = (*iter)->covers_y_position (y);
2578 
2579  if (r.first) {
2580  return r;
2581  }
2582  }
2583 
2584  return std::make_pair ( (TimeAxisView *) 0, 0);
2585 }
2586 
2592 void
2593 Editor::snap_to_with_modifier (framepos_t& start, GdkEvent const * event, RoundMode direction, bool for_mark)
2594 {
2595  if (!_session || !event) {
2596  return;
2597  }
2598 
2599  if (Keyboard::modifier_state_contains (event->button.state, Keyboard::snap_modifier())) {
2600  if (_snap_mode == SnapOff) {
2601  snap_to_internal (start, direction, for_mark);
2602  }
2603  } else {
2604  if (_snap_mode != SnapOff) {
2605  snap_to_internal (start, direction, for_mark);
2606  }
2607  }
2608 }
2609 
2610 void
2611 Editor::snap_to (framepos_t& start, RoundMode direction, bool for_mark)
2612 {
2613  if (!_session || _snap_mode == SnapOff) {
2614  return;
2615  }
2616 
2617  snap_to_internal (start, direction, for_mark);
2618 }
2619 
2620 void
2622 {
2623  const framepos_t one_timecode_second = (framepos_t)(rint(_session->timecode_frames_per_second()) * _session->frames_per_timecode_frame());
2624  framepos_t one_timecode_minute = (framepos_t)(rint(_session->timecode_frames_per_second()) * _session->frames_per_timecode_frame() * 60);
2625 
2626  switch (_snap_type) {
2627  case SnapToTimecodeFrame:
2628  if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
2629  fmod((double)start, (double)_session->frames_per_timecode_frame()) == 0) {
2630  /* start is already on a whole timecode frame, do nothing */
2631  } else if (((direction == 0) && (fmod((double)start, (double)_session->frames_per_timecode_frame()) > (_session->frames_per_timecode_frame() / 2))) || (direction > 0)) {
2632  start = (framepos_t) (ceil ((double) start / _session->frames_per_timecode_frame()) * _session->frames_per_timecode_frame());
2633  } else {
2634  start = (framepos_t) (floor ((double) start / _session->frames_per_timecode_frame()) * _session->frames_per_timecode_frame());
2635  }
2636  break;
2637 
2638  case SnapToTimecodeSeconds:
2639  if (_session->config.get_timecode_offset_negative()) {
2640  start += _session->config.get_timecode_offset ();
2641  } else {
2642  start -= _session->config.get_timecode_offset ();
2643  }
2644  if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
2645  (start % one_timecode_second == 0)) {
2646  /* start is already on a whole second, do nothing */
2647  } else if (((direction == 0) && (start % one_timecode_second > one_timecode_second / 2)) || direction > 0) {
2648  start = (framepos_t) ceil ((double) start / one_timecode_second) * one_timecode_second;
2649  } else {
2650  start = (framepos_t) floor ((double) start / one_timecode_second) * one_timecode_second;
2651  }
2652 
2653  if (_session->config.get_timecode_offset_negative()) {
2654  start -= _session->config.get_timecode_offset ();
2655  } else {
2656  start += _session->config.get_timecode_offset ();
2657  }
2658  break;
2659 
2660  case SnapToTimecodeMinutes:
2661  if (_session->config.get_timecode_offset_negative()) {
2662  start += _session->config.get_timecode_offset ();
2663  } else {
2664  start -= _session->config.get_timecode_offset ();
2665  }
2666  if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
2667  (start % one_timecode_minute == 0)) {
2668  /* start is already on a whole minute, do nothing */
2669  } else if (((direction == 0) && (start % one_timecode_minute > one_timecode_minute / 2)) || direction > 0) {
2670  start = (framepos_t) ceil ((double) start / one_timecode_minute) * one_timecode_minute;
2671  } else {
2672  start = (framepos_t) floor ((double) start / one_timecode_minute) * one_timecode_minute;
2673  }
2674  if (_session->config.get_timecode_offset_negative()) {
2675  start -= _session->config.get_timecode_offset ();
2676  } else {
2677  start += _session->config.get_timecode_offset ();
2678  }
2679  break;
2680  default:
2681  fatal << "Editor::smpte_snap_to_internal() called with non-timecode snap type!" << endmsg;
2682  abort(); /*NOTREACHED*/
2683  }
2684 }
2685 
2686 void
2688 {
2689  const framepos_t one_second = _session->frame_rate();
2690  const framepos_t one_minute = _session->frame_rate() * 60;
2691  framepos_t presnap = start;
2693  framepos_t after;
2694 
2695  switch (_snap_type) {
2696  case SnapToTimecodeFrame:
2697  case SnapToTimecodeSeconds:
2698  case SnapToTimecodeMinutes:
2699  return timecode_snap_to_internal (start, direction, for_mark);
2700 
2701  case SnapToCDFrame:
2702  if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
2703  start % (one_second/75) == 0) {
2704  /* start is already on a whole CD frame, do nothing */
2705  } else if (((direction == 0) && (start % (one_second/75) > (one_second/75) / 2)) || (direction > 0)) {
2706  start = (framepos_t) ceil ((double) start / (one_second / 75)) * (one_second / 75);
2707  } else {
2708  start = (framepos_t) floor ((double) start / (one_second / 75)) * (one_second / 75);
2709  }
2710  break;
2711 
2712  case SnapToSeconds:
2713  if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
2714  start % one_second == 0) {
2715  /* start is already on a whole second, do nothing */
2716  } else if (((direction == 0) && (start % one_second > one_second / 2)) || (direction > 0)) {
2717  start = (framepos_t) ceil ((double) start / one_second) * one_second;
2718  } else {
2719  start = (framepos_t) floor ((double) start / one_second) * one_second;
2720  }
2721  break;
2722 
2723  case SnapToMinutes:
2724  if ((direction == RoundUpMaybe || direction == RoundDownMaybe) &&
2725  start % one_minute == 0) {
2726  /* start is already on a whole minute, do nothing */
2727  } else if (((direction == 0) && (start % one_minute > one_minute / 2)) || (direction > 0)) {
2728  start = (framepos_t) ceil ((double) start / one_minute) * one_minute;
2729  } else {
2730  start = (framepos_t) floor ((double) start / one_minute) * one_minute;
2731  }
2732  break;
2733 
2734  case SnapToBar:
2735  start = _session->tempo_map().round_to_bar (start, direction);
2736  break;
2737 
2738  case SnapToBeat:
2739  start = _session->tempo_map().round_to_beat (start, direction);
2740  break;
2741 
2742  case SnapToBeatDiv128:
2743  start = _session->tempo_map().round_to_beat_subdivision (start, 128, direction);
2744  break;
2745  case SnapToBeatDiv64:
2746  start = _session->tempo_map().round_to_beat_subdivision (start, 64, direction);
2747  break;
2748  case SnapToBeatDiv32:
2749  start = _session->tempo_map().round_to_beat_subdivision (start, 32, direction);
2750  break;
2751  case SnapToBeatDiv28:
2752  start = _session->tempo_map().round_to_beat_subdivision (start, 28, direction);
2753  break;
2754  case SnapToBeatDiv24:
2755  start = _session->tempo_map().round_to_beat_subdivision (start, 24, direction);
2756  break;
2757  case SnapToBeatDiv20:
2758  start = _session->tempo_map().round_to_beat_subdivision (start, 20, direction);
2759  break;
2760  case SnapToBeatDiv16:
2761  start = _session->tempo_map().round_to_beat_subdivision (start, 16, direction);
2762  break;
2763  case SnapToBeatDiv14:
2764  start = _session->tempo_map().round_to_beat_subdivision (start, 14, direction);
2765  break;
2766  case SnapToBeatDiv12:
2767  start = _session->tempo_map().round_to_beat_subdivision (start, 12, direction);
2768  break;
2769  case SnapToBeatDiv10:
2770  start = _session->tempo_map().round_to_beat_subdivision (start, 10, direction);
2771  break;
2772  case SnapToBeatDiv8:
2773  start = _session->tempo_map().round_to_beat_subdivision (start, 8, direction);
2774  break;
2775  case SnapToBeatDiv7:
2776  start = _session->tempo_map().round_to_beat_subdivision (start, 7, direction);
2777  break;
2778  case SnapToBeatDiv6:
2779  start = _session->tempo_map().round_to_beat_subdivision (start, 6, direction);
2780  break;
2781  case SnapToBeatDiv5:
2782  start = _session->tempo_map().round_to_beat_subdivision (start, 5, direction);
2783  break;
2784  case SnapToBeatDiv4:
2785  start = _session->tempo_map().round_to_beat_subdivision (start, 4, direction);
2786  break;
2787  case SnapToBeatDiv3:
2788  start = _session->tempo_map().round_to_beat_subdivision (start, 3, direction);
2789  break;
2790  case SnapToBeatDiv2:
2791  start = _session->tempo_map().round_to_beat_subdivision (start, 2, direction);
2792  break;
2793 
2794  case SnapToMark:
2795  if (for_mark) {
2796  return;
2797  }
2798 
2799  _session->locations()->marks_either_side (start, before, after);
2800 
2801  if (before == max_framepos && after == max_framepos) {
2802  /* No marks to snap to, so just don't snap */
2803  return;
2804  } else if (before == max_framepos) {
2805  start = after;
2806  } else if (after == max_framepos) {
2807  start = before;
2808  } else if (before != max_framepos && after != max_framepos) {
2809  /* have before and after */
2810  if ((start - before) < (after - start)) {
2811  start = before;
2812  } else {
2813  start = after;
2814  }
2815  }
2816 
2817  break;
2818 
2819  case SnapToRegionStart:
2820  case SnapToRegionEnd:
2821  case SnapToRegionSync:
2822  case SnapToRegionBoundary:
2823  if (!region_boundary_cache.empty()) {
2824 
2825  vector<framepos_t>::iterator prev = region_boundary_cache.end ();
2826  vector<framepos_t>::iterator next = region_boundary_cache.end ();
2827 
2828  if (direction > 0) {
2829  next = std::upper_bound (region_boundary_cache.begin(), region_boundary_cache.end(), start);
2830  } else {
2831  next = std::lower_bound (region_boundary_cache.begin(), region_boundary_cache.end(), start);
2832  }
2833 
2834  if (next != region_boundary_cache.begin ()) {
2835  prev = next;
2836  prev--;
2837  }
2838 
2839  framepos_t const p = (prev == region_boundary_cache.end()) ? region_boundary_cache.front () : *prev;
2840  framepos_t const n = (next == region_boundary_cache.end()) ? region_boundary_cache.back () : *next;
2841 
2842  if (start > (p + n) / 2) {
2843  start = n;
2844  } else {
2845  start = p;
2846  }
2847  }
2848  break;
2849  }
2850 
2851  switch (_snap_mode) {
2852  case SnapNormal:
2853  return;
2854 
2855  case SnapMagnetic:
2856 
2857  if (presnap > start) {
2858  if (presnap > (start + pixel_to_sample(snap_threshold))) {
2859  start = presnap;
2860  }
2861 
2862  } else if (presnap < start) {
2863  if (presnap < (start - pixel_to_sample(snap_threshold))) {
2864  start = presnap;
2865  }
2866  }
2867 
2868  default:
2869  /* handled at entry */
2870  return;
2871 
2872  }
2873 }
2874 
2875 
2876 void
2878 {
2879  HBox* mode_box = manage(new HBox);
2880  mode_box->set_border_width (2);
2881  mode_box->set_spacing(2);
2882 
2883  HBox* mouse_mode_box = manage (new HBox);
2884  HBox* mouse_mode_hbox = manage (new HBox);
2885  VBox* mouse_mode_vbox = manage (new VBox);
2886  Alignment* mouse_mode_align = manage (new Alignment);
2887 
2888  Glib::RefPtr<SizeGroup> mouse_mode_size_group = SizeGroup::create (SIZE_GROUP_VERTICAL);
2889  mouse_mode_size_group->add_widget (smart_mode_button);
2890  mouse_mode_size_group->add_widget (mouse_move_button);
2891  mouse_mode_size_group->add_widget (mouse_cut_button);
2892  mouse_mode_size_group->add_widget (mouse_select_button);
2893  mouse_mode_size_group->add_widget (mouse_timefx_button);
2894  mouse_mode_size_group->add_widget (mouse_audition_button);
2895  mouse_mode_size_group->add_widget (mouse_draw_button);
2896  mouse_mode_size_group->add_widget (mouse_content_button);
2897 
2898  mouse_mode_size_group->add_widget (zoom_in_button);
2899  mouse_mode_size_group->add_widget (zoom_out_button);
2900  mouse_mode_size_group->add_widget (zoom_preset_selector);
2901  mouse_mode_size_group->add_widget (zoom_out_full_button);
2902  mouse_mode_size_group->add_widget (zoom_focus_selector);
2903 
2904  mouse_mode_size_group->add_widget (tav_shrink_button);
2905  mouse_mode_size_group->add_widget (tav_expand_button);
2906  mouse_mode_size_group->add_widget (visible_tracks_selector);
2907 
2908  mouse_mode_size_group->add_widget (snap_type_selector);
2909  mouse_mode_size_group->add_widget (snap_mode_selector);
2910 
2911  mouse_mode_size_group->add_widget (edit_point_selector);
2912  mouse_mode_size_group->add_widget (edit_mode_selector);
2913 
2914  mouse_mode_size_group->add_widget (*nudge_clock);
2915  mouse_mode_size_group->add_widget (nudge_forward_button);
2916  mouse_mode_size_group->add_widget (nudge_backward_button);
2917 
2918  mouse_mode_hbox->set_spacing (2);
2919 
2920  if (!ARDOUR::Profile->get_trx()) {
2921  mouse_mode_hbox->pack_start (smart_mode_button, false, false);
2922  }
2923 
2924  mouse_mode_hbox->pack_start (mouse_move_button, false, false);
2925  mouse_mode_hbox->pack_start (mouse_select_button, false, false);
2926 
2927  if (!ARDOUR::Profile->get_mixbus()) {
2928  mouse_mode_hbox->pack_start (mouse_cut_button, false, false);
2929  }
2930 
2931  if (!ARDOUR::Profile->get_trx()) {
2932  mouse_mode_hbox->pack_start (mouse_timefx_button, false, false);
2933  mouse_mode_hbox->pack_start (mouse_audition_button, false, false);
2934  mouse_mode_hbox->pack_start (mouse_draw_button, false, false);
2935  mouse_mode_hbox->pack_start (mouse_content_button, false, false);
2936  }
2937 
2938  mouse_mode_vbox->pack_start (*mouse_mode_hbox);
2939 
2940  mouse_mode_align->add (*mouse_mode_vbox);
2941  mouse_mode_align->set (0.5, 1.0, 0.0, 0.0);
2942 
2943  mouse_mode_box->pack_start (*mouse_mode_align, false, false);
2944 
2945  edit_mode_selector.set_name ("mouse mode button");
2946 
2947  if (!ARDOUR::Profile->get_trx()) {
2948  mode_box->pack_start (edit_mode_selector, false, false);
2949  }
2950  mode_box->pack_start (*mouse_mode_box, false, false);
2951 
2952  _mouse_mode_tearoff = manage (new TearOff (*mode_box));
2953  _mouse_mode_tearoff->set_name ("MouseModeBase");
2954  _mouse_mode_tearoff->tearoff_window().signal_key_press_event().connect (sigc::bind (sigc::ptr_fun (relay_key_press), &_mouse_mode_tearoff->tearoff_window()), false);
2955 
2956  if (Profile->get_sae() || Profile->get_mixbus() ) {
2958  }
2959 
2960  _mouse_mode_tearoff->Detach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast<Box*>(&toolbar_hbox),
2962  _mouse_mode_tearoff->Attach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast<Box*> (&toolbar_hbox),
2964  _mouse_mode_tearoff->Hidden.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast<Box*>(&toolbar_hbox),
2966  _mouse_mode_tearoff->Visible.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast<Box*> (&toolbar_hbox),
2968 
2969  /* Zoom */
2970 
2971  _zoom_box.set_spacing (2);
2972  _zoom_box.set_border_width (2);
2973 
2974  RefPtr<Action> act;
2975 
2976  zoom_preset_selector.set_name ("zoom button");
2977  zoom_preset_selector.set_image(::get_icon ("time_exp"));
2978  zoom_preset_selector.set_size_request (42, -1);
2979 
2980  zoom_in_button.set_name ("zoom button");
2981  zoom_in_button.set_image(::get_icon ("zoom_in"));
2982  act = ActionManager::get_action (X_("Editor"), X_("temporal-zoom-in"));
2984 
2985  zoom_out_button.set_name ("zoom button");
2986  zoom_out_button.set_image(::get_icon ("zoom_out"));
2987  act = ActionManager::get_action (X_("Editor"), X_("temporal-zoom-out"));
2989 
2990  zoom_out_full_button.set_name ("zoom button");
2991  zoom_out_full_button.set_image(::get_icon ("zoom_full"));
2992  act = ActionManager::get_action (X_("Editor"), X_("zoom-to-session"));
2994 
2995  zoom_focus_selector.set_name ("zoom button");
2996 
2997  if (ARDOUR::Profile->get_mixbus()) {
2998  _zoom_box.pack_start (zoom_preset_selector, false, false);
2999  } else if (ARDOUR::Profile->get_trx()) {
3000  mode_box->pack_start (zoom_out_button, false, false);
3001  mode_box->pack_start (zoom_in_button, false, false);
3002  } else {
3003  _zoom_box.pack_start (zoom_out_button, false, false);
3004  _zoom_box.pack_start (zoom_in_button, false, false);
3005  _zoom_box.pack_start (zoom_out_full_button, false, false);
3006  _zoom_box.pack_start (zoom_focus_selector, false, false);
3007  }
3008 
3009  /* Track zoom buttons */
3010  visible_tracks_selector.set_name ("zoom button");
3011  if (Profile->get_mixbus()) {
3013  visible_tracks_selector.set_size_request (42, -1);
3014  } else {
3016  }
3017 
3018  tav_expand_button.set_name ("zoom button");
3019  tav_expand_button.set_image(::get_icon ("tav_exp"));
3020  act = ActionManager::get_action (X_("Editor"), X_("expand-tracks"));
3022 
3023  tav_shrink_button.set_name ("zoom button");
3024  tav_shrink_button.set_image(::get_icon ("tav_shrink"));
3025  act = ActionManager::get_action (X_("Editor"), X_("shrink-tracks"));
3027 
3028  if (ARDOUR::Profile->get_mixbus()) {
3029  _zoom_box.pack_start (visible_tracks_selector);
3030  } else if (ARDOUR::Profile->get_trx()) {
3031  _zoom_box.pack_start (tav_shrink_button);
3032  _zoom_box.pack_start (tav_expand_button);
3033  } else {
3034  _zoom_box.pack_start (visible_tracks_selector);
3035  _zoom_box.pack_start (tav_shrink_button);
3036  _zoom_box.pack_start (tav_expand_button);
3037  }
3038 
3039  if (!ARDOUR::Profile->get_trx()) {
3040  _zoom_tearoff = manage (new TearOff (_zoom_box));
3041 
3042  _zoom_tearoff->Detach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast<Box*>(&toolbar_hbox),
3044  _zoom_tearoff->Attach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast<Box*> (&toolbar_hbox),
3045  &_zoom_tearoff->tearoff_window(), 0));
3046  _zoom_tearoff->Hidden.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast<Box*>(&toolbar_hbox),
3048  _zoom_tearoff->Visible.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast<Box*> (&toolbar_hbox),
3049  &_zoom_tearoff->tearoff_window(), 0));
3050  }
3051 
3052  if (Profile->get_sae() || Profile->get_mixbus() ) {
3054  }
3055 
3056  snap_box.set_spacing (2);
3057  snap_box.set_border_width (2);
3058 
3059  snap_type_selector.set_name ("mouse mode button");
3060 
3061  snap_mode_selector.set_name ("mouse mode button");
3062 
3063  edit_point_selector.set_name ("mouse mode button");
3064 
3065  snap_box.pack_start (snap_mode_selector, false, false);
3066  snap_box.pack_start (snap_type_selector, false, false);
3067  snap_box.pack_start (edit_point_selector, false, false);
3068 
3069  /* Nudge */
3070 
3071  HBox *nudge_box = manage (new HBox);
3072  nudge_box->set_spacing (2);
3073  nudge_box->set_border_width (2);
3074 
3075  nudge_forward_button.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::nudge_forward_release), false);
3076  nudge_backward_button.signal_button_release_event().connect (sigc::mem_fun(*this, &Editor::nudge_backward_release), false);
3077 
3078  nudge_box->pack_start (nudge_backward_button, false, false);
3079  nudge_box->pack_start (nudge_forward_button, false, false);
3080  nudge_box->pack_start (*nudge_clock, false, false);
3081 
3082 
3083  /* Pack everything in... */
3084 
3085  HBox* hbox = manage (new HBox);
3086  hbox->set_spacing(2);
3087 
3088  _tools_tearoff = manage (new TearOff (*hbox));
3089  _tools_tearoff->set_name ("MouseModeBase");
3090  _tools_tearoff->tearoff_window().signal_key_press_event().connect (sigc::bind (sigc::ptr_fun (relay_key_press), &_tools_tearoff->tearoff_window()), false);
3091 
3092  if (Profile->get_sae() || Profile->get_mixbus()) {
3094  }
3095 
3096  _tools_tearoff->Detach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast<Box*>(&toolbar_hbox),
3098  _tools_tearoff->Attach.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast<Box*> (&toolbar_hbox),
3099  &_tools_tearoff->tearoff_window(), 0));
3100  _tools_tearoff->Hidden.connect (sigc::bind (sigc::mem_fun(*this, &Editor::detach_tearoff), static_cast<Box*>(&toolbar_hbox),
3102  _tools_tearoff->Visible.connect (sigc::bind (sigc::mem_fun(*this, &Editor::reattach_tearoff), static_cast<Box*> (&toolbar_hbox),
3103  &_tools_tearoff->tearoff_window(), 0));
3104 
3105  toolbar_hbox.set_spacing (2);
3106  toolbar_hbox.set_border_width (1);
3107 
3108  toolbar_hbox.pack_start (*_mouse_mode_tearoff, false, false);
3109  if (!ARDOUR::Profile->get_trx()) {
3110  toolbar_hbox.pack_start (*_zoom_tearoff, false, false);
3111  toolbar_hbox.pack_start (*_tools_tearoff, false, false);
3112  }
3113 
3114  if (!ARDOUR::Profile->get_trx()) {
3115  hbox->pack_start (snap_box, false, false);
3116  if ( !Profile->get_small_screen() || Profile->get_mixbus() ) {
3117  hbox->pack_start (*nudge_box, false, false);
3118  } else {
3119  ARDOUR_UI::instance()->editor_transport_box().pack_start (*nudge_box, false, false);
3120  }
3121  }
3122  hbox->pack_start (panic_box, false, false);
3123 
3124  hbox->show_all ();
3125 
3126  toolbar_base.set_name ("ToolBarBase");
3127  toolbar_base.add (toolbar_hbox);
3128 
3130  /* stick to the required height but allow width to vary if there's not enough room */
3131  _toolbar_viewport.set_size_request (1, -1);
3132 
3133  toolbar_frame.set_shadow_type (SHADOW_OUT);
3134  toolbar_frame.set_name ("BaseFrame");
3136 }
3137 
3138 void
3140 {
3141  using namespace Menu_Helpers;
3142 
3143  edit_point_selector.AddMenuElem (MenuElem ( edit_point_strings[(int)EditAtPlayhead], sigc::bind (sigc::mem_fun(*this, &Editor::edit_point_selection_done), (EditPoint) EditAtPlayhead)));
3144  if(!Profile->get_mixbus())
3145  edit_point_selector.AddMenuElem (MenuElem ( edit_point_strings[(int)EditAtSelectedMarker], sigc::bind (sigc::mem_fun(*this, &Editor::edit_point_selection_done), (EditPoint) EditAtSelectedMarker)));
3146  edit_point_selector.AddMenuElem (MenuElem ( edit_point_strings[(int)EditAtMouse], sigc::bind (sigc::mem_fun(*this, &Editor::edit_point_selection_done), (EditPoint) EditAtMouse)));
3147 
3149 }
3150 
3151 void
3153 {
3154  using namespace Menu_Helpers;
3155 
3156  edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_strings[(int)Slide], sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Slide)));
3157 // edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_strings[(int)Splice], sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Splice)));
3158  edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_strings[(int)Ripple], sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Ripple)));
3159  edit_mode_selector.AddMenuElem (MenuElem ( edit_mode_strings[(int)Lock], sigc::bind (sigc::mem_fun(*this, &Editor::edit_mode_selection_done), (EditMode) Lock)));
3160 
3162 }
3163 
3164 void
3166 {
3167  using namespace Menu_Helpers;
3168 
3169  snap_mode_selector.AddMenuElem (MenuElem ( snap_mode_strings[(int)SnapOff], sigc::bind (sigc::mem_fun(*this, &Editor::snap_mode_selection_done), (SnapMode) SnapOff)));
3170  snap_mode_selector.AddMenuElem (MenuElem ( snap_mode_strings[(int)SnapNormal], sigc::bind (sigc::mem_fun(*this, &Editor::snap_mode_selection_done), (SnapMode) SnapNormal)));
3171  snap_mode_selector.AddMenuElem (MenuElem ( snap_mode_strings[(int)SnapMagnetic], sigc::bind (sigc::mem_fun(*this, &Editor::snap_mode_selection_done), (SnapMode) SnapMagnetic)));
3172 
3174 }
3175 
3176 void
3178 {
3179  using namespace Menu_Helpers;
3180 
3181  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToCDFrame], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToCDFrame)));
3182  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToTimecodeFrame], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToTimecodeFrame)));
3183  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToTimecodeSeconds], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToTimecodeSeconds)));
3184  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToTimecodeMinutes], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToTimecodeMinutes)));
3185  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToSeconds], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToSeconds)));
3186  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToMinutes], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToMinutes)));
3187  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv128], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv128)));
3188  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv64], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv64)));
3189  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv32], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv32)));
3190  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv28], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv28)));
3191  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv24], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv24)));
3192  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv20], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv20)));
3193  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv16], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv16)));
3194  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv14], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv14)));
3195  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv12], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv12)));
3196  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv10], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv10)));
3197  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv8], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv8)));
3198  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv7], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv7)));
3199  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv6], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv6)));
3200  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv5], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv5)));
3201  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv4], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv4)));
3202  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv3], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv3)));
3203  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeatDiv2], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeatDiv2)));
3204  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBeat], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBeat)));
3205  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToBar], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToBar)));
3206  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToMark], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToMark)));
3207  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToRegionStart], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToRegionStart)));
3208  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToRegionEnd], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToRegionEnd)));
3209  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToRegionSync], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToRegionSync)));
3210  snap_type_selector.AddMenuElem (MenuElem ( snap_type_strings[(int)SnapToRegionBoundary], sigc::bind (sigc::mem_fun(*this, &Editor::snap_type_selection_done), (SnapType) SnapToRegionBoundary)));
3211 
3213 
3214 }
3215 
3216 void
3218 {
3219  ARDOUR_UI::instance()->set_tip (smart_mode_button, _("Smart Mode (add Range functions to Grab mode)"));
3220  ARDOUR_UI::instance()->set_tip (mouse_move_button, _("Grab Mode (select/move objects)"));
3221  ARDOUR_UI::instance()->set_tip (mouse_cut_button, _("Cut Mode (split regions)"));
3222  ARDOUR_UI::instance()->set_tip (mouse_select_button, _("Range Mode (select time ranges)"));
3223  ARDOUR_UI::instance()->set_tip (mouse_draw_button, _("Draw Mode (draw and edit gain/notes/automation)"));
3224  ARDOUR_UI::instance()->set_tip (mouse_timefx_button, _("Stretch Mode (time-stretch audio and midi regions, preserving pitch)"));
3225  ARDOUR_UI::instance()->set_tip (mouse_audition_button, _("Audition Mode (listen to regions)"));
3226  ARDOUR_UI::instance()->set_tip (mouse_content_button, _("Internal Edit Mode (edit notes and gain curves inside regions)"));
3227  ARDOUR_UI::instance()->set_tip (*_group_tabs, _("Groups: click to (de)activate\nContext-click for other operations"));
3228  ARDOUR_UI::instance()->set_tip (nudge_forward_button, _("Nudge Region/Selection Later"));
3229  ARDOUR_UI::instance()->set_tip (nudge_backward_button, _("Nudge Region/Selection Earlier"));
3230  ARDOUR_UI::instance()->set_tip (zoom_in_button, _("Zoom In"));
3231  ARDOUR_UI::instance()->set_tip (zoom_out_button, _("Zoom Out"));
3232  ARDOUR_UI::instance()->set_tip (zoom_preset_selector, _("Zoom to Time Scale"));
3233  ARDOUR_UI::instance()->set_tip (zoom_out_full_button, _("Zoom to Session"));
3234  ARDOUR_UI::instance()->set_tip (zoom_focus_selector, _("Zoom focus"));
3235  ARDOUR_UI::instance()->set_tip (tav_expand_button, _("Expand Tracks"));
3236  ARDOUR_UI::instance()->set_tip (tav_shrink_button, _("Shrink Tracks"));
3237  ARDOUR_UI::instance()->set_tip (visible_tracks_selector, _("Number of visible tracks"));
3238  ARDOUR_UI::instance()->set_tip (snap_type_selector, _("Snap/Grid Units"));
3239  ARDOUR_UI::instance()->set_tip (snap_mode_selector, _("Snap/Grid Mode"));
3240  ARDOUR_UI::instance()->set_tip (edit_point_selector, _("Edit point"));
3241  ARDOUR_UI::instance()->set_tip (edit_mode_selector, _("Edit Mode"));
3242  ARDOUR_UI::instance()->set_tip (nudge_clock, _("Nudge Clock\n(controls distance used to nudge regions and selections)"));
3243 }
3244 
3245 int
3247  vector<string>& paths,
3248  const RefPtr<Gdk::DragContext>& /*context*/,
3249  gint /*x*/,
3250  gint /*y*/,
3251  const SelectionData& data,
3252  guint /*info*/,
3253  guint /*time*/)
3254 {
3255  if (_session == 0) {
3256  return -1;
3257  }
3258 
3259  vector<string> uris = data.get_uris();
3260 
3261  if (uris.empty()) {
3262 
3263  /* This is seriously fucked up. Nautilus doesn't say that its URI lists
3264  are actually URI lists. So do it by hand.
3265  */
3266 
3267  if (data.get_target() != "text/plain") {
3268  return -1;
3269  }
3270 
3271  /* Parse the "uri-list" format that Nautilus provides,
3272  where each pathname is delimited by \r\n.
3273 
3274  THERE MAY BE NO NULL TERMINATING CHAR!!!
3275  */
3276 
3277  string txt = data.get_text();
3278  char* p;
3279  const char* q;
3280 
3281  p = (char *) malloc (txt.length() + 1);
3282  txt.copy (p, txt.length(), 0);
3283  p[txt.length()] = '\0';
3284 
3285  while (p)
3286  {
3287  if (*p != '#')
3288  {
3289  while (g_ascii_isspace (*p))
3290  p++;
3291 
3292  q = p;
3293  while (*q && (*q != '\n') && (*q != '\r')) {
3294  q++;
3295  }
3296 
3297  if (q > p)
3298  {
3299  q--;
3300  while (q > p && g_ascii_isspace (*q))
3301  q--;
3302 
3303  if (q > p)
3304  {
3305  uris.push_back (string (p, q - p + 1));
3306  }
3307  }
3308  }
3309  p = strchr (p, '\n');
3310  if (p)
3311  p++;
3312  }
3313 
3314  free ((void*)p);
3315 
3316  if (uris.empty()) {
3317  return -1;
3318  }
3319  }
3320 
3321  for (vector<string>::iterator i = uris.begin(); i != uris.end(); ++i) {
3322  if ((*i).substr (0,7) == "file://") {
3323  paths.push_back (Glib::filename_from_uri (*i));
3324  }
3325  }
3326 
3327  return 0;
3328 }
3329 
3330 void
3332 {
3333 }
3334 
3335 void
3337 {
3339 
3340  if (_session && _session->transport_stopped()) {
3342  }
3343 
3345 }
3346 
3347 /* UNDO/REDO */
3348 
3349 void
3351 {
3354 
3355  while(!selection_op_history.empty()) {
3356  delete selection_op_history.front();
3357  selection_op_history.pop_front();
3358  }
3359 
3360  selection_undo_action->set_sensitive (false);
3361  selection_redo_action->set_sensitive (false);
3363 }
3364 
3365 void
3367 {
3368  if (_session) {
3369  //cerr << name << endl;
3370  /* begin/commit pairs can be nested */
3372  }
3373 }
3374 
3375 void
3377 {
3378  if (_session) {
3379  if (selection_op_cmd_depth == 1) {
3380 
3387  list<XMLNode *>::iterator it = selection_op_history.begin();
3388  list<XMLNode *>::iterator e_it = it;
3389  advance (e_it, selection_op_history_it);
3390 
3391  for ( ; it != e_it; ++it) {
3392  delete *it;
3393  }
3394  selection_op_history.erase (selection_op_history.begin(), e_it);
3395  }
3396 
3399 
3400  selection_undo_action->set_sensitive (true);
3401  selection_redo_action->set_sensitive (false);
3402  }
3403 
3404  if (selection_op_cmd_depth > 0) {
3406  }
3407  }
3408 }
3409 
3410 void
3412 {
3413  if (_session) {
3415  uint32_t n = 0;
3416  for (std::list<XMLNode *>::iterator i = selection_op_history.begin(); i != selection_op_history.end(); ++i) {
3417  if (n == selection_op_history_it) {
3418  _selection_memento->set_state (*(*i), Stateful::current_state_version);
3419  selection_redo_action->set_sensitive (true);
3420  }
3421  ++n;
3422  }
3423  /* is there an earlier entry? */
3424  if ((selection_op_history_it + 1) >= selection_op_history.size()) {
3425  selection_undo_action->set_sensitive (false);
3426  }
3427  }
3428 }
3429 
3430 void
3432 {
3433  if (_session) {
3434  if (selection_op_history_it > 0) {
3436  }
3437  uint32_t n = 0;
3438  for (std::list<XMLNode *>::iterator i = selection_op_history.begin(); i != selection_op_history.end(); ++i) {
3439  if (n == selection_op_history_it) {
3440  _selection_memento->set_state (*(*i), Stateful::current_state_version);
3441  selection_undo_action->set_sensitive (true);
3442  }
3443  ++n;
3444  }
3445 
3446  if (selection_op_history_it == 0) {
3447  selection_redo_action->set_sensitive (false);
3448  }
3449  }
3450 }
3451 
3452 void
3454 {
3455  if (_session) {
3456  before.push_back (&_selection_memento->get_state ());
3458  }
3459 }
3460 
3461 void
3463 {
3464  if (_session) {
3465  before.push_back (&_selection_memento->get_state ());
3467  }
3468 }
3469 
3470 void
3472 {
3473  if (_session) {
3474  while(!before.empty()) {
3475  delete before.front();
3476  before.pop_front();
3477  }
3479  }
3480 }
3481 
3482 void
3484 {
3485  if (_session) {
3486  if (before.size() == 1) {
3488  redo_action->set_sensitive(false);
3489  undo_action->set_sensitive(true);
3491  }
3492 
3493  if (before.empty()) {
3494  cerr << "Please call begin_reversible_command() before commit_reversible_command()." << endl;
3495  } else {
3496  before.pop_back();
3497  }
3498 
3500  }
3501 }
3502 
3503 void
3505 {
3506  string label;
3507 
3508  if (undo_action && _session) {
3509  if (_session->undo_depth() == 0) {
3510  label = S_("Command|Undo");
3511  } else {
3512  label = string_compose(S_("Command|Undo (%1)"), _session->next_undo());
3513  }
3514  undo_action->property_label() = label;
3515  }
3516 
3517  if (redo_action && _session) {
3518  if (_session->redo_depth() == 0) {
3519  label = _("Redo");
3520  } else {
3521  label = string_compose(_("Redo (%1)"), _session->next_redo());
3522  }
3523  redo_action->property_label() = label;
3524  }
3525 }
3526 
3527 void
3528 Editor::duplicate_range (bool with_dialog)
3529 {
3530  float times = 1.0f;
3531 
3533 
3534  if ( selection->time.length() == 0 && rs.empty()) {
3535  return;
3536  }
3537 
3538  if (with_dialog) {
3539 
3540  ArdourDialog win (_("Duplicate"));
3541  Label label (_("Number of duplications:"));
3542  Adjustment adjustment (1.0, 1.0, 1000000.0, 1.0, 5.0);
3543  SpinButton spinner (adjustment, 0.0, 1);
3544  HBox hbox;
3545 
3546  win.get_vbox()->set_spacing (12);
3547  win.get_vbox()->pack_start (hbox);
3548  hbox.set_border_width (6);
3549  hbox.pack_start (label, PACK_EXPAND_PADDING, 12);
3550 
3551  /* dialogs have ::add_action_widget() but that puts the spinner in the wrong
3552  place, visually. so do this by hand.
3553  */
3554 
3555  hbox.pack_start (spinner, PACK_EXPAND_PADDING, 12);
3556  spinner.signal_activate().connect (sigc::bind (sigc::mem_fun (win, &ArdourDialog::response), RESPONSE_ACCEPT));
3557  spinner.grab_focus();
3558 
3559  hbox.show ();
3560  label.show ();
3561  spinner.show ();
3562 
3563  win.add_button (Stock::CANCEL, RESPONSE_CANCEL);
3564  win.add_button (_("Duplicate"), RESPONSE_ACCEPT);
3565  win.set_default_response (RESPONSE_ACCEPT);
3566 
3567  spinner.grab_focus ();
3568 
3569  switch (win.run ()) {
3570  case RESPONSE_ACCEPT:
3571  break;
3572  default:
3573  return;
3574  }
3575 
3576  times = adjustment.get_value();
3577  }
3578 
3579  if ((current_mouse_mode() == Editing::MouseRange)) {
3580  if (selection->time.length()) {
3581  duplicate_selection (times);
3582  }
3583  } else if (get_smart_mode()) {
3584  if (selection->time.length()) {
3585  duplicate_selection (times);
3586  } else
3587  duplicate_some_regions (rs, times);
3588  } else {
3589  duplicate_some_regions (rs, times);
3590  }
3591 }
3592 
3593 void
3595 {
3596  Config->set_edit_mode (m);
3597 }
3598 
3599 void
3601 {
3602  switch (Config->get_edit_mode()) {
3603  case Slide:
3604  if (Profile->get_sae()) {
3605  Config->set_edit_mode (Lock);
3606  } else {
3607  Config->set_edit_mode (Ripple);
3608  }
3609  break;
3610  case Splice:
3611  case Ripple:
3612  Config->set_edit_mode (Lock);
3613  break;
3614  case Lock:
3615  Config->set_edit_mode (Slide);
3616  break;
3617  }
3618 }
3619 
3620 void
3622 {
3623  Config->set_edit_mode ( m );
3624 }
3625 
3626 void
3628 {
3629  RefPtr<RadioAction> ract = snap_type_action (snaptype);
3630  if (ract) {
3631  ract->set_active ();
3632  }
3633 }
3634 
3635 void
3637 {
3638  RefPtr<RadioAction> ract = snap_mode_action (mode);
3639 
3640  if (ract) {
3641  ract->set_active (true);
3642  }
3643 }
3644 
3645 void
3646 Editor::cycle_edit_point (bool with_marker)
3647 {
3648  if(Profile->get_mixbus())
3649  with_marker = false;
3650 
3651  switch (_edit_point) {
3652  case EditAtMouse:
3653  set_edit_point_preference (EditAtPlayhead);
3654  break;
3655  case EditAtPlayhead:
3656  if (with_marker) {
3657  set_edit_point_preference (EditAtSelectedMarker);
3658  } else {
3659  set_edit_point_preference (EditAtMouse);
3660  }
3661  break;
3662  case EditAtSelectedMarker:
3663  set_edit_point_preference (EditAtMouse);
3664  break;
3665  }
3666 }
3667 
3668 void
3670 {
3672 }
3673 
3674 void
3676 {
3677  using namespace Menu_Helpers;
3678 
3679  zoom_focus_selector.AddMenuElem (MenuElem ( zoom_focus_strings[(int)ZoomFocusLeft], sigc::bind (sigc::mem_fun(*this, &Editor::zoom_focus_selection_done), (ZoomFocus) ZoomFocusLeft)));
3680  zoom_focus_selector.AddMenuElem (MenuElem ( zoom_focus_strings[(int)ZoomFocusRight], sigc::bind (sigc::mem_fun(*this, &Editor::zoom_focus_selection_done), (ZoomFocus) ZoomFocusRight)));
3681  zoom_focus_selector.AddMenuElem (MenuElem ( zoom_focus_strings[(int)ZoomFocusCenter], sigc::bind (sigc::mem_fun(*this, &Editor::zoom_focus_selection_done), (ZoomFocus) ZoomFocusCenter)));
3682  zoom_focus_selector.AddMenuElem (MenuElem ( zoom_focus_strings[(int)ZoomFocusPlayhead], sigc::bind (sigc::mem_fun(*this, &Editor::zoom_focus_selection_done), (ZoomFocus) ZoomFocusPlayhead)));
3683  zoom_focus_selector.AddMenuElem (MenuElem ( zoom_focus_strings[(int)ZoomFocusMouse], sigc::bind (sigc::mem_fun(*this, &Editor::zoom_focus_selection_done), (ZoomFocus) ZoomFocusMouse)));
3684  zoom_focus_selector.AddMenuElem (MenuElem ( zoom_focus_strings[(int)ZoomFocusEdit], sigc::bind (sigc::mem_fun(*this, &Editor::zoom_focus_selection_done), (ZoomFocus) ZoomFocusEdit)));
3685 
3687 }
3688 
3689 void
3691 {
3692  RefPtr<RadioAction> ract = zoom_focus_action (f);
3693  if (ract) {
3694  ract->set_active ();
3695  }
3696 }
3697 
3698 void
3700 {
3701  using namespace Menu_Helpers;
3702 
3703  if (!Profile->get_mixbus()) {
3704  visible_tracks_selector.AddMenuElem (MenuElem (X_("1"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 1)));
3705  visible_tracks_selector.AddMenuElem (MenuElem (X_("2"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 2)));
3706  visible_tracks_selector.AddMenuElem (MenuElem (X_("3"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 3)));
3707  visible_tracks_selector.AddMenuElem (MenuElem (X_("4"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 4)));
3708  visible_tracks_selector.AddMenuElem (MenuElem (X_("8"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 8)));
3709  visible_tracks_selector.AddMenuElem (MenuElem (X_("12"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 12)));
3710  visible_tracks_selector.AddMenuElem (MenuElem (X_("16"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 16)));
3711  visible_tracks_selector.AddMenuElem (MenuElem (X_("20"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 20)));
3712  visible_tracks_selector.AddMenuElem (MenuElem (X_("24"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 24)));
3713  visible_tracks_selector.AddMenuElem (MenuElem (X_("32"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 32)));
3714  visible_tracks_selector.AddMenuElem (MenuElem (X_("64"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 64)));
3715  visible_tracks_selector.AddMenuElem (MenuElem (_("Selection"), sigc::mem_fun(*this, &Editor::fit_selection)));
3716  visible_tracks_selector.AddMenuElem (MenuElem (_("All"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 0)));
3717  } else {
3718  visible_tracks_selector.AddMenuElem (MenuElem (_("Fit 1 track"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 1)));
3719  visible_tracks_selector.AddMenuElem (MenuElem (_("Fit 2 tracks"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 2)));
3720  visible_tracks_selector.AddMenuElem (MenuElem (_("Fit 4 tracks"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 4)));
3721  visible_tracks_selector.AddMenuElem (MenuElem (_("Fit 8 tracks"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 8)));
3722  visible_tracks_selector.AddMenuElem (MenuElem (_("Fit 16 tracks"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 16)));
3723  visible_tracks_selector.AddMenuElem (MenuElem (_("Fit 24 tracks"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 24)));
3724  visible_tracks_selector.AddMenuElem (MenuElem (_("Fit 32 tracks"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 32)));
3725  visible_tracks_selector.AddMenuElem (MenuElem (_("Fit 48 tracks"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 48)));
3726  visible_tracks_selector.AddMenuElem (MenuElem (_("Fit All tracks"), sigc::bind (sigc::mem_fun(*this, &Editor::set_visible_track_count), 0)));
3727  visible_tracks_selector.AddMenuElem (MenuElem (_("Fit Selection"), sigc::mem_fun(*this, &Editor::fit_selection)));
3728 
3729  zoom_preset_selector.AddMenuElem (MenuElem (_("Zoom to 10 ms"), sigc::bind (sigc::mem_fun(*this, &Editor::set_zoom_preset), 10)));
3730  zoom_preset_selector.AddMenuElem (MenuElem (_("Zoom to 100 ms"), sigc::bind (sigc::mem_fun(*this, &Editor::set_zoom_preset), 100)));
3731  zoom_preset_selector.AddMenuElem (MenuElem (_("Zoom to 1 sec"), sigc::bind (sigc::mem_fun(*this, &Editor::set_zoom_preset), 1 * 1000)));
3732  zoom_preset_selector.AddMenuElem (MenuElem (_("Zoom to 10 sec"), sigc::bind (sigc::mem_fun(*this, &Editor::set_zoom_preset), 10 * 1000)));
3733  zoom_preset_selector.AddMenuElem (MenuElem (_("Zoom to 1 min"), sigc::bind (sigc::mem_fun(*this, &Editor::set_zoom_preset), 60 * 1000)));
3734  zoom_preset_selector.AddMenuElem (MenuElem (_("Zoom to 10 min"), sigc::bind (sigc::mem_fun(*this, &Editor::set_zoom_preset), 10 * 60 * 1000)));
3735  zoom_preset_selector.AddMenuElem (MenuElem (_("Zoom to 1 hour"), sigc::bind (sigc::mem_fun(*this, &Editor::set_zoom_preset), 60 * 60 * 1000)));
3736  zoom_preset_selector.AddMenuElem (MenuElem (_("Zoom to 8 hours"), sigc::bind (sigc::mem_fun(*this, &Editor::set_zoom_preset), 8 * 60 * 60 * 1000)));
3737  zoom_preset_selector.AddMenuElem (MenuElem (_("Zoom to 24 hours"), sigc::bind (sigc::mem_fun(*this, &Editor::set_zoom_preset), 24 * 60 * 60 * 1000)));
3738  zoom_preset_selector.AddMenuElem (MenuElem (_("Zoom to Session"), sigc::mem_fun(*this, &Editor::temporal_zoom_session)));
3739  zoom_preset_selector.AddMenuElem (MenuElem (_("Zoom to Range/Region Selection"), sigc::bind (sigc::mem_fun(*this, &Editor::temporal_zoom_selection), false)));
3740  }
3741 }
3742 
3743 void
3745 {
3746  if ( ms <= 0 ) {
3748  return;
3749  }
3750 
3752  temporal_zoom( (sample_rate * ms / 1000) / _visible_canvas_width );
3753 }
3754 
3755 void
3757 {
3759 
3760  /* if the canvas hasn't really been allocated any size yet, just
3761  record the desired number of visible tracks and return. when canvas
3762  allocation happens, we will get called again and then we can do the
3763  real work.
3764  */
3765 
3766  if (_visible_canvas_height <= 1) {
3767  return;
3768  }
3769 
3770  int h;
3771  string str;
3772  DisplaySuspender ds;
3773 
3774  if (_visible_track_count > 0) {
3776  std::ostringstream s;
3777  s << _visible_track_count;
3778  str = s.str();
3779  } else if (_visible_track_count == 0) {
3780  uint32_t n = 0;
3781  for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
3782  if ((*i)->marked_for_display()) {
3783  ++n;
3784  }
3785  }
3786  h = trackviews_height() / n;
3787  str = _("All");
3788  } else {
3789  /* negative value means that the visible track count has
3790  been overridden by explicit track height changes.
3791  */
3793  return;
3794  }
3795 
3796  for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
3797  (*i)->set_height (h, TimeAxisView::HeightPerLane);
3798  }
3799 
3800  if (str != visible_tracks_selector.get_text()) {
3802  }
3803 }
3804 
3805 void
3807 {
3808  _visible_track_count = -1;
3810 }
3811 
3812 bool
3814 {
3815  if (Keyboard::is_context_menu_event (ev)) {
3816  ARDOUR_UI::instance()->add_route (this);
3817  } else if (ev->button == 1) {
3818  selection->clear_tracks ();
3819  }
3820 
3821  return true;
3822 }
3823 
3824 bool
3826 {
3827  /* this handles just right-clicks */
3828 
3829  if (ev->button != 3) {
3830  return false;
3831  }
3832 
3833  return true;
3834 }
3835 
3836 void
3838 {
3839  string str = zoom_focus_strings[(int)f];
3840 
3841  if (str != zoom_focus_selector.get_text()) {
3843  }
3844 
3845  if (zoom_focus != f) {
3846  zoom_focus = f;
3847  instant_save ();
3848  }
3849 }
3850 
3851 void
3853 {
3854  switch (zoom_focus) {
3855  case ZoomFocusLeft:
3856  set_zoom_focus (ZoomFocusRight);
3857  break;
3858  case ZoomFocusRight:
3859  set_zoom_focus (ZoomFocusCenter);
3860  break;
3861  case ZoomFocusCenter:
3862  set_zoom_focus (ZoomFocusPlayhead);
3863  break;
3864  case ZoomFocusPlayhead:
3865  set_zoom_focus (ZoomFocusMouse);
3866  break;
3867  case ZoomFocusMouse:
3868  set_zoom_focus (ZoomFocusEdit);
3869  break;
3870  case ZoomFocusEdit:
3871  set_zoom_focus (ZoomFocusLeft);
3872  break;
3873  }
3874 }
3875 
3876 void
3878 {
3879  win.set_transient_for (*this);
3880 }
3881 
3882 void
3883 Editor::pane_allocation_handler (Allocation &alloc, Paned* which)
3884 {
3885  /* recover or initialize pane positions. do this here rather than earlier because
3886  we don't want the positions to change the child allocations, which they seem to do.
3887  */
3888 
3889  int pos;
3890  XMLProperty* prop;
3891  char buf[32];
3893 
3894  enum Pane {
3895  Horizontal = 0x1,
3896  Vertical = 0x2
3897  };
3898 
3899  static Pane done;
3900 
3901  XMLNode* geometry = find_named_node (*node, "geometry");
3902 
3903  if (which == static_cast<Paned*> (&edit_pane)) {
3904 
3905  if (done & Horizontal) {
3906  return;
3907  }
3908 
3909  if (geometry && (prop = geometry->property ("notebook-shrunk"))) {
3911  }
3912 
3913  if (!geometry || (prop = geometry->property ("edit-horizontal-pane-pos")) == 0) {
3914  /* initial allocation is 90% to canvas, 10% to notebook */
3915  pos = (int) floor (alloc.get_width() * 0.90f);
3916  snprintf (buf, sizeof(buf), "%d", pos);
3917  } else {
3918  pos = atoi (prop->value());
3919  }
3920 
3921  if (GTK_WIDGET(edit_pane.gobj())->allocation.width > pos) {
3922  edit_pane.set_position (pos);
3923  }
3924 
3925  done = (Pane) (done | Horizontal);
3926 
3927  } else if (which == static_cast<Paned*> (&editor_summary_pane)) {
3928 
3929  if (done & Vertical) {
3930  return;
3931  }
3932 
3933  if (!geometry || (prop = geometry->property ("edit-vertical-pane-pos")) == 0) {
3934  /* initial allocation is 90% to canvas, 10% to summary */
3935  pos = (int) floor (alloc.get_height() * 0.90f);
3936  snprintf (buf, sizeof(buf), "%d", pos);
3937  } else {
3938 
3939  pos = atoi (prop->value());
3940  }
3941 
3942  if (GTK_WIDGET(editor_summary_pane.gobj())->allocation.height > pos) {
3943  editor_summary_pane.set_position (pos);
3944  }
3945 
3946  done = (Pane) (done | Vertical);
3947  }
3948 }
3949 
3950 void
3951 Editor::detach_tearoff (Box* /*b*/, Window* /*w*/)
3952 {
3953  if ((_tools_tearoff->torn_off() || !_tools_tearoff->visible()) &&
3956  top_hbox.remove (toolbar_frame);
3957  }
3958 }
3959 
3960 void
3961 Editor::reattach_tearoff (Box* /*b*/, Window* /*w*/, int32_t /*n*/)
3962 {
3963  if (toolbar_frame.get_parent() == 0) {
3964  top_hbox.pack_end (toolbar_frame);
3965  }
3966 }
3967 
3968 void
3970 {
3971  if (_show_measures != yn) {
3972  hide_measures ();
3973 
3974  if ((_show_measures = yn) == true) {
3975  if (tempo_lines) {
3976  tempo_lines->show();
3977  }
3978 
3979  ARDOUR::TempoMap::BBTPointList::const_iterator begin;
3980  ARDOUR::TempoMap::BBTPointList::const_iterator end;
3981 
3983  draw_measures (begin, end);
3984  }
3985 
3986  instant_save ();
3987  }
3988 }
3989 
3990 void
3992 {
3993  RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-follow-playhead"));
3994  if (act) {
3995  RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
3996  set_follow_playhead (tact->get_active());
3997  }
3998 }
3999 
4003 void
4004 Editor::set_follow_playhead (bool yn, bool catch_up)
4005 {
4006  if (_follow_playhead != yn) {
4007  if ((_follow_playhead = yn) == true && catch_up) {
4008  /* catch up */
4010  }
4011  instant_save ();
4012  }
4013 }
4014 
4015 void
4017 {
4018  RefPtr<Action> act = ActionManager::get_action (X_("Editor"), X_("toggle-stationary-playhead"));
4019  if (act) {
4020  RefPtr<ToggleAction> tact = RefPtr<ToggleAction>::cast_dynamic(act);
4021  set_stationary_playhead (tact->get_active());
4022  }
4023 }
4024 
4025 void
4027 {
4028  if (_stationary_playhead != yn) {
4029  if ((_stationary_playhead = yn) == true) {
4030  /* catch up */
4031  // FIXME need a 3.0 equivalent of this 2.X call
4032  // update_current_screen ();
4033  }
4034  instant_save ();
4035  }
4036 }
4037 
4040 {
4041  return *_playlist_selector;
4042 }
4043 
4044 framecnt_t
4046 {
4047  if (paste_count == 0) {
4048  /* don't bother calculating an offset that will be zero anyway */
4049  return 0;
4050  }
4051 
4052  /* calculate basic unsnapped multi-paste offset */
4053  framecnt_t offset = paste_count * duration;
4054 
4055  /* snap offset so pos + offset is aligned to the grid */
4056  framepos_t offset_pos = pos + offset;
4057  snap_to(offset_pos, RoundUpMaybe);
4058  offset = offset_pos - pos;
4059 
4060  return offset;
4061 }
4062 
4063 unsigned
4065 {
4066  switch (_snap_type) {
4067  case SnapToBeatDiv128: return 128;
4068  case SnapToBeatDiv64: return 64;
4069  case SnapToBeatDiv32: return 32;
4070  case SnapToBeatDiv28: return 28;
4071  case SnapToBeatDiv24: return 24;
4072  case SnapToBeatDiv20: return 20;
4073  case SnapToBeatDiv16: return 16;
4074  case SnapToBeatDiv14: return 14;
4075  case SnapToBeatDiv12: return 12;
4076  case SnapToBeatDiv10: return 10;
4077  case SnapToBeatDiv8: return 8;
4078  case SnapToBeatDiv7: return 7;
4079  case SnapToBeatDiv6: return 6;
4080  case SnapToBeatDiv5: return 5;
4081  case SnapToBeatDiv4: return 4;
4082  case SnapToBeatDiv3: return 3;
4083  case SnapToBeatDiv2: return 2;
4084  default: return 0;
4085  }
4086  return 0;
4087 }
4088 
4091 {
4092  success = true;
4093 
4094  const unsigned divisions = get_grid_beat_divisions(position);
4095  if (divisions) {
4096  return Evoral::Beats(1.0 / (double)get_grid_beat_divisions(position));
4097  }
4098 
4099  switch (_snap_type) {
4100  case SnapToBeat:
4101  return Evoral::Beats(1.0);
4102  case SnapToBar:
4103  if (_session) {
4104  return Evoral::Beats(_session->tempo_map().meter_at (position).divisions_per_bar());
4105  }
4106  break;
4107  default:
4108  success = false;
4109  break;
4110  }
4111 
4112  return Evoral::Beats();
4113 }
4114 
4115 framecnt_t
4117 {
4118  framecnt_t ret;
4119 
4120  ret = nudge_clock->current_duration (pos);
4121  next = ret + 1; /* XXXX fix me */
4122 
4123  return ret;
4124 }
4125 
4126 int
4128 {
4129  ArdourDialog dialog (_("Playlist Deletion"));
4130  Label label (string_compose (_("Playlist %1 is currently unused.\n"
4131  "If it is kept, its audio files will not be cleaned.\n"
4132  "If it is deleted, audio files used by it alone will be cleaned."),
4133  pl->name()));
4134 
4135  dialog.set_position (WIN_POS_CENTER);
4136  dialog.get_vbox()->pack_start (label);
4137 
4138  label.show ();
4139 
4140  dialog.add_button (_("Delete Playlist"), RESPONSE_ACCEPT);
4141  dialog.add_button (_("Keep Playlist"), RESPONSE_REJECT);
4142  dialog.add_button (_("Cancel"), RESPONSE_CANCEL);
4143 
4144  switch (dialog.run ()) {
4145  case RESPONSE_ACCEPT:
4146  /* delete the playlist */
4147  return 0;
4148  break;
4149 
4150  case RESPONSE_REJECT:
4151  /* keep the playlist */
4152  return 1;
4153  break;
4154 
4155  default:
4156  break;
4157  }
4158 
4159  return -1;
4160 }
4161 
4162 bool
4164 {
4165  for (RegionSelection::iterator a = selection->regions.begin(); a != selection->regions.end(); ++a) {
4166  if ((*a)->region()->covers (where)) {
4167  return true;
4168  }
4169  }
4170 
4171  return false;
4172 }
4173 
4174 void
4176 {
4179 
4182 
4184 }
4185 
4186 void
4188 {
4190 }
4191 
4192 Location*
4194 {
4195  if (_session) {
4196  return _session->locations()->auto_loop_location();
4197  } else {
4198  return 0;
4199  }
4200 }
4201 
4202 Location*
4204 {
4205  if (_session) {
4206  return _session->locations()->auto_punch_location();
4207  } else {
4208  return 0;
4209  }
4210 }
4211 
4212 bool
4213 Editor::control_layout_scroll (GdkEventScroll* ev)
4214 {
4215  /* Just forward to the normal canvas scroll method. The coordinate
4216  systems are different but since the canvas is always larger than the
4217  track headers, and aligned with the trackview area, this will work.
4218 
4219  In the not too distant future this layout is going away anyway and
4220  headers will be on the canvas.
4221  */
4222  return canvas_scroll_event (ev, false);
4223 }
4224 
4225 void
4227 {
4228  update_title ();
4229  _snapshots->redisplay ();
4230 }
4231 
4232 void
4234 {
4235  bool visible = ARDOUR_UI::config()->get_keep_tearoffs();
4236  _mouse_mode_tearoff->set_visible (visible);
4237  _tools_tearoff->set_visible (visible);
4238  if (_zoom_tearoff) {
4239  _zoom_tearoff->set_visible (visible);
4240  }
4241 }
4242 
4243 void
4245 {
4249 }
4250 
4251 void
4253 {
4254  if (_maximised) {
4255  return;
4256  }
4257 
4258  fullscreen ();
4259 
4260  _maximised = true;
4261 }
4262 
4263 void
4265 {
4266  if (!_maximised) {
4267  return;
4268  }
4269 
4270  unfullscreen();
4271 
4272  _maximised = false;
4273 }
4274 
4281 void
4283 {
4284  begin_reversible_command (_("new playlists"));
4285  vector<boost::shared_ptr<ARDOUR::Playlist> > playlists;
4286  _session->playlists->get (playlists);
4287  mapover_tracks (sigc::bind (sigc::mem_fun (*this, &Editor::mapped_use_new_playlist), playlists), v, ARDOUR::Properties::select.property_id);
4289 }
4290 
4297 void
4299 {
4300  begin_reversible_command (_("copy playlists"));
4301  vector<boost::shared_ptr<ARDOUR::Playlist> > playlists;
4302  _session->playlists->get (playlists);
4303  mapover_tracks (sigc::bind (sigc::mem_fun (*this, &Editor::mapped_use_copy_playlist), playlists), v, ARDOUR::Properties::select.property_id);
4305 }
4306 
4312 void
4314 {
4315  begin_reversible_command (_("clear playlists"));
4316  vector<boost::shared_ptr<ARDOUR::Playlist> > playlists;
4317  _session->playlists->get (playlists);
4318  mapover_tracks (sigc::mem_fun (*this, &Editor::mapped_clear_playlist), v, ARDOUR::Properties::select.property_id);
4320 }
4321 
4322 void
4324 {
4325  atv.use_new_playlist (sz > 1 ? false : true, playlists);
4326 }
4327 
4328 void
4330 {
4331  atv.use_copy_playlist (sz > 1 ? false : true, playlists);
4332 }
4333 
4334 void
4336 {
4337  atv.clear_playlist ();
4338 }
4339 
4340 bool
4342 {
4343  return key_press_focus_accelerator_handler (*this, ev);
4344 }
4345 
4346 bool
4348 {
4349  return Gtk::Window::on_key_release_event (ev);
4350  // return key_press_focus_accelerator_handler (*this, ev);
4351 }
4352 
4353 double
4355 {
4356  return vertical_adjustment.get_value ();
4357 }
4358 
4362 void
4364 {
4368 }
4369 
4370 void
4372 {
4376 }
4377 
4378 void
4380 {
4381  if (spp == samples_per_pixel) {
4382  return;
4383  }
4384 
4388 }
4389 
4390 void
4392 {
4393  reset_x_origin (frame);
4394  reset_zoom (fpu);
4395 
4396  if (!no_save_visual) {
4397  undo_visual_stack.push_back (current_visual_state(false));
4398  }
4399 }
4400 
4402  : gui_state (with_tracks ? new GUIObjectState : 0)
4403 {
4404 }
4405 
4407 {
4408  delete gui_state;
4409 }
4410 
4413 {
4414  VisualState* vs = new VisualState (with_tracks);
4415  vs->y_position = vertical_adjustment.get_value();
4418  vs->zoom_focus = zoom_focus;
4419 
4420  if (with_tracks) {
4422  }
4423 
4424  return vs;
4425 }
4426 
4427 void
4429 {
4430  if (undo_visual_stack.empty()) {
4431  return;
4432  }
4433 
4434  VisualState* vs = undo_visual_stack.back();
4435  undo_visual_stack.pop_back();
4436 
4437 
4438  redo_visual_stack.push_back (current_visual_state (vs ? vs->gui_state != 0 : false));
4439 
4440  if (vs) {
4441  use_visual_state (*vs);
4442  }
4443 }
4444 
4445 void
4447 {
4448  if (redo_visual_stack.empty()) {
4449  return;
4450  }
4451 
4452  VisualState* vs = redo_visual_stack.back();
4453  redo_visual_stack.pop_back();
4454 
4455  // can 'vs' really be 0? Is there a place that puts NULL pointers onto the stack?
4456  // why do we check here?
4457  undo_visual_stack.push_back (current_visual_state (vs ? (vs->gui_state != 0) : false));
4458 
4459  if (vs) {
4460  use_visual_state (*vs);
4461  }
4462 }
4463 
4464 void
4466 {
4467  if (undo_visual_stack.empty()) {
4468  redo_visual_state ();
4469  } else {
4470  undo_visual_state ();
4471  }
4472 }
4473 
4474 void
4476 {
4477  PBD::Unwinder<bool> nsv (no_save_visual, true);
4478  DisplaySuspender ds;
4479 
4480  vertical_adjustment.set_value (vs.y_position);
4481 
4484 
4485  if (vs.gui_state) {
4487 
4488  for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
4489  (*i)->clear_property_cache();
4490  (*i)->reset_visual_state ();
4491  }
4492  }
4493 
4495 }
4496 
4501 void
4503 {
4504  if (spp < 1) {
4505  return;
4506  }
4507 
4508  const framecnt_t three_days = 3 * 24 * 60 * 60 * (_session ? _session->frame_rate() : 48000);
4509  const framecnt_t lots_of_pixels = 4000;
4510 
4511  /* if the zoom level is greater than what you'd get trying to display 3
4512  * days of audio on a really big screen, then it's too big.
4513  */
4514 
4515  if (spp * lots_of_pixels > three_days) {
4516  return;
4517  }
4518 
4519  samples_per_pixel = spp;
4520 
4521  if (tempo_lines) {
4523  }
4524 
4525  bool const showing_time_selection = selection->time.length() > 0;
4526 
4527  if (showing_time_selection && selection->time.start () != selection->time.end_frame ()) {
4528  for (TrackViewList::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
4529  (*i)->reshow_selection (selection->time);
4530  }
4531  }
4532 
4533  ZoomChanged (); /* EMIT_SIGNAL */
4534 
4535  ArdourCanvas::GtkCanvasViewport* c;
4536 
4537  c = get_track_canvas();
4538  if (c) {
4539  c->canvas()->zoomed ();
4540  }
4541 
4542  if (playhead_cursor) {
4544  }
4545 
4548 
4550 
4551  instant_save ();
4552 }
4553 
4554 void
4556 {
4557  /* TODO:
4558  * pending_visual_change.add (VisualChange::VideoTimeline);
4559  * or maybe even more specific: which videotimeline-image
4560  * currently it calls update_video_timeline() to update
4561  * _all outdated_ images on the video-timeline.
4562  * see 'exposeimg()' in video_image_frame.cc
4563  */
4565 }
4566 
4567 void
4569 {
4571  // see comment in add_to_idle_resize above.
4572  pending_visual_change.idle_handler_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, _idle_visual_changer, this, NULL);
4574  }
4575 }
4576 
4577 int
4579 {
4580  return static_cast<Editor*>(arg)->idle_visual_changer ();
4581 }
4582 
4583 int
4585 {
4586  /* set_horizontal_position() below (and maybe other calls) call
4587  gtk_main_iteration(), so it's possible that a signal will be handled
4588  half-way through this method. If this signal wants an
4589  idle_visual_changer we must schedule another one after this one, so
4590  mark the idle_handler_id as -1 here to allow that. Also make a note
4591  that we are doing the visual change, so that changes in response to
4592  super-rapid-screen-update can be dropped if we are still processing
4593  the last one.
4594  */
4595 
4598 
4600 
4602 
4603  visual_changer (vc);
4604 
4606 
4607  return 0; /* this is always a one-shot call */
4608 }
4609 
4610 void
4612 {
4613  double const last_time_origin = horizontal_position ();
4614 
4615  if (vc.pending & VisualChange::ZoomLevel) {
4617 
4619 
4620  ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin;
4621  ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end;
4622 
4624  current_bbt_points_begin, current_bbt_points_end);
4626  current_bbt_points_begin, current_bbt_points_end);
4627  update_tempo_based_rulers (current_bbt_points_begin, current_bbt_points_end);
4628 
4630  }
4631 
4632  if (vc.pending & VisualChange::TimeOrigin) {
4634  }
4635 
4636  if (vc.pending & VisualChange::YOrigin) {
4637  vertical_adjustment.set_value (vc.y_origin);
4638  }
4639 
4640  if (last_time_origin == horizontal_position ()) {
4641  /* changed signal not emitted */
4643  redisplay_tempo (true);
4644  }
4645 
4646  if (!(vc.pending & VisualChange::ZoomLevel)) {
4648  }
4649 
4651 }
4652 
4654  bool operator() (const TimeAxisView* a, const TimeAxisView* b) const {
4655  return a->order () < b->order ();
4656  }
4657 };
4658 
4659 void
4661 {
4663  sel.sort (cmp);
4664 }
4665 
4666 framepos_t
4667 Editor::get_preferred_edit_position (EditIgnoreOption ignore, bool from_context_menu, bool from_outside_canvas)
4668 {
4669  bool ignored;
4670  framepos_t where = 0;
4671  EditPoint ep = _edit_point;
4672 
4673  if (Profile->get_mixbus())
4674  if (ep == EditAtSelectedMarker)
4675  ep = EditAtPlayhead;
4676 
4677  if (from_outside_canvas && (ep == EditAtMouse)) {
4678  ep = EditAtPlayhead;
4679  } else if (from_context_menu && (ep == EditAtMouse)) {
4680  return canvas_event_sample (&context_click_event, 0, 0);
4681  }
4682 
4683  if (entered_marker) {
4684  DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("GPEP: use entered marker @ %1\n", entered_marker->position()));
4685  return entered_marker->position();
4686  }
4687 
4688  if ( (ignore==EDIT_IGNORE_PHEAD) && ep == EditAtPlayhead) {
4689  ep = EditAtSelectedMarker;
4690  }
4691 
4692  if ( (ignore==EDIT_IGNORE_MOUSE) && ep == EditAtMouse) {
4693  ep = EditAtPlayhead;
4694  }
4695 
4696  switch (ep) {
4697  case EditAtPlayhead:
4698  if (_dragging_playhead) {
4699  if (!mouse_frame (where, ignored)) {
4700  /* XXX not right but what can we do ? */
4701  return 0;
4702  }
4703  } else {
4704  where = _session->audible_frame();
4705  }
4706  DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("GPEP: use playhead @ %1\n", where));
4707  break;
4708 
4709  case EditAtSelectedMarker:
4710  if (!selection->markers.empty()) {
4711  bool is_start;
4712  Location* loc = find_location_from_marker (selection->markers.front(), is_start);
4713  if (loc) {
4714  if (is_start) {
4715  where = loc->start();
4716  } else {
4717  where = loc->end();
4718  }
4719  DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("GPEP: use selected marker @ %1\n", where));
4720  break;
4721  }
4722  }
4723  /* fallthru */
4724 
4725  default:
4726  case EditAtMouse:
4727  if (!mouse_frame (where, ignored)) {
4728  /* XXX not right but what can we do ? */
4729  return 0;
4730  }
4731  snap_to (where);
4732  DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("GPEP: use mouse @ %1\n", where));
4733  break;
4734  }
4735 
4736  return where;
4737 }
4738 
4739 void
4741 {
4742  if (!_session) return;
4743 
4745 
4746  Location* tll;
4747 
4748  if ((tll = transport_loop_location()) == 0) {
4749  Location* loc = new Location (*_session, start, end, _("Loop"), Location::IsAutoLoop);
4751  _session->locations()->add (loc, true);
4753  XMLNode &after = _session->locations()->get_state();
4754  _session->add_command (new MementoCommand<Locations>(*(_session->locations()), &before, &after));
4755  } else {
4756  XMLNode &before = tll->get_state();
4757  tll->set_hidden (false, this);
4758  tll->set (start, end);
4759  XMLNode &after = tll->get_state();
4760  _session->add_command (new MementoCommand<Location>(*tll, &before, &after));
4761  }
4762 
4764 }
4765 
4766 void
4768 {
4769  if (!_session) return;
4770 
4772 
4773  Location* tpl;
4774 
4775  if ((tpl = transport_punch_location()) == 0) {
4776  Location* loc = new Location (*_session, start, end, _("Punch"), Location::IsAutoPunch);
4778  _session->locations()->add (loc, true);
4780  XMLNode &after = _session->locations()->get_state();
4781  _session->add_command (new MementoCommand<Locations>(*(_session->locations()), &before, &after));
4782  } else {
4783  XMLNode &before = tpl->get_state();
4784  tpl->set_hidden (false, this);
4785  tpl->set (start, end);
4786  XMLNode &after = tpl->get_state();
4787  _session->add_command (new MementoCommand<Location>(*tpl, &before, &after));
4788  }
4789 
4791 }
4792 
4798 void
4800 {
4801  const TrackViewList* tracks;
4802 
4803  if (ts.empty()) {
4804  tracks = &track_views;
4805  } else {
4806  tracks = &ts;
4807  }
4808 
4809  for (TrackViewList::const_iterator t = tracks->begin(); t != tracks->end(); ++t) {
4810 
4811  RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(*t);
4812 
4813  if (rtv) {
4816 
4817  if ((tr = rtv->track()) && ((pl = tr->playlist()))) {
4818 
4820  (framepos_t) floor ( (double) where * tr->speed()));
4821 
4822  for (RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
4823  RegionView* rv = rtv->view()->find_view (*i);
4824  if (rv) {
4825  rs.add (rv);
4826  }
4827  }
4828  }
4829  }
4830  }
4831 }
4832 
4833 void
4835 {
4836  const TrackViewList* tracks;
4837 
4838  if (ts.empty()) {
4839  tracks = &track_views;
4840  } else {
4841  tracks = &ts;
4842  }
4843 
4844  for (TrackViewList::const_iterator t = tracks->begin(); t != tracks->end(); ++t) {
4845  RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(*t);
4846  if (rtv) {
4849 
4850  if ((tr = rtv->track()) && ((pl = tr->playlist()))) {
4851 
4853  (framepos_t) floor ( (double)where * tr->speed()), max_framepos);
4854 
4855  for (RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
4856 
4857  RegionView* rv = rtv->view()->find_view (*i);
4858 
4859  if (rv) {
4860  rs.add (rv);
4861  }
4862  }
4863  }
4864  }
4865  }
4866 }
4867 
4882 {
4884 
4885  if (_edit_point == EditAtMouse && entered_regionview && selection->tracks.empty() && selection->regions.empty() ) {
4886  regions.add (entered_regionview);
4887  } else {
4888  regions = selection->regions;
4889  }
4890 
4891  if ( regions.empty() ) {
4892  TrackViewList tracks = selection->tracks;
4893 
4894  if (!tracks.empty()) {
4895  /* no region selected or entered, but some selected tracks:
4896  * act on all regions on the selected tracks at the edit point
4897  */
4898  framepos_t const where = get_preferred_edit_position ();
4899  get_regions_at(regions, where, tracks);
4900  }
4901  }
4902 
4903  return regions;
4904 }
4905 
4919 {
4921 
4922  if (entered_regionview && selection->tracks.empty() && selection->regions.empty() ) {
4923  regions.add (entered_regionview);
4924  } else {
4925  regions = selection->regions;
4926  }
4927 
4928  if ( regions.empty() ) {
4929  TrackViewList tracks = selection->tracks;
4930 
4931  if (!tracks.empty()) {
4932  /* no region selected or entered, but some selected tracks:
4933  * act on all regions on the selected tracks at the edit point
4934  */
4935  get_regions_at(regions, pos, tracks);
4936  }
4937  }
4938 
4939  return regions;
4940 }
4941 
4949 {
4951 
4952  if (regions.empty() && entered_regionview) {
4953  regions.add (entered_regionview);
4954  }
4955 
4956  return regions;
4957 }
4958 
4959 void
4961 {
4962  for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i) {
4963  RouteTimeAxisView* rtav;
4964 
4965  if ((rtav = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
4967  std::vector<boost::shared_ptr<Region> > results;
4969 
4970  if ((tr = rtav->track()) == 0) {
4971  /* bus */
4972  continue;
4973  }
4974 
4975  if ((pl = (tr->playlist())) != 0) {
4977  if (r) {
4978  RegionView* rv = rtav->view()->find_view (r);
4979  if (rv) {
4980  regions.push_back (rv);
4981  }
4982  }
4983  }
4984  }
4985  }
4986 }
4987 
4988 void
4990 {
4991 
4992  for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i) {
4993  MidiTimeAxisView* mtav;
4994 
4995  if ((mtav = dynamic_cast<MidiTimeAxisView*> (*i)) != 0) {
4996 
4998  }
4999  }
5000 
5001 }
5002 
5003 void
5004 Editor::get_regions_corresponding_to (boost::shared_ptr<Region> region, vector<RegionView*>& regions, bool src_comparison)
5005 {
5006  for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
5007 
5008  RouteTimeAxisView* tatv;
5009 
5010  if ((tatv = dynamic_cast<RouteTimeAxisView*> (*i)) != 0) {
5011 
5013  vector<boost::shared_ptr<Region> > results;
5014  RegionView* marv;
5016 
5017  if ((tr = tatv->track()) == 0) {
5018  /* bus */
5019  continue;
5020  }
5021 
5022  if ((pl = (tr->playlist())) != 0) {
5023  if (src_comparison) {
5024  pl->get_source_equivalent_regions (region, results);
5025  } else {
5026  pl->get_region_list_equivalent_regions (region, results);
5027  }
5028  }
5029 
5030  for (vector<boost::shared_ptr<Region> >::iterator ir = results.begin(); ir != results.end(); ++ir) {
5031  if ((marv = tatv->view()->find_view (*ir)) != 0) {
5032  regions.push_back (marv);
5033  }
5034  }
5035 
5036  }
5037  }
5038 }
5039 
5040 void
5042 {
5043  if (rhythm_ferret == 0) {
5044  rhythm_ferret = new RhythmFerret(*this);
5045  }
5046 
5048  rhythm_ferret->show ();
5049  rhythm_ferret->present ();
5050 }
5051 
5052 void
5054 {
5055  MessageDialog* dialog = 0;
5056 
5057  if (track_views.size() > 1) {
5058  dialog = new MessageDialog (
5059  *this,
5060  string_compose (_("Please wait while %1 loads visual data."), PROGRAM_NAME),
5061  true
5062  );
5063  dialog->present ();
5065  }
5066 
5067  for (TrackViewList::iterator t = track_views.begin(); t != track_views.end(); ++t) {
5068  (*t)->first_idle();
5069  }
5070 
5071  // first idle adds route children (automation tracks), so we need to redisplay here
5072  _routes->redisplay ();
5073 
5074  delete dialog;
5075 
5076  if (_session->undo_depth() == 0) {
5077  undo_action->set_sensitive(false);
5078  }
5079  redo_action->set_sensitive(false);
5081 
5082  _have_idled = true;
5083 }
5084 
5085 gboolean
5086 Editor::_idle_resize (gpointer arg)
5087 {
5088  return ((Editor*)arg)->idle_resize ();
5089 }
5090 
5091 void
5093 {
5094  if (resize_idle_id < 0) {
5095  /* https://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#G-PRIORITY-HIGH-IDLE:CAPS
5096  * GTK+ uses G_PRIORITY_HIGH_IDLE + 10 for resizing operations, and G_PRIORITY_HIGH_IDLE + 20 for redrawing operations.
5097  * (This is done to ensure that any pending resizes are processed before any pending redraws, so that widgets are not redrawn twice unnecessarily.)
5098  */
5099  resize_idle_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, _idle_resize, this, NULL);
5101  }
5102 
5103  /* make a note of the smallest resulting height, so that we can clamp the
5104  lower limit at TimeAxisView::hSmall */
5105 
5106  int32_t min_resulting = INT32_MAX;
5107 
5109  _pending_resize_view = view;
5110 
5111  min_resulting = min (min_resulting, int32_t (_pending_resize_view->current_height()) + _pending_resize_amount);
5112 
5114  for (TrackViewList::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
5115  min_resulting = min (min_resulting, int32_t ((*i)->current_height()) + _pending_resize_amount);
5116  }
5117  }
5118 
5119  if (min_resulting < 0) {
5120  min_resulting = 0;
5121  }
5122 
5123  /* clamp */
5124  if (uint32_t (min_resulting) < TimeAxisView::preset_height (HeightSmall)) {
5126  }
5127 }
5128 
5130 bool
5132 {
5134 
5135  if (dynamic_cast<AutomationTimeAxisView*> (_pending_resize_view) == 0 &&
5137 
5138  for (TrackViewList::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
5139  if (*i != _pending_resize_view) {
5140  (*i)->idle_resize ((*i)->current_height() + _pending_resize_amount);
5141  }
5142  }
5143  }
5144 
5146  _group_tabs->set_dirty ();
5147  resize_idle_id = -1;
5148 
5149  return false;
5150 }
5151 
5152 void
5154 {
5156 
5157  if (_session) {
5161  }
5162  }
5163 
5164  _pending_locate_request = false;
5165  _pending_initial_locate = false;
5166 }
5167 
5168 void
5170 {
5171  for (list<PBD::ID>::iterator pr = selection->regions.pending.begin (); pr != selection->regions.pending.end (); ++pr) {
5172  if (rv->region ()->id () == (*pr)) {
5173  selection->add (rv);
5174  selection->regions.pending.erase (pr);
5175  break;
5176  }
5177  }
5178 
5179  MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (rv);
5180  if (mrv) {
5181  list<pair<PBD::ID const, list<boost::shared_ptr<Evoral::Note<Evoral::Beats> > > > >::iterator rnote;
5182  for (rnote = selection->pending_midi_note_selection.begin(); rnote != selection->pending_midi_note_selection.end(); ++rnote) {
5183  if (rv->region()->id () == (*rnote).first) {
5184  mrv->select_notes ((*rnote).second);
5185  selection->pending_midi_note_selection.erase(rnote);
5186  break;
5187  }
5188  }
5189  }
5190 
5192 }
5193 
5194 void
5196 {
5198 }
5199 
5202 {
5203  TrackViewList::const_iterator j = track_views.begin ();
5204  while (j != track_views.end()) {
5205  RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*j);
5206  if (rtv && rtv->route() == r) {
5207  return rtv;
5208  }
5209  ++j;
5210  }
5211 
5212  return 0;
5213 }
5214 
5215 
5218 {
5219  TrackViewList t;
5220 
5221  for (RouteList::const_iterator i = r->begin(); i != r->end(); ++i) {
5223  if (tv) {
5224  t.push_back (tv);
5225  }
5226  }
5227 
5228  return t;
5229 }
5230 
5231 void
5233 {
5234  if (_routes) {
5236  }
5237 }
5238 
5239 void
5241 {
5242  if (_routes) {
5243  _routes->redisplay(); // queue redisplay
5245  }
5246 }
5247 
5248 void
5250 {
5251  ENSURE_GUI_THREAD (*this, &Editor::handle_new_route, routes)
5252 
5253  RouteTimeAxisView *rtv;
5254  list<RouteTimeAxisView*> new_views;
5255  TrackViewList new_selection;
5256  bool from_scratch = (track_views.size() == 0);
5257 
5258  for (RouteList::iterator x = routes.begin(); x != routes.end(); ++x) {
5259  boost::shared_ptr<Route> route = (*x);
5260 
5261  if (route->is_auditioner() || route->is_monitor()) {
5262  continue;
5263  }
5264 
5265  DataType dt = route->input()->default_type();
5266 
5267  if (dt == ARDOUR::DataType::AUDIO) {
5268  rtv = new AudioTimeAxisView (*this, _session, *_track_canvas);
5269  rtv->set_route (route);
5270  } else if (dt == ARDOUR::DataType::MIDI) {
5271  rtv = new MidiTimeAxisView (*this, _session, *_track_canvas);
5272  rtv->set_route (route);
5273  } else {
5274  throw unknown_type();
5275  }
5276 
5277  new_views.push_back (rtv);
5278  track_views.push_back (rtv);
5279  new_selection.push_back (rtv);
5280 
5281  rtv->effective_gain_display ();
5282 
5283  rtv->view()->RegionViewAdded.connect (sigc::mem_fun (*this, &Editor::region_view_added));
5284  rtv->view()->RegionViewRemoved.connect (sigc::mem_fun (*this, &Editor::region_view_removed));
5285  }
5286 
5287  if (new_views.size() > 0) {
5288  _routes->routes_added (new_views);
5289  _summary->routes_added (new_views);
5290  }
5291 
5292  if (!from_scratch) {
5293  selection->tracks.clear();
5294  selection->add (new_selection);
5296  }
5297 
5299  show_editor_mixer (true);
5300  }
5301 
5302  editor_list_button.set_sensitive (true);
5303 }
5304 
5305 void
5307 {
5308  if (tv == entered_track) {
5309  entered_track = 0;
5310  }
5311 
5313  /* the situation is under control */
5314  return;
5315  }
5316 
5318 
5319  RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (tv);
5320 
5321  _routes->route_removed (tv);
5322 
5324  for (TimeAxisView::Children::const_iterator i = c.begin(); i != c.end(); ++i) {
5325  if (entered_track == i->get()) {
5326  entered_track = 0;
5327  }
5328  }
5329 
5330  /* remove it from the list of track views */
5331 
5332  TrackViewList::iterator i;
5333 
5334  if ((i = find (track_views.begin(), track_views.end(), tv)) != track_views.end()) {
5335  i = track_views.erase (i);
5336  }
5337 
5338  /* update whatever the current mixer strip is displaying, if revelant */
5339 
5341 
5342  if (rtav) {
5343  route = rtav->route ();
5344  }
5345 
5346  if (current_mixer_strip && current_mixer_strip->route() == route) {
5347 
5348  TimeAxisView* next_tv;
5349 
5350  if (track_views.empty()) {
5351  next_tv = 0;
5352  } else if (i == track_views.end()) {
5353  next_tv = track_views.front();
5354  } else {
5355  next_tv = (*i);
5356  }
5357 
5358 
5359  if (next_tv) {
5360  set_selected_mixer_strip (*next_tv);
5361  } else {
5362  /* make the editor mixer strip go away setting the
5363  * button to inactive (which also unticks the menu option)
5364  */
5365 
5366  ActionManager::uncheck_toggleaction ("<Actions>/Editor/show-editor-mixer");
5367  }
5368  }
5369 }
5370 
5371 void
5372 Editor::hide_track_in_display (TimeAxisView* tv, bool apply_to_selection)
5373 {
5374  if (apply_to_selection) {
5375  for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ) {
5376 
5377  TrackSelection::iterator j = i;
5378  ++j;
5379 
5380  hide_track_in_display (*i, false);
5381 
5382  i = j;
5383  }
5384  } else {
5385  RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tv);
5386 
5387  if (rtv && current_mixer_strip && (rtv->route() == current_mixer_strip->route())) {
5388  // this will hide the mixer strip
5390  }
5391 
5393  }
5394 }
5395 
5396 bool
5398 {
5400 
5401  _summary->set_dirty ();
5402  _group_tabs->set_dirty ();
5403 
5404  return false; // do not call again (until needed)
5405 }
5406 
5407 void
5408 Editor::foreach_time_axis_view (sigc::slot<void,TimeAxisView&> theslot)
5409 {
5410  for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
5411  theslot (**i);
5412  }
5413 }
5414 
5418 {
5419  RouteTimeAxisView* v;
5420 
5421  for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i) {
5422  if((v = dynamic_cast<RouteTimeAxisView*>(*i)) != 0) {
5423  if(v->route()->id() == id) {
5424  return v;
5425  }
5426  }
5427  }
5428 
5429  return 0;
5430 }
5431 
5432 void
5434 {
5436  fit_tracks (ts);
5437 }
5438 
5439 void
5441 {
5443 
5444  if (r == 0) {
5446  return;
5447  }
5448 
5449  if (_session->is_auditioning()) {
5451  if (r == last_audition_region) {
5452  return;
5453  }
5454  }
5455 
5458 }
5459 
5460 
5461 void
5463 {
5464  r->set_hidden (true);
5465 }
5466 
5467 void
5469 {
5470  r->set_hidden (false);
5471 }
5472 
5473 void
5475 {
5476  _regions->selection_mapover (sigc::mem_fun (*this, &Editor::consider_auditioning));
5477 }
5478 
5479 void
5481 {
5482  _regions->selection_mapover (sigc::mem_fun (*this, &Editor::hide_a_region));
5483 }
5484 
5485 void
5487 {
5488  _regions->selection_mapover (sigc::mem_fun (*this, &Editor::show_a_region));
5489 }
5490 
5491 void
5493 {
5494  if (yn) {
5495  start_step_editing ();
5496  } else {
5497  stop_step_editing ();
5498  }
5499 }
5500 
5501 void
5503 {
5504  step_edit_connection = Glib::signal_timeout().connect (sigc::mem_fun (*this, &Editor::check_step_edit), 20);
5505 }
5506 
5507 void
5509 {
5510  step_edit_connection.disconnect ();
5511 }
5512 
5513 bool
5515 {
5516  for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
5517  MidiTimeAxisView* mtv = dynamic_cast<MidiTimeAxisView*> (*i);
5518  if (mtv) {
5519  mtv->check_step_edit ();
5520  }
5521  }
5522 
5523  return true; // do it again, till we stop
5524 }
5525 
5526 bool
5528 {
5530 
5531  if (_scroll_connection.connected() && _scroll_callbacks < 5) {
5532  /* delay the first auto-repeat */
5533  return true;
5534  }
5535 
5536  switch (dir) {
5537  case LEFT:
5538  scroll_backward (1);
5539  break;
5540 
5541  case RIGHT:
5542  scroll_forward (1);
5543  break;
5544 
5545  case UP:
5547  break;
5548 
5549  case DOWN:
5551  break;
5552  }
5553 
5554  /* do hacky auto-repeat */
5555  if (!_scroll_connection.connected ()) {
5556 
5557  _scroll_connection = Glib::signal_timeout().connect (
5558  sigc::bind (sigc::mem_fun (*this, &Editor::scroll_press), dir), 100
5559  );
5560 
5561  _scroll_callbacks = 0;
5562  }
5563 
5564  return true;
5565 }
5566 
5567 void
5569 {
5570  _scroll_connection.disconnect ();
5571 }
5572 
5574 void
5576 {
5577  framepos_t const frame = playhead_cursor->current_frame ();
5578 
5579  if (frame < leftmost_frame || frame > leftmost_frame + current_page_samples()) {
5580 
5581  if (_session->transport_speed() < 0) {
5582 
5583  if (frame > (current_page_samples() / 2)) {
5584  center_screen (frame-(current_page_samples()/2));
5585  } else {
5587  }
5588 
5589  } else {
5590 
5591  framepos_t l = 0;
5592 
5593  if (frame < leftmost_frame) {
5594  /* moving left */
5595  if (_session->transport_rolling()) {
5596  /* rolling; end up with the playhead at the right of the page */
5597  l = frame - current_page_samples ();
5598  } else {
5599  /* not rolling: end up with the playhead 1/4 of the way along the page */
5600  l = frame - current_page_samples() / 4;
5601  }
5602  } else {
5603  /* moving right */
5604  if (_session->transport_rolling()) {
5605  /* rolling: end up with the playhead on the left of the page */
5606  l = frame;
5607  } else {
5608  /* not rolling: end up with the playhead 3/4 of the way along the page */
5609  l = frame - 3 * current_page_samples() / 4;
5610  }
5611  }
5612 
5613  if (l < 0) {
5614  l = 0;
5615  }
5616 
5618  }
5619  }
5620 }
5621 
5622 void
5624 {
5625  if (!_session || !_session->engine().running()) {
5626  return;
5627  }
5628 
5629  /* METERING / MIXER STRIPS */
5630 
5631  /* update track meters, if required */
5632  if (is_mapped() && meters_running) {
5633  RouteTimeAxisView* rtv;
5634  for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
5635  if ((rtv = dynamic_cast<RouteTimeAxisView*>(*i)) != 0) {
5636  rtv->fast_update ();
5637  }
5638  }
5639  }
5640 
5641  /* and any current mixer strip */
5642  if (current_mixer_strip) {
5644  }
5645 
5646  /* PLAYHEAD AND VIEWPORT */
5647 
5648  framepos_t const frame = _session->audible_frame();
5649 
5650  /* There are a few reasons why we might not update the playhead / viewport stuff:
5651  *
5652  * 1. we don't update things when there's a pending locate request, otherwise
5653  * when the editor requests a locate there is a chance that this method
5654  * will move the playhead before the locate request is processed, causing
5655  * a visual glitch.
5656  * 2. if we're not rolling, there's nothing to do here (locates are handled elsewhere).
5657  * 3. if we're still at the same frame that we were last time, there's nothing to do.
5658  */
5659 
5660  if (!_pending_locate_request && _session->transport_speed() != 0 && frame != last_update_frame) {
5661 
5662  last_update_frame = frame;
5663 
5664  if (!_dragging_playhead) {
5665  playhead_cursor->set_position (frame);
5666  }
5667 
5668  if (!_stationary_playhead) {
5669 
5671  /* We only do this if we aren't already
5672  handling a visual change (ie if
5673  pending_visual_change.being_handled is
5674  false) so that these requests don't stack
5675  up there are too many of them to handle in
5676  time.
5677  */
5679  }
5680 
5681  } else {
5682 
5683  /* don't do continuous scroll till the new position is in the rightmost quarter of the
5684  editor canvas
5685  */
5686 #if 0
5687  // FIXME DO SOMETHING THAT WORKS HERE - this is 2.X code
5688  double target = ((double)frame - (double)current_page_samples()/2.0) / samples_per_pixel;
5689  if (target <= 0.0) {
5690  target = 0.0;
5691  }
5692  if (fabs(target - current) < current_page_samples() / samples_per_pixel) {
5693  target = (target * 0.15) + (current * 0.85);
5694  } else {
5695  /* relax */
5696  }
5697 
5698  current = target;
5699  set_horizontal_position (current);
5700 #endif
5701  }
5702 
5703  }
5704 }
5705 
5706 
5707 void
5709 {
5710  _have_idled = false;
5711 
5713 
5715 
5716  selection->clear ();
5717  cut_buffer->clear ();
5718 
5719  clicked_regionview = 0;
5720  clicked_axisview = 0;
5721  clicked_routeview = 0;
5722  entered_regionview = 0;
5723  entered_track = 0;
5724  last_update_frame = 0;
5725  _drags->abort ();
5726 
5727  playhead_cursor->hide ();
5728 
5729  /* rip everything out of the list displays */
5730 
5731  _regions->clear ();
5732  _routes->clear ();
5733  _route_groups->clear ();
5734 
5735  /* do this first so that deleting a track doesn't reset cms to null
5736  and thus cause a leak.
5737  */
5738 
5739  if (current_mixer_strip) {
5740  if (current_mixer_strip->get_parent() != 0) {
5742  }
5743  delete current_mixer_strip;
5744  current_mixer_strip = 0;
5745  }
5746 
5747  /* delete all trackviews */
5748 
5749  for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
5750  delete *i;
5751  }
5752  track_views.clear ();
5753 
5754  nudge_clock->set_session (0);
5755 
5756  editor_list_button.set_active(false);
5757  editor_list_button.set_sensitive(false);
5758 
5759  /* clear tempo/meter rulers */
5761  hide_measures ();
5763 
5764  stop_step_editing ();
5765 
5766  /* get rid of any existing editor mixer strip */
5767 
5768  WindowTitle title(Glib::get_application_name());
5769  title += _("Editor");
5770 
5771  set_title (title.get_string());
5772 
5773  SessionHandlePtr::session_going_away ();
5774 }
5775 
5776 
5777 void
5779 {
5780  if (yn) {
5781  _the_notebook.show ();
5782  } else {
5783  _the_notebook.hide ();
5784  }
5785 }
5786 
5787 void
5789 {
5790  const framepos_t position = get_preferred_edit_position (EDIT_IGNORE_NONE, from_context_menu);
5791 
5792  if (!clicked_routeview) {
5793  if (layering_order_editor) {
5794  layering_order_editor->hide ();
5795  }
5796  return;
5797  }
5798 
5800 
5801  if (!track) {
5802  return;
5803  }
5804 
5805  boost::shared_ptr<Playlist> pl = track->playlist();
5806 
5807  if (!pl) {
5808  return;
5809  }
5810 
5811  if (layering_order_editor == 0) {
5813  }
5814 
5817 }
5818 
5819 void
5821 {
5822  if (layering_order_editor && layering_order_editor->is_visible ()) {
5824  }
5825 }
5826 
5827 void
5829 {
5830  _fade_in_images[FadeLinear] = new Gtk::Image (get_icon_path (X_("fadein-linear")));
5831  _fade_in_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadein-symmetric")));
5832  _fade_in_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadein-fast-cut")));
5833  _fade_in_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadein-slow-cut")));
5834  _fade_in_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadein-constant-power")));
5835 
5836  _fade_out_images[FadeLinear] = new Gtk::Image (get_icon_path (X_("fadeout-linear")));
5837  _fade_out_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadeout-symmetric")));
5838  _fade_out_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadeout-fast-cut")));
5839  _fade_out_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadeout-slow-cut")));
5840  _fade_out_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadeout-constant-power")));
5841 
5842  _xfade_in_images[FadeLinear] = new Gtk::Image (get_icon_path (X_("fadein-linear")));
5843  _xfade_in_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadein-symmetric")));
5844  _xfade_in_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadein-fast-cut")));
5845  _xfade_in_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadein-slow-cut")));
5846  _xfade_in_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadein-constant-power")));
5847 
5848  _xfade_out_images[FadeLinear] = new Gtk::Image (get_icon_path (X_("fadeout-linear")));
5849  _xfade_out_images[FadeSymmetric] = new Gtk::Image (get_icon_path (X_("fadeout-symmetric")));
5850  _xfade_out_images[FadeFast] = new Gtk::Image (get_icon_path (X_("fadeout-fast-cut")));
5851  _xfade_out_images[FadeSlow] = new Gtk::Image (get_icon_path (X_("fadeout-slow-cut")));
5852  _xfade_out_images[FadeConstantPower] = new Gtk::Image (get_icon_path (X_("fadeout-constant-power")));
5853 
5854 }
5855 
5857 Gtk::MenuItem&
5858 Editor::action_menu_item (std::string const & name)
5859 {
5860  Glib::RefPtr<Action> a = editor_actions->get_action (name);
5861  assert (a);
5862 
5863  return *manage (a->create_menu_item ());
5864 }
5865 
5866 void
5867 Editor::add_notebook_page (string const & name, Gtk::Widget& widget)
5868 {
5869  EventBox* b = manage (new EventBox);
5870  b->signal_button_press_event().connect (sigc::bind (sigc::mem_fun (*this, &Editor::notebook_tab_clicked), &widget));
5871  Label* l = manage (new Label (name));
5872  l->set_angle (-90);
5873  b->add (*l);
5874  b->show_all ();
5875  _the_notebook.append_page (widget, *b);
5876 }
5877 
5878 bool
5879 Editor::notebook_tab_clicked (GdkEventButton* ev, Gtk::Widget* page)
5880 {
5881  if (ev->type == GDK_BUTTON_PRESS || ev->type == GDK_2BUTTON_PRESS) {
5882  _the_notebook.set_current_page (_the_notebook.page_num (*page));
5883  }
5884 
5885  if (ev->type == GDK_2BUTTON_PRESS) {
5886 
5887  /* double-click on a notebook tab shrinks or expands the notebook */
5888 
5889  if (_notebook_shrunk) {
5891  edit_pane.set_position (*pre_notebook_shrink_pane_width);
5892  }
5893  _notebook_shrunk = false;
5894  } else {
5895  pre_notebook_shrink_pane_width = edit_pane.get_position();
5896 
5897  /* this expands the LHS of the edit pane to cover the notebook
5898  PAGE but leaves the tabs visible.
5899  */
5900  edit_pane.set_position (edit_pane.get_position() + page->get_width());
5901  _notebook_shrunk = true;
5902  }
5903  }
5904 
5905  return true;
5906 }
5907 
5908 void
5909 Editor::popup_control_point_context_menu (ArdourCanvas::Item* item, GdkEvent* event)
5910 {
5911  using namespace Menu_Helpers;
5912 
5913  MenuList& items = _control_point_context_menu.items ();
5914  items.clear ();
5915 
5916  items.push_back (MenuElem (_("Edit..."), sigc::bind (sigc::mem_fun (*this, &Editor::edit_control_point), item)));
5917  items.push_back (MenuElem (_("Delete"), sigc::bind (sigc::mem_fun (*this, &Editor::remove_control_point), item)));
5918  if (!can_remove_control_point (item)) {
5919  items.back().set_sensitive (false);
5920  }
5921 
5922  _control_point_context_menu.popup (event->button.button, event->button.time);
5923 }
5924 
5925 void
5926 Editor::popup_note_context_menu (ArdourCanvas::Item* item, GdkEvent* event)
5927 {
5928  using namespace Menu_Helpers;
5929 
5930  NoteBase* note = reinterpret_cast<NoteBase*>(item->get_data("notebase"));
5931  if (!note) {
5932  return;
5933  }
5934 
5935  /* We need to get the selection here and pass it to the operations, since
5936  popping up the menu will cause a region leave event which clears
5937  entered_regionview. */
5938 
5939  MidiRegionView& mrv = note->region_view();
5941 
5942  MenuList& items = _note_context_menu.items();
5943  items.clear();
5944 
5945  items.push_back(MenuElem(_("Delete"),
5946  sigc::mem_fun(mrv, &MidiRegionView::delete_selection)));
5947  items.push_back(MenuElem(_("Edit..."),
5948  sigc::bind(sigc::mem_fun(*this, &Editor::edit_notes), &mrv)));
5949  items.push_back(MenuElem(_("Legatize"),
5950  sigc::bind(sigc::mem_fun(*this, &Editor::legatize_regions), rs, false)));
5951  items.push_back(MenuElem(_("Quantize..."),
5952  sigc::bind(sigc::mem_fun(*this, &Editor::quantize_regions), rs)));
5953  items.push_back(MenuElem(_("Remove Overlap"),
5954  sigc::bind(sigc::mem_fun(*this, &Editor::legatize_regions), rs, true)));
5955  items.push_back(MenuElem(_("Transform..."),
5956  sigc::bind(sigc::mem_fun(*this, &Editor::transform_regions), rs)));
5957 
5958  _note_context_menu.popup (event->button.button, event->button.time);
5959 }
5960 
5961 void
5963 {
5964  _stepping_axis_view = 0;
5965 }
5966 
5967 void
5969 {
5970  if (parameter == "icon-set") {
5971  while (!_cursor_stack.empty()) {
5972  _cursor_stack.pop_back();
5973  }
5974  _cursors->set_cursor_set (ARDOUR_UI::config()->get_icon_set());
5975  _cursor_stack.push_back(_cursors->grabber);
5976  } else if (parameter == "draggable-playhead") {
5977  if (_verbose_cursor) {
5978  playhead_cursor->set_sensitive (ARDOUR_UI::config()->get_draggable_playhead());
5979  }
5980  }
5981 }
void get_regions_corresponding_to(boost::shared_ptr< ARDOUR::Region > region, std::vector< RegionView * > &regions, bool src_comparison)
Definition: editor.cc:5004
ARDOUR::Location * transport_punch_location()
Definition: editor.cc:4203
Gtk::EventBox time_bars_event_box
Definition: editor.h:804
RegionView * find_view(boost::shared_ptr< const ARDOUR::Region >)
Definition: streamview.cc:481
framepos_t audible_frame() const
Definition: session.cc:1760
bool transport_rolling() const
Definition: session.h:592
bool relay_key_press(GdkEventKey *ev, Gtk::Window *win)
Definition: utils.cc:301
static PBD::Signal1< void, TimeAxisView * > CatchDeletion
bool active() const
Definition: editor_drag.h:74
void set_visible(bool yn, bool force=false)
Definition: tearoff.cc:115
bool add(RegionView *)
std::pair< TimeAxisView *, double > trackview_by_y_position(double, bool trackview_relative_offset=true) const
Definition: editor.cc:2565
SelectionMemento * _selection_memento
Definition: editor.h:1803
void scroll_release()
Definition: editor.cc:5568
double y_position
Definition: editor.h:560
sigc::signal< void > Hidden
Definition: tearoff.h:48
void reset_y_origin(double)
Definition: editor.cc:4371
bool _all_region_actions_sensitized
Definition: editor.h:1812
void instant_save()
Definition: editor.cc:954
void center_screen(framepos_t)
Definition: editor.cc:1239
double timecode_frames_per_second() const
Definition: session_time.cc:55
EditorRegions * _regions
Definition: editor.h:1863
void region_view_removed()
Definition: editor.cc:5195
bool get_mixbus() const
Definition: profile.h:53
ArdourCanvas::Item * get_canvas_group()
Gtk::Widget & widget()
void add_selection_context_items(Gtk::Menu_Helpers::MenuList &)
Definition: editor.cc:1820
std::list< XMLNode * > before
Definition: editor.h:1967
LIBPBD_API Transmitter fatal
ArdourCanvas::Color color(const std::string &, bool *failed=0) const
Definition: ui_config.cc:567
void export_selection()
void map_transport_state()
Definition: editor.cc:3336
void editor_list_button_toggled()
Definition: editor_mixer.cc:63
LIBGTKMM2EXT_API Gtk::Widget * get_widget(const char *name)
Definition: actions.cc:366
bool scroll_up_one_track(bool skip_child_views=false)
Definition: editor_ops.cc:1485
void hide_region_from_region_list()
Definition: editor.cc:5480
void update_loop_range_view()
Gtk::Menu _control_point_context_menu
Definition: editor.h:762
void set_route(boost::shared_ptr< ARDOUR::Route >)
void copy_playlists(TimeAxisView *v)
Definition: editor.cc:4298
void set_session_extents_from_selection()
Definition: editor_ops.cc:6079
std::list< PBD::ID > pending
int atoi(const string &s)
Definition: convert.cc:140
Gtk::HPaned edit_pane
Definition: editor.h:614
void clear_regions()
Definition: selection.cc:159
static PBD::Signal1< void, RegionView * > RegionViewGoingAway
Definition: region_view.h:100
bool _show_measures
Definition: editor.h:1609
void setup_toolbar()
Definition: editor.cc:2877
void commit_reversible_selection_op()
Definition: editor.cc:3376
void scroll_tracks_up_line()
Definition: editor_ops.cc:1408
void fit_selection()
Definition: editor_ops.cc:7240
int32_t _pending_resize_amount
Definition: editor.h:2154
RulerDialog * ruler_dialog
Definition: editor.h:885
boost::shared_ptr< Region > region_by_id(const PBD::ID &) const
Definition: playlist.cc:2646
framecnt_t get_paste_offset(framepos_t pos, unsigned paste_count, framecnt_t duration)
Definition: editor.cc:4045
void mapped_use_copy_playlist(RouteTimeAxisView &, uint32_t, std::vector< boost::shared_ptr< ARDOUR::Playlist > > const &)
Definition: editor.cc:4329
void reset_focus()
PBD::Signal0< void > Changed
Definition: undo.h:111
void build_edit_point_menu()
Definition: editor.cc:3139
Gdk::Cursor * grabber
Definition: mouse_cursors.h:48
void nudge_track(bool use_edit_point, bool forwards)
Definition: editor_ops.cc:4830
void set(framepos_t, bool force=false, ARDOUR::framecnt_t offset=0)
Definition: audio_clock.cc:956
void reset_sort_type(Editing::RegionListSortType, bool)
bool get_sae() const
Definition: profile.h:48
VisualChange pending_visual_change
Definition: editor.h:1127
void copy()
Definition: editor_ops.cc:3990
void redisplay_tempo(bool immediate_redraw)
ArdourCanvas::GtkCanvasViewport * get_track_canvas() const
TimeAxisView * current_stepping_trackview
Definition: editor.h:2059
void redo(uint32_t n=1)
Definition: editor_ops.cc:134
void undo_selection_op()
Definition: editor.cc:3411
void begin_reversible_command(const std::string &cmd_name)
PBD::Signal0< void > TransportStateChange
Definition: session.h:308
void cycle_edit_point(bool with_marker)
Definition: editor.cc:3646
PlaylistSelector * _playlist_selector
Definition: editor.h:553
Selection * selection
Definition: editor.h:1801
XMLNode * editor_settings() const
Definition: ardour_ui.cc:4069
bool idle_resize()
Definition: editor.cc:5131
Width editor_mixer_strip_width
Definition: editor.h:308
bool select_new_marker
Definition: editor.h:1455
Gtk::Menu xfade_in_context_menu
Definition: editor.h:1495
void set_follow_playhead(bool yn, bool catch_up=true)
Definition: editor.cc:4004
void add_new_location(ARDOUR::Location *)
MouseMode
Definition: editing.h:91
sigc::connection super_rapid_connect(const sigc::slot< void > &slot)
Definition: timers.cc:189
ArdourButton mouse_content_button
Definition: editor.h:1726
Location * auto_loop_location() const
Definition: location.cc:1359
Gtk::Menu * editor_ruler_menu
Definition: editor.h:966
TimeAxisView * clicked_axisview
Definition: editor.h:695
void set_session(ARDOUR::Session *)
Gtk::HBox _summary_hbox
Definition: editor.h:2170
RoundMode
Definition: types.h:221
void use_new_playlist(bool prompt, std::vector< boost::shared_ptr< ARDOUR::Playlist > > const &)
void build_snap_type_menu()
Definition: editor.cc:3177
const std::string & value() const
Definition: xml++.h:159
PBD::Signal1< void, const PropertyChange & > PropertyChanged
Definition: stateful.h:87
static void setup_sizes()
LIBGTKMM2EXT_API void set_size_request_to_display_given_text(Gtk::Widget &w, const gchar *text, gint hpadding, gint vpadding)
Definition: utils.cc:70
void set_session(ARDOUR::Session *s)
uint32_t redo_depth() const
Definition: session.h:778
ItemType
Definition: editor_items.h:23
bool canvas_scroll_event(GdkEventScroll *event, bool from_canvas)
boost::shared_ptr< RegionList > regions_touched(framepos_t start, framepos_t end)
Definition: playlist.cc:1824
Gtk::Label minsec_label
Definition: editor.h:975
PBD::Signal1< void, Location * > added
Definition: location.h:209
void abort_reversible_command()
Definition: editor.cc:3471
Gtk::HBox panic_box
Definition: editor.h:1795
framepos_t time_origin
Definition: editor.h:1113
Editing::SnapType internal_snap_type
Definition: editor.h:589
void begin_reversible_command(std::string cmd_name)
void set_snap_to(Editing::SnapType)
Definition: editor.cc:2046
void duplicate_some_regions(RegionSelection &, float times)
Definition: editor_ops.cc:4711
int set_state(const XMLNode &, int version)
Definition: editor.cc:2189
void restore_editing_space()
Definition: editor.cc:4264
static PublicEditor * _instance
Singleton instance, set up by Editor::Editor()
void history_changed()
Definition: editor.cc:3504
ArdourDropdown visible_tracks_selector
Definition: editor.h:1707
void control_vertical_zoom_in_all()
Definition: editor.cc:968
int _scroll_callbacks
Definition: editor.h:1071
double transport_speed() const
Definition: session.h:590
virtual void exited()
Definition: region_view.h:95
int videotl_bar_height
Definition: editor.h:1005
void update_video_timeline(bool flush=false)
Glib::RefPtr< Gtk::Action > redo_action
Definition: editor.h:2091
std::string name() const
EditorSnapshots * _snapshots
Definition: editor.h:1864
void set_hidden(bool yn)
Definition: region.cc:939
friend class EditorRoutes
Definition: editor.h:2267
sigc::connection control_scroll_connection
Definition: editor.h:1099
EditorRouteGroups * _route_groups
Definition: editor.h:1861
#define enum_2_string(e)
Definition: enumwriter.h:97
sigc::signal< void, RegionView * > RegionViewAdded
Definition: streamview.h:122
void popup_xfade_in_context_menu(int, int, ArdourCanvas::Item *, ItemType)
Definition: editor.cc:1497
void redo_selection_op()
Definition: editor.cc:3431
bool running() const
Definition: audioengine.h:130
void remove_control_point(ArdourCanvas::Item *)
EditorSummary * _summary
Definition: editor.h:2171
void new_region_from_selection()
Definition: editor_ops.cc:2927
Gtk::ToggleButton editor_list_button
Definition: editor.h:1697
ArdourButton zoom_out_full_button
Definition: editor.h:1703
EditorRoutes * _routes
Definition: editor.h:1862
Gtk::Label cd_mark_label
Definition: editor.h:984
Gtk::HBox snap_box
Definition: editor.h:1756
GdkEvent context_click_event
Definition: editor.h:748
Gtk::Widget & widget()
SoundFileOmega * sfbrowser
Definition: editor.h:1326
Editor()
Definition: editor.cc:251
void set_selected_mixer_strip(TimeAxisView &)
void tav_zoom_smooth(bool coarser, bool force_all)
Definition: editor_ops.cc:1597
void ui_parameter_changed(std::string)
Definition: editor.cc:5968
void show_rhythm_ferret()
Definition: editor.cc:5041
void start_lock_event_timing()
Definition: editor.cc:1156
bool torn_off() const
Definition: tearoff.cc:261
Editing::SnapType _snap_type
Definition: editor.h:1473
framepos_t position() const
Definition: marker.h:79
framepos_t leftmost_frame
Definition: editor.h:580
void set_name(const std::string &str)
Definition: location.cc:167
bool ending() const
Definition: editor_drag.h:70
framecnt_t samples_per_pixel
Definition: editor.h:561
Definition: ardour_ui.h:130
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
static ARDOUR_UI * instance()
Definition: ardour_ui.h:187
void add_region_context_items(Gtk::Menu_Helpers::MenuList &, boost::shared_ptr< ARDOUR::Track >)
Definition: editor.cc:1769
TimeAxisView * entered_track
Definition: editor.h:2064
framecnt_t get_nudge_distance(framepos_t pos, framecnt_t &next)
Definition: editor.cc:4116
void compute_fixed_ruler_scale()
void cut()
Definition: editor_ops.cc:3983
gint exit_on_main_window_close(GdkEventAny *)
ArdourButton mouse_select_button
Definition: editor.h:1722
framepos_t canvas_event_sample(GdkEvent const *, double *px=0, double *py=0) const
void detach_tearoff(Gtk::Box *b, Gtk::Window *w)
Definition: editor.cc:3951
ArdourCanvas::Item * marker_menu_item
Definition: editor.h:1677
void redo_visual_state()
Definition: editor.cc:4446
double horizontal_position() const
Gtk::Widget & widget()
Definition: editor_routes.h:34
bool covers(framepos_t frame) const
Definition: region.h:185
void clear()
Definition: selection.cc:101
bool key_press_focus_accelerator_handler(Gtk::Window &window, GdkEventKey *ev)
Definition: utils.cc:410
void scroll_tracks_down_line()
Definition: editor_ops.cc:1396
Lists of selected things.
Definition: selection.h:66
ArdourDropdown zoom_focus_selector
Definition: editor.h:1770
bool no_save_visual
Definition: editor.h:573
void queue_visual_videotimeline_update()
Definition: editor.cc:4555
void update_visibility()
void undo(uint32_t n=1)
Definition: editor_ops.cc:117
void maybe_add_mixer_strip_width(XMLNode &)
void get_regionviews_by_id(PBD::ID const id, RegionSelection &regions) const
Definition: editor.cc:4960
std::vector< boost::shared_ptr< TimeAxisView > > Children
void add_command(Command *const cmd)
Definition: session.h:787
void ensure_float(Gtk::Window &)
Definition: editor.cc:3877
void track_selection_changed()
void session_going_away()
Definition: editor.cc:5708
bool control_layout_scroll(GdkEventScroll *ev)
Definition: editor.cc:4213
TempoMap & tempo_map()
Definition: session.h:596
void reset_x_origin_to_follow_playhead()
Definition: editor.cc:5575
static void set_focus_handler(sigc::slot< void >)
void align_regions_relative(ARDOUR::RegionPoint point)
Definition: editor_ops.cc:3491
PBD::Signal0< void > Located
Definition: session.h:315
AnalysisWindow * analysis_window
Definition: editor.h:1382
static const gchar * _edit_mode_strings[]
Definition: editor.cc:194
void set_related_action(Glib::RefPtr< Gtk::Action >)
LIBGTKMM2EXT_API Glib::RefPtr< Gtk::Action > get_action(const char *group, const char *name)
Definition: actions.cc:406
void export_video(bool range=false)
Definition: ardour_ui.cc:4028
const std::string & get_text()
Definition: ardour_button.h:97
virtual void entered()
Definition: region_view.h:94
bool show_editor_mixer_when_tracks_arrive
Definition: editor.h:2016
void hide_measures()
void show_editor_list(bool yn)
Definition: editor.cc:5778
RouteTimeAxisView * clicked_routeview
Definition: editor.h:696
ControlPoint * clicked_control_point
Definition: editor.h:704
static const gchar * _snap_type_strings[]
Definition: editor.cc:146
void located()
Definition: editor.cc:5153
bool deferred_control_scroll(framepos_t)
Definition: editor.cc:1116
void set_punch_from_selection()
Definition: editor_ops.cc:6065
std::string name() const
Definition: session.h:166
void snap_to_internal(framepos_t &first, ARDOUR::RoundMode direction=ARDOUR::RoundNearest, bool for_mark=false)
Definition: editor.cc:2687
void get_region_list_equivalent_regions(boost::shared_ptr< Region >, std::vector< boost::shared_ptr< Region > > &)
Definition: playlist.cc:849
void temporal_zoom(framecnt_t samples_per_pixel)
Definition: editor_ops.cc:1644
void quantize_regions(const RegionSelection &rs)
Definition: editor_ops.cc:5179
std::string next_undo() const
Definition: session.h:779
ArdourCanvas::Pixbuf * logo_item
Definition: editor.h:807
ARDOUR::framepos_t end_frame()
void get_regions_at(RegionSelection &, framepos_t where, const TrackViewList &ts) const
Definition: editor.cc:4799
void build_underlay_menu(Gtk::Menu *)
MarkerSelection markers
Definition: selection.h:87
bool _dragging_edit_point
Definition: editor.h:1513
tuple f
Definition: signals.py:35
Gtk::Adjustment vertical_adjustment
Definition: editor.h:1052
void start_updating_meters()
bool is_auditioning() const
Definition: session.cc:4184
framepos_t end() const
Definition: location.h:72
int set_state(const XMLNode &, int version)
void set(std::list< Selectable * > const &)
Definition: selection.cc:1024
bool visible() const
Definition: tearoff.h:43
LIBGTKMM2EXT_API void do_action(const char *group, const char *name)
Definition: actions.cc:532
sigc::signal< void > MarkersChanged
Definition: selection.h:103
Definition: Beats.hpp:239
void resume_route_redisplay()
Definition: editor.cc:5240
void analyze_range_selection()
Definition: editor.cc:1737
virtual void set_session(ARDOUR::Session *)
Definition: sfdb_ui.cc:815
LIBPBD_API Transmitter warning
const XMLNodeList & children(const std::string &str=std::string()) const
Definition: xml++.cc:329
Glib::RefPtr< Gtk::RadioAction > snap_mode_action(Editing::SnapMode)
ArdourButton mouse_timefx_button
Definition: editor.h:1725
void override_visible_track_count()
Definition: editor.cc:3806
void play_from_start()
Definition: editor_ops.cc:2469
void get_regions_after(RegionSelection &, framepos_t where, const TrackViewList &ts) const
Definition: editor.cc:4834
std::list< std::pair< PBD::ID const, std::list< boost::shared_ptr< Evoral::Note< Evoral::Beats > > > > > pending_midi_note_selection
Definition: selection.h:226
Gtk::EventBox toolbar_base
Definition: editor.h:1789
sigc::signal< void > TimeChanged
Definition: selection.h:99
virtual void exited()
bool is_auditioner() const
Definition: route.h:110
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
void insert_region_list_selection(float times)
Definition: editor_ops.cc:2388
void control_select(uint32_t rid, Selection::Operation)
Definition: editor.cc:1004
SessionConfiguration config
Definition: session.h:866
void parameter_changed(std::string)
void fast_update()
Glib::RefPtr< Gtk::Action > selection_undo_action
Definition: editor.h:2094
void temporal_zoom_step(bool coarser)
Definition: editor_ops.cc:1628
Gtk::Menu * new_transport_marker_menu
Definition: editor.h:1675
StreamView * view() const
void set_session(ARDOUR::Session *)
void set_entered_track(TimeAxisView *)
Definition: editor.cc:902
boost::shared_ptr< ARDOUR::AudioRegion > audio_region() const
void select_all_selectables_using_edit(bool)
void update_all_enter_cursors()
void edit_notes(MidiRegionView *)
void set_entered_regionview(RegionView *)
Definition: editor.cc:877
void action_pre_activated(Glib::RefPtr< Gtk::Action > const &)
Definition: editor.cc:1415
void control_step_tracks_down()
Definition: editor.cc:1048
void select_range_between()
Evoral::Beats get_grid_type_as_beats(bool &success, framepos_t position)
Definition: editor.cc:4090
void set_image(const Glib::RefPtr< Gdk::Pixbuf > &)
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
void marks_either_side(framepos_t const, framepos_t &, framepos_t &) const
Definition: location.cc:1283
bool save(const std::string &path)
ZoomFocus
Definition: editing.h:119
ArdourCanvas::GtkCanvasViewport * _track_canvas_viewport
Definition: editor.h:794
Gtk::VBox vpacker
Definition: editor.h:772
VerboseCursor * _verbose_cursor
Definition: editor.h:799
void request_locate(framepos_t frame, bool with_roll=false)
void popup_note_context_menu(ArdourCanvas::Item *, GdkEvent *)
Definition: editor.cc:5926
uint32_t current_height() const
EditorCursor * playhead_cursor
Definition: editor.h:1011
static AudioEngine * instance()
Definition: audioengine.h:196
framecnt_t frame_rate() const
Definition: session.h:365
void undo_visual_state()
Definition: editor.cc:4428
void add(Type t)
Definition: editor.h:1122
void hide_track_in_display(TimeAxisView &)
void set_context(const std::string &, ARDOUR::Session *, TimeAxisView *, boost::shared_ptr< ARDOUR::Playlist >, ARDOUR::framepos_t)
void map_parameters(boost::function< void(std::string)> &)
Definition: ui_config.cc:146
bool mouse_frame(framepos_t &, bool &in_track_canvas) const
Definition: editor_mouse.cc:86
Gtk::Menu * build_track_context_menu()
Definition: editor.cc:1666
ArdourDropdown zoom_preset_selector
Definition: editor.h:1708
#define ENSURE_GUI_THREAD(obj, method,...)
Definition: gui_thread.h:34
Gtk::Menu * tempo_or_meter_marker_menu
Definition: editor.h:1671
ArdourDropdown edit_mode_selector
Definition: editor.h:1743
SnapType
Definition: editing.h:49
Gtk::HBox global_hpacker
Definition: editor.h:770
void parameter_changed(std::string)
#define invalidator(x)
Definition: gui_thread.h:40
bool fade_in_active() const
Definition: audioregion.h:84
ArdourDropdown edit_point_selector
Definition: editor.h:2103
GUIObjectState * gui_object_state
Definition: ardour_ui.h:227
void register_actions()
bool audio_region_selection_covers(framepos_t where)
Definition: editor.cc:4163
RegionSelection get_regions_from_selection_and_entered()
Definition: editor.cc:4948
void fit_route_group(ARDOUR::RouteGroup *)
Definition: editor.cc:5433
void cancel_audition()
Definition: session.cc:4160
XMLNode & get_state()
Definition: editor.cc:2459
framepos_t round_to_bar(framepos_t frame, RoundMode dir)
Definition: tempo.cc:1295
void reset_canvas_action_sensitivity(bool)
void setup_tooltips()
Definition: editor.cc:3217
void set_session(ARDOUR::Session *)
Definition: group_tabs.cc:58
void set_can_be_torn_off(bool)
Definition: tearoff.cc:100
PBD::Signal1< void, framepos_t > PositionChanged
Definition: session.h:310
void clear_playlists()
Definition: selection.cc:193
bool generic_event_handler(GdkEvent *)
Definition: editor.cc:1164
Definition: id.h:32
void show_editor_mixer(bool yn)
Definition: editor_mixer.cc:73
void timeaxisview_deleted(TimeAxisView *)
Definition: editor.cc:5306
void update_tearoff_visibility()
Definition: editor.cc:4233
ArdourCanvas::Container * _trackview_group
Definition: editor.h:843
Gtk::Label timecode_label
Definition: editor.h:977
bool dirty() const
Definition: session.h:176
EditIgnoreOption
Definition: editing.h:211
const Meter & meter_at(framepos_t) const
Definition: tempo.cc:1652
#define COMBO_TRIANGLE_WIDTH
Definition: editor.cc:225
void add_notebook_page(std::string const &, Gtk::Widget &)
Definition: editor.cc:5867
std::map< ARDOUR::FadeShape, Gtk::Image * > _xfade_in_images
Definition: editor.h:2203
ArdourButton mouse_draw_button
Definition: editor.h:1723
void invert_selection()
PlaylistSelector & playlist_selector() const
Definition: editor.cc:4039
std::list< XMLNode * > XMLNodeList
Definition: xml++.h:44
bool _follow_playhead
true if the editor should follow the playhead, otherwise false
Definition: editor.h:1611
void center_screen_internal(framepos_t, float)
Definition: editor.cc:1252
Editing::SnapMode pre_internal_snap_mode
Definition: editor.h:588
unsigned paste_count
Definition: editor.h:1186
gint just_hide_it(GdkEventAny *, Gtk::Window *)
Definition: utils.cc:92
const std::string & get_string()
Definition: window_title.h:53
framepos_t get_preferred_edit_position(Editing::EditIgnoreOption=Editing::EDIT_IGNORE_NONE, bool use_context_click=false, bool from_outside_canvas=false)
Definition: editor.cc:4667
double frames_per_timecode_frame() const
Definition: session.h:370
void set_session(ARDOUR::Session *)
Definition: editor.cc:1295
void session_state_saved(std::string)
Definition: editor.cc:4226
Locations * locations()
Definition: session.h:382
void reattach_tearoff(Gtk::Box *b, Gtk::Window *w, int32_t n)
Definition: editor.cc:3961
framecnt_t samples_per_pixel
Definition: editor.h:1114
std::string next_redo() const
Definition: session.h:780
#define _(Text)
Definition: i18n.h:11
Gtk::Menu fade_context_menu
Definition: editor.h:1493
void build_track_count_menu()
Definition: editor.cc:3699
Editing::ZoomFocus zoom_focus
Definition: editor.h:582
void build_snap_mode_menu()
Definition: editor.cc:3165
EditorLocations * _locations
Definition: editor.h:1865
uint32_t undo_depth() const
Definition: session.h:777
void edit_point_selection_done(Editing::EditPoint)
Definition: editor.cc:3669
void add(std::list< Selectable * > const &)
Definition: selection.cc:1045
framecnt_t sample_rate() const
Definition: audioengine.cc:974
Selection * cut_buffer
Definition: editor.h:1802
LIBGTKMM2EXT_API void set_sensitive(std::vector< Glib::RefPtr< Gtk::Action > > &actions, bool)
Gtk::Label samples_label
Definition: editor.h:978
void set_auto_loop_location(Location *)
Definition: session.cc:1438
void update_region_layering_order_editor()
Definition: editor.cc:5820
void bounce_range_selection(bool replace, bool enable_processing)
Definition: editor_ops.cc:3886
void duplicate_selection(float times)
Definition: editor_ops.cc:4751
Gtk::HBox & editor_transport_box()
Definition: ardour_ui.h:201
ARDOUR::InterThreadInfo * current_interthread_info
Definition: editor.h:1380
bool _dragging_playhead
Definition: editor.h:1512
void location_changed(ARDOUR::Location *)
void sensitize_all_region_actions(bool)
MidiRegionView & region_view() const
Definition: note_base.h:104
UndoHistory & history()
Definition: session.h:775
friend class EditorRouteGroups
Definition: editor.h:1582
TimeFXDialog * current_timefx
Definition: editor.h:2003
LIBGTKMM2EXT_API uint64_t Keyboard
Definition: debug.cc:23
void toggle(std::list< Selectable * > const &)
Definition: selection.cc:991
void marker_selection_changed()
void maximise_editing_space()
Definition: editor.cc:4252
framepos_t current_frame() const
void location_gone(ARDOUR::Location *)
void idle_resize(int32_t)
void catch_vanishing_regionview(RegionView *)
Definition: editor.cc:853
void set_edit_point_preference(Editing::EditPoint ep, bool force=false)
Definition: editor.cc:2137
bool track_canvas_map_handler(GdkEventAny *)
void set_fade_in_shape(ARDOUR::FadeShape)
Definition: editor_ops.cc:5702
ArdourDropdown snap_mode_selector
Definition: editor.h:1754
void show()
Definition: tempo_lines.cc:45
std::vector< std::string > snap_type_strings
Definition: editor.h:1758
AudioClock * nudge_clock
Definition: editor.h:2039
Gtk::HBox toolbar_hbox
Definition: editor.h:1788
vector< string > internationalize(const char *package_name, const char **array)
Definition: convert.cc:164
void first_idle()
Definition: editor.cc:5053
#define X_(Text)
Definition: i18n.h:13
void toggle_follow_playhead()
Definition: editor.cc:3991
void routes_added(std::list< RouteTimeAxisView * > const &)
int64_t framecnt_t
Definition: types.h:76
bool meters_running
Definition: editor.h:2127
void hide_a_region(boost::shared_ptr< ARDOUR::Region >)
Definition: editor.cc:5462
gboolean configure_handler(GdkEventConfigure *conf)
Definition: ardour_ui.cc:630
int convert_drop_to_paths(std::vector< std::string > &paths, const Glib::RefPtr< Gdk::DragContext > &context, gint x, gint y, const Gtk::SelectionData &data, guint info, guint time)
Definition: editor.cc:3246
XMLProperty * property(const char *)
Definition: xml++.cc:413
LIBARDOUR_API RCConfiguration * Config
Definition: globals.cc:119
ArdourButton smart_mode_button
Definition: editor.h:1730
void build_zoom_focus_menu()
Definition: editor.cc:3675
sigc::signal< void > Attach
Definition: tearoff.h:46
int set(framepos_t start, framepos_t end, bool allow_bbt_recompute=true)
Definition: location.cc:321
void point_selection_changed()
#define string_2_enum(str, e)
Definition: enumwriter.h:98
Gtk::Label videotl_label
Definition: editor.h:987
void clear_marker_display()
void control_view(uint32_t)
Definition: editor.cc:992
boost::shared_ptr< ARDOUR::Region > region() const
Definition: region_view.h:66
void set_fade_out_active(bool)
Definition: editor_ops.cc:5792
bool _notebook_shrunk
Definition: editor.h:610
void edit_mode_selection_done(ARDOUR::EditMode m)
Definition: editor.cc:3621
framecnt_t samples_per_pixel
Definition: editor.h:581
Glib::RefPtr< Gtk::RadioAction > zoom_focus_action(Editing::ZoomFocus)
void reset_zoom(framecnt_t)
Definition: editor.cc:4379
void set_position(framepos_t)
void set_selection_from_loop()
bool _ignore_region_action
Definition: editor.h:1817
void initialize_canvas()
PBD::Signal1< void, Location * > removed
Definition: location.h:210
void flush_pending()
Definition: gtk_ui.cc:681
std::vector< std::string > zoom_focus_strings
Definition: editor.h:1773
void play_from_edit_point()
Definition: editor_ops.cc:2475
void timecode_snap_to_internal(framepos_t &first, ARDOUR::RoundMode direction=ARDOUR::RoundNearest, bool for_mark=false)
Definition: editor.cc:2621
ARDOUR::Location * temp_location
Definition: editor.h:1853
ArdourButton zoom_in_button
Definition: editor.h:1701
VisualState(bool with_tracks)
Definition: editor.cc:4401
void begin_reversible_selection_op(std::string cmd_name)
Definition: editor.cc:3366
void move_range_selection_start_or_end_to_region_boundary(bool, bool)
Definition: editor_ops.cc:306
void routes_added(std::list< RouteTimeAxisView * > routes)
void set_background_dirty()
bool check_step_edit()
Definition: editor.cc:5514
Editing::MouseMode current_mouse_mode() const
Definition: editor.h:179
uint32_t location_marker_color
Definition: editor.h:636
bool string_is_affirmative(const std::string &str)
Definition: convert.cc:282
MixerStrip * current_mixer_strip
Definition: editor.h:2015
void analyze_region_selection()
Definition: editor.cc:1719
boost::shared_ptr< RegionList > regions_at(framepos_t frame)
Definition: playlist.cc:1705
void region_fill_selection()
Definition: editor_ops.cc:3339
bool fade_out_active() const
Definition: audioregion.h:85
int playlist_deletion_dialog(boost::shared_ptr< ARDOUR::Playlist >)
Definition: editor.cc:4127
size_t push_canvas_cursor(Gdk::Cursor *)
void use_visual_state(VisualState &)
Definition: editor.cc:4475
Round down only if necessary.
Definition: types.h:222
ArdourButton zoom_out_button
Definition: editor.h:1702
Glib::RefPtr< Gtk::Action > undo_action
Definition: editor.h:2090
framepos_t transport_frame() const
Definition: session.h:551
Definition: amp.h:29
void unfreeze_route()
Definition: editor_ops.cc:3795
Gtk::Table edit_packer
Definition: editor.h:1049
void set_selection_from_punch()
Gtk::Menu xfade_out_context_menu
Definition: editor.h:1496
bool have_pending_keyboard_selection
Definition: editor.h:1468
Editing::EditPoint _edit_point
Definition: editor.h:2101
ArdourButton tav_expand_button
Definition: editor.h:1705
void change_region_layering_order(bool from_context_menu)
Definition: editor.cc:5788
sigc::connection super_rapid_screen_update_connection
Definition: editor.h:1141
ArdourButton nudge_backward_button
Definition: editor.h:2036
const PBD::ID & id() const
Definition: stateful.h:68
void set_zoom_focus(Editing::ZoomFocus)
Definition: editor.cc:3837
std::vector< Gdk::Cursor * > _cursor_stack
Definition: editor.h:776
void stop_step_editing()
Definition: editor.cc:5508
bool _stationary_playhead
true if we scroll the tracks rather than the playhead
Definition: editor.h:1613
LIBGTKMM2EXT_API uint64_t Bindings
Definition: debug.cc:24
void add_dstream_context_items(Gtk::Menu_Helpers::MenuList &)
Definition: editor.cc:1896
void print(char *buf, uint32_t bufsize) const
Definition: id.cc:73
void visual_changer(const VisualChange &)
Definition: editor.cc:4611
static gboolean _idle_resize(gpointer)
Definition: editor.cc:5086
boost::shared_ptr< ARDOUR::Track > track() const
Definition: route_ui.cc:1738
void legatize_regions(const RegionSelection &rs, bool shrink_only)
Definition: editor_ops.cc:5209
bool set_id(const XMLNode &)
Definition: stateful.cc:381
PBD::Signal0< void > DirtyChanged
Definition: session.h:180
void scroll_forward(float pages=0.8f)
Definition: editor_ops.cc:1363
void popup_xfade_out_context_menu(int, int, ArdourCanvas::Item *, ItemType)
Definition: editor.cc:1522
#define gui_context()
Definition: gui_thread.h:36
Gtk::Label mark_label
Definition: editor.h:981
friend class RhythmFerret
Definition: editor.h:2268
void set_session(ARDOUR::Session *)
LIBGTKMM2EXT_API void uncheck_toggleaction(std::string)
RegionLayeringOrderEditor * layering_order_editor
Definition: editor.h:2187
void goto_visual_state(uint32_t)
Definition: editor_ops.cc:7380
bool deletion_in_progress() const
Definition: session.h:179
Gtk::Widget & widget()
framepos_t last_update_frame
Definition: editor.h:1142
RegionSelection get_regions_from_selection_and_mouse(framepos_t)
Definition: editor.cc:4918
bool on_key_press_event(GdkEventKey *)
Definition: editor.cc:4341
Gtk::HBox bottom_hbox
Definition: editor.h:1047
bool internal_editing() const
void commit_reversible_command(Command *cmd=0)
void set_dirty()
sigc::signal< void > Realized
const char * enum2str(SnapType m)
Definition: editing.h:54
bool nudge_backward_release(GdkEventButton *)
Definition: editor_ops.cc:356
Glib::RefPtr< Gtk::ToggleAction > smart_mode_action
Definition: editor.h:1731
void select_all_objects(Selection::Operation op)
VisualState * current_visual_state(bool with_tracks=true)
Definition: editor.cc:4412
static Keyboard & the_keyboard()
Definition: keyboard.h:146
void update_marker_labels()
boost::shared_ptr< Playlist > playlist()
Definition: track.cc:590
bool _pending_initial_locate
Definition: editor.h:2168
void snap_to_with_modifier(framepos_t &first, GdkEvent const *ev, ARDOUR::RoundMode direction=ARDOUR::RoundNearest, bool for_mark=false)
Definition: editor.cc:2593
ArdourButton mouse_cut_button
Definition: editor.h:1728
void set_samples_per_pixel(framecnt_t)
Definition: editor.cc:4502
void set_sensitive(bool)
XMLNode & get_state(void)
Definition: location.cc:566
std::vector< std::string > snap_mode_strings
Definition: editor.h:1759
void tempo_map_changed(const PBD::PropertyChange &)
void route_removed(TimeAxisView *)
std::list< XMLNode * > selection_op_history
Definition: editor.h:1966
void select_all_selectables_between(bool within)
uint32_t bbt_beat_subdivision
Definition: editor.h:1692
PBD::Signal0< void > SnapChanged
void mapover_tracks(sigc::slot< void, RouteTimeAxisView &, uint32_t > sl, TimeAxisView *, PBD::PropertyID) const
#define DEBUG_TRACE(bits, str)
Definition: debug.h:55
RegionSelection regions
Definition: selection.h:82
std::map< ARDOUR::FadeShape, Gtk::Image * > _xfade_out_images
Definition: editor.h:2204
void get_per_region_note_selection(std::list< std::pair< PBD::ID, std::set< boost::shared_ptr< Evoral::Note< Evoral::Beats > > > > > &)
void play_selected_region()
Definition: editor_ops.cc:2789
void suspend_redisplay()
Definition: editor_routes.h:42
int64_t framepos_t
Definition: types.h:66
friend class DragManager
Definition: editor.h:1581
PBD::Signal1< void, bool > StepEditStatusChange
Definition: session.h:332
sigc::signal< void, framepos_t > UpdateAllTransportClocks
void control_step_tracks_up()
Definition: editor.cc:1042
bool _maximised
true if we are in fullscreen mode
Definition: editor.h:1615
void add_transport_frame(Gtk::Container &)
Definition: editor.cc:835
sigc::signal< void > Detach
Definition: tearoff.h:45
void resume_redisplay()
EditMode
Definition: types.h:351
std::vector< ARDOUR::framepos_t > region_boundary_cache
Definition: editor.h:1041
void add_external_audio_action(Editing::ImportMode)
void fit_tracks(TrackViewList &)
Definition: editor_ops.cc:7271
void crop_region_to_selection()
Definition: editor_ops.cc:3210
Gtkmm2ext::TearOff * _mouse_mode_tearoff
Definition: editor.h:1721
bool lock_timeout_callback()
Definition: editor.cc:1200
void prepare_for_cleanup()
Definition: editor.cc:4175
friend class EditorGroupTabs
Definition: editor.h:2265
void on_realize()
Definition: editor.cc:1143
void set_cursor_set(const std::string &name)
void sort_track_selection(TrackViewList &)
Definition: editor.cc:4660
LIBARDOUR_API XMLNode * find_named_node(const XMLNode &node, std::string name)
TempoLines * tempo_lines
Definition: editor.h:1617
void access_action(std::string, std::string)
Definition: editor.cc:1126
Gtk::VBox time_bars_vbox
Definition: editor.h:805
#define I18N(Array)
Definition: i18n.h:14
bool can_remove_control_point(ArdourCanvas::Item *)
FadeShape
Definition: types.h:592
PBD::ScopedConnectionList _session_connections
void new_tempo_section()
Definition: editor.cc:3331
std::map< ARDOUR::FadeShape, Gtk::Image * > _fade_in_images
Definition: editor.h:2201
void set_horizontal_position(double)
void cycle_edit_mode()
Definition: editor.cc:3600
Gtk::Window & tearoff_window()
Definition: tearoff.h:50
static const gchar * _snap_mode_strings[]
Definition: editor.cc:180
int32_t _visible_track_count
Definition: editor.h:1710
XMLNode * button_settings() const
Definition: editor.cc:815
void pane_allocation_handler(Gtk::Allocation &, Gtk::Paned *)
Definition: editor.cc:3883
bool autoscroll_vertical_allowed
Definition: editor.h:1881
Gtk::MenuItem * region_edit_menu_split_item
Definition: editor.h:742
LIBARDOUR_API PBD::PropertyDescriptor< bool > regions
Definition: playlist.cc:51
void set_state(const XMLNode &)
bool no_ruler_shown_update
Definition: editor.h:881
void set_mode(Mode)
SnapMode
Definition: editing.h:63
PBD::Signal1< void, std::string > ParameterChanged
Definition: configuration.h:44
void select_all_in_track(Selection::Operation op)
double trackviews_height() const
void popup_track_context_menu(int, int, ItemType, bool)
Definition: editor.cc:1546
sigc::connection _scroll_connection
Definition: editor.h:1070
Gtk::Menu track_region_context_menu
Definition: editor.h:739
LIBARDOUR_API RuntimeProfile * Profile
Definition: globals.cc:120
void foreach_time_axis_view(sigc::slot< void, TimeAxisView & >)
Definition: editor.cc:5408
void control_vertical_zoom_out_selected()
Definition: editor.cc:986
bool changed() const
Definition: stateful.cc:325
void reattach_all_tearoffs()
Definition: editor.cc:4244
ArdourCanvas::GtkCanvas * _track_canvas
Definition: editor.h:793
EditPoint
Definition: editing.h:178
void suspend_redisplay()
Gtk::Menu * build_track_region_context_menu()
Definition: editor.cc:1690
double _visible_canvas_width
Definition: editor.h:1073
void control_unselect()
Definition: editor.cc:998
int resize_idle_id
Definition: editor.h:2151
~Editor()
Definition: editor.cc:804
Gtk::Menu * range_marker_menu
Definition: editor.h:1673
void set_tip(Gtk::Widget &w, const gchar *tip)
void mapped_use_new_playlist(RouteTimeAxisView &, uint32_t, std::vector< boost::shared_ptr< ARDOUR::Playlist > > const &)
Definition: editor.cc:4323
LIBGTKMM2EXT_API Glib::RefPtr< Gtk::UIManager > ui_manager
Definition: actions.cc:53
bool show_gain_after_trim
Definition: editor.h:1905
void update_title()
Definition: editor.cc:1267
void super_rapid_screen_update()
Definition: editor.cc:5623
TimeAxisView * _stepping_axis_view
Definition: editor.h:2230
Gtk::VBox global_vpacker
Definition: editor.h:771
void snap_mode_selection_done(Editing::SnapMode)
Definition: editor.cc:3636
static void setup_sizes(const double timebar_height)
Definition: marker.cc:57
void set_loop_range(framepos_t start, framepos_t end, std::string cmd)
Definition: editor.cc:4740
void update_fixed_rulers()
Gtk::Label tempo_label
Definition: editor.h:979
int idle_visual_changer()
Definition: editor.cc:4584
void compute_bbt_ruler_scale(framepos_t lower, framepos_t upper, ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_begin, ARDOUR::TempoMap::BBTPointList::const_iterator current_bbt_points_end)
double _visible_canvas_height
height of the visible area of the track canvas
Definition: editor.h:1074
void map_parameters(boost::function< void(std::string)> &)
XMLProperty * add_property(const char *name, const std::string &value)
static const gchar * _zoom_focus_strings[]
Definition: editor.cc:202
void update_tempo_based_rulers(ARDOUR::TempoMap::BBTPointList::const_iterator &begin, ARDOUR::TempoMap::BBTPointList::const_iterator &end)
void set_snap_mode(Editing::SnapMode)
Definition: editor.cc:2118
ArdourDropdown snap_type_selector
Definition: editor.h:1751
void add_routes(ARDOUR::RouteList &)
Definition: editor.cc:5249
void new_playlists(TimeAxisView *v)
Definition: editor.cc:4282
void set_auto_punch_location(Location *)
Definition: session.cc:1382
Gtk::MenuItem & action_menu_item(std::string const &)
Definition: editor.cc:5858
Editing::SnapMode snap_mode() const
Definition: editor.cc:2040
void add(Location *, bool make_current=false)
Definition: location.cc:953
double get_y_origin() const
Definition: editor.cc:4354
void audition_region(boost::shared_ptr< Region >)
Definition: session.cc:4152
framepos_t requested_return_frame() const
Definition: session.h:554
GUIObjectState * gui_state
Definition: editor.h:564
void compute_current_bbt_points(framepos_t left, framepos_t right, ARDOUR::TempoMap::BBTPointList::const_iterator &begin, ARDOUR::TempoMap::BBTPointList::const_iterator &end)
Gtk::Label transport_mark_label
Definition: editor.h:983
ArdourButton mouse_move_button
Definition: editor.h:1724
void time_selection_changed()
bool constructed
Definition: editor.h:548
boost::shared_ptr< Route > route_by_remote_id(uint32_t id)
Definition: session.cc:3367
Gtk::VBox edit_controls_vbox
Definition: editor.h:1084
framepos_t round_to_beat_subdivision(framepos_t fr, int sub_num, RoundMode dir)
Definition: tempo.cc:1307
void zoom_vertical_modifier_released()
Definition: editor.cc:5962
bool transport_stopped() const
Definition: session.h:591
Gtk::Menu * build_track_bus_context_menu()
Definition: editor.cc:1678
sigc::signal< void > Visible
Definition: tearoff.h:47
std::string snap_name() const
Definition: session.h:167
bool _have_idled
Definition: editor.h:2150
void add_location_from_selection()
Definition: editor_ops.cc:2067
Gtk::HBox top_hbox
Definition: editor.h:1046
static const gchar * _edit_point_strings[]
Definition: editor.cc:187
void zoom_focus_selection_done(Editing::ZoomFocus f)
Definition: editor.cc:3690
ARDOUR::framepos_t start()
const char * name
Editing::RegionListSortType sort_type() const
bool get_trx() const
Definition: profile.h:50
void add_child_nocopy(XMLNode &)
Definition: xml++.cc:357
framepos_t pixel_to_sample(double pixel) const
Definition: editor.h:230
ARDOUR::framepos_t length()
static const int32_t default_width
Definition: editor.h:2030
Editing::SnapType snap_type() const
Definition: editor.cc:2034
XMLNode & get_state(void)
Definition: location.cc:1017
void set_stationary_playhead(bool yn)
Definition: editor.cc:4026
bool load(const std::string &path)
bool scroll_down_one_track(bool skip_child_views=false)
Definition: editor_ops.cc:1414
Editing::ZoomFocus zoom_focus
Definition: editor.h:563
MouseMode str2mousemode(const string &str)
Definition: editing.cc:103
void add_toplevel_menu(Gtk::Container &)
Definition: editor.cc:828
static int _idle_visual_changer(void *arg)
Definition: editor.cc:4578
Definition: editor.h:134
void set_fade_out_shape(ARDOUR::FadeShape)
Definition: editor_ops.cc:5733
Gtk::Menu * marker_menu
Definition: editor.h:1672
framepos_t leftmost_frame
Definition: editor.h:562
uint32_t n_channels() const
Definition: region.h:259
RouteTimeAxisView * get_route_view_by_route_id(const PBD::ID &id) const
Definition: editor.cc:5417
Gtk::Label bbt_label
Definition: editor.h:976
uint32_t selection_op_cmd_depth
Definition: editor.h:1963
Gtkmm2ext::TearOff * _zoom_tearoff
Definition: editor.h:1780
Glib::RefPtr< Gtk::RadioAction > snap_type_action(Editing::SnapType)
void abort_reversible_command()
void map_position_change(framepos_t)
Definition: editor.cc:1223
bool have_item(ArdourCanvas::Item *) const
Definition: editor_drag.cc:207
framecnt_t current_page_samples() const
Definition: editor.h:148
virtual void entered()
void begin_selection_op_history()
Definition: editor.cc:3350
Marker * entered_marker
Definition: editor.h:667
void abort()
Definition: editor_drag.cc:95
Gtk::Viewport _toolbar_viewport
Definition: editor.h:1791
PBD::Signal1< void, std::string > StateSaved
Definition: session.h:441
void toggle_stationary_playhead()
Definition: editor.cc:4016
bool _ignore_follow_edits
Definition: editor.h:1822
void popup_control_point_context_menu(ArdourCanvas::Item *, GdkEvent *)
Definition: editor.cc:5909
void setup_fade_images()
Definition: editor.cc:5828
std::vector< std::string > edit_mode_strings
Definition: editor.h:2113
Editing::SnapMode internal_snap_mode
Definition: editor.h:590
Definition: xml++.h:95
void show_window()
Definition: editor.cc:916
Width
Definition: enums.h:25
void tie_vertical_scrolling()
sigc::signal< void > PointsChanged
Definition: selection.h:102
void region_view_added(RegionView *)
Definition: editor.cc:5169
std::string name() const
void clear_tracks()
Definition: selection.cc:127
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > position
Definition: region.cc:65
TimeSelection time
Definition: selection.h:83
void put_it_back()
Definition: tearoff.cc:177
void duplicate_range(bool with_dialog)
Definition: editor.cc:3528
uint64_t CutNPaste
Definition: debug.cc:29
ARDOUR::Location * find_location_from_marker(Marker *, bool &is_start) const
boost::shared_ptr< RouteList > route_list()
Definition: route_group.h:126
TrackSelection tracks
Definition: selection.h:81
static UIConfiguration * config()
Definition: ardour_ui.h:188
bool get_small_screen() const
Definition: profile.h:45
void set_loop_from_selection(bool play)
Definition: editor_ops.cc:6032
friend class EditorSummary
Definition: editor.h:2264
void add_instant_xml(XMLNode &, bool write_to_config=true)
The instant xml file is written to the session directory.
std::vector< std::string > edit_point_strings
Definition: editor.h:2112
void set_text(const std::string &)
bool edit_controls_button_release(GdkEventButton *)
Definition: editor.cc:3813
Gtk::Widget & widget()
TrackViewList axis_views_from_routes(boost::shared_ptr< ARDOUR::RouteList >) const
Definition: editor.cc:5217
Gtk::Menu * build_track_selection_context_menu()
Definition: editor.cc:1755
XMLNode & get_state() const
Definition: selection.cc:1208
void get_per_region_note_selection(std::list< std::pair< PBD::ID, std::set< boost::shared_ptr< Evoral::Note< Evoral::Beats > > > > > &) const
Definition: editor.cc:4989
Gtk::Frame toolbar_frame
Definition: editor.h:1790
std::vector< Glib::RefPtr< Gtk::Action > > edit_point_in_region_sensitive_actions
Definition: actions.cc:64
uint32_t location_cd_marker_color
Definition: editor.h:640
LIBARDOUR_API PBD::PropertyDescriptor< bool > select
Definition: route_group.cc:48
Definition: debug.h:30
ARDOUR::Location * transport_loop_location()
Definition: editor.cc:4193
bool _show_marker_lines
Definition: editor.h:668
double divisions_per_bar() const
Definition: tempo.h:70
void hide_things()
boost::shared_ptr< IO > input() const
Definition: route.h:89
Gtk::HBox _zoom_box
Definition: editor.h:1779
void control_vertical_zoom_out_all()
Definition: editor.cc:974
void finish_cleanup()
Definition: editor.cc:4187
void build_edit_mode_menu()
Definition: editor.cc:3152
std::string session_name
Definition: opts.cc:34
void remove_metric_marks()
std::list< TimeAxisView * > views() const
bool button_release_can_deselect
Definition: editor.h:720
Gtk::HBox status_bar_hpacker
Definition: editor.h:2099
Gtkmm2ext::TearOff * _tools_tearoff
Definition: editor.h:1787
Direction
Definition: editor.h:1061
sigc::connection editor_regions_selection_changed_connection
Definition: editor.h:1809
void set_edit_mode(ARDOUR::EditMode)
Definition: editor.cc:3594
framepos_t last_paste_pos
Definition: editor.h:1185
bool scroll_press(Direction)
Definition: editor.cc:5527
bool contains(TimeAxisView const *) const
sigc::signal< void > ZoomChanged
void get_source_equivalent_regions(boost::shared_ptr< Region >, std::vector< boost::shared_ptr< Region > > &)
Definition: playlist.cc:860
bool clear_entered_track
Definition: editor.h:2072
void set_session(ARDOUR::Session *)
EditorGroupTabs * _group_tabs
Definition: editor.h:2176
Editing::SnapType pre_internal_snap_type
Definition: editor.h:587
Gtk::MenuItem * _popup_region_menu_item
Definition: editor.h:759
framepos_t current_duration(framepos_t position=0) const
uint32_t selection_op_history_it
Definition: editor.h:1964
void freeze_route()
Definition: editor_ops.cc:3822
void set_session(ARDOUR::Session *)
TrackViewList track_views
Definition: editor.h:1135
RegionSelection get_regions_from_selection_and_edit_point()
Definition: editor.cc:4881
TimeAxisView * _pending_resize_view
Definition: editor.h:2155
#define S_(Text)
Definition: i18n.h:18
sigc::signal< void, std::string > ParameterChanged
Definition: ui_config.h:78
void show_a_region(boost::shared_ptr< ARDOUR::Region >)
Definition: editor.cc:5468
Gtkmm2ext::Bindings * button_bindings
Definition: editor.h:1171
boost::shared_ptr< SessionPlaylists > playlists
Definition: session.h:907
void set_fade_in_active(bool)
Definition: editor_ops.cc:5763
void start_step_editing()
Definition: editor.cc:5502
void consider_auditioning(boost::shared_ptr< ARDOUR::Region >)
Definition: editor.cc:5440
bool nudge_forward_release(GdkEventButton *)
Definition: editor_ops.cc:345
LIBEVORAL_API uint64_t Beats
void temporal_zoom_session()
Definition: editor_ops.cc:1920
RouteTimeAxisView * axis_view_from_route(boost::shared_ptr< ARDOUR::Route >) const
Definition: editor.cc:5201
bool ruler_label_button_release(GdkEventButton *)
boost::shared_ptr< ARDOUR::AudioRegion > last_audition_region
Definition: editor.h:1974
framepos_t start() const
Definition: location.h:71
void paste(float times, bool from_context_menu=false)
Definition: editor_ops.cc:4580
void reset_x_origin(framepos_t)
Definition: editor.cc:4363
framepos_t round_to_beat(framepos_t frame, RoundMode dir)
Definition: tempo.cc:1301
void selection_mapover(sigc::slot< void, boost::shared_ptr< ARDOUR::Region > >)
Gtk::Label meter_label
Definition: editor.h:980
void step_edit_status_change(bool)
Definition: editor.cc:5492
void draw_metric_marks(const ARDOUR::Metrics &metrics)
static const framepos_t max_framepos
Definition: types.h:78
Round up only if necessary.
Definition: types.h:226
Gtk::Layout controls_layout
Definition: editor.h:1056
void snap_type_selection_done(Editing::SnapType)
Definition: editor.cc:3627
sigc::signal< void > TracksChanged
Definition: selection.h:98
virtual void set_session(ARDOUR::Session *)
void region_selection_changed()
std::list< VisualState * > undo_visual_stack
Definition: editor.h:567
void set_session(ARDOUR::Session *)
void draw_measures(ARDOUR::TempoMap::BBTPointList::const_iterator &begin, ARDOUR::TempoMap::BBTPointList::const_iterator &end)
Gtk::MenuItem * region_edit_menu_split_multichannel_item
Definition: editor.h:743
Gtk::Label range_mark_label
Definition: editor.h:982
void set_session(ARDOUR::Session *)
int scrubbing_direction
Definition: editor.h:1461
bool _last_region_menu_was_main
Definition: editor.h:1818
std::string get_icon_path(const char *, std::string icon_set=std::string(), bool is_image=true)
bool mouse_select_button_release(GdkEventButton *)
Definition: editor.cc:3825
void invert_selection_in_track()
void refresh_location_display()
Gtk::VPaned editor_summary_pane
Definition: editor.h:615
static uint32_t preset_height(Height)
void add_to_idle_resize(TimeAxisView *, int32_t)
Definition: editor.cc:5092
sigc::signal0< void > ZoomVerticalModifierReleased
Definition: keyboard.h:174
void restore_ruler_visibility()
void select_notes(std::list< boost::shared_ptr< NoteType > >)
void commit_reversible_command()
Definition: editor.cc:3483
static float ui_scale
Definition: ardour_ui.h:189
friend class EditorRegions
Definition: editor.h:1583
struct timeval last_event_time
Definition: editor.h:1488
void set_punch_range(framepos_t start, framepos_t end, std::string cmd)
Definition: editor.cc:4767
bool notebook_tab_clicked(GdkEventButton *, Gtk::Widget *)
Definition: editor.cc:5879
boost::shared_ptr< ARDOUR::AudioTrack > audio_track() const
Definition: route_ui.cc:1750
void sensitize_the_right_region_actions()
void clear_playlists(TimeAxisView *v)
Definition: editor.cc:4313
void set_selection_from_region()
XMLNode & get_state() const
ArdourButton tav_shrink_button
Definition: editor.h:1706
void audition_region_from_region_list()
Definition: editor.cc:5474
Gtk::Menu _note_context_menu
Definition: editor.h:765
void separate_region_from_selection()
Definition: editor_ops.cc:3073
void select_all_selectables_using_time_selection()
#define timersub(a, b, result)
Definition: timersub.h:22
sigc::signal< void > RegionsChanged
Definition: selection.h:97
MouseCursors * _cursors
Definition: editor.h:2209
void play_selection()
Definition: editor_ops.cc:2505
void set_show_measures(bool yn)
Definition: editor.cc:3969
void cycle_zoom_focus()
Definition: editor.cc:3852
ArdourButton mouse_audition_button
Definition: editor.h:1727
bool within_track_canvas
Definition: editor.h:796
void set_mouse_mode(Editing::MouseMode, bool force=true)
void add_bus_context_items(Gtk::Menu_Helpers::MenuList &)
Definition: editor.cc:1978
DragManager * _drags
Definition: editor.h:1481
void control_scroll(float)
Definition: editor.cc:1054
std::list< VisualState * > redo_visual_stack
Definition: editor.h:568
void set_visible_track_count(int32_t)
Definition: editor.cc:3756
Editing::SnapMode _snap_mode
Definition: editor.h:1474
uint32_t location_range_color
Definition: editor.h:637
boost::optional< int > pre_notebook_shrink_pane_width
Definition: editor.h:605
void build_region_boundary_cache()
Definition: editor_ops.cc:665
Glib::RefPtr< Gdk::Pixbuf > get_icon(const char *cname)
Definition: utils.cc:674
void select_all_selectables_using_cursor(EditorCursor *, bool)
void register_with_memento_command_factory(PBD::ID, PBD::StatefulDestructible *)
void tempo_map_changed()
Definition: tempo_lines.cc:39
void add_instant_xml(XMLNode &)
Gtk::Notebook _the_notebook
Definition: editor.h:609
std::list< boost::shared_ptr< Route > > RouteList
Definition: types.h:532
RegionView * entered_regionview
Definition: editor.h:2068
void set_overlays_dirty()
int64_t framepos_t
uint32_t location_punch_color
Definition: editor.h:639
Definition: enums.h:26
void set_loop_from_region(bool play)
Definition: editor_ops.cc:6050
Gtk::Menu * transport_marker_menu
Definition: editor.h:1674
void set_zoom_preset(int64_t)
Definition: editor.cc:3744
void suspend_route_redisplay()
Definition: editor.cc:5232
RhythmFerret * rhythm_ferret
Definition: editor.h:2140
void use_copy_playlist(bool prompt, std::vector< boost::shared_ptr< ARDOUR::Playlist > > const &)
void hide_track_in_display(TimeAxisView *tv, bool apply_to_selection=false)
Definition: editor.cc:5372
static double timebar_height
Definition: editor.h:964
void add_route(Gtk::Window *float_window)
Definition: ardour_ui.cc:3660
void set_hidden(bool yn, void *src)
Definition: location.cc:441
double snap_threshold
Snap threshold in pixels.
Definition: editor.h:1477
ARDOUR::Session * _session
void show_region_in_region_list()
Definition: editor.cc:5486
void apply_with_metrics(T &obj, void(T::*method)(const Metrics &))
Definition: tempo.h:240
boost::shared_ptr< ARDOUR::Route > route() const
Definition: route_ui.h:76
bool sync_track_view_list_and_routes()
Definition: editor.cc:5397
void AddMenuElem(Gtk::Menu_Helpers::MenuElem e)
Glib::RefPtr< Gtk::ActionGroup > editor_actions
void map_parameters(boost::function< void(std::string)> &)
AudioEngine & engine()
Definition: session.h:546
void swap_visual_state()
Definition: editor.cc:4465
void scroll_backward(float pages=0.8f)
Definition: editor_ops.cc:1347
uint32_t location_loop_color
Definition: editor.h:638
int order() const
bool get_smart_mode() const
Definition: editor.cc:847
PBD::Signal0< void > changed
Definition: location.h:211
void fill_xfade_menu(Gtk::Menu_Helpers::MenuList &items, bool start)
Definition: editor.cc:1432
void lock()
Definition: editor_ops.cc:7536
std::map< ARDOUR::FadeShape, Gtk::Image * > _fade_out_images
Definition: editor.h:2202
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208
Glib::RefPtr< Gtk::Action > selection_redo_action
Definition: editor.h:2095
void transform_regions(const RegionSelection &rs)
Definition: editor_ops.cc:5228
uint32_t count_regions_at(framepos_t) const
Definition: playlist.cc:1712
#define N_(Text)
Definition: i18n.h:12
void ensure_visual_change_idle_handler()
Definition: editor.cc:4568
static const int32_t default_height
Definition: editor.h:2031
double atof(const string &s)
Definition: convert.cc:158
void control_vertical_zoom_in_selected()
Definition: editor.cc:980
void temporal_zoom_selection(bool both_axes=false)
Definition: editor_ops.cc:1892
unsigned get_grid_beat_divisions(framepos_t position)
Definition: editor.cc:4064
Gtk::Menu track_selection_context_menu
Definition: editor.h:740
Gtk::Dialog * lock_dialog
Definition: editor.h:1486
void mapped_clear_playlist(RouteTimeAxisView &, uint32_t)
Definition: editor.cc:4335
void align_regions(ARDOUR::RegionPoint)
Definition: editor_ops.cc:3465
Gtk::Menu track_context_menu
Definition: editor.h:738
Children get_child_list()
static void pane_size_watcher(Paned *pane)
Definition: editor.cc:228
ArdourButton nudge_forward_button
Definition: editor.h:2035
Editing::MouseMode mouse_mode
Definition: editor.h:586
RegionView * clicked_regionview
Definition: editor.h:701
void reposition_and_zoom(framepos_t, double)
Definition: editor.cc:4391
RegionListSortType
Definition: editing.h:77
bool on_key_release_event(GdkEventKey *)
Definition: editor.cc:4347
sigc::connection step_edit_connection
Definition: editor.h:2183
bool is_monitor() const
Definition: route.h:112
void edit_control_point(ArdourCanvas::Item *)
PBD::Signal1< void, RouteList & > RouteAdded
Definition: session.h:317
sigc::signal< void > RegionViewRemoved
Definition: streamview.h:123
double speed() const
Definition: track.cc:759
bool autoscroll_horizontal_allowed
Definition: editor.h:1880
Glib::RefPtr< Gtk::ActionGroup > _region_actions
void snap_to(framepos_t &first, ARDOUR::RoundMode direction=ARDOUR::RoundNearest, bool for_mark=false)
Definition: editor.cc:2611
int set_state(XMLNode const &, int)
Definition: selection.cc:1307
bool _pending_locate_request
Definition: editor.h:2162
Location * auto_punch_location() const
Definition: location.cc:1370
void resume_redisplay()
Definition: editor_routes.h:49
boost::optional< framepos_t > _control_scroll_target
Definition: editor.h:551