mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-27 00:47:43 +01:00
slightly modified patch from colinf to make region context menu items always operate on well-defined and reasonably obvious region selection
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@3476 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
612f25ab3a
commit
6446d0ce49
3 changed files with 126 additions and 87 deletions
|
|
@ -1603,9 +1603,19 @@ Editor::build_track_region_context_menu (nframes64_t frame)
|
|||
|
||||
if ((ds = atv->get_diskstream()) && ((pl = ds->playlist()))) {
|
||||
Playlist::RegionList* regions = pl->regions_at ((nframes64_t) floor ( (double)frame * ds->speed()));
|
||||
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
|
||||
add_region_context_items (atv->audio_view(), (*i), edit_items);
|
||||
|
||||
if (selection->regions.size() > 1) {
|
||||
// there's already a multiple selection: just add a
|
||||
// single region context menu that will act on all
|
||||
// selected regions
|
||||
boost::shared_ptr<Region> dummy_region; // = NULL
|
||||
add_region_context_items (atv->audio_view(), dummy_region, edit_items);
|
||||
} else {
|
||||
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
|
||||
add_region_context_items (atv->audio_view(), (*i), edit_items);
|
||||
}
|
||||
}
|
||||
|
||||
delete regions;
|
||||
}
|
||||
}
|
||||
|
|
@ -1642,10 +1652,17 @@ Editor::build_track_crossfade_context_menu (nframes64_t frame)
|
|||
add_crossfade_context_items (atv->audio_view(), (*i), edit_items, many);
|
||||
}
|
||||
|
||||
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
|
||||
add_region_context_items (atv->audio_view(), (*i), edit_items);
|
||||
if (selection->regions.size() > 1) {
|
||||
// there's already a multiple selection: just add a
|
||||
// single region context menu that will act on all
|
||||
// selected regions
|
||||
boost::shared_ptr<Region> dummy_region; // = NULL
|
||||
add_region_context_items (atv->audio_view(), dummy_region, edit_items);
|
||||
} else {
|
||||
for (Playlist::RegionList::iterator i = regions->begin(); i != regions->end(); ++i) {
|
||||
add_region_context_items (atv->audio_view(), (*i), edit_items);
|
||||
}
|
||||
}
|
||||
|
||||
delete regions;
|
||||
}
|
||||
}
|
||||
|
|
@ -1778,16 +1795,23 @@ Editor::add_region_context_items (AudioStreamView* sv, boost::shared_ptr<Region>
|
|||
|
||||
if (region) {
|
||||
ar = boost::dynamic_pointer_cast<AudioRegion> (region);
|
||||
|
||||
/* when this particular menu pops up, make the relevant region
|
||||
become selected.
|
||||
*/
|
||||
|
||||
region_menu->signal_map_event().connect (
|
||||
bind (
|
||||
mem_fun(*this, &Editor::set_selected_regionview_from_map_event),
|
||||
sv,
|
||||
boost::weak_ptr<Region>(region)
|
||||
)
|
||||
);
|
||||
|
||||
items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
|
||||
items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
|
||||
}
|
||||
|
||||
/* when this particular menu pops up, make the relevant region
|
||||
become selected.
|
||||
*/
|
||||
|
||||
region_menu->signal_map_event().connect (bind (mem_fun(*this, &Editor::set_selected_regionview_from_map_event), sv, boost::weak_ptr<Region>(region)));
|
||||
|
||||
items.push_back (MenuElem (_("Rename"), mem_fun(*this, &Editor::rename_region)));
|
||||
items.push_back (MenuElem (_("Popup region editor"), mem_fun(*this, &Editor::edit_region)));
|
||||
items.push_back (MenuElem (_("Raise to top layer"), mem_fun(*this, &Editor::raise_region_to_top)));
|
||||
items.push_back (MenuElem (_("Lower to bottom layer"), mem_fun (*this, &Editor::lower_region_to_bottom)));
|
||||
items.push_back (SeparatorElem());
|
||||
|
|
@ -1807,49 +1831,51 @@ Editor::add_region_context_items (AudioStreamView* sv, boost::shared_ptr<Region>
|
|||
|
||||
sigc::connection fooc;
|
||||
|
||||
items.push_back (CheckMenuElem (_("Lock")));
|
||||
CheckMenuItem* region_lock_item = static_cast<CheckMenuItem*>(&items.back());
|
||||
if (region->locked()) {
|
||||
region_lock_item->set_active();
|
||||
}
|
||||
region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_lock));
|
||||
if (region) {
|
||||
items.push_back (CheckMenuElem (_("Lock")));
|
||||
CheckMenuItem* region_lock_item = static_cast<CheckMenuItem*>(&items.back());
|
||||
if (region->locked()) {
|
||||
region_lock_item->set_active();
|
||||
}
|
||||
region_lock_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_lock));
|
||||
|
||||
items.push_back (CheckMenuElem (_("Glue to Bars&Beats")));
|
||||
CheckMenuItem* bbt_glue_item = static_cast<CheckMenuItem*>(&items.back());
|
||||
items.push_back (CheckMenuElem (_("Glue to Bars&Beats")));
|
||||
CheckMenuItem* bbt_glue_item = static_cast<CheckMenuItem*>(&items.back());
|
||||
|
||||
switch (region->positional_lock_style()) {
|
||||
case Region::MusicTime:
|
||||
bbt_glue_item->set_active (true);
|
||||
break;
|
||||
default:
|
||||
bbt_glue_item->set_active (false);
|
||||
break;
|
||||
}
|
||||
switch (region->positional_lock_style()) {
|
||||
case Region::MusicTime:
|
||||
bbt_glue_item->set_active (true);
|
||||
break;
|
||||
default:
|
||||
bbt_glue_item->set_active (false);
|
||||
break;
|
||||
}
|
||||
|
||||
bbt_glue_item->signal_activate().connect (bind (mem_fun (*this, &Editor::set_region_lock_style), Region::MusicTime));
|
||||
bbt_glue_item->signal_activate().connect (bind (mem_fun (*this, &Editor::set_region_lock_style), Region::MusicTime));
|
||||
|
||||
items.push_back (CheckMenuElem (_("Mute")));
|
||||
CheckMenuItem* region_mute_item = static_cast<CheckMenuItem*>(&items.back());
|
||||
fooc = region_mute_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_mute));
|
||||
if (region->muted()) {
|
||||
fooc.block (true);
|
||||
region_mute_item->set_active();
|
||||
fooc.block (false);
|
||||
}
|
||||
|
||||
if (!Profile->get_sae()) {
|
||||
items.push_back (CheckMenuElem (_("Opaque")));
|
||||
CheckMenuItem* region_opaque_item = static_cast<CheckMenuItem*>(&items.back());
|
||||
fooc = region_opaque_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_opaque));
|
||||
if (region->opaque()) {
|
||||
items.push_back (CheckMenuElem (_("Mute")));
|
||||
CheckMenuItem* region_mute_item = static_cast<CheckMenuItem*>(&items.back());
|
||||
fooc = region_mute_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_mute));
|
||||
if (region->muted()) {
|
||||
fooc.block (true);
|
||||
region_opaque_item->set_active();
|
||||
region_mute_item->set_active();
|
||||
fooc.block (false);
|
||||
}
|
||||
|
||||
if (!Profile->get_sae()) {
|
||||
items.push_back (CheckMenuElem (_("Opaque")));
|
||||
CheckMenuItem* region_opaque_item = static_cast<CheckMenuItem*>(&items.back());
|
||||
fooc = region_opaque_item->signal_activate().connect (mem_fun(*this, &Editor::toggle_region_opaque));
|
||||
if (region->opaque()) {
|
||||
fooc.block (true);
|
||||
region_opaque_item->set_active();
|
||||
fooc.block (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
items.push_back (CheckMenuElem (_("Original position"), mem_fun(*this, &Editor::naturalize)));
|
||||
if (region->at_natural_position()) {
|
||||
if (region && region->at_natural_position()) {
|
||||
items.back().set_sensitive (false);
|
||||
}
|
||||
|
||||
|
|
@ -1937,7 +1963,7 @@ Editor::add_region_context_items (AudioStreamView* sv, boost::shared_ptr<Region>
|
|||
items.push_back (MenuElem (_("Multi-Duplicate"), (bind (mem_fun(*this, &Editor::duplicate_dialog), true))));
|
||||
items.push_back (MenuElem (_("Fill Track"), (mem_fun(*this, &Editor::region_fill_track))));
|
||||
items.push_back (SeparatorElem());
|
||||
items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_clicked_region)));
|
||||
items.push_back (MenuElem (_("Remove"), mem_fun(*this, &Editor::remove_region)));
|
||||
|
||||
/* OK, stick the region submenu at the top of the list, and then add
|
||||
the standard items.
|
||||
|
|
@ -1948,7 +1974,7 @@ Editor::add_region_context_items (AudioStreamView* sv, boost::shared_ptr<Region>
|
|||
*/
|
||||
|
||||
string::size_type pos = 0;
|
||||
string menu_item_name = region->name();
|
||||
string menu_item_name = (region) ? region->name() : _("Selected regions");
|
||||
|
||||
while ((pos = menu_item_name.find ("_", pos)) != string::npos) {
|
||||
menu_item_name.replace (pos, 1, "__");
|
||||
|
|
|
|||
|
|
@ -1025,8 +1025,8 @@ class Editor : public PublicEditor
|
|||
void align_selection_relative (ARDOUR::RegionPoint point, nframes64_t position, const RegionSelection&);
|
||||
void align_region (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes64_t position);
|
||||
void align_region_internal (boost::shared_ptr<ARDOUR::Region>, ARDOUR::RegionPoint point, nframes64_t position);
|
||||
void remove_region ();
|
||||
void remove_clicked_region ();
|
||||
void destroy_clicked_region ();
|
||||
void edit_region ();
|
||||
void rename_region ();
|
||||
void duplicate_some_regions (RegionSelection&, float times);
|
||||
|
|
|
|||
|
|
@ -199,46 +199,50 @@ Editor::remove_clicked_region ()
|
|||
}
|
||||
|
||||
void
|
||||
Editor::destroy_clicked_region ()
|
||||
Editor::remove_region ()
|
||||
{
|
||||
uint32_t selected = selection->regions.size();
|
||||
|
||||
if (!session || !selected) {
|
||||
RegionSelection rs;
|
||||
get_regions_for_action (rs);
|
||||
|
||||
if (!session) {
|
||||
return;
|
||||
}
|
||||
|
||||
vector<string> choices;
|
||||
string prompt;
|
||||
|
||||
prompt = string_compose (_(" This is destructive, will possibly delete audio files\n\
|
||||
It cannot be undone\n\
|
||||
Do you really want to destroy %1 ?"),
|
||||
(selected > 1 ?
|
||||
_("these regions") : _("this region")));
|
||||
|
||||
choices.push_back (_("No, do nothing."));
|
||||
|
||||
if (selected > 1) {
|
||||
choices.push_back (_("Yes, destroy them."));
|
||||
} else {
|
||||
choices.push_back (_("Yes, destroy it."));
|
||||
}
|
||||
|
||||
Gtkmm2ext::Choice prompter (prompt, choices);
|
||||
|
||||
if (prompter.run() == 0) { /* first choice */
|
||||
if (rs.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
list<boost::shared_ptr<Region> > r;
|
||||
begin_reversible_command (_("remove region"));
|
||||
|
||||
for (RegionSelection::iterator i = selection->regions.begin(); i != selection->regions.end(); ++i) {
|
||||
r.push_back ((*i)->region());
|
||||
}
|
||||
list<boost::shared_ptr<Region> > regions_to_remove;
|
||||
|
||||
session->destroy_regions (r);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
XMLNode &before = playlist->get_state();
|
||||
playlist->remove_region (*rl);
|
||||
XMLNode &after = playlist->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*playlist, &before, &after));
|
||||
}
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
boost::shared_ptr<Region>
|
||||
|
|
@ -3152,15 +3156,23 @@ Editor::set_sync_point (nframes64_t where, const RegionSelection& rs)
|
|||
void
|
||||
Editor::remove_region_sync ()
|
||||
{
|
||||
if (clicked_regionview) {
|
||||
boost::shared_ptr<Region> region (clicked_regionview->region());
|
||||
begin_reversible_command (_("remove sync"));
|
||||
XMLNode &before = region->playlist()->get_state();
|
||||
region->clear_sync_position ();
|
||||
XMLNode &after = region->playlist()->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*(region->playlist()), &before, &after));
|
||||
commit_reversible_command ();
|
||||
RegionSelection rs;
|
||||
|
||||
get_regions_for_action (rs);
|
||||
|
||||
if (rs.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
begin_reversible_command (_("remove sync"));
|
||||
for (RegionSelection::iterator i = rs.begin(); i != rs.end(); ++i) {
|
||||
|
||||
XMLNode &before = (*i)->region()->playlist()->get_state();
|
||||
(*i)->region()->clear_sync_position ();
|
||||
XMLNode &after = (*i)->region()->playlist()->get_state();
|
||||
session->add_command(new MementoCommand<Playlist>(*((*i)->region()->playlist()), &before, &after));
|
||||
}
|
||||
commit_reversible_command ();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -4470,6 +4482,7 @@ Editor::region_selection_op (void (Region::*pmf)(bool), bool yn)
|
|||
void
|
||||
Editor::external_edit_region ()
|
||||
{
|
||||
// XXX shouldn't this use get_regions_for_action(rs) too?
|
||||
if (!clicked_regionview) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue