Fixed overflow issue. Code originally meant to truncate the 64 bit integer did not...
[ardour.git] / gtk2_ardour / editor_ops.cc
index e990f603f5a33982e3482c8cf396320f11d8d055..139e07a36666b5296ee8fc7c0e7bc764aab04c7d 100644 (file)
@@ -108,7 +108,7 @@ Editor::split_region ()
 }
 
 void
-Editor::split_region_at (nframes_t where)
+Editor::split_region_at (nframes64_t where)
 {
        RegionSelection rs;
 
@@ -117,7 +117,7 @@ Editor::split_region_at (nframes_t where)
 }
 
 void
-Editor::split_regions_at (nframes_t where, RegionSelection& regions)
+Editor::split_regions_at (nframes64_t where, RegionSelection& regions)
 {
        if (regions.empty()) {
                return;
@@ -140,7 +140,8 @@ Editor::split_regions_at (nframes_t where, RegionSelection& regions)
        } else {
                snap_to (where);
        }
-               
+
+       cerr << "Split " << regions.size() << " at " << where << endl;
 
        for (RegionSelection::iterator a = regions.begin(); a != regions.end(); ) {
 
@@ -198,46 +199,50 @@ Editor::remove_clicked_region ()
 }
 
 void
-Editor::destroy_clicked_region ()
+Editor::remove_region ()
 {
-       uint32_t selected = selection->regions.size();
-
-       if (!session || !selected) {
-               return;
-       }
 
-       vector<string> choices;
-       string prompt;
+       RegionSelection rs; 
+       get_regions_for_action (rs);
        
-       prompt  = string_compose (_(" This is destructive, will possibly delete audio files\n\
-It cannot be undone\n\
-Do you really want to destroy %1 ?"),
-                          (selected > 1 ? 
-                           _("these regions") : _("this region")));
-
-       choices.push_back (_("No, do nothing."));
-
-       if (selected > 1) {
-               choices.push_back (_("Yes, destroy them."));
-       } else {
-               choices.push_back (_("Yes, destroy it."));
+       if (!session) {
+               return;
        }
 
-       Gtkmm2ext::Choice prompter (prompt, choices);
-       
-       if (prompter.run() == 0) { /* first choice */
+       if (rs.empty()) {
                return;
        }
 
-       if (selected) {
-               list<boost::shared_ptr<Region> > r;
+       begin_reversible_command (_("remove region"));
 
-               for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
-                       r.push_back ((*i)->region());
-               }
+       list<boost::shared_ptr<Region> > regions_to_remove;
 
-               session->destroy_regions (r);
-       } 
+       for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+               // we can't just remove the region(s) in this loop because
+               // this removes them from the RegionSelection, and they thus
+               // disappear from underneath the iterator, and the ++i above
+               // SEGVs in a puzzling fashion.
+
+               // so, first iterate over the regions to be removed from rs and
+               // add them to the regions_to_remove list, and then
+               // iterate over the list to actually remove them.
+               
+               regions_to_remove.push_back ((*i)->region());
+       }
+       
+       for (list<boost::shared_ptr<Region> >::iterator rl = regions_to_remove.begin(); rl != regions_to_remove.end(); ++rl) {
+               boost::shared_ptr<Playlist> playlist = (*rl)->playlist();
+               if (!playlist) {
+                       // is this check necessary?
+                       continue;
+               }
+
+               XMLNode &before = playlist->get_state();
+               playlist->remove_region (*rl);
+               XMLNode &after = playlist->get_state();
+               session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
+       }
+       commit_reversible_command ();
 }
 
 boost::shared_ptr<Region>
@@ -245,7 +250,7 @@ Editor::select_region_for_operation (int dir, TimeAxisView **tv)
 {
        RegionView* rv;
        boost::shared_ptr<Region> region;
-       nframes_t start = 0;
+       nframes64_t start = 0;
 
        if (selection->time.start () == selection->time.end_frame ()) {
                
@@ -288,7 +293,7 @@ Editor::extend_selection_to_end_of_region (bool next)
 {
        TimeAxisView *tv;
        boost::shared_ptr<Region> region;
-       nframes_t start;
+       nframes64_t start;
 
        if ((region = select_region_for_operation (next ? 1 : 0, &tv)) == 0) {
                return;
@@ -316,7 +321,7 @@ Editor::extend_selection_to_start_of_region (bool previous)
 {
        TimeAxisView *tv;
        boost::shared_ptr<Region> region;
-       nframes_t end;
+       nframes64_t end;
 
        if ((region = select_region_for_operation (previous ? -1 : 0, &tv)) == 0) {
                return;
@@ -365,8 +370,8 @@ Editor::nudge_backward_release (GdkEventButton* ev)
 void
 Editor::nudge_forward (bool next, bool force_playhead)
 {
-       nframes_t distance;
-       nframes_t next_distance;
+       nframes64_t distance;
+       nframes64_t next_distance;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -398,40 +403,45 @@ Editor::nudge_forward (bool next, bool force_playhead)
        } else if (!force_playhead && !selection->markers.empty()) {
 
                bool is_start;
-               Location* loc = find_location_from_marker (selection->markers.front(), is_start);
-
-               if (loc) {
-
-                       begin_reversible_command (_("nudge location forward"));
-
-                       XMLNode& before (loc->get_state());
 
-                       if (is_start) {
-                               distance = get_nudge_distance (loc->start(), next_distance);
-                               if (next) {
-                                       distance = next_distance;
-                               }
-                               if (max_frames - distance > loc->start() + loc->length()) {
-                                       loc->set_start (loc->start() + distance);
-                               } else {
-                                       loc->set_start (max_frames - loc->length());
-                               }
-                       } else {
-                               distance = get_nudge_distance (loc->end(), next_distance);
-                               if (next) {
-                                       distance = next_distance;
-                               }
-                               if (max_frames - distance > loc->end()) {
-                                       loc->set_end (loc->end() + distance);
+               begin_reversible_command (_("nudge location forward"));
+               
+               for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
+                       
+                       Location* loc = find_location_from_marker ((*i), is_start);
+                       
+                       if (loc) {
+                               
+                               XMLNode& before (loc->get_state());
+                               
+                               if (is_start) {
+                                       distance = get_nudge_distance (loc->start(), next_distance);
+                                       if (next) {
+                                               distance = next_distance;
+                                       }
+                                       if (max_frames - distance > loc->start() + loc->length()) {
+                                               loc->set_start (loc->start() + distance);
+                                       } else {
+                                               loc->set_start (max_frames - loc->length());
+                                       }
                                } else {
-                                       loc->set_end (max_frames);
+                                       distance = get_nudge_distance (loc->end(), next_distance);
+                                       if (next) {
+                                               distance = next_distance;
+                                       }
+                                       if (max_frames - distance > loc->end()) {
+                                               loc->set_end (loc->end() + distance);
+                                       } else {
+                                               loc->set_end (max_frames);
+                                       }
                                }
+                               XMLNode& after (loc->get_state());
+                               session->add_command (new MementoCommand<Location>(*loc, &before, &after));
                        }
-                       XMLNode& after (loc->get_state());
-                       session->add_command (new MementoCommand<Location>(*loc, &before, &after));
-                       commit_reversible_command ();
                }
                
+               commit_reversible_command ();
+               
        } else {
                distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);
                session->request_locate (playhead_cursor->current_frame + distance);
@@ -441,8 +451,8 @@ Editor::nudge_forward (bool next, bool force_playhead)
 void
 Editor::nudge_backward (bool next, bool force_playhead)
 {
-       nframes_t distance;
-       nframes_t next_distance;
+       nframes64_t distance;
+       nframes64_t next_distance;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -478,41 +488,48 @@ Editor::nudge_backward (bool next, bool force_playhead)
        } else if (!force_playhead && !selection->markers.empty()) {
 
                bool is_start;
-               Location* loc = find_location_from_marker (selection->markers.front(), is_start);
-
-               if (loc) {
-
-                       begin_reversible_command (_("nudge location forward"));
-                       XMLNode& before (loc->get_state());
 
-                       if (is_start) {
-                               distance = get_nudge_distance (loc->start(), next_distance);
-                               if (next) {
-                                       distance = next_distance;
-                               }
-                               if (distance < loc->start()) {
-                                       loc->set_start (loc->start() - distance);
-                               } else {
-                                       loc->set_start (0);
-                               }
-                       } else {
-                               distance = get_nudge_distance (loc->end(), next_distance);
+               begin_reversible_command (_("nudge location forward"));
 
-                               if (next) {
-                                       distance = next_distance;
-                               }
+               for (MarkerSelection::iterator i = selection->markers.begin(); i != selection->markers.end(); ++i) {
 
-                               if (distance < loc->end() - loc->length()) {
-                                       loc->set_end (loc->end() - distance);
+                       Location* loc = find_location_from_marker ((*i), is_start);
+                       
+                       if (loc) {
+                               
+                               XMLNode& before (loc->get_state());
+                       
+                               if (is_start) {
+                                       distance = get_nudge_distance (loc->start(), next_distance);
+                                       if (next) {
+                                               distance = next_distance;
+                                       }
+                                       if (distance < loc->start()) {
+                                               loc->set_start (loc->start() - distance);
+                                       } else {
+                                               loc->set_start (0);
+                                       }
                                } else {
-                                       loc->set_end (loc->length());
+                                       distance = get_nudge_distance (loc->end(), next_distance);
+                                       
+                                       if (next) {
+                                               distance = next_distance;
+                                       }
+                                       
+                                       if (distance < loc->end() - loc->length()) {
+                                               loc->set_end (loc->end() - distance);
+                                       } else {
+                                               loc->set_end (loc->length());
+                                       }
                                }
+                               
+                               XMLNode& after (loc->get_state());
+                               session->add_command (new MementoCommand<Location>(*loc, &before, &after));
                        }
-
-                       XMLNode& after (loc->get_state());
-                       session->add_command (new MementoCommand<Location>(*loc, &before, &after));
                }
-               
+
+               commit_reversible_command ();
+                       
        } else {
 
                distance = get_nudge_distance (playhead_cursor->current_frame, next_distance);
@@ -528,7 +545,7 @@ Editor::nudge_backward (bool next, bool force_playhead)
 void
 Editor::nudge_forward_capture_offset ()
 {
-       nframes_t distance;
+       nframes64_t distance;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -558,7 +575,7 @@ Editor::nudge_forward_capture_offset ()
 void
 Editor::nudge_backward_capture_offset ()
 {
-       nframes_t distance;
+       nframes64_t distance;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -607,7 +624,7 @@ Editor::move_to_end ()
 void
 Editor::build_region_boundary_cache ()
 {
-       nframes_t pos = 0;
+       nframes64_t pos = 0;
        vector<RegionPoint> interesting_points;
        boost::shared_ptr<Region> r;
        TrackViewList tracks;
@@ -650,8 +667,8 @@ Editor::build_region_boundary_cache ()
 
        while (pos < session->current_end_frame() && !at_end) {
 
-               nframes_t rpos;
-               nframes_t lpos = max_frames;
+               nframes64_t rpos;
+               nframes64_t lpos = max_frames;
 
                for (vector<RegionPoint>::iterator p = interesting_points.begin(); p != interesting_points.end(); ++p) {
 
@@ -699,7 +716,7 @@ Editor::build_region_boundary_cache ()
                           to sort later.
                        */
 
-                       vector<nframes_t>::iterator ri; 
+                       vector<nframes64_t>::iterator ri; 
                        
                        for (ri = region_boundary_cache.begin(); ri != region_boundary_cache.end(); ++ri) {
                                if (*ri == rpos) {
@@ -721,20 +738,20 @@ Editor::build_region_boundary_cache ()
 }
 
 boost::shared_ptr<Region>
-Editor::find_next_region (nframes_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack)
+Editor::find_next_region (nframes64_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack)
 {
        TrackViewList::iterator i;
-       nframes_t closest = max_frames;
+       nframes64_t closest = max_frames;
        boost::shared_ptr<Region> ret;
-       nframes_t rpos = 0;
+       nframes64_t rpos = 0;
 
        float track_speed;
-       nframes_t track_frame;
+       nframes64_t track_frame;
        AudioTimeAxisView *atav;
 
        for (i = tracks.begin(); i != tracks.end(); ++i) {
 
-               nframes_t distance;
+               nframes64_t distance;
                boost::shared_ptr<Region> r;
                
                track_speed = 1.0f;
@@ -866,7 +883,7 @@ void
 Editor::cursor_to_region_point (Cursor* cursor, RegionPoint point, int32_t dir)
 {
        boost::shared_ptr<Region> r;
-       nframes_t pos = cursor->current_frame;
+       nframes64_t pos = cursor->current_frame;
 
        if (!session) {
                return;
@@ -945,7 +962,7 @@ Editor::cursor_to_previous_region_point (Cursor* cursor, RegionPoint point)
 void
 Editor::cursor_to_selection_start (Cursor *cursor)
 {
-       nframes_t pos = 0;
+       nframes64_t pos = 0;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -977,7 +994,7 @@ Editor::cursor_to_selection_start (Cursor *cursor)
 void
 Editor::cursor_to_selection_end (Cursor *cursor)
 {
-       nframes_t pos = 0;
+       nframes64_t pos = 0;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -1071,7 +1088,7 @@ void
 Editor::selected_marker_to_region_point (RegionPoint point, int32_t dir)
 {
        boost::shared_ptr<Region> r;
-       nframes_t pos;
+       nframes64_t pos;
        Location* loc;
        bool ignored;
 
@@ -1154,7 +1171,7 @@ Editor::selected_marker_to_previous_region_point (RegionPoint point)
 void
 Editor::selected_marker_to_selection_start ()
 {
-       nframes_t pos = 0;
+       nframes64_t pos = 0;
        Location* loc;
        bool ignored;
 
@@ -1193,7 +1210,7 @@ Editor::selected_marker_to_selection_start ()
 void
 Editor::selected_marker_to_selection_end ()
 {
-       nframes_t pos = 0;
+       nframes64_t pos = 0;
        Location* loc;
        bool ignored;
 
@@ -1232,8 +1249,8 @@ Editor::selected_marker_to_selection_end ()
 void
 Editor::scroll_playhead (bool forward)
 {
-       nframes_t pos = playhead_cursor->current_frame;
-       nframes_t delta = (nframes_t) floor (current_page_frames() / 0.8);
+       nframes64_t pos = playhead_cursor->current_frame;
+       nframes64_t delta = (nframes64_t) floor (current_page_frames() / 0.8);
 
        if (forward) {
                if (pos == max_frames) {
@@ -1265,8 +1282,8 @@ Editor::scroll_playhead (bool forward)
 void
 Editor::playhead_backward ()
 {
-       nframes_t pos;
-       nframes_t cnt;
+       nframes64_t pos;
+       nframes64_t cnt;
        float prefix;
        bool was_floating;
 
@@ -1274,15 +1291,15 @@ Editor::playhead_backward ()
                cnt = 1;
        } else {
                if (was_floating) {
-                       cnt = (nframes_t) floor (prefix * session->frame_rate ());
+                       cnt = (nframes64_t) floor (prefix * session->frame_rate ());
                } else {
-                       cnt = (nframes_t) prefix;
+                       cnt = (nframes64_t) prefix;
                }
        }
 
        pos = playhead_cursor->current_frame;
 
-       if ((nframes_t) pos < cnt) {
+       if ((nframes64_t) pos < cnt) {
                pos = 0;
        } else {
                pos -= cnt;
@@ -1299,8 +1316,8 @@ Editor::playhead_backward ()
 void
 Editor::playhead_forward ()
 {
-       nframes_t pos;
-       nframes_t cnt;
+       nframes64_t pos;
+       nframes64_t cnt;
        bool was_floating;
        float prefix;
 
@@ -1308,9 +1325,9 @@ Editor::playhead_forward ()
                cnt = 1;
        } else {
                if (was_floating) {
-                       cnt = (nframes_t) floor (prefix * session->frame_rate ());
+                       cnt = (nframes64_t) floor (prefix * session->frame_rate ());
                } else {
-                       cnt = (nframes_t) floor (prefix);
+                       cnt = (nframes64_t) floor (prefix);
                }
        }
 
@@ -1370,9 +1387,9 @@ Editor::edit_cursor_backward ()
                cnt = 1;
        } else {
                if (was_floating) {
-                       cnt = (nframes_t) floor (prefix * session->frame_rate ());
+                       cnt = (nframes64_t) floor (prefix * session->frame_rate ());
                } else {
-                       cnt = (nframes_t) prefix;
+                       cnt = (nframes64_t) prefix;
                }
        }
 
@@ -1392,8 +1409,8 @@ Editor::edit_cursor_backward ()
 void
 Editor::edit_cursor_forward ()
 {
-       //nframes_t pos;
-       nframes_t cnt;
+       //nframes64_t pos;
+       nframes64_t cnt;
        bool was_floating;
        float prefix;
 
@@ -1401,9 +1418,9 @@ Editor::edit_cursor_forward ()
                cnt = 1;
        } else {
                if (was_floating) {
-                       cnt = (nframes_t) floor (prefix * session->frame_rate ());
+                       cnt = (nframes64_t) floor (prefix * session->frame_rate ());
                } else {
-                       cnt = (nframes_t) floor (prefix);
+                       cnt = (nframes64_t) floor (prefix);
                }
        }
 
@@ -1416,16 +1433,16 @@ Editor::goto_frame ()
 {
        float prefix;
        bool was_floating;
-       nframes_t frame;
+       nframes64_t frame;
 
        if (get_prefix (prefix, was_floating)) {
                return;
        }
 
        if (was_floating) {
-               frame = (nframes_t) floor (prefix * session->frame_rate());
+               frame = (nframes64_t) floor (prefix * session->frame_rate());
        } else {
-               frame = (nframes_t) floor (prefix);
+               frame = (nframes64_t) floor (prefix);
        }
 
        session->request_locate (frame);
@@ -1434,19 +1451,19 @@ Editor::goto_frame ()
 void
 Editor::scroll_backward (float pages)
 {
-       nframes_t frame;
-       nframes_t one_page = (nframes_t) rint (canvas_width * frames_per_unit);
+       nframes64_t frame;
+       nframes64_t one_page = (nframes64_t) rint (canvas_width * frames_per_unit);
        bool was_floating;
        float prefix;
-       nframes_t cnt;
+       nframes64_t cnt;
        
        if (get_prefix (prefix, was_floating)) {
-               cnt = (nframes_t) floor (pages * one_page);
+               cnt = (nframes64_t) floor (pages * one_page);
        } else {
                if (was_floating) {
-                       cnt = (nframes_t) floor (prefix * session->frame_rate());
+                       cnt = (nframes64_t) floor (prefix * session->frame_rate());
                } else {
-                       cnt = (nframes_t) floor (prefix * one_page);
+                       cnt = (nframes64_t) floor (prefix * one_page);
                }
        }
 
@@ -1462,19 +1479,19 @@ Editor::scroll_backward (float pages)
 void
 Editor::scroll_forward (float pages)
 {
-       nframes_t frame;
-       nframes_t one_page = (nframes_t) rint (canvas_width * frames_per_unit);
+       nframes64_t frame;
+       nframes64_t one_page = (nframes64_t) rint (canvas_width * frames_per_unit);
        bool was_floating;
        float prefix;
-       nframes_t cnt;
+       nframes64_t cnt;
        
        if (get_prefix (prefix, was_floating)) {
-               cnt = (nframes_t) floor (pages * one_page);
+               cnt = (nframes64_t) floor (pages * one_page);
        } else {
                if (was_floating) {
-                       cnt = (nframes_t) floor (prefix * session->frame_rate());
+                       cnt = (nframes64_t) floor (prefix * session->frame_rate());
                } else {
-                       cnt = (nframes_t) floor (prefix * one_page);
+                       cnt = (nframes64_t) floor (prefix * one_page);
                }
        }
 
@@ -1529,7 +1546,7 @@ Editor::scroll_tracks_down_line ()
 {
 
         Gtk::Adjustment* adj = edit_vscrollbar.get_adjustment();
-       double vert_value = adj->get_value() + 20;
+       double vert_value = adj->get_value() + 60;
 
        if (vert_value>adj->get_upper() - canvas_height) {
                vert_value = adj->get_upper() - canvas_height;
@@ -1541,7 +1558,7 @@ void
 Editor::scroll_tracks_up_line ()
 {
         Gtk::Adjustment* adj = edit_vscrollbar.get_adjustment();
-       adj->set_value (adj->get_value() - 20);
+       adj->set_value (adj->get_value() - 60);
 }
 
 /* ZOOM */
@@ -1589,7 +1606,7 @@ Editor::temporal_zoom (gdouble fpu)
 
        nfpu = fpu;
        
-       new_page_size = (nframes_t) floor (canvas_width * nfpu);
+       new_page_size = (nframes64_t) floor (canvas_width * nfpu);
        half_page_size = new_page_size / 2;
 
        switch (zoom_focus) {
@@ -1736,9 +1753,9 @@ Editor::temporal_zoom_region (bool both_axes)
                return;
        }
 
-       nframes_t range = end - start;
+       nframes64_t range = end - start;
        double new_fpu = (double)range / (double)canvas_width;
-       nframes_t extra_samples = (nframes_t) floor (one_centimeter_in_pixels * new_fpu);
+       nframes64_t extra_samples = (nframes64_t) floor (one_centimeter_in_pixels * new_fpu);
 
        if (start > extra_samples) {
                start -= extra_samples;
@@ -1811,8 +1828,8 @@ Editor::temporal_zoom_selection ()
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
 
        temporal_zoom_by_frame (start, end, "zoom to selection");
 }
@@ -1823,12 +1840,13 @@ Editor::temporal_zoom_session ()
        ENSURE_GUI_THREAD (mem_fun (*this, &Editor::temporal_zoom_session));
 
        if (session) {
+               last_canvas_frame = ((session->current_end_frame() - session->current_start_frame()) + (current_page_frames() / 24));
                temporal_zoom_by_frame (session->current_start_frame(), session->current_end_frame(), "zoom to session");
        }
 }
 
 void
-Editor::temporal_zoom_by_frame (nframes_t start, nframes_t end, const string & op)
+Editor::temporal_zoom_by_frame (nframes64_t start, nframes64_t end, const string & op)
 {
        if (!session) return;
 
@@ -1836,13 +1854,13 @@ Editor::temporal_zoom_by_frame (nframes_t start, nframes_t end, const string & o
                return;
        }
 
-       nframes_t range = end - start;
+       nframes64_t range = end - start;
 
        double new_fpu = (double)range / (double)canvas_width;
        
-       nframes_t new_page = (nframes_t) floor (canvas_width * new_fpu);
-       nframes_t middle = (nframes_t) floor( (double)start + ((double)range / 2.0f ));
-       nframes_t new_leftmost = (nframes_t) floor( (double)middle - ((double)new_page/2.0f));
+       nframes64_t new_page = (nframes64_t) floor (canvas_width * new_fpu);
+       nframes64_t middle = (nframes64_t) floor( (double)start + ((double)range / 2.0f ));
+       nframes64_t new_leftmost = (nframes64_t) floor( (double)middle - ((double)new_page/2.0f));
 
        if (new_leftmost > middle) {
                new_leftmost = 0;
@@ -1852,10 +1870,11 @@ Editor::temporal_zoom_by_frame (nframes_t start, nframes_t end, const string & o
 }
 
 void 
-Editor::temporal_zoom_to_frame (bool coarser, nframes_t frame)
+Editor::temporal_zoom_to_frame (bool coarser, nframes64_t frame)
 {
-       if (!session) return;
-       
+       if (!session) {
+               return;
+       }
        double range_before = frame - leftmost_frame;
        double new_fpu;
        
@@ -1869,12 +1888,15 @@ Editor::temporal_zoom_to_frame (bool coarser, nframes_t frame)
                range_before /= 1.61803399;
        }
 
-       if (new_fpu == frames_per_unit) return;
-
-       nframes_t new_leftmost = frame - (nframes_t)range_before;
+       if (new_fpu == frames_per_unit)  {
+               return;
+       }
 
-       if (new_leftmost > frame) new_leftmost = 0;
+       nframes64_t new_leftmost = frame - (nframes64_t)range_before;
 
+       if (new_leftmost > frame) {
+               new_leftmost = 0;
+       }
 //     begin_reversible_command (_("zoom to frame"));
 //     session->add_undo (bind (mem_fun(*this, &Editor::reposition_and_zoom), leftmost_frame, frames_per_unit));
 //     session->add_redo (bind (mem_fun(*this, &Editor::reposition_and_zoom), new_leftmost, new_fpu));
@@ -1936,8 +1958,8 @@ Editor::add_location_from_selection ()
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
 
        session->locations()->next_available_name(rangename,"selection");
        Location *location = new Location (start, end, rangename, Location::IsRangeMarker);
@@ -2089,7 +2111,7 @@ Editor::jump_backward_to_mark ()
 void
 Editor::set_mark ()
 {
-       nframes_t pos;
+       nframes64_t pos;
        float prefix;
        bool was_floating;
        string markername;
@@ -2098,9 +2120,9 @@ Editor::set_mark ()
                pos = session->audible_frame ();
        } else {
                if (was_floating) {
-                       pos = (nframes_t) floor (prefix * session->frame_rate ());
+                       pos = (nframes64_t) floor (prefix * session->frame_rate ());
                } else {
-                       pos = (nframes_t) floor (prefix);
+                       pos = (nframes64_t) floor (prefix);
                }
        }
 
@@ -2187,13 +2209,13 @@ Editor::insert_region_list_drag (boost::shared_ptr<AudioRegion> region, int x, i
        double wx, wy;
        double cx, cy;
        TimeAxisView *tv;
-       nframes_t where;
+       nframes64_t where;
        AudioTimeAxisView *atv = 0;
        boost::shared_ptr<Playlist> playlist;
        
        track_canvas->window_to_world (x, y, wx, wy);
-       wx += horizontal_adjustment.get_value();
-       wy += vertical_adjustment.get_value();
+       //wx += horizontal_adjustment.get_value();
+       //wy += vertical_adjustment.get_value();
 
        GdkEvent event;
        event.type = GDK_BUTTON_RELEASE;
@@ -2640,17 +2662,17 @@ Editor::region_from_selection ()
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
 
-       nframes_t selection_cnt = end - start + 1;
+       nframes64_t selection_cnt = end - start + 1;
        
        for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
                boost::shared_ptr<AudioRegion> current;
                boost::shared_ptr<Region> current_r;
                boost::shared_ptr<Playlist> pl;
 
-               nframes_t internal_start;
+               nframes64_t internal_start;
                string new_name;
 
                if ((pl = (*i)->playlist()) == 0) {
@@ -2678,8 +2700,8 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<AudioRegion> >& n
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
        
        sort_track_selection ();
 
@@ -2688,7 +2710,7 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<AudioRegion> >& n
                boost::shared_ptr<AudioRegion> current;
                boost::shared_ptr<Region> current_r;
                boost::shared_ptr<Playlist> playlist;
-               nframes_t internal_start;
+               nframes64_t internal_start;
                string new_name;
 
                if ((playlist = (*i)->playlist()) == 0) {
@@ -2823,7 +2845,7 @@ Editor::separate_regions_between (const TimeSelection& ts)
                                                sigc::connection c = atv->view()->RegionViewAdded.connect (mem_fun(*this, &Editor::collect_new_region_view));
                                                latest_regionviews.clear ();
 
-                                               playlist->partition ((nframes_t)((*t).start * speed), (nframes_t)((*t).end * speed), true);
+                                               playlist->partition ((nframes64_t)((*t).start * speed), (nframes64_t)((*t).end * speed), true);
 
                                                c.disconnect ();
 
@@ -2940,7 +2962,7 @@ Editor::crop_region_to_selection ()
 }              
 
 void
-Editor::crop_region_to (nframes_t start, nframes_t end)
+Editor::crop_region_to (nframes64_t start, nframes64_t end)
 {
        vector<boost::shared_ptr<Playlist> > playlists;
        boost::shared_ptr<Playlist> playlist;
@@ -2978,9 +3000,9 @@ Editor::crop_region_to (nframes_t start, nframes_t end)
                return;
        }
                
-       nframes_t the_start;
-       nframes_t the_end;
-       nframes_t cnt;
+       nframes64_t the_start;
+       nframes64_t the_end;
+       nframes64_t cnt;
        
        begin_reversible_command (_("trim to selection"));
        
@@ -2998,7 +3020,7 @@ Editor::crop_region_to (nframes_t start, nframes_t end)
                   if the selection extends beyond the region
                */
                
-               the_start = max (the_start, region->position());
+               the_start = max (the_start, (nframes64_t) region->position());
                if (max_frames - the_start < region->length()) {
                        the_end = the_start + region->length() - 1;
                } else {
@@ -3019,7 +3041,7 @@ Editor::crop_region_to (nframes_t start, nframes_t end)
 void
 Editor::region_fill_track ()
 {
-       nframes_t end;
+       nframes64_t end;
        RegionSelection rs; 
 
        get_regions_for_action (rs);
@@ -3082,8 +3104,8 @@ Editor::region_fill_selection ()
        TreeModel::iterator i = region_list_display.get_selection()->get_selected();
        boost::shared_ptr<Region> region = (*i)[region_list_columns.region];
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
 
        boost::shared_ptr<Playlist> playlist; 
 
@@ -3091,7 +3113,7 @@ Editor::region_fill_selection ()
                return;
        }
 
-       nframes_t selection_length = end - start;
+       nframes64_t selection_length = end - start;
        float times = (float)selection_length / region->length();
        
        begin_reversible_command (_("fill selection"));
@@ -3151,15 +3173,23 @@ Editor::set_sync_point (nframes64_t where, const RegionSelection& rs)
 void
 Editor::remove_region_sync ()
 {
-       if (clicked_regionview) {
-               boost::shared_ptr<Region> region (clicked_regionview->region());
-               begin_reversible_command (_("remove sync"));
-                XMLNode &before = region->playlist()->get_state();
-               region->clear_sync_position ();
-                XMLNode &after = region->playlist()->get_state();
-               session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
-               commit_reversible_command ();
+       RegionSelection rs; 
+
+       get_regions_for_action (rs);
+
+       if (rs.empty()) {
+               return;
+       }
+
+       begin_reversible_command (_("remove sync"));
+       for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+
+                XMLNode &before = (*i)->region()->playlist()->get_state();
+               (*i)->region()->clear_sync_position ();
+                XMLNode &after = (*i)->region()->playlist()->get_state();
+               session->add_command(new MementoCommand<Playlist>(*((*i)->region()->playlist()), &before, &after));
        }
+       commit_reversible_command ();
 }
 
 void
@@ -3221,18 +3251,19 @@ struct RegionSortByTime {
 };
 
 void
-Editor::align_selection_relative (RegionPoint point, nframes_t position, const RegionSelection& rs)
+Editor::align_selection_relative (RegionPoint point, nframes64_t position, const RegionSelection& rs)
 {
        if (rs.empty()) {
                return;
        }
 
-       nframes_t distance;
-       nframes_t pos = 0;
-       int dir;
+       nframes64_t distance = 0;
+       nframes64_t pos = 0;
+       int dir = 1;
 
        list<RegionView*> sorted;
        rs.by_position (sorted);
+
        boost::shared_ptr<Region> r ((*sorted.begin())->region());
 
        switch (point) {
@@ -3240,7 +3271,6 @@ Editor::align_selection_relative (RegionPoint point, nframes_t position, const R
                pos = position;
                if (position > r->position()) {
                        distance = position - r->position();
-                       dir = 1;
                } else {
                        distance = r->position() - position;
                        dir = -1;
@@ -3251,7 +3281,6 @@ Editor::align_selection_relative (RegionPoint point, nframes_t position, const R
                if (position > r->last_frame()) {
                        distance = position - r->last_frame();
                        pos = r->position() + distance;
-                       dir = 1;
                } else {
                        distance = r->last_frame() - position;
                        pos = r->position() - distance;
@@ -3263,7 +3292,6 @@ Editor::align_selection_relative (RegionPoint point, nframes_t position, const R
                pos = r->adjust_to_sync (position);
                if (pos > r->position()) {
                        distance = pos - r->position();
-                       dir = 1;
                } else {
                        distance = r->position() - pos;
                        dir = -1;
@@ -3309,7 +3337,7 @@ Editor::align_selection_relative (RegionPoint point, nframes_t position, const R
 }
 
 void
-Editor::align_selection (RegionPoint point, nframes_t position, const RegionSelection& rs)
+Editor::align_selection (RegionPoint point, nframes64_t position, const RegionSelection& rs)
 {
        if (rs.empty()) {
                return;
@@ -3325,7 +3353,7 @@ Editor::align_selection (RegionPoint point, nframes_t position, const RegionSele
 }
 
 void
-Editor::align_region (boost::shared_ptr<Region> region, RegionPoint point, nframes_t position)
+Editor::align_region (boost::shared_ptr<Region> region, RegionPoint point, nframes64_t position)
 {
        begin_reversible_command (_("align region"));
        align_region_internal (region, point, position);
@@ -3333,7 +3361,7 @@ Editor::align_region (boost::shared_ptr<Region> region, RegionPoint point, nfram
 }
 
 void
-Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint point, nframes_t position)
+Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint point, nframes64_t position)
 {
        XMLNode &before = region->playlist()->get_state();
 
@@ -3409,8 +3437,8 @@ Editor::trim_region_to_location (const Location& loc, const char* str)
                }
 
                float speed = 1.0;
-               nframes_t start;
-               nframes_t end;
+               nframes64_t start;
+               nframes64_t end;
 
                if (atav->get_diskstream() != 0) {
                        speed = atav->get_diskstream()->speed();
@@ -3600,7 +3628,7 @@ Editor::freeze_route ()
 }
 
 void
-Editor::bounce_range_selection ()
+Editor::bounce_range_selection (bool replace)
 {
        if (selection->time.empty()) {
                return;
@@ -3608,9 +3636,9 @@ Editor::bounce_range_selection ()
 
        TrackSelection views = selection->tracks;
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
-       nframes_t cnt = end - start + 1;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
+       nframes64_t cnt = end - start + 1;
 
        begin_reversible_command (_("bounce range"));
 
@@ -3635,7 +3663,15 @@ Editor::bounce_range_selection ()
                itt.progress = false;
 
                 XMLNode &before = playlist->get_state();
-               atv->audio_track()->bounce_range (start, cnt, itt);
+               boost::shared_ptr<Region> r = atv->audio_track()->bounce_range (start, start+cnt, itt);
+               
+               if (replace) {
+                       list<AudioRange> ranges;
+                       ranges.push_back (AudioRange (start, start+cnt, 0));
+                       playlist->cut (ranges); // discard result
+                       playlist->add_region (r, start);
+               }
+
                 XMLNode &after = playlist->get_state();
                session->add_command (new MementoCommand<Playlist> (*playlist, &before, &after));
        }
@@ -3673,6 +3709,19 @@ Editor::cut_copy (CutCopyOp op)
                opname = _("clear");
                break;
        }
+
+       /* if we're deleting something, and the mouse is still pressed,
+          the thing we started a drag for will be gone when we release
+          the mouse button(s). avoid this. see part 2 at the end of
+          this function.
+       */
+
+       if (op == Cut || op == Clear) {
+               if (drag_info.item) {
+                       drag_info.item->ungrab (0);
+                       drag_info.item = 0;
+               }
+       }
        
        cut_buffer->clear ();
 
@@ -3687,6 +3736,8 @@ Editor::cut_copy (CutCopyOp op)
                        Glib::signal_idle().connect (bind (mem_fun(*this, &Editor::really_remove_marker), loc));
                }
 
+               break_drag ();
+
                return;
        }
 
@@ -3751,6 +3802,11 @@ Editor::cut_copy (CutCopyOp op)
        default:
                break;
        }
+
+
+       if (op == Cut || op == Clear) {
+               break_drag ();
+       }
 }
 
 void
@@ -3793,7 +3849,7 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
 
        vector<PlaylistMapping> pmap;
 
-       nframes_t first_position = max_frames;
+       nframes64_t first_position = max_frames;
        
        set<PlaylistState, lt_playlist> freezelist;
        pair<set<PlaylistState, lt_playlist>::iterator,bool> insert_result;
@@ -3804,7 +3860,7 @@ Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
 
        for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
 
-               first_position = min ((*x)->region()->position(), first_position);
+               first_position = min ((nframes64_t) (*x)->region()->position(), first_position);
 
                if (op == Cut || op == Clear) {
                        boost::shared_ptr<AudioPlaylist> pl = boost::dynamic_pointer_cast<AudioPlaylist>((*x)->region()->playlist());
@@ -3960,7 +4016,7 @@ Editor::mouse_paste ()
 }
 
 void
-Editor::paste_internal (nframes_t position, float times)
+Editor::paste_internal (nframes64_t position, float times)
 {
        bool commit = false;
 
@@ -4179,9 +4235,9 @@ void
 Editor::nudge_track (bool use_edit, bool forwards)
 {
        boost::shared_ptr<Playlist> playlist; 
-       nframes_t distance;
-       nframes_t next_distance;
-       nframes_t start;
+       nframes64_t distance;
+       nframes64_t next_distance;
+       nframes64_t start;
 
        if (use_edit) {
                start = get_preferred_edit_position();
@@ -4448,6 +4504,7 @@ Editor::region_selection_op (void (Region::*pmf)(bool), bool yn)
 void
 Editor::external_edit_region ()
 {
+       // XXX shouldn't this use get_regions_for_action(rs) too?       
        if (!clicked_regionview) {
                return;
        }
@@ -4456,7 +4513,7 @@ Editor::external_edit_region ()
 }
 
 void
-Editor::brush (nframes_t pos)
+Editor::brush (nframes64_t pos)
 {
        RegionSelection sel;
        RegionSelection rs; 
@@ -4609,7 +4666,7 @@ Editor::set_fade_length (bool in)
        }
 
        nframes64_t pos = get_preferred_edit_position();
-       nframes_t len;
+       nframes64_t len;
        char* cmd;
        
        if (pos > rv->region()->last_frame() || pos < rv->region()->first_frame()) {
@@ -4680,7 +4737,7 @@ Editor::toggle_fade_active (bool in)
 
        const char* cmd = (in ? _("toggle fade in active") : _("toggle fade out active"));
        bool have_switch = false;
-       bool yn;
+       bool yn = false;
 
        begin_reversible_command (cmd);
 
@@ -5053,8 +5110,8 @@ Editor::set_loop_from_selection (bool play)
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
        
        set_loop_range (start, end,  _("set loop range from selection"));
 
@@ -5124,8 +5181,8 @@ Editor::set_punch_from_selection ()
                return;
        }
 
-       nframes_t start = selection->time[clicked_selection].start;
-       nframes_t end = selection->time[clicked_selection].end;
+       nframes64_t start = selection->time[clicked_selection].start;
+       nframes64_t end = selection->time[clicked_selection].end;
        
        set_punch_range (start, end,  _("set punch range from selection"));
 }
@@ -5800,7 +5857,7 @@ Editor::do_insert_time ()
                return;
        }
        
-       nframes_t distance = clock.current_duration (pos);
+       nframes64_t distance = clock.current_duration (pos);
 
        if (distance == 0) {
                return;
@@ -5909,7 +5966,6 @@ Editor::fit_tracks ()
                first_y_pos = std::min ((*t)->y_position, first_y_pos);
        }
 
-
        vertical_adjustment.set_value (first_y_pos);
 
        redo_visual_stack.push_back (current_visual_state());