X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_ops.cc;h=41fe50d6ef59b79db0853c9807733588500bc128;hb=631629b8e7d3ca826fc55901653c1c795a8a5083;hp=0441ee9e524f5a17329385f89a3ac49c28441fc1;hpb=eb1e423b7521d4c277c11a884113f40e7406ade8;p=ardour.git diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 0441ee9e52..41fe50d6ef 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -42,6 +42,7 @@ #include "widgets/choice.h" #include "widgets/popup.h" +#include "widgets/prompter.h" #include "ardour/audio_track.h" #include "ardour/audioregion.h" @@ -62,6 +63,7 @@ #include "ardour/strip_silence.h" #include "ardour/transient_detector.h" #include "ardour/transpose.h" +#include "ardour/vca_manager.h" #include "canvas/canvas.h" @@ -105,6 +107,7 @@ #include "transpose_dialog.h" #include "transform_dialog.h" #include "ui_config.h" +#include "vca_time_axis.h" #include "pbd/i18n.h" @@ -720,9 +723,12 @@ Editor::build_region_boundary_cache () return; } + bool maybe_first_frame = false; + switch (_snap_type) { case SnapToRegionStart: interesting_points.push_back (Start); + maybe_first_frame = true; break; case SnapToRegionEnd: interesting_points.push_back (End); @@ -733,6 +739,7 @@ Editor::build_region_boundary_cache () case SnapToRegionBoundary: interesting_points.push_back (Start); interesting_points.push_back (End); + maybe_first_frame = true; break; default: fatal << string_compose (_("build_region_boundary_cache called with snap_type = %1"), _snap_type) << endmsg; @@ -749,6 +756,17 @@ Editor::build_region_boundary_cache () tlist = track_views.filter_to_unique_playlists (); } + if (maybe_first_frame) { + TrackViewList::const_iterator i; + for (i = tlist.begin(); i != tlist.end(); ++i) { + boost::shared_ptr pl = (*i)->playlist(); + if (pl && pl->count_regions_at (0)) { + region_boundary_cache.push_back (0); + break; + } + } + } + while (pos < _session->current_end_frame() && !at_end) { framepos_t rpos; @@ -1771,6 +1789,13 @@ Editor::temporal_zoom_step_scale (bool zoom_out, double scale) } } + //zoom-behavior-tweaks + //limit our maximum zoom to the session gui extents value + std::pair ext = session_gui_extents(); + framecnt_t session_extents_pp = ( ext.second - ext.first ) / _visible_canvas_width; + if (nspp > session_extents_pp) + nspp = session_extents_pp; + temporal_zoom (nspp); } @@ -2033,6 +2058,39 @@ Editor::temporal_zoom_session () } } +void +Editor::temporal_zoom_extents () +{ + ENSURE_GUI_THREAD (*this, &Editor::temporal_zoom_extents) + + if (_session) { + std::pair ext = session_gui_extents( false ); //in this case we want to zoom to the extents explicitly; ignore the users prefs for extra padding + + framecnt_t start = ext.first; + framecnt_t end = ext.second; + + if (_session->actively_recording () ) { + framepos_t cur = playhead_cursor->current_frame (); + if (cur > end) { + /* recording beyond the end marker; zoom out + * by 5 seconds more so that if 'follow + * playhead' is active we don't immediately + * scroll. + */ + end = cur + _session->frame_rate() * 5; + } + } + + if ((start == 0 && end == 0) || end < start) { + return; + } + + calc_extra_zoom_edges(start, end); + + temporal_zoom_by_frame (start, end); + } +} + void Editor::temporal_zoom_by_frame (framepos_t start, framepos_t end) { @@ -2121,7 +2179,7 @@ Editor::choose_new_marker_name(string &name) { return true; } - ArdourPrompter dialog (true); + Prompter dialog (true); dialog.set_prompt (_("New Name:")); @@ -3031,7 +3089,7 @@ Editor::split_multichannel_region () vector< boost::shared_ptr > v; for (list::iterator x = rs.begin(); x != rs.end(); ++x) { - (*x)->region()->separate_by_channel (*_session, v); + (*x)->region()->separate_by_channel (v); } } @@ -3297,7 +3355,7 @@ Editor::separate_under_selected_regions () PlaylistState before; before.playlist = playlist; before.before = &playlist->get_state(); - + playlist->clear_changes (); playlist->freeze (); playlists.push_back(before); } @@ -3324,15 +3382,22 @@ Editor::crop_region_to_selection () { if (!selection->time.empty()) { - crop_region_to (selection->time.start(), selection->time.end_frame()); - + begin_reversible_command (_("Crop Regions to Time Selection")); + for (std::list::iterator i = selection->time.begin(); i != selection->time.end(); ++i) { + crop_region_to ((*i).start, (*i).end); + } + commit_reversible_command(); } else { framepos_t start; framepos_t end; if (get_edit_op_range (start, end)) { + begin_reversible_command (_("Crop Regions to Edit Range")); + crop_region_to (start, end); + + commit_reversible_command(); } } @@ -3379,7 +3444,6 @@ Editor::crop_region_to (framepos_t start, framepos_t end) framepos_t new_start; framepos_t new_end; framecnt_t new_length; - bool in_command = false; for (vector >::iterator i = playlists.begin(); i != playlists.end(); ++i) { @@ -3409,19 +3473,11 @@ Editor::crop_region_to (framepos_t start, framepos_t end) 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; - } (*i)->clear_changes (); (*i)->trim_to (new_start, new_length); _session->add_command (new StatefulDiffCommand (*i)); } } - - if (in_command) { - commit_reversible_command (); - } } void @@ -4147,8 +4203,9 @@ Editor::cut_copy (CutCopyOp op) } } - if ( op != Delete ) //"Delete" doesn't change copy/paste buf + if ( op != Delete ) { //"Delete" doesn't change copy/paste buf cut_buffer->clear (); + } if (entered_marker) { @@ -4220,7 +4277,7 @@ Editor::cut_copy (CutCopyOp op) if (did_edit) { /* reset repeated paste state */ paste_count = 0; - last_paste_pos = 0; + last_paste_pos = -1; commit_reversible_command (); } @@ -5367,6 +5424,7 @@ Editor::apply_midi_note_edit_op (MidiOperator& op, const RegionSelection& rs) if (in_command) { commit_reversible_command (); + _session->set_dirty (); } } @@ -5873,18 +5931,18 @@ Editor::toggle_solo () boost::shared_ptr cl (new ControlList); for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { - RouteTimeAxisView *rtav = dynamic_cast(*i); + StripableTimeAxisView *stav = dynamic_cast(*i); - if (!rtav) { + if (!stav || !stav->stripable()->solo_control()) { continue; } if (first) { - new_state = !rtav->route()->soloed (); + new_state = !stav->stripable()->solo_control()->soloed (); first = false; } - cl->push_back (rtav->route()->solo_control()); + cl->push_back (stav->stripable()->solo_control()); } _session->set_controls (cl, new_state ? 1.0 : 0.0, Controllable::UseGroup); @@ -5895,24 +5953,24 @@ Editor::toggle_mute () { bool new_state = false; bool first = true; - boost::shared_ptr rl (new RouteList); + boost::shared_ptr cl (new ControlList); for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { - RouteTimeAxisView *rtav = dynamic_cast(*i); + StripableTimeAxisView *stav = dynamic_cast(*i); - if (!rtav) { + if (!stav || !stav->stripable()->mute_control()) { continue; } if (first) { - new_state = !rtav->route()->muted(); + new_state = !stav->stripable()->mute_control()->muted(); first = false; } - rl->push_back (rtav->route()); + cl->push_back (stav->stripable()->mute_control()); } - _session->set_controls (route_list_to_control_list (rl, &Stripable::mute_control), new_state, Controllable::UseGroup); + _session->set_controls (cl, new_state, Controllable::UseGroup); } void @@ -6316,7 +6374,7 @@ Editor::split_region () } void -Editor::select_next_route() +Editor::select_next_stripable (bool routes_only) { if (selection->tracks.empty()) { selection->set (track_views.front()); @@ -6325,7 +6383,7 @@ Editor::select_next_route() TimeAxisView* current = selection->tracks.front(); - RouteUI *rui; + bool valid; do { for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { @@ -6341,9 +6399,14 @@ Editor::select_next_route() } } - rui = dynamic_cast(current); + if (routes_only) { + RouteUI* rui = dynamic_cast(current); + valid = rui && rui->route()->active(); + } else { + valid = 0 != current->stripable ().get(); + } - } while (current->hidden() || (rui == NULL) || !rui->route()->active()); + } while (current->hidden() || !valid); selection->set (current); @@ -6351,7 +6414,7 @@ Editor::select_next_route() } void -Editor::select_prev_route() +Editor::select_prev_stripable (bool routes_only) { if (selection->tracks.empty()) { selection->set (track_views.front()); @@ -6360,7 +6423,7 @@ Editor::select_prev_route() TimeAxisView* current = selection->tracks.front(); - RouteUI *rui; + bool valid; do { for (TrackViewList::reverse_iterator i = track_views.rbegin(); i != track_views.rend(); ++i) { @@ -6374,9 +6437,14 @@ Editor::select_prev_route() break; } } - rui = dynamic_cast(current); + if (routes_only) { + RouteUI* rui = dynamic_cast(current); + valid = rui && rui->route()->active(); + } else { + valid = 0 != current->stripable ().get(); + } - } while (current->hidden() || (rui == NULL) || !rui->route()->active()); + } while (current->hidden() || !valid); selection->set (current); @@ -7258,7 +7326,7 @@ Editor::playhead_forward_to_grid () if (pos.frame < max_framepos - 1) { pos.frame += 2; - snap_to_internal (pos, RoundUpAlways, false); + snap_to_internal (pos, RoundUpAlways, false, true); _session->request_locate (pos.frame); } } @@ -7275,7 +7343,7 @@ Editor::playhead_backward_to_grid () if (pos.frame > 2) { pos.frame -= 2; - snap_to_internal (pos, RoundDownAlways, false); + snap_to_internal (pos, RoundDownAlways, false, true); _session->request_locate (pos.frame); } } @@ -7345,20 +7413,29 @@ Editor::_remove_tracks () string prompt; int ntracks = 0; int nbusses = 0; + int nvcas = 0; const char* trackstr; const char* busstr; + const char* vcastr; vector > routes; + vector > vcas; bool special_bus = false; for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) { + VCATimeAxisView* vtv = dynamic_cast (*x); + if (vtv) { + vcas.push_back (vtv->vca()); + ++nvcas; + continue; + } RouteTimeAxisView* rtv = dynamic_cast (*x); if (!rtv) { continue; } if (rtv->is_track()) { - ntracks++; + ++ntracks; } else { - nbusses++; + ++nbusses; } routes.push_back (rtv->_route); @@ -7385,45 +7462,68 @@ edit your ardour.rc file to set the\n\ return; } - if (ntracks + nbusses == 0) { + if (ntracks + nbusses + nvcas == 0) { return; } + string title; + trackstr = P_("track", "tracks", ntracks); busstr = P_("bus", "busses", nbusses); + vcastr = P_("VCA", "VCAs", nvcas); - if (ntracks) { - if (nbusses) { - prompt = string_compose (_("Do you really want to remove %1 %2 and %3 %4?\n" - "(You may also lose the playlists associated with the %2)\n\n" - "This action cannot be undone, and the session file will be overwritten!"), - ntracks, trackstr, nbusses, busstr); - } else { - prompt = string_compose (_("Do you really want to remove %1 %2?\n" - "(You may also lose the playlists associated with the %2)\n\n" - "This action cannot be undone, and the session file will be overwritten!"), - ntracks, trackstr); - } - } else if (nbusses) { - prompt = string_compose (_("Do you really want to remove %1 %2?\n\n" - "This action cannot be undone, and the session file will be overwritten"), - nbusses, busstr); + if (ntracks > 0 && nbusses > 0 && nvcas > 0) { + title = _("Remove various strips"); + prompt = string_compose (_("Do you really want to remove %1 %2, %3 %4 and %5 %6?"), + ntracks, trackstr, nbusses, busstr, nvcas, vcastr); + } + else if (ntracks > 0 && nbusses > 0) { + title = string_compose (_("Remove %1 and %2"), trackstr, busstr); + prompt = string_compose (_("Do you really want to remove %1 %2 and %3 %4?"), + ntracks, trackstr, nbusses, busstr); + } + else if (ntracks > 0 && nvcas > 0) { + title = string_compose (_("Remove %1 and %2"), trackstr, vcastr); + prompt = string_compose (_("Do you really want to remove %1 %2 and %3 %4?"), + ntracks, trackstr, nvcas, vcastr); + } + else if (nbusses > 0 && nvcas > 0) { + title = string_compose (_("Remove %1 and %2"), busstr, vcastr); + prompt = string_compose (_("Do you really want to remove %1 %2 and %3 %4?"), + nbusses, busstr, nvcas, vcastr); + } + else if (ntracks > 0) { + title = string_compose (_("Remove %1"), trackstr); + prompt = string_compose (_("Do you really want to remove %1 %2?"), + ntracks, trackstr); + } + else if (nbusses > 0) { + title = string_compose (_("Remove %1"), busstr); + prompt = string_compose (_("Do you really want to remove %1 %2?"), + nbusses, busstr); + } + else if (nvcas > 0) { + title = string_compose (_("Remove %1"), vcastr); + prompt = string_compose (_("Do you really want to remove %1 %2?"), + nvcas, vcastr); + } + else { + assert (0); + } + + if (ntracks > 0) { + prompt += "\n" + string_compose ("(You may also lose the playlists associated with the %1)", trackstr) + "\n"; } + prompt += "\n" + string(_("This action cannot be undone, and the session file will be overwritten!")); + choices.push_back (_("No, do nothing.")); - if (ntracks + nbusses > 1) { + if (ntracks + nbusses + nvcas > 1) { choices.push_back (_("Yes, remove them.")); } else { choices.push_back (_("Yes, remove it.")); } - string title; - if (ntracks) { - title = string_compose (_("Remove %1"), trackstr); - } else { - title = string_compose (_("Remove %1"), busstr); - } - Choice prompter (title, prompt, choices); if (prompter.run () != 1) { @@ -7457,6 +7557,11 @@ edit your ardour.rc file to set the\n\ rl->push_back (*x); } _session->remove_routes (rl); + + for (vector >::iterator x = vcas.begin(); x != vcas.end(); ++x) { + _session->vca_manager().remove_vca (*x); + } + } /* TrackSelection and RouteList leave scope, * destructors are called,