Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(152)

Side by Side Diff: chrome/browser/gtk/bookmark_menu_controller_gtk.cc

Issue 1118005: GTK: More transitions to thunk definition macros. (Closed)
Patch Set: Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/gtk/bookmark_menu_controller_gtk.h" 5 #include "chrome/browser/gtk/bookmark_menu_controller_gtk.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 8
9 #include "app/gfx/gtk_util.h" 9 #include "app/gfx/gtk_util.h"
10 #include "app/gtk_dnd_util.h" 10 #include "app/gtk_dnd_util.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 profile_(profile), 93 profile_(profile),
94 page_navigator_(navigator), 94 page_navigator_(navigator),
95 parent_window_(window), 95 parent_window_(window),
96 model_(profile->GetBookmarkModel()), 96 model_(profile->GetBookmarkModel()),
97 node_(node), 97 node_(node),
98 ignore_button_release_(false), 98 ignore_button_release_(false),
99 triggering_widget_(NULL) { 99 triggering_widget_(NULL) {
100 menu_ = gtk_menu_new(); 100 menu_ = gtk_menu_new();
101 BuildMenu(node, start_child_index, menu_); 101 BuildMenu(node, start_child_index, menu_);
102 g_signal_connect(menu_, "hide", 102 g_signal_connect(menu_, "hide",
103 G_CALLBACK(OnMenuHidden), this); 103 G_CALLBACK(OnMenuHiddenThunk), this);
104 gtk_widget_show_all(menu_); 104 gtk_widget_show_all(menu_);
105 } 105 }
106 106
107 BookmarkMenuController::~BookmarkMenuController() { 107 BookmarkMenuController::~BookmarkMenuController() {
108 profile_->GetBookmarkModel()->RemoveObserver(this); 108 profile_->GetBookmarkModel()->RemoveObserver(this);
109 gtk_menu_popdown(GTK_MENU(menu_)); 109 gtk_menu_popdown(GTK_MENU(menu_));
110 } 110 }
111 111
112 void BookmarkMenuController::Popup(GtkWidget* widget, gint button_type, 112 void BookmarkMenuController::Popup(GtkWidget* widget, gint button_type,
113 guint32 timestamp) { 113 guint32 timestamp) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 node->GetURL(), GURL(), disposition, PageTransition::AUTO_BOOKMARK); 151 node->GetURL(), GURL(), disposition, PageTransition::AUTO_BOOKMARK);
152 } 152 }
153 153
154 void BookmarkMenuController::BuildMenu(const BookmarkNode* parent, 154 void BookmarkMenuController::BuildMenu(const BookmarkNode* parent,
155 int start_child_index, 155 int start_child_index,
156 GtkWidget* menu) { 156 GtkWidget* menu) {
157 DCHECK(!parent->GetChildCount() || 157 DCHECK(!parent->GetChildCount() ||
158 start_child_index < parent->GetChildCount()); 158 start_child_index < parent->GetChildCount());
159 159
160 g_signal_connect(menu, "button-press-event", 160 g_signal_connect(menu, "button-press-event",
161 G_CALLBACK(OnButtonPressed), this); 161 G_CALLBACK(OnButtonPressedThunk), this);
162 162
163 for (int i = start_child_index; i < parent->GetChildCount(); ++i) { 163 for (int i = start_child_index; i < parent->GetChildCount(); ++i) {
164 const BookmarkNode* node = parent->GetChild(i); 164 const BookmarkNode* node = parent->GetChild(i);
165 165
166 // This breaks on word boundaries. Ideally we would break on character 166 // This breaks on word boundaries. Ideally we would break on character
167 // boundaries. 167 // boundaries.
168 std::wstring elided_name = 168 std::wstring elided_name =
169 l10n_util::TruncateString(node->GetTitle(), kMaxChars); 169 l10n_util::TruncateString(node->GetTitle(), kMaxChars);
170 GtkWidget* menu_item = 170 GtkWidget* menu_item =
171 gtk_image_menu_item_new_with_label(WideToUTF8(elided_name).c_str()); 171 gtk_image_menu_item_new_with_label(WideToUTF8(elided_name).c_str());
172 g_object_set_data(G_OBJECT(menu_item), "bookmark-node", AsVoid(node)); 172 g_object_set_data(G_OBJECT(menu_item), "bookmark-node", AsVoid(node));
173 SetImageMenuItem(menu_item, node, profile_->GetBookmarkModel()); 173 SetImageMenuItem(menu_item, node, profile_->GetBookmarkModel());
174 gtk_util::SetAlwaysShowImage(menu_item); 174 gtk_util::SetAlwaysShowImage(menu_item);
175 175
176 g_signal_connect(menu_item, "button-release-event", 176 g_signal_connect(menu_item, "button-release-event",
177 G_CALLBACK(OnButtonReleased), this); 177 G_CALLBACK(OnButtonReleasedThunk), this);
178 if (node->is_url()) { 178 if (node->is_url()) {
179 g_signal_connect(menu_item, "activate", 179 g_signal_connect(menu_item, "activate",
180 G_CALLBACK(OnMenuItemActivated), this); 180 G_CALLBACK(OnMenuItemActivatedThunk), this);
181 } else if (node->is_folder()) { 181 } else if (node->is_folder()) {
182 GtkWidget* submenu = gtk_menu_new(); 182 GtkWidget* submenu = gtk_menu_new();
183 BuildMenu(node, 0, submenu); 183 BuildMenu(node, 0, submenu);
184 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu); 184 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), submenu);
185 } else { 185 } else {
186 NOTREACHED(); 186 NOTREACHED();
187 } 187 }
188 188
189 gtk_drag_source_set(menu_item, GDK_BUTTON1_MASK, NULL, 0, 189 gtk_drag_source_set(menu_item, GDK_BUTTON1_MASK, NULL, 0,
190 static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_LINK)); 190 static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_LINK));
191 int target_mask = gtk_dnd_util::CHROME_BOOKMARK_ITEM; 191 int target_mask = gtk_dnd_util::CHROME_BOOKMARK_ITEM;
192 if (node->is_url()) 192 if (node->is_url())
193 target_mask |= gtk_dnd_util::TEXT_URI_LIST | gtk_dnd_util::NETSCAPE_URL; 193 target_mask |= gtk_dnd_util::TEXT_URI_LIST | gtk_dnd_util::NETSCAPE_URL;
194 gtk_dnd_util::SetSourceTargetListFromCodeMask(menu_item, target_mask); 194 gtk_dnd_util::SetSourceTargetListFromCodeMask(menu_item, target_mask);
195 g_signal_connect(menu_item, "drag-begin", 195 g_signal_connect(menu_item, "drag-begin",
196 G_CALLBACK(&OnMenuItemDragBegin), this); 196 G_CALLBACK(&OnMenuItemDragBeginThunk), this);
197 g_signal_connect(menu_item, "drag-end", 197 g_signal_connect(menu_item, "drag-end",
198 G_CALLBACK(&OnMenuItemDragEnd), this); 198 G_CALLBACK(&OnMenuItemDragEndThunk), this);
199 g_signal_connect(menu_item, "drag-data-get", 199 g_signal_connect(menu_item, "drag-data-get",
200 G_CALLBACK(&OnMenuItemDragGet), this); 200 G_CALLBACK(&OnMenuItemDragGetThunk), this);
201 201
202 // It is important to connect to this signal after setting up the drag 202 // It is important to connect to this signal after setting up the drag
203 // source because we only want to stifle the menu's default handler and 203 // source because we only want to stifle the menu's default handler and
204 // not the handler that the drag source uses. 204 // not the handler that the drag source uses.
205 if (node->is_folder()) { 205 if (node->is_folder()) {
206 g_signal_connect(menu_item, "button-press-event", 206 g_signal_connect(menu_item, "button-press-event",
207 G_CALLBACK(OnFolderButtonPressed), this); 207 G_CALLBACK(OnFolderButtonPressedThunk), this);
208 } 208 }
209 209
210 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); 210 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item);
211 node_to_menu_widget_map_[node] = menu_item; 211 node_to_menu_widget_map_[node] = menu_item;
212 } 212 }
213 213
214 if (parent->GetChildCount() == 0) { 214 if (parent->GetChildCount() == 0) {
215 GtkWidget* empty_menu = gtk_menu_item_new_with_label( 215 GtkWidget* empty_menu = gtk_menu_item_new_with_label(
216 l10n_util::GetStringUTF8(IDS_MENU_EMPTY_SUBMENU).c_str()); 216 l10n_util::GetStringUTF8(IDS_MENU_EMPTY_SUBMENU).c_str());
217 gtk_widget_set_sensitive(empty_menu, FALSE); 217 gtk_widget_set_sensitive(empty_menu, FALSE);
218 g_object_set_data(G_OBJECT(menu), "parent-node", AsVoid(parent)); 218 g_object_set_data(G_OBJECT(menu), "parent-node", AsVoid(parent));
219 gtk_menu_shell_append(GTK_MENU_SHELL(menu), empty_menu); 219 gtk_menu_shell_append(GTK_MENU_SHELL(menu), empty_menu);
220 } 220 }
221 } 221 }
222 222
223 // static
224 gboolean BookmarkMenuController::OnButtonPressed( 223 gboolean BookmarkMenuController::OnButtonPressed(
225 GtkWidget* sender, 224 GtkWidget* sender,
226 GdkEventButton* event, 225 GdkEventButton* event) {
227 BookmarkMenuController* controller) { 226 ignore_button_release_ = false;
228 controller->ignore_button_release_ = false;
229 GtkMenuShell* menu_shell = GTK_MENU_SHELL(sender); 227 GtkMenuShell* menu_shell = GTK_MENU_SHELL(sender);
230 228
231 if (event->button == 3) { 229 if (event->button == 3) {
232 // If the cursor is outside our bounds, pass this event up to the parent. 230 // If the cursor is outside our bounds, pass this event up to the parent.
233 if (!gtk_util::WidgetContainsCursor(sender)) { 231 if (!gtk_util::WidgetContainsCursor(sender)) {
234 if (menu_shell->parent_menu_shell) { 232 if (menu_shell->parent_menu_shell) {
235 return OnButtonPressed(menu_shell->parent_menu_shell, event, 233 return OnButtonPressed(menu_shell->parent_menu_shell, event);
236 controller);
237 } else { 234 } else {
238 // We are the top level menu; we can propagate no further. 235 // We are the top level menu; we can propagate no further.
239 return FALSE; 236 return FALSE;
240 } 237 }
241 } 238 }
242 239
243 // This will return NULL if we are not an empty menu. 240 // This will return NULL if we are not an empty menu.
244 const BookmarkNode* parent = GetParentNodeFromEmptyMenu(sender); 241 const BookmarkNode* parent = GetParentNodeFromEmptyMenu(sender);
245 bool is_empty_menu = !!parent; 242 bool is_empty_menu = !!parent;
246 // If there is no active menu item and we are not an empty menu, then do 243 // If there is no active menu item and we are not an empty menu, then do
247 // nothing. 244 // nothing.
248 GtkWidget* menu_item = menu_shell->active_menu_item; 245 GtkWidget* menu_item = menu_shell->active_menu_item;
249 if (!is_empty_menu && !menu_item) 246 if (!is_empty_menu && !menu_item)
250 return FALSE; 247 return FALSE;
251 248
252 const BookmarkNode* node = 249 const BookmarkNode* node =
253 menu_item ? GetNodeFromMenuItem(menu_item) : NULL; 250 menu_item ? GetNodeFromMenuItem(menu_item) : NULL;
254 DCHECK_NE(is_empty_menu, !!node); 251 DCHECK_NE(is_empty_menu, !!node);
255 if (!is_empty_menu) 252 if (!is_empty_menu)
256 parent = node->GetParent(); 253 parent = node->GetParent();
257 254
258 // Show the right click menu and stop processing this button event. 255 // Show the right click menu and stop processing this button event.
259 std::vector<const BookmarkNode*> nodes; 256 std::vector<const BookmarkNode*> nodes;
260 if (node) 257 if (node)
261 nodes.push_back(node); 258 nodes.push_back(node);
262 controller->context_menu_controller_.reset( 259 context_menu_controller_.reset(
263 new BookmarkContextMenuController( 260 new BookmarkContextMenuController(
264 controller->parent_window_, controller, controller->profile_, 261 parent_window_, this, profile_,
265 controller->page_navigator_, parent, nodes, 262 page_navigator_, parent, nodes,
266 BookmarkContextMenuController::BOOKMARK_BAR)); 263 BookmarkContextMenuController::BOOKMARK_BAR));
267 controller->context_menu_.reset( 264 context_menu_.reset(
268 new MenuGtk(NULL, controller->context_menu_controller_->menu_model())); 265 new MenuGtk(NULL, context_menu_controller_->menu_model()));
269 266
270 // Our bookmark folder menu loses the grab to the context menu. When the 267 // Our bookmark folder menu loses the grab to the context menu. When the
271 // context menu is hidden, re-assert our grab. 268 // context menu is hidden, re-assert our grab.
272 GtkWidget* grabbing_menu = gtk_grab_get_current(); 269 GtkWidget* grabbing_menu = gtk_grab_get_current();
273 g_object_ref(grabbing_menu); 270 g_object_ref(grabbing_menu);
274 g_signal_connect(controller->context_menu_->widget(), "hide", 271 g_signal_connect(context_menu_->widget(), "hide",
275 G_CALLBACK(OnContextMenuHide), grabbing_menu); 272 G_CALLBACK(OnContextMenuHide), grabbing_menu);
276 273
277 controller->context_menu_->PopupAsContext(event->time); 274 context_menu_->PopupAsContext(event->time);
278 return TRUE; 275 return TRUE;
279 } 276 }
280 277
281 return FALSE; 278 return FALSE;
282 } 279 }
283 280
284 // static
285 gboolean BookmarkMenuController::OnButtonReleased( 281 gboolean BookmarkMenuController::OnButtonReleased(
286 GtkWidget* sender, 282 GtkWidget* sender,
287 GdkEventButton* event, 283 GdkEventButton* event) {
288 BookmarkMenuController* controller) { 284 if (ignore_button_release_) {
289 if (controller->ignore_button_release_) {
290 // Don't handle this message; it was a drag. 285 // Don't handle this message; it was a drag.
291 controller->ignore_button_release_ = false; 286 ignore_button_release_ = false;
292 return FALSE; 287 return FALSE;
293 } 288 }
294 289
295 // Releasing either button 1 or 2 should trigger the bookmark. 290 // Releasing either button 1 or 2 should trigger the bookmark.
296 if (!gtk_menu_item_get_submenu(GTK_MENU_ITEM(sender))) { 291 if (!gtk_menu_item_get_submenu(GTK_MENU_ITEM(sender))) {
297 // The menu item is a link node. 292 // The menu item is a link node.
298 if (event->button == 1 || event->button == 2) { 293 if (event->button == 1 || event->button == 2) {
299 WindowOpenDisposition disposition = 294 WindowOpenDisposition disposition =
300 event_utils::DispositionFromEventFlags(event->state); 295 event_utils::DispositionFromEventFlags(event->state);
301 controller->NavigateToMenuItem(sender, disposition); 296 NavigateToMenuItem(sender, disposition);
302 297
303 // We need to manually dismiss the popup menu because we're overriding 298 // We need to manually dismiss the popup menu because we're overriding
304 // button-release-event. 299 // button-release-event.
305 gtk_menu_popdown(GTK_MENU(controller->menu_)); 300 gtk_menu_popdown(GTK_MENU(menu_));
306 return TRUE; 301 return TRUE;
307 } 302 }
308 } else { 303 } else {
309 // The menu item is a folder node. 304 // The menu item is a folder node.
310 if (event->button == 1) { 305 if (event->button == 1) {
311 gtk_menu_popup(GTK_MENU(gtk_menu_item_get_submenu(GTK_MENU_ITEM(sender))), 306 gtk_menu_popup(GTK_MENU(gtk_menu_item_get_submenu(GTK_MENU_ITEM(sender))),
312 sender->parent, sender, NULL, NULL, 307 sender->parent, sender, NULL, NULL,
313 event->button, event->time); 308 event->button, event->time);
314 } 309 }
315 } 310 }
316 311
317 return FALSE; 312 return FALSE;
318 } 313 }
319 314
320 // static
321 gboolean BookmarkMenuController::OnFolderButtonPressed( 315 gboolean BookmarkMenuController::OnFolderButtonPressed(
322 GtkWidget* sender, 316 GtkWidget* sender, GdkEventButton* event) {
323 GdkEventButton* event,
324 BookmarkMenuController* controller) {
325 // The button press may start a drag; don't let the default handler run. 317 // The button press may start a drag; don't let the default handler run.
326 if (event->button == 1) 318 if (event->button == 1)
327 return TRUE; 319 return TRUE;
328 return FALSE; 320 return FALSE;
329 } 321 }
330 322
331 // static 323 void BookmarkMenuController::OnMenuHidden(GtkWidget* menu) {
332 void BookmarkMenuController::OnMenuHidden(GtkWidget* menu, 324 if (triggering_widget_)
333 BookmarkMenuController* controller) { 325 gtk_chrome_button_unset_paint_state(GTK_CHROME_BUTTON(triggering_widget_));
334 if (controller->triggering_widget_) {
335 gtk_chrome_button_unset_paint_state(
336 GTK_CHROME_BUTTON(controller->triggering_widget_));
337 }
338 } 326 }
339 327
340 // static 328 void BookmarkMenuController::OnMenuItemActivated(GtkWidget* menu_item) {
341 void BookmarkMenuController::OnMenuItemActivated( 329 NavigateToMenuItem(menu_item, CURRENT_TAB);
342 GtkMenuItem* menu_item, BookmarkMenuController* controller) {
343 controller->NavigateToMenuItem(GTK_WIDGET(menu_item), CURRENT_TAB);
344 } 330 }
345 331
346 // static 332 void BookmarkMenuController::OnMenuItemDragBegin(GtkWidget* menu_item,
347 void BookmarkMenuController::OnMenuItemDragBegin( 333 GdkDragContext* drag_context) {
348 GtkWidget* menu_item,
349 GdkDragContext* drag_context,
350 BookmarkMenuController* controller) {
351 // The parent menu item might be removed during the drag. Ref it so |button| 334 // The parent menu item might be removed during the drag. Ref it so |button|
352 // won't get destroyed. 335 // won't get destroyed.
353 g_object_ref(menu_item->parent); 336 g_object_ref(menu_item->parent);
354 337
355 // Signal to any future OnButtonReleased calls that we're dragging instead of 338 // Signal to any future OnButtonReleased calls that we're dragging instead of
356 // pressing. 339 // pressing.
357 controller->ignore_button_release_ = true; 340 ignore_button_release_ = true;
358 341
359 const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(menu_item); 342 const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(menu_item);
360 GtkWidget* window = bookmark_utils::GetDragRepresentation( 343 GtkWidget* window = bookmark_utils::GetDragRepresentation(
361 node, controller->model_, 344 node, model_, GtkThemeProvider::GetFrom(profile_));
362 GtkThemeProvider::GetFrom(controller->profile_));
363 gint x, y; 345 gint x, y;
364 gtk_widget_get_pointer(menu_item, &x, &y); 346 gtk_widget_get_pointer(menu_item, &x, &y);
365 gtk_drag_set_icon_widget(drag_context, window, x, y); 347 gtk_drag_set_icon_widget(drag_context, window, x, y);
366 348
367 // Hide our node. 349 // Hide our node.
368 gtk_widget_hide(menu_item); 350 gtk_widget_hide(menu_item);
369 } 351 }
370 352
371 // static 353 void BookmarkMenuController::OnMenuItemDragEnd(GtkWidget* menu_item,
372 void BookmarkMenuController::OnMenuItemDragEnd( 354 GdkDragContext* drag_context) {
373 GtkWidget* menu_item,
374 GdkDragContext* drag_context,
375 BookmarkMenuController* controller) {
376 gtk_widget_show(menu_item); 355 gtk_widget_show(menu_item);
377 g_object_unref(menu_item->parent); 356 g_object_unref(menu_item->parent);
378 } 357 }
379 358
380 // static
381 void BookmarkMenuController::OnMenuItemDragGet( 359 void BookmarkMenuController::OnMenuItemDragGet(
382 GtkWidget* widget, GdkDragContext* context, 360 GtkWidget* widget, GdkDragContext* context,
383 GtkSelectionData* selection_data, 361 GtkSelectionData* selection_data,
384 guint target_type, guint time, 362 guint target_type, guint time) {
385 BookmarkMenuController* controller) {
386 const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(widget); 363 const BookmarkNode* node = bookmark_utils::BookmarkNodeForWidget(widget);
387 bookmark_utils::WriteBookmarkToSelection(node, selection_data, target_type, 364 bookmark_utils::WriteBookmarkToSelection(node, selection_data, target_type,
388 controller->profile_); 365 profile_);
389 } 366 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/bookmark_menu_controller_gtk.h ('k') | chrome/browser/gtk/external_protocol_dialog_gtk.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698