#include "ardour/quantize.h"
#include "ardour/strip_silence.h"
#include "ardour/route_group.h"
+#include "ardour/operations.h"
#include "ardour_ui.h"
+#include "debug.h"
#include "editor.h"
#include "time_axis_view.h"
#include "route_time_axis.h"
#include "editor_regions.h"
#include "quantize_dialog.h"
#include "interthread_progress_window.h"
+#include "insert_time_dialog.h"
+#include "normalize_dialog.h"
+#include "editor_cursors.h"
+#include "mouse_cursors.h"
+#include "patch_change_dialog.h"
+#include "transpose_dialog.h"
#include "i18n.h"
}
void
-Editor::split_regions_at (nframes64_t where, RegionSelection& regions)
+Editor::split_regions_at (framepos_t where, RegionSelection& regions)
{
+ bool frozen = false;
+
list <boost::shared_ptr<Playlist > > used_playlists;
if (regions.empty()) {
}
} else {
snap_to (where);
+
+ frozen = true;
+ EditorFreeze(); /* Emit Signal */
}
for (RegionSelection::iterator a = regions.begin(); a != regions.end(); ) {
boost::shared_ptr<Playlist> pl = (*a)->region()->playlist();
- if (!pl) {
- cerr << "region " << (*a)->region()->name() << " has no playlist!\n";
- a = tmp;
- continue;
- }
+ if (!pl) {
+ a = tmp;
+ continue;
+ }
if (!pl->frozen()) {
/* we haven't seen this playlist before */
}
if (pl) {
- pl->clear_history ();
+ pl->clear_changes ();
pl->split_region ((*a)->region(), where);
_session->add_command (new StatefulDiffCommand (pl));
}
}
commit_reversible_command ();
-}
-
-boost::shared_ptr<Region>
-Editor::select_region_for_operation (int /*dir*/, TimeAxisView **tv)
-{
- RegionView* rv;
- boost::shared_ptr<Region> region;
- nframes64_t start = 0;
-
- if (selection->time.start () == selection->time.end_frame ()) {
-
- /* no current selection-> is there a selected regionview? */
-
- if (selection->regions.empty()) {
- return region;
- }
-
- }
- if (!selection->regions.empty()) {
-
- rv = *(selection->regions.begin());
- (*tv) = &rv->get_time_axis_view();
- region = rv->region();
-
- } else if (!selection->tracks.empty()) {
-
- (*tv) = selection->tracks.front();
-
- RouteTimeAxisView* rtv;
-
- if ((rtv = dynamic_cast<RouteTimeAxisView*> (*tv)) != 0) {
- boost::shared_ptr<Playlist> pl;
-
- if ((pl = rtv->playlist()) == 0) {
- return region;
- }
-
- region = pl->top_region_at (start);
- }
+ if (frozen){
+ EditorThaw(); /* Emit Signal */
}
-
- return region;
}
+/** Move one extreme of the current range selection. If more than one range is selected,
+ * the start of the earliest range or the end of the latest range is moved.
+ *
+ * @param move_end true to move the end of the current range selection, false to move
+ * the start.
+ * @param next true to move the extreme to the next region boundary, false to move to
+ * the previous.
+ */
void
-Editor::extend_selection_to_end_of_region (bool next)
+Editor::move_range_selection_start_or_end_to_region_boundary (bool move_end, bool next)
{
- TimeAxisView *tv;
- boost::shared_ptr<Region> region;
- nframes64_t start;
-
- if ((region = select_region_for_operation (next ? 1 : 0, &tv)) == 0) {
+ if (selection->time.start() == selection->time.end_frame()) {
return;
}
- if (region && selection->time.start () == selection->time.end_frame ()) {
- start = region->position();
- } else {
- start = selection->time.start ();
- }
+ framepos_t start = selection->time.start ();
+ framepos_t end = selection->time.end_frame ();
- begin_reversible_command (_("extend selection"));
- selection->set (start, region->position() + region->length());
- commit_reversible_command ();
-}
+ /* the position of the thing we may move */
+ framepos_t pos = move_end ? end : start;
+ int dir = next ? 1 : -1;
-void
-Editor::extend_selection_to_start_of_region (bool previous)
-{
- TimeAxisView *tv;
- boost::shared_ptr<Region> region;
- nframes64_t end;
+ /* so we don't find the current region again */
+ if (dir > 0 || pos > 0) {
+ pos += dir;
+ }
- if ((region = select_region_for_operation (previous ? -1 : 0, &tv)) == 0) {
+ framepos_t const target = get_region_boundary (pos, dir, true, false);
+ if (target < 0) {
return;
}
- if (region && selection->time.start () == selection->time.end_frame ()) {
- end = region->position() + region->length();
+ if (move_end) {
+ end = target;
} else {
- end = selection->time.end_frame ();
+ start = target;
}
- /* Try to leave the selection with the same route if possible */
+ if (end < start) {
+ return;
+ }
- begin_reversible_command (_("extend selection"));
- selection->set (region->position(), end);
+ begin_reversible_command (_("alter selection"));
+ selection->set_preserving_all_ranges (start, end);
commit_reversible_command ();
}
void
Editor::nudge_forward (bool next, bool force_playhead)
{
- nframes64_t distance;
- nframes64_t next_distance;
- RegionSelection rs;
+ framepos_t distance;
+ framepos_t next_distance;
- get_regions_for_action (rs);
+ if (!_session) {
+ return;
+ }
- if (!_session) return;
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (!force_playhead && !rs.empty()) {
distance = next_distance;
}
- r->clear_history ();
- r->set_position (r->position() + distance, this);
+ r->clear_changes ();
+ r->set_position (r->position() + distance);
_session->add_command (new StatefulDiffCommand (r));
}
if (next) {
distance = next_distance;
}
- if (max_frames - distance > loc->start() + loc->length()) {
+ if (max_framepos - distance > loc->start() + loc->length()) {
loc->set_start (loc->start() + distance);
} else {
- loc->set_start (max_frames - loc->length());
+ loc->set_start (max_framepos - loc->length());
}
} else {
distance = get_nudge_distance (loc->end(), next_distance);
if (next) {
distance = next_distance;
}
- if (max_frames - distance > loc->end()) {
+ if (max_framepos - distance > loc->end()) {
loc->set_end (loc->end() + distance);
} else {
- loc->set_end (max_frames);
+ loc->set_end (max_framepos);
}
}
XMLNode& after (loc->get_state());
void
Editor::nudge_backward (bool next, bool force_playhead)
{
- nframes64_t distance;
- nframes64_t next_distance;
- RegionSelection rs;
+ framepos_t distance;
+ framepos_t next_distance;
- get_regions_for_action (rs);
+ if (!_session) {
+ return;
+ }
- if (!_session) return;
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (!force_playhead && !rs.empty()) {
if (next) {
distance = next_distance;
}
-
- r->clear_history ();
+
+ r->clear_changes ();
if (r->position() > distance) {
- r->set_position (r->position() - distance, this);
+ r->set_position (r->position() - distance);
} else {
- r->set_position (0, this);
+ r->set_position (0);
}
_session->add_command (new StatefulDiffCommand (r));
}
void
Editor::nudge_forward_capture_offset ()
{
- nframes64_t distance;
- RegionSelection rs;
-
- get_regions_for_action (rs);
-
- if (!_session) return;
+ RegionSelection rs = get_regions_from_selection_and_entered ();
- if (!rs.empty()) {
-
- begin_reversible_command (_("nudge forward"));
-
- distance = _session->worst_output_latency();
+ if (!_session || rs.empty()) {
+ return;
+ }
- for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
- boost::shared_ptr<Region> r ((*i)->region());
+ begin_reversible_command (_("nudge forward"));
- r->clear_history ();
- r->set_position (r->position() + distance, this);
- _session->add_command(new StatefulDiffCommand (r));
- }
+ framepos_t const distance = _session->worst_output_latency();
- commit_reversible_command ();
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+ boost::shared_ptr<Region> r ((*i)->region());
+ r->clear_changes ();
+ r->set_position (r->position() + distance);
+ _session->add_command(new StatefulDiffCommand (r));
}
+
+ commit_reversible_command ();
}
void
Editor::nudge_backward_capture_offset ()
{
- nframes64_t distance;
- RegionSelection rs;
-
- get_regions_for_action (rs);
-
- if (!_session) return;
+ RegionSelection rs = get_regions_from_selection_and_entered ();
- if (!rs.empty()) {
+ if (!_session || rs.empty()) {
+ return;
+ }
- begin_reversible_command (_("nudge forward"));
+ begin_reversible_command (_("nudge forward"));
- distance = _session->worst_output_latency();
+ framepos_t const distance = _session->worst_output_latency();
- for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
- boost::shared_ptr<Region> r ((*i)->region());
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+ boost::shared_ptr<Region> r ((*i)->region());
- r->clear_history ();
+ r->clear_changes ();
- if (r->position() > distance) {
- r->set_position (r->position() - distance, this);
- } else {
- r->set_position (0, this);
- }
- _session->add_command(new StatefulDiffCommand (r));
+ if (r->position() > distance) {
+ r->set_position (r->position() - distance);
+ } else {
+ r->set_position (0);
}
-
- commit_reversible_command ();
+ _session->add_command(new StatefulDiffCommand (r));
}
+
+ commit_reversible_command ();
}
/* DISPLAY MOTION */
void
Editor::build_region_boundary_cache ()
{
- nframes64_t pos = 0;
+ framepos_t pos = 0;
vector<RegionPoint> interesting_points;
boost::shared_ptr<Region> r;
TrackViewList tracks;
while (pos < _session->current_end_frame() && !at_end) {
- nframes64_t rpos;
- nframes64_t lpos = max_frames;
+ framepos_t rpos;
+ framepos_t lpos = max_framepos;
for (vector<RegionPoint>::iterator p = interesting_points.begin(); p != interesting_points.end(); ++p) {
case SyncPoint:
rpos = r->sync_position ();
- //r->adjust_to_sync (r->first_frame());
break;
default:
to sort later.
*/
- vector<nframes64_t>::iterator ri;
+ vector<framepos_t>::iterator ri;
for (ri = region_boundary_cache.begin(); ri != region_boundary_cache.end(); ++ri) {
if (*ri == rpos) {
}
boost::shared_ptr<Region>
-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;
+ framepos_t closest = max_framepos;
boost::shared_ptr<Region> 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<Region> r;
track_speed = 1.0f;
case SyncPoint:
rpos = r->sync_position ();
- // r->adjust_to_sync (r->first_frame());
break;
}
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_framepos;
+ 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<RouteTimeAxisView*> (*i);
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()) {
void
Editor::cursor_to_region_boundary (bool with_selection, int32_t dir)
{
- nframes64_t pos = playhead_cursor->current_frame;
- nframes64_t target;
+ framepos_t pos = playhead_cursor->current_frame;
+ framepos_t target;
if (!_session) {
return;
Editor::cursor_to_region_point (EditorCursor* cursor, RegionPoint point, int32_t dir)
{
boost::shared_ptr<Region> r;
- nframes64_t pos = cursor->current_frame;
+ framepos_t pos = cursor->current_frame;
if (!_session) {
return;
return;
}
- switch (point){
+ switch (point) {
case Start:
pos = r->first_frame ();
break;
case SyncPoint:
pos = r->sync_position ();
- // r->adjust_to_sync (r->first_frame());
break;
}
void
Editor::cursor_to_selection_start (EditorCursor *cursor)
{
- nframes64_t pos = 0;
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ framepos_t pos = 0;
switch (mouse_mode) {
case MouseObject:
- if (!rs.empty()) {
- pos = rs.start();
+ if (!selection->regions.empty()) {
+ pos = selection->regions.start();
}
break;
void
Editor::cursor_to_selection_end (EditorCursor *cursor)
{
- nframes64_t pos = 0;
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ framepos_t pos = 0;
switch (mouse_mode) {
case MouseObject:
- if (!rs.empty()) {
- pos = rs.end_frame();
+ if (!selection->regions.empty()) {
+ pos = selection->regions.end_frame();
}
break;
void
Editor::selected_marker_to_region_boundary (bool with_selection, int32_t dir)
{
- nframes64_t target;
+ framepos_t target;
Location* loc;
bool ignored;
}
if (selection->markers.empty()) {
- nframes64_t mouse;
+ framepos_t mouse;
bool ignored;
if (!mouse_frame (mouse, ignored)) {
return;
}
- nframes64_t pos = loc->start();
+ framepos_t pos = loc->start();
// so we don't find the current region again..
if (dir > 0 || pos > 0) {
Editor::selected_marker_to_region_point (RegionPoint point, int32_t dir)
{
boost::shared_ptr<Region> r;
- nframes64_t pos;
+ framepos_t pos;
Location* loc;
bool ignored;
return;
}
- switch (point){
+ switch (point) {
case Start:
pos = r->first_frame ();
break;
void
Editor::selected_marker_to_selection_start ()
{
- nframes64_t pos = 0;
+ framepos_t pos = 0;
Location* loc;
bool ignored;
return;
}
- RegionSelection rs;
-
- get_regions_for_action (rs);
-
switch (mouse_mode) {
case MouseObject:
- if (!rs.empty()) {
- pos = rs.start();
+ if (!selection->regions.empty()) {
+ pos = selection->regions.start();
}
break;
void
Editor::selected_marker_to_selection_end ()
{
- nframes64_t pos = 0;
+ framepos_t pos = 0;
Location* loc;
bool ignored;
return;
}
- RegionSelection rs;
-
- get_regions_for_action (rs);
-
switch (mouse_mode) {
case MouseObject:
- if (!rs.empty()) {
- pos = rs.end_frame();
+ if (!selection->regions.empty()) {
+ pos = selection->regions.end_frame();
}
break;
void
Editor::scroll_playhead (bool forward)
{
- nframes64_t pos = playhead_cursor->current_frame;
- nframes64_t delta = (nframes64_t) floor (current_page_frames() / 0.8);
+ framepos_t pos = playhead_cursor->current_frame;
+ framecnt_t delta = (framecnt_t) floor (current_page_frames() / 0.8);
if (forward) {
- if (pos == max_frames) {
+ if (pos == max_framepos) {
return;
}
- if (pos < max_frames - delta) {
+ if (pos < max_framepos - delta) {
pos += delta ;
} else {
- pos = max_frames;
+ pos = max_framepos;
}
} else {
_session->request_locate (pos);
}
-void
-Editor::playhead_backward ()
-{
- nframes64_t pos;
- nframes64_t cnt;
- float prefix;
- bool was_floating;
-
- if (get_prefix (prefix, was_floating)) {
- cnt = 1;
- } else {
- if (was_floating) {
- cnt = (nframes64_t) floor (prefix * _session->frame_rate ());
- } else {
- cnt = (nframes64_t) prefix;
- }
- }
-
- pos = playhead_cursor->current_frame;
-
- if ((nframes64_t) pos < cnt) {
- pos = 0;
- } else {
- pos -= cnt;
- }
-
- /* XXX this is completely insane. with the current buffering
- design, we'll force a complete track buffer flush and
- reload, just to move 1 sample !!!
- */
-
- _session->request_locate (pos);
-}
-
-void
-Editor::playhead_forward ()
-{
- nframes64_t pos;
- nframes64_t cnt;
- bool was_floating;
- float prefix;
-
- if (get_prefix (prefix, was_floating)) {
- cnt = 1;
- } else {
- if (was_floating) {
- cnt = (nframes64_t) floor (prefix * _session->frame_rate ());
- } else {
- cnt = (nframes64_t) floor (prefix);
- }
- }
-
- pos = playhead_cursor->current_frame;
-
- /* XXX this is completely insane. with the current buffering
- design, we'll force a complete track buffer flush and
- reload, just to move 1 sample !!!
- */
-
- _session->request_locate (pos+cnt);
-}
-
void
Editor::cursor_align (bool playhead_to_edit)
{
}
}
-void
-Editor::edit_cursor_backward ()
-{
- nframes64_t pos;
- nframes64_t cnt;
- float prefix;
- bool was_floating;
-
- if (get_prefix (prefix, was_floating)) {
- cnt = 1;
- } else {
- if (was_floating) {
- cnt = (nframes64_t) floor (prefix * _session->frame_rate ());
- } else {
- cnt = (nframes64_t) prefix;
- }
- }
-
- if ((pos = get_preferred_edit_position()) < 0) {
- return;
- }
-
- if (pos < cnt) {
- pos = 0;
- } else {
- pos -= cnt;
- }
-
- // EDIT CURSOR edit_cursor->set_position (pos);
-}
-
-void
-Editor::edit_cursor_forward ()
-{
- //nframes64_t pos;
- nframes64_t cnt;
- bool was_floating;
- float prefix;
-
- if (get_prefix (prefix, was_floating)) {
- cnt = 1;
- } else {
- if (was_floating) {
- cnt = (nframes64_t) floor (prefix * _session->frame_rate ());
- } else {
- cnt = (nframes64_t) floor (prefix);
- }
- }
-
- // pos = edit_cursor->current_frame;
- // EDIT CURSOR edit_cursor->set_position (pos+cnt);
-}
-
-void
-Editor::goto_frame ()
-{
- float prefix;
- bool was_floating;
- nframes64_t frame;
-
- if (get_prefix (prefix, was_floating)) {
- return;
- }
-
- if (was_floating) {
- frame = (nframes64_t) floor (prefix * _session->frame_rate());
- } else {
- frame = (nframes64_t) floor (prefix);
- }
-
- _session->request_locate (frame);
-}
-
void
Editor::scroll_backward (float pages)
{
- nframes64_t frame;
- nframes64_t one_page = (nframes64_t) rint (_canvas_width * frames_per_unit);
- bool was_floating;
- float prefix;
- nframes64_t cnt;
-
- if (get_prefix (prefix, was_floating)) {
- cnt = (nframes64_t) floor (pages * one_page);
- } else {
- if (was_floating) {
- cnt = (nframes64_t) floor (prefix * _session->frame_rate());
- } else {
- cnt = (nframes64_t) floor (prefix * one_page);
- }
- }
+ framepos_t const one_page = (framepos_t) rint (_canvas_width * frames_per_unit);
+ framepos_t const cnt = (framepos_t) floor (pages * one_page);
+ framepos_t frame;
if (leftmost_frame < cnt) {
frame = 0;
} else {
void
Editor::scroll_forward (float pages)
{
- nframes64_t frame;
- nframes64_t one_page = (nframes64_t) rint (_canvas_width * frames_per_unit);
- bool was_floating;
- float prefix;
- nframes64_t cnt;
-
- if (get_prefix (prefix, was_floating)) {
- cnt = (nframes64_t) floor (pages * one_page);
- } else {
- if (was_floating) {
- cnt = (nframes64_t) floor (prefix * _session->frame_rate());
- } else {
- cnt = (nframes64_t) floor (prefix * one_page);
- }
- }
+ framepos_t const one_page = (framepos_t) rint (_canvas_width * frames_per_unit);
+ framepos_t const cnt = (framepos_t) floor (pages * one_page);
- if (max_frames - cnt < leftmost_frame) {
- frame = max_frames - cnt;
+ framepos_t frame;
+ if (max_framepos - cnt < leftmost_frame) {
+ frame = max_framepos - cnt;
} else {
frame = leftmost_frame + cnt;
}
void
Editor::scroll_tracks_down ()
{
- float prefix;
- bool was_floating;
- int cnt;
-
- if (get_prefix (prefix, was_floating)) {
- cnt = 1;
- } else {
- cnt = (int) floor (prefix);
- }
-
- double vert_value = vertical_adjustment.get_value() + (cnt *
- vertical_adjustment.get_page_size());
+ double vert_value = vertical_adjustment.get_value() + vertical_adjustment.get_page_size();
if (vert_value > vertical_adjustment.get_upper() - _canvas_height) {
vert_value = vertical_adjustment.get_upper() - _canvas_height;
}
+
vertical_adjustment.set_value (vert_value);
}
void
Editor::scroll_tracks_up ()
{
- float prefix;
- bool was_floating;
- int cnt;
-
- if (get_prefix (prefix, was_floating)) {
- cnt = 1;
- } else {
- cnt = (int) floor (prefix);
- }
-
- vertical_adjustment.set_value (vertical_adjustment.get_value() - (cnt * vertical_adjustment.get_page_size()));
+ vertical_adjustment.set_value (vertical_adjustment.get_value() - vertical_adjustment.get_page_size());
}
void
if (vert_value > vertical_adjustment.get_upper() - _canvas_height) {
vert_value = vertical_adjustment.get_upper() - _canvas_height;
}
-
+
vertical_adjustment.set_value (vert_value);
}
{
if (!_session) return;
- nframes64_t current_page = current_page_frames();
- nframes64_t current_leftmost = leftmost_frame;
- nframes64_t current_rightmost;
- nframes64_t current_center;
- nframes64_t new_page_size;
- nframes64_t half_page_size;
- nframes64_t leftmost_after_zoom = 0;
- nframes64_t where;
+ framepos_t current_page = current_page_frames();
+ framepos_t current_leftmost = leftmost_frame;
+ framepos_t current_rightmost;
+ framepos_t current_center;
+ framepos_t new_page_size;
+ framepos_t half_page_size;
+ framepos_t leftmost_after_zoom = 0;
+ framepos_t where;
bool in_track_canvas;
double nfpu;
double l;
nfpu = fpu;
- new_page_size = (nframes64_t) floor (_canvas_width * nfpu);
+ new_page_size = (framepos_t) floor (_canvas_width * nfpu);
half_page_size = new_page_size / 2;
switch (zoom_focus) {
if (l < 0) {
leftmost_after_zoom = 0;
- } else if (l > max_frames) {
- leftmost_after_zoom = max_frames - new_page_size;
+ } else if (l > max_framepos) {
+ leftmost_after_zoom = max_framepos - new_page_size;
} else {
- leftmost_after_zoom = (nframes64_t) l;
+ leftmost_after_zoom = (framepos_t) l;
}
break;
if (l < 0) {
leftmost_after_zoom = 0;
- } else if (l > max_frames) {
- leftmost_after_zoom = max_frames - new_page_size;
+ } else if (l > max_framepos) {
+ leftmost_after_zoom = max_framepos - new_page_size;
} else {
- leftmost_after_zoom = (nframes64_t) l;
+ leftmost_after_zoom = (framepos_t) l;
}
}
if (l < 0) {
leftmost_after_zoom = 0;
- } else if (l > max_frames) {
- leftmost_after_zoom = max_frames - new_page_size;
+ } else if (l > max_framepos) {
+ leftmost_after_zoom = max_framepos - new_page_size;
} else {
- leftmost_after_zoom = (nframes64_t) l;
+ leftmost_after_zoom = (framepos_t) l;
}
} else {
void
Editor::temporal_zoom_region (bool both_axes)
{
-
- nframes64_t start = max_frames;
- nframes64_t end = 0;
- RegionSelection rs;
+ framepos_t start = max_framepos;
+ framepos_t end = 0;
set<TimeAxisView*> tracks;
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
return;
}
- nframes64_t range = end - start;
+ framepos_t range = end - start;
double new_fpu = (double)range / (double)_canvas_width;
- nframes64_t extra_samples = (nframes64_t) floor (one_centimeter_in_pixels * new_fpu);
+ framepos_t extra_samples = (framepos_t) floor (one_centimeter_in_pixels * new_fpu);
if (start > extra_samples) {
start -= extra_samples;
start = 0;
}
- if (max_frames - extra_samples > end) {
+ if (max_framepos - extra_samples > end) {
end += extra_samples;
} else {
- end = max_frames;
+ end = max_framepos;
}
if (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);
}
}
return;
}
- nframes64_t start = selection->time[clicked_selection].start;
- nframes64_t end = selection->time[clicked_selection].end;
+ framepos_t start = selection->time[clicked_selection].start;
+ framepos_t end = selection->time[clicked_selection].end;
temporal_zoom_by_frame (start, end, "zoom to selection");
}
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");
+ framecnt_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;
+ }
+ framecnt_t const e = _session->current_end_frame() + l * 0.01;
+ temporal_zoom_by_frame (framecnt_t (s), e, "zoom to _session");
}
}
void
-Editor::temporal_zoom_by_frame (nframes64_t start, nframes64_t end, const string & /*op*/)
+Editor::temporal_zoom_by_frame (framepos_t start, framepos_t end, const string & /*op*/)
{
if (!_session) return;
return;
}
- nframes64_t range = end - start;
+ framepos_t range = end - start;
double new_fpu = (double)range / (double)_canvas_width;
- nframes64_t new_page = (nframes64_t) floor (_canvas_width * new_fpu);
- nframes64_t middle = (nframes64_t) floor( (double)start + ((double)range / 2.0f ));
- nframes64_t new_leftmost = (nframes64_t) floor( (double)middle - ((double)new_page/2.0f));
+ framepos_t new_page = (framepos_t) floor (_canvas_width * new_fpu);
+ framepos_t middle = (framepos_t) floor( (double)start + ((double)range / 2.0f ));
+ framepos_t new_leftmost = (framepos_t) floor( (double)middle - ((double)new_page/2.0f));
if (new_leftmost > middle) {
new_leftmost = 0;
}
void
-Editor::temporal_zoom_to_frame (bool coarser, nframes64_t frame)
+Editor::temporal_zoom_to_frame (bool coarser, framepos_t frame)
{
if (!_session) {
return;
return;
}
- nframes64_t new_leftmost = frame - (nframes64_t)range_before;
+ framepos_t new_leftmost = frame - (framepos_t)range_before;
if (new_leftmost > frame) {
new_leftmost = 0;
}
-// begin_reversible_command (_("zoom to frame"));
-// _session->add_undo (sigc::bind (sigc::mem_fun(*this, &Editor::reposition_and_zoom), leftmost_frame, frames_per_unit));
-// _session->add_redo (sigc::bind (sigc::mem_fun(*this, &Editor::reposition_and_zoom), new_leftmost, new_fpu));
-// commit_reversible_command ();
+
+ if (new_leftmost < 0) {
+ new_leftmost = 0;
+ }
reposition_and_zoom (new_leftmost, new_fpu);
}
return;
}
- nframes64_t start = selection->time[clicked_selection].start;
- nframes64_t end = selection->time[clicked_selection].end;
+ framepos_t start = selection->time[clicked_selection].start;
+ framepos_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();
+ XMLNode &before = _session->locations()->get_state();
_session->locations()->add (location, true);
- XMLNode &after = _session->locations()->get_state();
+ XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
_session->commit_reversible_command ();
}
void
-Editor::add_location_mark (nframes64_t where)
+Editor::add_location_mark (framepos_t where)
{
string markername;
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();
+ XMLNode &before = _session->locations()->get_state();
_session->locations()->add (location, true);
- XMLNode &after = _session->locations()->get_state();
+ XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
_session->commit_reversible_command ();
}
add_location_mark (_session->audible_frame());
}
+/** Add a range marker around each selected region */
void
-Editor::add_locations_from_audio_region ()
+Editor::add_locations_from_region ()
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
}
- _session->begin_reversible_command (rs.size () > 1 ? _("add markers") : _("add marker"));
+ _session->begin_reversible_command (selection->regions.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> 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);
}
_session->commit_reversible_command ();
}
+/** Add a single range marker around all selected regions */
void
-Editor::add_location_from_audio_region ()
+Editor::add_location_from_region ()
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
string markername;
- if (rs.size() > 1) { // more than one region selected
+ if (rs.size() > 1) {
_session->locations()->next_available_name(markername, "regions");
} else {
RegionView* rv = *(rs.begin());
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, selection->regions.start(), selection->regions.end_frame(), markername, Location::IsRangeMarker);
_session->locations()->add (location, true);
XMLNode &after = _session->locations()->get_state();
_session->commit_reversible_command ();
}
-void
-Editor::amplitude_zoom_step (bool in)
-{
- gdouble zoom = 1.0;
-
- if (in) {
- zoom *= 2.0;
- } else {
- if (zoom > 2.0) {
- zoom /= 2.0;
- } else {
- zoom = 1.0;
- }
- }
-
-#ifdef FIX_FOR_CANVAS
- /* XXX DO SOMETHING */
-#endif
-}
-
-
-/* DELETION */
-
-
-void
-Editor::delete_sample_forward ()
-{
-}
-
-void
-Editor::delete_sample_backward ()
-{
-}
-
-void
-Editor::delete_screen ()
-{
-}
-
-/* SEARCH */
-
-void
-Editor::search_backwards ()
-{
- /* what ? */
-}
-
-void
-Editor::search_forwards ()
-{
- /* what ? */
-}
-
/* MARKS */
void
void
Editor::set_mark ()
{
- nframes64_t pos;
- float prefix;
- bool was_floating;
- string markername;
+ framepos_t const pos = _session->audible_frame ();
- if (get_prefix (prefix, was_floating)) {
- pos = _session->audible_frame ();
- } else {
- if (was_floating) {
- pos = (nframes64_t) floor (prefix * _session->frame_rate ());
- } else {
- pos = (nframes64_t) floor (prefix);
- }
- }
+ string markername;
+ _session->locations()->next_available_name (markername, "mark");
- _session->locations()->next_available_name(markername,"mark");
- if (!choose_new_marker_name(markername)) {
+ 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
{
if (_session) {
_session->begin_reversible_command (_("clear markers"));
- XMLNode &before = _session->locations()->get_state();
+ XMLNode &before = _session->locations()->get_state();
_session->locations()->clear_markers ();
- XMLNode &after = _session->locations()->get_state();
+ XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
_session->commit_reversible_command ();
}
{
if (_session) {
_session->begin_reversible_command (_("clear ranges"));
- XMLNode &before = _session->locations()->get_state();
+ XMLNode &before = _session->locations()->get_state();
Location * looploc = _session->locations()->auto_loop_location();
Location * punchloc = _session->locations()->auto_punch_location();
if (looploc) _session->locations()->add (looploc);
if (punchloc) _session->locations()->add (punchloc);
- XMLNode &after = _session->locations()->get_state();
+ XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
_session->commit_reversible_command ();
}
Editor::clear_locations ()
{
_session->begin_reversible_command (_("clear locations"));
- XMLNode &before = _session->locations()->get_state();
+ XMLNode &before = _session->locations()->get_state();
_session->locations()->clear ();
- XMLNode &after = _session->locations()->get_state();
+ XMLNode &after = _session->locations()->get_state();
_session->add_command(new MementoCommand<Locations>(*(_session->locations()), &before, &after));
_session->commit_reversible_command ();
_session->locations()->clear ();
{
double wx, wy;
double cx, cy;
- nframes64_t where;
+ framepos_t where;
RouteTimeAxisView *rtv = 0;
boost::shared_ptr<Playlist> playlist;
snap_to (where);
begin_reversible_command (_("insert dragged region"));
- playlist->clear_history ();
- playlist->add_region (RegionFactory::create (region), where, 1.0);
+ playlist->clear_changes ();
+ playlist->add_region (RegionFactory::create (region, true), where, 1.0);
_session->add_command(new StatefulDiffCommand (playlist));
commit_reversible_command ();
}
{
double wx, wy;
double cx, cy;
- nframes_t where;
+ framepos_t where;
RouteTimeAxisView *dest_rtv = 0;
RouteTimeAxisView *source_rtv = 0;
}
begin_reversible_command (_("insert region"));
- playlist->clear_history ();
- playlist->add_region ((RegionFactory::create (region)), get_preferred_edit_position(), times);
+ playlist->clear_changes ();
+ playlist->add_region ((RegionFactory::create (region, true)), get_preferred_edit_position(), times);
_session->add_command(new StatefulDiffCommand (playlist));
commit_reversible_command ();
}
void
Editor::play_from_edit_point_and_return ()
{
- nframes64_t start_frame;
- nframes64_t return_frame;
+ framepos_t start_frame;
+ framepos_t return_frame;
start_frame = get_preferred_edit_position (true);
}
void
-Editor::loop_selected_region ()
-{
- RegionSelection rs;
-
- get_regions_for_action (rs);
-
- if (!rs.empty()) {
- RegionView *rv = *(rs.begin());
- Location* tll;
-
- if ((tll = transport_loop_location()) != 0) {
-
- tll->set (rv->region()->position(), rv->region()->last_frame());
-
- // enable looping, reposition and start rolling
-
- _session->request_play_loop (true);
- _session->request_locate (tll->start(), false);
- _session->request_transport_speed (1.0f);
- }
- }
-}
-
-void
-Editor::play_location (Location& location)
+Editor::play_location (Location& location)
{
if (location.start() <= location.end()) {
return;
/** Show the region editor for the selected regions */
void
-Editor::edit_region ()
+Editor::show_region_properties ()
{
selection->foreach_regionview (&RegionView::show_region_editor);
}
}
void
-Editor::rename_region()
+Editor::rename_region ()
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
d.set_size_request (300, -1);
d.set_position (Gtk::WIN_POS_MOUSE);
- entry.set_text (rs.front()->region()->name());
+ entry.set_text (selection->regions.front()->region()->name());
entry.select_region (0, -1);
entry.signal_activate().connect (sigc::bind (sigc::mem_fun (d, &Dialog::response), RESPONSE_OK));
entry.grab_focus();
- int ret = d.run();
+ int const ret = d.run();
d.hide ();
- if (ret == RESPONSE_OK) {
- std::string str = entry.get_text();
- strip_whitespace_edges (str);
- if (!str.empty()) {
- rs.front()->region()->set_name (str);
- _regions->redisplay ();
- }
+ if (ret != RESPONSE_OK) {
+ return;
+ }
+
+ std::string str = entry.get_text();
+ strip_whitespace_edges (str);
+ if (!str.empty()) {
+ rs.front()->region()->set_name (str);
+ _regions->redisplay ();
}
}
void
Editor::play_edit_range ()
{
- nframes64_t start, end;
+ framepos_t start, end;
if (get_edit_op_range (start, end)) {
_session->request_bounded_roll (start, end);
void
Editor::play_selected_region ()
{
- nframes64_t start = max_frames;
- nframes64_t end = 0;
- RegionSelection rs;
+ framepos_t start = max_framepos;
+ framepos_t end = 0;
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
return;
}
- nframes64_t start = selection->time[clicked_selection].start;
- nframes64_t end = selection->time[clicked_selection].end;
+ framepos_t start = selection->time[clicked_selection].start;
+ framepos_t end = selection->time[clicked_selection].end;
TrackViewList tracks = get_tracks_for_range_action ();
- nframes64_t selection_cnt = end - start + 1;
+ framepos_t selection_cnt = end - start + 1;
for (TrackSelection::iterator i = tracks.begin(); i != tracks.end(); ++i) {
boost::shared_ptr<Region> current;
boost::shared_ptr<Playlist> pl;
- nframes64_t internal_start;
+ framepos_t internal_start;
string new_name;
if ((pl = (*i)->playlist()) == 0) {
internal_start = start - current->position();
RegionFactory::region_name (new_name, current->name(), true);
- PropertyList plist;
-
+ PropertyList plist;
+
plist.add (ARDOUR::Properties::start, current->start() + internal_start);
plist.add (ARDOUR::Properties::length, selection_cnt);
plist.add (ARDOUR::Properties::name, new_name);
return;
}
- nframes64_t start = selection->time[clicked_selection].start;
- nframes64_t end = selection->time[clicked_selection].end;
+ framepos_t start = selection->time[clicked_selection].start;
+ framepos_t end = selection->time[clicked_selection].end;
sort_track_selection ();
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
boost::shared_ptr<Region> current;
boost::shared_ptr<Playlist> playlist;
- nframes64_t internal_start;
+ framepos_t internal_start;
string new_name;
if ((playlist = (*i)->playlist()) == 0) {
internal_start = start - current->position();
RegionFactory::region_name (new_name, current->name(), true);
- PropertyList plist;
-
+ PropertyList plist;
+
plist.add (ARDOUR::Properties::start, current->start() + internal_start);
plist.add (ARDOUR::Properties::length, end - start + 1);
plist.add (ARDOUR::Properties::name, new_name);
void
Editor::split_multichannel_region ()
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
if ((playlist = rtv->playlist()) != 0) {
- playlist->clear_history ();
+ playlist->clear_changes ();
/* XXX need to consider musical time selections here at some point */
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);
+ playlist->partition ((framepos_t)((*t).start * speed),
+ (framepos_t)((*t).end * speed), false);
c.disconnect ();
rtv->view()->foreach_regionview (sigc::bind (
sigc::ptr_fun (add_if_covered),
&(*t), &new_selection));
-
+
if (!in_command) {
begin_reversible_command (_("separate"));
in_command = true;
}
+ /* pick up changes to existing regions */
+
+ vector<Command*> cmds;
+ playlist->rdiff (cmds);
+ _session->add_commands (cmds);
+
+ /* pick up changes to the playlist itself (adds/removes)
+ */
+
_session->add_command(new StatefulDiffCommand (playlist));
}
}
}
}
+struct PlaylistState {
+ boost::shared_ptr<Playlist> 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.
} else {
- nframes64_t start;
- nframes64_t end;
+ framepos_t start;
+ framepos_t end;
if (get_edit_op_range (start, end)) {
separate_regions_between (ts);
}
+/** Separate regions under the selected region */
+void
+Editor::separate_under_selected_regions ()
+{
+ vector<PlaylistState> playlists;
+
+ RegionSelection rs;
+
+ rs = get_regions_from_selection_and_entered();
+
+ if (!_session || rs.empty()) {
+ return;
+ }
+
+ begin_reversible_command (_("separate region under"));
+
+ list<boost::shared_ptr<Region> > 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<boost::shared_ptr<Region> >::iterator rl = regions_to_remove.begin(); rl != regions_to_remove.end(); ++rl) {
+
+ boost::shared_ptr<Playlist> playlist = (*rl)->playlist();
+
+ if (!playlist) {
+ // is this check necessary?
+ continue;
+ }
+
+ vector<PlaylistState>::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<PlaylistState>::iterator pl;
+
+ for (pl = playlists.begin(); pl != playlists.end(); ++pl) {
+ (*pl).playlist->thaw ();
+ _session->add_command(new MementoCommand<Playlist>(*(*pl).playlist, (*pl).before, &(*pl).playlist->get_state()));
+ }
+
+ commit_reversible_command ();
+}
+
void
Editor::crop_region_to_selection ()
{
} else {
- nframes64_t start;
- nframes64_t end;
+ framepos_t start;
+ framepos_t end;
if (get_edit_op_range (start, end)) {
crop_region_to (start, end);
}
void
-Editor::crop_region_to (nframes64_t start, nframes64_t end)
+Editor::crop_region_to (framepos_t start, framepos_t end)
{
vector<boost::shared_ptr<Playlist> > playlists;
boost::shared_ptr<Playlist> playlist;
return;
}
- nframes64_t the_start;
- nframes64_t the_end;
- nframes64_t cnt;
+ framepos_t the_start;
+ framepos_t the_end;
+ framepos_t cnt;
begin_reversible_command (_("trim to selection"));
if the selection extends beyond the region
*/
- the_start = max (the_start, (nframes64_t) region->position());
- if (max_frames - the_start < region->length()) {
+ the_start = max (the_start, (framepos_t) region->position());
+ if (max_framepos - the_start < region->length()) {
the_end = the_start + region->length() - 1;
} else {
- the_end = max_frames;
+ the_end = max_framepos;
}
the_end = min (end, the_end);
cnt = the_end - the_start + 1;
- region->clear_history ();
- region->trim_to (the_start, cnt, this);
+ region->clear_changes ();
+ region->trim_to (the_start, cnt);
_session->add_command (new StatefulDiffCommand (region));
}
void
Editor::region_fill_track ()
{
- nframes64_t end;
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (!_session || rs.empty()) {
return;
}
- end = _session->current_end_frame ();
+ framepos_t const end = _session->current_end_frame ();
- begin_reversible_command (_("region fill"));
+ begin_reversible_command (Operations::region_fill);
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
return;
}
- pl->clear_history ();
- pl->add_region (RegionFactory::create (region), region->last_frame(), times);
+ pl->clear_changes ();
+ pl->add_region (RegionFactory::create (region, true), region->last_frame(), times);
_session->add_command (new StatefulDiffCommand (pl));
}
return;
}
- nframes64_t start = selection->time[clicked_selection].start;
- nframes64_t end = selection->time[clicked_selection].end;
+ framepos_t start = selection->time[clicked_selection].start;
+ framepos_t end = selection->time[clicked_selection].end;
boost::shared_ptr<Playlist> playlist;
return;
}
- nframes64_t selection_length = end - start;
+ framepos_t selection_length = end - start;
float times = (float)selection_length / region->length();
- begin_reversible_command (_("fill selection"));
+ begin_reversible_command (Operations::fill_selection);
for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
continue;
}
- playlist->clear_history ();
- playlist->add_region (RegionFactory::create (region), start, times);
+ playlist->clear_changes ();
+ playlist->add_region (RegionFactory::create (region, true), start, times);
_session->add_command (new StatefulDiffCommand (playlist));
}
}
void
-Editor::set_region_sync_from_edit_point ()
+Editor::set_region_sync_position ()
{
- nframes64_t where = get_preferred_edit_position ();
- RegionSelection rs;
- get_regions_for_action (rs);
- set_sync_point (where, rs);
+ set_sync_point (get_preferred_edit_position (), get_regions_from_selection_and_edit_point ());
}
void
-Editor::set_sync_point (nframes64_t where, const RegionSelection& rs)
+Editor::set_sync_point (framepos_t where, const RegionSelection& rs)
{
bool in_command = false;
in_command = true;
}
- region->clear_history ();
+ region->clear_changes ();
region->set_sync_position (where);
_session->add_command(new StatefulDiffCommand (region));
}
void
Editor::remove_region_sync ()
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
}
- begin_reversible_command (_("remove sync"));
+ begin_reversible_command (_("remove region sync"));
+
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
- (*i)->region()->clear_history ();
+ (*i)->region()->clear_changes ();
(*i)->region()->clear_sync_position ();
_session->add_command(new StatefulDiffCommand ((*i)->region()));
}
+
commit_reversible_command ();
}
void
-Editor::naturalize ()
+Editor::naturalize_region ()
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
}
- begin_reversible_command (_("naturalize"));
+ if (rs.size() > 1) {
+ begin_reversible_command (_("move regions to original position"));
+ } else {
+ begin_reversible_command (_("move region to original position"));
+ }
+
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
- (*i)->region()->clear_history ();
- (*i)->region()->move_to_natural_position (this);
+ (*i)->region()->clear_changes ();
+ (*i)->region()->move_to_natural_position ();
_session->add_command (new StatefulDiffCommand ((*i)->region()));
}
+
commit_reversible_command ();
}
void
-Editor::align (RegionPoint what)
+Editor::align_regions (RegionPoint what)
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
- nframes64_t where = get_preferred_edit_position();
-
- if (!rs.empty()) {
- align_selection (what, where, rs);
- } else {
+ RegionSelection const rs = get_regions_from_selection_and_edit_point ();
- RegionSelection rs;
- get_regions_at (rs, where, selection->tracks);
- align_selection (what, where, rs);
+ if (rs.empty()) {
+ return;
}
-}
-void
-Editor::align_relative (RegionPoint what)
-{
- nframes64_t where = get_preferred_edit_position();
- RegionSelection rs;
+ begin_reversible_command (_("align selection"));
- get_regions_for_action (rs);
+ framepos_t const position = get_preferred_edit_position ();
- if (!rs.empty()) {
- align_selection_relative (what, where, rs);
+ for (RegionSelection::const_iterator i = rs.begin(); i != rs.end(); ++i) {
+ align_region_internal ((*i)->region(), what, position);
}
+
+ commit_reversible_command ();
}
struct RegionSortByTime {
};
void
-Editor::align_selection_relative (RegionPoint point, nframes64_t position, const RegionSelection& rs)
+Editor::align_regions_relative (RegionPoint point)
{
+ RegionSelection const rs = get_regions_from_selection_and_edit_point ();
+
if (rs.empty()) {
return;
}
- nframes64_t distance = 0;
- nframes64_t pos = 0;
+ framepos_t const position = get_preferred_edit_position ();
+
+ framepos_t distance = 0;
+ framepos_t pos = 0;
int dir = 1;
list<RegionView*> sorted;
/* move first one specially */
- r->clear_history ();
- r->set_position (pos, this);
+ r->clear_changes ();
+ r->set_position (pos);
_session->add_command(new StatefulDiffCommand (r));
/* move rest by the same amount */
boost::shared_ptr<Region> region ((*i)->region());
- region->clear_history ();
+ region->clear_changes ();
if (dir > 0) {
- region->set_position (region->position() + distance, this);
+ region->set_position (region->position() + distance);
} else {
- region->set_position (region->position() - distance, this);
+ region->set_position (region->position() - distance);
}
-
- _session->add_command(new StatefulDiffCommand (region));
-
- }
-
- commit_reversible_command ();
-}
-
-void
-Editor::align_selection (RegionPoint point, nframes64_t position, const RegionSelection& rs)
-{
- if (rs.empty()) {
- return;
- }
- begin_reversible_command (_("align selection"));
+ _session->add_command(new StatefulDiffCommand (region));
- for (RegionSelection::const_iterator i = rs.begin(); i != rs.end(); ++i) {
- align_region_internal ((*i)->region(), point, position);
}
commit_reversible_command ();
}
void
-Editor::align_region (boost::shared_ptr<Region> region, RegionPoint point, nframes64_t position)
+Editor::align_region (boost::shared_ptr<Region> region, RegionPoint point, framepos_t position)
{
begin_reversible_command (_("align region"));
align_region_internal (region, point, position);
}
void
-Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint point, nframes64_t position)
+Editor::align_region_internal (boost::shared_ptr<Region> region, RegionPoint point, framepos_t position)
{
- region->clear_history ();
+ region->clear_changes ();
switch (point) {
case SyncPoint:
- region->set_position (region->adjust_to_sync (position), this);
+ region->set_position (region->adjust_to_sync (position));
break;
case End:
if (position > region->length()) {
- region->set_position (position - region->length(), this);
+ region->set_position (position - region->length());
}
break;
case Start:
- region->set_position (position, this);
+ region->set_position (position);
break;
}
void
Editor::trim_region (bool front)
{
- nframes64_t where = get_preferred_edit_position();
- RegionSelection rs;
+ framepos_t where = get_preferred_edit_position();
+ RegionSelection rs = get_regions_from_selection_and_edit_point ();
- get_regions_for_action (rs);
+ cerr << "trim regions\n";
if (rs.empty()) {
+ cerr << " no regions\n";
return;
}
+ cerr << "where = " << where << endl;
+
begin_reversible_command (front ? _("trim front") : _("trim back"));
for (list<RegionView*>::const_iterator i = rs.by_layer().begin(); i != rs.by_layer().end(); ++i) {
if (!(*i)->region()->locked()) {
- (*i)->region()->clear_history ();
+
+ (*i)->region()->clear_changes ();
+
if (front) {
- (*i)->region()->trim_front (where, this);
+ (*i)->region()->trim_front (where);
} else {
- (*i)->region()->trim_end (where, this);
+ (*i)->region()->trim_end (where);
}
+
_session->add_command (new StatefulDiffCommand ((*i)->region()));
}
}
}
trim_region_to_location (*loc, _("trim to punch"));
}
+
void
Editor::trim_region_to_location (const Location& loc, const char* str)
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
begin_reversible_command (str);
}
float speed = 1.0;
- nframes64_t start;
- nframes64_t end;
+ framepos_t start;
+ framepos_t end;
if (tav->track() != 0) {
speed = tav->track()->speed();
start = session_frame_to_track_frame (loc.start(), speed);
end = session_frame_to_track_frame (loc.end(), speed);
-
- rv->region()->clear_history ();
- rv->region()->trim_to (start, (end - start), this);
- _session->add_command(new StatefulDiffCommand (rv->region()));
- }
-
- commit_reversible_command ();
-}
-
-void
-Editor::trim_region_to_edit_point ()
-{
- RegionSelection rs;
-
- get_regions_for_action (rs);
-
- nframes64_t where = get_preferred_edit_position();
-
- begin_reversible_command (_("trim region start to edit point"));
-
- for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
- RegionView* rv = (*x);
-
- /* require region to cover trim */
- if (!rv->region()->covers (where)) {
- continue;
- }
-
- RouteTimeAxisView* tav = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view());
- if (!tav) {
- return;
- }
-
- float speed = 1.0;
-
- if (tav->track() != 0) {
- speed = tav->track()->speed();
- }
-
- rv->region()->clear_history ();
- rv->region()->trim_end (session_frame_to_track_frame(where, speed), this);
- _session->add_command(new StatefulDiffCommand (rv->region()));
- }
-
- commit_reversible_command ();
-}
-
-void
-Editor::trim_region_from_edit_point ()
-{
- RegionSelection rs;
-
- get_regions_for_action (rs);
-
- nframes64_t where = get_preferred_edit_position();
-
- begin_reversible_command (_("trim region end to edit point"));
-
- for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
- RegionView* rv = (*x);
-
- /* require region to cover trim */
- if (!rv->region()->covers (where)) {
- continue;
- }
- RouteTimeAxisView* tav = dynamic_cast<RouteTimeAxisView*> (&rv->get_time_axis_view());
- if (!tav) {
- return;
- }
-
- float speed = 1.0;
-
- if (tav->track() != 0) {
- speed = tav->track()->speed();
- }
-
- rv->region()->clear_history ();
- rv->region()->trim_front (session_frame_to_track_frame(where, speed), this);
+ rv->region()->clear_changes ();
+ rv->region()->trim_to (start, (end - start));
_session->add_command(new StatefulDiffCommand (rv->region()));
}
void
Editor::trim_to_region(bool forward)
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
begin_reversible_command (_("trim to region"));
boost::shared_ptr<Region> region = arv->region();
boost::shared_ptr<Playlist> playlist (region->playlist());
- region->clear_history ();
+ region->clear_changes ();
- if(forward){
+ if (forward) {
next_region = playlist->find_next_region (region->first_frame(), Start, 1);
- if(!next_region){
+ if (!next_region) {
continue;
}
- region->trim_end((nframes64_t) (next_region->first_frame() * speed), this);
+ region->trim_end((framepos_t) ( (next_region->first_frame() - 1) * speed));
arv->region_changed (PropertyChange (ARDOUR::Properties::length));
}
else {
continue;
}
- region->trim_front((nframes64_t) ((next_region->last_frame() + 1) * speed), this);
+ region->trim_front((framepos_t) ((next_region->last_frame() + 1) * speed));
arv->region_changed (ARDOUR::bounds_change);
}
return;
}
+ if (!clicked_routeview->track()->bounceable()) {
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (clicked_routeview);
+ if (rtv && !rtv->track()->bounceable()) {
+ MessageDialog d (
+ _("This route cannot be frozen because it has more outputs than inputs. "
+ "You can fix this by increasing the number of inputs.")
+ );
+ d.set_title (_("Cannot freeze"));
+ d.run ();
+ return;
+ }
+ }
+
InterThreadInfo itt;
current_interthread_info = &itt;
pthread_create_and_store (X_("freezer"), &itt.thread, _freeze_thread, this);
- track_canvas->get_window()->set_cursor (Gdk::Cursor (Gdk::WATCH));
+ set_canvas_cursor (_cursors->wait);
while (!itt.done && !itt.cancel) {
gtk_main_iteration ();
}
current_interthread_info = 0;
- track_canvas->get_window()->set_cursor (*current_canvas_cursor);
+ set_canvas_cursor (current_canvas_cursor);
}
void
TrackSelection views = selection->tracks;
- nframes64_t start = selection->time[clicked_selection].start;
- nframes64_t end = selection->time[clicked_selection].end;
- nframes64_t cnt = end - start + 1;
+ for (TrackViewList::iterator i = views.begin(); i != views.end(); ++i) {
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*i);
+ if (rtv && rtv->track() && replace && enable_processing && !rtv->track()->bounceable()) {
+ MessageDialog d (
+ _("You can't perform this operation because the processing of the signal "
+ "will cause one or more of the tracks will end up with a region with more channels than this track has inputs.\n\n"
+ "You can do this without processing, which is a different operation.")
+ );
+ d.set_title (_("Cannot bounce"));
+ d.run ();
+ return;
+ }
+ }
+
+ framepos_t start = selection->time[clicked_selection].start;
+ framepos_t end = selection->time[clicked_selection].end;
+ framepos_t cnt = end - start + 1;
begin_reversible_command (_("bounce range"));
InterThreadInfo itt;
- playlist->clear_history ();
+ playlist->clear_changes ();
+ playlist->clear_owned_changes ();
+
boost::shared_ptr<Region> r = rtv->track()->bounce_range (start, start+cnt, itt, enable_processing);
if (replace) {
playlist->add_region (r, start);
}
+ vector<Command*> cmds;
+ playlist->rdiff (cmds);
+ _session->add_commands (cmds);
+
_session->add_command (new StatefulDiffCommand (playlist));
}
commit_reversible_command ();
}
+/** Delete selected regions, automation points or a time range */
+void
+Editor::delete_ ()
+{
+ cut_copy (Delete);
+}
+
/** Cut selected regions, automation points or a time range */
void
Editor::cut ()
string opname;
switch (op) {
+ case Delete:
+ opname = _("delete");
+ break;
case Cut:
opname = _("cut");
break;
this function.
*/
- if (op == Cut || op == Clear) {
+ if (op == Delete || op == Cut || op == Clear) {
if (_drags->active ()) {
_drags->abort ();
}
/* we only want to cut regions if some are selected */
if (!selection->regions.empty()) {
- get_regions_for_action (rs, false, false);
+ rs = selection->regions;
}
switch (current_mouse_mode()) {
if (!rs.empty()) {
cut_copy_regions (op, rs);
- if (op == Cut) {
+ if (op == Cut || op == Delete) {
selection->clear_regions ();
}
}
if (!selection->points.empty()) {
cut_copy_points (op);
- if (op == Cut) {
+ if (op == Cut || op == Delete) {
selection->clear_points ();
}
}
case MouseRange:
if (selection->time.empty()) {
- nframes64_t start, end;
+ framepos_t start, end;
if (!get_edit_op_range (start, end)) {
return;
}
cut_copy_ranges (op);
commit_reversible_command ();
- if (op == Cut) {
+ if (op == Cut || op == Delete) {
selection->clear_time ();
}
}
}
- if (op == Cut || op == Clear) {
+ if (op == Delete || op == Cut || op == Clear) {
_drags->abort ();
}
}
for (PointSelection::iterator i = selection->points.begin(); i != selection->points.end(); ++i) {
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*>((*i).track);
+ _last_cut_copy_source_track = atv;
if (atv) {
atv->cut_copy_clear_objects (selection->points, op);
}
}
+
+
+struct lt_playlist {
+ bool operator () (const PlaylistState& a, const PlaylistState& b) {
+ return a.playlist < b.playlist;
+ }
+};
+
struct PlaylistMapping {
TimeAxisView* tv;
boost::shared_ptr<Playlist> pl;
boost::shared_ptr<Playlist> playlist = clicked_routeview->playlist();
begin_reversible_command (_("remove region"));
- playlist->clear_history ();
+ playlist->clear_changes ();
playlist->remove_region (clicked_regionview->region());
_session->add_command(new StatefulDiffCommand (playlist));
commit_reversible_command ();
void
Editor::remove_selected_regions ()
{
- RegionSelection rs;
- get_regions_for_action (rs);
-
- if (!_session) {
- return;
- }
+ RegionSelection rs = get_regions_from_selection_and_entered ();
- if (rs.empty()) {
+ if (!_session || rs.empty()) {
return;
}
regions_to_remove.push_back ((*i)->region());
}
- vector<boost::shared_ptr<Playlist> > playlists;
+ vector<boost::shared_ptr<Playlist> > playlists;
for (list<boost::shared_ptr<Region> >::iterator rl = regions_to_remove.begin(); rl != regions_to_remove.end(); ++rl) {
if (i == playlists.end()) {
- playlist->clear_history ();
+ playlist->clear_changes ();
playlist->freeze ();
playlists.push_back (playlist);
vector<PlaylistMapping> pmap;
- nframes64_t first_position = max_frames;
+ framepos_t first_position = max_framepos;
typedef set<boost::shared_ptr<Playlist> > FreezeList;
- FreezeList freezelist;
+ FreezeList freezelist;
/* get ordering correct before we cut/copy */
for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
- first_position = min ((nframes64_t) (*x)->region()->position(), first_position);
+ first_position = min ((framepos_t) (*x)->region()->position(), first_position);
- if (op == Cut || op == Clear) {
+ if (op == Cut || op == Clear || op == Delete) {
boost::shared_ptr<Playlist> pl = (*x)->region()->playlist();
if (pl) {
FreezeList::iterator fl;
- //only take state if this is a new playlist.
+ // only take state if this is a new playlist.
for (fl = freezelist.begin(); fl != freezelist.end(); ++fl) {
if ((*fl) == pl) {
break;
}
if (fl == freezelist.end()) {
- pl->clear_history();
+ pl->clear_changes();
pl->freeze ();
freezelist.insert (pl);
}
}
}
- TimeAxisView* tv = &(*x)->get_trackview();
+ TimeAxisView* tv = &(*x)->get_time_axis_view();
vector<PlaylistMapping>::iterator z;
for (z = pmap.begin(); z != pmap.end(); ++z) {
boost::shared_ptr<Playlist> pl = (*x)->region()->playlist();
if (!pl) {
- /* impossible, but this handles it for the future */
+ /* region not yet associated with a playlist (e.g. unfinished
+ capture pass.
+ */
+ ++x;
continue;
}
- TimeAxisView& tv = (*x)->get_trackview();
+ TimeAxisView& tv = (*x)->get_time_axis_view();
boost::shared_ptr<Playlist> npl;
RegionSelection::iterator tmp;
tmp = x;
++tmp;
- vector<PlaylistMapping>::iterator z;
+ if (op != Delete) {
- for (z = pmap.begin(); z != pmap.end(); ++z) {
- if ((*z).tv == &tv) {
- break;
+ vector<PlaylistMapping>::iterator z;
+
+ for (z = pmap.begin(); z != pmap.end(); ++z) {
+ if ((*z).tv == &tv) {
+ break;
+ }
+ }
+
+ assert (z != pmap.end());
+
+ if (!(*z).pl) {
+ npl = PlaylistFactory::create (pl->data_type(), *_session, "cutlist", true);
+ npl->freeze();
+ (*z).pl = npl;
+ } else {
+ npl = (*z).pl;
}
- }
-
- assert (z != pmap.end());
-
- if (!(*z).pl) {
- npl = PlaylistFactory::create (pl->data_type(), *_session, "cutlist", true);
- npl->freeze();
- (*z).pl = npl;
- } else {
- npl = (*z).pl;
}
boost::shared_ptr<Region> r = (*x)->region();
assert (r != 0);
switch (op) {
+ case Delete:
+ pl->remove_region (r);
+ break;
+
case Cut:
_xx = RegionFactory::create (r);
npl->add_region (_xx, r->position() - first_position);
case Copy:
/* copy region before adding, so we're not putting same object into two different playlists */
npl->add_region (RegionFactory::create (r), r->position() - first_position);
- break;
-
- case Clear:
+ case Clear:
pl->remove_region (r);
break;
}
x = tmp;
}
- list<boost::shared_ptr<Playlist> > foo;
+ if (op != Delete) {
- /* the pmap is in the same order as the tracks in which selected regions occured */
-
- for (vector<PlaylistMapping>::iterator i = pmap.begin(); i != pmap.end(); ++i) {
- (*i).pl->thaw();
- foo.push_back ((*i).pl);
+ list<boost::shared_ptr<Playlist> > foo;
+
+ /* the pmap is in the same order as the tracks in which selected regions occured */
+
+ for (vector<PlaylistMapping>::iterator i = pmap.begin(); i != pmap.end(); ++i) {
+ if ((*i).pl) {
+ (*i).pl->thaw();
+ foo.push_back ((*i).pl);
+ }
+ }
+
+ if (!foo.empty()) {
+ cut_buffer->set (foo);
+ }
+
+ if (pmap.empty()) {
+ _last_cut_copy_source_track = 0;
+ } else {
+ _last_cut_copy_source_track = pmap.front().tv;
+ }
}
-
- if (!foo.empty()) {
- cut_buffer->set (foo);
- }
-
for (FreezeList::iterator pl = freezelist.begin(); pl != freezelist.end(); ++pl) {
(*pl)->thaw ();
_session->add_command (new StatefulDiffCommand (*pl));
TrackViewList* ts;
TrackViewList entered;
+ /* Sort the track selection now, so that it if is used, the playlists
+ selected by the calls below to cut_copy_clear are in the order that
+ their tracks appear in the editor. This makes things like paste
+ of ranges work properly.
+ */
+ sort_track_selection (&selection->tracks);
+
if (selection->tracks.empty()) {
if (!entered_track) {
return;
void
Editor::paste (float times)
{
+ DEBUG_TRACE (DEBUG::CutNPaste, "paste to preferred edit pos\n");
paste_internal (get_preferred_edit_position(), times);
}
void
Editor::mouse_paste ()
{
- nframes64_t where;
+ framepos_t where;
bool ignored;
if (!mouse_frame (where, ignored)) {
}
void
-Editor::paste_internal (nframes64_t position, float times)
+Editor::paste_internal (framepos_t position, float times)
{
- bool commit = false;
+ DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("apparent paste position is %1\n", position));
if (internal_editing()) {
if (cut_buffer->midi_notes.empty()) {
}
}
- if (position == max_frames) {
+ if (position == max_framepos) {
position = get_preferred_edit_position();
+ DEBUG_TRACE (DEBUG::CutNPaste, string_compose ("preferred edit position is %1\n", position));
}
- begin_reversible_command (_("paste"));
-
TrackViewList ts;
TrackViewList::iterator i;
size_t nth;
/* get everything in the correct order */
if (!selection->tracks.empty()) {
+ /* there are some selected tracks, so paste to them */
sort_track_selection ();
ts = selection->tracks;
- } else if (entered_track) {
- ts.push_back (entered_track);
+ } else if (_last_cut_copy_source_track) {
+ /* otherwise paste to the track that the cut/copy came from;
+ see discussion in mantis #3333.
+ */
+ ts.push_back (_last_cut_copy_source_track);
}
- for (nth = 0, i = ts.begin(); i != ts.end(); ++i, ++nth) {
+ if (internal_editing ()) {
/* undo/redo is handled by individual tracks/regions */
- if (internal_editing()) {
+ for (nth = 0, i = ts.begin(); i != ts.end(); ++i, ++nth) {
RegionSelection rs;
RegionSelection::iterator r;
++cb;
}
}
+ }
- } else {
+ } else {
- if ((*i)->paste (position, times, *cut_buffer, nth)) {
- commit = true;
- }
+ /* we do redo (do you do voodoo?) */
+
+ begin_reversible_command (Operations::paste);
+
+ for (nth = 0, i = ts.begin(); i != ts.end(); ++i, ++nth) {
+ (*i)->paste (position, times, *cut_buffer, nth);
}
- }
- if (commit) {
commit_reversible_command ();
}
}
RegionSelection sel = regions; // clear (below) may clear the argument list if its the current region selection
RegionSelection foo;
- nframes_t const start_frame = regions.start ();
- nframes_t const end_frame = regions.end_frame ();
+ framepos_t const start_frame = regions.start ();
+ framepos_t const end_frame = regions.end_frame ();
- begin_reversible_command (_("duplicate region"));
+ begin_reversible_command (Operations::duplicate_region);
selection->clear_regions ();
sigc::connection c = rtv->view()->RegionViewAdded.connect (sigc::mem_fun(*this, &Editor::collect_new_region_view));
playlist = (*i)->region()->playlist();
- playlist->clear_history ();
- playlist->duplicate (r, end_frame + (r->first_frame() - start_frame) + 1, times);
+ playlist->clear_changes ();
+ playlist->duplicate (r, end_frame + (r->first_frame() - start_frame), times);
_session->add_command(new StatefulDiffCommand (playlist));
c.disconnect ();
if ((playlist = (*i)->playlist()) == 0) {
continue;
}
- playlist->clear_history ();
+ playlist->clear_changes ();
playlist->duplicate (*ri, selection->time[clicked_selection].end, times);
_session->add_command (new StatefulDiffCommand (playlist));
center_screen_internal (get_preferred_edit_position(), page);
}
+/** Caller must begin and commit a reversible command */
void
Editor::clear_playlist (boost::shared_ptr<Playlist> playlist)
{
- begin_reversible_command (_("clear playlist"));
- playlist->clear_history ();
+ playlist->clear_changes ();
playlist->clear ();
_session->add_command (new StatefulDiffCommand (playlist));
- commit_reversible_command ();
}
void
Editor::nudge_track (bool use_edit, bool forwards)
{
boost::shared_ptr<Playlist> playlist;
- nframes64_t distance;
- nframes64_t next_distance;
- nframes64_t start;
+ framepos_t distance;
+ framepos_t next_distance;
+ framepos_t start;
if (use_edit) {
start = get_preferred_edit_position();
continue;
}
- playlist->clear_history ();
- playlist->clear_owned_history ();
+ playlist->clear_changes ();
+ playlist->clear_owned_changes ();
playlist->nudge_after (start, distance, forwards);
-
- vector<StatefulDiffCommand*> cmds;
- playlist->rdiff (cmds);
+ vector<Command*> cmds;
- for (vector<StatefulDiffCommand*>::iterator c = cmds.begin(); c != cmds.end(); ++c) {
- _session->add_command (*c);
- }
+ playlist->rdiff (cmds);
+ _session->add_commands (cmds);
- _session->add_command (new StatefulDiffCommand (playlist));
+ _session->add_command (new StatefulDiffCommand (playlist));
}
commit_reversible_command ();
if (prompter.run () == 1) {
_session->remove_last_capture ();
+ _regions->redisplay ();
}
} else {
_session->remove_last_capture();
+ _regions->redisplay ();
}
}
return;
}
- RegionSelection rs;
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
}
- 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);
- spin.set_increments (0.1, 1);
- spin.set_value (0);
- hbox.pack_start (spin);
- 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);
+ NormalizeDialog dialog (rs.size() > 1);
if (dialog.run () == RESPONSE_CANCEL) {
return;
}
+ set_canvas_cursor (_cursors->wait);
+ gdk_flush ();
+
+ /* XXX: should really only count audio regions here */
+ int const regions = rs.size ();
+
+ /* Make a list of the selected audio regions' maximum amplitudes, and also
+ obtain the maximum amplitude of them all.
+ */
+ list<double> max_amps;
+ double max_amp = 0;
+ for (RegionSelection::const_iterator i = rs.begin(); i != rs.end(); ++i) {
+ AudioRegionView const * arv = dynamic_cast<AudioRegionView const *> (*i);
+ if (arv) {
+ dialog.descend (1.0 / regions);
+ double const a = arv->audio_region()->maximum_amplitude (&dialog);
+
+ if (a == -1) {
+ /* the user cancelled the operation */
+ set_canvas_cursor (current_canvas_cursor);
+ return;
+ }
+
+ max_amps.push_back (a);
+ max_amp = max (max_amp, a);
+ dialog.ascend ();
+ }
+ }
+
begin_reversible_command (_("normalize"));
- track_canvas->get_window()->set_cursor (*wait_cursor);
- gdk_flush ();
+ list<double>::const_iterator a = max_amps.begin ();
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
- AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
- if (!arv)
+ AudioRegionView* const arv = dynamic_cast<AudioRegionView*> (*r);
+ if (!arv) {
continue;
- arv->region()->clear_history ();
- arv->audio_region()->normalize_to (spin.get_value());
+ }
+
+ arv->region()->clear_changes ();
+
+ double const amp = dialog.normalize_individually() ? *a : max_amp;
+
+ arv->audio_region()->normalize (amp, dialog.target ());
_session->add_command (new StatefulDiffCommand (arv->region()));
-
+
+ ++a;
}
commit_reversible_command ();
- track_canvas->get_window()->set_cursor (*current_canvas_cursor);
-
- _last_normalization_value = spin.get_value ();
+ set_canvas_cursor (current_canvas_cursor);
}
return;
}
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
if (!arv)
continue;
- arv->region()->clear_history ();
+ arv->region()->clear_changes ();
arv->audio_region()->set_scale_amplitude (1.0f);
_session->add_command (new StatefulDiffCommand (arv->region()));
}
}
void
-Editor::adjust_region_scale_amplitude (bool up)
+Editor::adjust_region_gain (bool up)
{
- if (!_session) {
- return;
- }
-
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
- if (rs.empty()) {
+ if (!_session || rs.empty()) {
return;
}
- begin_reversible_command ("denormalize");
+ begin_reversible_command ("adjust region gain");
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*r);
if (!arv) {
continue;
- }
-
- arv->region()->clear_history ();
-
- double fraction = gain_to_slider_position (arv->audio_region()->scale_amplitude ());
-
- if (up) {
- fraction += 0.05;
- fraction = min (fraction, 1.0);
- } else {
- fraction -= 0.05;
- fraction = max (fraction, 0.0);
}
- if (!up && fraction <= 0) {
- continue;
- }
+ arv->region()->clear_changes ();
- fraction = slider_position_to_gain (fraction);
+ double dB = accurate_coefficient_to_dB (arv->audio_region()->scale_amplitude ());
- if (up && fraction >= 2.0) {
- continue;
+ if (up) {
+ dB += 1;
+ } else {
+ dB -= 1;
}
- arv->audio_region()->set_scale_amplitude (fraction);
+ arv->audio_region()->set_scale_amplitude (dB_to_coefficient (dB));
_session->add_command (new StatefulDiffCommand (arv->region()));
}
return;
}
- RegionSelection rs;
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
}
- std::list<boost::shared_ptr<AudioRegion> > ar;
+ std::list<RegionView*> audio_only;
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*> (*i);
if (arv) {
- ar.push_back (arv->audio_region ());
+ audio_only.push_back (arv);
}
}
- StripSilenceDialog d (_session, ar);
+ StripSilenceDialog d (_session, audio_only);
int const r = d.run ();
- if (r == Gtk::RESPONSE_OK) {
- StripSilence s (*_session, d.threshold (), d.minimum_length (), d.fade_length ());
- apply_filter (s, _("strip silence"));
+ d.drop_rects ();
+
+ if (r == Gtk::RESPONSE_OK) {
+ ARDOUR::AudioIntervalMap silences;
+ d.silences (silences);
+ StripSilence s (*_session, silences, d.fade_length());
+ apply_filter (s, _("strip silence"), &d);
}
}
Editor::apply_midi_note_edit_op_to_region (MidiOperator& op, MidiRegionView& mrv)
{
Evoral::Sequence<Evoral::MusicalTime>::Notes selected;
- mrv.selection_as_notelist (selected);
+ mrv.selection_as_notelist (selected, true);
vector<Evoral::Sequence<Evoral::MusicalTime>::Notes> v;
v.push_back (selected);
- return op (mrv.midi_region()->model(), v);
+ framepos_t pos_frames = mrv.midi_region()->position();
+ double 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)
{
- RegionSelection rs;
Command* cmd;
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
}
commit_reversible_command ();
- rs.clear ();
+}
+
+void
+Editor::fork_region ()
+{
+ RegionSelection rs = get_regions_from_selection_and_entered ();
+
+ if (rs.empty()) {
+ return;
+ }
+
+ begin_reversible_command (_("Fork Region(s)"));
+
+ set_canvas_cursor (_cursors->wait);
+ gdk_flush ();
+
+ for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) {
+ RegionSelection::iterator tmp = r;
+ ++tmp;
+
+ MidiRegionView* const mrv = dynamic_cast<MidiRegionView*>(*r);
+
+ if (mrv) {
+ boost::shared_ptr<Playlist> playlist = mrv->region()->playlist();
+ boost::shared_ptr<MidiRegion> newregion = mrv->midi_region()->clone ();
+
+ playlist->clear_changes ();
+ playlist->replace_region (mrv->region(), newregion, mrv->region()->position());
+ _session->add_command(new StatefulDiffCommand (playlist));
+ }
+
+ r = tmp;
+ }
+
+ 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<MidiRegionView*> (*r);
+ if (mrv) {
+ selected_midi_region_cnt++;
+ }
+ }
+
+ if (selected_midi_region_cnt == 0) {
+ return;
+ }
+
QuantizeDialog* qd = new QuantizeDialog (*this);
qd->present ();
}
void
-Editor::apply_filter (Filter& filter, string command)
+Editor::insert_patch_change ()
{
- RegionSelection rs;
+ RegionSelection rs = get_regions_from_selection_and_entered ();
+ if (rs.empty ()) {
+ return;
+ }
+
+ framepos_t const p = get_preferred_edit_position (false);
+
+ Evoral::PatchChange<Evoral::MusicalTime> empty (0, 0, 0, 0);
+ PatchChangeDialog d (0, _session, empty, Gtk::Stock::ADD);
+
+ if (d.run() == RESPONSE_CANCEL) {
+ return;
+ }
+
+ for (RegionSelection::iterator i = rs.begin (); i != rs.end(); ++i) {
+ MidiRegionView* const mrv = dynamic_cast<MidiRegionView*> (*i);
+ if (mrv) {
+ if (p >= mrv->region()->first_frame() && p <= mrv->region()->last_frame()) {
+ mrv->add_patch_change (p - mrv->region()->position(), d.patch ());
+ }
+ }
+ }
+}
- get_regions_for_action (rs);
+void
+Editor::apply_filter (Filter& filter, string command, ProgressReporter* progress)
+{
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
begin_reversible_command (command);
- track_canvas->get_window()->set_cursor (*wait_cursor);
+ set_canvas_cursor (_cursors->wait);
gdk_flush ();
+ int n = 0;
+ int const N = rs.size ();
+
for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ) {
RegionSelection::iterator tmp = r;
++tmp;
if (arv) {
boost::shared_ptr<Playlist> playlist = arv->region()->playlist();
- if (arv->audio_region()->apply (filter) == 0) {
+ if (progress) {
+ progress->descend (1.0 / N);
+ }
+
+ if (arv->audio_region()->apply (filter, progress) == 0) {
+
+ playlist->clear_changes ();
- playlist->clear_history ();
-
if (filter.results.empty ()) {
/* no regions returned; remove the old one */
} else {
goto out;
}
+
+ if (progress) {
+ progress->ascend ();
+ }
}
r = tmp;
+ ++n;
}
commit_reversible_command ();
- rs.clear ();
out:
- track_canvas->get_window()->set_cursor (*current_canvas_cursor);
-}
-
-void
-Editor::region_selection_op (void (Region::*pmf)(void))
-{
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
- Region* region = (*i)->region().get();
- (region->*pmf)();
- }
-}
-
-
-void
-Editor::region_selection_op (void (Region::*pmf)(void*), void *arg)
-{
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
- Region* region = (*i)->region().get();
- (region->*pmf)(arg);
- }
-}
-
-void
-Editor::region_selection_op (void (Region::*pmf)(bool), bool yn)
-{
- for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
- Region* region = (*i)->region().get();
- (region->*pmf)(yn);
- }
+ set_canvas_cursor (current_canvas_cursor);
}
void
/* more to come */
}
-void
-Editor::brush (nframes64_t pos)
-{
- RegionSelection sel;
- RegionSelection rs;
-
- get_regions_for_action (rs);
-
- snap_to (pos);
-
- if (rs.empty()) {
- return;
- }
-
- for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
- mouse_brush_insert_region ((*i), pos);
- }
-}
-
void
Editor::reset_region_gain_envelopes ()
{
- RegionSelection rs = get_equivalent_regions (selection->regions, ARDOUR::Properties::edit.property_id);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (!_session || rs.empty()) {
return;
void
Editor::toggle_gain_envelope_visibility ()
{
- RegionSelection rs = get_equivalent_regions (selection->regions, ARDOUR::Properties::edit.property_id);
+ if (_ignore_region_action) {
+ return;
+ }
+
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (!_session || rs.empty()) {
return;
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
if (arv) {
- arv->region()->clear_history ();
+ arv->region()->clear_changes ();
arv->set_envelope_visible (!arv->envelope_visible());
_session->add_command (new StatefulDiffCommand (arv->region()));
}
void
Editor::toggle_gain_envelope_active ()
{
- RegionSelection rs = get_equivalent_regions (selection->regions, ARDOUR::Properties::edit.property_id);
+ if (_ignore_region_action) {
+ return;
+ }
+
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (!_session || rs.empty()) {
return;
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
AudioRegionView* const arv = dynamic_cast<AudioRegionView*>(*i);
if (arv) {
- arv->region()->clear_history ();
+ arv->region()->clear_changes ();
arv->audio_region()->set_envelope_active (!arv->audio_region()->envelope_active());
_session->add_command (new StatefulDiffCommand (arv->region()));
}
void
Editor::toggle_region_lock ()
{
- RegionSelection rs = get_equivalent_regions (selection->regions, ARDOUR::Properties::edit.property_id);
+ if (_ignore_region_action) {
+ return;
+ }
+
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (!_session || rs.empty()) {
return;
}
- _session->begin_reversible_command (_("region lock"));
+ _session->begin_reversible_command (_("toggle region lock"));
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
- (*i)->region()->clear_history ();
+ (*i)->region()->clear_changes ();
(*i)->region()->set_locked (!(*i)->region()->locked());
_session->add_command (new StatefulDiffCommand ((*i)->region()));
}
void
Editor::toggle_region_lock_style ()
{
- RegionSelection rs = get_equivalent_regions (selection->regions, ARDOUR::Properties::edit.property_id);
+ if (_ignore_region_action) {
+ return;
+ }
+
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (!_session || rs.empty()) {
return;
_session->begin_reversible_command (_("region lock style"));
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
- (*i)->region()->clear_history ();
- Region::PositionLockStyle const ns = (*i)->region()->positional_lock_style() == Region::AudioTime ? Region::MusicTime : Region::AudioTime;
+ (*i)->region()->clear_changes ();
+ 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()));
}
_session->commit_reversible_command ();
}
-
void
-Editor::toggle_region_mute ()
+Editor::toggle_opaque_region ()
{
- RegionSelection rs = get_equivalent_regions (selection->regions, ARDOUR::Properties::edit.property_id);
-
- if (!_session || rs.empty()) {
+ if (_ignore_region_action) {
return;
}
- _session->begin_reversible_command (_("region mute"));
-
- for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
- (*i)->region()->clear_history ();
- (*i)->region()->set_muted (!(*i)->region()->muted());
- _session->add_command (new StatefulDiffCommand ((*i)->region()));
- }
-
- _session->commit_reversible_command ();
-}
-
-void
-Editor::toggle_region_opaque ()
-{
- RegionSelection rs = get_equivalent_regions (selection->regions, ARDOUR::Properties::edit.property_id);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (!_session || rs.empty()) {
return;
}
- _session->begin_reversible_command (_("region opacity"));
+ _session->begin_reversible_command (_("change region opacity"));
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
- (*i)->region()->clear_history ();
+ (*i)->region()->clear_changes ();
(*i)->region()->set_opaque (!(*i)->region()->opaque());
_session->add_command (new StatefulDiffCommand ((*i)->region()));
}
first = false;
}
- rtav->track()->set_record_enable(new_state, this);
+ rtav->track()->set_record_enabled (new_state, this);
}
}
void
Editor::set_fade_length (bool in)
{
- RegionSelection rs;
-
- get_regions_for_action (rs, true);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
RegionView* rv = rs.front ();
- nframes64_t pos = get_preferred_edit_position();
- nframes64_t len;
+ framepos_t pos = get_preferred_edit_position();
+ framepos_t len;
char const * cmd;
if (pos > rv->region()->last_frame() || pos < rv->region()->first_frame()) {
}
void
-Editor::toggle_fade_active (bool in)
-{
- RegionSelection rs;
-
- get_regions_for_action (rs);
-
- if (rs.empty()) {
- return;
- }
-
- const char* cmd = (in ? _("toggle fade in active") : _("toggle fade out active"));
- bool have_switch = false;
- bool yn = false;
-
- begin_reversible_command (cmd);
-
- for (RegionSelection::iterator x = rs.begin(); x != rs.end(); ++x) {
- AudioRegionView* tmp = dynamic_cast<AudioRegionView*> (*x);
-
- if (!tmp) {
- return;
- }
-
- boost::shared_ptr<AudioRegion> region (tmp->audio_region());
-
- /* make the behaviour consistent across all regions */
-
- if (!have_switch) {
- if (in) {
- yn = region->fade_in_active();
- } else {
- yn = region->fade_out_active();
- }
- have_switch = true;
- }
-
- region->clear_history ();
-
- if (in) {
- region->set_fade_in_active (!yn);
- } else {
- region->set_fade_out_active (!yn);
- }
-
- _session->add_command(new StatefulDiffCommand (region));
- }
-
- commit_reversible_command ();
-}
-
-void
-Editor::set_fade_in_shape (AudioRegion::FadeShape shape)
+Editor::set_fade_in_shape (FadeShape shape)
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
}
void
-Editor::set_fade_out_shape (AudioRegion::FadeShape shape)
+Editor::set_fade_out_shape (FadeShape shape)
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
void
Editor::set_fade_in_active (bool yn)
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
boost::shared_ptr<AudioRegion> ar (tmp->audio_region());
-
- ar->clear_history ();
+
+ ar->clear_changes ();
ar->set_fade_in_active (yn);
_session->add_command (new StatefulDiffCommand (ar));
}
void
Editor::set_fade_out_active (bool yn)
{
- RegionSelection rs;
-
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
boost::shared_ptr<AudioRegion> ar (tmp->audio_region());
- ar->clear_history ();
+ ar->clear_changes ();
ar->set_fade_out_active (yn);
_session->add_command(new StatefulDiffCommand (ar));
}
}
void
-Editor::toggle_selected_region_fades (int dir)
+Editor::toggle_region_fades (int dir)
{
- RegionSelection rs;
- RegionSelection::iterator i;
boost::shared_ptr<AudioRegion> ar;
bool yn;
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
}
+ RegionSelection::iterator i;
for (i = rs.begin(); i != rs.end(); ++i) {
if ((ar = boost::dynamic_pointer_cast<AudioRegion>((*i)->region())) != 0) {
if (dir == -1) {
void
Editor::set_edit_point ()
{
- nframes64_t where;
+ framepos_t where;
bool ignored;
if (!mouse_frame (where, ignored)) {
if (entered_marker) {
_session->request_locate (entered_marker->position(), _session->transport_rolling());
} else {
- nframes64_t where;
+ framepos_t where;
bool ignored;
if (!mouse_frame (where, ignored)) {
}
void
-Editor::split ()
+Editor::split_region ()
{
- RegionSelection rs;
-
- get_regions_for_action (rs, true);
+ if (((mouse_mode == MouseRange) ||
+ (mouse_mode != MouseObject && _join_object_range_state == JOIN_OBJECT_RANGE_RANGE)) &&
+ !selection->time.empty()) {
+ separate_regions_between (selection->time);
+ return;
+ }
- nframes64_t where = get_preferred_edit_position();
+ RegionSelection rs = get_regions_from_selection_and_edit_point ();
+
+ framepos_t where = get_preferred_edit_position ();
if (rs.empty()) {
return;
double const track_max_y = track->y_position () + track->effective_height ();
if (track_min_y >= current_view_min_y &&
- track_max_y <= current_view_max_y) {
+ track_max_y <= current_view_max_y) {
return;
}
return;
}
- nframes64_t start = selection->time[clicked_selection].start;
- nframes64_t end = selection->time[clicked_selection].end;
+ 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"));
return;
}
- nframes64_t start;
- nframes64_t end;
+ framepos_t start;
+ framepos_t end;
if (!get_edit_op_range (start, end)) {
return;
void
Editor::set_loop_from_region (bool play)
{
- nframes64_t start = max_frames;
- nframes64_t end = 0;
-
- RegionSelection rs;
+ framepos_t start = max_framepos;
+ framepos_t end = 0;
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
return;
}
- nframes64_t start = selection->time[clicked_selection].start;
- nframes64_t end = selection->time[clicked_selection].end;
+ framepos_t start = selection->time[clicked_selection].start;
+ framepos_t end = selection->time[clicked_selection].end;
set_punch_range (start, end, _("set punch range from selection"));
}
return;
}
- nframes64_t start;
- nframes64_t end;
+ framepos_t start;
+ framepos_t end;
if (!get_edit_op_range (start, end)) {
return;
void
Editor::set_punch_from_region ()
{
- nframes64_t start = max_frames;
- nframes64_t end = 0;
-
- RegionSelection rs;
+ framepos_t start = max_framepos;
+ framepos_t end = 0;
- get_regions_for_action (rs);
+ RegionSelection rs = get_regions_from_selection_and_entered ();
if (rs.empty()) {
return;
}
void
-Editor::pitch_shift_regions ()
+Editor::pitch_shift_region ()
{
- RegionSelection rs;
+ RegionSelection rs = get_regions_from_selection_and_entered ();
- get_regions_for_action (rs);
+ RegionSelection audio_rs;
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+ if (dynamic_cast<AudioRegionView*> (*i)) {
+ audio_rs.push_back (*i);
+ }
+ }
- if (rs.empty()) {
+ if (audio_rs.empty()) {
return;
}
- pitch_shift (rs, 1.2);
+ pitch_shift (audio_rs, 1.2);
}
void
-Editor::use_region_as_bar ()
+Editor::transpose_region ()
{
- if (!_session) {
+ RegionSelection rs = get_regions_from_selection_and_entered ();
+
+ list<MidiRegionView*> midi_region_views;
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+ MidiRegionView* mrv = dynamic_cast<MidiRegionView*> (*i);
+ if (mrv) {
+ midi_region_views.push_back (mrv);
+ }
+ }
+
+ TransposeDialog d;
+ int const r = d.run ();
+ if (r != RESPONSE_ACCEPT) {
return;
}
- RegionSelection rs;
+ for (list<MidiRegionView*>::iterator i = midi_region_views.begin(); i != midi_region_views.end(); ++i) {
+ (*i)->midi_region()->transpose (d.semitones ());
+ }
+}
- get_regions_for_action (rs);
+void
+Editor::set_tempo_from_region ()
+{
+ RegionSelection rs = get_regions_from_selection_and_entered ();
- if (rs.empty()) {
+ if (!_session || rs.empty()) {
return;
}
void
Editor::use_range_as_bar ()
{
- nframes64_t start, end;
+ framepos_t start, end;
if (get_edit_op_range (start, end)) {
define_one_bar (start, end);
}
}
void
-Editor::define_one_bar (nframes64_t start, nframes64_t end)
+Editor::define_one_bar (framepos_t start, framepos_t end)
{
- nframes64_t length = end - start;
+ framepos_t length = end - start;
const Meter& m (_session->tempo_map().meter_at (start));
_("Do you want to set the global tempo or add a new tempo marker?"),
options
);
-
+
c.set_default_response (2);
switch (c.run()) {
{
AnalysisFeatureList positions;
- if (!_session) {
- return;
- }
+ RegionSelection rs = get_regions_from_selection_and_entered ();
- RegionSelection rs;
-
- get_regions_for_action (rs);
-
- if (rs.empty()) {
+ if (!_session || rs.empty()) {
return;
}
}
void
-Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList& positions, bool can_ferret)
+Editor::split_region_at_points (boost::shared_ptr<Region> r, AnalysisFeatureList& positions, bool can_ferret, bool select_new)
{
bool use_rhythmic_rodent = false;
boost::shared_ptr<Playlist> pl = r->playlist();
+ list<boost::shared_ptr<Region> > new_regions;
+
if (!pl) {
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);
+ if (positions.size() > 20 && can_ferret) {
+ std::string 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,
int response = msg.run();
msg.hide ();
+
switch (response) {
case RESPONSE_OK:
break;
AnalysisFeatureList::const_iterator x;
- nframes64_t pos = r->position();
-
- pl->clear_history ();
+ pl->clear_changes ();
x = positions.begin();
- while (x != positions.end()) {
- if ((*x) > pos) {
- break;
- }
- ++x;
- }
-
if (x == positions.end()) {
return;
}
pl->freeze ();
pl->remove_region (r);
+ framepos_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());
+ framepos_t file_start = r->start() + pos;
/* length = next position - current position
*/
- nframes64_t len = (*x) - pos;
+ framepos_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?
/* do NOT announce new regions 1 by one, just wait till they are all done */
- PropertyList plist;
-
+ PropertyList plist;
+
plist.add (ARDOUR::Properties::start, file_start);
plist.add (ARDOUR::Properties::length, len);
plist.add (ARDOUR::Properties::name, new_name);
plist.add (ARDOUR::Properties::layer, 0);
boost::shared_ptr<Region> nr = RegionFactory::create (r->sources(), plist, false);
- pl->add_region (nr, pos);
+
+ pl->add_region (nr, r->position() + pos);
+
+ if (select_new) {
+ new_regions.push_front(nr);
+ }
pos += len;
++x;
+ }
- if (*x > r->last_frame()) {
+ string new_name;
- /* add final fragment */
+ RegionFactory::region_name (new_name, r->name());
- file_start = r->start() + (pos - r->position());
- len = r->last_frame() - pos;
+ /* Add the final region */
+ PropertyList plist;
- 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);
+ 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);
- nr = RegionFactory::create (r->sources(), plist2);
- pl->add_region (nr, pos);
+ boost::shared_ptr<Region> nr = RegionFactory::create (r->sources(), plist, false);
+ pl->add_region (nr, r->position() + pos);
- break;
- }
+ if (select_new) {
+ new_regions.push_front(nr);
}
pl->thaw ();
_session->add_command (new StatefulDiffCommand (pl));
+
+ if (select_new) {
+
+ for (list<boost::shared_ptr<Region> >::iterator i = new_regions.begin(); i != new_regions.end(); ++i){
+ set_selected_regionview_from_region_list ((*i), Selection::Add);
+ }
+ }
+}
+
+void
+Editor::place_transient()
+{
+ if (!_session) {
+ return;
+ }
+
+ RegionSelection rs = get_regions_from_selection_and_edit_point ();
+
+ if (rs.empty()) {
+ return;
+ }
+
+ framepos_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::Line* _line = reinterpret_cast<ArdourCanvas::Line*> (item);
+ assert (_line);
+
+ AudioRegionView* _arv = reinterpret_cast<AudioRegionView*> (item->get_data ("regionview"));
+ _arv->remove_transient (*(float*) _line->get_data ("position"));
+}
+
+void
+Editor::snap_regions_to_grid ()
+{
+ list <boost::shared_ptr<Playlist > > used_playlists;
+
+ RegionSelection rs = get_regions_from_selection_and_entered ();
+
+ if (!_session || rs.empty()) {
+ return;
+ }
+
+ _session->begin_reversible_command (_("snap regions to grid"));
+
+ for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
+
+ boost::shared_ptr<Playlist> pl = (*r)->region()->playlist();
+
+ if (!pl->frozen()) {
+ /* we haven't seen this playlist before */
+
+ /* remember used playlists so we can thaw them later */
+ used_playlists.push_back(pl);
+ pl->freeze();
+ }
+
+ framepos_t start_frame = (*r)->region()->first_frame ();
+ snap_to (start_frame);
+ (*r)->region()->set_position (start_frame);
+ }
+
+ while (used_playlists.size() > 0) {
+ list <boost::shared_ptr<Playlist > >::iterator i = used_playlists.begin();
+ (*i)->thaw();
+ used_playlists.pop_front();
+ }
+
+ _session->commit_reversible_command ();
+}
+
+void
+Editor::close_region_gaps ()
+{
+ list <boost::shared_ptr<Playlist > > used_playlists;
+
+ RegionSelection rs = get_regions_from_selection_and_entered ();
+
+ if (!_session || rs.empty()) {
+ return;
+ }
+
+ Dialog dialog (_("Close Region Gaps"));
+
+ Table table (2, 3);
+ table.set_spacings (12);
+ table.set_border_width (12);
+ Label* l = manage (new Label (_("Crossfade length")));
+ l->set_alignment (0, 0.5);
+ table.attach (*l, 0, 1, 0, 1);
+
+ SpinButton spin_crossfade (1, 0);
+ spin_crossfade.set_range (0, 15);
+ spin_crossfade.set_increments (1, 1);
+ spin_crossfade.set_value (5);
+ table.attach (spin_crossfade, 1, 2, 0, 1);
+
+ table.attach (*manage (new Label (_("ms"))), 2, 3, 0, 1);
+
+ l = manage (new Label (_("Pull-back length")));
+ l->set_alignment (0, 0.5);
+ table.attach (*l, 0, 1, 1, 2);
+
+ SpinButton spin_pullback (1, 0);
+ spin_pullback.set_range (0, 100);
+ spin_pullback.set_increments (1, 1);
+ spin_pullback.set_value(30);
+ table.attach (spin_pullback, 1, 2, 1, 2);
+
+ table.attach (*manage (new Label (_("ms"))), 2, 3, 1, 2);
+
+ dialog.get_vbox()->pack_start (table);
+ dialog.add_button (Stock::CANCEL, RESPONSE_CANCEL);
+ dialog.add_button (_("Ok"), RESPONSE_ACCEPT);
+ dialog.show_all ();
+
+ if (dialog.run () == RESPONSE_CANCEL) {
+ return;
+ }
+
+ framepos_t crossfade_len = spin_crossfade.get_value();
+ framepos_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<Region> last_region;
+
+ rs.sort_by_position_and_track();
+
+ for (RegionSelection::iterator r = rs.begin(); r != rs.end(); ++r) {
+
+ boost::shared_ptr<Playlist> pl = (*r)->region()->playlist();
+
+ if (!pl->frozen()) {
+ /* we haven't seen this playlist before */
+
+ /* remember used playlists so we can thaw them later */
+ used_playlists.push_back(pl);
+ pl->freeze();
+ }
+
+ framepos_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));
+ last_region->trim_end( (position - pull_back_frames + crossfade_len));
+
+ last_region = (*r)->region();
+
+ idx++;
+ }
+
+ while (used_playlists.size() > 0) {
+ list <boost::shared_ptr<Playlist > >::iterator i = used_playlists.begin();
+ (*i)->thaw();
+ used_playlists.pop_front();
+ }
+
+ _session->commit_reversible_command ();
}
void
{
AnalysisFeatureList positions;
+ RegionSelection rs = get_regions_from_selection_and_entered ();
+
if (!_session) {
return;
}
- nframes64_t pos = _session->audible_frame ();
+ framepos_t pos = _session->audible_frame ();
if (!selection->tracks.empty()) {
if (tr) {
boost::shared_ptr<Playlist> pl = tr->playlist ();
if (pl) {
- nframes64_t result = pl->find_next_transient (pos, forward ? 1 : -1);
+ framepos_t result = pl->find_next_transient (pos, forward ? 1 : -1);
if (result >= 0) {
positions.push_back (result);
} else {
- RegionSelection rs;
-
- get_regions_for_action (rs);
-
if (rs.empty()) {
return;
}
}
}
}
+
void
Editor::playhead_forward_to_grid ()
{
if (!_session) return;
- nframes64_t pos = playhead_cursor->current_frame;
- if (pos < max_frames - 1) {
+ framepos_t pos = playhead_cursor->current_frame;
+ if (pos < max_framepos - 1) {
pos += 2;
snap_to_internal (pos, 1, false);
_session->request_locate (pos);
Editor::playhead_backward_to_grid ()
{
if (!_session) return;
- nframes64_t pos = playhead_cursor->current_frame;
+ framepos_t pos = playhead_cursor->current_frame;
if (pos > 2) {
pos -= 2;
snap_to_internal (pos, -1, false);
}
void
-Editor::set_track_height (uint32_t h)
+Editor::set_track_height (Height h)
{
TrackSelection& ts (selection->tracks);
for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) {
- (*x)->set_height (h);
+ (*x)->set_height_enum (h);
}
}
target = !rtv->_route->active();
first = false;
}
- rtv->_route->set_active (target);
+ rtv->_route->set_active (target, this);
}
}
}
const char* trackstr;
const char* busstr;
vector<boost::shared_ptr<Route> > routes;
+ bool special_bus = false;
for (TrackSelection::iterator x = ts.begin(); x != ts.end(); ++x) {
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (*x);
}
}
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;
+ return;
}
if (ntracks > 1) {
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!"),
+ "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!"),
+ "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?"),
+ prompt = string_compose (_("Do you really want to remove %1 %2?\n\n"
+ "This action cannot be undon, and the session file will be overwritten"),
nbusses, busstr);
}
return;
}
- ArdourDialog d (*this, _("Insert Time"));
-
- nframes64_t const pos = get_preferred_edit_position ();
-
- d.get_vbox()->set_border_width (12);
- d.get_vbox()->set_spacing (4);
-
- Table table (2, 2);
- table.set_spacings (4);
-
- Label time_label (_("Time to insert:"));
- time_label.set_alignment (1, 0.5);
- table.attach (time_label, 0, 1, 0, 1, FILL | EXPAND);
- AudioClock clock ("insertTimeClock", true, X_("InsertTimeClock"), true, false, true, true);
- clock.set (0);
- clock.set_session (_session);
- clock.set_bbt_reference (pos);
- table.attach (clock, 1, 2, 0, 1);
-
- Label intersected_label (_("Intersected regions should:"));
- intersected_label.set_alignment (1, 0.5);
- table.attach (intersected_label, 0, 1, 1, 2, FILL | EXPAND);
- ComboBoxText intersected_combo;
- intersected_combo.append_text (_("stay in position"));
- intersected_combo.append_text (_("move"));
- intersected_combo.append_text (_("be split"));
- intersected_combo.set_active (0);
- table.attach (intersected_combo, 1, 2, 1, 2);
-
- d.get_vbox()->pack_start (table);
-
- CheckButton move_glued (_("Move glued regions"));
- d.get_vbox()->pack_start (move_glued);
- CheckButton move_markers (_("Move markers"));
- d.get_vbox()->pack_start (move_markers);
- CheckButton move_tempos (_("Move tempo and meter changes"));
- d.get_vbox()->pack_start (move_tempos);
-
- d.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
- d.add_button (_("Insert time"), Gtk::RESPONSE_OK);
- d.show_all ();
-
+ InsertTimeDialog d (*this);
int response = d.run ();
if (response != RESPONSE_OK) {
return;
}
- nframes64_t distance = clock.current_duration (pos);
-
- if (distance == 0) {
+ if (d.distance() == 0) {
return;
}
- /* only setting this to keep GCC quiet */
- InsertTimeOption opt = LeaveIntersected;
-
- switch (intersected_combo.get_active_row_number ()) {
- case 0:
- opt = LeaveIntersected;
- break;
- case 1:
- opt = MoveIntersected;
- break;
- case 2:
- opt = SplitIntersected;
- break;
- }
+ InsertTimeOption opt = d.intersected_region_action ();
- insert_time (pos, distance, opt, move_glued.get_active(), move_markers.get_active(), move_tempos.get_active());
+ insert_time (
+ get_preferred_edit_position(),
+ d.distance(),
+ opt,
+ d.move_glued(),
+ d.move_markers(),
+ d.move_glued_markers(),
+ d.move_locked_markers(),
+ d.move_tempos()
+ );
}
void
-Editor::insert_time (nframes64_t pos, nframes64_t frames, InsertTimeOption opt,
- bool ignore_music_glue, bool markers_too, bool tempo_too)
+Editor::insert_time (framepos_t pos, framecnt_t frames, InsertTimeOption opt,
+ bool ignore_music_glue, bool markers_too, bool glued_markers_too, bool locked_markers_too, bool tempo_too)
{
bool commit = false;
if (pl) {
- pl->clear_history ();
- pl->clear_owned_history ();
+ pl->clear_changes ();
+ pl->clear_owned_changes ();
if (opt == SplitIntersected) {
pl->split (pos);
pl->shift (pos, frames, (opt == MoveIntersected), ignore_music_glue);
- vector<StatefulDiffCommand*> cmds;
-
- pl->rdiff (cmds);
-
- cerr << "Shift generated " << cmds.size() << " sdc's\n";
+ vector<Command*> cmds;
+ pl->rdiff (cmds);
+ _session->add_commands (cmds);
- for (vector<StatefulDiffCommand*>::iterator c = cmds.begin(); c != cmds.end(); ++c) {
- _session->add_command (*c);
- }
-
_session->add_command (new StatefulDiffCommand (pl));
commit = true;
}
Locations::LocationList::const_iterator tmp;
- if ((*i)->start() >= pos) {
- (*i)->set_start ((*i)->start() + frames);
- if (!(*i)->is_mark()) {
- (*i)->set_end ((*i)->end() + frames);
+ bool const was_locked = (*i)->locked ();
+ if (locked_markers_too) {
+ (*i)->unlock ();
+ }
+
+ if ((*i)->position_lock_style() == AudioTime || glued_markers_too) {
+
+ if ((*i)->start() >= pos) {
+ (*i)->set_start ((*i)->start() + frames);
+ if (!(*i)->is_mark()) {
+ (*i)->set_end ((*i)->end() + frames);
+ }
+ moved = true;
}
- moved = true;
+
+ }
+
+ if (was_locked) {
+ (*i)->lock ();
}
}
void
Editor::fit_selected_tracks ()
{
- fit_tracks (selection->tracks);
+ if (!selection->tracks.empty()) {
+ fit_tracks (selection->tracks);
+ } else {
+ TrackViewList tvl;
+
+ /* no selected tracks - use tracks with selected regions */
+
+ if (!selection->regions.empty()) {
+ for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) {
+ tvl.push_back (&(*r)->get_time_axis_view ());
+ }
+
+ if (!tvl.empty()) {
+ fit_tracks (tvl);
+ }
+ } else if (internal_editing()) {
+ /* no selected tracks, or regions, but in internal edit mode, so follow the mouse and use
+ the entered track
+ */
+ if (entered_track) {
+ tvl.push_back (entered_track);
+ fit_tracks (tvl);
+ }
+ }
+ }
}
void
}
uint32_t child_heights = 0;
+ int visible_tracks = 0;
for (TrackSelection::iterator t = tracks.begin(); t != tracks.end(); ++t) {
}
child_heights += (*t)->effective_height() - (*t)->current_height();
+ ++visible_tracks;
}
- uint32_t h = (uint32_t) floor ((_canvas_height - child_heights - canvas_timebars_vsize) / tracks.size());
+ uint32_t h = (uint32_t) floor ((_canvas_height - child_heights - canvas_timebars_vsize) / visible_tracks);
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;
undo_visual_stack.push_back (current_visual_state());
+ /* build a list of all tracks, including children */
+
+ TrackViewList all;
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) {
+ all.push_back (*i);
+ TimeAxisView::Children c = (*i)->get_child_list ();
+ for (TimeAxisView::Children::iterator j = c.begin(); j != c.end(); ++j) {
+ all.push_back (j->get());
+ }
+ }
+
/* operate on all tracks, hide unselected ones that are in the middle of selected ones */
bool prev_was_selected = false;
- bool is_selected = tracks.contains (track_views.front());
+ bool is_selected = tracks.contains (all.front());
bool next_is_selected;
- for (TrackViewList::iterator t = track_views.begin(); t != track_views.end(); ++t) {
+ for (TrackViewList::iterator t = all.begin(); t != all.end(); ++t) {
TrackViewList::iterator next;
next = t;
++next;
- if (next != track_views.end()) {
+ if (next != all.end()) {
next_is_selected = tracks.contains (*next);
} else {
next_is_selected = false;
}
- if (is_selected) {
- (*t)->set_height (h);
- first_y_pos = std::min ((*t)->y_position (), first_y_pos);
- } else {
- if (prev_was_selected && next_is_selected) {
- hide_track_in_display (**t);
+ if ((*t)->marked_for_display ()) {
+ if (is_selected) {
+ (*t)->set_height (h);
+ first_y_pos = std::min ((*t)->y_position (), first_y_pos);
+ } else {
+ if (prev_was_selected && next_is_selected) {
+ hide_track_in_display (*t);
+ }
}
}
return false; // do not call again
}
+void
+Editor::toggle_region_mute ()
+{
+ if (_ignore_region_action) {
+ return;
+ }
+
+ RegionSelection rs = get_regions_from_selection_and_entered ();
+
+ if (rs.empty ()) {
+ return;
+ }
+
+ if (rs.size() > 1) {
+ begin_reversible_command (_("mute regions"));
+ } else {
+ begin_reversible_command (_("mute region"));
+ }
+
+ for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
+
+ (*i)->region()->playlist()->clear_changes ();
+ (*i)->region()->set_muted (!(*i)->region()->muted ());
+ _session->add_command (new StatefulDiffCommand ((*i)->region()->playlist()));
+
+ }
+
+ commit_reversible_command ();
+}
+
+void
+Editor::combine_regions ()
+{
+ /* foreach track with selected regions, take all selected regions
+ and join them into a new region containing the subregions (as a
+ playlist)
+ */
+
+ typedef set<RouteTimeAxisView*> RTVS;
+ RTVS tracks;
+
+ if (selection->regions.empty()) {
+ return;
+ }
+
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&(*i)->get_time_axis_view());
+
+ if (rtv) {
+ tracks.insert (rtv);
+ }
+ }
+
+ begin_reversible_command (_("combine regions"));
+
+ vector<RegionView*> new_selection;
+
+ for (RTVS::iterator i = tracks.begin(); i != tracks.end(); ++i) {
+ RegionView* rv;
+
+ if ((rv = (*i)->combine_regions ()) != 0) {
+ new_selection.push_back (rv);
+ }
+ }
+
+ selection->clear_regions ();
+ for (vector<RegionView*>::iterator i = new_selection.begin(); i != new_selection.end(); ++i) {
+ selection->add (*i);
+ }
+
+ commit_reversible_command ();
+}
+
+void
+Editor::uncombine_regions ()
+{
+ typedef set<RouteTimeAxisView*> RTVS;
+ RTVS tracks;
+
+ if (selection->regions.empty()) {
+ return;
+ }
+
+ for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
+ RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*>(&(*i)->get_time_axis_view());
+
+ if (rtv) {
+ tracks.insert (rtv);
+ }
+ }
+
+ begin_reversible_command (_("uncombine regions"));
+
+ for (RTVS::iterator i = tracks.begin(); i != tracks.end(); ++i) {
+ (*i)->uncombine_regions ();
+ }
+
+ commit_reversible_command ();
+}
+