| Index: chrome/browser/ui/gtk/gtk_menu_creator.cc
|
| diff --git a/chrome/browser/ui/gtk/gtk_menu_creator.cc b/chrome/browser/ui/gtk/gtk_menu_creator.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..cf8815abea0e61197b3e6ba74d5ce8a1e8090a52
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/gtk/gtk_menu_creator.cc
|
| @@ -0,0 +1,303 @@
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/ui/gtk/gtk_menu_creator.h"
|
| +
|
| +#include <gtk/gtk.h>
|
| +#include <map>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/utf_string_conversions.h"
|
| +#include "chrome/app/chrome_command_ids.h"
|
| +#include "chrome/browser/ui/gtk/accelerators_gtk.h"
|
| +#include "chrome/browser/ui/gtk/gtk_util.h"
|
| +#include "ui/base/models/menu_model.h"
|
| +#include "ui/gfx/gtk_util.h"
|
| +#include "third_party/skia/include/core/SkBitmap.h"
|
| +
|
| +bool GtkMenuCreator::IconSource::AlwaysShowIconForCmd(int command_id) const {
|
| + return false;
|
| +}
|
| +
|
| +GtkWidget* GtkMenuCreator::IconSource::GetImageForCommandId(
|
| + int command_id) const {
|
| + return GetDefaultImageForCommandId(command_id);
|
| +}
|
| +
|
| +GtkIconSet* GtkMenuCreator::IconSource::GetIconSetForId(int idr) {
|
| + return NULL;
|
| +}
|
| +
|
| +GtkWidget* GtkMenuCreator::GetDefaultImageForCommandId(int command_id) {
|
| + const char* stock;
|
| + switch (command_id) {
|
| + case IDC_NEW_TAB:
|
| + case IDC_CONTENT_CONTEXT_OPENIMAGENEWTAB:
|
| + case IDC_CONTENT_CONTEXT_OPENLINKNEWTAB:
|
| + case IDC_CONTENT_CONTEXT_OPENAVNEWTAB:
|
| + stock = GTK_STOCK_NEW;
|
| + break;
|
| +
|
| + case IDC_CLOSE_TAB:
|
| + stock = GTK_STOCK_CLOSE;
|
| + break;
|
| +
|
| + case IDC_CONTENT_CONTEXT_SAVEIMAGEAS:
|
| + case IDC_CONTENT_CONTEXT_SAVEAVAS:
|
| + case IDC_CONTENT_CONTEXT_SAVELINKAS:
|
| + stock = GTK_STOCK_SAVE_AS;
|
| + break;
|
| +
|
| + case IDC_SAVE_PAGE:
|
| + stock = GTK_STOCK_SAVE;
|
| + break;
|
| +
|
| + case IDC_COPY:
|
| + case IDC_COPY_URL:
|
| + case IDC_CONTENT_CONTEXT_COPYIMAGELOCATION:
|
| + case IDC_CONTENT_CONTEXT_COPYLINKLOCATION:
|
| + case IDC_CONTENT_CONTEXT_COPYAVLOCATION:
|
| + case IDC_CONTENT_CONTEXT_COPYEMAILADDRESS:
|
| + case IDC_CONTENT_CONTEXT_COPY:
|
| + stock = GTK_STOCK_COPY;
|
| + break;
|
| +
|
| + case IDC_CUT:
|
| + case IDC_CONTENT_CONTEXT_CUT:
|
| + stock = GTK_STOCK_CUT;
|
| + break;
|
| +
|
| + case IDC_PASTE:
|
| + case IDC_CONTENT_CONTEXT_PASTE:
|
| + stock = GTK_STOCK_PASTE;
|
| + break;
|
| +
|
| + case IDC_CONTENT_CONTEXT_DELETE:
|
| + case IDC_BOOKMARK_BAR_REMOVE:
|
| + stock = GTK_STOCK_DELETE;
|
| + break;
|
| +
|
| + case IDC_CONTENT_CONTEXT_UNDO:
|
| + stock = GTK_STOCK_UNDO;
|
| + break;
|
| +
|
| + case IDC_CONTENT_CONTEXT_REDO:
|
| + stock = GTK_STOCK_REDO;
|
| + break;
|
| +
|
| + case IDC_SEARCH:
|
| + case IDC_FIND:
|
| + case IDC_CONTENT_CONTEXT_SEARCHWEBFOR:
|
| + stock = GTK_STOCK_FIND;
|
| + break;
|
| +
|
| + case IDC_CONTENT_CONTEXT_SELECTALL:
|
| + stock = GTK_STOCK_SELECT_ALL;
|
| + break;
|
| +
|
| + case IDC_CLEAR_BROWSING_DATA:
|
| + stock = GTK_STOCK_CLEAR;
|
| + break;
|
| +
|
| + case IDC_BACK:
|
| + stock = GTK_STOCK_GO_BACK;
|
| + break;
|
| +
|
| + case IDC_RELOAD:
|
| + stock = GTK_STOCK_REFRESH;
|
| + break;
|
| +
|
| + case IDC_FORWARD:
|
| + stock = GTK_STOCK_GO_FORWARD;
|
| + break;
|
| +
|
| + case IDC_PRINT:
|
| + stock = GTK_STOCK_PRINT;
|
| + break;
|
| +
|
| + case IDC_CONTENT_CONTEXT_VIEWPAGEINFO:
|
| + stock = GTK_STOCK_INFO;
|
| + break;
|
| +
|
| + case IDC_SPELLCHECK_MENU:
|
| + stock = GTK_STOCK_SPELL_CHECK;
|
| + break;
|
| +
|
| + case IDC_RESTORE_TAB:
|
| + stock = GTK_STOCK_UNDELETE;
|
| + break;
|
| +
|
| + case IDC_HOME:
|
| + stock = GTK_STOCK_HOME;
|
| + break;
|
| +
|
| + case IDC_STOP:
|
| + stock = GTK_STOCK_STOP;
|
| + break;
|
| +
|
| + case IDC_ABOUT:
|
| + stock = GTK_STOCK_ABOUT;
|
| + break;
|
| +
|
| + case IDC_EXIT:
|
| + stock = GTK_STOCK_QUIT;
|
| + break;
|
| +
|
| + case IDC_HELP_PAGE:
|
| + stock = GTK_STOCK_HELP;
|
| + break;
|
| +
|
| + case IDC_OPTIONS:
|
| + stock = GTK_STOCK_PREFERENCES;
|
| + break;
|
| +
|
| + case IDC_CONTENT_CONTEXT_GOTOURL:
|
| + stock = GTK_STOCK_JUMP_TO;
|
| + break;
|
| +
|
| + case IDC_DEV_TOOLS_INSPECT:
|
| + case IDC_CONTENT_CONTEXT_INSPECTELEMENT:
|
| + stock = GTK_STOCK_PROPERTIES;
|
| + break;
|
| +
|
| + case IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK:
|
| + stock = GTK_STOCK_ADD;
|
| + break;
|
| +
|
| + case IDC_BOOKMARK_BAR_RENAME_FOLDER:
|
| + case IDC_BOOKMARK_BAR_EDIT:
|
| + stock = GTK_STOCK_EDIT;
|
| + break;
|
| +
|
| + case IDC_BOOKMARK_BAR_NEW_FOLDER:
|
| + stock = GTK_STOCK_DIRECTORY;
|
| + break;
|
| +
|
| + case IDC_BOOKMARK_BAR_OPEN_ALL:
|
| + stock = GTK_STOCK_OPEN;
|
| + break;
|
| +
|
| + default:
|
| + stock = NULL;
|
| + }
|
| +
|
| + return stock ? gtk_image_new_from_stock(stock, GTK_ICON_SIZE_MENU) : NULL;
|
| +}
|
| +
|
| +GtkMenuCreator::GtkMenuCreator(IconSource* icon_source)
|
| + : icon_source_(icon_source),
|
| + dummy_accel_group_(gtk_accel_group_new()) {
|
| +}
|
| +
|
| +GtkMenuCreator::~GtkMenuCreator() {
|
| + g_object_unref(dummy_accel_group_);
|
| +}
|
| +
|
| +void GtkMenuCreator::BuildSubmenuFromModel(ui::MenuModel* model,
|
| + GtkWidget* menu) {
|
| + std::map<int, GtkWidget*> radio_groups;
|
| + GtkWidget* menu_item = NULL;
|
| + for (int i = 0; i < model->GetItemCount(); ++i) {
|
| + SkBitmap icon;
|
| + std::string label =
|
| + gfx::ConvertAcceleratorsFromWindowsStyle(
|
| + UTF16ToUTF8(model->GetLabelAt(i)));
|
| +
|
| + switch (model->GetTypeAt(i)) {
|
| + case ui::MenuModel::TYPE_SEPARATOR:
|
| + menu_item = gtk_separator_menu_item_new();
|
| + break;
|
| +
|
| + case ui::MenuModel::TYPE_CHECK:
|
| + menu_item = gtk_check_menu_item_new_with_mnemonic(label.c_str());
|
| + break;
|
| +
|
| + case ui::MenuModel::TYPE_RADIO: {
|
| + std::map<int, GtkWidget*>::iterator iter =
|
| + radio_groups.find(model->GetGroupIdAt(i));
|
| +
|
| + if (iter == radio_groups.end()) {
|
| + menu_item = gtk_radio_menu_item_new_with_mnemonic(
|
| + NULL, label.c_str());
|
| + radio_groups[model->GetGroupIdAt(i)] = menu_item;
|
| + } else {
|
| + menu_item = gtk_radio_menu_item_new_with_mnemonic_from_widget(
|
| + GTK_RADIO_MENU_ITEM(iter->second), label.c_str());
|
| + }
|
| + break;
|
| + }
|
| + case ui::MenuModel::TYPE_BUTTON_ITEM: {
|
| + ui::ButtonMenuItemModel* button_menu_item_model =
|
| + model->GetButtonMenuItemAt(i);
|
| + menu_item = BuildButtonMenuItem(button_menu_item_model, menu);
|
| + if (!menu_item)
|
| + continue;
|
| + break;
|
| + }
|
| + case ui::MenuModel::TYPE_SUBMENU:
|
| + case ui::MenuModel::TYPE_COMMAND: {
|
| + int command_id = model->GetCommandIdAt(i);
|
| + if (model->GetIconAt(i, &icon))
|
| + menu_item = BuildMenuItemWithImage(label, icon);
|
| + else
|
| + menu_item = BuildMenuItemWithLabel(label, command_id);
|
| + if (icon_source_ && icon_source_->AlwaysShowIconForCmd(command_id) &&
|
| + GTK_IS_IMAGE_MENU_ITEM(menu_item))
|
| + gtk_util::SetAlwaysShowImage(menu_item);
|
| + break;
|
| + }
|
| +
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| +
|
| + if (model->GetTypeAt(i) == ui::MenuModel::TYPE_SUBMENU) {
|
| + GtkWidget* submenu = gtk_menu_new();
|
| + BuildSubmenuFromModel(model->GetSubmenuModelAt(i), submenu);
|
| + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu);
|
| + }
|
| +
|
| + ui::AcceleratorGtk accelerator;
|
| + if (model->GetAcceleratorAt(i, &accelerator)) {
|
| + gtk_widget_add_accelerator(menu_item,
|
| + "activate",
|
| + dummy_accel_group_,
|
| + accelerator.GetGdkKeyCode(),
|
| + accelerator.gdk_modifier_type(),
|
| + GTK_ACCEL_VISIBLE);
|
| + }
|
| +
|
| + g_object_set_data(G_OBJECT(menu_item), "model", model);
|
| + AppendMenuItemToMenu(i, model, menu_item, menu);
|
| + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
|
| +
|
| + menu_item = NULL;
|
| + }
|
| +}
|
| +
|
| +GtkWidget* GtkMenuCreator::BuildMenuItemWithImage(const std::string& label,
|
| + GtkWidget* image) const {
|
| + GtkWidget* menu_item =
|
| + gtk_image_menu_item_new_with_mnemonic(label.c_str());
|
| + gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), image);
|
| + return menu_item;
|
| +}
|
| +
|
| +GtkWidget* GtkMenuCreator::BuildMenuItemWithImage(const std::string& label,
|
| + const SkBitmap& icon) const {
|
| + GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&icon);
|
| + GtkWidget* menu_item = BuildMenuItemWithImage(
|
| + label, gtk_image_new_from_pixbuf(pixbuf));
|
| + g_object_unref(pixbuf);
|
| + return menu_item;
|
| +}
|
| +
|
| +GtkWidget* GtkMenuCreator::BuildMenuItemWithLabel(const std::string& label,
|
| + int command_id) const {
|
| + GtkWidget* img =
|
| + icon_source_ ? icon_source_->GetImageForCommandId(command_id) :
|
| + GtkMenuCreator::GetDefaultImageForCommandId(command_id);
|
| + return img ? BuildMenuItemWithImage(label, img) :
|
| + gtk_menu_item_new_with_mnemonic(label.c_str());
|
| +}
|
|
|