[Summary] When range sellection covers multiple regions all of them will be processed by range drag

This commit is contained in:
GZharun 2014-10-01 17:56:06 +03:00
parent a1d4529776
commit 048d03ecd8
5 changed files with 84 additions and 136 deletions

View file

@ -1195,8 +1195,8 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD
void keyboard_paste ();
void region_from_selection ();
void create_region_from_selection (std::vector<boost::shared_ptr<ARDOUR::Region> >&, RouteTimeAxisView*);
void cut_region_from_selection (std::vector<boost::shared_ptr<ARDOUR::Region> >&, RouteTimeAxisView*);
void create_region_from_selection (std::vector<boost::shared_ptr<ARDOUR::Region> >&);
void cut_copy_region_from_selection (RegionSelection& new_regions, RouteTimeAxisView* rtv, bool follow_track_selection = false, bool copy = false);
void play_from_start ();
void play_from_edit_point ();

View file

@ -2458,66 +2458,24 @@ Editor::add_region_brush_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView*
void
Editor::start_selection_grab (ArdourCanvas::Item* item, RouteTimeAxisView* rtv, GdkEvent* event, bool copy/*=false*/)
{
if (rtv == 0) {
return;
}
/* lets try to create new Region for the selection */
vector<boost::shared_ptr<Region> > new_regions;
begin_reversible_command (_("new region for selection drag"));
if (copy) {
create_region_from_selection (new_regions, rtv);
} else {
cut_region_from_selection (new_regions, rtv);
}
RegionSelection new_regions;
cut_copy_region_from_selection (new_regions, rtv, true, copy);
commit_reversible_command ();
if (new_regions.empty()) {
return;
}
/* XXX fix me one day to use all new regions */
boost::shared_ptr<Region> region (new_regions.front());
/* add it to the current stream/playlist.
tricky: the streamview for the track will add a new regionview. we will
catch the signal it sends when it creates the regionview to
set the regionview we want to then drag.
*/
latest_regionviews.clear();
sigc::connection c = rtv->view()->RegionViewAdded.connect (sigc::mem_fun(*this, &Editor::collect_new_region_view));
/* A selection grab currently creates two undo/redo operations, one for
creating the new region and another for moving it.
*/
begin_reversible_command (Operations::selection_grab);
boost::shared_ptr<Playlist> playlist = rtv->playlist();
playlist->clear_changes ();
rtv->playlist()->add_region (region, selection->time[clicked_selection].start);
_session->add_command(new StatefulDiffCommand (playlist));
commit_reversible_command ();
c.disconnect ();
if (latest_regionviews.empty()) {
/* something went wrong */
return;
}
/* we need to deselect all other regionviews, and select this one
i'm ignoring undo stuff, because the region creation will take care of it
*/
selection->set (latest_regionviews);
selection->set (new_regions);
_drags->set (new RegionMoveDrag (this, latest_regionviews.front()->get_canvas_group(), latest_regionviews.front(), latest_regionviews, false, false), event);
_drags->set (new RegionMoveDrag (this, new_regions.front()->get_canvas_group(), new_regions.front(), latest_regionviews, false, false), event);
}
void

View file

@ -2673,7 +2673,7 @@ Editor::region_from_selection ()
}
void
Editor::create_region_from_selection (vector<boost::shared_ptr<Region> >& new_regions, RouteTimeAxisView* rtv)
Editor::create_region_from_selection (vector<boost::shared_ptr<Region> >& new_regions)
{
new_regions.clear ();
@ -2687,89 +2687,73 @@ Editor::create_region_from_selection (vector<boost::shared_ptr<Region> >& new_re
TrackViewList ts = selection->tracks.filter_to_unique_playlists ();
sort_track_selection (ts);
if (rtv) {
for (TrackSelection::iterator i = ts.begin(); i != ts.end(); ++i) {
boost::shared_ptr<Region> current;
boost::shared_ptr<Playlist> playlist;
framepos_t internal_start;
string new_name;
if ((playlist = rtv->playlist()) == 0) {
return;
}
if ((current = playlist->top_region_at(start)) == 0) {
return;
}
internal_start = start - current->position();
RegionFactory::region_name (new_name, current->name(), true);
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);
new_regions.push_back (RegionFactory::create (current, plist));
} else {
for (TrackSelection::iterator i = ts.begin(); i != ts.end(); ++i) {
boost::shared_ptr<Region> current;
boost::shared_ptr<Playlist> playlist;
framepos_t internal_start;
string new_name;
boost::shared_ptr<Playlist> playlist;
framepos_t internal_start;
string new_name;
if ((playlist = (*i)->playlist()) == 0) {
continue;
}
if ((current = playlist->top_region_at(start)) == 0) {
continue;
}
internal_start = start - current->position();
RegionFactory::region_name (new_name, current->name(), true);
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);
new_regions.push_back (RegionFactory::create (current, plist));
if ((playlist = (*i)->playlist()) == 0) {
continue;
}
if ((current = playlist->top_region_at(start)) == 0) {
continue;
}
internal_start = start - current->position();
RegionFactory::region_name (new_name, current->name(), true);
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);
new_regions.push_back (RegionFactory::create (current, plist));
}
}
void
Editor::cut_region_from_selection (vector<boost::shared_ptr<Region> >& new_regions, RouteTimeAxisView* rtv)
Editor::cut_copy_region_from_selection (RegionSelection& new_regions, RouteTimeAxisView* rtv, bool follow_track_selection/*=false*/, bool copy /*=false*/)
{
new_regions.clear();
if (selection->time.empty() || selection->tracks.empty() || !rtv) {
if (selection->time.empty() || selection->tracks.empty() ) {
return;
}
AudioRange range = selection->time[clicked_selection];
rtv->cut_range(range);
rtv->paste(range.start, 1, *cut_buffer, 0);
boost::shared_ptr<Region> current;
boost::shared_ptr<ARDOUR::Playlist> playlist;
if ((playlist = rtv->playlist() ) == 0) {
return;
TrackViewList ts;
if (follow_track_selection) {
ts = selection->tracks.filter_to_unique_playlists ();
sort_track_selection (ts);
} else {
if (rtv) {
ts.push_back(rtv);
}
}
if ((current = playlist->top_region_at(range.start) ) == 0) {
return;
latest_regionviews.clear();
for (TrackSelection::iterator i = ts.begin(); i != ts.end(); ++i) {
RouteTimeAxisView* route_view = dynamic_cast<RouteTimeAxisView*> (*i);
if (!route_view) {
continue;
}
Selection new_items(this);
route_view->cut_copy_range(*selection, copy, new_items);
sigc::connection c = route_view->view()->RegionViewAdded.connect (sigc::mem_fun(*this, &Editor::collect_new_region_view));
AudioRange range = selection->time[clicked_selection];
route_view->paste(range.start, 1, new_items, 0);
c.disconnect ();
}
playlist->clear_changes ();
playlist->remove_region (current);
new_regions.push_back( current );
new_regions = latest_regionviews;
}
@ -4561,7 +4545,7 @@ Editor::duplicate_selection (float times)
vector<boost::shared_ptr<Region> > new_regions;
vector<boost::shared_ptr<Region> >::iterator ri;
create_region_from_selection (new_regions, NULL);
create_region_from_selection (new_regions);
if (new_regions.empty()) {
return;

View file

@ -1434,8 +1434,10 @@ RouteTimeAxisView::fade_range (TimeSelection& selection)
}
void
RouteTimeAxisView::cut_range (ARDOUR::AudioRange& range)
RouteTimeAxisView::cut_copy_range (Selection& selection, bool copy, Selection& new_items)
{
new_items.clear();
boost::shared_ptr<Playlist> what_we_got;
boost::shared_ptr<Track> tr = track ();
boost::shared_ptr<Playlist> playlist;
@ -1447,28 +1449,32 @@ RouteTimeAxisView::cut_range (ARDOUR::AudioRange& range)
playlist = tr->playlist();
float const speed = tr->speed();
if (speed != 1.0f) {
range.start = session_frame_to_track_frame(range.start, speed);
range.end = session_frame_to_track_frame(range.end, speed);
}
TimeSelection time (selection.time);
float const speed = tr->speed();
if (speed != 1.0f) {
for (TimeSelection::iterator i = time.begin(); i != time.end(); ++i) {
(*i).start = session_frame_to_track_frame((*i).start, speed);
(*i).end = session_frame_to_track_frame((*i).end, speed);
}
}
playlist->clear_changes ();
playlist->clear_owned_changes ();
std::list<AudioRange> audio_ranges;
audio_ranges.push_back(range);
if ((what_we_got = playlist->cut (audio_ranges)) != 0) {
_editor.get_cut_buffer().set (what_we_got);
if (Config->get_edit_mode() == Ripple)
playlist->ripple(range.start, -range.length(), NULL);
// no need to exclude any regions from rippling here
if (copy) {
vector<Command*> cmds;
playlist->rdiff (cmds);
_session->add_commands (cmds);
if ((what_we_got = playlist->copy (time)) != 0) {
new_items.set (what_we_got);
}
} else {
if ((what_we_got = playlist->cut (time)) != 0) {
new_items.set (what_we_got);
if (Config->get_edit_mode() == Ripple)
playlist->ripple(time.start(), -time.length(), NULL);
}
_session->add_command (new StatefulDiffCommand (playlist));
}
}

View file

@ -108,7 +108,7 @@ public:
void uncombine_region (RegionView*);
void toggle_automation_track (const Evoral::Parameter& param);
void fade_range (TimeSelection&);
void cut_range (ARDOUR::AudioRange& range);
void cut_copy_range (Selection& selection, bool copy, Selection& new_items);
/* The editor calls these when mapping an operation across multiple tracks */
void use_new_playlist (bool prompt, std::vector<boost::shared_ptr<ARDOUR::Playlist> > const &);