void
Editor::split_region_at (nframes_t where)
{
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
split_regions_at (where, selection->regions);
}
{
nframes_t distance;
nframes_t next_distance;
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
if (!session) return;
- if (!force_playhead && !selection->regions.empty()) {
+ if (!force_playhead && !rs.empty()) {
begin_reversible_command (_("nudge regions forward"));
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
boost::shared_ptr<Region> r ((*i)->region());
distance = get_nudge_distance (r->position(), next_distance);
{
nframes_t distance;
nframes_t next_distance;
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
if (!session) return;
- if (!force_playhead && !selection->regions.empty()) {
+ if (!force_playhead && !rs.empty()) {
begin_reversible_command (_("nudge regions backward"));
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
boost::shared_ptr<Region> r ((*i)->region());
distance = get_nudge_distance (r->position(), next_distance);
Editor::nudge_forward_capture_offset ()
{
nframes_t distance;
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
if (!session) return;
- if (!selection->regions.empty()) {
+ if (!rs.empty()) {
begin_reversible_command (_("nudge forward"));
distance = session->worst_output_latency();
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
boost::shared_ptr<Region> r ((*i)->region());
XMLNode &before = r->playlist()->get_state();
Editor::nudge_backward_capture_offset ()
{
nframes_t distance;
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
if (!session) return;
- if (!selection->regions.empty()) {
+ if (!rs.empty()) {
begin_reversible_command (_("nudge forward"));
distance = session->worst_output_latency();
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
boost::shared_ptr<Region> r ((*i)->region());
XMLNode &before = r->playlist()->get_state();
Editor::cursor_to_selection_start (Cursor *cursor)
{
nframes_t pos = 0;
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
switch (mouse_mode) {
case MouseObject:
- if (!selection->regions.empty()) {
- pos = selection->regions.start();
+ if (!rs.empty()) {
+ pos = rs.start();
}
break;
Editor::cursor_to_selection_end (Cursor *cursor)
{
nframes_t pos = 0;
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
switch (mouse_mode) {
case MouseObject:
- if (!selection->regions.empty()) {
- pos = selection->regions.end_frame();
+ if (!rs.empty()) {
+ pos = rs.end_frame();
}
break;
return;
}
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
switch (mouse_mode) {
case MouseObject:
- if (!selection->regions.empty()) {
- pos = selection->regions.start();
+ if (!rs.empty()) {
+ pos = rs.start();
}
break;
return;
}
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
switch (mouse_mode) {
case MouseObject:
- if (!selection->regions.empty()) {
- pos = selection->regions.end_frame();
+ if (!rs.empty()) {
+ pos = rs.end_frame();
}
break;
nframes64_t start = max_frames;
nframes64_t end = 0;
+ RegionSelection rs;
- ensure_entered_region_selected (true);
+ get_regions_for_action (rs);
- if (selection->regions.empty()) {
+ if (rs.empty()) {
return;
}
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
if ((*i)->region()->position() < start) {
start = (*i)->region()->position();
}
void
Editor::add_location_from_audio_region ()
{
- if (selection->regions.empty()) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
- RegionView* rv = *(selection->regions.begin());
+ RegionView* rv = *(rs.begin());
boost::shared_ptr<Region> region = rv->region();
Location *location = new Location (region->position(), region->last_frame(), region->name(), Location::IsRangeMarker);
RouteTimeAxisView *rtv = 0;
boost::shared_ptr<Playlist> playlist;
- track_canvas.window_to_world (x, y, wx, wy);
+ track_canvas->window_to_world (x, y, wx, wy);
wx += horizontal_adjustment.get_value();
wy += vertical_adjustment.get_value();
commit_reversible_command ();
}
+void
+Editor::insert_route_list_drag (boost::shared_ptr<Route> route, int x, int y) {
+ double wx, wy;
+ double cx, cy;
+ TimeAxisView *tv;
+ nframes_t where;
+ RouteTimeAxisView *dest_rtv = 0;
+ RouteTimeAxisView *source_rtv = 0;
+
+ 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;
+ event.button.x = wx;
+ event.button.y = wy;
+
+ where = event_frame (&event, &cx, &cy);
+
+ if ((tv = trackview_by_y_position (cy)) == 0) {
+ return;
+ }
+
+ if ((dest_rtv = dynamic_cast<RouteTimeAxisView*>(tv)) == 0) {
+ return;
+ }
+
+ /* use this drag source to add underlay to a track. But we really don't care
+ about the Route, only the view of the route, so find it first */
+ for(TrackViewList::iterator it = track_views.begin(); it != track_views.end(); ++it) {
+ if((source_rtv = dynamic_cast<RouteTimeAxisView*>(*it)) == 0) {
+ continue;
+ }
+
+ if(source_rtv->route() == route && source_rtv != dest_rtv) {
+ dest_rtv->add_underlay(source_rtv->view());
+ break;
+ }
+ }
+}
+
void
Editor::insert_region_list_selection (float times)
{
nframes64_t start_frame;
nframes64_t return_frame;
+ start_frame = get_preferred_edit_position (true);
+
+ if (session->transport_rolling()) {
+ session->request_locate (start_frame, false);
+ return;
+ }
+
/* don't reset the return frame if its already set */
if ((return_frame = session->requested_return_frame()) < 0) {
return_frame = session->audible_frame();
}
- start_frame = get_preferred_edit_position (true);
-
if (start_frame >= 0) {
session->request_roll_at_and_return (start_frame, return_frame);
}
void
Editor::loop_selected_region ()
{
- if (!selection->regions.empty()) {
- RegionView *rv = *(selection->regions.begin());
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (!rs.empty()) {
+ RegionView *rv = *(rs.begin());
Location* tll;
if ((tll = transport_loop_location()) != 0) {
void
Editor::rename_region()
{
- if (selection->regions.empty()) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
d.set_size_request (300, -1);
d.set_position (Gtk::WIN_POS_MOUSE);
- entry.set_text (selection->regions.front()->region()->name());
+ entry.set_text (rs.front()->region()->name());
entry.select_region (0, -1);
entry.signal_activate().connect (bind (mem_fun (d, &Dialog::response), RESPONSE_OK));
std::string str = entry.get_text();
strip_whitespace_edges (str);
if (!str.empty()) {
- selection->regions.front()->region()->set_name (str);
+ rs.front()->region()->set_name (str);
redisplay_regions ();
}
}
{
nframes64_t start = max_frames;
nframes64_t end = 0;
+ RegionSelection rs;
- ExclusiveRegionSelection esr (*this, entered_regionview);
-
- if (selection->regions.empty()) {
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
if ((*i)->region()->position() < start) {
start = (*i)->region()->position();
}
}
void
-Editor::create_region_from_selection (vector<boost::shared_ptr<AudioRegion> >& new_regions)
+Editor::create_region_from_selection (vector<boost::shared_ptr<Region> >& new_regions)
{
if (selection->time.empty() || selection->tracks.empty()) {
return;
void
Editor::split_multichannel_region ()
{
- if (selection->regions.empty()) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
vector<boost::shared_ptr<AudioRegion> > v;
- for (list<RegionView*>::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+ for (list<RegionView*>::iterator x = rs.begin(); x != rs.end(); ++x) {
AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*x);
/* use tracks with selected regions */
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
TimeAxisView* tv = &(*i)->get_time_axis_view();
if (find (tmptracks.begin(), tmptracks.end(), tv) == tmptracks.end()) {
}
if (tmptracks.empty()) {
- /* no regions selected: use all tracks */
- tmptracks = track_views;
+ /* no regions selected: do nothing */
+ return;
}
} else {
to allow discontiguous operation, since get_edit_op_range() currently
returns a single range.
*/
+
if (mouse_mode == MouseRange && !selection->time.empty()) {
separate_regions_between (selection->time);
TimeSelection ts;
ts.push_back (ar);
- /* force track selection */
-
- ensure_entered_region_selected ();
-
separate_regions_between (ts);
}
}
}
+void
+Editor::separate_region_from_punch ()
+{
+ Location* loc = session->locations()->auto_punch_location();
+ if (loc) {
+ separate_regions_using_location (*loc);
+ }
+}
+
+void
+Editor::separate_region_from_loop ()
+{
+ Location* loc = session->locations()->auto_loop_location();
+ if (loc) {
+ separate_regions_using_location (*loc);
+ }
+}
+
void
Editor::separate_regions_using_location (Location& loc)
{
void
Editor::crop_region_to_selection ()
{
- ensure_entered_region_selected (true);
-
if (!selection->time.empty()) {
crop_region_to (selection->time.start(), selection->time.end_frame());
Editor::region_fill_track ()
{
nframes_t end;
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
- if (!session || selection->regions.empty()) {
+ if (!session || rs.empty()) {
return;
}
begin_reversible_command (_("region fill"));
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
boost::shared_ptr<Region> region ((*i)->region());
Editor::set_region_sync_from_edit_point ()
{
nframes64_t where = get_preferred_edit_position ();
- ensure_entered_region_selected (true);
- set_sync_point (where, selection->regions);
+ RegionSelection rs;
+ get_regions_for_action (rs);
+ set_sync_point (where, rs);
}
void
void
Editor::naturalize ()
{
- if (selection->regions.empty()) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
+
begin_reversible_command (_("naturalize"));
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
XMLNode &before = (*i)->region()->get_state();
(*i)->region()->move_to_natural_position (this);
XMLNode &after = (*i)->region()->get_state();
void
Editor::align (RegionPoint what)
{
- ensure_entered_region_selected ();
+ RegionSelection rs;
+ get_regions_for_action (rs);
nframes64_t where = get_preferred_edit_position();
- if (!selection->regions.empty()) {
- align_selection (what, where, selection->regions);
+ if (!rs.empty()) {
+ align_selection (what, where, rs);
} else {
RegionSelection rs;
- rs = get_regions_at (where, selection->tracks);
+ get_regions_at (rs, where, selection->tracks);
align_selection (what, where, rs);
}
}
Editor::align_relative (RegionPoint what)
{
nframes64_t where = get_preferred_edit_position();
+ RegionSelection rs;
- if (!selection->regions.empty()) {
- align_selection_relative (what, where, selection->regions);
- } else {
+ get_regions_for_action (rs);
- RegionSelection rs;
- rs = get_regions_at (where, selection->tracks);
+ if (!rs.empty()) {
align_selection_relative (what, where, rs);
- }
+ }
}
struct RegionSortByTime {
/* move rest by the same amount */
- RegionSelection::const_iterator i = rs.begin();
- ++i;
-
- for (; i != rs.end(); ++i) {
+ sorted.pop_front();
+
+ for (list<RegionView*>::iterator i = sorted.begin(); i != sorted.end(); ++i) {
boost::shared_ptr<Region> region ((*i)->region());
void
Editor::trim_region_to_location (const Location& loc, const char* str)
{
- ExclusiveRegionSelection ers (*this, entered_regionview);
+ RegionSelection rs;
- RegionSelection& rs (get_regions_for_action ());
+ get_regions_for_action (rs);
begin_reversible_command (str);
void
Editor::trim_region_to_edit_point ()
{
- ExclusiveRegionSelection ers (*this, entered_regionview);
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
- RegionSelection& rs (get_regions_for_action ());
nframes64_t where = get_preferred_edit_position();
begin_reversible_command (_("trim region start to edit point"));
void
Editor::trim_region_from_edit_point ()
{
- ExclusiveRegionSelection ers (*this, entered_regionview);
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
- RegionSelection& rs (get_regions_for_action ());
nframes64_t where = get_preferred_edit_position();
begin_reversible_command (_("trim region end to edit point"));
pthread_attr_destroy(&attr);
- track_canvas.get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
+ track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
while (!itt.done && !itt.cancel) {
gtk_main_iteration ();
interthread_progress_connection.disconnect ();
interthread_progress_window->hide_all ();
current_interthread_info = 0;
- track_canvas.get_window()->set_cursor (*current_canvas_cursor);
+ track_canvas->get_window()->set_cursor (*current_canvas_cursor);
}
void
return;
}
+ RegionSelection rs;
+
+ /* we only want to cut regions if some are selected */
+
+ if (!selection->regions.empty()) {
+ get_regions_for_action (rs);
+ }
+
switch (current_mouse_mode()) {
case MouseObject:
- if (!selection->regions.empty() || !selection->points.empty()) {
+ if (!rs.empty() || !selection->points.empty()) {
begin_reversible_command (opname + _(" objects"));
- if (!selection->regions.empty()) {
- cut_copy_regions (op);
+ if (!rs.empty()) {
+ cut_copy_regions (op, rs);
if (op == Cut) {
selection->clear_regions ();
* @param op Operation (Cut, Copy or Clear)
*/
void
-Editor::cut_copy_regions (CutCopyOp op)
+Editor::cut_copy_regions (CutCopyOp op, RegionSelection& rs)
{
/* we can't use a std::map here because the ordering is important, and we can't trivially sort
a map when we want ordered access to both elements. i think.
/* get ordering correct before we cut/copy */
- selection->regions.sort_by_position_and_track ();
+ rs.sort_by_position_and_track ();
- for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+ for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
first_position = min ((*x)->region()->position(), first_position);
}
}
- for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ) {
+ for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ) {
boost::shared_ptr<Playlist> pl = (*x)->region()->playlist();
Editor::cut_copy_ranges (CutCopyOp op)
{
TrackSelection* ts;
+ TrackSelection entered;
if (selection->tracks.empty()) {
- ts = &track_views;
+ if (!entered_track) {
+ return;
+ }
+ entered.push_back (entered_track);
+ ts = &entered;
} else {
ts = &selection->tracks;
}
}
boost::shared_ptr<Playlist> playlist;
- vector<boost::shared_ptr<AudioRegion> > new_regions;
- vector<boost::shared_ptr<AudioRegion> >::iterator ri;
+ vector<boost::shared_ptr<Region> > new_regions;
+ vector<boost::shared_ptr<Region> >::iterator ri;
create_region_from_selection (new_regions);
if ((playlist = (*i)->playlist()) == 0) {
continue;
}
- XMLNode &before = playlist->get_state();
+ XMLNode &before = playlist->get_state();
playlist->duplicate (*ri, selection->time[clicked_selection].end, times);
- XMLNode &after = playlist->get_state();
+ XMLNode &after = playlist->get_state();
session->add_command (new MementoCommand<Playlist>(*playlist, &before, &after));
++ri;
void
Editor::normalize_region ()
{
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
if (!session) {
return;
}
- if (selection->regions.empty()) {
+ if (rs.empty()) {
return;
}
begin_reversible_command (_("normalize"));
- track_canvas.get_window()->set_cursor (*wait_cursor);
+ track_canvas->get_window()->set_cursor (*wait_cursor);
gdk_flush ();
- for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) {
+ for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
if (!arv)
continue;
}
commit_reversible_command ();
- track_canvas.get_window()->set_cursor (*current_canvas_cursor);
+ track_canvas->get_window()->set_cursor (*current_canvas_cursor);
}
return;
}
- ExclusiveRegionSelection (*this, entered_regionview);
+ RegionSelection rs;
- if (selection->regions.empty()) {
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
begin_reversible_command ("denormalize");
- for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) {
+ for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
if (!arv)
continue;
return;
}
- ExclusiveRegionSelection esr (*this, entered_regionview);
+ RegionSelection rs;
- if (selection->regions.empty()) {
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
begin_reversible_command ("denormalize");
- for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) {
+ for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
if (!arv)
continue;
void
Editor::apply_filter (Filter& filter, string command)
{
- if (selection->regions.empty()) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
begin_reversible_command (command);
- track_canvas.get_window()->set_cursor (*wait_cursor);
+ track_canvas->get_window()->set_cursor (*wait_cursor);
gdk_flush ();
- /* this is ugly. */
- for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ) {
+ for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) {
RegionSelection::iterator tmp = r;
++tmp;
}
commit_reversible_command ();
- selection->regions.clear ();
+ rs.clear ();
out:
- track_canvas.get_window()->set_cursor (*current_canvas_cursor);
+ track_canvas->get_window()->set_cursor (*current_canvas_cursor);
}
void
Editor::brush (nframes_t pos)
{
RegionSelection sel;
- snap_to (pos);
+ RegionSelection rs;
- if (selection->regions.empty()) {
- /* XXX get selection from region list */
- } else {
- sel = selection->regions;
- }
+ get_regions_for_action (rs);
+
+ snap_to (pos);
- if (sel.empty()) {
+ if (rs.empty()) {
return;
}
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
mouse_brush_insert_region ((*i), pos);
}
}
void
Editor::reset_region_gain_envelopes ()
{
- if (!session || selection->regions.empty()) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (!session || rs.empty()) {
return;
}
session->begin_reversible_command (_("reset region gain"));
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
if (arv) {
boost::shared_ptr<AutomationList> alist (arv->audio_region()->envelope());
void
Editor::toggle_gain_envelope_visibility ()
{
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
if (arv) {
arv->set_envelope_visible (!arv->envelope_visible());
void
Editor::toggle_gain_envelope_active ()
{
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
if (arv) {
arv->audio_region()->set_envelope_active (!arv->audio_region()->envelope_active());
void
Editor::toggle_region_lock ()
{
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
(*i)->region()->set_locked (!(*i)->region()->locked());
}
}
void
Editor::set_region_lock_style (Region::PositionLockStyle ps)
{
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
(*i)->region()->set_position_lock_style (ps);
}
}
void
Editor::toggle_region_mute ()
{
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
(*i)->region()->set_muted (!(*i)->region()->muted());
}
}
void
Editor::toggle_region_opaque ()
{
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
(*i)->region()->set_opaque (!(*i)->region()->opaque());
}
}
void
Editor::set_fade_length (bool in)
{
- ExclusiveRegionSelection esr (*this, entered_regionview);
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
/* we need a region to measure the offset from the start */
RegionView* rv;
- if (!selection->regions.empty()) {
- rv = selection->regions.front();
+ if (!rs.empty()) {
+ rv = rs.front();
} else if (entered_regionview) {
rv = entered_regionview;
} else {
begin_reversible_command (cmd);
- RegionSelection& rs (get_regions_for_action());
-
for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
if (in) {
tmp->audio_region()->set_fade_in_length (len);
+ tmp->audio_region()->set_fade_in_active (true);
} else {
tmp->audio_region()->set_fade_out_length (len);
+ tmp->audio_region()->set_fade_out_active (true);
}
XMLNode &after = alist->get_state();
void
Editor::toggle_fade_active (bool in)
{
- ensure_entered_region_selected (true);
+ RegionSelection rs;
- if (selection->regions.empty()) {
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
begin_reversible_command (cmd);
- for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+ for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
if (!tmp) {
void
Editor::set_fade_in_shape (AudioRegion::FadeShape shape)
{
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
+ return;
+ }
begin_reversible_command (_("set fade in shape"));
- for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+ for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
if (!tmp) {
void
Editor::set_fade_out_shape (AudioRegion::FadeShape shape)
{
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
+ return;
+ }
+
begin_reversible_command (_("set fade out shape"));
- for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+ for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
if (!tmp) {
void
Editor::set_fade_in_active (bool yn)
{
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
+ return;
+ }
+
begin_reversible_command (_("set fade in active"));
- for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+ for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
if (!tmp) {
void
Editor::set_fade_out_active (bool yn)
{
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
+ return;
+ }
+
begin_reversible_command (_("set fade out active"));
- for (RegionSelection::iterator x = selection->regions.begin(); x != selection->regions.end(); ++x) {
+ for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
if (!tmp) {
void
Editor::split ()
{
- ensure_entered_region_selected ();
+ RegionSelection rs;
- nframes64_t where = get_preferred_edit_position();
+ get_regions_for_action (rs);
- if (!selection->regions.empty()) {
-
- split_regions_at (where, selection->regions);
+ nframes64_t where = get_preferred_edit_position();
- } else {
-
- RegionSelection rs;
- rs = get_regions_at (where, selection->tracks);
- split_regions_at (where, rs);
+ if (rs.empty()) {
+ return;
}
+
+ split_regions_at (where, rs);
}
void
}
}
-void
-Editor::ensure_entered_region_selected (bool op_really_wants_one_region_if_none_are_selected)
-{
- if (!entered_regionview || mouse_mode != MouseObject) {
- return;
- }
-
-
- /* heuristic:
-
- - if there is no existing selection, don't change it. the operation will thus apply to "all"
-
- - if there is an existing selection, but the entered regionview isn't in it, add it. this
- avoids key-mouse ops on unselected regions from interfering with an existing selection,
- but also means that the operation will apply to the pointed-at region.
- */
-
- if (!selection->regions.empty()) {
- if (!selection->selected (entered_regionview)) {
- selection->add (entered_regionview);
- }
- } else {
- /* there is no selection, but this operation requires/prefers selected objects */
-
- if (op_really_wants_one_region_if_none_are_selected) {
- selection->set (entered_regionview, false);
- }
- }
-}
-
void
Editor::trim_region_front ()
{
void
Editor::trim_region (bool front)
{
- ExclusiveRegionSelection ers (*this, entered_regionview);
-
nframes64_t where = get_preferred_edit_position();
- RegionSelection& rs = get_regions_for_action ();
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
if (rs.empty()) {
return;
nframes64_t start = max_frames;
nframes64_t end = 0;
- ExclusiveRegionSelection esr (*this, entered_regionview);
+ RegionSelection rs;
- if (selection->regions.empty()) {
- info << _("cannot set loop: no region selected") << endmsg;
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
if ((*i)->region()->position() < start) {
start = (*i)->region()->position();
}
nframes64_t start = max_frames;
nframes64_t end = 0;
- ExclusiveRegionSelection esr (*this, entered_regionview);
+ RegionSelection rs;
- if (selection->regions.empty()) {
- info << _("cannot set punch: no region selected") << endmsg;
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
if ((*i)->region()->position() < start) {
start = (*i)->region()->position();
}
void
Editor::pitch_shift_regions ()
{
- ensure_entered_region_selected (true);
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
- if (selection->regions.empty()) {
+ if (rs.empty()) {
return;
}
- pitch_shift (selection->regions, 1.2);
+ pitch_shift (rs, 1.2);
}
void
return;
}
- ExclusiveRegionSelection esr (*this, entered_regionview);
+ RegionSelection rs;
- if (selection->regions.empty()) {
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
- RegionView* rv = selection->regions.front();
+ RegionView* rv = rs.front();
define_one_bar (rv->region()->position(), rv->region()->last_frame() + 1);
}
*/
vector<string> options;
- options.push_back (_("Set global tempo"));
- options.push_back (_("Add new marker"));
options.push_back (_("Cancel"));
+ options.push_back (_("Add new marker"));
+ options.push_back (_("Set global tempo"));
Choice c (_("Do you want to set the global tempo or add new tempo marker?"),
options);
+ c.set_default_response (2);
switch (c.run()) {
case 0:
+ return;
+
+ case 2:
do_global = true;
break;
- case 2:
- return;
default:
do_global = false;
return;
}
- ExclusiveRegionSelection esr (*this, entered_regionview);
+ RegionSelection rs;
- if (selection->regions.empty()) {
+ get_regions_for_action (rs);
+
+ if (rs.empty()) {
return;
}
session->begin_reversible_command (_("split regions"));
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ) {
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ) {
RegionSelection::iterator tmp;
boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> ((*i)->region());
if (ar && (ar->get_transients (positions) == 0)) {
- split_region_at_points ((*i)->region(), positions);
+ split_region_at_points ((*i)->region(), positions, true);
positions.clear ();
}
}
void
-Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList& positions)
+Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList& positions, bool can_ferret)
{
- boost::shared_ptr<AudioRegion> ar = boost::dynamic_pointer_cast<AudioRegion> (r);
-
- if (!ar) {
- return;
- }
-
- boost::shared_ptr<Playlist> pl = ar->playlist();
+ bool use_rhythmic_rodent = false;
+
+ boost::shared_ptr<Playlist> pl = r->playlist();
if (!pl) {
return;
if (positions.empty()) {
return;
}
+
+
+ if (positions.size() > 20) {
+ Glib::ustring msgstr = string_compose (_("You are about to split\n%1\ninto %2 pieces.\nThis could take a long time."), r->name(), positions.size() + 1);
+ MessageDialog msg (msgstr,
+ false,
+ Gtk::MESSAGE_INFO,
+ Gtk::BUTTONS_OK_CANCEL);
+
+ if (can_ferret) {
+ msg.add_button (_("Call for the Ferret!"), RESPONSE_APPLY);
+ msg.set_secondary_text (_("Press OK to continue with this split operation\nor ask the Ferret dialog to tune the analysis"));
+ } else {
+ msg.set_secondary_text (_("Press OK to continue with this split operation"));
+ }
+
+ msg.set_title (_("Excessive split?"));
+ msg.present ();
+
+ int response = msg.run();
+ msg.hide ();
+ switch (response) {
+ case RESPONSE_OK:
+ break;
+ case RESPONSE_APPLY:
+ use_rhythmic_rodent = true;
+ break;
+ default:
+ return;
+ }
+ }
+ if (use_rhythmic_rodent) {
+ show_rhythm_ferret ();
+ return;
+ }
+
AnalysisFeatureList::const_iterator x;
- nframes64_t pos = ar->position();
-
+ nframes64_t pos = r->position();
+
XMLNode& before (pl->get_state());
x = positions.begin();
if ((*x) > pos) {
break;
}
+ ++x;
}
if (x == positions.end()) {
}
pl->freeze ();
- pl->remove_region (ar);
+ pl->remove_region (r);
- do {
+ while (x != positions.end()) {
/* file start = original start + how far we from the initial position ?
*/
- nframes64_t file_start = ar->start() + (pos - ar->position());
-
+ nframes64_t file_start = r->start() + (pos - r->position());
+
/* 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?
+ */
+
+ if (len <= 0) {
+ break;
+ }
string new_name;
- if (session->region_name (new_name, ar->name())) {
- continue;
+ if (session->region_name (new_name, r->name())) {
+ break;
}
- pl->add_region (RegionFactory::create (ar->sources(), file_start, len, new_name), pos);
-
+ /* do NOT announce new regions 1 by one, just wait till they are all done */
+
+ boost::shared_ptr<Region> nr = RegionFactory::create (r->sources(), file_start, len, new_name, 0, Region::DefaultFlags, false);
+ pl->add_region (nr, pos);
+
pos += len;
-
++x;
-
- } while (x != positions.end() && (*x) < ar->last_frame());
-
+
+ if (*x > r->last_frame()) {
+
+ /* add final fragment */
+
+ file_start = r->start() + (pos - r->position());
+ len = r->last_frame() - pos;
+
+ nr = RegionFactory::create (r->sources(), file_start, len, new_name, 0, Region::DefaultFlags);
+ pl->add_region (nr, pos);
+
+ break;
+ }
+ }
+
pl->thaw ();
-
+
XMLNode& after (pl->get_state());
session->add_command (new MementoCommand<Playlist>(*pl, &before, &after));
} else {
- ExclusiveRegionSelection esr (*this, entered_regionview);
+ RegionSelection rs;
+
+ get_regions_for_action (rs);
- if (selection->regions.empty()) {
+ if (rs.empty()) {
return;
}
- for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) {
+ for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
(*r)->region()->get_transients (positions);
}
}
}
}
}
+
+void
+Editor::playhead_forward_to_grid ()
+{
+ if (!session) return;
+ nframes64_t pos = playhead_cursor->current_frame;
+ if (pos < max_frames) {
+ pos++;
+ snap_to_internal (pos, 1, false);
+ session->request_locate (pos);
+ }
+}
+
+
+void
+Editor::playhead_backward_to_grid ()
+{
+ if (!session) return;
+ nframes64_t pos = playhead_cursor->current_frame;
+ if (pos > 1) {
+ pos--;
+ snap_to_internal (pos, -1, false);
+ session->request_locate (pos);
+ }
+}
+
+void
+Editor::set_track_height (TimeAxisView::TrackHeight h)
+{
+ TrackSelection& ts (selection->tracks);
+
+ if (ts.empty()) {
+ return;
+ }
+
+ for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) {
+ (*x)->set_height (h);
+ }
+}
+
+void
+Editor::set_track_height_largest ()
+{
+ set_track_height (TimeAxisView::Largest);
+}
+void
+Editor::set_track_height_large ()
+{
+ set_track_height (TimeAxisView::Large);
+}
+void
+Editor::set_track_height_larger ()
+{
+ set_track_height (TimeAxisView::Larger);
+}
+void
+Editor::set_track_height_normal ()
+{
+ set_track_height (TimeAxisView::Normal);
+}
+void
+Editor::set_track_height_smaller ()
+{
+ set_track_height (TimeAxisView::Smaller);
+}
+void
+Editor::set_track_height_small ()
+{
+ set_track_height (TimeAxisView::Small);
+}
+
+void
+Editor::toggle_tracks_active ()
+{
+ TrackSelection& ts (selection->tracks);
+ bool first = true;
+ bool target = false;
+
+ if (ts.empty()) {
+ return;
+ }
+
+ for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) {
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(*x);
+
+ if (rtv) {
+ if (first) {
+ target = !rtv->_route->active();
+ first = false;
+ }
+ rtv->_route->set_active (target);
+ }
+ }
+}
+
+void
+Editor::remove_tracks ()
+{
+ TrackSelection& ts (selection->tracks);
+
+ if (ts.empty()) {
+ return;
+ }
+
+ vector<string> choices;
+ string prompt;
+ int ntracks = 0;
+ int nbusses = 0;
+ const char* trackstr;
+ const char* busstr;
+ vector<boost::shared_ptr<Route> > routes;
+
+ for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) {
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*x);
+ if (rtv) {
+ if (rtv->is_track()) {
+ ntracks++;
+ } else {
+ nbusses++;
+ }
+ }
+ routes.push_back (rtv->_route);
+ }
+
+ if (ntracks + nbusses == 0) {
+ return;
+ }
+
+ if (ntracks > 1) {
+ trackstr = _("tracks");
+ } else {
+ trackstr = _("track");
+ }
+
+ if (nbusses > 1) {
+ busstr = _("busses");
+ } else {
+ busstr = _("bus");
+ }
+
+ 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!"),
+ 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!"),
+ ntracks, trackstr);
+ }
+ } else if (nbusses) {
+ prompt = string_compose (_("Do you really want to remove %1 %2?"),
+ nbusses, busstr);
+ }
+
+ choices.push_back (_("No, do nothing."));
+ if (ntracks + nbusses > 1) {
+ choices.push_back (_("Yes, remove them."));
+ } else {
+ choices.push_back (_("Yes, remove it."));
+ }
+
+ Choice prompter (prompt, choices);
+
+ if (prompter.run () != 1) {
+ return;
+ }
+
+ for (vector<boost::shared_ptr<Route> >::iterator x = routes.begin(); x != routes.end(); ++x) {
+ session->remove_route (*x);
+ }
+}
+
+void
+Editor::set_waveform_scale (WaveformScale ws)
+{
+ TrackSelection& ts (selection->tracks);
+
+ if (ts.empty()) {
+ return;
+ }
+
+ for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) {
+ AudioTimeAxisView* atv = dynamic_cast<AudioTimeAxisView*> (*x);
+ if (atv) {
+ atv->set_waveform_scale (ws);
+ }
+ }
+}
+
+void
+Editor::do_insert_time ()
+{
+ if (selection->tracks.empty()) {
+ return;
+ }
+
+ nframes64_t pos = get_preferred_edit_position ();
+ ArdourDialog d (*this, _("Insert Time"));
+ VButtonBox button_box;
+ VBox option_box;
+ RadioButtonGroup group;
+ RadioButton leave_button (group, _("Stay in position"));
+ RadioButton move_button (group, _("Move"));
+ RadioButton split_button (group, _("Split & Later Section Moves"));
+ Label intersect_option_label (_("Intersected regions should:"));
+ ToggleButton glue_button (_("Move Glued Regions"));
+ AudioClock clock ("insertTimeClock", true, X_("InsertTimeClock"), true, true, true);
+ HBox clock_box;
+
+ clock.set (0);
+ clock.set_session (session);
+ clock.set_bbt_reference (pos);
+
+ clock_box.pack_start (clock, false, true);
+
+ option_box.set_spacing (6);
+ option_box.pack_start (intersect_option_label, false, false);
+ option_box.pack_start (button_box, false, false);
+ option_box.pack_start (glue_button, false, false);
+
+ button_box.pack_start (leave_button, false, false);
+ button_box.pack_start (move_button, false, false);
+ button_box.pack_start (split_button, false, false);
+
+ d.get_vbox()->set_border_width (12);
+ d.get_vbox()->pack_start (clock_box, false, false);
+ d.get_vbox()->pack_start (option_box, false, false);
+
+ leave_button.show ();
+ move_button.show ();
+ split_button.show ();
+ intersect_option_label.show ();
+ option_box.show ();
+ button_box.show ();
+ glue_button.show ();
+ clock.show_all();
+ clock_box.show ();
+
+ d.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
+ d.add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK);
+ d.show ();
+
+ int response = d.run ();
+
+ if (response != RESPONSE_OK) {
+ return;
+ }
+
+ nframes_t distance = clock.current_duration (pos);
+
+ if (distance == 0) {
+ return;
+ }
+
+ InsertTimeOption opt;
+
+ if (leave_button.get_active()) {
+ opt = LeaveIntersected;
+ } else if (move_button.get_active()) {
+ opt = MoveIntersected;
+ } else {
+ opt = SplitIntersected;
+ }
+
+ insert_time (pos, distance, opt, glue_button.get_active());
+}
+
+void
+Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt, bool ignore_music_glue)
+{
+ bool commit = false;
+
+ if (Config->get_edit_mode() == Lock) {
+ return;
+ }
+
+ begin_reversible_command (_("insert time"));
+
+ for (TrackSelection::iterator x = selection->tracks.begin(); x != selection->tracks.end(); ++x) {
+ boost::shared_ptr<Playlist> pl = (*x)->playlist();
+
+ if (!pl) {
+ continue;
+ }
+
+ XMLNode &before = pl->get_state();
+
+ if (opt == SplitIntersected) {
+ pl->split (pos);
+ }
+
+ pl->shift (pos, frames, (opt == MoveIntersected), ignore_music_glue);
+
+ XMLNode &after = pl->get_state();
+
+ session->add_command (new MementoCommand<Playlist> (*pl, &before, &after));
+ commit = true;
+ }
+
+ if (commit) {
+ commit_reversible_command ();
+ }
+}