X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_ops.cc;h=2eb3987b8915fe75f8c6765e4ad58844dc3c9173;hb=5b520324ceab2559723b4ef5127301fa61ff4846;hp=7f3aa7f7a84347feef185d86eb0fb86b05e562c7;hpb=061a85191c301ac18f2e8ca59d43127a4499ba96;p=ardour.git diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 7f3aa7f7a8..2eb3987b89 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -157,7 +157,6 @@ Editor::split_regions_at (nframes64_t where, RegionSelection& regions) boost::shared_ptr pl = (*a)->region()->playlist(); if (!pl) { - cerr << "region " << (*a)->region()->name() << " has no playlist!\n"; a = tmp; continue; } @@ -170,11 +169,6 @@ Editor::split_regions_at (nframes64_t where, RegionSelection& regions) pl->freeze(); } - AudioRegionView* const arv = dynamic_cast(*a); - if (arv) { - _new_regionviews_show_envelope = arv->envelope_visible(); - } - if (pl) { pl->clear_history (); pl->split_region ((*a)->region(), where); @@ -191,7 +185,6 @@ Editor::split_regions_at (nframes64_t where, RegionSelection& regions) } commit_reversible_command (); - _new_regionviews_show_envelope = false; } boost::shared_ptr @@ -559,7 +552,7 @@ Editor::move_to_end () void Editor::build_region_boundary_cache () { - nframes64_t pos = 0; + framepos_t pos = 0; vector interesting_points; boost::shared_ptr r; TrackViewList tracks; @@ -602,8 +595,8 @@ Editor::build_region_boundary_cache () while (pos < _session->current_end_frame() && !at_end) { - nframes64_t rpos; - nframes64_t lpos = max_frames; + framepos_t rpos; + framepos_t lpos = max_frames; for (vector::iterator p = interesting_points.begin(); p != interesting_points.end(); ++p) { @@ -652,7 +645,7 @@ Editor::build_region_boundary_cache () to sort later. */ - vector::iterator ri; + vector::iterator ri; for (ri = region_boundary_cache.begin(); ri != region_boundary_cache.end(); ++ri) { if (*ri == rpos) { @@ -671,23 +664,29 @@ Editor::build_region_boundary_cache () /* finally sort to be sure that the order is correct */ sort (region_boundary_cache.begin(), region_boundary_cache.end()); + + cerr << "RBC contains " << region_boundary_cache.size() << endl; + + for (vector::iterator x = region_boundary_cache.begin(); x != region_boundary_cache.end(); ++x) { + cerr << "Region boundary @ " << *x << endl; + } } boost::shared_ptr -Editor::find_next_region (nframes64_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack) +Editor::find_next_region (framepos_t frame, RegionPoint point, int32_t dir, TrackViewList& tracks, TimeAxisView **ontrack) { TrackViewList::iterator i; nframes64_t closest = max_frames; boost::shared_ptr ret; - nframes64_t rpos = 0; + framepos_t rpos = 0; float track_speed; - nframes64_t track_frame; + framepos_t track_frame; RouteTimeAxisView *rtav; for (i = tracks.begin(); i != tracks.end(); ++i) { - nframes64_t distance; + framecnt_t distance; boost::shared_ptr r; track_speed = 1.0f; @@ -737,17 +736,16 @@ Editor::find_next_region (nframes64_t frame, RegionPoint point, int32_t dir, Tra return ret; } -nframes64_t -Editor::find_next_region_boundary (nframes64_t pos, int32_t dir, const TrackViewList& tracks) +framepos_t +Editor::find_next_region_boundary (framepos_t pos, int32_t dir, const TrackViewList& tracks) { - nframes64_t distance = max_frames; - nframes64_t current_nearest = -1; - + framecnt_t distance = max_frames; + framepos_t current_nearest = -1; for (TrackViewList::const_iterator i = tracks.begin(); i != tracks.end(); ++i) { - nframes64_t contender; - nframes64_t d; - + framepos_t contender; + framecnt_t d; + RouteTimeAxisView* rtv = dynamic_cast (*i); if (!rtv) { @@ -769,10 +767,10 @@ Editor::find_next_region_boundary (nframes64_t pos, int32_t dir, const TrackView return current_nearest; } -nframes64_t -Editor::get_region_boundary (nframes64_t pos, int32_t dir, bool with_selection, bool only_onscreen) +framepos_t +Editor::get_region_boundary (framepos_t pos, int32_t dir, bool with_selection, bool only_onscreen) { - nframes64_t target; + framepos_t target; TrackViewList tvl; if (with_selection && Config->get_region_boundaries_from_selected_tracks()) { @@ -1742,7 +1740,7 @@ Editor::temporal_zoom_region (bool both_axes) for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { if (find (tracks.begin(), tracks.end(), (*i)) == tracks.end()) { - hide_track_in_display (**i, true); + hide_track_in_display (*i, true); } } @@ -1782,7 +1780,13 @@ Editor::temporal_zoom_session () ENSURE_GUI_THREAD (*this, &Editor::temporal_zoom_session) if (_session) { - temporal_zoom_by_frame (_session->current_start_frame(), _session->current_end_frame(), "zoom to _session"); + nframes_t const l = _session->current_end_frame() - _session->current_start_frame(); + double s = _session->current_start_frame() - l * 0.01; + if (s < 0) { + s = 0; + } + nframes_t const e = _session->current_end_frame() + l * 0.01; + temporal_zoom_by_frame (nframes_t (s), e, "zoom to _session"); } } @@ -1900,7 +1904,7 @@ Editor::add_location_from_selection () nframes64_t end = selection->time[clicked_selection].end; _session->locations()->next_available_name(rangename,"selection"); - Location *location = new Location (start, end, rangename, Location::IsRangeMarker); + Location *location = new Location (*_session, start, end, rangename, Location::IsRangeMarker); _session->begin_reversible_command (_("add marker")); XMLNode &before = _session->locations()->get_state(); @@ -1921,7 +1925,7 @@ Editor::add_location_mark (nframes64_t where) if (!choose_new_marker_name(markername)) { return; } - Location *location = new Location (where, where, markername, Location::IsMark); + Location *location = new Location (*_session, where, where, markername, Location::IsMark); _session->begin_reversible_command (_("add marker")); XMLNode &before = _session->locations()->get_state(); _session->locations()->add (location, true); @@ -1950,13 +1954,11 @@ Editor::add_locations_from_audio_region () _session->begin_reversible_command (rs.size () > 1 ? _("add markers") : _("add marker")); XMLNode &before = _session->locations()->get_state(); - cerr << "Add locations\n"; - for (RegionSelection::iterator i = rs.begin (); i != rs.end (); ++i) { boost::shared_ptr region = (*i)->region (); - Location *location = new Location (region->position(), region->last_frame(), region->name(), Location::IsRangeMarker); + Location *location = new Location (*_session, region->position(), region->last_frame(), region->name(), Location::IsRangeMarker); _session->locations()->add (location, true); } @@ -1994,10 +1996,8 @@ Editor::add_location_from_audio_region () return; } - cerr << "Add location\n"; - // single range spanning all selected - Location *location = new Location (rs.start(), rs.end_frame(), markername, Location::IsRangeMarker); + Location *location = new Location (*_session, rs.start(), rs.end_frame(), markername, Location::IsRangeMarker); _session->locations()->add (location, true); XMLNode &after = _session->locations()->get_state(); @@ -2114,7 +2114,7 @@ Editor::set_mark () if (!choose_new_marker_name(markername)) { return; } - _session->locations()->add (new Location (pos, 0, markername, Location::IsMark), true); + _session->locations()->add (new Location (*_session, pos, 0, markername, Location::IsMark), true); } void @@ -2197,8 +2197,6 @@ Editor::insert_region_list_drag (boost::shared_ptr region, int x, int y) boost::shared_ptr playlist; track_canvas->window_to_world (x, y, wx, wy); - //wx += horizontal_adjustment.get_value(); - //wy += vertical_adjustment.get_value(); GdkEvent event; event.type = GDK_BUTTON_RELEASE; @@ -2235,7 +2233,8 @@ Editor::insert_region_list_drag (boost::shared_ptr region, int x, int y) } void -Editor::insert_route_list_drag (boost::shared_ptr route, int x, int y) { +Editor::insert_route_list_drag (boost::shared_ptr route, int x, int y) +{ double wx, wy; double cx, cy; nframes_t where; @@ -2243,7 +2242,7 @@ Editor::insert_route_list_drag (boost::shared_ptr route, int x, int y) { RouteTimeAxisView *source_rtv = 0; track_canvas->window_to_world (x, y, wx, wy); - wx += horizontal_adjustment.get_value(); + wx += horizontal_position (); wy += vertical_adjustment.get_value(); GdkEvent event; @@ -2799,10 +2798,11 @@ Editor::separate_regions_between (const TimeSelection& ts) sigc::connection c = rtv->view()->RegionViewAdded.connect ( sigc::mem_fun(*this, &Editor::collect_new_region_view)); + latest_regionviews.clear (); playlist->partition ((nframes64_t)((*t).start * speed), - (nframes64_t)((*t).end * speed), true); + (nframes64_t)((*t).end * speed), false); c.disconnect (); @@ -2816,6 +2816,17 @@ Editor::separate_regions_between (const TimeSelection& ts) begin_reversible_command (_("separate")); in_command = true; } + + /* pick up changes to existing regions */ + + vector cmds; + playlist->rdiff (cmds); + for (vector::iterator j = cmds.begin(); j != cmds.end(); ++j) { + _session->add_command (*j); + } + + /* pick up changes to the playlist itself (adds/removes) + */ _session->add_command(new StatefulDiffCommand (playlist)); } @@ -2833,6 +2844,11 @@ Editor::separate_regions_between (const TimeSelection& ts) } } +struct PlaylistState { + boost::shared_ptr playlist; + XMLNode* before; +}; + /** Take tracks from get_tracks_for_range_action and cut any regions * on those tracks so that the tracks are empty over the time * selection. @@ -2898,6 +2914,85 @@ Editor::separate_regions_using_location (Location& loc) separate_regions_between (ts); } +/** Separate regions under the selected region */ +void +Editor::separate_under_selected_regions () +{ + RegionSelection rs; + get_regions_for_action (rs); + + vector playlists; + + if (!_session) { + return; + } + + if (rs.empty()) { + return; + } + + begin_reversible_command (_("separate region under")); + + list > regions_to_remove; + + 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 >::iterator rl = regions_to_remove.begin(); rl != regions_to_remove.end(); ++rl) { + + boost::shared_ptr playlist = (*rl)->playlist(); + + if (!playlist) { + // is this check necessary? + continue; + } + + vector::iterator i; + + //only take state if this is a new playlist. + for (i = playlists.begin(); i != playlists.end(); ++i) { + if ((*i).playlist == playlist) { + break; + } + } + + if (i == playlists.end()) { + + PlaylistState before; + before.playlist = playlist; + before.before = &playlist->get_state(); + + playlist->freeze (); + playlists.push_back(before); + } + + //Partition on the region bounds + playlist->partition ((*rl)->first_frame() - 1, (*rl)->last_frame() + 1, true); + + //Re-add region that was just removed due to the partition operation + playlist->add_region( (*rl), (*rl)->first_frame() ); + } + + vector::iterator pl; + + for (pl = playlists.begin(); pl != playlists.end(); ++pl) { + (*pl).playlist->thaw (); + _session->add_command(new MementoCommand(*(*pl).playlist, (*pl).before, &(*pl).playlist->get_state())); + } + + commit_reversible_command (); +} + void Editor::crop_region_to_selection () { @@ -3349,12 +3444,15 @@ Editor::trim_region (bool front) for (list::const_iterator i = rs.by_layer().begin(); i != rs.by_layer().end(); ++i) { if (!(*i)->region()->locked()) { - (*i)->region()->clear_history (); + + (*i)->region()->clear_history (); + if (front) { (*i)->region()->trim_front (where, this); } else { (*i)->region()->trim_end (where, this); } + _session->add_command (new StatefulDiffCommand ((*i)->region())); } } @@ -3559,7 +3657,7 @@ Editor::trim_to_region(bool forward) continue; } - region->trim_end((nframes64_t) (next_region->first_frame() * speed), this); + region->trim_end((nframes64_t) ( (next_region->first_frame() - 1) * speed), this); arv->region_changed (PropertyChange (ARDOUR::Properties::length)); } else { @@ -3619,10 +3717,6 @@ Editor::freeze_route () InterthreadProgressWindow ipw (current_interthread_info, _("Freeze"), _("Cancel Freeze")); - itt.done = false; - itt.cancel = false; - itt.progress = 0.0f; - pthread_create_and_store (X_("freezer"), &itt.thread, _freeze_thread, this); track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH)); @@ -3666,11 +3760,9 @@ Editor::bounce_range_selection (bool replace, bool enable_processing) InterThreadInfo itt; - itt.done = false; - itt.cancel = false; - itt.progress = false; - playlist->clear_history (); + playlist->clear_owned_history (); + boost::shared_ptr r = rtv->track()->bounce_range (start, start+cnt, itt, enable_processing); if (replace) { @@ -3680,7 +3772,13 @@ Editor::bounce_range_selection (bool replace, bool enable_processing) playlist->add_region (r, start); } - _session->add_command (new StatefulDiffCommand (playlist)); + vector cmds; + playlist->rdiff (cmds); + for (vector::iterator j = cmds.begin(); j != cmds.end(); ++j) { + _session->add_command (*j); + } + + _session->add_command (new StatefulDiffCommand (playlist)); } commit_reversible_command (); @@ -3774,7 +3872,7 @@ Editor::cut_copy (CutCopyOp op) Glib::signal_idle().connect (sigc::bind (sigc::mem_fun(*this, &Editor::really_remove_marker), loc)); } - _drags->break_drag (); + _drags->abort (); return; } @@ -3855,7 +3953,7 @@ Editor::cut_copy (CutCopyOp op) } if (op == Cut || op == Clear) { - _drags->break_drag (); + _drags->abort (); } } @@ -3887,6 +3985,14 @@ Editor::cut_copy_midi (CutCopyOp op) } } + + +struct lt_playlist { + bool operator () (const PlaylistState& a, const PlaylistState& b) { + return a.playlist < b.playlist; + } +}; + struct PlaylistMapping { TimeAxisView* tv; boost::shared_ptr pl; @@ -4258,7 +4364,7 @@ Editor::duplicate_some_regions (RegionSelection& regions, float times) playlist = (*i)->region()->playlist(); playlist->clear_history (); - playlist->duplicate (r, end_frame + (r->first_frame() - start_frame) + 1, times); + playlist->duplicate (r, end_frame + (r->first_frame() - start_frame), times); _session->add_command(new StatefulDiffCommand (playlist)); c.disconnect (); @@ -4420,10 +4526,12 @@ Editor::remove_last_capture () if (prompter.run () == 1) { _session->remove_last_capture (); + _regions->redisplay (); } } else { _session->remove_last_capture(); + _regions->redisplay (); } } @@ -4443,6 +4551,8 @@ Editor::normalize_region () Dialog dialog (rs.size() > 1 ? _("Normalize regions") : _("Normalize region")); HBox hbox; + hbox.set_spacing (6); + hbox.set_border_width (6); hbox.pack_start (*manage (new Label (_("Normalize to:")))); SpinButton spin (0.2, 2); spin.set_range (-112, 0); @@ -4452,6 +4562,7 @@ Editor::normalize_region () spin.set_value (_last_normalization_value); hbox.pack_start (*manage (new Label (_("dbFS")))); hbox.show_all (); + dialog.get_vbox()->set_spacing (12); dialog.get_vbox()->pack_start (hbox); dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL); dialog.add_button (_("Normalize"), RESPONSE_ACCEPT); @@ -4611,7 +4722,7 @@ Command* Editor::apply_midi_note_edit_op_to_region (MidiOperator& op, MidiRegionView& mrv) { Evoral::Sequence::Notes selected; - mrv.selection_as_notelist (selected); + mrv.selection_as_notelist (selected, true); vector::Notes> v; v.push_back (selected); @@ -4654,6 +4765,46 @@ Editor::apply_midi_note_edit_op (MidiOperator& op) rs.clear (); } +void +Editor::fork_region () +{ + RegionSelection rs; + + get_regions_for_action (rs); + + if (rs.empty()) { + return; + } + + begin_reversible_command (_("Fork Region(s)")); + + track_canvas->get_window()->set_cursor (*wait_cursor); + gdk_flush (); + + for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) { + RegionSelection::iterator tmp = r; + ++tmp; + + MidiRegionView* const mrv = dynamic_cast(*r); + + if (mrv) { + boost::shared_ptr playlist = mrv->region()->playlist(); + boost::shared_ptr newregion = mrv->midi_region()->clone (); + + playlist->clear_history (); + playlist->replace_region (mrv->region(), newregion, mrv->region()->position()); + _session->add_command(new StatefulDiffCommand (playlist)); + } + + r = tmp; + } + + commit_reversible_command (); + rs.clear (); + + track_canvas->get_window()->set_cursor (*current_canvas_cursor); +} + void Editor::quantize_region () { @@ -4887,7 +5038,7 @@ Editor::toggle_region_lock () } void -Editor::set_region_lock_style (Region::PositionLockStyle ps) +Editor::toggle_region_lock_style () { RegionSelection rs = get_equivalent_regions (selection->regions, ARDOUR::Properties::edit.property_id); @@ -4899,7 +5050,8 @@ Editor::set_region_lock_style (Region::PositionLockStyle ps) for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { (*i)->region()->clear_history (); - (*i)->region()->set_position_lock_style (ps); + PositionLockStyle const ns = (*i)->region()->position_lock_style() == AudioTime ? MusicTime : AudioTime; + (*i)->region()->set_position_lock_style (ns); _session->add_command (new StatefulDiffCommand ((*i)->region())); } @@ -4964,7 +5116,7 @@ Editor::toggle_record_enable () first = false; } - rtav->track()->set_record_enable(new_state, this); + rtav->track()->set_record_enabled (new_state, this); } } @@ -4986,7 +5138,7 @@ Editor::set_fade_length (bool in) nframes64_t pos = get_preferred_edit_position(); nframes64_t len; - char* cmd; + char const * cmd; if (pos > rv->region()->last_frame() || pos < rv->region()->first_frame()) { /* edit point is outside the relevant region */ @@ -5352,6 +5504,13 @@ Editor::set_playhead_cursor () void Editor::split () { + if (((mouse_mode == MouseRange) || + (mouse_mode != MouseObject && _join_object_range_state == JOIN_OBJECT_RANGE_RANGE)) && + !selection->time.empty()) { + separate_regions_between (selection->time); + return; + } + RegionSelection rs; get_regions_for_action (rs, true); @@ -5814,6 +5973,7 @@ Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList int response = msg.run(); msg.hide (); + switch (response) { case RESPONSE_OK: break; @@ -5832,19 +5992,10 @@ Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList AnalysisFeatureList::const_iterator x; - nframes64_t pos = r->position(); - pl->clear_history (); x = positions.begin(); - while (x != positions.end()) { - if ((*x) > pos) { - break; - } - ++x; - } - if (x == positions.end()) { return; } @@ -5852,18 +6003,26 @@ Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList pl->freeze (); pl->remove_region (r); + nframes64_t pos = 0; + while (x != positions.end()) { + + /* deal with positons that are out of scope of present region bounds */ + if (*x <= 0 || *x > r->length()){ + ++x; + continue; + } /* file start = original start + how far we from the initial position ? */ - nframes64_t file_start = r->start() + (pos - r->position()); + nframes64_t file_start = r->start() + pos; /* length = next position - current position */ nframes64_t len = (*x) - pos; - + /* XXX we do we really want to allow even single-sample regions? shouldn't we have some kind of lower limit on region size? */ @@ -5888,35 +6047,190 @@ Editor::split_region_at_points (boost::shared_ptr r, AnalysisFeatureList plist.add (ARDOUR::Properties::layer, 0); boost::shared_ptr nr = RegionFactory::create (r->sources(), plist, false); - pl->add_region (nr, pos); + pl->add_region (nr, r->position() + pos); pos += len; ++x; + } - if (*x > r->last_frame()) { + string new_name; - /* add final fragment */ + RegionFactory::region_name (new_name, r->name()); + + /* Add the final region */ + PropertyList plist; + + plist.add (ARDOUR::Properties::start, r->start() + pos); + plist.add (ARDOUR::Properties::length, r->last_frame() - (r->position() + pos) + 1); + plist.add (ARDOUR::Properties::name, new_name); + plist.add (ARDOUR::Properties::layer, 0); - file_start = r->start() + (pos - r->position()); - len = r->last_frame() - pos; + boost::shared_ptr nr = RegionFactory::create (r->sources(), plist, false); + pl->add_region (nr, r->position() + pos); - PropertyList plist2; - - plist2.add (ARDOUR::Properties::start, file_start); - plist2.add (ARDOUR::Properties::length, len); - plist2.add (ARDOUR::Properties::name, new_name); - plist2.add (ARDOUR::Properties::layer, 0); + + pl->thaw (); - nr = RegionFactory::create (r->sources(), plist2); - pl->add_region (nr, pos); + _session->add_command (new StatefulDiffCommand (pl)); +} - break; - } +void +Editor::place_transient() +{ + if (!_session) { + return; } - pl->thaw (); + RegionSelection rs; - _session->add_command (new StatefulDiffCommand (pl)); + get_regions_for_action (rs); + + if (rs.empty()) { + return; + } + + nframes64_t where = get_preferred_edit_position(); + + _session->begin_reversible_command (_("place transient")); + + for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { + framepos_t position = (*r)->region()->position(); + (*r)->region()->add_transient(where - position); + } + + _session->commit_reversible_command (); +} + +void +Editor::remove_transient(ArdourCanvas::Item* item) +{ + if (!_session) { + return; + } + + ArdourCanvas::SimpleLine* _line = reinterpret_cast (item); + assert (_line); + + AudioRegionView* _arv = reinterpret_cast (item->get_data ("regionview")); + _arv->remove_transient(_line->property_x1()); +} + +void +Editor::snap_regions_to_grid() +{ + if (!_session) { + return; + } + + RegionSelection rs; + + get_regions_for_action (rs); + + if (rs.empty()) { + return; + } + + _session->begin_reversible_command (_("snap regions to grid")); + + for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { + framepos_t start_frame = (*r)->region()->first_frame (); + snap_to (start_frame); + (*r)->region()->set_position (start_frame, this); + } + + _session->commit_reversible_command (); +} + +void +Editor::close_region_gaps() +{ + if (!_session) { + return; + } + + RegionSelection rs; + + get_regions_for_action (rs); + + if (rs.empty()) { + return; + } + + Dialog dialog (rs.size() > 1 ? _("Conform regions") : _("Conform region")); + + HBox hbox_crossfade; + hbox_crossfade.set_spacing (10); + //hbox_crossfade.set_border_width (3); + hbox_crossfade.pack_start (*manage (new Label (_("Crossfade length:")))); + + SpinButton spin_crossfade (1, 0); + spin_crossfade.set_range (0, 15); + spin_crossfade.set_increments (1, 1); + spin_crossfade.set_value (3); + + hbox_crossfade.pack_start (spin_crossfade); + hbox_crossfade.pack_start (*manage (new Label (_("ms")))); + hbox_crossfade.show_all (); + + HBox hbox_pullback; + + hbox_pullback.set_spacing (10); + //hbox_pullback.set_border_width (3); + hbox_pullback.pack_start (*manage (new Label (_("Pull-back length:")))); + + SpinButton spin_pullback (1, 0); + spin_pullback.set_range (0, 15); + spin_pullback.set_increments (1, 1); + spin_pullback.set_value (5); + + hbox_pullback.pack_start (spin_pullback); + hbox_pullback.pack_start (*manage (new Label (_("ms")))); + hbox_pullback.show_all (); + + dialog.get_vbox()->set_spacing (6); + dialog.get_vbox()->pack_start (hbox_crossfade); + dialog.get_vbox()->pack_start (hbox_pullback); + dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL); + dialog.add_button (_("Ok"), RESPONSE_ACCEPT); + + if (dialog.run () == RESPONSE_CANCEL) { + return; + } + + nframes64_t crossfade_len = spin_crossfade.get_value(); + nframes64_t pull_back_frames = spin_pullback.get_value(); + + crossfade_len = lrintf (crossfade_len * _session->frame_rate()/1000); + pull_back_frames = lrintf (pull_back_frames * _session->frame_rate()/1000); + + /* Iterate over the region list and make adjacent regions overlap by crossfade_len_ms */ + + _session->begin_reversible_command (_("close region gaps")); + + int idx = 0; + boost::shared_ptr last_region; + + rs.sort_by_position_and_track(); + + for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { + + nframes64_t position = (*r)->region()->position(); + + if (idx == 0 || position < last_region->position()){ + last_region = (*r)->region(); + idx++; + continue; + } + + (*r)->region()->trim_front( (position - pull_back_frames), this ); + last_region->trim_end( (position - pull_back_frames + crossfade_len), this ); + + last_region = (*r)->region(); + + idx++; + } + + _session->commit_reversible_command (); } void @@ -5995,6 +6309,7 @@ Editor::tab_to_transient (bool forward) } } } + void Editor::playhead_forward_to_grid () { @@ -6021,7 +6336,7 @@ Editor::playhead_backward_to_grid () } void -Editor::set_track_height (uint32_t h) +Editor::set_track_height (Height h) { TrackSelection& ts (selection->tracks); @@ -6070,6 +6385,7 @@ Editor::remove_tracks () const char* trackstr; const char* busstr; vector > routes; + bool special_bus = false; for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) { RouteTimeAxisView* rtv = dynamic_cast (*x); @@ -6081,8 +6397,30 @@ Editor::remove_tracks () } } routes.push_back (rtv->_route); - } + if (rtv->route()->is_master() || rtv->route()->is_monitor()) { + special_bus = true; + } + } + + if (special_bus && !Config->get_allow_special_bus_removal()) { + MessageDialog msg (_("That would be bad news ...."), + false, + Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK); + msg.set_secondary_text (string_compose (_( +"Removing the master or monitor bus is such a bad idea\n\ +that %1 is not going to allow it.\n\ +\n\ +If you really want to do this sort of thing\n\ +edit your ardour.rc file to set the\n\ +\"allow-special-bus-removal\" option to be \"yes\""), PROGRAM_NAME)); + + msg.present (); + msg.run (); + return; + } + if (ntracks + nbusses == 0) { return; } @@ -6202,7 +6540,8 @@ Editor::do_insert_time () return; } - InsertTimeOption opt; + /* only setting this to keep GCC quiet */ + InsertTimeOption opt = LeaveIntersected; switch (intersected_combo.get_active_row_number ()) { case 0: @@ -6250,8 +6589,6 @@ Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt, pl->rdiff (cmds); - cerr << "Shift generated " << cmds.size() << " sdc's\n"; - for (vector::iterator c = cmds.begin(); c != cmds.end(); ++c) { _session->add_command (*c); } @@ -6329,7 +6666,7 @@ Editor::fit_tracks (TrackViewList & tracks) uint32_t h = (uint32_t) floor ((_canvas_height - child_heights - canvas_timebars_vsize) / tracks.size()); double first_y_pos = DBL_MAX; - if (h < TimeAxisView::hSmall) { + if (h < TimeAxisView::preset_height (HeightSmall)) { MessageDialog msg (*this, _("There are too many tracks to fit in the current window")); /* too small to be displayed */ return; @@ -6361,7 +6698,7 @@ Editor::fit_tracks (TrackViewList & tracks) first_y_pos = std::min ((*t)->y_position (), first_y_pos); } else { if (prev_was_selected && next_is_selected) { - hide_track_in_display (**t); + hide_track_in_display (*t); } }