summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk
diff options
context:
space:
mode:
authorevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-21 01:18:18 +0000
committerevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-21 01:18:18 +0000
commit2d8bfca747e386fd929c57e014e227b148ac2142 (patch)
tree16f10c8b5cd98f97555c34644665e9cbb217ccd3 /chrome/browser/gtk
parent296bdc35c3dc39002707388f834e1f93c0242fe6 (diff)
downloadchromium_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.cc47
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.h1
-rw-r--r--chrome/browser/gtk/menu_gtk.cc79
-rw-r--r--chrome/browser/gtk/menu_gtk.h12
-rw-r--r--chrome/browser/gtk/standard_menus.cc23
-rw-r--r--chrome/browser/gtk/standard_menus.h7
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();