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:
Paul Davis 2008-06-18 18:22:22 +00:00
parent 612f25ab3a
commit 6446d0ce49
3 changed files with 126 additions and 87 deletions

View file

@ -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, "__");

View file

@ -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);

View file

@ -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;
}