| Index: chrome/browser/ui/gtk/bookmarks/bookmark_menu_controller_gtk.cc
|
| diff --git a/chrome/browser/ui/gtk/bookmarks/bookmark_menu_controller_gtk.cc b/chrome/browser/ui/gtk/bookmarks/bookmark_menu_controller_gtk.cc
|
| deleted file mode 100644
|
| index c649fdf0c68958f94d86c50f9d52daf803436ec5..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/ui/gtk/bookmarks/bookmark_menu_controller_gtk.cc
|
| +++ /dev/null
|
| @@ -1,378 +0,0 @@
|
| -// Copyright (c) 2012 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/bookmarks/bookmark_menu_controller_gtk.h"
|
| -
|
| -#include <gtk/gtk.h>
|
| -
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "chrome/browser/bookmarks/bookmark_model.h"
|
| -#include "chrome/browser/bookmarks/bookmark_model_factory.h"
|
| -#include "chrome/browser/bookmarks/bookmark_stats.h"
|
| -#include "chrome/browser/bookmarks/bookmark_utils.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/ui/bookmarks/bookmark_utils.h"
|
| -#include "chrome/browser/ui/browser.h"
|
| -#include "chrome/browser/ui/gtk/bookmarks/bookmark_utils_gtk.h"
|
| -#include "chrome/browser/ui/gtk/event_utils.h"
|
| -#include "chrome/browser/ui/gtk/gtk_chrome_button.h"
|
| -#include "chrome/browser/ui/gtk/gtk_theme_service.h"
|
| -#include "chrome/browser/ui/gtk/gtk_util.h"
|
| -#include "chrome/browser/ui/gtk/menu_gtk.h"
|
| -#include "content/public/browser/page_navigator.h"
|
| -#include "grit/generated_resources.h"
|
| -#include "grit/theme_resources.h"
|
| -#include "grit/ui_resources.h"
|
| -#include "ui/base/dragdrop/gtk_dnd_util.h"
|
| -#include "ui/base/l10n/l10n_util.h"
|
| -#include "ui/base/window_open_disposition.h"
|
| -#include "ui/gfx/gtk_util.h"
|
| -
|
| -using content::OpenURLParams;
|
| -using content::PageNavigator;
|
| -
|
| -namespace {
|
| -
|
| -void SetImageMenuItem(GtkWidget* menu_item,
|
| - const BookmarkNode* node,
|
| - BookmarkModel* model) {
|
| - GdkPixbuf* pixbuf = GetPixbufForNode(node, model, true);
|
| - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item),
|
| - gtk_image_new_from_pixbuf(pixbuf));
|
| - g_object_unref(pixbuf);
|
| -}
|
| -
|
| -const BookmarkNode* GetNodeFromMenuItem(GtkWidget* menu_item) {
|
| - return static_cast<const BookmarkNode*>(
|
| - g_object_get_data(G_OBJECT(menu_item), "bookmark-node"));
|
| -}
|
| -
|
| -const BookmarkNode* GetParentNodeFromEmptyMenu(GtkWidget* menu) {
|
| - return static_cast<const BookmarkNode*>(
|
| - g_object_get_data(G_OBJECT(menu), "parent-node"));
|
| -}
|
| -
|
| -void* AsVoid(const BookmarkNode* node) {
|
| - return const_cast<BookmarkNode*>(node);
|
| -}
|
| -
|
| -// The context menu has been dismissed, restore the X and application grabs
|
| -// to whichever menu last had them. (Assuming that menu is still showing.)
|
| -void OnContextMenuHide(GtkWidget* context_menu, GtkWidget* grab_menu) {
|
| - gtk_util::GrabAllInput(grab_menu);
|
| -
|
| - // Match the ref we took when connecting this signal.
|
| - g_object_unref(grab_menu);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -BookmarkMenuController::BookmarkMenuController(Browser* browser,
|
| - PageNavigator* navigator,
|
| - GtkWindow* window,
|
| - const BookmarkNode* node,
|
| - int start_child_index)
|
| - : browser_(browser),
|
| - page_navigator_(navigator),
|
| - parent_window_(window),
|
| - model_(BookmarkModelFactory::GetForProfile(browser->profile())),
|
| - node_(node),
|
| - drag_icon_(NULL),
|
| - ignore_button_release_(false),
|
| - triggering_widget_(NULL) {
|
| - menu_ = gtk_menu_new();
|
| - g_object_ref_sink(menu_);
|
| - BuildMenu(node, start_child_index, menu_);
|
| - signals_.Connect(menu_, "hide", G_CALLBACK(OnMenuHiddenThunk), this);
|
| - gtk_widget_show_all(menu_);
|
| -}
|
| -
|
| -BookmarkMenuController::~BookmarkMenuController() {
|
| - model_->RemoveObserver(this);
|
| - // Make sure the hide handler runs.
|
| - gtk_widget_hide(menu_);
|
| - gtk_widget_destroy(menu_);
|
| - g_object_unref(menu_);
|
| -}
|
| -
|
| -void BookmarkMenuController::Popup(GtkWidget* widget, gint button_type,
|
| - guint32 timestamp) {
|
| - model_->AddObserver(this);
|
| -
|
| - triggering_widget_ = widget;
|
| - signals_.Connect(triggering_widget_, "destroy",
|
| - G_CALLBACK(gtk_widget_destroyed), &triggering_widget_);
|
| - gtk_chrome_button_set_paint_state(GTK_CHROME_BUTTON(widget),
|
| - GTK_STATE_ACTIVE);
|
| - gtk_menu_popup(GTK_MENU(menu_), NULL, NULL,
|
| - &MenuGtk::WidgetMenuPositionFunc,
|
| - widget, button_type, timestamp);
|
| -}
|
| -
|
| -void BookmarkMenuController::BookmarkModelChanged() {
|
| - gtk_menu_popdown(GTK_MENU(menu_));
|
| -}
|
| -
|
| -void BookmarkMenuController::BookmarkNodeFaviconChanged(
|
| - BookmarkModel* model, const BookmarkNode* node) {
|
| - std::map<const BookmarkNode*, GtkWidget*>::iterator it =
|
| - node_to_menu_widget_map_.find(node);
|
| - if (it != node_to_menu_widget_map_.end())
|
| - SetImageMenuItem(it->second, node, model);
|
| -}
|
| -
|
| -void BookmarkMenuController::WillExecuteCommand(
|
| - int command_id,
|
| - const std::vector<const BookmarkNode*>& bookmarks) {
|
| - gtk_menu_popdown(GTK_MENU(menu_));
|
| -}
|
| -
|
| -void BookmarkMenuController::CloseMenu() {
|
| - context_menu_->Cancel();
|
| -}
|
| -
|
| -void BookmarkMenuController::NavigateToMenuItem(
|
| - GtkWidget* menu_item,
|
| - WindowOpenDisposition disposition) {
|
| - const BookmarkNode* node = GetNodeFromMenuItem(menu_item);
|
| - DCHECK(node);
|
| - DCHECK(page_navigator_);
|
| - RecordBookmarkLaunch(node, BOOKMARK_LAUNCH_LOCATION_BAR_SUBFOLDER);
|
| - page_navigator_->OpenURL(OpenURLParams(
|
| - node->url(), content::Referrer(), disposition,
|
| - content::PAGE_TRANSITION_AUTO_BOOKMARK, false));
|
| -}
|
| -
|
| -void BookmarkMenuController::BuildMenu(const BookmarkNode* parent,
|
| - int start_child_index,
|
| - GtkWidget* menu) {
|
| - DCHECK(parent->empty() || start_child_index < parent->child_count());
|
| -
|
| - signals_.Connect(menu, "button-press-event",
|
| - G_CALLBACK(OnMenuButtonPressedOrReleasedThunk), this);
|
| - signals_.Connect(menu, "button-release-event",
|
| - G_CALLBACK(OnMenuButtonPressedOrReleasedThunk), this);
|
| -
|
| - for (int i = start_child_index; i < parent->child_count(); ++i) {
|
| - const BookmarkNode* node = parent->GetChild(i);
|
| -
|
| - GtkWidget* menu_item =
|
| - gtk_image_menu_item_new_with_label(BuildMenuLabelFor(node).c_str());
|
| - g_object_set_data(G_OBJECT(menu_item), "bookmark-node", AsVoid(node));
|
| - SetImageMenuItem(menu_item, node, model_);
|
| - gtk_util::SetAlwaysShowImage(menu_item);
|
| -
|
| - signals_.Connect(menu_item, "button-release-event",
|
| - G_CALLBACK(OnButtonReleasedThunk), this);
|
| - if (node->is_url()) {
|
| - signals_.Connect(menu_item, "activate",
|
| - G_CALLBACK(OnMenuItemActivatedThunk), this);
|
| - } else if (node->is_folder()) {
|
| - GtkWidget* submenu = gtk_menu_new();
|
| - BuildMenu(node, 0, submenu);
|
| - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu);
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| -
|
| - gtk_drag_source_set(menu_item, GDK_BUTTON1_MASK, NULL, 0,
|
| - static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_LINK));
|
| - int target_mask = ui::CHROME_BOOKMARK_ITEM;
|
| - if (node->is_url())
|
| - target_mask |= ui::TEXT_URI_LIST | ui::NETSCAPE_URL;
|
| - ui::SetSourceTargetListFromCodeMask(menu_item, target_mask);
|
| - signals_.Connect(menu_item, "drag-begin",
|
| - G_CALLBACK(OnMenuItemDragBeginThunk), this);
|
| - signals_.Connect(menu_item, "drag-end",
|
| - G_CALLBACK(OnMenuItemDragEndThunk), this);
|
| - signals_.Connect(menu_item, "drag-data-get",
|
| - G_CALLBACK(OnMenuItemDragGetThunk), this);
|
| -
|
| - // It is important to connect to this signal after setting up the drag
|
| - // source because we only want to stifle the menu's default handler and
|
| - // not the handler that the drag source uses.
|
| - if (node->is_folder()) {
|
| - signals_.Connect(menu_item, "button-press-event",
|
| - G_CALLBACK(OnFolderButtonPressedThunk), this);
|
| - }
|
| -
|
| - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
|
| - node_to_menu_widget_map_[node] = menu_item;
|
| - }
|
| -
|
| - if (parent->empty()) {
|
| - GtkWidget* empty_menu = gtk_menu_item_new_with_label(
|
| - l10n_util::GetStringUTF8(IDS_MENU_EMPTY_SUBMENU).c_str());
|
| - gtk_widget_set_sensitive(empty_menu, FALSE);
|
| - g_object_set_data(G_OBJECT(menu), "parent-node", AsVoid(parent));
|
| - gtk_menu_shell_append(GTK_MENU_SHELL(menu), empty_menu);
|
| - }
|
| -}
|
| -
|
| -gboolean BookmarkMenuController::OnMenuButtonPressedOrReleased(
|
| - GtkWidget* sender,
|
| - GdkEventButton* event) {
|
| - // Handle middle mouse downs and right mouse ups.
|
| - if (!((event->button == 2 && event->type == GDK_BUTTON_RELEASE) ||
|
| - (event->button == 3 && event->type == GDK_BUTTON_PRESS))) {
|
| - return FALSE;
|
| - }
|
| -
|
| - ignore_button_release_ = false;
|
| - GtkMenuShell* menu_shell = GTK_MENU_SHELL(sender);
|
| - // If the cursor is outside our bounds, pass this event up to the parent.
|
| - if (!gtk_util::WidgetContainsCursor(sender)) {
|
| - if (menu_shell->parent_menu_shell) {
|
| - return OnMenuButtonPressedOrReleased(menu_shell->parent_menu_shell,
|
| - event);
|
| - } else {
|
| - // We are the top level menu; we can propagate no further.
|
| - return FALSE;
|
| - }
|
| - }
|
| -
|
| - // This will return NULL if we are not an empty menu.
|
| - const BookmarkNode* parent = GetParentNodeFromEmptyMenu(sender);
|
| - bool is_empty_menu = !!parent;
|
| - // If there is no active menu item and we are not an empty menu, then do
|
| - // nothing. This can happen if the user has canceled a context menu while
|
| - // the cursor is hovering over a bookmark menu. Doing nothing is not optimal
|
| - // (the hovered item should be active), but it's a hopefully rare corner
|
| - // case.
|
| - GtkWidget* menu_item = menu_shell->active_menu_item;
|
| - if (!is_empty_menu && !menu_item)
|
| - return TRUE;
|
| - const BookmarkNode* node =
|
| - menu_item ? GetNodeFromMenuItem(menu_item) : NULL;
|
| -
|
| - if (event->button == 2 && node && node->is_folder()) {
|
| - chrome::OpenAll(parent_window_, page_navigator_, node, NEW_BACKGROUND_TAB,
|
| - browser_->profile());
|
| - gtk_menu_popdown(GTK_MENU(menu_));
|
| - return TRUE;
|
| - } else if (event->button == 3) {
|
| - DCHECK_NE(is_empty_menu, !!node);
|
| - if (!is_empty_menu)
|
| - parent = node->parent();
|
| -
|
| - // Show the right click menu and stop processing this button event.
|
| - std::vector<const BookmarkNode*> nodes;
|
| - if (node)
|
| - nodes.push_back(node);
|
| - context_menu_controller_.reset(
|
| - new BookmarkContextMenuController(
|
| - parent_window_, this, browser_, browser_->profile(),
|
| - page_navigator_, parent, nodes));
|
| - context_menu_.reset(
|
| - new MenuGtk(NULL, context_menu_controller_->menu_model()));
|
| -
|
| - // Our bookmark folder menu loses the grab to the context menu. When the
|
| - // context menu is hidden, re-assert our grab.
|
| - GtkWidget* grabbing_menu = gtk_grab_get_current();
|
| - g_object_ref(grabbing_menu);
|
| - signals_.Connect(context_menu_->widget(), "hide",
|
| - G_CALLBACK(OnContextMenuHide), grabbing_menu);
|
| -
|
| - context_menu_->PopupAsContext(gfx::Point(event->x_root, event->y_root),
|
| - event->time);
|
| - return TRUE;
|
| - }
|
| -
|
| - return FALSE;
|
| -}
|
| -
|
| -gboolean BookmarkMenuController::OnButtonReleased(
|
| - GtkWidget* sender,
|
| - GdkEventButton* event) {
|
| - if (ignore_button_release_) {
|
| - // Don't handle this message; it was a drag.
|
| - ignore_button_release_ = false;
|
| - return FALSE;
|
| - }
|
| -
|
| - // Releasing either button 1 or 2 should trigger the bookmark.
|
| - if (!gtk_menu_item_get_submenu(GTK_MENU_ITEM(sender))) {
|
| - // The menu item is a link node.
|
| - if (event->button == 1 || event->button == 2) {
|
| - WindowOpenDisposition disposition =
|
| - event_utils::DispositionFromGdkState(event->state);
|
| -
|
| - NavigateToMenuItem(sender, disposition);
|
| -
|
| - // We need to manually dismiss the popup menu because we're overriding
|
| - // button-release-event.
|
| - gtk_menu_popdown(GTK_MENU(menu_));
|
| - return TRUE;
|
| - }
|
| - } else {
|
| - // The menu item is a folder node.
|
| - if (event->button == 1) {
|
| - // Having overriden the normal handling, we need to manually activate
|
| - // the item.
|
| - gtk_menu_shell_select_item(GTK_MENU_SHELL(sender->parent), sender);
|
| - g_signal_emit_by_name(sender->parent, "activate-current");
|
| - return TRUE;
|
| - }
|
| - }
|
| -
|
| - return FALSE;
|
| -}
|
| -
|
| -gboolean BookmarkMenuController::OnFolderButtonPressed(
|
| - GtkWidget* sender, GdkEventButton* event) {
|
| - // The button press may start a drag; don't let the default handler run.
|
| - if (event->button == 1)
|
| - return TRUE;
|
| - return FALSE;
|
| -}
|
| -
|
| -void BookmarkMenuController::OnMenuHidden(GtkWidget* menu) {
|
| - if (triggering_widget_)
|
| - gtk_chrome_button_unset_paint_state(GTK_CHROME_BUTTON(triggering_widget_));
|
| -}
|
| -
|
| -void BookmarkMenuController::OnMenuItemActivated(GtkWidget* menu_item) {
|
| - NavigateToMenuItem(menu_item, CURRENT_TAB);
|
| -}
|
| -
|
| -void BookmarkMenuController::OnMenuItemDragBegin(GtkWidget* menu_item,
|
| - GdkDragContext* drag_context) {
|
| - // The parent menu item might be removed during the drag. Ref it so |button|
|
| - // won't get destroyed.
|
| - g_object_ref(menu_item->parent);
|
| -
|
| - // Signal to any future OnButtonReleased calls that we're dragging instead of
|
| - // pressing.
|
| - ignore_button_release_ = true;
|
| -
|
| - const BookmarkNode* node = BookmarkNodeForWidget(menu_item);
|
| - drag_icon_ = GetDragRepresentationForNode(
|
| - node, model_, GtkThemeService::GetFrom(browser_->profile()));
|
| - gint x, y;
|
| - gtk_widget_get_pointer(menu_item, &x, &y);
|
| - gtk_drag_set_icon_widget(drag_context, drag_icon_, x, y);
|
| -
|
| - // Hide our node.
|
| - gtk_widget_hide(menu_item);
|
| -}
|
| -
|
| -void BookmarkMenuController::OnMenuItemDragEnd(GtkWidget* menu_item,
|
| - GdkDragContext* drag_context) {
|
| - gtk_widget_show(menu_item);
|
| - g_object_unref(menu_item->parent);
|
| -
|
| - gtk_widget_destroy(drag_icon_);
|
| - drag_icon_ = NULL;
|
| -}
|
| -
|
| -void BookmarkMenuController::OnMenuItemDragGet(GtkWidget* widget,
|
| - GdkDragContext* context,
|
| - GtkSelectionData* selection_data,
|
| - guint target_type,
|
| - guint time) {
|
| - const BookmarkNode* node = BookmarkNodeForWidget(widget);
|
| - WriteBookmarkToSelection(
|
| - node, selection_data, target_type, browser_->profile());
|
| -}
|
|
|