Fix "Crop Region to Range" -- second attempt.
[ardour.git] / gtk2_ardour / editor_ops.cc
index 2d718284d28aaed31d8582feb3996b63ea6f9eaf..7402d231471d555bda48647b2bd2e5ff1dd1b607 100644 (file)
@@ -96,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"
@@ -2531,7 +2532,7 @@ 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();
 }
 
 
@@ -3255,41 +3256,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) {
@@ -3300,56 +3308,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 ();
+       if (!foo.empty()) {
+               selection->set (foo);
        }
+
+       commit_reversible_command ();
 }
 
 void
@@ -4774,7 +4775,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);
 
@@ -4789,7 +4790,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);
@@ -4840,7 +4841,7 @@ Editor::duplicate_selection (float times)
                } else {
                        end = selection->time.end_frame();
                }
-               playlist->duplicate (*ri, end, times);
+               playlist->duplicate (*ri, end + 1, times);
 
                if (!in_command) {
                        begin_reversible_command (_("duplicate selection"));
@@ -6122,7 +6123,7 @@ Editor::set_playhead_cursor ()
                }
        }
 
-       if (UIConfiguration::instance().get_follow_edits() && !_session->config.get_external_sync()) {
+       if (UIConfiguration::instance().get_follow_edits() && (!_session || !_session->config.get_external_sync())) {
                cancel_time_selection();
        }
 }
@@ -7887,6 +7888,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 ();
 }
@@ -7907,6 +7909,7 @@ Editor::bring_all_sources_into_session ()
         * files
         */
 
+       Timers::TimerSuspender t;
        Gtkmm2ext::UI::instance()->flush_pending ();
 
        cerr << " Do it\n";