diff options
author | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-21 01:18:18 +0000 |
---|---|---|
committer | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-21 01:18:18 +0000 |
commit | 2d8bfca747e386fd929c57e014e227b148ac2142 (patch) | |
tree | 16f10c8b5cd98f97555c34644665e9cbb217ccd3 /chrome/browser/gtk | |
parent | 296bdc35c3dc39002707388f834e1f93c0242fe6 (diff) | |
download | chromium_src-2d8bfca747e386fd929c57e014e227b148ac2142.zip chromium_src-2d8bfca747e386fd929c57e014e227b148ac2142.tar.gz chromium_src-2d8bfca747e386fd929c57e014e227b148ac2142.tar.bz2 |
linux: implement encodings menu
BUG=11599
Review URL: http://codereview.chromium.org/155830
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21140 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/gtk')
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.cc | 47 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_toolbar_gtk.h | 1 | ||||
-rw-r--r-- | chrome/browser/gtk/menu_gtk.cc | 79 | ||||
-rw-r--r-- | chrome/browser/gtk/menu_gtk.h | 12 | ||||
-rw-r--r-- | chrome/browser/gtk/standard_menus.cc | 23 | ||||
-rw-r--r-- | chrome/browser/gtk/standard_menus.h | 7 |
6 files changed, 105 insertions, 64 deletions
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc index 5c4a364..b49c860 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_toolbar_gtk.cc @@ -15,6 +15,7 @@ #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_theme_provider.h" +#include "chrome/browser/encoding_menu_controller.h" #include "chrome/browser/gtk/back_forward_button_gtk.h" #include "chrome/browser/gtk/browser_window_gtk.h" #include "chrome/browser/gtk/custom_button.h" @@ -29,6 +30,7 @@ #include "chrome/browser/gtk/toolbar_star_toggle_gtk.h" #include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/profile.h" +#include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/gtk_util.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_service.h" @@ -94,6 +96,33 @@ BrowserToolbarGtk::~BrowserToolbarGtk() { g_object_unref(accel_group_); } +// Construct an "encodings" menu based on profile settings. +static MenuGtk* BuildEncodingsMenu(Profile* profile, + MenuGtk::Delegate* delegate) { + EncodingMenuController controller; + EncodingMenuController::EncodingMenuItemList items; + controller.GetEncodingMenuItems(profile, &items); + + MenuGtk* menu = new MenuGtk(delegate, false); + GSList* radio_group = NULL; + for (EncodingMenuController::EncodingMenuItemList::const_iterator i = + items.begin(); + i != items.end(); ++i) { + if (i == items.begin()) { + menu->AppendCheckMenuItemWithLabel(i->first, WideToUTF8(i->second)); + } else if (i->first == 0) { + menu->AppendSeparator(); + } else { + GtkWidget* item = + gtk_radio_menu_item_new_with_label(radio_group, + WideToUTF8(i->second).c_str()); + radio_group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(item)); + menu->AppendMenuItem(i->first, item); + } + } + return menu; +} + void BrowserToolbarGtk::Init(Profile* profile, GtkWindow* top_level_window) { // Make sure to tell the location bar the profile before calling its Init. @@ -168,7 +197,10 @@ void BrowserToolbarGtk::Init(Profile* profile, page_menu_image_ = gtk_image_new_from_pixbuf( theme_provider_->GetRTLEnabledPixbufNamed(IDR_MENU_PAGE)); gtk_container_add(GTK_CONTAINER(page_menu), page_menu_image_); - page_menu_.reset(new MenuGtk(this, GetStandardPageMenu(), accel_group_)); + + encodings_menu_.reset(BuildEncodingsMenu(profile, this)); + page_menu_.reset(new MenuGtk(this, GetStandardPageMenu(encodings_menu_.get()), + accel_group_)); g_signal_connect(page_menu_->widget(), "motion-notify-event", G_CALLBACK(OnPageAppMenuMouseMotion), this); g_signal_connect(page_menu_->widget(), "move-current", @@ -254,9 +286,18 @@ bool BrowserToolbarGtk::IsCommandEnabled(int command_id) const { bool BrowserToolbarGtk::IsItemChecked(int id) const { if (!profile_) return false; - if (id == IDC_SHOW_BOOKMARK_BAR) + + EncodingMenuController controller; + if (id == IDC_SHOW_BOOKMARK_BAR) { return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar); - // TODO(port): Fix this when we get some items that want checking! + } else if (controller.DoesCommandBelongToEncodingMenu(id)) { + TabContents* tab_contents = browser_->GetSelectedTabContents(); + if (tab_contents) { + return controller.IsItemChecked(profile_, tab_contents->encoding(), + id); + } + } + return false; } diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h index 37a2c3f..90f270d 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.h +++ b/chrome/browser/gtk/browser_toolbar_gtk.h @@ -189,6 +189,7 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, scoped_ptr<MenuGtk> page_menu_; scoped_ptr<MenuGtk> app_menu_; + scoped_ptr<MenuGtk> encodings_menu_; Browser* browser_; BrowserWindowGtk* window_; diff --git a/chrome/browser/gtk/menu_gtk.cc b/chrome/browser/gtk/menu_gtk.cc index d1c66d8..9826110 100644 --- a/chrome/browser/gtk/menu_gtk.cc +++ b/chrome/browser/gtk/menu_gtk.cc @@ -50,14 +50,14 @@ void MenuGtk::AppendMenuItemWithLabel(int command_id, std::string converted_label = ConvertAcceleratorsFromWindowsStyle(label); GtkWidget* menu_item = gtk_menu_item_new_with_mnemonic(converted_label.c_str()); - AddMenuItemWithId(menu_item, command_id); + AppendMenuItem(command_id, menu_item); } void MenuGtk::AppendMenuItemWithIcon(int command_id, const std::string& label, const SkBitmap& icon) { GtkWidget* menu_item = BuildMenuItemWithImage(label, icon); - AddMenuItemWithId(menu_item, command_id); + AppendMenuItem(command_id, menu_item); } void MenuGtk::AppendCheckMenuItemWithLabel(int command_id, @@ -65,7 +65,7 @@ void MenuGtk::AppendCheckMenuItemWithLabel(int command_id, std::string converted_label = ConvertAcceleratorsFromWindowsStyle(label); GtkWidget* menu_item = gtk_check_menu_item_new_with_mnemonic(converted_label.c_str()); - AddMenuItemWithId(menu_item, command_id); + AppendMenuItem(command_id, menu_item); } void MenuGtk::AppendSeparator() { @@ -74,6 +74,17 @@ void MenuGtk::AppendSeparator() { gtk_menu_shell_append(GTK_MENU_SHELL(menu_.get()), menu_item); } +void MenuGtk::AppendMenuItem(int command_id, GtkWidget* menu_item) { + g_object_set_data(G_OBJECT(menu_item), "menu-id", + reinterpret_cast<void*>(command_id)); + + g_signal_connect(G_OBJECT(menu_item), "activate", + G_CALLBACK(OnMenuItemActivated), this); + + gtk_widget_show(menu_item); + gtk_menu_shell_append(GTK_MENU_SHELL(menu_.get()), menu_item); +} + void MenuGtk::Popup(GtkWidget* widget, GdkEvent* event) { DCHECK(event->type == GDK_BUTTON_PRESS) << "Non-button press event sent to RunMenuAt"; @@ -147,6 +158,9 @@ void MenuGtk::BuildMenuIn(GtkWidget* menu, GtkWidget* submenu = gtk_menu_new(); BuildMenuIn(submenu, menu_data->submenu, accel_group); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu); + } else if (menu_data->custom_submenu) { + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), + menu_data->custom_submenu->menu_.get()); } if (accel_group && menu_data->accel_key) { @@ -202,21 +216,10 @@ void MenuGtk::BuildMenuFromDelegate() { menu_item = gtk_menu_item_new_with_label(delegate_->GetLabel(i).c_str()); } - AddMenuItemWithId(menu_item, i); + AppendMenuItem(i, menu_item); } } -void MenuGtk::AddMenuItemWithId(GtkWidget* menu_item, int id) { - g_object_set_data(G_OBJECT(menu_item), "menu-id", - reinterpret_cast<void*>(id)); - - g_signal_connect(G_OBJECT(menu_item), "activate", - G_CALLBACK(OnMenuItemActivatedById), this); - - gtk_widget_show(menu_item); - gtk_menu_shell_append(GTK_MENU_SHELL(menu_.get()), menu_item); -} - // static void MenuGtk::OnMenuItemActivated(GtkMenuItem* menuitem, MenuGtk* menu) { // We receive activation messages when highlighting a menu that has a @@ -225,19 +228,15 @@ void MenuGtk::OnMenuItemActivated(GtkMenuItem* menuitem, MenuGtk* menu) { const MenuCreateMaterial* data = reinterpret_cast<const MenuCreateMaterial*>( g_object_get_data(G_OBJECT(menuitem), "menu-data")); - // The menu item can still be activated by hotkeys even if it is disabled. - if (menu->delegate_->IsCommandEnabled(data->id)) - menu->delegate_->ExecuteCommand(data->id); - } -} -// static -void MenuGtk::OnMenuItemActivatedById(GtkMenuItem* menuitem, MenuGtk* menu) { - // We receive activation messages when highlighting a menu that has a - // submenu. Ignore them. - if (!gtk_menu_item_get_submenu(menuitem)) { - int id = reinterpret_cast<int>( - g_object_get_data(G_OBJECT(menuitem), "menu-id")); + int id; + if (data) { + id = data->id; + } else { + id = reinterpret_cast<int>(g_object_get_data(G_OBJECT(menuitem), + "menu-id")); + } + // The menu item can still be activated by hotkeys even if it is disabled. if (menu->delegate_->IsCommandEnabled(id)) menu->delegate_->ExecuteCommand(id); @@ -319,26 +318,22 @@ void MenuGtk::SetMenuItemInfo(GtkWidget* widget, gpointer userdata) { // gtk_check_menu_item_set_active() will send the activate signal. Touching // the underlying "active" property will also call the "activate" handler - // for this menu item. So we prevent the correct activate handler from + // for this menu item. So we prevent the "activate" handler from // being called while we set the checkbox. - if (data) { - g_signal_handlers_block_by_func( - item, reinterpret_cast<void*>(OnMenuItemActivated), userdata); - } else { - g_signal_handlers_block_by_func( - item, reinterpret_cast<void*>(OnMenuItemActivatedById), userdata); - } + g_signal_handlers_block_matched( + item, G_SIGNAL_MATCH_FUNC, + 0, 0, NULL, + reinterpret_cast<void*>(OnMenuItemActivated), + NULL); gtk_check_menu_item_set_active( item, menu->delegate_->IsItemChecked(id)); - if (data) { - g_signal_handlers_unblock_by_func( - item, reinterpret_cast<void*>(OnMenuItemActivated), userdata); - } else { - g_signal_handlers_unblock_by_func( - item, reinterpret_cast<void*>(OnMenuItemActivatedById), userdata); - } + g_signal_handlers_unblock_matched( + item, G_SIGNAL_MATCH_FUNC, + 0, 0, NULL, + reinterpret_cast<void*>(OnMenuItemActivated), + NULL); } if (GTK_IS_MENU_ITEM(widget)) { diff --git a/chrome/browser/gtk/menu_gtk.h b/chrome/browser/gtk/menu_gtk.h index 2249e3d..501d80f 100644 --- a/chrome/browser/gtk/menu_gtk.h +++ b/chrome/browser/gtk/menu_gtk.h @@ -62,6 +62,7 @@ class MenuGtk { const SkBitmap& icon); void AppendCheckMenuItemWithLabel(int command_id, const std::string& label); void AppendSeparator(); + void AppendMenuItem(int command_id, GtkWidget* menu_item); // Displays the menu. |timestamp| is the time of activation. The popup is // statically positioned at |widget|. @@ -109,18 +110,9 @@ class MenuGtk { // recursive and does not support sub-menus. void BuildMenuFromDelegate(); - // Helper method that sets properties on a GtkMenuItem and then adds it to - // our internal |menu_|. - void AddMenuItemWithId(GtkWidget* menu_item, int id); - - // Callback for when a menu item is clicked. Used when the menu is created - // via a MenuCreateMaterial. + // Callback for when a menu item is clicked. static void OnMenuItemActivated(GtkMenuItem* menuitem, MenuGtk* menu); - // Callback for when a menu item is clicked. Used when the menu is created - // via |delegate_|. - static void OnMenuItemActivatedById(GtkMenuItem* menuitem, MenuGtk* menu); - // Sets the check mark and enabled/disabled state on our menu items. static void SetMenuItemInfo(GtkWidget* widget, void* raw_menu); diff --git a/chrome/browser/gtk/standard_menus.cc b/chrome/browser/gtk/standard_menus.cc index d557f0a..6d60c2d 100644 --- a/chrome/browser/gtk/standard_menus.cc +++ b/chrome/browser/gtk/standard_menus.cc @@ -10,6 +10,7 @@ #include "app/l10n_util.h" #include "base/basictypes.h" #include "chrome/app/chrome_dll_resource.h" +#include "chrome/browser/encoding_menu_controller.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" @@ -25,11 +26,6 @@ struct MenuCreateMaterial zoom_menu_materials[] = { { MENU_END } }; -struct MenuCreateMaterial encoding_menu_materials[] = { - { MENU_CHECKBOX, IDC_ENCODING_AUTO_DETECT, IDS_ENCODING_AUTO_DETECT }, - { MENU_END } -}; - struct MenuCreateMaterial developer_menu_materials[] = { { MENU_NORMAL, IDC_VIEW_SOURCE, IDS_VIEW_SOURCE, 0, NULL, GDK_u, GDK_CONTROL_MASK }, @@ -60,8 +56,8 @@ struct MenuCreateMaterial standard_page_menu_materials[] = { //{ MENU_NORMAL, IDC_PRINT, IDS_PRINT, 0, NULL, GDK_p, GDK_CONTROL_MASK }, { MENU_SEPARATOR }, { MENU_NORMAL, IDC_ZOOM_MENU, IDS_ZOOM_MENU, 0, zoom_menu_materials }, - { MENU_NORMAL, IDC_ENCODING_MENU, IDS_ENCODING_MENU, 0, - encoding_menu_materials }, + // The encoding menu submenu is filled in by code below. + { MENU_NORMAL, IDC_ENCODING_MENU, IDS_ENCODING_MENU }, { MENU_SEPARATOR }, { MENU_NORMAL, IDC_DEVELOPER_MENU, IDS_DEVELOPER_MENU, 0, developer_menu_materials }, @@ -105,9 +101,20 @@ struct MenuCreateMaterial standard_app_menu_materials[] = { { MENU_NORMAL, IDC_EXIT, IDS_EXIT, 0, NULL, GDK_q, GDK_CONTROL_MASK }, { MENU_END } }; + } // namespace -const MenuCreateMaterial* GetStandardPageMenu() { + +const MenuCreateMaterial* GetStandardPageMenu(MenuGtk* encodings_menu) { + // Find the encoding menu and attach this menu. + for (MenuCreateMaterial* entry = standard_page_menu_materials; + entry->type != MENU_END; ++entry) { + if (entry->id == IDC_ENCODING_MENU) { + entry->custom_submenu = encodings_menu; + break; + } + } + return standard_page_menu_materials; } diff --git a/chrome/browser/gtk/standard_menus.h b/chrome/browser/gtk/standard_menus.h index e9ea047..c9298c3 100644 --- a/chrome/browser/gtk/standard_menus.h +++ b/chrome/browser/gtk/standard_menus.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_GTK_STANDARD_MENUS_H_ class Menu; +class MenuGtk; class Profile; enum MenuItemType { @@ -46,10 +47,14 @@ struct MenuCreateMaterial { // the same key combination may be handled by GTK. Windows handles this in // toolbar_view.cc::GetAcceleratorInfo(). bool only_show; + + // If non-NULL, specifies a custom submenu to be used. + // The menu lifetime must at least match this menu's lifetime. + MenuGtk* custom_submenu; }; // Returns the menu construction data structure for the page menu. -const MenuCreateMaterial* GetStandardPageMenu(); +const MenuCreateMaterial* GetStandardPageMenu(MenuGtk* encodings_menu); // Returns the menu construction data structure for the app menu. const MenuCreateMaterial* GetStandardAppMenu(); |