summaryrefslogtreecommitdiffstats
path: root/chrome/browser/gtk/bookmark_menu_controller_gtk.h
blob: dbd0c3ea3b6be5f6609e346a36fc98f4726cc47b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Copyright (c) 2009 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.

#ifndef CHROME_BROWSER_GTK_BOOKMARK_MENU_CONTROLLER_GTK_H_
#define CHROME_BROWSER_GTK_BOOKMARK_MENU_CONTROLLER_GTK_H_

#include <gtk/gtk.h>

#include <map>

#include "base/scoped_ptr.h"
#include "chrome/browser/bookmarks/base_bookmark_model_observer.h"
#include "chrome/browser/gtk/bookmark_context_menu_gtk.h"
#include "chrome/common/owned_widget_gtk.h"
#include "webkit/glue/window_open_disposition.h"

class Browser;
class Profile;
class Profiler;
class PageNavigator;
class BookmarkModel;
class BookmarkNode;

class BookmarkMenuController : public BaseBookmarkModelObserver,
                               public BookmarkContextMenuGtk::Delegate {
 public:
  // Creates a BookmarkMenuController showing the children of |node| starting
  // at index |start_child_index|.
  BookmarkMenuController(Browser* browser,
                         Profile* profile,
                         PageNavigator* page_navigator,
                         GtkWindow* window,
                         const BookmarkNode* node,
                         int start_child_index,
                         bool show_other_folder);
  virtual ~BookmarkMenuController();

  GtkWidget* widget() { return menu_; }

  // Pops up the menu. |widget| must be a GtkChromeButton.
  void Popup(GtkWidget* widget, gint button_type, guint32 timestamp);

  // Overridden from BaseBookmarkModelObserver:
  virtual void BookmarkModelChanged();
  virtual void BookmarkNodeFavIconLoaded(BookmarkModel* model,
                                         const BookmarkNode* node);

  // Overridden from BookmarkContextMenuGtk::Delegate:
  virtual void WillExecuteCommand();

 private:
  // Recursively change the bookmark hierarchy rooted in |parent| into a set of
  // gtk menus rooted in |menu|.
  void BuildMenu(const BookmarkNode* parent,
                 int start_child_index,
                 GtkWidget* menu);

  // Calls the page navigator to navigate to the node represented by
  // |menu_item|.
  void NavigateToMenuItem(GtkWidget* menu_item,
                          WindowOpenDisposition disposition);

  // Button press and release events for a GtkMenuItem. We have to override
  // these separate from OnMenuItemActivated because we need to handle right
  // clicks and opening bookmarks with different dispositions.
  static gboolean OnButtonPressed(GtkWidget* sender,
                                  GdkEventButton* event,
                                  BookmarkMenuController* controller);
  static gboolean OnButtonReleased(GtkWidget* sender,
                                   GdkEventButton* event,
                                   BookmarkMenuController* controller);

  // We have to stop drawing |triggering_widget_| as active when the menu
  // closes.
  static void OnMenuHidden(GtkWidget* menu, BookmarkMenuController* controller);

  // We respond to the activate signal because things other than mouse button
  // events can trigger it.
  static void OnMenuItemActivated(GtkMenuItem* menuitem,
                                  BookmarkMenuController* controller);

  // The individual GtkMenuItems in the BookmarkMenu are all drag sources.
  static void OnMenuItemDragBegin(GtkWidget* menu_item,
                                  GdkDragContext* drag_context,
                                  BookmarkMenuController* bar);
  static void OnMenuItemDragEnd(GtkWidget* menu_item,
                                GdkDragContext* drag_context,
                                BookmarkMenuController* controller);
  static void OnMenuItemDragGet(
      GtkWidget* widget, GdkDragContext* context,
      GtkSelectionData* selection_data,
      guint target_type, guint time,
      BookmarkMenuController* controller);

  Browser* browser_;
  Profile* profile_;
  PageNavigator* page_navigator_;

  // Parent window of this menu.
  GtkWindow* parent_window_;

  // The bookmark model.
  BookmarkModel* model_;

  // The node we're showing the contents of.
  const BookmarkNode* node_;

  // Our bookmark menus. We don't use the MenuGtk class because we have to do
  // all sorts of weird non-standard things with this menu, like:
  // - The menu is a drag target
  // - The menu items have context menus.
  GtkWidget* menu_;

  // Whether we should ignore the next button release event (because we were
  // dragging).
  bool ignore_button_release_;

  // The widget we are showing for (i.e. the bookmark bar folder button).
  GtkWidget* triggering_widget_;

  // Mapping from node to GtkMenuItem menu id. This only contains entries for
  // nodes of type URL.
  std::map<const BookmarkNode*, GtkWidget*> node_to_menu_widget_map_;

  // Owns our right click context menu.
  scoped_ptr<BookmarkContextMenuGtk> context_menu_;

  DISALLOW_COPY_AND_ASSIGN(BookmarkMenuController);
};

#endif  // CHROME_BROWSER_GTK_BOOKMARK_MENU_CONTROLLER_GTK_H_