2 Copyright (C) 2000-2004 Paul Davis
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.
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.
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.
28 #include <pbd/error.h>
29 #include <pbd/basename.h>
30 #include <pbd/pthread_utils.h>
32 #include <gtkmm2ext/utils.h>
33 #include <gtkmm2ext/choice.h>
35 #include <ardour/audioengine.h>
36 #include <ardour/session.h>
37 #include <ardour/audioplaylist.h>
38 #include <ardour/audioregion.h>
39 #include <ardour/audio_diskstream.h>
40 #include <ardour/utils.h>
41 #include <ardour/location.h>
42 #include <ardour/named_selection.h>
43 #include <ardour/audio_track.h>
44 #include <ardour/audioplaylist.h>
45 #include <ardour/region_factory.h>
46 #include <ardour/reverse.h>
48 #include "ardour_ui.h"
50 #include "time_axis_view.h"
51 #include "audio_time_axis.h"
52 #include "automation_time_axis.h"
53 #include "streamview.h"
54 #include "regionview.h"
55 #include "rgb_macros.h"
56 #include "selection_templates.h"
57 #include "selection.h"
60 #include "gtk-custom-hruler.h"
61 #include "gui_thread.h"
66 using namespace ARDOUR;
69 using namespace Editing;
71 /***********************************************************************
73 ***********************************************************************/
76 Editor::undo (uint32_t n)
84 Editor::redo (uint32_t n)
92 Editor::set_meter_hold (int32_t cnt)
94 Config->set_meter_hold_off(false);
95 Config->set_meter_hold_short(false);
96 Config->set_meter_hold_medium(false);
97 Config->set_meter_hold_long(false);
102 Config->set_meter_hold_off(true);
105 Config->set_meter_hold_short(true);
108 Config->set_meter_hold_medium(true);
111 Config->set_meter_hold_long(true);
116 session->set_meter_hold (cnt);
121 Editor::set_meter_falloff (int intval)
123 float val = 0.0f; /* off */
126 Config->set_meter_falloff_off(false);
127 Config->set_meter_falloff_slowest(false);
128 Config->set_meter_falloff_slow(false);
129 Config->set_meter_falloff_medium(false);
130 Config->set_meter_falloff_fast(false);
131 Config->set_meter_falloff_faster(false);
132 Config->set_meter_falloff_fastest(false);
138 Config->set_meter_falloff_off(true);
142 Config->set_meter_falloff_slowest(true);
146 Config->set_meter_falloff_slow(true);
150 Config->set_meter_falloff_medium(true);
154 Config->set_meter_falloff_fast(true);
158 Config->set_meter_falloff_faster(true);
162 Config->set_meter_falloff_fastest(true);
167 session->set_meter_falloff (val);
173 Editor::ensure_cursor (jack_nframes_t *pos)
175 *pos = edit_cursor->current_frame;
180 Editor::split_region ()
182 split_region_at (edit_cursor->current_frame);
186 Editor::split_region_at (jack_nframes_t where)
188 split_regions_at (where, selection->audio_regions);
192 Editor::split_regions_at (jack_nframes_t where, AudioRegionSelection& regions)
194 begin_reversible_command (_("split"));
197 for (AudioRegionSelection::iterator a = regions.begin(); a != regions.end(); ) {
199 AudioRegionSelection::iterator tmp;
204 Playlist* pl = (*a)->region.playlist();
206 _new_regionviews_show_envelope = (*a)->envelope_visible();
209 session->add_undo (pl->get_memento());
210 pl->split_region ((*a)->region, where);
211 session->add_redo_no_execute (pl->get_memento());
217 commit_reversible_command ();
218 _new_regionviews_show_envelope = false;
222 Editor::remove_clicked_region ()
224 if (clicked_audio_trackview == 0 || clicked_regionview == 0) {
228 Playlist* playlist = clicked_audio_trackview->playlist();
230 begin_reversible_command (_("remove region"));
231 session->add_undo (playlist->get_memento());
232 playlist->remove_region (&clicked_regionview->region);
233 session->add_redo_no_execute (playlist->get_memento());
234 commit_reversible_command ();
238 Editor::destroy_clicked_region ()
240 int32_t selected = selection->audio_regions.size();
242 if (!session || clicked_regionview == 0 && selected == 0) {
246 vector<string> choices;
249 prompt = string_compose (_(" This is destructive, will possibly delete audio files\n\
250 It cannot be undone\n\
251 Do you really want to destroy %1 ?"),
253 _("these regions") : _("this region")));
255 choices.push_back (_("No, do nothing."));
258 choices.push_back (_("Yes, destroy them."));
260 choices.push_back (_("Yes, destroy it."));
263 Gtkmm2ext::Choice prompter (prompt, choices);
265 if (prompter.run() == 0) { /* first choice */
272 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
273 r.push_back (&(*i)->region);
276 session->destroy_regions (r);
278 } else if (clicked_regionview) {
279 session->destroy_region (&clicked_regionview->region);
284 Editor::select_region_for_operation (int dir, TimeAxisView **tv)
288 jack_nframes_t start = 0;
290 if (selection->time.start () == selection->time.end_frame ()) {
292 /* no current selection-> is there a selected regionview? */
294 if (selection->audio_regions.empty()) {
302 if (!selection->audio_regions.empty()) {
304 rv = *(selection->audio_regions.begin());
305 (*tv) = &rv->get_time_axis_view();
306 region = &rv->region;
308 } else if (!selection->tracks.empty()) {
310 (*tv) = selection->tracks.front();
312 AudioTimeAxisView* atv;
314 if ((atv = dynamic_cast<AudioTimeAxisView*> (*tv)) != 0) {
317 if ((pl = atv->playlist()) == 0) {
321 region = dynamic_cast<AudioRegion*> (pl->top_region_at (start));
329 Editor::extend_selection_to_end_of_region (bool next)
333 jack_nframes_t start;
335 if ((region = select_region_for_operation (next ? 1 : 0, &tv)) == 0) {
339 if (region && selection->time.start () == selection->time.end_frame ()) {
340 start = region->position();
342 start = selection->time.start ();
345 /* Try to leave the selection with the same route if possible */
347 if ((tv = selection->time.track) == 0) {
351 begin_reversible_command (_("extend selection"));
352 selection->set (tv, start, region->position() + region->length());
353 commit_reversible_command ();
357 Editor::extend_selection_to_start_of_region (bool previous)
363 if ((region = select_region_for_operation (previous ? -1 : 0, &tv)) == 0) {
367 if (region && selection->time.start () == selection->time.end_frame ()) {
368 end = region->position() + region->length();
370 end = selection->time.end_frame ();
373 /* Try to leave the selection with the same route if possible */
375 if ((tv = selection->time.track) == 0) {
379 begin_reversible_command (_("extend selection"));
380 selection->set (tv, region->position(), end);
381 commit_reversible_command ();
386 Editor::nudge_forward (bool next)
388 jack_nframes_t distance;
389 jack_nframes_t next_distance;
391 if (!session) return;
393 if (!selection->audio_regions.empty()) {
395 begin_reversible_command (_("nudge forward"));
397 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
398 AudioRegion& r ((*i)->region);
400 distance = get_nudge_distance (r.position(), next_distance);
403 distance = next_distance;
406 session->add_undo (r.playlist()->get_memento());
407 r.set_position (r.position() + distance, this);
408 session->add_redo_no_execute (r.playlist()->get_memento());
411 commit_reversible_command ();
414 distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);
415 session->request_locate (playhead_cursor->current_frame + distance);
420 Editor::nudge_backward (bool next)
422 jack_nframes_t distance;
423 jack_nframes_t next_distance;
425 if (!session) return;
427 if (!selection->audio_regions.empty()) {
429 begin_reversible_command (_("nudge forward"));
431 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
432 AudioRegion& r ((*i)->region);
434 distance = get_nudge_distance (r.position(), next_distance);
437 distance = next_distance;
440 session->add_undo (r.playlist()->get_memento());
442 if (r.position() > distance) {
443 r.set_position (r.position() - distance, this);
445 r.set_position (0, this);
447 session->add_redo_no_execute (r.playlist()->get_memento());
450 commit_reversible_command ();
454 distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);
456 if (playhead_cursor->current_frame > distance) {
457 session->request_locate (playhead_cursor->current_frame - distance);
459 session->goto_start();
465 Editor::nudge_forward_capture_offset ()
467 jack_nframes_t distance;
469 if (!session) return;
471 if (!selection->audio_regions.empty()) {
473 begin_reversible_command (_("nudge forward"));
475 distance = session->worst_output_latency();
477 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
478 AudioRegion& r ((*i)->region);
480 session->add_undo (r.playlist()->get_memento());
481 r.set_position (r.position() + distance, this);
482 session->add_redo_no_execute (r.playlist()->get_memento());
485 commit_reversible_command ();
491 Editor::nudge_backward_capture_offset ()
493 jack_nframes_t distance;
495 if (!session) return;
497 if (!selection->audio_regions.empty()) {
499 begin_reversible_command (_("nudge forward"));
501 distance = session->worst_output_latency();
503 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
504 AudioRegion& r ((*i)->region);
506 session->add_undo (r.playlist()->get_memento());
508 if (r.position() > distance) {
509 r.set_position (r.position() - distance, this);
511 r.set_position (0, this);
513 session->add_redo_no_execute (r.playlist()->get_memento());
516 commit_reversible_command ();
523 Editor::move_to_start ()
525 session->goto_start ();
529 Editor::move_to_end ()
532 session->request_locate (session->current_end_frame());
536 Editor::build_region_boundary_cache ()
538 jack_nframes_t pos = 0;
541 TrackViewList tracks;
543 region_boundary_cache.clear ();
550 case SnapToRegionStart:
553 case SnapToRegionEnd:
556 case SnapToRegionSync:
559 case SnapToRegionBoundary:
563 fatal << string_compose (_("build_region_boundary_cache called with snap_type = %1"), snap_type) << endmsg;
568 TimeAxisView *ontrack = 0;
570 while (pos < session->current_end_frame()) {
572 if (!selection->tracks.empty()) {
574 if ((r = find_next_region (pos, point, 1, selection->tracks, &ontrack)) == 0) {
578 } else if (clicked_trackview) {
581 t.push_back (clicked_trackview);
583 if ((r = find_next_region (pos, point, 1, t, &ontrack)) == 0) {
589 if ((r = find_next_region (pos, point, 1, track_views, &ontrack)) == 0) {
597 case SnapToRegionStart:
598 rpos = r->first_frame();
600 case SnapToRegionEnd:
601 rpos = r->last_frame();
603 case SnapToRegionSync:
604 rpos = r->adjust_to_sync (r->first_frame());
607 case SnapToRegionBoundary:
608 rpos = r->last_frame();
615 AudioTimeAxisView *atav;
617 if ( ontrack != 0 && (atav = dynamic_cast<AudioTimeAxisView*>(ontrack)) != 0 ) {
618 if (atav->get_diskstream() != 0) {
619 speed = atav->get_diskstream()->speed();
623 rpos = track_frame_to_session_frame(rpos, speed);
625 if (region_boundary_cache.empty() || rpos != region_boundary_cache.back()) {
626 if (snap_type == SnapToRegionBoundary) {
627 region_boundary_cache.push_back (r->first_frame());
629 region_boundary_cache.push_back (rpos);
637 Editor::find_next_region (jack_nframes_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack)
639 TrackViewList::iterator i;
640 jack_nframes_t closest = max_frames;
642 jack_nframes_t rpos = 0;
645 jack_nframes_t track_frame;
646 AudioTimeAxisView *atav;
648 for (i = tracks.begin(); i != tracks.end(); ++i) {
650 jack_nframes_t distance;
654 if ( (atav = dynamic_cast<AudioTimeAxisView*>(*i)) != 0 ) {
655 if (atav->get_diskstream()!=0)
656 track_speed = atav->get_diskstream()->speed();
659 track_frame = session_frame_to_track_frame(frame, track_speed);
661 if ((r = (*i)->find_next_region (track_frame, point, dir)) == 0) {
667 rpos = r->first_frame ();
671 rpos = r->last_frame ();
675 rpos = r->adjust_to_sync (r->first_frame());
678 // rpos is a "track frame", converting it to "session frame"
679 rpos = track_frame_to_session_frame(rpos, track_speed);
682 distance = rpos - frame;
684 distance = frame - rpos;
687 if (distance < closest) {
699 Editor::cursor_to_region_point (Cursor* cursor, RegionPoint point, int32_t dir)
702 jack_nframes_t pos = cursor->current_frame;
708 TimeAxisView *ontrack = 0;
710 // so we don't find the current region again..
714 if (!selection->tracks.empty()) {
716 r = find_next_region (pos, point, dir, selection->tracks, &ontrack);
718 } else if (clicked_trackview) {
721 t.push_back (clicked_trackview);
723 r = find_next_region (pos, point, dir, t, &ontrack);
727 r = find_next_region (pos, point, dir, track_views, &ontrack);
736 pos = r->first_frame ();
740 pos = r->last_frame ();
744 pos = r->adjust_to_sync (r->first_frame());
749 AudioTimeAxisView *atav;
751 if ( ontrack != 0 && (atav = dynamic_cast<AudioTimeAxisView*>(ontrack)) != 0 ) {
752 if (atav->get_diskstream() != 0) {
753 speed = atav->get_diskstream()->speed();
757 pos = track_frame_to_session_frame(pos, speed);
759 if (cursor == playhead_cursor) {
760 session->request_locate (pos);
762 cursor->set_position (pos);
767 Editor::cursor_to_next_region_point (Cursor* cursor, RegionPoint point)
769 cursor_to_region_point (cursor, point, 1);
773 Editor::cursor_to_previous_region_point (Cursor* cursor, RegionPoint point)
775 cursor_to_region_point (cursor, point, -1);
779 Editor::cursor_to_selection_start (Cursor *cursor)
781 jack_nframes_t pos = 0;
782 switch (mouse_mode) {
784 if (!selection->audio_regions.empty()) {
785 pos = selection->audio_regions.start();
790 if (!selection->time.empty()) {
791 pos = selection->time.start ();
799 if (cursor == playhead_cursor) {
800 session->request_locate (pos);
802 cursor->set_position (pos);
807 Editor::cursor_to_selection_end (Cursor *cursor)
809 jack_nframes_t pos = 0;
811 switch (mouse_mode) {
813 if (!selection->audio_regions.empty()) {
814 pos = selection->audio_regions.end_frame();
819 if (!selection->time.empty()) {
820 pos = selection->time.end_frame ();
828 if (cursor == playhead_cursor) {
829 session->request_locate (pos);
831 cursor->set_position (pos);
836 Editor::playhead_backward ()
843 if (get_prefix (prefix, was_floating)) {
847 cnt = (jack_nframes_t) floor (prefix * session->frame_rate ());
849 cnt = (jack_nframes_t) prefix;
853 pos = playhead_cursor->current_frame;
855 if ((jack_nframes_t) pos < cnt) {
861 /* XXX this is completely insane. with the current buffering
862 design, we'll force a complete track buffer flush and
863 reload, just to move 1 sample !!!
866 session->request_locate (pos);
870 Editor::playhead_forward ()
877 if (get_prefix (prefix, was_floating)) {
881 cnt = (jack_nframes_t) floor (prefix * session->frame_rate ());
883 cnt = (jack_nframes_t) floor (prefix);
887 pos = playhead_cursor->current_frame;
889 /* XXX this is completely insane. with the current buffering
890 design, we'll force a complete track buffer flush and
891 reload, just to move 1 sample !!!
894 session->request_locate (pos+cnt);
898 Editor::cursor_align (bool playhead_to_edit)
900 if (playhead_to_edit) {
902 session->request_locate (edit_cursor->current_frame);
905 edit_cursor->set_position (playhead_cursor->current_frame);
910 Editor::edit_cursor_backward ()
917 if (get_prefix (prefix, was_floating)) {
921 cnt = (jack_nframes_t) floor (prefix * session->frame_rate ());
923 cnt = (jack_nframes_t) prefix;
927 pos = edit_cursor->current_frame;
929 if ((jack_nframes_t) pos < cnt) {
935 edit_cursor->set_position (pos);
939 Editor::edit_cursor_forward ()
946 if (get_prefix (prefix, was_floating)) {
950 cnt = (jack_nframes_t) floor (prefix * session->frame_rate ());
952 cnt = (jack_nframes_t) floor (prefix);
956 pos = edit_cursor->current_frame;
957 edit_cursor->set_position (pos+cnt);
961 Editor::goto_frame ()
965 jack_nframes_t frame;
967 if (get_prefix (prefix, was_floating)) {
972 frame = (jack_nframes_t) floor (prefix * session->frame_rate());
974 frame = (jack_nframes_t) floor (prefix);
977 session->request_locate (frame);
981 Editor::scroll_backward (float pages)
983 jack_nframes_t frame;
984 jack_nframes_t one_page = (jack_nframes_t) rint (canvas_width * frames_per_unit);
989 if (get_prefix (prefix, was_floating)) {
990 cnt = (jack_nframes_t) floor (pages * one_page);
993 cnt = (jack_nframes_t) floor (prefix * session->frame_rate());
995 cnt = (jack_nframes_t) floor (prefix * one_page);
999 if (leftmost_frame < cnt) {
1002 frame = leftmost_frame - cnt;
1005 reposition_x_origin (frame);
1009 Editor::scroll_forward (float pages)
1011 jack_nframes_t frame;
1012 jack_nframes_t one_page = (jack_nframes_t) rint (canvas_width * frames_per_unit);
1017 if (get_prefix (prefix, was_floating)) {
1018 cnt = (jack_nframes_t) floor (pages * one_page);
1021 cnt = (jack_nframes_t) floor (prefix * session->frame_rate());
1023 cnt = (jack_nframes_t) floor (prefix * one_page);
1027 if (ULONG_MAX - cnt < leftmost_frame) {
1028 frame = ULONG_MAX - cnt;
1030 frame = leftmost_frame + cnt;
1033 reposition_x_origin (frame);
1037 Editor::scroll_tracks_down ()
1043 if (get_prefix (prefix, was_floating)) {
1046 cnt = (int) floor (prefix);
1049 double vert_value = vertical_adjustment.get_value() + (cnt *
1050 vertical_adjustment.get_page_size());
1051 if (vert_value > vertical_adjustment.get_upper() - canvas_height) {
1052 vert_value = vertical_adjustment.get_upper() - canvas_height;
1054 vertical_adjustment.set_value (vert_value);
1058 Editor::scroll_tracks_up ()
1064 if (get_prefix (prefix, was_floating)) {
1067 cnt = (int) floor (prefix);
1070 vertical_adjustment.set_value (vertical_adjustment.get_value() - (cnt * vertical_adjustment.get_page_size()));
1074 Editor::scroll_tracks_down_line ()
1077 Gtk::Adjustment* adj = edit_vscrollbar.get_adjustment();
1078 double vert_value = adj->get_value() + 20;
1080 if (vert_value>adj->get_upper() - canvas_height) {
1081 vert_value = adj->get_upper() - canvas_height;
1083 adj->set_value (vert_value);
1087 Editor::scroll_tracks_up_line ()
1089 Gtk::Adjustment* adj = edit_vscrollbar.get_adjustment();
1090 adj->set_value (adj->get_value() - 20);
1096 Editor::temporal_zoom_step (bool coarser)
1098 ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::temporal_zoom_step), coarser));
1102 nfpu = frames_per_unit;
1107 nfpu = max(1.0,(nfpu/2.0));
1110 temporal_zoom (nfpu);
1114 Editor::temporal_zoom (gdouble fpu)
1116 if (!session) return;
1118 jack_nframes_t current_page = current_page_frames();
1119 jack_nframes_t current_leftmost = leftmost_frame;
1120 jack_nframes_t current_rightmost;
1121 jack_nframes_t current_center;
1122 jack_nframes_t new_page;
1123 jack_nframes_t leftmost_after_zoom = 0;
1128 new_page = (jack_nframes_t) floor (canvas_width * nfpu);
1130 switch (zoom_focus) {
1132 leftmost_after_zoom = current_leftmost;
1135 case ZoomFocusRight:
1136 current_rightmost = leftmost_frame + current_page;
1137 if (current_rightmost > new_page) {
1138 leftmost_after_zoom = current_rightmost - new_page;
1140 leftmost_after_zoom = 0;
1144 case ZoomFocusCenter:
1145 current_center = current_leftmost + (current_page/2);
1146 if (current_center > (new_page/2)) {
1147 leftmost_after_zoom = current_center - (new_page / 2);
1149 leftmost_after_zoom = 0;
1153 case ZoomFocusPlayhead:
1154 /* try to keep the playhead in the center */
1155 if (playhead_cursor->current_frame > new_page/2) {
1156 leftmost_after_zoom = playhead_cursor->current_frame - (new_page/2);
1158 leftmost_after_zoom = 0;
1163 /* try to keep the edit cursor in the center */
1164 if (edit_cursor->current_frame > leftmost_frame + (new_page/2)) {
1165 leftmost_after_zoom = edit_cursor->current_frame - (new_page/2);
1167 leftmost_after_zoom = 0;
1173 // leftmost_after_zoom = min (leftmost_after_zoom, session->current_end_frame());
1175 // begin_reversible_command (_("zoom"));
1176 // session->add_undo (bind (mem_fun(*this, &Editor::reposition_and_zoom), current_leftmost, frames_per_unit));
1177 // session->add_redo (bind (mem_fun(*this, &Editor::reposition_and_zoom), leftmost_after_zoom, nfpu));
1178 // commit_reversible_command ();
1180 reposition_and_zoom (leftmost_after_zoom, nfpu);
1184 Editor::temporal_zoom_selection ()
1186 if (!selection) return;
1188 if (selection->time.empty()) {
1192 jack_nframes_t start = selection->time[clicked_selection].start;
1193 jack_nframes_t end = selection->time[clicked_selection].end;
1195 temporal_zoom_by_frame (start, end, "zoom to selection");
1199 Editor::temporal_zoom_session ()
1201 ENSURE_GUI_THREAD (mem_fun (*this, &Editor::temporal_zoom_session));
1204 temporal_zoom_by_frame (session->current_start_frame(), session->current_end_frame(), "zoom to session");
1209 Editor::temporal_zoom_by_frame (jack_nframes_t start, jack_nframes_t end, const string & op)
1211 if (!session) return;
1213 if ((start == 0 && end == 0) || end < start) {
1217 jack_nframes_t range = end - start;
1219 double new_fpu = (double)range / (double)canvas_width;
1222 // while (p2 < new_fpu) {
1227 jack_nframes_t new_page = (jack_nframes_t) floor (canvas_width * new_fpu);
1228 jack_nframes_t middle = (jack_nframes_t) floor( (double)start + ((double)range / 2.0f ));
1229 jack_nframes_t new_leftmost = (jack_nframes_t) floor( (double)middle - ((double)new_page/2.0f));
1231 if (new_leftmost > middle) new_leftmost = 0;
1233 // begin_reversible_command (op);
1234 // session->add_undo (bind (mem_fun(*this, &Editor::reposition_and_zoom), leftmost_frame, frames_per_unit));
1235 // session->add_redo (bind (mem_fun(*this, &Editor::reposition_and_zoom), new_leftmost, new_fpu));
1236 // commit_reversible_command ();
1238 reposition_and_zoom (new_leftmost, new_fpu);
1242 Editor::temporal_zoom_to_frame (bool coarser, jack_nframes_t frame)
1244 if (!session) return;
1246 jack_nframes_t range_before = frame - leftmost_frame;
1249 new_fpu = frames_per_unit;
1255 new_fpu = max(1.0,(new_fpu/2.0));
1259 if (new_fpu == frames_per_unit) return;
1261 jack_nframes_t new_leftmost = frame - range_before;
1263 if (new_leftmost > frame) new_leftmost = 0;
1265 // begin_reversible_command (_("zoom to frame"));
1266 // session->add_undo (bind (mem_fun(*this, &Editor::reposition_and_zoom), leftmost_frame, frames_per_unit));
1267 // session->add_redo (bind (mem_fun(*this, &Editor::reposition_and_zoom), new_leftmost, new_fpu));
1268 // commit_reversible_command ();
1270 reposition_and_zoom (new_leftmost, new_fpu);
1274 Editor::add_location_from_selection ()
1276 if (selection->time.empty()) {
1280 if (session == 0 || clicked_trackview == 0) {
1284 jack_nframes_t start = selection->time[clicked_selection].start;
1285 jack_nframes_t end = selection->time[clicked_selection].end;
1287 Location *location = new Location (start, end, "selection");
1289 session->begin_reversible_command (_("add marker"));
1290 session->add_undo (session->locations()->get_memento());
1291 session->locations()->add (location, true);
1292 session->add_redo_no_execute (session->locations()->get_memento());
1293 session->commit_reversible_command ();
1297 Editor::add_location_from_playhead_cursor ()
1299 jack_nframes_t where = session->audible_frame();
1301 Location *location = new Location (where, where, "mark", Location::IsMark);
1302 session->begin_reversible_command (_("add marker"));
1303 session->add_undo (session->locations()->get_memento());
1304 session->locations()->add (location, true);
1305 session->add_redo_no_execute (session->locations()->get_memento());
1306 session->commit_reversible_command ();
1310 Editor::add_location_from_audio_region ()
1312 if (selection->audio_regions.empty()) {
1316 AudioRegionView* rv = *(selection->audio_regions.begin());
1317 Region& region = rv->region;
1319 Location *location = new Location (region.position(), region.last_frame(), region.name());
1320 session->begin_reversible_command (_("add marker"));
1321 session->add_undo (session->locations()->get_memento());
1322 session->locations()->add (location, true);
1323 session->add_redo_no_execute (session->locations()->get_memento());
1324 session->commit_reversible_command ();
1328 Editor::select_all_in_track (Selection::Operation op)
1330 list<Selectable *> touched;
1332 if (!clicked_trackview) {
1336 clicked_trackview->get_selectables (0, max_frames, 0, DBL_MAX, touched);
1339 case Selection::Toggle:
1340 selection->add (touched);
1342 case Selection::Set:
1343 selection->set (touched);
1345 case Selection::Extend:
1346 /* not defined yet */
1352 Editor::select_all (Selection::Operation op)
1354 list<Selectable *> touched;
1356 for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
1357 if ((*iter)->hidden()) {
1360 (*iter)->get_selectables (0, max_frames, 0, DBL_MAX, touched);
1362 begin_reversible_command (_("select all"));
1364 case Selection::Toggle:
1365 selection->add (touched);
1367 case Selection::Set:
1368 selection->set (touched);
1370 case Selection::Extend:
1371 /* not defined yet */
1374 commit_reversible_command ();
1378 Editor::invert_selection_in_track ()
1380 list<Selectable *> touched;
1382 if (!clicked_trackview) {
1386 clicked_trackview->get_inverted_selectables (*selection, touched);
1387 selection->set (touched);
1391 Editor::invert_selection ()
1393 list<Selectable *> touched;
1395 for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
1396 if ((*iter)->hidden()) {
1399 (*iter)->get_inverted_selectables (*selection, touched);
1402 selection->set (touched);
1406 Editor::select_all_within (jack_nframes_t start, jack_nframes_t end, double top, double bot, Selection::Operation op)
1408 list<Selectable *> touched;
1410 for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
1411 if ((*iter)->hidden()) {
1414 (*iter)->get_selectables (start, end, top, bot, touched);
1417 cerr << "select all within found " << touched.size() << endl;
1419 begin_reversible_command (_("select all within"));
1421 case Selection::Toggle:
1423 selection->add (touched);
1425 case Selection::Set:
1427 selection->set (touched);
1429 case Selection::Extend:
1431 /* not defined yet */
1435 cerr << "selection now has " << selection->points.size() << endl;
1437 commit_reversible_command ();
1438 return !touched.empty();
1442 Editor::set_selection_from_audio_region ()
1444 if (selection->audio_regions.empty()) {
1448 AudioRegionView* rv = *(selection->audio_regions.begin());
1449 Region& region = rv->region;
1451 begin_reversible_command (_("set selection from region"));
1452 selection->set (0, region.position(), region.last_frame());
1453 commit_reversible_command ();
1455 set_mouse_mode (Editing::MouseRange, false);
1459 Editor::set_selection_from_punch()
1463 if ((location = session->locations()->auto_punch_location()) == 0) {
1467 set_selection_from_range (*location);
1471 Editor::set_selection_from_loop()
1475 if ((location = session->locations()->auto_loop_location()) == 0) {
1478 set_selection_from_range (*location);
1482 Editor::set_selection_from_range (Location& loc)
1484 begin_reversible_command (_("set selection from range"));
1485 selection->set (0, loc.start(), loc.end());
1486 commit_reversible_command ();
1488 set_mouse_mode (Editing::MouseRange, false);
1492 Editor::select_all_selectables_using_time_selection ()
1494 list<Selectable *> touched;
1496 if (selection->time.empty()) {
1500 jack_nframes_t start = selection->time[clicked_selection].start;
1501 jack_nframes_t end = selection->time[clicked_selection].end;
1503 if (end - start < 1) {
1507 for (TrackViewList::iterator iter = selection->tracks.begin(); iter != selection->tracks.end(); ++iter) {
1508 if ((*iter)->hidden()) {
1511 (*iter)->get_selectables (start, end - 1, 0, DBL_MAX, touched);
1514 begin_reversible_command (_("select all from range"));
1515 selection->set (touched);
1516 commit_reversible_command ();
1521 Editor::select_all_selectables_using_punch()
1523 Location* location = session->locations()->auto_punch_location();
1524 list<Selectable *> touched;
1526 if (location == 0 || (location->end() - location->start() <= 1)) {
1530 for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
1531 if ((*iter)->hidden()) {
1534 (*iter)->get_selectables (location->start(), location->end() - 1, 0, DBL_MAX, touched);
1536 begin_reversible_command (_("select all from punch"));
1537 selection->set (touched);
1538 commit_reversible_command ();
1543 Editor::select_all_selectables_using_loop()
1545 Location* location = session->locations()->auto_loop_location();
1546 list<Selectable *> touched;
1548 if (location == 0 || (location->end() - location->start() <= 1)) {
1552 for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
1553 if ((*iter)->hidden()) {
1556 (*iter)->get_selectables (location->start(), location->end() - 1, 0, DBL_MAX, touched);
1558 begin_reversible_command (_("select all from loop"));
1559 selection->set (touched);
1560 commit_reversible_command ();
1565 Editor::select_all_selectables_using_cursor (Cursor *cursor, bool after)
1567 jack_nframes_t start;
1569 list<Selectable *> touched;
1572 begin_reversible_command (_("select all after cursor"));
1573 start = cursor->current_frame ;
1574 end = session->current_end_frame();
1576 if (cursor->current_frame > 0) {
1577 begin_reversible_command (_("select all before cursor"));
1579 end = cursor->current_frame - 1;
1585 for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
1586 if ((*iter)->hidden()) {
1589 (*iter)->get_selectables (start, end, 0, DBL_MAX, touched);
1591 selection->set (touched);
1592 commit_reversible_command ();
1596 Editor::select_all_selectables_between_cursors (Cursor *cursor, Cursor *other_cursor)
1598 jack_nframes_t start;
1600 list<Selectable *> touched;
1601 bool other_cursor_is_first = cursor->current_frame > other_cursor->current_frame;
1603 if (cursor->current_frame == other_cursor->current_frame) {
1607 begin_reversible_command (_("select all between cursors"));
1608 if (other_cursor_is_first) {
1609 start = other_cursor->current_frame;
1610 end = cursor->current_frame - 1;
1613 start = cursor->current_frame;
1614 end = other_cursor->current_frame - 1;
1617 for (TrackViewList::iterator iter = track_views.begin(); iter != track_views.end(); ++iter) {
1618 if ((*iter)->hidden()) {
1621 (*iter)->get_selectables (start, end, 0, DBL_MAX, touched);
1623 selection->set (touched);
1624 commit_reversible_command ();
1628 Editor::amplitude_zoom_step (bool in)
1642 #ifdef FIX_FOR_CANVAS
1643 /* XXX DO SOMETHING */
1652 Editor::delete_sample_forward ()
1657 Editor::delete_sample_backward ()
1662 Editor::delete_screen ()
1669 Editor::search_backwards ()
1675 Editor::search_forwards ()
1683 Editor::jump_forward_to_mark ()
1689 Location *location = session->locations()->first_location_after (playhead_cursor->current_frame);
1692 session->request_locate (location->start(), session->transport_rolling());
1694 session->request_locate (session->current_end_frame());
1699 Editor::jump_backward_to_mark ()
1705 Location *location = session->locations()->first_location_before (playhead_cursor->current_frame);
1708 session->request_locate (location->start(), session->transport_rolling());
1710 session->goto_start ();
1721 if (get_prefix (prefix, was_floating)) {
1722 pos = session->audible_frame ();
1725 pos = (jack_nframes_t) floor (prefix * session->frame_rate ());
1727 pos = (jack_nframes_t) floor (prefix);
1731 session->locations()->add (new Location (pos, 0, "mark", Location::IsMark), true);
1735 Editor::clear_markers ()
1738 session->begin_reversible_command (_("clear markers"));
1739 session->add_undo (session->locations()->get_memento());
1740 session->locations()->clear_markers ();
1741 session->add_redo_no_execute (session->locations()->get_memento());
1742 session->commit_reversible_command ();
1747 Editor::clear_ranges ()
1750 session->begin_reversible_command (_("clear ranges"));
1751 session->add_undo (session->locations()->get_memento());
1753 Location * looploc = session->locations()->auto_loop_location();
1754 Location * punchloc = session->locations()->auto_punch_location();
1756 session->locations()->clear_ranges ();
1758 if (looploc) session->locations()->add (looploc);
1759 if (punchloc) session->locations()->add (punchloc);
1761 session->add_redo_no_execute (session->locations()->get_memento());
1762 session->commit_reversible_command ();
1767 Editor::clear_locations ()
1769 session->begin_reversible_command (_("clear locations"));
1770 session->add_undo (session->locations()->get_memento());
1771 session->locations()->clear ();
1772 session->add_redo_no_execute (session->locations()->get_memento());
1773 session->commit_reversible_command ();
1774 session->locations()->clear ();
1777 /* INSERT/REPLACE */
1780 Editor::insert_region_list_drag (AudioRegion& region, int x, int y)
1785 jack_nframes_t where;
1786 AudioTimeAxisView *atv = 0;
1789 track_canvas.window_to_world (x, y, wx, wy);
1790 wx += horizontal_adjustment.get_value();
1791 wy += vertical_adjustment.get_value();
1794 event.type = GDK_BUTTON_RELEASE;
1795 event.button.x = wx;
1796 event.button.y = wy;
1798 where = event_frame (&event, &cx, &cy);
1800 if (where < leftmost_frame || where > leftmost_frame + current_page_frames()) {
1801 /* clearly outside canvas area */
1805 if ((tv = trackview_by_y_position (cy)) == 0) {
1809 if ((atv = dynamic_cast<AudioTimeAxisView*>(tv)) == 0) {
1813 if ((playlist = atv->playlist()) == 0) {
1819 begin_reversible_command (_("insert dragged region"));
1820 session->add_undo (playlist->get_memento());
1821 playlist->add_region (*(new AudioRegion (region)), where, 1.0);
1822 session->add_redo_no_execute (playlist->get_memento());
1823 commit_reversible_command ();
1827 Editor::insert_region_list_selection (float times)
1829 AudioTimeAxisView *tv = 0;
1832 if (clicked_audio_trackview != 0) {
1833 tv = clicked_audio_trackview;
1834 } else if (!selection->tracks.empty()) {
1835 if ((tv = dynamic_cast<AudioTimeAxisView*>(selection->tracks.front())) == 0) {
1842 if ((playlist = tv->playlist()) == 0) {
1846 Glib::RefPtr<TreeSelection> selected = region_list_display.get_selection();
1848 if (selected->count_selected_rows() != 1) {
1852 TreeModel::iterator i = region_list_display.get_selection()->get_selected();
1853 Region* region = (*i)[region_list_columns.region];
1855 begin_reversible_command (_("insert region"));
1856 session->add_undo (playlist->get_memento());
1857 playlist->add_region (*(createRegion (*region)), edit_cursor->current_frame, times);
1858 session->add_redo_no_execute (playlist->get_memento());
1859 commit_reversible_command ();
1863 /* BUILT-IN EFFECTS */
1866 Editor::reverse_selection ()
1871 /* GAIN ENVELOPE EDITING */
1874 Editor::edit_envelope ()
1881 Editor::toggle_playback (bool with_abort)
1887 switch (session->slave_source()) {
1892 /* transport controlled by the master */
1896 if (session->is_auditioning()) {
1897 session->cancel_audition ();
1901 if (session->transport_rolling()) {
1902 session->request_stop (with_abort);
1903 if (session->get_auto_loop()) {
1904 session->request_auto_loop (false);
1907 session->request_transport_speed (1.0f);
1912 Editor::play_from_start ()
1914 session->request_locate (session->current_start_frame(), true);
1918 Editor::play_selection ()
1920 if (selection->time.empty()) {
1924 session->request_play_range (true);
1928 Editor::play_selected_region ()
1930 if (!selection->audio_regions.empty()) {
1931 AudioRegionView *rv = *(selection->audio_regions.begin());
1933 session->request_bounded_roll (rv->region.position(), rv->region.last_frame());
1938 Editor::loop_selected_region ()
1940 if (!selection->audio_regions.empty()) {
1941 AudioRegionView *rv = *(selection->audio_regions.begin());
1944 if ((tll = transport_loop_location()) != 0) {
1946 tll->set (rv->region.position(), rv->region.last_frame());
1948 // enable looping, reposition and start rolling
1950 session->request_auto_loop (true);
1951 session->request_locate (tll->start(), false);
1952 session->request_transport_speed (1.0f);
1958 Editor::play_location (Location& location)
1960 if (location.start() <= location.end()) {
1964 session->request_bounded_roll (location.start(), location.end());
1968 Editor::loop_location (Location& location)
1970 if (location.start() <= location.end()) {
1976 if ((tll = transport_loop_location()) != 0) {
1977 tll->set (location.start(), location.end());
1979 // enable looping, reposition and start rolling
1980 session->request_auto_loop (true);
1981 session->request_locate (tll->start(), true);
1986 Editor::toggle_region_mute ()
1988 if (clicked_regionview) {
1989 clicked_regionview->region.set_muted (!clicked_regionview->region.muted());
1990 } else if (!selection->audio_regions.empty()) {
1991 bool yn = ! (*selection->audio_regions.begin())->region.muted();
1992 selection->foreach_audio_region (&AudioRegion::set_muted, yn);
1997 Editor::toggle_region_opaque ()
1999 if (clicked_regionview) {
2000 clicked_regionview->region.set_opaque (!clicked_regionview->region.opaque());
2001 } else if (!selection->audio_regions.empty()) {
2002 bool yn = ! (*selection->audio_regions.begin())->region.opaque();
2003 selection->foreach_audio_region (&Region::set_opaque, yn);
2008 Editor::raise_region ()
2010 selection->foreach_audio_region (&Region::raise);
2014 Editor::raise_region_to_top ()
2016 selection->foreach_audio_region (&Region::raise_to_top);
2020 Editor::lower_region ()
2022 selection->foreach_audio_region (&Region::lower);
2026 Editor::lower_region_to_bottom ()
2028 selection->foreach_audio_region (&Region::lower_to_bottom);
2032 Editor::edit_region ()
2034 if (clicked_regionview == 0) {
2038 clicked_regionview->show_region_editor ();
2042 Editor::rename_region ()
2046 Button ok_button (_("OK"));
2047 Button cancel_button (_("Cancel"));
2049 if (selection->audio_regions.empty()) {
2053 dialog.set_title (_("ardour: rename region"));
2054 dialog.set_name ("RegionRenameWindow");
2055 dialog.set_size_request (300, -1);
2056 dialog.set_position (Gtk::WIN_POS_MOUSE);
2057 dialog.set_modal (true);
2059 dialog.get_vbox()->set_border_width (10);
2060 dialog.get_vbox()->pack_start (entry);
2061 dialog.get_action_area()->pack_start (ok_button);
2062 dialog.get_action_area()->pack_start (cancel_button);
2064 entry.set_name ("RegionNameDisplay");
2065 ok_button.set_name ("EditorGTKButton");
2066 cancel_button.set_name ("EditorGTKButton");
2068 region_renamed = false;
2070 entry.signal_activate().connect (bind (mem_fun(*this, &Editor::rename_region_finished), true));
2071 ok_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::rename_region_finished), true));
2072 cancel_button.signal_clicked().connect (bind (mem_fun(*this, &Editor::rename_region_finished), false));
2079 if (region_renamed) {
2080 (*selection->audio_regions.begin())->region.set_name (entry.get_text());
2081 redisplay_regions ();
2086 Editor::rename_region_finished (bool status)
2089 region_renamed = status;
2094 Editor::audition_playlist_region_via_route (AudioRegion& region, Route& route)
2096 if (session->is_auditioning()) {
2097 session->cancel_audition ();
2100 // note: some potential for creativity here, because region doesn't
2101 // have to belong to the playlist that Route is handling
2103 // bool was_soloed = route.soloed();
2105 route.set_solo (true, this);
2107 session->request_bounded_roll (region.position(), region.position() + region.length());
2109 /* XXX how to unset the solo state ? */
2113 Editor::audition_selected_region ()
2115 if (!selection->audio_regions.empty()) {
2116 AudioRegionView* rv = *(selection->audio_regions.begin());
2117 session->audition_region (rv->region);
2122 Editor::audition_playlist_region_standalone (AudioRegion& region)
2124 session->audition_region (region);
2128 Editor::build_interthread_progress_window ()
2130 interthread_progress_window = new ArdourDialog (X_("interthread progress"), true);
2132 interthread_progress_bar.set_orientation (Gtk::PROGRESS_LEFT_TO_RIGHT);
2134 interthread_progress_window->get_vbox()->pack_start (interthread_progress_label, false, false);
2135 interthread_progress_window->get_vbox()->pack_start (interthread_progress_bar,false, false);
2137 // GTK2FIX: this button needs a modifiable label
2139 Button* b = interthread_progress_window->add_button (Stock::CANCEL, RESPONSE_CANCEL);
2140 b->signal_clicked().connect (mem_fun(*this, &Editor::interthread_cancel_clicked));
2142 interthread_cancel_button.add (interthread_cancel_label);
2144 interthread_progress_window->set_default_size (200, 100);
2148 Editor::interthread_cancel_clicked ()
2150 if (current_interthread_info) {
2151 current_interthread_info->cancel = true;
2156 Editor::region_from_selection ()
2158 if (clicked_trackview == 0) {
2162 if (selection->time.empty()) {
2166 jack_nframes_t start = selection->time[clicked_selection].start;
2167 jack_nframes_t end = selection->time[clicked_selection].end;
2169 jack_nframes_t selection_cnt = end - start + 1;
2171 for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
2173 AudioRegion *region;
2174 AudioRegion *current;
2178 jack_nframes_t internal_start;
2181 if ((pl = (*i)->playlist()) == 0) {
2185 if ((current_r = pl->top_region_at (start)) == 0) {
2189 if ((current = dynamic_cast<AudioRegion*> (current_r)) != 0) {
2190 internal_start = start - current->position();
2191 session->region_name (new_name, current->name(), true);
2192 region = new AudioRegion (*current, internal_start, selection_cnt, new_name);
2198 Editor::create_region_from_selection (vector<AudioRegion *>& new_regions)
2200 if (selection->time.empty() || selection->tracks.empty()) {
2204 jack_nframes_t start = selection->time[clicked_selection].start;
2205 jack_nframes_t end = selection->time[clicked_selection].end;
2207 for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
2209 AudioRegion* current;
2212 jack_nframes_t internal_start;
2215 if ((playlist = (*i)->playlist()) == 0) {
2219 if ((current_r = playlist->top_region_at(start)) == 0) {
2223 if ((current = dynamic_cast<AudioRegion*>(current_r)) == 0) {
2227 internal_start = start - current->position();
2228 session->region_name (new_name, current->name(), true);
2230 new_regions.push_back (new AudioRegion (*current, internal_start, end - start + 1, new_name));
2235 Editor::split_multichannel_region ()
2237 vector<AudioRegion*> v;
2239 if (!clicked_regionview || clicked_regionview->region.n_channels() < 2) {
2243 clicked_regionview->region.separate_by_channel (*session, v);
2245 /* nothing else to do, really */
2249 Editor::new_region_from_selection ()
2251 region_from_selection ();
2252 cancel_selection ();
2256 Editor::separate_region_from_selection ()
2258 bool doing_undo = false;
2260 if (selection->time.empty()) {
2266 for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
2268 AudioTimeAxisView* atv;
2270 if ((atv = dynamic_cast<AudioTimeAxisView*> ((*i))) != 0) {
2272 if (atv->is_audio_track()) {
2274 if ((playlist = atv->playlist()) != 0) {
2276 begin_reversible_command (_("separate"));
2279 if (doing_undo) session->add_undo ((playlist)->get_memento());
2281 /* XXX need to consider musical time selections here at some point */
2283 double speed = atv->get_diskstream()->speed();
2285 for (list<AudioRange>::iterator t = selection->time.begin(); t != selection->time.end(); ++t) {
2286 playlist->partition ((jack_nframes_t)((*t).start * speed), (jack_nframes_t)((*t).end * speed), true);
2289 if (doing_undo) session->add_redo_no_execute (playlist->get_memento());
2295 if (doing_undo) commit_reversible_command ();
2299 Editor::separate_regions_using_location (Location& loc)
2301 bool doing_undo = false;
2303 if (loc.is_mark()) {
2309 /* XXX i'm unsure as to whether this should operate on selected tracks only
2310 or the entire enchillada. uncomment the below line to correct the behaviour
2311 (currently set for all tracks)
2314 for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
2315 //for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
2317 AudioTimeAxisView* atv;
2319 if ((atv = dynamic_cast<AudioTimeAxisView*> ((*i))) != 0) {
2321 if (atv->is_audio_track()) {
2323 if ((playlist = atv->playlist()) != 0) {
2325 begin_reversible_command (_("separate"));
2328 if (doing_undo) session->add_undo ((playlist)->get_memento());
2330 /* XXX need to consider musical time selections here at some point */
2332 double speed = atv->get_diskstream()->speed();
2335 playlist->partition ((jack_nframes_t)(loc.start() * speed), (jack_nframes_t)(loc.end() * speed), true);
2336 if (doing_undo) session->add_redo_no_execute (playlist->get_memento());
2342 if (doing_undo) commit_reversible_command ();
2346 Editor::crop_region_to_selection ()
2348 if (selection->time.empty()) {
2352 vector<Playlist*> playlists;
2355 if (clicked_trackview != 0) {
2357 if ((playlist = clicked_trackview->playlist()) == 0) {
2361 playlists.push_back (playlist);
2365 for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
2367 AudioTimeAxisView* atv;
2369 if ((atv = dynamic_cast<AudioTimeAxisView*> ((*i))) != 0) {
2371 if (atv->is_audio_track()) {
2373 if ((playlist = atv->playlist()) != 0) {
2374 playlists.push_back (playlist);
2381 if (!playlists.empty()) {
2383 jack_nframes_t start;
2387 begin_reversible_command (_("trim to selection"));
2389 for (vector<Playlist*>::iterator i = playlists.begin(); i != playlists.end(); ++i) {
2393 start = selection->time.start();
2395 if ((region = (*i)->top_region_at(start)) == 0) {
2399 /* now adjust lengths to that we do the right thing
2400 if the selection extends beyond the region
2403 start = max (start, region->position());
2404 end = min (selection->time.end_frame(), start + region->length() - 1);
2405 cnt = end - start + 1;
2407 session->add_undo ((*i)->get_memento());
2408 region->trim_to (start, cnt, this);
2409 session->add_redo_no_execute ((*i)->get_memento());
2412 commit_reversible_command ();
2417 Editor::region_fill_track ()
2421 if (!session || selection->audio_regions.empty()) {
2425 end = session->current_end_frame ();
2427 begin_reversible_command (_("region fill"));
2429 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
2431 AudioRegion& region ((*i)->region);
2432 Playlist* pl = region.playlist();
2434 if (end <= region.last_frame()) {
2438 double times = (double) (end - region.last_frame()) / (double) region.length();
2444 session->add_undo (pl->get_memento());
2445 pl->add_region (*(new AudioRegion (region)), region.last_frame(), times);
2446 session->add_redo_no_execute (pl->get_memento());
2449 commit_reversible_command ();
2453 Editor::region_fill_selection ()
2455 if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_audio_track()) {
2459 if (selection->time.empty()) {
2465 Glib::RefPtr<TreeSelection> selected = region_list_display.get_selection();
2467 if (selected->count_selected_rows() != 1) {
2471 TreeModel::iterator i = region_list_display.get_selection()->get_selected();
2472 region = (*i)[region_list_columns.region];
2474 jack_nframes_t start = selection->time[clicked_selection].start;
2475 jack_nframes_t end = selection->time[clicked_selection].end;
2479 if (selection->tracks.empty()) {
2483 jack_nframes_t selection_length = end - start;
2484 float times = (float)selection_length / region->length();
2486 begin_reversible_command (_("fill selection"));
2488 for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
2490 if ((playlist = (*i)->playlist()) == 0) {
2494 session->add_undo (playlist->get_memento());
2495 playlist->add_region (*(createRegion (*region)), start, times);
2496 session->add_redo_no_execute (playlist->get_memento());
2499 commit_reversible_command ();
2503 Editor::set_a_regions_sync_position (Region& region, jack_nframes_t position)
2506 if (!region.covers (position)) {
2507 error << _("Programming error. that region doesn't cover that position") << __FILE__ << " +" << __LINE__ << endmsg;
2510 begin_reversible_command (_("set region sync position"));
2511 session->add_undo (region.playlist()->get_memento());
2512 region.set_sync_position (position);
2513 session->add_redo_no_execute (region.playlist()->get_memento());
2514 commit_reversible_command ();
2518 Editor::set_region_sync_from_edit_cursor ()
2520 if (clicked_regionview == 0) {
2524 if (!clicked_regionview->region.covers (edit_cursor->current_frame)) {
2525 error << _("Place the edit cursor at the desired sync point") << endmsg;
2529 Region& region (clicked_regionview->region);
2530 begin_reversible_command (_("set sync from edit cursor"));
2531 session->add_undo (region.playlist()->get_memento());
2532 region.set_sync_position (edit_cursor->current_frame);
2533 session->add_redo_no_execute (region.playlist()->get_memento());
2534 commit_reversible_command ();
2538 Editor::remove_region_sync ()
2540 if (clicked_regionview) {
2541 Region& region (clicked_regionview->region);
2542 begin_reversible_command (_("remove sync"));
2543 session->add_undo (region.playlist()->get_memento());
2544 region.clear_sync_position ();
2545 session->add_redo_no_execute (region.playlist()->get_memento());
2546 commit_reversible_command ();
2551 Editor::naturalize ()
2553 if (selection->audio_regions.empty()) {
2556 begin_reversible_command (_("naturalize"));
2557 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
2558 session->add_undo ((*i)->region.get_memento());
2559 (*i)->region.move_to_natural_position (this);
2560 session->add_redo_no_execute ((*i)->region.get_memento());
2562 commit_reversible_command ();
2566 Editor::align (RegionPoint what)
2568 align_selection (what, edit_cursor->current_frame);
2572 Editor::align_relative (RegionPoint what)
2574 align_selection_relative (what, edit_cursor->current_frame);
2577 struct RegionSortByTime {
2578 bool operator() (const AudioRegionView* a, const AudioRegionView* b) {
2579 return a->region.position() < b->region.position();
2584 Editor::align_selection_relative (RegionPoint point, jack_nframes_t position)
2586 if (selection->audio_regions.empty()) {
2590 jack_nframes_t distance;
2591 jack_nframes_t pos = 0;
2594 list<AudioRegionView*> sorted;
2595 selection->audio_regions.by_position (sorted);
2596 Region& r ((*sorted.begin())->region);
2600 pos = r.first_frame ();
2604 pos = r.last_frame();
2608 pos = r.adjust_to_sync (r.first_frame());
2612 if (pos > position) {
2613 distance = pos - position;
2616 distance = position - pos;
2620 begin_reversible_command (_("align selection (relative)"));
2622 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
2624 Region& region ((*i)->region);
2626 session->add_undo (region.playlist()->get_memento());
2629 region.set_position (region.position() + distance, this);
2631 region.set_position (region.position() - distance, this);
2634 session->add_redo_no_execute (region.playlist()->get_memento());
2638 commit_reversible_command ();
2642 Editor::align_selection (RegionPoint point, jack_nframes_t position)
2644 if (selection->audio_regions.empty()) {
2648 begin_reversible_command (_("align selection"));
2650 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
2651 align_region_internal ((*i)->region, point, position);
2654 commit_reversible_command ();
2658 Editor::align_region (Region& region, RegionPoint point, jack_nframes_t position)
2660 begin_reversible_command (_("align region"));
2661 align_region_internal (region, point, position);
2662 commit_reversible_command ();
2666 Editor::align_region_internal (Region& region, RegionPoint point, jack_nframes_t position)
2668 session->add_undo (region.playlist()->get_memento());
2672 region.set_position (region.adjust_to_sync (position), this);
2676 if (position > region.length()) {
2677 region.set_position (position - region.length(), this);
2682 region.set_position (position, this);
2686 session->add_redo_no_execute (region.playlist()->get_memento());
2690 Editor::trim_region_to_edit_cursor ()
2692 if (clicked_regionview == 0) {
2696 Region& region (clicked_regionview->region);
2699 AudioTimeAxisView *atav;
2701 if ( clicked_trackview != 0 && (atav = dynamic_cast<AudioTimeAxisView*>(clicked_trackview)) != 0 ) {
2702 if (atav->get_diskstream() != 0) {
2703 speed = atav->get_diskstream()->speed();
2707 begin_reversible_command (_("trim to edit"));
2708 session->add_undo (region.playlist()->get_memento());
2709 region.trim_end( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
2710 session->add_redo_no_execute (region.playlist()->get_memento());
2711 commit_reversible_command ();
2715 Editor::trim_region_from_edit_cursor ()
2717 if (clicked_regionview == 0) {
2721 Region& region (clicked_regionview->region);
2724 AudioTimeAxisView *atav;
2726 if ( clicked_trackview != 0 && (atav = dynamic_cast<AudioTimeAxisView*>(clicked_trackview)) != 0 ) {
2727 if (atav->get_diskstream() != 0) {
2728 speed = atav->get_diskstream()->speed();
2732 begin_reversible_command (_("trim to edit"));
2733 session->add_undo (region.playlist()->get_memento());
2734 region.trim_front ( session_frame_to_track_frame(edit_cursor->current_frame, speed), this);
2735 session->add_redo_no_execute (region.playlist()->get_memento());
2736 commit_reversible_command ();
2740 Editor::unfreeze_route ()
2742 if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_audio_track()) {
2746 clicked_audio_trackview->audio_track()->unfreeze ();
2750 Editor::_freeze_thread (void* arg)
2752 PBD::ThreadCreated (pthread_self(), X_("Freeze"));
2753 return static_cast<Editor*>(arg)->freeze_thread ();
2757 Editor::freeze_thread ()
2759 clicked_audio_trackview->audio_track()->freeze (*current_interthread_info);
2764 Editor::freeze_progress_timeout (void *arg)
2766 interthread_progress_bar.set_fraction (current_interthread_info->progress/100);
2767 return !(current_interthread_info->done || current_interthread_info->cancel);
2771 Editor::freeze_route ()
2773 if (clicked_audio_trackview == 0 || !clicked_audio_trackview->is_audio_track()) {
2777 InterThreadInfo itt;
2779 if (interthread_progress_window == 0) {
2780 build_interthread_progress_window ();
2783 interthread_progress_window->set_title (_("ardour: freeze"));
2784 interthread_progress_window->set_position (Gtk::WIN_POS_MOUSE);
2785 interthread_progress_window->show_all ();
2786 interthread_progress_bar.set_fraction (0.0f);
2787 interthread_progress_label.set_text ("");
2788 interthread_cancel_label.set_text (_("Cancel Freeze"));
2789 current_interthread_info = &itt;
2791 interthread_progress_connection =
2792 Glib::signal_timeout().connect (bind (mem_fun(*this, &Editor::freeze_progress_timeout), (gpointer) 0), 100);
2796 itt.progress = 0.0f;
2798 pthread_create (&itt.thread, 0, _freeze_thread, this);
2800 track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
2802 while (!itt.done && !itt.cancel) {
2803 gtk_main_iteration ();
2806 interthread_progress_connection.disconnect ();
2807 interthread_progress_window->hide_all ();
2808 current_interthread_info = 0;
2809 track_canvas.get_window()->set_cursor (*current_canvas_cursor);
2813 Editor::bounce_range_selection ()
2815 if (selection->time.empty()) {
2819 TrackViewList *views = get_valid_views (selection->time.track, selection->time.group);
2821 jack_nframes_t start = selection->time[clicked_selection].start;
2822 jack_nframes_t end = selection->time[clicked_selection].end;
2823 jack_nframes_t cnt = end - start + 1;
2825 begin_reversible_command (_("bounce range"));
2827 for (TrackViewList::iterator i = views->begin(); i != views->end(); ++i) {
2829 AudioTimeAxisView* atv;
2831 if ((atv = dynamic_cast<AudioTimeAxisView*> (*i)) == 0) {
2837 if ((playlist = atv->playlist()) == 0) {
2841 InterThreadInfo itt;
2845 itt.progress = false;
2847 session->add_undo (playlist->get_memento());
2848 atv->audio_track()->bounce_range (start, cnt, itt);
2849 session->add_redo_no_execute (playlist->get_memento());
2852 commit_reversible_command ();
2870 Editor::cut_copy (CutCopyOp op)
2872 /* only cancel selection if cut/copy is successful.*/
2884 opname = _("clear");
2888 cut_buffer->clear ();
2890 switch (current_mouse_mode()) {
2892 if (!selection->audio_regions.empty() || !selection->points.empty()) {
2894 begin_reversible_command (opname + _(" objects"));
2896 if (!selection->audio_regions.empty()) {
2898 cut_copy_regions (op);
2901 selection->clear_audio_regions ();
2905 if (!selection->points.empty()) {
2906 cut_copy_points (op);
2909 selection->clear_points ();
2913 commit_reversible_command ();
2918 if (!selection->time.empty()) {
2920 begin_reversible_command (opname + _(" range"));
2921 cut_copy_ranges (op);
2922 commit_reversible_command ();
2925 selection->clear_time ();
2937 Editor::cut_copy_points (CutCopyOp op)
2939 for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
2941 AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>(&(*i).track);
2944 atv->cut_copy_clear_objects (selection->points, op);
2950 Editor::cut_copy_regions (CutCopyOp op)
2952 typedef std::map<AudioPlaylist*,AudioPlaylist*> PlaylistMapping;
2953 PlaylistMapping pmap;
2954 jack_nframes_t first_position = max_frames;
2955 set<Playlist*> freezelist;
2956 pair<set<Playlist*>::iterator,bool> insert_result;
2958 for (AudioRegionSelection::iterator x = selection->audio_regions.begin(); x != selection->audio_regions.end(); ++x) {
2959 first_position = min ((*x)->region.position(), first_position);
2961 if (op == Cut || op == Clear) {
2962 AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region.playlist());
2964 insert_result = freezelist.insert (pl);
2965 if (insert_result.second) {
2967 session->add_undo (pl->get_memento());
2973 for (AudioRegionSelection::iterator x = selection->audio_regions.begin(); x != selection->audio_regions.end(); ) {
2975 AudioPlaylist *pl = dynamic_cast<AudioPlaylist*>((*x)->region.playlist());
2977 AudioRegionSelection::iterator tmp;
2984 PlaylistMapping::iterator pi = pmap.find (pl);
2986 if (pi == pmap.end()) {
2987 npl = new AudioPlaylist (*session, "cutlist", true);
2996 npl->add_region (*(new AudioRegion ((*x)->region)), (*x)->region.position() - first_position);
2997 pl->remove_region (&((*x)->region));
3001 npl->add_region (*(new AudioRegion ((*x)->region)), (*x)->region.position() - first_position);
3005 pl->remove_region (&((*x)->region));
3013 list<Playlist*> foo;
3015 for (PlaylistMapping::iterator i = pmap.begin(); i != pmap.end(); ++i) {
3016 foo.push_back (i->second);
3020 cut_buffer->set (foo);
3023 for (set<Playlist*>::iterator pl = freezelist.begin(); pl != freezelist.end(); ++pl) {
3025 session->add_redo_no_execute ((*pl)->get_memento());
3030 Editor::cut_copy_ranges (CutCopyOp op)
3032 for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
3033 (*i)->cut_copy_clear (*selection, op);
3038 Editor::paste (float times)
3040 paste_internal (edit_cursor->current_frame, times);
3044 Editor::mouse_paste ()
3049 track_canvas.get_pointer (x, y);
3050 track_canvas.window_to_world (x, y, wx, wy);
3051 wx += horizontal_adjustment.get_value();
3052 wy += vertical_adjustment.get_value();
3055 event.type = GDK_BUTTON_RELEASE;
3056 event.button.x = wx;
3057 event.button.y = wy;
3059 jack_nframes_t where = event_frame (&event, 0, 0);
3061 paste_internal (where, 1);
3065 Editor::paste_internal (jack_nframes_t position, float times)
3067 bool commit = false;
3069 if (cut_buffer->empty() || selection->tracks.empty()) {
3073 if (position == max_frames) {
3074 position = edit_cursor->current_frame;
3077 begin_reversible_command (_("paste"));
3079 TrackSelection::iterator i;
3082 for (nth = 0, i = selection->tracks.begin(); i != selection->tracks.end(); ++i, ++nth) {
3084 /* undo/redo is handled by individual tracks */
3086 if ((*i)->paste (position, times, *cut_buffer, nth)) {
3092 commit_reversible_command ();
3097 Editor::paste_named_selection (float times)
3099 TrackSelection::iterator t;
3101 Glib::RefPtr<TreeSelection> selected = named_selection_display.get_selection();
3103 if (selected->count_selected_rows() != 1 || selection->tracks.empty()) {
3107 TreeModel::iterator i = selected->get_selected();
3108 NamedSelection* ns = (*i)[named_selection_columns.selection];
3110 list<Playlist*>::iterator chunk;
3111 list<Playlist*>::iterator tmp;
3113 chunk = ns->playlists.begin();
3115 begin_reversible_command (_("paste chunk"));
3117 for (t = selection->tracks.begin(); t != selection->tracks.end(); ++t) {
3119 AudioTimeAxisView* atv;
3123 if ((atv = dynamic_cast<AudioTimeAxisView*> (*t)) == 0) {
3127 if ((pl = atv->playlist()) == 0) {
3131 if ((apl = dynamic_cast<AudioPlaylist*> (pl)) == 0) {
3138 session->add_undo (apl->get_memento());
3139 apl->paste (**chunk, edit_cursor->current_frame, times);
3140 session->add_redo_no_execute (apl->get_memento());
3142 if (tmp != ns->playlists.end()) {
3147 commit_reversible_command();
3151 Editor::duplicate_some_regions (AudioRegionSelection& regions, float times)
3154 AudioRegionSelection sel = regions; // clear (below) will clear the argument list
3156 begin_reversible_command (_("duplicate region"));
3158 selection->clear_audio_regions ();
3160 for (AudioRegionSelection::iterator i = sel.begin(); i != sel.end(); ++i) {
3162 Region& r ((*i)->region);
3164 TimeAxisView& tv = (*i)->get_time_axis_view();
3165 AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (&tv);
3166 sigc::connection c = atv->view->AudioRegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
3168 playlist = (*i)->region.playlist();
3169 session->add_undo (playlist->get_memento());
3170 playlist->duplicate (r, r.last_frame(), times);
3171 session->add_redo_no_execute (playlist->get_memento());
3175 if (latest_regionview) {
3176 selection->add (latest_regionview);
3181 commit_reversible_command ();
3185 Editor::duplicate_selection (float times)
3187 if (selection->time.empty() || selection->tracks.empty()) {
3192 vector<AudioRegion*> new_regions;
3193 vector<AudioRegion*>::iterator ri;
3195 create_region_from_selection (new_regions);
3197 if (new_regions.empty()) {
3201 begin_reversible_command (_("duplicate selection"));
3203 ri = new_regions.begin();
3205 for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
3206 if ((playlist = (*i)->playlist()) == 0) {
3209 session->add_undo (playlist->get_memento());
3210 playlist->duplicate (**ri, selection->time[clicked_selection].end, times);
3211 session->add_redo_no_execute (playlist->get_memento());
3214 if (ri == new_regions.end()) {
3219 commit_reversible_command ();
3223 Editor::reset_point_selection ()
3225 /* reset all selected points to the relevant default value */
3227 cerr << "point selection has " << selection->points.size() << " entries\n";
3229 for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
3231 AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>(&(*i).track);
3234 atv->reset_objects (selection->points);
3240 Editor::center_playhead ()
3242 float page = canvas_width * frames_per_unit;
3244 center_screen_internal (playhead_cursor->current_frame, page);
3248 Editor::center_edit_cursor ()
3250 float page = canvas_width * frames_per_unit;
3252 center_screen_internal (edit_cursor->current_frame, page);
3256 Editor::clear_playlist (Playlist& playlist)
3258 begin_reversible_command (_("clear playlist"));
3259 session->add_undo (playlist.get_memento());
3261 session->add_redo_no_execute (playlist.get_memento());
3262 commit_reversible_command ();
3266 Editor::nudge_track (bool use_edit_cursor, bool forwards)
3269 jack_nframes_t distance;
3270 jack_nframes_t next_distance;
3271 jack_nframes_t start;
3273 if (use_edit_cursor) {
3274 start = edit_cursor->current_frame;
3279 if ((distance = get_nudge_distance (start, next_distance)) == 0) {
3283 if (selection->tracks.empty()) {
3287 begin_reversible_command (_("nudge track"));
3289 for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
3291 if ((playlist = (*i)->playlist()) == 0) {
3295 session->add_undo (playlist->get_memento());
3296 playlist->nudge_after (start, distance, forwards);
3297 session->add_redo_no_execute (playlist->get_memento());
3300 commit_reversible_command ();
3304 Editor::remove_last_capture ()
3306 vector<string> choices;
3313 if (Config->get_verify_remove_last_capture()) {
3314 prompt = _("Do you really want to destroy the last capture?"
3315 "\n(This is destructive and cannot be undone)");
3317 choices.push_back (_("No, do nothing."));
3318 choices.push_back (_("Yes, destroy it."));
3320 Gtkmm2ext::Choice prompter (prompt, choices);
3322 if (prompter.run () == 1) {
3323 session->remove_last_capture ();
3327 session->remove_last_capture();
3332 Editor::normalize_region ()
3338 if (selection->audio_regions.empty()) {
3342 begin_reversible_command (_("normalize"));
3344 track_canvas.get_window()->set_cursor (*wait_cursor);
3347 for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ++r) {
3348 session->add_undo ((*r)->region.get_memento());
3349 (*r)->region.normalize_to (0.0f);
3350 session->add_redo_no_execute ((*r)->region.get_memento());
3353 commit_reversible_command ();
3354 track_canvas.get_window()->set_cursor (*current_canvas_cursor);
3359 Editor::denormalize_region ()
3365 if (selection->audio_regions.empty()) {
3369 begin_reversible_command ("denormalize");
3371 for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ++r) {
3372 session->add_undo ((*r)->region.get_memento());
3373 (*r)->region.set_scale_amplitude (1.0f);
3374 session->add_redo_no_execute ((*r)->region.get_memento());
3377 commit_reversible_command ();
3382 Editor::reverse_region ()
3388 Reverse rev (*session);
3389 apply_filter (rev, _("reverse regions"));
3393 Editor::apply_filter (AudioFilter& filter, string command)
3395 if (selection->audio_regions.empty()) {
3399 begin_reversible_command (command);
3401 track_canvas.get_window()->set_cursor (*wait_cursor);
3404 for (AudioRegionSelection::iterator r = selection->audio_regions.begin(); r != selection->audio_regions.end(); ) {
3406 AudioRegion& region ((*r)->region);
3407 Playlist* playlist = region.playlist();
3409 AudioRegionSelection::iterator tmp;
3414 if (region.apply (filter) == 0) {
3416 session->add_undo (playlist->get_memento());
3417 playlist->replace_region (region, *(filter.results.front()), region.position());
3418 session->add_redo_no_execute (playlist->get_memento());
3426 commit_reversible_command ();
3427 selection->audio_regions.clear ();
3430 track_canvas.get_window()->set_cursor (*current_canvas_cursor);
3434 Editor::region_selection_op (void (Region::*pmf)(void))
3436 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
3437 ((*i)->region.*pmf)();
3443 Editor::region_selection_op (void (Region::*pmf)(void*), void *arg)
3445 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
3446 ((*i)->region.*pmf)(arg);
3451 Editor::region_selection_op (void (Region::*pmf)(bool), bool yn)
3453 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
3454 ((*i)->region.*pmf)(yn);
3459 Editor::external_edit_region ()
3461 if (!clicked_regionview) {
3469 Editor::brush (jack_nframes_t pos)
3471 AudioRegionSelection sel;
3474 if (selection->audio_regions.empty()) {
3475 /* XXX get selection from region list */
3477 sel = selection->audio_regions;
3484 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
3485 mouse_brush_insert_region ((*i), pos);
3490 Editor::toggle_gain_envelope_visibility ()
3492 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
3493 (*i)->set_envelope_visible (!(*i)->envelope_visible());
3498 Editor::toggle_gain_envelope_active ()
3500 for (AudioRegionSelection::iterator i = selection->audio_regions.begin(); i != selection->audio_regions.end(); ++i) {
3501 AudioRegion* ar = dynamic_cast<AudioRegion*>(&(*i)->region);
3503 ar->set_envelope_active (true);