Spelling correction patch from Debian
[ardour.git] / gtk2_ardour / editor_ops.cc
index e8174ce9e6b64ffbe6772fb93721cf4ec7e19959..91f2031efa1890dfaaf6472e6dad90796aec5ab7 100644 (file)
@@ -57,6 +57,7 @@
 #include "ardour/session_playlists.h"
 #include "ardour/strip_silence.h"
 #include "ardour/transient_detector.h"
+#include "ardour/transpose.h"
 
 #include "canvas/canvas.h"
 
@@ -95,6 +96,7 @@
 #include "streamview.h"
 #include "strip_silence_dialog.h"
 #include "time_axis_view.h"
+#include "timers.h"
 #include "transpose_dialog.h"
 #include "transform_dialog.h"
 #include "ui_config.h"
@@ -1587,6 +1589,53 @@ Editor::scroll_up_one_track (bool skip_child_views)
        return false;
 }
 
+void
+Editor::scroll_left_step ()
+{
+       framepos_t xdelta = (current_page_samples() / 8);
+
+       if (leftmost_frame > xdelta) {
+               reset_x_origin (leftmost_frame - xdelta);
+       } else {
+               reset_x_origin (0);
+       }
+}
+
+
+void
+Editor::scroll_right_step ()
+{
+       framepos_t xdelta = (current_page_samples() / 8);
+
+       if (max_framepos - xdelta > leftmost_frame) {
+               reset_x_origin (leftmost_frame + xdelta);
+       } else {
+               reset_x_origin (max_framepos - current_page_samples());
+       }
+}
+
+void
+Editor::scroll_left_half_page ()
+{
+       framepos_t xdelta = (current_page_samples() / 2);
+       if (leftmost_frame > xdelta) {
+               reset_x_origin (leftmost_frame - xdelta);
+       } else {
+               reset_x_origin (0);
+       }
+}
+
+void
+Editor::scroll_right_half_page ()
+{
+       framepos_t xdelta = (current_page_samples() / 2);
+       if (max_framepos - xdelta > leftmost_frame) {
+               reset_x_origin (leftmost_frame + xdelta);
+       } else {
+               reset_x_origin (max_framepos - current_page_samples());
+       }
+}
+
 /* ZOOM */
 
 void
@@ -1638,6 +1687,14 @@ Editor::tav_zoom_smooth (bool coarser, bool force_all)
        }
 }
 
+void
+Editor::temporal_zoom_step_mouse_focus (bool coarser)
+{
+       Editing::ZoomFocus temp_focus = zoom_focus;
+       zoom_focus = Editing::ZoomFocusMouse;
+       temporal_zoom_step (coarser);
+       zoom_focus = temp_focus;
+}
 
 void
 Editor::temporal_zoom_step (bool coarser)
@@ -2530,14 +2587,14 @@ Editor::play_selection ()
 framepos_t
 Editor::get_preroll ()
 {
-       return 1.0 /*Config->get_edit_preroll_seconds()*/ * _session->frame_rate();
+       return Config->get_preroll_seconds() * _session->frame_rate();
 }
 
 
 void
 Editor::maybe_locate_with_edit_preroll ( framepos_t location )
 {
-       if ( _session->transport_rolling() || !UIConfiguration::instance().get_follow_edits() || _ignore_follow_edits )
+       if ( _session->transport_rolling() || !UIConfiguration::instance().get_follow_edits() || _ignore_follow_edits || _session->config.get_external_sync() )
                return;
 
        location -= get_preroll();
@@ -3254,41 +3311,48 @@ Editor::crop_region_to (framepos_t start, framepos_t end)
                return;
        }
 
-       framepos_t the_start;
-       framepos_t the_end;
-       framepos_t cnt;
+       framepos_t pos;
+       framepos_t new_start;
+       framepos_t new_end;
+       framecnt_t new_length;
        bool in_command = false;
 
        for (vector<boost::shared_ptr<Playlist> >::iterator i = playlists.begin(); i != playlists.end(); ++i) {
 
-               boost::shared_ptr<Region> region;
+               /* Only the top regions at start and end have to be cropped */
+               boost::shared_ptr<Region> region_at_start = (*i)->top_region_at(start);
+               boost::shared_ptr<Region> region_at_end = (*i)->top_region_at(end);
 
-               the_start = start;
+               vector<boost::shared_ptr<Region> > regions;
 
-               if ((region = (*i)->top_region_at(the_start)) == 0) {
-                       continue;
+               if (region_at_start != 0) {
+                       regions.push_back (region_at_start);
+               }
+               if (region_at_end != 0) {
+                       regions.push_back (region_at_end);
                }
 
-               /* now adjust lengths to that we do the right thing
-                  if the selection extends beyond the region
-               */
+               /* now adjust lengths */
+               for (vector<boost::shared_ptr<Region> >::iterator i = regions.begin(); i != regions.end(); ++i) {
 
-               the_start = max (the_start, (framepos_t) region->position());
-               if (max_framepos - the_start < region->length()) {
-                       the_end = the_start + region->length() - 1;
-               } else {
-                       the_end = max_framepos;
-               }
-               the_end = min (end, the_end);
-               cnt = the_end - the_start + 1;
+                       pos = (*i)->position();
+                       new_start = max (start, pos);
+                       if (max_framepos - pos > (*i)->length()) {
+                               new_end = pos + (*i)->length() - 1;
+                       } else {
+                               new_end = max_framepos;
+                       }
+                       new_end = min (end, new_end);
+                       new_length = new_end - new_start + 1;
 
-               if(!in_command) {
-                       begin_reversible_command (_("trim to selection"));
-                       in_command = true;
+                       if(!in_command) {
+                               begin_reversible_command (_("trim to selection"));
+                               in_command = true;
+                       }
+                       (*i)->clear_changes ();
+                       (*i)->trim_to (new_start, new_length);
+                       _session->add_command (new StatefulDiffCommand (*i));
                }
-               region->clear_changes ();
-               region->trim_to (the_start, cnt);
-               _session->add_command (new StatefulDiffCommand (region));
        }
 
        if (in_command) {
@@ -3299,117 +3363,49 @@ Editor::crop_region_to (framepos_t start, framepos_t end)
 void
 Editor::region_fill_track ()
 {
-       RegionSelection rs = get_regions_from_selection_and_entered ();
-
-       if (!_session || rs.empty()) {
-               return;
-       }
+       boost::shared_ptr<Playlist> playlist;
+       RegionSelection regions = get_regions_from_selection_and_entered ();
+       RegionSelection foo;
 
        framepos_t const end = _session->current_end_frame ();
-       RegionSelection foo;
-       bool in_command = false;
 
-       for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+       if (regions.empty () || regions.end_frame () + 1 >= end) {
+               return;
+       }
 
-               boost::shared_ptr<Region> region ((*i)->region());
+       framepos_t const start_frame = regions.start ();
+       framepos_t const end_frame = regions.end_frame ();
+       framecnt_t const gap = end_frame - start_frame + 1;
 
-               boost::shared_ptr<Playlist> pl = region->playlist();
+       begin_reversible_command (Operations::region_fill);
 
-               if (end <= region->last_frame()) {
-                       continue;
-               }
+       selection->clear_regions ();
 
-               double times = (double) (end - region->last_frame()) / (double) region->length();
+       for (RegionSelection::iterator i = regions.begin(); i != regions.end(); ++i) {
 
-               if (times == 0) {
-                       continue;
-               }
+               boost::shared_ptr<Region> r ((*i)->region());
 
-               if (!in_command) {
-                       begin_reversible_command (Operations::region_fill);
-                       in_command = true;
-               }
                TimeAxisView& tv = (*i)->get_time_axis_view();
                RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (&tv);
                latest_regionviews.clear ();
                sigc::connection c = rtv->view()->RegionViewAdded.connect (sigc::mem_fun(*this, &Editor::collect_new_region_view));
 
-               pl->clear_changes ();
-               pl->add_region (RegionFactory::create (region, true), region->last_frame(), times);
-               _session->add_command (new StatefulDiffCommand (pl));
+               framepos_t const position = end_frame + (r->first_frame() - start_frame + 1);
+               playlist = (*i)->region()->playlist();
+               playlist->clear_changes ();
+               playlist->duplicate_until (r, position, gap, end);
+               _session->add_command(new StatefulDiffCommand (playlist));
 
                c.disconnect ();
 
                foo.insert (foo.end(), latest_regionviews.begin(), latest_regionviews.end());
        }
 
-       if (in_command) {
-               if (!foo.empty()) {
-                       selection->set (foo);
-               }
-               commit_reversible_command ();
-       }
-}
-
-void
-Editor::region_fill_selection ()
-{
-       if (clicked_routeview == 0 || !clicked_routeview->is_audio_track()) {
-               return;
-       }
-
-       if (selection->time.empty()) {
-               return;
-       }
-
-       boost::shared_ptr<Region> region = _regions->get_single_selection ();
-       if (region == 0) {
-               return;
-       }
-
-       framepos_t start = selection->time[clicked_selection].start;
-       framepos_t end = selection->time[clicked_selection].end;
-
-       boost::shared_ptr<Playlist> playlist;
-
-       if (selection->tracks.empty()) {
-               return;
-       }
-
-       framepos_t selection_length = end - start;
-       float times = (float)selection_length / region->length();
-       bool in_command = false;
-
-       TrackViewList ts = selection->tracks.filter_to_unique_playlists ();
-       RegionSelection foo;
-
-       for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) {
-
-               if ((playlist = (*i)->playlist()) == 0) {
-                       continue;
-               }
-
-               if (!in_command) {
-                       begin_reversible_command (Operations::fill_selection);
-                       in_command = true;
-               }
-               RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
-               latest_regionviews.clear ();
-               sigc::connection c = rtv->view()->RegionViewAdded.connect (sigc::mem_fun(*this, &Editor::collect_new_region_view));
-
-               playlist->clear_changes ();
-               playlist->add_region (RegionFactory::create (region, true), start, times);
-               _session->add_command (new StatefulDiffCommand (playlist));
-               c.disconnect ();
-               foo.insert (foo.end(), latest_regionviews.begin(), latest_regionviews.end());
+       if (!foo.empty()) {
+               selection->set (foo);
        }
 
-       if (in_command) {
-               if (!foo.empty()) {
-                       selection->set (foo);
-               }
-               commit_reversible_command ();
-       }
+       commit_reversible_command ();
 }
 
 void
@@ -4099,6 +4095,7 @@ Editor::cut_copy (CutCopyOp op)
                Location* loc = find_location_from_marker (entered_marker, ignored);
 
                if (_session && loc) {
+                       entered_marker = NULL;
                        Glib::signal_idle().connect (sigc::bind (sigc::mem_fun(*this, &Editor::really_remove_marker), loc));
                }
 
@@ -4570,7 +4567,7 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
 
                list<boost::shared_ptr<Playlist> > foo;
 
-               /* the pmap is in the same order as the tracks in which selected regions occured */
+               /* the pmap is in the same order as the tracks in which selected regions occurred */
 
                for (vector<PlaylistMapping>::iterator i = pmap.begin(); i != pmap.end(); ++i) {
                        if ((*i).pl) {
@@ -4773,7 +4770,7 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times)
 
        framepos_t const start_frame = regions.start ();
        framepos_t const end_frame = regions.end_frame ();
-       framecnt_t const gap = end_frame - start_frame;
+       framecnt_t const gap = end_frame - start_frame + 1;
 
        begin_reversible_command (Operations::duplicate_region);
 
@@ -4788,7 +4785,7 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times)
                latest_regionviews.clear ();
                sigc::connection c = rtv->view()->RegionViewAdded.connect (sigc::mem_fun(*this, &Editor::collect_new_region_view));
 
-               framepos_t const position = end_frame + (r->first_frame() - start_frame);
+               framepos_t const position = end_frame + (r->first_frame() - start_frame + 1);
                playlist = (*i)->region()->playlist();
                playlist->clear_changes ();
                playlist->duplicate (r, position, gap, times);
@@ -4814,18 +4811,9 @@ Editor::duplicate_selection (float times)
        }
 
        boost::shared_ptr<Playlist> playlist;
-       vector<boost::shared_ptr<Region> > new_regions;
-       vector<boost::shared_ptr<Region> >::iterator ri;
-
-       create_region_from_selection (new_regions);
-
-       if (new_regions.empty()) {
-               return;
-       }
-
-       ri = new_regions.begin();
 
        TrackViewList ts = selection->tracks.filter_to_unique_playlists ();
+
        bool in_command = false;
 
        for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) {
@@ -4833,27 +4821,34 @@ Editor::duplicate_selection (float times)
                        continue;
                }
                playlist->clear_changes ();
-               framepos_t end;
+
                if (clicked_selection) {
-                       end = selection->time[clicked_selection].end;
+                       playlist->duplicate_range (selection->time[clicked_selection], times);
                } else {
-                       end = selection->time.end_frame();
+                       playlist->duplicate_ranges (selection->time, times);
                }
-               playlist->duplicate (*ri, end, times);
 
                if (!in_command) {
-                       begin_reversible_command (_("duplicate selection"));
+                       begin_reversible_command (_("duplicate range selection"));
                        in_command = true;
                }
                _session->add_command (new StatefulDiffCommand (playlist));
 
-               ++ri;
-               if (ri == new_regions.end()) {
-                       --ri;
-               }
        }
 
        if (in_command) {
+               // now "move" range selection to after the current range selection
+               framecnt_t distance = 0;
+
+               if (clicked_selection) {
+                       distance = selection->time[clicked_selection].end -
+                                  selection->time[clicked_selection].start;
+               } else {
+                       distance = selection->time.end_frame() - selection->time.start();
+               }
+
+               selection->move_time (distance);
+
                commit_reversible_command ();
        }
 }
@@ -5341,18 +5336,42 @@ Editor::transform_regions (const RegionSelection& rs)
                return;
        }
 
-       TransformDialog* td = new TransformDialog();
+       TransformDialog td;
 
-       td->present();
-       const int r = td->run();
-       td->hide();
+       td.present();
+       const int r = td.run();
+       td.hide();
 
        if (r == Gtk::RESPONSE_OK) {
-               Transform transform(td->get());
+               Transform transform(td.get());
                apply_midi_note_edit_op(transform, rs);
        }
 }
 
+void
+Editor::transpose_region ()
+{
+       if (_session) {
+               transpose_regions(get_regions_from_selection_and_entered ());
+       }
+}
+
+void
+Editor::transpose_regions (const RegionSelection& rs)
+{
+       if (rs.n_midi_regions() == 0) {
+               return;
+       }
+
+       TransposeDialog d;
+       int const r = d.run ();
+
+       if (r == RESPONSE_ACCEPT) {
+               Transpose transpose(d.semitones ());
+               apply_midi_note_edit_op (transpose, rs);
+       }
+}
+
 void
 Editor::insert_patch_change (bool from_context)
 {
@@ -5680,7 +5699,7 @@ Editor::toggle_record_enable ()
                        first = false;
                }
 
-               rtav->track()->set_record_enabled (new_state, this);
+               rtav->track()->set_record_enabled (new_state, Controllable::UseGroup);
        }
 }
 
@@ -5706,7 +5725,7 @@ Editor::toggle_solo ()
                rl->push_back (rtav->route());
        }
 
-       _session->set_solo (rl, new_state, Session::rt_cleanup, true);
+       _session->set_solo (rl, new_state, Session::rt_cleanup, Controllable::UseGroup);
 }
 
 void
@@ -5731,7 +5750,7 @@ Editor::toggle_mute ()
                rl->push_back (rtav->route());
        }
 
-       _session->set_mute (rl, new_state, Session::rt_cleanup, true);
+       _session->set_mute (rl, new_state, Session::rt_cleanup, Controllable::UseGroup);
 }
 
 void
@@ -6097,7 +6116,7 @@ Editor::set_playhead_cursor ()
                }
        }
 
-       if (UIConfiguration::instance().get_follow_edits()) {
+       if (UIConfiguration::instance().get_follow_edits() && (!_session || !_session->config.get_external_sync())) {
                cancel_time_selection();
        }
 }
@@ -6425,30 +6444,6 @@ Editor::pitch_shift_region ()
        pitch_shift (audio_rs, 1.2);
 }
 
-void
-Editor::transpose_region ()
-{
-       RegionSelection rs = get_regions_from_selection_and_entered ();
-
-       list<MidiRegionView*> midi_region_views;
-       for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
-               MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (*i);
-               if (mrv) {
-                       midi_region_views.push_back (mrv);
-               }
-       }
-
-       TransposeDialog d;
-       int const r = d.run ();
-       if (r != RESPONSE_ACCEPT) {
-               return;
-       }
-
-       for (list<MidiRegionView*>::iterator i = midi_region_views.begin(); i != midi_region_views.end(); ++i) {
-               (*i)->midi_region()->transpose (d.semitones ());
-       }
-}
-
 void
 Editor::set_tempo_from_region ()
 {
@@ -7229,12 +7224,10 @@ Editor::do_insert_time ()
                return;
        }
 
-       InsertTimeOption opt = d.intersected_region_action ();
-
        insert_time (
-               get_preferred_edit_position(),
+               get_preferred_edit_position (EDIT_IGNORE_MOUSE),
                d.distance(),
-               opt,
+               d.intersected_region_action (),
                d.all_playlists(),
                d.move_glued(),
                d.move_markers(),
@@ -7432,7 +7425,7 @@ Editor::remove_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt,
                        pl->shift (pos, -frames, true, ignore_music_glue);
 
                        if (!in_command) {
-                               begin_reversible_command (_("cut time"));
+                               begin_reversible_command (_("remove time"));
                                in_command = true;
                        }
                        XMLNode &after = pl->get_state();
@@ -7444,7 +7437,7 @@ Editor::remove_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt,
                RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*> (*x);
                if (rtav) {
                        if (!in_command) {
-                               begin_reversible_command (_("cut time"));
+                               begin_reversible_command (_("remove time"));
                                in_command = true;
                        }
                        rtav->route ()->shift (pos, -frames);
@@ -7517,7 +7510,7 @@ Editor::remove_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt,
 
                if (moved) {
                        if (!in_command) {
-                               begin_reversible_command (_("cut time"));
+                               begin_reversible_command (_("remove time"));
                                in_command = true;
                        }
                        XMLNode& after (_session->locations()->get_state());
@@ -7870,6 +7863,7 @@ Editor::unlock ()
        lock_dialog->hide ();
 
        delete _main_menu_disabler;
+       _main_menu_disabler = 0;
 
        if (UIConfiguration::instance().get_lock_gui_after_seconds()) {
                start_lock_event_timing ();
@@ -7885,6 +7879,7 @@ Editor::bring_in_callback (Gtk::Label* label, uint32_t n, uint32_t total, string
 void
 Editor::update_bring_in_message (Gtk::Label* label, uint32_t n, uint32_t total, string name)
 {
+       Timers::TimerSuspender t;
        label->set_text (string_compose ("Copying %1, %2 of %3", name, n, total));
        Gtkmm2ext::UI::instance()->flush_pending ();
 }
@@ -7905,6 +7900,7 @@ Editor::bring_all_sources_into_session ()
         * files
         */
 
+       Timers::TimerSuspender t;
        Gtkmm2ext::UI::instance()->flush_pending ();
 
        cerr << " Do it\n";