| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/ui/gtk/global_bookmark_menu.h" | 5 #include "chrome/browser/ui/gtk/global_bookmark_menu.h" |
| 6 | 6 |
| 7 #include <dlfcn.h> |
| 7 #include <gtk/gtk.h> | 8 #include <gtk/gtk.h> |
| 8 | 9 |
| 9 #include "base/logging.h" | 10 #include "base/logging.h" |
| 10 #include "base/utf_string_conversions.h" | 11 #include "base/utf_string_conversions.h" |
| 11 #include "chrome/browser/bookmarks/bookmark_model.h" | 12 #include "chrome/browser/bookmarks/bookmark_model.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/ui/browser.h" | 14 #include "chrome/browser/ui/browser.h" |
| 14 #include "chrome/browser/ui/gtk/global_bookmark_menu.h" | 15 #include "chrome/browser/ui/gtk/global_bookmark_menu.h" |
| 15 #include "chrome/browser/ui/gtk/global_menu_bar.h" | 16 #include "chrome/browser/ui/gtk/global_menu_bar.h" |
| 16 #include "chrome/browser/ui/gtk/gtk_theme_service.h" | 17 #include "chrome/browser/ui/gtk/gtk_theme_service.h" |
| 17 #include "chrome/browser/ui/gtk/gtk_util.h" | 18 #include "chrome/browser/ui/gtk/gtk_util.h" |
| 18 #include "content/common/notification_service.h" | 19 #include "content/common/notification_service.h" |
| 19 #include "grit/generated_resources.h" | 20 #include "grit/generated_resources.h" |
| 20 #include "ui/base/l10n/l10n_util.h" | 21 #include "ui/base/l10n/l10n_util.h" |
| 21 #include "ui/gfx/gtk_util.h" | 22 #include "ui/gfx/gtk_util.h" |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 | 25 |
| 25 const int kMaxChars = 50; | 26 const int kMaxChars = 50; |
| 26 | 27 |
| 28 // We need to know whether we're using a newer GTK at run time because we need |
| 29 // to prevent |
| 30 typedef void (*gtk_menu_item_set_label_func)(GtkMenuItem*, const gchar*); |
| 31 gtk_menu_item_set_label_func gtk_menu_item_set_label_sym = |
| 32 #if GTK_CHECK_VERSION(2, 16, 1) |
| 33 gtk_menu_item_set_label; |
| 34 #else |
| 35 NULL; |
| 36 #endif |
| 37 |
| 38 void EnsureMenuItemFunctions() { |
| 39 #if !GTK_CHECK_VERSION(2, 16, 1) |
| 40 static bool methods_looked_up = false; |
| 41 if (!methods_looked_up) { |
| 42 methods_looked_up = true; |
| 43 gtk_menu_item_set_label_sym = |
| 44 reinterpret_cast<gtk_menu_item_set_label_func>( |
| 45 dlsym(NULL, "gtk_menu_item_set_label")); |
| 46 } |
| 47 #endif |
| 48 } |
| 49 |
| 27 } // namespace | 50 } // namespace |
| 28 | 51 |
| 29 GlobalBookmarkMenu::GlobalBookmarkMenu(Browser* browser) | 52 GlobalBookmarkMenu::GlobalBookmarkMenu(Browser* browser) |
| 30 : browser_(browser), | 53 : browser_(browser), |
| 31 profile_(browser->profile()), | 54 profile_(browser->profile()), |
| 32 default_favicon_(NULL), | 55 default_favicon_(NULL), |
| 33 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { | 56 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
| 34 DCHECK(profile_); | 57 DCHECK(profile_); |
| 35 | 58 |
| 36 default_favicon_ = GtkThemeService::GetDefaultFavicon(true); | 59 default_favicon_ = GtkThemeService::GetDefaultFavicon(true); |
| 37 default_folder_ = GtkThemeService::GetFolderIcon(true); | 60 default_folder_ = GtkThemeService::GetFolderIcon(true); |
| 38 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, | 61 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, |
| 39 Source<Profile>(profile_)); | 62 Source<Profile>(profile_)); |
| 40 } | 63 } |
| 41 | 64 |
| 42 GlobalBookmarkMenu::~GlobalBookmarkMenu() { | 65 GlobalBookmarkMenu::~GlobalBookmarkMenu() { |
| 43 profile_->GetBookmarkModel()->RemoveObserver(this); | 66 profile_->GetBookmarkModel()->RemoveObserver(this); |
| 44 } | 67 } |
| 45 | 68 |
| 46 void GlobalBookmarkMenu::Init(GtkWidget* bookmark_menu) { | 69 void GlobalBookmarkMenu::Init(GtkWidget* bookmark_menu) { |
| 47 bookmark_menu_ = bookmark_menu; | 70 bookmark_menu_ = bookmark_menu; |
| 48 | 71 |
| 49 BookmarkModel* model = profile_->GetBookmarkModel(); | 72 EnsureMenuItemFunctions(); |
| 50 model->AddObserver(this); | 73 if (gtk_menu_item_set_label_sym) { |
| 51 if (model->IsLoaded()) | 74 BookmarkModel* model = profile_->GetBookmarkModel(); |
| 52 Loaded(model); | 75 model->AddObserver(this); |
| 76 if (model->IsLoaded()) |
| 77 Loaded(model); |
| 78 } |
| 53 } | 79 } |
| 54 | 80 |
| 55 void GlobalBookmarkMenu::RebuildMenuInFuture() { | 81 void GlobalBookmarkMenu::RebuildMenuInFuture() { |
| 56 method_factory_.RevokeAll(); | 82 method_factory_.RevokeAll(); |
| 57 MessageLoop::current()->PostTask( | 83 MessageLoop::current()->PostTask( |
| 58 FROM_HERE, | 84 FROM_HERE, |
| 59 method_factory_.NewRunnableMethod(&GlobalBookmarkMenu::RebuildMenu)); | 85 method_factory_.NewRunnableMethod(&GlobalBookmarkMenu::RebuildMenu)); |
| 60 } | 86 } |
| 61 | 87 |
| 62 void GlobalBookmarkMenu::RebuildMenu() { | 88 void GlobalBookmarkMenu::RebuildMenu() { |
| 63 #if !GTK_CHECK_VERSION(2, 16, 1) | 89 |
| 64 // We can't deal with this case; we need to use dynamic APIs. Thankfully, | 90 |
| 65 // this will never visibly do anything on earlier versions of GTK+. | |
| 66 return; | |
| 67 #endif | |
| 68 BookmarkModel* model = profile_->GetBookmarkModel(); | 91 BookmarkModel* model = profile_->GetBookmarkModel(); |
| 69 DCHECK(model); | 92 DCHECK(model); |
| 70 DCHECK(model->IsLoaded()); | 93 DCHECK(model->IsLoaded()); |
| 71 | 94 |
| 72 ClearBookmarkMenu(); | 95 ClearBookmarkMenu(); |
| 73 | 96 |
| 74 const BookmarkNode* bar_node = model->GetBookmarkBarNode(); | 97 const BookmarkNode* bar_node = model->GetBookmarkBarNode(); |
| 75 if (bar_node->child_count()) { | 98 if (bar_node->child_count()) { |
| 76 AddBookmarkMenuItem(bookmark_menu_, gtk_separator_menu_item_new()); | 99 AddBookmarkMenuItem(bookmark_menu_, gtk_separator_menu_item_new()); |
| 77 AddNodeToMenu(bar_node, bookmark_menu_); | 100 AddNodeToMenu(bar_node, bookmark_menu_); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 AddBookmarkMenuItem(menu, item); | 156 AddBookmarkMenuItem(menu, item); |
| 134 } | 157 } |
| 135 } | 158 } |
| 136 } | 159 } |
| 137 | 160 |
| 138 void GlobalBookmarkMenu::ConfigureMenuItem(const BookmarkNode* node, | 161 void GlobalBookmarkMenu::ConfigureMenuItem(const BookmarkNode* node, |
| 139 GtkWidget* menu_item) { | 162 GtkWidget* menu_item) { |
| 140 // This check is only to make things compile on Hardy; this code won't | 163 // This check is only to make things compile on Hardy; this code won't |
| 141 // display any visible widgets in older systems that don't have a global menu | 164 // display any visible widgets in older systems that don't have a global menu |
| 142 // bar. | 165 // bar. |
| 143 #if GTK_CHECK_VERSION(2, 16, 1) | 166 if (gtk_menu_item_set_label_sym) { |
| 144 string16 elided_name = l10n_util::TruncateString(node->GetTitle(), kMaxChars); | 167 string16 elided_name = |
| 145 gtk_menu_item_set_label(GTK_MENU_ITEM(menu_item), | 168 l10n_util::TruncateString(node->GetTitle(), kMaxChars); |
| 146 UTF16ToUTF8(elided_name).c_str()); | 169 gtk_menu_item_set_label_sym(GTK_MENU_ITEM(menu_item), |
| 147 #endif | 170 UTF16ToUTF8(elided_name).c_str()); |
| 171 } |
| 148 | 172 |
| 149 if (node->is_url()) { | 173 if (node->is_url()) { |
| 150 std::string tooltip = gtk_util::BuildTooltipTitleFor(node->GetTitle(), | 174 std::string tooltip = gtk_util::BuildTooltipTitleFor(node->GetTitle(), |
| 151 node->GetURL()); | 175 node->GetURL()); |
| 152 gtk_widget_set_tooltip_markup(menu_item, tooltip.c_str()); | 176 gtk_widget_set_tooltip_markup(menu_item, tooltip.c_str()); |
| 153 } | 177 } |
| 154 | 178 |
| 155 const SkBitmap& bitmap = profile_->GetBookmarkModel()->GetFavicon(node); | 179 const SkBitmap& bitmap = profile_->GetBookmarkModel()->GetFavicon(node); |
| 156 if (!bitmap.isNull()) { | 180 if (!bitmap.isNull()) { |
| 157 GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&bitmap); | 181 GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&bitmap); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 void GlobalBookmarkMenu::OnBookmarkItemActivated(GtkWidget* menu_item) { | 285 void GlobalBookmarkMenu::OnBookmarkItemActivated(GtkWidget* menu_item) { |
| 262 // The actual mouse event that generated this activated event was in a | 286 // The actual mouse event that generated this activated event was in a |
| 263 // different process. Go with something default. | 287 // different process. Go with something default. |
| 264 const BookmarkNode* node = static_cast<const BookmarkNode*>( | 288 const BookmarkNode* node = static_cast<const BookmarkNode*>( |
| 265 g_object_get_data(G_OBJECT(menu_item), "bookmark-node")); | 289 g_object_get_data(G_OBJECT(menu_item), "bookmark-node")); |
| 266 | 290 |
| 267 browser_->OpenURL(node->GetURL(), GURL(), NEW_FOREGROUND_TAB, | 291 browser_->OpenURL(node->GetURL(), GURL(), NEW_FOREGROUND_TAB, |
| 268 PageTransition::AUTO_BOOKMARK); | 292 PageTransition::AUTO_BOOKMARK); |
| 269 } | 293 } |
| 270 | 294 |
| OLD | NEW |