X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fredirect_box.cc;h=9533cbf782ec2fd830c9403a25b70fca4e9cea0f;hb=cd9fdb935f08966cc8c7170a39870e8adcae69d8;hp=058cc9f5ab912d92713bc5b2c505e030ea78d48b;hpb=37bfd8900c82702d1cb6f2caa3eb753f30a62372;p=ardour.git diff --git a/gtk2_ardour/redirect_box.cc b/gtk2_ardour/redirect_box.cc index 058cc9f5ab..9533cbf782 100644 --- a/gtk2_ardour/redirect_box.cc +++ b/gtk2_ardour/redirect_box.cc @@ -15,15 +15,17 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id$ */ #include +#include #include #include +#include + #include #include @@ -32,6 +34,7 @@ #include #include #include +#include #include #include @@ -42,8 +45,6 @@ #include #include #include -#include -#include #include "ardour_ui.h" #include "ardour_dialog.h" @@ -62,7 +63,7 @@ #include "i18n.h" -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT #include "au_pluginui.h" #endif @@ -102,6 +103,7 @@ RedirectBox::RedirectBox (Placement pcmnt, Session& sess, boost::shared_ptrredirects_changed.connect (mem_fun(*this, &RedirectBox::redisplay_redirects)); + _route->GoingAway.connect (mem_fun (*this, &RedirectBox::route_going_away)); redirect_eventbox.signal_enter_notify_event().connect (bind (sigc::ptr_fun (RedirectBox::enter_box), this)); redirect_display.signal_button_press_event().connect (mem_fun(*this, &RedirectBox::redirect_button_press_event), false); - redirect_display.signal_button_release_event().connect (mem_fun(*this, &RedirectBox::redirect_button_press_event)); + redirect_display.signal_button_release_event().connect (mem_fun(*this, &RedirectBox::redirect_button_release_event)); /* start off as a passthru strip. we'll correct this, if necessary, in update_diskstream_display(). @@ -156,9 +159,16 @@ RedirectBox::~RedirectBox () } void -RedirectBox::object_drop (string type, uint32_t cnt, void** ptr) +RedirectBox::route_going_away () +{ + /* don't keep updating display as redirects are deleted */ + no_redirect_redisplay = true; +} + +void +RedirectBox::object_drop (string type, uint32_t cnt, const boost::shared_ptr* ptr) { - if (type != "redirects" || cnt == 0 || ptr == 0) { + if (type != "redirects" || cnt == 0 || !ptr) { return; } @@ -167,7 +177,7 @@ RedirectBox::object_drop (string type, uint32_t cnt, void** ptr) list > redirects; for (uint32_t n = 0; n < cnt; ++n) { - redirects.push_back (boost::shared_ptr ((Redirect*) ptr[n])); + redirects.push_back (ptr[n]); } paste_redirect_list (redirects); @@ -282,13 +292,8 @@ RedirectBox::redirect_button_press_event (GdkEventButton *ev) } } - - if (redirect && Keyboard::is_delete_event (ev)) { - - Glib::signal_idle().connect (bind (mem_fun(*this, &RedirectBox::idle_delete_redirect), redirect)); - ret = true; - - } else if (redirect && (Keyboard::is_edit_event (ev) || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS && ev->state == 0))) { + + if (redirect && (Keyboard::is_edit_event (ev) || (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS))) { if (_session.engine().connected()) { /* XXX giving an error message here is hard, because we may be in the midst of a button press */ @@ -296,23 +301,50 @@ RedirectBox::redirect_button_press_event (GdkEventButton *ev) } ret = true; + } else if (redirect && ev->button == 1 && selected) { + + // this is purely informational but necessary + RedirectSelected (redirect); // emit + } + + return ret; +} + +bool +RedirectBox::redirect_button_release_event (GdkEventButton *ev) +{ + TreeIter iter; + TreeModel::Path path; + TreeViewColumn* column; + int cellx; + int celly; + boost::shared_ptr redirect; + int ret = false; + + + if (redirect_display.get_path_at_pos ((int)ev->x, (int)ev->y, path, column, cellx, celly)) { + if ((iter = model->get_iter (path))) { + redirect = (*iter)[columns.redirect]; + } + } + + if (redirect && Keyboard::is_delete_event (ev)) { + + Glib::signal_idle().connect (bind (mem_fun(*this, &RedirectBox::idle_delete_redirect), boost::weak_ptr(redirect))); + ret = true; + } else if (Keyboard::is_context_menu_event (ev)) { show_redirect_menu(ev->time); ret = true; - } else if (redirect && ev->button == 2 && ev->state == 0) { + } else if (redirect && (ev->button == 2) && (ev->state == Gdk::BUTTON2_MASK)) { redirect->set_active (!redirect->active(), this); ret = true; } - else if (redirect && ev->button == 1 && selected) { - // this is purely informational but necessary - RedirectSelected (redirect); // emit - } - return ret; } @@ -362,21 +394,21 @@ RedirectBox::insert_plugin_chosen (boost::shared_ptr plugin) boost::shared_ptr redirect (new PluginInsert (_session, plugin, _placement)); - redirect->active_changed.connect (mem_fun(*this, &RedirectBox::show_redirect_active)); + redirect->active_changed.connect (bind (mem_fun (*this, &RedirectBox::show_redirect_active_r), boost::weak_ptr(redirect))); uint32_t err_streams; if (_route->add_redirect (redirect, this, &err_streams)) { - wierd_plugin_dialog (*plugin, err_streams, _route); + weird_plugin_dialog (*plugin, err_streams, _route); // XXX SHAREDPTR delete plugin here .. do we even need to care? } } } void -RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, boost::shared_ptr io) +RedirectBox::weird_plugin_dialog (Plugin& p, uint32_t streams, boost::shared_ptr io) { - ArdourDialog dialog ("wierd plugin dialog"); + ArdourDialog dialog (_("ardour: weird plugin dialog")); Label label; /* i hate this kind of code */ @@ -420,8 +452,8 @@ RedirectBox::wierd_plugin_dialog (Plugin& p, uint32_t streams, boost::shared_ptr p.name(), p.get_info()->n_inputs, p.get_info()->n_outputs, - io->n_inputs(), - io->n_outputs(), + io->n_inputs().n_total(), + io->n_outputs().n_total(), streams)); } @@ -440,7 +472,7 @@ void RedirectBox::choose_insert () { boost::shared_ptr redirect (new PortInsert (_session, _placement)); - redirect->active_changed.connect (mem_fun(*this, &RedirectBox::show_redirect_active)); + redirect->active_changed.connect (bind (mem_fun(*this, &RedirectBox::show_redirect_active_r), boost::weak_ptr(redirect))); _route->add_redirect (redirect, this); } @@ -448,23 +480,33 @@ void RedirectBox::choose_send () { boost::shared_ptr send (new Send (_session, _placement)); + send->set_default_type(_route->default_type()); /* XXX need redirect lock on route */ - send->ensure_io (0, _route->max_redirect_outs(), false, this); + send->ensure_io (ChanCount::ZERO, _route->max_redirect_outs(), false, this); IOSelectorWindow *ios = new IOSelectorWindow (_session, send, false, true); ios->show_all (); - ios->selector().Finished.connect (bind (mem_fun(*this, &RedirectBox::send_io_finished), boost::static_pointer_cast(send), ios)); + + boost::shared_ptr r = boost::static_pointer_cast(send); + + ios->selector().Finished.connect (bind (mem_fun(*this, &RedirectBox::send_io_finished), boost::weak_ptr(r), ios)); } void -RedirectBox::send_io_finished (IOSelector::Result r, boost::shared_ptr redirect, IOSelectorWindow* ios) +RedirectBox::send_io_finished (IOSelector::Result r, boost::weak_ptr weak_redirect, IOSelectorWindow* ios) { + boost::shared_ptr redirect (weak_redirect.lock()); + + if (!redirect) { + return; + } + switch (r) { case IOSelector::Cancelled: - // delete redirect; XXX SHAREDPTR HOW TO DESTROY THE REDIRECT ? do we even need to think about it? + // redirect will go away when all shared_ptrs to it vanish break; case IOSelector::Accepted: @@ -483,7 +525,7 @@ RedirectBox::redisplay_redirects (void *src) if (no_redirect_redisplay) { return; } - + ignore_delete = true; model->clear (); ignore_delete = false; @@ -514,16 +556,22 @@ RedirectBox::add_redirect_to_display (boost::shared_ptr redirect) Gtk::TreeModel::Row row = *(model->append()); row[columns.text] = redirect_name (redirect); row[columns.redirect] = redirect; - - show_redirect_active (redirect.get(), this); - redirect_active_connections.push_back (redirect->active_changed.connect (mem_fun(*this, &RedirectBox::show_redirect_active))); - redirect_name_connections.push_back (redirect->name_changed.connect (bind (mem_fun(*this, &RedirectBox::show_redirect_name), redirect))); + show_redirect_active (redirect); + + redirect_active_connections.push_back (redirect->active_changed.connect (bind (mem_fun(*this, &RedirectBox::show_redirect_active_r), boost::weak_ptr(redirect)))); + redirect_name_connections.push_back (redirect->name_changed.connect (bind (mem_fun(*this, &RedirectBox::show_redirect_name), boost::weak_ptr(redirect)))); } string -RedirectBox::redirect_name (boost::shared_ptr redirect) +RedirectBox::redirect_name (boost::weak_ptr weak_redirect) { + boost::shared_ptr redirect (weak_redirect.lock()); + + if (!redirect) { + return string(); + } + boost::shared_ptr send; string name_display; @@ -579,22 +627,38 @@ RedirectBox::build_redirect_tooltip (EventBox& box, string start) for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end(); ++iter) { Gtk::TreeModel::Row row = *iter; tip += '\n'; - tip += row[columns.text]; + + /* don't use the column text, since it may be narrowed */ + + boost::shared_ptr r = row[columns.redirect]; + tip += r->name(); } ARDOUR_UI::instance()->tooltips().set_tip (box, tip); } void -RedirectBox::show_redirect_name (void* src, boost::shared_ptr redirect) +RedirectBox::show_redirect_name (void* src, boost::weak_ptr redirect) { ENSURE_GUI_THREAD(bind (mem_fun(*this, &RedirectBox::show_redirect_name), src, redirect)); - show_redirect_active (redirect.get(), src); + show_redirect_active (redirect); } void -RedirectBox::show_redirect_active (Redirect* redirect, void *src) +RedirectBox::show_redirect_active_r (Redirect* r, void *src, boost::weak_ptr weak_redirect) { - ENSURE_GUI_THREAD(bind (mem_fun(*this, &RedirectBox::show_redirect_active), redirect, src)); + show_redirect_active (weak_redirect); +} + +void +RedirectBox::show_redirect_active (boost::weak_ptr weak_redirect) +{ + ENSURE_GUI_THREAD(bind (mem_fun(*this, &RedirectBox::show_redirect_active), weak_redirect)); + + boost::shared_ptr redirect (weak_redirect.lock()); + + if (!redirect) { + return; + } Gtk::TreeModel::Children children = model->children(); Gtk::TreeModel::Children::iterator iter = children.begin(); @@ -603,7 +667,7 @@ RedirectBox::show_redirect_active (Redirect* redirect, void *src) boost::shared_ptr r = (*iter)[columns.redirect]; - if (r.get() == redirect) { + if (r == redirect) { (*iter)[columns.text] = redirect_name (r); if (redirect->active()) { @@ -644,7 +708,7 @@ RedirectBox::compute_redirect_sort_keys () /* now tell them about the problem */ - ArdourDialog dialog ("wierd plugin dialog"); + ArdourDialog dialog (_("ardour: weird plugin dialog")); Label label; label.set_text (_("\ @@ -698,20 +762,27 @@ RedirectBox::cut_redirects () _rr_selection.set (to_be_removed); + no_redirect_redisplay = true; for (vector >::iterator i = to_be_removed.begin(); i != to_be_removed.end(); ++i) { + // Do not cut inserts or sends + if (boost::dynamic_pointer_cast((*i)) != 0) { + void* gui = (*i)->get_gui (); - void* gui = (*i)->get_gui (); - - if (gui) { - static_cast(gui)->hide (); - } + if (gui) { + static_cast(gui)->hide (); + } - if (_route->remove_redirect (*i, this)) { - /* removal failed */ + if (_route->remove_redirect (*i, this)) { + /* removal failed */ + _rr_selection.remove (*i); + } + } else { _rr_selection.remove (*i); } } + no_redirect_redisplay = false; + redisplay_redirects (this); } void @@ -727,19 +798,59 @@ RedirectBox::copy_redirects () } for (vector >::iterator i = to_be_copied.begin(); i != to_be_copied.end(); ++i) { - copies.push_back (Redirect::clone (*i)); + // Do not copy inserts or sends + if (boost::dynamic_pointer_cast((*i)) != 0) { + copies.push_back (Redirect::clone (*i)); + } } _rr_selection.set (copies); + +} + +void +RedirectBox::delete_redirects () +{ + vector > to_be_deleted; + + get_selected_redirects (to_be_deleted); + + if (to_be_deleted.empty()) { + return; + } + + for (vector >::iterator i = to_be_deleted.begin(); i != to_be_deleted.end(); ++i) { + + void* gui = (*i)->get_gui (); + + if (gui) { + static_cast(gui)->hide (); + } + + _route->remove_redirect( *i, this); + } + + no_redirect_redisplay = false; + redisplay_redirects (this); } gint -RedirectBox::idle_delete_redirect (boost::shared_ptr redirect) +RedirectBox::idle_delete_redirect (boost::weak_ptr weak_redirect) { + boost::shared_ptr redirect (weak_redirect.lock()); + + if (!redirect) { + return false; + } + /* NOT copied to _mixer.selection() */ + no_redirect_redisplay = true; _route->remove_redirect (redirect, this); - return FALSE; + no_redirect_redisplay = false; + redisplay_redirects (this); + + return false; } void @@ -764,7 +875,6 @@ RedirectBox::rename_redirect (boost::shared_ptr redirect) } return; - } void @@ -783,9 +893,12 @@ RedirectBox::cut_redirect (boost::shared_ptr redirect) static_cast(gui)->hide (); } + no_redirect_redisplay = true; if (_route->remove_redirect (redirect, this)) { _rr_selection.remove (redirect); } + no_redirect_redisplay = false; + redisplay_redirects (this); } void @@ -846,8 +959,9 @@ RedirectBox::get_selected_redirects (vector >& redir { vector pathlist = redirect_display.get_selection()->get_selected_rows(); - for (vector::iterator iter = pathlist.begin(); iter != pathlist.end(); ++iter) - redirects.push_back ((*(model->get_iter(*iter)))[columns.redirect]); + for (vector::iterator iter = pathlist.begin(); iter != pathlist.end(); ++iter) { + redirects.push_back ((*(model->get_iter(*iter)))[columns.redirect]); + } } void @@ -881,21 +995,48 @@ could not match the configuration of this track."); void RedirectBox::all_redirects_active (bool state) { - _route->all_redirects_active (state); + _route->all_redirects_active (_placement, state); } void -RedirectBox::clear_redirects() +RedirectBox::all_plugins_active (bool state) +{ + if (state) { + // XXX not implemented + } else { + _route->disable_plugins (_placement); + } +} + +void +RedirectBox::ab_plugins () +{ + _route->ab_plugins (ab_direction); + ab_direction = !ab_direction; +} + +void +RedirectBox::clear_redirects () { string prompt; vector choices; if (boost::dynamic_pointer_cast(_route) != 0) { - prompt = _("Do you really want to remove all redirects from this track?\n" - "(this cannot be undone)"); + if (_placement == PreFader) { + prompt = _("Do you really want to remove all pre-fader redirects from this track?\n" + "(this cannot be undone)"); + } else { + prompt = _("Do you really want to remove all post-fader redirects from this track?\n" + "(this cannot be undone)"); + } } else { - prompt = _("Do you really want to remove all redirects from this bus?\n" - "(this cannot be undone)"); + if (_placement == PreFader) { + prompt = _("Do you really want to remove all pre-fader redirects from this bus?\n" + "(this cannot be undone)"); + } else { + prompt = _("Do you really want to remove all post-fader redirects from this bus?\n" + "(this cannot be undone)"); + } } choices.push_back (_("Cancel")); @@ -904,7 +1045,7 @@ RedirectBox::clear_redirects() Gtkmm2ext::Choice prompter (prompt, choices); if (prompter.run () == 1) { - _route->clear_redirects (this); + _route->clear_redirects (_placement, this); } } @@ -922,7 +1063,7 @@ RedirectBox::edit_redirect (boost::shared_ptr redirect) if ((insert = boost::dynamic_pointer_cast (redirect)) == 0) { - /* its a send */ + /* it's a send */ if (!_session.engine().connected()) { return; @@ -934,11 +1075,12 @@ RedirectBox::edit_redirect (boost::shared_ptr redirect) if (send->get_gui() == 0) { - string title; - title = string_compose(_("ardour: %1"), send->name()); - send_ui = new SendUIWindow (send, _session); - send_ui->set_title (title); + + WindowTitle title(Glib::get_application_name()); + title += send->name(); + send_ui->set_title (title.get_string()); + send->set_gui (send_ui); } else { @@ -949,11 +1091,12 @@ RedirectBox::edit_redirect (boost::shared_ptr redirect) send_ui->get_window()->raise (); } else { send_ui->show_all (); + send_ui->present (); } } else { - /* its an insert */ + /* it's an insert */ boost::shared_ptr plugin_insert; boost::shared_ptr port_insert; @@ -966,30 +1109,24 @@ RedirectBox::edit_redirect (boost::shared_ptr redirect) PluginUIWindow *plugin_ui; if (plugin_insert->get_gui() == 0) { - - string title; - string maker = plugin_insert->plugin()->maker(); - string::size_type email_pos; - - if ((email_pos = maker.find_first_of ('<')) != string::npos) { - maker = maker.substr (0, email_pos - 1); - } - - if (maker.length() > 32) { - maker = maker.substr (0, 32); - maker += " ..."; - } - - title = string_compose(_("ardour: %1: %2 (by %3)"), _route->name(), plugin_insert->name(), maker); - + plugin_ui = new PluginUIWindow (plugin_insert); + if (_owner_is_mixer) { ARDOUR_UI::instance()->the_mixer()->ensure_float (*plugin_ui); } else { ARDOUR_UI::instance()->the_editor().ensure_float (*plugin_ui); } - plugin_ui->set_title (title); + + WindowTitle title(Glib::get_application_name()); + title += generate_redirect_title (plugin_insert); + plugin_ui->set_title (title.get_string()); + plugin_insert->set_gui (plugin_ui); + + // change window title when route name is changed + _route->name_changed.connect (bind (mem_fun(*this, &RedirectBox::route_name_changed), plugin_ui, boost::weak_ptr (plugin_insert))); + } else { plugin_ui = reinterpret_cast (plugin_insert->get_gui()); @@ -999,8 +1136,9 @@ RedirectBox::edit_redirect (boost::shared_ptr redirect) plugin_ui->get_window()->raise (); } else { plugin_ui->show_all (); + plugin_ui->present (); } -#ifdef HAVE_COREAUDIO +#ifdef HAVE_AUDIOUNIT } else if (type == ARDOUR::AudioUnit) { AUPluginUI* plugin_ui; if (plugin_insert->get_gui() == 0) { @@ -1009,12 +1147,18 @@ RedirectBox::edit_redirect (boost::shared_ptr redirect) plugin_ui = reinterpret_cast (plugin_insert->get_gui()); } - // raise window, somehow + if (plugin_ui->is_visible()) { + plugin_ui->get_window()->raise (); + } else { + plugin_ui->show_all (); + plugin_ui->present (); + } #endif } else { warning << "Unsupported plugin sent to RedirectBox::edit_redirect()" << endmsg; return; } + } else if ((port_insert = boost::dynamic_pointer_cast (insert)) != 0) { if (!_session.engine().connected()) { @@ -1037,6 +1181,7 @@ RedirectBox::edit_redirect (boost::shared_ptr redirect) io_selector->get_window()->raise (); } else { io_selector->show_all (); + io_selector->present (); } } } @@ -1067,8 +1212,12 @@ RedirectBox::register_actions () /* new stuff */ ActionManager::register_action (popup_act_grp, X_("newplugin"), _("New Plugin ..."), sigc::ptr_fun (RedirectBox::rb_choose_plugin)); - ActionManager::register_action (popup_act_grp, X_("newinsert"), _("New Insert"), sigc::ptr_fun (RedirectBox::rb_choose_insert)); - ActionManager::register_action (popup_act_grp, X_("newsend"), _("New Send ..."), sigc::ptr_fun (RedirectBox::rb_choose_send)); + + act = ActionManager::register_action (popup_act_grp, X_("newinsert"), _("New Insert"), sigc::ptr_fun (RedirectBox::rb_choose_insert)); + ActionManager::jack_sensitive_actions.push_back (act); + act = ActionManager::register_action (popup_act_grp, X_("newsend"), _("New Send ..."), sigc::ptr_fun (RedirectBox::rb_choose_send)); + ActionManager::jack_sensitive_actions.push_back (act); + ActionManager::register_action (popup_act_grp, X_("clear"), _("Clear"), sigc::ptr_fun (RedirectBox::rb_clear)); /* standard editing stuff */ @@ -1076,6 +1225,10 @@ RedirectBox::register_actions () ActionManager::plugin_selection_sensitive_actions.push_back(act); act = ActionManager::register_action (popup_act_grp, X_("copy"), _("Copy"), sigc::ptr_fun (RedirectBox::rb_copy)); ActionManager::plugin_selection_sensitive_actions.push_back(act); + + act = ActionManager::register_action (popup_act_grp, X_("delete"), _("Delete"), sigc::ptr_fun (RedirectBox::rb_delete)); + ActionManager::plugin_selection_sensitive_actions.push_back(act); // ?? + paste_action = ActionManager::register_action (popup_act_grp, X_("paste"), _("Paste"), sigc::ptr_fun (RedirectBox::rb_paste)); act = ActionManager::register_action (popup_act_grp, X_("rename"), _("Rename"), sigc::ptr_fun (RedirectBox::rb_rename)); ActionManager::plugin_selection_sensitive_actions.push_back(act); @@ -1090,11 +1243,16 @@ RedirectBox::register_actions () ActionManager::register_action (popup_act_grp, X_("activate_all"), _("Activate all"), sigc::ptr_fun (RedirectBox::rb_activate_all)); ActionManager::register_action (popup_act_grp, X_("deactivate_all"), _("Deactivate all"), sigc::ptr_fun (RedirectBox::rb_deactivate_all)); + ActionManager::register_action (popup_act_grp, X_("a_b_plugins"), _("A/B plugins"), sigc::ptr_fun (RedirectBox::rb_ab_plugins)); + ActionManager::register_action (popup_act_grp, X_("deactivate_plugins"), _("Deactivate plugins"), sigc::ptr_fun (RedirectBox::rb_deactivate_plugins)); + /* show editors */ act = ActionManager::register_action (popup_act_grp, X_("edit"), _("Edit"), sigc::ptr_fun (RedirectBox::rb_edit)); ActionManager::plugin_selection_sensitive_actions.push_back(act); ActionManager::add_action_group (popup_act_grp); + + } void @@ -1144,6 +1302,16 @@ RedirectBox::rb_cut () _current_redirect_box->cut_redirects (); } +void +RedirectBox::rb_delete () +{ + if (_current_redirect_box == 0) { + return; + } + + _current_redirect_box->delete_redirects (); +} + void RedirectBox::rb_copy () { @@ -1230,6 +1398,27 @@ RedirectBox::rb_deactivate_all () _current_redirect_box->all_redirects_active (false); } +void +RedirectBox::rb_deactivate_plugins () +{ + if (_current_redirect_box == 0) { + return; + } + _current_redirect_box->all_plugins_active (false); +} + + +void +RedirectBox::rb_ab_plugins () +{ + if (_current_redirect_box == 0) { + return; + } + + _current_redirect_box->ab_plugins (); +} + + void RedirectBox::rb_edit () { @@ -1240,3 +1429,35 @@ RedirectBox::rb_edit () _current_redirect_box->for_selected_redirects (&RedirectBox::edit_redirect); } +void +RedirectBox::route_name_changed (void* src, PluginUIWindow* plugin_ui, boost::weak_ptr wpi) +{ + ENSURE_GUI_THREAD(bind (mem_fun (*this, &RedirectBox::route_name_changed), src, plugin_ui, wpi)); + boost::shared_ptr pi (wpi.lock()); + + + if (pi) { + WindowTitle title(Glib::get_application_name()); + title += generate_redirect_title (pi); + plugin_ui->set_title (title.get_string()); + } +} + +string +RedirectBox::generate_redirect_title (boost::shared_ptr pi) +{ + string maker = pi->plugin()->maker(); + string::size_type email_pos; + + if ((email_pos = maker.find_first_of ('<')) != string::npos) { + maker = maker.substr (0, email_pos - 1); + } + + if (maker.length() > 32) { + maker = maker.substr (0, 32); + maker += " ..."; + } + + return string_compose(_("%1: %2 (by %3)"), _route->name(), pi->name(), maker); +} +