X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_ops.cc;h=2683020cbf0653f69df888bd77eaa39320ec9679;hb=58137b83262208bb317c3dbd08f95698b409f254;hp=c09bbcceb8dd3e31f8557795bdb0b496865361ec;hpb=a12a065457a10d9be2582f3ad2fcee7178405981;p=ardour.git diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index c09bbcceb8..2683020cbf 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -97,6 +97,7 @@ #include "strip_silence_dialog.h" #include "time_axis_view.h" #include "transpose_dialog.h" +#include "transform_dialog.h" #include "i18n.h" @@ -121,6 +122,11 @@ Editor::undo (uint32_t n) if (_session) { _session->undo (n); + if (_session->undo_depth() == 0) { + undo_action->set_sensitive(false); + } + redo_action->set_sensitive(true); + begin_selection_op_history (); } } @@ -133,6 +139,11 @@ Editor::redo (uint32_t n) if (_session) { _session->redo (n); + if (_session->redo_depth() == 0) { + redo_action->set_sensitive(false); + } + undo_action->set_sensitive(true); + begin_selection_op_history (); } } @@ -241,12 +252,35 @@ Editor::split_regions_at (framepos_t where, RegionSelection& regions) EditorThaw(); /* Emit Signal */ } - if (ARDOUR::Profile->get_mixbus()) { - //IFF we were working on selected regions, try to reinstate the other region selections that existed before the freeze/thaw. - _ignore_follow_edits = true; //a split will change the region selection in mysterious ways; its not practical or wanted to follow this edit - if( working_on_selection ) { + if (working_on_selection) { + // IFF we were working on selected regions, try to reinstate the other region selections that existed before the freeze/thaw. + + _ignore_follow_edits = true; // a split will change the region selection in mysterious ways; it's not practical or wanted to follow this edit + RegionSelectionAfterSplit rsas = Config->get_region_selection_after_split(); + /* There are three classes of regions that we might want selected after + splitting selected regions: + - regions selected before the split operation, and unaffected by it + - newly-created regions before the split + - newly-created regions after the split + */ + + if (rsas & Existing) { + // region selections that existed before the split. selection->add ( pre_selected_regions ); - selection->add (latest_regionviews); //these are the new regions created after the split + } + + for (RegionSelection::iterator ri = latest_regionviews.begin(); ri != latest_regionviews.end(); ri++) { + if ((*ri)->region()->position() < where) { + // new regions created before the split + if (rsas & NewlyCreatedLeft) { + selection->add (*ri); + } + } else { + // new regions created after the split + if (rsas & NewlyCreatedRight) { + selection->add (*ri); + } + } } _ignore_follow_edits = false; } else { @@ -1678,29 +1712,9 @@ Editor::temporal_zoom_region (bool both_axes) framepos_t end = 0; set tracks; - RegionSelection rs = get_regions_from_selection_and_entered (); - - if (rs.empty()) { + if ( !get_selection_extents(start, end) ) return; - } - - for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { - - if ((*i)->region()->position() < start) { - start = (*i)->region()->position(); - } - - if ((*i)->region()->last_frame() + 1 > end) { - end = (*i)->region()->last_frame() + 1; - } - - tracks.insert (&((*i)->get_time_axis_view())); - } - - if ((start == 0 && end == 0) || end < start) { - return; - } - + calc_extra_zoom_edges (start, end); /* if we're zooming on both axes we need to save track heights etc. @@ -1737,35 +1751,73 @@ Editor::temporal_zoom_region (bool both_axes) redo_visual_stack.push_back (current_visual_state (both_axes)); } -void -Editor::zoom_to_region (bool both_axes) + +bool +Editor::get_selection_extents ( framepos_t &start, framepos_t &end ) { - temporal_zoom_region (both_axes); + start = max_framepos; + end = 0; + bool ret = true; + + //ToDo: if notes are selected, set extents to that selection + + //ToDo: if control points are selected, set extents to that selection + + if ( !selection->regions.empty() ) { + RegionSelection rs = get_regions_from_selection_and_entered (); + + for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { + + if ((*i)->region()->position() < start) { + start = (*i)->region()->position(); + } + + if ((*i)->region()->last_frame() + 1 > end) { + end = (*i)->region()->last_frame() + 1; + } + } + + } else if (!selection->time.empty()) { + start = selection->time.start(); + end = selection->time.end_frame(); + } else + ret = false; //no selection found + + //range check + if ((start == 0 && end == 0) || end < start) { + ret = false; + } + + return ret; } + void Editor::temporal_zoom_selection (bool both_axes) { if (!selection) return; - //if a range is selected, zoom to that - if (!selection->time.empty()) { + //ToDo: if notes are selected, zoom to that - framepos_t start = selection->time.start(); - framepos_t end = selection->time.end_frame(); + //ToDo: if control points are selected, zoom to that - calc_extra_zoom_edges(start, end); + //if region(s) are selected, zoom to that + if ( !selection->regions.empty() ) + temporal_zoom_region (both_axes); - temporal_zoom_by_frame (start, end); + //if a range is selected, zoom to that + if (!selection->time.empty()) { + framepos_t start, end; + if (get_selection_extents (start, end)) { + calc_extra_zoom_edges(start, end); + temporal_zoom_by_frame (start, end); + } + if (both_axes) - fit_selected_tracks(); - - } else { - temporal_zoom_region (both_axes); + fit_selection(); } - } void @@ -1882,7 +1934,7 @@ Editor::temporal_zoom_to_frame (bool coarser, framepos_t frame) bool Editor::choose_new_marker_name(string &name) { - if (!Config->get_name_new_markers()) { + if (!ARDOUR_UI::config()->get_name_new_markers()) { /* don't prompt user for a new name */ return true; } @@ -2308,11 +2360,15 @@ Editor::play_from_edit_point_and_return () void Editor::play_selection () { - if (selection->time.empty()) { + framepos_t start, end; + if (!get_selection_extents ( start, end)) return; - } - _session->request_play_range (&selection->time, true); + AudioRange ar (start, end, 0); + list lar; + lar.push_back (ar); + + _session->request_play_range (&lar, true); } framepos_t @@ -2325,7 +2381,7 @@ Editor::get_preroll () void Editor::maybe_locate_with_edit_preroll ( framepos_t location ) { - if ( _session->transport_rolling() || !Config->get_follow_edits() || _ignore_follow_edits ) + if ( _session->transport_rolling() || !ARDOUR_UI::config()->get_follow_edits() || _ignore_follow_edits ) return; location -= get_preroll(); @@ -2345,16 +2401,17 @@ Editor::maybe_locate_with_edit_preroll ( framepos_t location ) void Editor::play_with_preroll () { - if (selection->time.empty()) { - return; - } else { + { framepos_t preroll = get_preroll(); - framepos_t start = 0; - if (selection->time[clicked_selection].start > preroll) - start = selection->time[clicked_selection].start - preroll; + framepos_t start, end; + if (!get_selection_extents ( start, end)) + return; + + if (start > preroll) + start = start - preroll; - framepos_t end = selection->time[clicked_selection].end + preroll; + end = end + preroll; //"post-roll" AudioRange ar (start, end, 0); list lar; @@ -2667,8 +2724,14 @@ Editor::create_region_from_selection (vector >& new_re return; } - framepos_t start = selection->time[clicked_selection].start; - framepos_t end = selection->time[clicked_selection].end; + framepos_t start, end; + if (clicked_selection) { + start = selection->time[clicked_selection].start; + end = selection->time[clicked_selection].end; + } else { + start = selection->time.start(); + end = selection->time.end_frame(); + } TrackViewList ts = selection->tracks.filter_to_unique_playlists (); sort_track_selection (ts); @@ -3666,14 +3729,13 @@ Editor::freeze_route () pthread_create_and_store (X_("freezer"), &itt.thread, _freeze_thread, this); - set_canvas_cursor (_cursors->wait); + CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); while (!itt.done && !itt.cancel) { gtk_main_iteration (); } current_interthread_info = 0; - set_canvas_cursor (current_canvas_cursor); } void @@ -3929,7 +3991,7 @@ struct AutomationRecord { * @param op Operation (Cut, Copy or Clear) */ void -Editor::cut_copy_points (Editing::CutCopyOp op, Evoral::MusicalTime earliest, bool midi) +Editor::cut_copy_points (Editing::CutCopyOp op, Evoral::Beats earliest, bool midi) { if (selection->points.empty ()) { return; @@ -3971,7 +4033,7 @@ Editor::cut_copy_points (Editing::CutCopyOp op, Evoral::MusicalTime earliest, bo lists[al].copy->fast_simple_add ((*j)->when, (*j)->value); if (midi) { /* Update earliest MIDI start time in beats */ - earliest = std::min(earliest, Evoral::MusicalTime((*j)->when)); + earliest = std::min(earliest, Evoral::Beats((*j)->when)); } else { /* Update earliest session start time in frames */ start = std::min(start, (*i)->line().session_position(j)); @@ -3980,8 +4042,8 @@ Editor::cut_copy_points (Editing::CutCopyOp op, Evoral::MusicalTime earliest, bo /* Snap start time backwards, so copy/paste is snap aligned. */ if (midi) { - if (earliest == Evoral::MusicalTime::max()) { - earliest = Evoral::MusicalTime(); // Weird... don't offset + if (earliest == Evoral::Beats::max()) { + earliest = Evoral::Beats(); // Weird... don't offset } earliest.round_down_to_beat(); } else { @@ -4034,7 +4096,7 @@ Editor::cut_copy_points (Editing::CutCopyOp op, Evoral::MusicalTime earliest, bo void Editor::cut_copy_midi (CutCopyOp op) { - Evoral::MusicalTime earliest = Evoral::MusicalTime::max(); + Evoral::Beats earliest = Evoral::Beats::max(); for (MidiRegionSelection::iterator i = selection->midi_regions.begin(); i != selection->midi_regions.end(); ++i) { MidiRegionView* mrv = dynamic_cast(*i); if (mrv) { @@ -4569,7 +4631,13 @@ Editor::duplicate_selection (float times) continue; } playlist->clear_changes (); - playlist->duplicate (*ri, selection->time[clicked_selection].end, times); + framepos_t end; + if (clicked_selection) { + end = selection->time[clicked_selection].end; + } else { + end = selection->time.end_frame(); + } + playlist->duplicate (*ri, end, times); _session->add_command (new StatefulDiffCommand (playlist)); ++ri; @@ -4711,7 +4779,7 @@ Editor::normalize_region () return; } - set_canvas_cursor (_cursors->wait); + CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); gdk_flush (); /* XXX: should really only count audio regions here */ @@ -4730,7 +4798,6 @@ Editor::normalize_region () if (a == -1) { /* the user cancelled the operation */ - set_canvas_cursor (current_canvas_cursor); return; } @@ -4761,7 +4828,6 @@ Editor::normalize_region () } commit_reversible_command (); - set_canvas_cursor (current_canvas_cursor); } @@ -4876,39 +4942,35 @@ Editor::strip_region_silence () Command* Editor::apply_midi_note_edit_op_to_region (MidiOperator& op, MidiRegionView& mrv) { - Evoral::Sequence::Notes selected; + Evoral::Sequence::Notes selected; mrv.selection_as_notelist (selected, true); - vector::Notes> v; + vector::Notes> v; v.push_back (selected); - framepos_t pos_frames = mrv.midi_region()->position() - mrv.midi_region()->start(); - Evoral::MusicalTime pos_beats = _session->tempo_map().framewalk_to_beats(0, pos_frames); + framepos_t pos_frames = mrv.midi_region()->position() - mrv.midi_region()->start(); + Evoral::Beats pos_beats = _session->tempo_map().framewalk_to_beats(0, pos_frames); return op (mrv.midi_region()->model(), pos_beats, v); } void -Editor::apply_midi_note_edit_op (MidiOperator& op) +Editor::apply_midi_note_edit_op (MidiOperator& op, const RegionSelection& rs) { - Command* cmd; - - RegionSelection rs = get_regions_from_selection_and_entered (); - if (rs.empty()) { return; } begin_reversible_command (op.name ()); - for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) { - RegionSelection::iterator tmp = r; + for (RegionSelection::const_iterator r = rs.begin(); r != rs.end(); ) { + RegionSelection::const_iterator tmp = r; ++tmp; MidiRegionView* const mrv = dynamic_cast (*r); if (mrv) { - cmd = apply_midi_note_edit_op_to_region (op, *mrv); + Command* cmd = apply_midi_note_edit_op_to_region (op, *mrv); if (cmd) { (*cmd)(); _session->add_command (cmd); @@ -4932,7 +4994,7 @@ Editor::fork_region () begin_reversible_command (_("Fork Region(s)")); - set_canvas_cursor (_cursors->wait); + CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); gdk_flush (); for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) { @@ -4959,33 +5021,20 @@ Editor::fork_region () } commit_reversible_command (); - - set_canvas_cursor (current_canvas_cursor); } void Editor::quantize_region () { - int selected_midi_region_cnt = 0; - - if (!_session) { - return; - } - - RegionSelection rs = get_regions_from_selection_and_entered (); - - if (rs.empty()) { - return; - } - - for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { - MidiRegionView* const mrv = dynamic_cast (*r); - if (mrv) { - selected_midi_region_cnt++; - } + if (_session) { + quantize_regions(get_regions_from_selection_and_entered ()); } +} - if (selected_midi_region_cnt == 0) { +void +Editor::quantize_regions (const RegionSelection& rs) +{ + if (rs.n_midi_regions() == 0) { return; } @@ -5000,38 +5049,54 @@ Editor::quantize_region () qd->start_grid_size(), qd->end_grid_size(), qd->strength(), qd->swing(), qd->threshold()); - apply_midi_note_edit_op (quant); + apply_midi_note_edit_op (quant, rs); } } void Editor::legatize_region (bool shrink_only) { - int selected_midi_region_cnt = 0; - - if (!_session) { - return; + if (_session) { + legatize_regions(get_regions_from_selection_and_entered (), shrink_only); } +} - RegionSelection rs = get_regions_from_selection_and_entered (); - - if (rs.empty()) { +void +Editor::legatize_regions (const RegionSelection& rs, bool shrink_only) +{ + if (rs.n_midi_regions() == 0) { return; } - for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) { - MidiRegionView* const mrv = dynamic_cast (*r); - if (mrv) { - selected_midi_region_cnt++; - } + Legatize legatize(shrink_only); + apply_midi_note_edit_op (legatize, rs); +} + +void +Editor::transform_region () +{ + if (_session) { + transform_regions(get_regions_from_selection_and_entered ()); } +} - if (selected_midi_region_cnt == 0) { +void +Editor::transform_regions (const RegionSelection& rs) +{ + if (rs.n_midi_regions() == 0) { return; } - Legatize legatize(shrink_only); - apply_midi_note_edit_op (legatize); + TransformDialog* td = new TransformDialog(); + + td->present(); + const int r = td->run(); + td->hide(); + + if (r == Gtk::RESPONSE_OK) { + Transform transform(td->get()); + apply_midi_note_edit_op(transform, rs); + } } void @@ -5051,7 +5116,7 @@ Editor::insert_patch_change (bool from_context) */ MidiRegionView* first = dynamic_cast (rs.front ()); - Evoral::PatchChange empty (Evoral::MusicalTime(), 0, 0, 0); + Evoral::PatchChange empty (Evoral::Beats(), 0, 0, 0); PatchChangeDialog d (0, _session, empty, first->instrument_info(), Gtk::Stock::ADD); if (d.run() == RESPONSE_CANCEL) { @@ -5079,7 +5144,7 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress begin_reversible_command (command); - set_canvas_cursor (_cursors->wait); + CursorContext::Handle cursor_ctx = CursorContext::create(*this, _cursors->wait); gdk_flush (); int n = 0; @@ -5132,7 +5197,7 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress _session->add_command(new StatefulDiffCommand (playlist)); } else { - goto out; + return; } if (progress) { @@ -5145,9 +5210,6 @@ Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress } commit_reversible_command (); - - out: - set_canvas_cursor (current_canvas_cursor); } void @@ -5724,27 +5786,33 @@ Editor::set_playhead_cursor () } } - if ( Config->get_follow_edits() ) + if (ARDOUR_UI::config()->get_follow_edits()) { cancel_time_selection(); + } } void Editor::split_region () { + //if a range is selected, separate it if ( !selection->time.empty()) { separate_regions_between (selection->time); return; } - RegionSelection rs = get_regions_from_selection_and_edit_point (); + //if no range was selected, try to find some regions to split + if (current_mouse_mode() == MouseObject) { //don't try this for Internal Edit, Stretch, Draw, etc. + + RegionSelection rs = get_regions_from_selection_and_edit_point (); - framepos_t where = get_preferred_edit_position (); + framepos_t where = get_preferred_edit_position (); - if (rs.empty()) { - return; - } + if (rs.empty()) { + return; + } - split_regions_at (where, rs); + split_regions_at (where, rs); + } } struct EditorOrderRouteSorter { @@ -5818,64 +5886,28 @@ Editor::select_prev_route() void Editor::set_loop_from_selection (bool play) -{ - if (_session == 0 || selection->time.empty()) { - return; - } - - framepos_t start = selection->time[clicked_selection].start; - framepos_t end = selection->time[clicked_selection].end; - - set_loop_range (start, end, _("set loop range from selection")); - - if (play) { - _session->request_locate (start, true); - _session->request_play_loop (true); - } -} - -void -Editor::set_loop_from_edit_range (bool play) { if (_session == 0) { return; } - framepos_t start; - framepos_t end; - - if (!get_edit_op_range (start, end)) { + framepos_t start, end; + if (!get_selection_extents ( start, end)) return; - } - set_loop_range (start, end, _("set loop range from edit range")); + set_loop_range (start, end, _("set loop range from selection")); if (play) { - _session->request_locate (start, true); - _session->request_play_loop (true); + _session->request_play_loop (true, true); } } void Editor::set_loop_from_region (bool play) { - framepos_t start = max_framepos; - framepos_t end = 0; - - RegionSelection rs = get_regions_from_selection_and_entered (); - - if (rs.empty()) { + framepos_t start, end; + if (!get_selection_extents ( start, end)) return; - } - - for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { - if ((*i)->region()->position() < start) { - start = (*i)->region()->position(); - } - if ((*i)->region()->last_frame() + 1 > end) { - end = (*i)->region()->last_frame() + 1; - } - } set_loop_range (start, end, _("set loop range from region")); @@ -5888,12 +5920,13 @@ Editor::set_loop_from_region (bool play) void Editor::set_punch_from_selection () { - if (_session == 0 || selection->time.empty()) { + if (_session == 0) { return; } - framepos_t start = selection->time[clicked_selection].start; - framepos_t end = selection->time[clicked_selection].end; + framepos_t start, end; + if (!get_selection_extents ( start, end)) + return; set_punch_range (start, end, _("set punch range from selection")); } @@ -5901,15 +5934,16 @@ Editor::set_punch_from_selection () void Editor::set_session_extents_from_selection () { - if (_session == 0 || selection->time.empty()) { + if (_session == 0) { return; } + + framepos_t start, end; + if (!get_selection_extents ( start, end)) + return; begin_reversible_command (_("set session start/stop from selection")); - framepos_t start = selection->time[clicked_selection].start; - framepos_t end = selection->time[clicked_selection].end; - Location* loc; if ((loc = _session->locations()->session_range_location()) == 0) { _session->set_session_extents ( start, end ); // this will create a new session range; no need for UNDO @@ -5926,43 +5960,12 @@ Editor::set_session_extents_from_selection () } } -void -Editor::set_punch_from_edit_range () -{ - if (_session == 0) { - return; - } - - framepos_t start; - framepos_t end; - - if (!get_edit_op_range (start, end)) { - return; - } - - set_punch_range (start, end, _("set punch range from edit range")); -} - void Editor::set_punch_from_region () { - framepos_t start = max_framepos; - framepos_t end = 0; - - RegionSelection rs = get_regions_from_selection_and_entered (); - - if (rs.empty()) { + framepos_t start, end; + if (!get_selection_extents ( start, end)) return; - } - - for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) { - if ((*i)->region()->position() < start) { - start = (*i)->region()->position(); - } - if ((*i)->region()->last_frame() + 1 > end) { - end = (*i)->region()->last_frame() + 1; - } - } set_punch_range (start, end, _("set punch range from region")); } @@ -6914,7 +6917,7 @@ Editor::insert_time ( } void -Editor::fit_selected_tracks () +Editor::fit_selection () { if (!selection->tracks.empty()) { fit_tracks (selection->tracks);