From cc58df90863ed3d5c056a976ee4cefffb99c7f04 Mon Sep 17 00:00:00 2001 From: John Smith Date: Mon, 18 Feb 2013 22:04:08 +0900 Subject: Fix for 998276 : Keyboard shortcuts not appearing in the main menu under Unity (bzr r12132) --- src/interface.cpp | 114 ++++++++---------------------------------------------- src/shortcuts.cpp | 68 +++++++++++++++++++++++++++----- src/shortcuts.h | 5 ++- 3 files changed, 79 insertions(+), 108 deletions(-) (limited to 'src') diff --git a/src/interface.cpp b/src/interface.cpp index 823119953..284368bff 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -458,47 +458,21 @@ static GtkWidget *sp_ui_menu_append_item_from_verb(GtkMenu *menu, Inkscape::Verb item = gtk_separator_menu_item_new(); } else { - unsigned int shortcut; action = verb->get_action(view); if (!action) return NULL; - shortcut = sp_shortcut_get_primary(verb); - if (shortcut!=GDK_KEY_VoidSymbol) { - gchar* c = sp_shortcut_get_label(shortcut); -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *const hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 16); - gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); -#else - GtkWidget *const hb = gtk_hbox_new(FALSE, 16); -#endif - GtkWidget *const name_lbl = gtk_label_new(""); - gtk_label_set_markup_with_mnemonic(GTK_LABEL(name_lbl), action->name); - gtk_misc_set_alignment(reinterpret_cast(name_lbl), 0.0, 0.5); - gtk_box_pack_start(reinterpret_cast(hb), name_lbl, TRUE, TRUE, 0); - GtkWidget *const accel_lbl = gtk_label_new(c); - gtk_misc_set_alignment(reinterpret_cast(accel_lbl), 1.0, 0.5); - gtk_box_pack_end(reinterpret_cast(hb), accel_lbl, FALSE, FALSE, 0); - gtk_widget_show_all(hb); - if (radio) { - item = gtk_radio_menu_item_new (group); - } else { - item = gtk_image_menu_item_new(); - } - gtk_container_add(reinterpret_cast(item), hb); - g_free(c); + if (radio) { + item = gtk_radio_menu_item_new_with_mnemonic(group, action->name); } else { - if (radio) { - item = gtk_radio_menu_item_new (group); - } else { - item = gtk_image_menu_item_new (); - } - GtkWidget *const name_lbl = gtk_label_new(""); - gtk_label_set_markup_with_mnemonic(GTK_LABEL(name_lbl), action->name); - gtk_misc_set_alignment(reinterpret_cast(name_lbl), 0.0, 0.5); - gtk_container_add(reinterpret_cast(item), name_lbl); + item = gtk_image_menu_item_new_with_mnemonic(action->name); } + GtkAccelGroup *accel_group = sp_shortcut_get_accel_group(); + gtk_menu_set_accel_group(menu, accel_group); + + sp_shortcut_add_accelerator(item, sp_shortcut_get_primary(verb)); + action->signal_set_sensitive.connect( sigc::bind<0>( sigc::ptr_fun(>k_widget_set_sensitive), @@ -698,45 +672,16 @@ sp_ui_menu_append_check_item_from_verb(GtkMenu *menu, Inkscape::UI::View::View * { unsigned int shortcut = (verb) ? sp_shortcut_get_primary(verb) : 0; SPAction *action = (verb) ? verb->get_action(view) : 0; - GtkWidget *item = gtk_check_menu_item_new(); - - - if (verb && shortcut!=GDK_KEY_VoidSymbol) { - gchar* c = sp_shortcut_get_label(shortcut); - -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 16); - gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); -#else - GtkWidget *hb = gtk_hbox_new(FALSE, 16); -#endif + GtkWidget *item = gtk_check_menu_item_new_with_mnemonic(action ? action->name : label); - { - GtkWidget *l = gtk_label_new_with_mnemonic(action ? action->name : label); - gtk_misc_set_alignment((GtkMisc *) l, 0.0, 0.5); - gtk_box_pack_start((GtkBox *) hb, l, TRUE, TRUE, 0); - } - - { - GtkWidget *l = gtk_label_new(c); - gtk_misc_set_alignment((GtkMisc *) l, 1.0, 0.5); - gtk_box_pack_end((GtkBox *) hb, l, FALSE, FALSE, 0); - } - - gtk_widget_show_all(hb); - - gtk_container_add((GtkContainer *) item, hb); - g_free(c); - } else { - GtkWidget *l = gtk_label_new_with_mnemonic(action ? action->name : label); - gtk_misc_set_alignment((GtkMisc *) l, 0.0, 0.5); - gtk_container_add((GtkContainer *) item, l); - } #if 0 if (!action->sensitive) { gtk_widget_set_sensitive(item, FALSE); } #endif + + sp_shortcut_add_accelerator(item, shortcut); + gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); @@ -1726,40 +1671,13 @@ void ContextMenu::AppendItemFromVerb(Inkscape::Verb *verb)//, SPDesktop *view)// append(*item); } else { action = verb->get_action(view); - if (!action) - { + if (!action) { return; } - Gtk::ImageMenuItem *item = NULL; - unsigned int shortcut = sp_shortcut_get_primary(verb); - if (shortcut!=GDK_KEY_VoidSymbol) { - gchar* c = sp_shortcut_get_label(shortcut); - Gtk::HBox *const hb = manage(new Gtk::HBox (FALSE, 16)); - Gtk::Label *const name_lbl = manage(new Gtk::Label(action->name, true)); - name_lbl->set_alignment(0.0, 0.5); - hb->pack_start(*name_lbl, TRUE, TRUE, 0); - Gtk::Label *const accel_lbl = manage(new Gtk::Label(c)); - accel_lbl->set_alignment(1.0, 0.5); - hb->pack_end(*accel_lbl, FALSE, FALSE, 0); - hb->show_all(); - // if (radio) { - // item = gtk_radio_menu_item_new (group); - // } else { - item = new Gtk::ImageMenuItem(); - // } - item->add(*hb); - g_free(c); - } else { - // if (radio) { - // item = gtk_radio_menu_item_new (group); - // } else { - item = manage(new Gtk::ImageMenuItem()); - // } - Gtk::Label *const name_lbl = manage(new Gtk::Label(action->name, true)); - name_lbl->set_alignment(0.0, 0.5); - item->add(*name_lbl); - } + Gtk::ImageMenuItem *item = manage(new Gtk::ImageMenuItem(action->name, true)); + + sp_shortcut_add_accelerator(GTK_WIDGET(item->gobj()), sp_shortcut_get_primary(verb)); action->signal_set_sensitive.connect(sigc::mem_fun(*this, &ContextMenu::set_sensitive)); action->signal_set_name.connect(sigc::mem_fun(*item, &ContextMenu::set_name)); diff --git a/src/shortcuts.cpp b/src/shortcuts.cpp index 5af75a9a5..755269edb 100644 --- a/src/shortcuts.cpp +++ b/src/shortcuts.cpp @@ -52,10 +52,12 @@ using Inkscape::IO::Resource::SYSTEM; using Inkscape::IO::Resource::USER; using Inkscape::IO::Resource::KEYS; - static void try_shortcuts_file(char const *filename); static void read_shortcuts_file(char const *filename, bool const is_user_set=false); +unsigned int sp_shortcut_get_key(unsigned int const shortcut); +GdkModifierType sp_shortcut_get_modifiers(unsigned int const shortcut); + /* Returns true if action was performed */ bool @@ -430,7 +432,7 @@ void sp_shortcut_delete_from_file(char const * /*action*/, unsigned int const sh return; } - gchar *key = gdk_keyval_name (shortcut & (~SP_SHORTCUT_MODIFIER_MASK)); + gchar *key = gdk_keyval_name (sp_shortcut_get_key(shortcut)); std::string modifiers = sp_shortcut_to_label(shortcut & (SP_SHORTCUT_MODIFIER_MASK)); if (!key) { @@ -502,7 +504,7 @@ void sp_shortcut_add_to_file(char const *action, unsigned int const shortcut) { } } - gchar *key = gdk_keyval_name (shortcut & (~SP_SHORTCUT_MODIFIER_MASK)); + gchar *key = gdk_keyval_name (sp_shortcut_get_key(shortcut)); std::string modifiers = sp_shortcut_to_label(shortcut & (SP_SHORTCUT_MODIFIER_MASK)); if (!key) { @@ -639,6 +641,58 @@ sp_shortcut_unset(unsigned int const shortcut) } } + +GtkAccelGroup * +sp_shortcut_get_accel_group() +{ + static GtkAccelGroup *accel_group = NULL; + + if (!accel_group) { + accel_group = gtk_accel_group_new (); + } + + return accel_group; +} + +/** + * Adds a gtk accelerator to a widget + * Used to display the keyboard shortcuts in the main menu items + */ +void +sp_shortcut_add_accelerator(GtkWidget *item, unsigned int const shortcut) +{ + if (shortcut == GDK_KEY_VoidSymbol) { + return; + } + + unsigned int accel_key = sp_shortcut_get_key(shortcut); + if (accel_key > 0) { + gtk_widget_add_accelerator (item, + "activate", + sp_shortcut_get_accel_group(), + accel_key, + sp_shortcut_get_modifiers(shortcut), + GTK_ACCEL_VISIBLE); + } +} + + +unsigned int +sp_shortcut_get_key(unsigned int const shortcut) +{ + return (shortcut & (~SP_SHORTCUT_MODIFIER_MASK)); +} + +GdkModifierType +sp_shortcut_get_modifiers(unsigned int const shortcut) +{ + return static_cast( + ((shortcut & SP_SHORTCUT_SHIFT_MASK) ? GDK_SHIFT_MASK : 0) | + ((shortcut & SP_SHORTCUT_CONTROL_MASK) ? GDK_CONTROL_MASK : 0) | + ((shortcut & SP_SHORTCUT_ALT_MASK) ? GDK_MOD1_MASK : 0) + ); +} + /** * Adds a keyboard shortcut for the given verb. * (Removes any existing binding for the given shortcut, including appropriately @@ -706,7 +760,6 @@ bool sp_shortcut_is_user_set(Inkscape::Verb *verb) return result; } - gchar *sp_shortcut_get_label(unsigned int shortcut) { // The comment below was copied from the function sp_ui_shortcut_string in interface.cpp (which was subsequently removed) @@ -721,11 +774,8 @@ gchar *sp_shortcut_get_label(unsigned int shortcut) gchar *result = 0; if (shortcut != GDK_KEY_VoidSymbol) { result = gtk_accelerator_get_label( - shortcut & (~SP_SHORTCUT_MODIFIER_MASK), static_cast( - ((shortcut & SP_SHORTCUT_SHIFT_MASK) ? GDK_SHIFT_MASK : 0) | - ((shortcut & SP_SHORTCUT_CONTROL_MASK) ? GDK_CONTROL_MASK : 0) | - ((shortcut & SP_SHORTCUT_ALT_MASK) ? GDK_MOD1_MASK : 0) - )); + sp_shortcut_get_key(shortcut), + sp_shortcut_get_modifiers(shortcut)); } return result; } diff --git a/src/shortcuts.h b/src/shortcuts.h index 118909bd3..c2a6f6cde 100644 --- a/src/shortcuts.h +++ b/src/shortcuts.h @@ -28,13 +28,14 @@ namespace Inkscape { #define SP_SHORTCUT_ALT_MASK (1 << 26) #define SP_SHORTCUT_MODIFIER_MASK (SP_SHORTCUT_SHIFT_MASK|SP_SHORTCUT_CONTROL_MASK|SP_SHORTCUT_ALT_MASK) + /* Returns true if action was performed */ bool sp_shortcut_invoke (unsigned int shortcut, Inkscape::UI::View::View *view); void sp_shortcut_init(); Inkscape::Verb * sp_shortcut_get_verb (unsigned int shortcut); unsigned int sp_shortcut_get_primary (Inkscape::Verb * verb); // Returns GDK_VoidSymbol if no shortcut is found. -char* sp_shortcut_get_label (unsigned int shortcut); // Returns the human readable form of the shortcut (or NULL), for example Shift+Ctrl+F. Free the returned string with g_free. +gchar* sp_shortcut_get_label (unsigned int shortcut); // Returns the human readable form of the shortcut (or NULL), for example Shift+Ctrl+F. Free the returned string with g_free. void sp_shortcut_set(unsigned int const shortcut, Inkscape::Verb *const verb, bool const is_primary, bool const is_user_set=false); void sp_shortcut_unset(unsigned int const shortcut); void sp_shortcut_add_to_file(char const *action, unsigned int const shortcut); @@ -48,6 +49,8 @@ void sp_shortcut_file_export(); bool sp_shortcut_file_import(); void sp_shortcut_file_import_do(char const *importname); void sp_shortcut_file_export_do(char const *exportname); +GtkAccelGroup *sp_shortcut_get_accel_group(); +void sp_shortcut_add_accelerator(GtkWidget *item, unsigned int const shortcut); #endif -- cgit v1.2.3