+void
+PortMatrix::popup_menu (BundleChannel column, BundleChannel row, uint32_t t)
+{
+ using namespace Menu_Helpers;
+
+ delete _menu;
+
+ _menu = new Menu;
+ _menu->set_name ("ArdourContextMenu");
+
+ MenuList& items = _menu->items ();
+
+ BundleChannel bc[2];
+ bc[_column_index] = column;
+ bc[_row_index] = row;
+
+ char buf [64];
+ bool need_separator = false;
+
+ for (int dim = 0; dim < 2; ++dim) {
+
+ if (bc[dim].bundle) {
+
+ Menu* m = manage (new Menu);
+ MenuList& sub = m->items ();
+
+ boost::weak_ptr<Bundle> w (bc[dim].bundle);
+
+ bool can_add_or_rename = false;
+
+ for (DataType::iterator i = DataType::begin(); i != DataType::end(); ++i) {
+ if (should_show (*i)) {
+ snprintf (buf, sizeof (buf), _("Add %s %s"), (*i).to_i18n_string(), channel_noun().c_str());
+ sub.push_back (MenuElem (buf, sigc::bind (sigc::mem_fun (*this, &PortMatrix::add_channel_proxy), w, *i)));
+ can_add_or_rename = true;
+ }
+ }
+
+ if (can_rename_channels (bc[dim].bundle)) {
+ snprintf (
+ buf, sizeof (buf), _("Rename '%s'..."),
+ escape_underscores (bc[dim].bundle->channel_name (bc[dim].channel)).c_str()
+ );
+ sub.push_back (
+ MenuElem (
+ buf,
+ sigc::bind (sigc::mem_fun (*this, &PortMatrix::rename_channel_proxy), w, bc[dim].channel)
+ )
+ );
+ can_add_or_rename = true;
+ }
+
+ if (can_add_or_rename) {
+ sub.push_back (SeparatorElem ());
+ }
+
+ if (can_remove_channels (bc[dim].bundle)) {
+ if (bc[dim].channel != -1) {
+ add_remove_option (sub, w, bc[dim].channel);
+ } else {
+
+ snprintf (buf, sizeof (buf), _("Remove all"));
+ sub.push_back (
+ MenuElem (buf, sigc::bind (sigc::mem_fun (*this, &PortMatrix::remove_all_channels), w))
+ );
+
+ for (uint32_t i = 0; i < bc[dim].bundle->nchannels().n_total(); ++i) {
+ if (should_show (bc[dim].bundle->channel_type(i))) {
+ add_remove_option (sub, w, i);
+ }
+ }
+ }
+ }
+
+ if (_show_only_bundles || count_of_our_type (bc[dim].bundle->nchannels()) <= 1) {
+ snprintf (buf, sizeof (buf), _("%s all"), disassociation_verb().c_str());
+ sub.push_back (
+ MenuElem (buf, sigc::bind (sigc::mem_fun (*this, &PortMatrix::disassociate_all_on_channel), w, bc[dim].channel, dim))
+ );
+
+ } else {
+
+ if (bc[dim].channel != -1) {
+ add_disassociate_option (sub, w, dim, bc[dim].channel);
+ } else {
+ snprintf (buf, sizeof (buf), _("%s all"), disassociation_verb().c_str());
+ sub.push_back (
+ MenuElem (buf, sigc::bind (sigc::mem_fun (*this, &PortMatrix::disassociate_all_on_bundle), w, dim))
+ );
+
+ for (uint32_t i = 0; i < bc[dim].bundle->nchannels().n_total(); ++i) {
+ if (should_show (bc[dim].bundle->channel_type(i))) {
+ add_disassociate_option (sub, w, dim, i);
+ }
+ }
+ }
+ }
+
+ items.push_back (MenuElem (escape_underscores (bc[dim].bundle->name()).c_str(), *m));
+ need_separator = true;