diff options
author | Kristian Monsen <kristianm@google.com> | 2011-05-31 20:30:28 +0100 |
---|---|---|
committer | Kristian Monsen <kristianm@google.com> | 2011-06-14 20:31:41 -0700 |
commit | 72a454cd3513ac24fbdd0e0cb9ad70b86a99b801 (patch) | |
tree | 382278a54ce7a744d62fa510a9a80688cc12434b /chrome/browser/gtk/bookmark_bubble_gtk.cc | |
parent | c4becdd46e31d261b930e4b5a539cbc1d45c23a6 (diff) | |
download | external_chromium-72a454cd3513ac24fbdd0e0cb9ad70b86a99b801.zip external_chromium-72a454cd3513ac24fbdd0e0cb9ad70b86a99b801.tar.gz external_chromium-72a454cd3513ac24fbdd0e0cb9ad70b86a99b801.tar.bz2 |
Merge Chromium.org at r11.0.672.0: Initial merge by git.
Change-Id: I8b4aaf611a2a405fe3fe10e8a94ea7658645c192
Diffstat (limited to 'chrome/browser/gtk/bookmark_bubble_gtk.cc')
-rw-r--r-- | chrome/browser/gtk/bookmark_bubble_gtk.cc | 346 |
1 files changed, 0 insertions, 346 deletions
diff --git a/chrome/browser/gtk/bookmark_bubble_gtk.cc b/chrome/browser/gtk/bookmark_bubble_gtk.cc deleted file mode 100644 index ba0e198..0000000 --- a/chrome/browser/gtk/bookmark_bubble_gtk.cc +++ /dev/null @@ -1,346 +0,0 @@ -// Copyright (c) 2010 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/gtk/bookmark_bubble_gtk.h" - -#include <gtk/gtk.h> - -#include "app/l10n_util.h" -#include "base/basictypes.h" -#include "base/i18n/rtl.h" -#include "base/logging.h" -#include "base/message_loop.h" -#include "base/string16.h" -#include "base/utf_string_conversions.h" -#include "chrome/browser/bookmarks/bookmark_editor.h" -#include "chrome/browser/bookmarks/bookmark_model.h" -#include "chrome/browser/bookmarks/bookmark_utils.h" -#include "chrome/browser/bookmarks/recently_used_folders_combo_model.h" -#include "chrome/browser/gtk/gtk_chrome_link_button.h" -#include "chrome/browser/gtk/gtk_theme_provider.h" -#include "chrome/browser/gtk/gtk_util.h" -#include "chrome/browser/gtk/info_bubble_gtk.h" -#include "chrome/browser/metrics/user_metrics.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/common/notification_service.h" -#include "grit/generated_resources.h" - -namespace { - -// We basically have a singleton, since a bubble is sort of app-modal. This -// keeps track of the currently open bubble, or NULL if none is open. -BookmarkBubbleGtk* g_bubble = NULL; - -// Padding between content and edge of info bubble. -const int kContentBorder = 7; - - -} // namespace - -// static -void BookmarkBubbleGtk::Show(GtkWidget* anchor, - Profile* profile, - const GURL& url, - bool newly_bookmarked) { - DCHECK(!g_bubble); - g_bubble = new BookmarkBubbleGtk(anchor, profile, url, newly_bookmarked); -} - -void BookmarkBubbleGtk::InfoBubbleClosing(InfoBubbleGtk* info_bubble, - bool closed_by_escape) { - if (closed_by_escape) { - remove_bookmark_ = newly_bookmarked_; - apply_edits_ = false; - } - - NotificationService::current()->Notify( - NotificationType::BOOKMARK_BUBBLE_HIDDEN, - Source<Profile>(profile_->GetOriginalProfile()), - NotificationService::NoDetails()); -} - -void BookmarkBubbleGtk::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - DCHECK(type == NotificationType::BROWSER_THEME_CHANGED); - - gtk_chrome_link_button_set_use_gtk_theme( - GTK_CHROME_LINK_BUTTON(remove_button_), - theme_provider_->UseGtkTheme()); - - if (theme_provider_->UseGtkTheme()) { - for (std::vector<GtkWidget*>::iterator it = labels_.begin(); - it != labels_.end(); ++it) { - gtk_widget_modify_fg(*it, GTK_STATE_NORMAL, NULL); - } - } else { - for (std::vector<GtkWidget*>::iterator it = labels_.begin(); - it != labels_.end(); ++it) { - gtk_widget_modify_fg(*it, GTK_STATE_NORMAL, >k_util::kGdkBlack); - } - } -} - -BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWidget* anchor, - Profile* profile, - const GURL& url, - bool newly_bookmarked) - : url_(url), - profile_(profile), - theme_provider_(GtkThemeProvider::GetFrom(profile_)), - anchor_(anchor), - content_(NULL), - name_entry_(NULL), - folder_combo_(NULL), - bubble_(NULL), - factory_(this), - newly_bookmarked_(newly_bookmarked), - apply_edits_(true), - remove_bookmark_(false) { - GtkWidget* label = gtk_label_new(l10n_util::GetStringUTF8( - newly_bookmarked_ ? IDS_BOOMARK_BUBBLE_PAGE_BOOKMARKED : - IDS_BOOMARK_BUBBLE_PAGE_BOOKMARK).c_str()); - labels_.push_back(label); - remove_button_ = gtk_chrome_link_button_new( - l10n_util::GetStringUTF8(IDS_BOOMARK_BUBBLE_REMOVE_BOOKMARK).c_str()); - GtkWidget* edit_button = gtk_button_new_with_label( - l10n_util::GetStringUTF8(IDS_BOOMARK_BUBBLE_OPTIONS).c_str()); - GtkWidget* close_button = gtk_button_new_with_label( - l10n_util::GetStringUTF8(IDS_DONE).c_str()); - - // Our content is arranged in 3 rows. |top| contains a left justified - // message, and a right justified remove link button. |table| is the middle - // portion with the name entry and the folder combo. |bottom| is the final - // row with a spacer, and the edit... and close buttons on the right. - GtkWidget* content = gtk_vbox_new(FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(content), kContentBorder); - GtkWidget* top = gtk_hbox_new(FALSE, 0); - - gtk_misc_set_alignment(GTK_MISC(label), 0, 1); - gtk_box_pack_start(GTK_BOX(top), label, - TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(top), remove_button_, - FALSE, FALSE, 0); - - folder_combo_ = gtk_combo_box_new_text(); - InitFolderComboModel(); - - // Create the edit entry for updating the bookmark name / title. - name_entry_ = gtk_entry_new(); - gtk_entry_set_text(GTK_ENTRY(name_entry_), GetTitle().c_str()); - - // We use a table to allow the labels to line up with each other, along - // with the entry and folder combo lining up. - GtkWidget* table = gtk_util::CreateLabeledControlsGroup( - &labels_, - l10n_util::GetStringUTF8(IDS_BOOMARK_BUBBLE_TITLE_TEXT).c_str(), - name_entry_, - l10n_util::GetStringUTF8(IDS_BOOMARK_BUBBLE_FOLDER_TEXT).c_str(), - folder_combo_, - NULL); - - GtkWidget* bottom = gtk_hbox_new(FALSE, 0); - // We want the buttons on the right, so just use an expanding label to fill - // all of the extra space on the right. - gtk_box_pack_start(GTK_BOX(bottom), gtk_label_new(""), - TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(bottom), edit_button, - FALSE, FALSE, 4); - gtk_box_pack_start(GTK_BOX(bottom), close_button, - FALSE, FALSE, 0); - - gtk_box_pack_start(GTK_BOX(content), top, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(content), table, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(content), bottom, TRUE, TRUE, 0); - // We want the focus to start on the entry, not on the remove button. - gtk_container_set_focus_child(GTK_CONTAINER(content), table); - - InfoBubbleGtk::ArrowLocationGtk arrow_location = - base::i18n::IsRTL() ? - InfoBubbleGtk::ARROW_LOCATION_TOP_LEFT : - InfoBubbleGtk::ARROW_LOCATION_TOP_RIGHT; - bubble_ = InfoBubbleGtk::Show(anchor_, - NULL, - content, - arrow_location, - true, // match_system_theme - true, // grab_input - theme_provider_, - this); // delegate - if (!bubble_) { - NOTREACHED(); - return; - } - - g_signal_connect(content, "destroy", - G_CALLBACK(&OnDestroyThunk), this); - g_signal_connect(name_entry_, "activate", - G_CALLBACK(&OnNameActivateThunk), this); - g_signal_connect(folder_combo_, "changed", - G_CALLBACK(&OnFolderChangedThunk), this); - g_signal_connect(folder_combo_, "notify::popup-shown", - G_CALLBACK(&OnFolderPopupShownThunk), this); - g_signal_connect(edit_button, "clicked", - G_CALLBACK(&OnEditClickedThunk), this); - g_signal_connect(close_button, "clicked", - G_CALLBACK(&OnCloseClickedThunk), this); - g_signal_connect(remove_button_, "clicked", - G_CALLBACK(&OnRemoveClickedThunk), this); - - registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, - NotificationService::AllSources()); - theme_provider_->InitThemesFor(this); -} - -BookmarkBubbleGtk::~BookmarkBubbleGtk() { - DCHECK(!content_); // |content_| should have already been destroyed. - - DCHECK(g_bubble); - g_bubble = NULL; - - if (apply_edits_) { - ApplyEdits(); - } else if (remove_bookmark_) { - BookmarkModel* model = profile_->GetBookmarkModel(); - const BookmarkNode* node = model->GetMostRecentlyAddedNodeForURL(url_); - if (node) - model->Remove(node->GetParent(), node->GetParent()->IndexOfChild(node)); - } -} - -void BookmarkBubbleGtk::OnDestroy(GtkWidget* widget) { - // We are self deleting, we have a destroy signal setup to catch when we - // destroyed (via the InfoBubble being destroyed), and delete ourself. - content_ = NULL; // We are being destroyed. - delete this; -} - -void BookmarkBubbleGtk::OnNameActivate(GtkWidget* widget) { - bubble_->Close(); -} - -void BookmarkBubbleGtk::OnFolderChanged(GtkWidget* widget) { - int index = gtk_combo_box_get_active(GTK_COMBO_BOX(folder_combo_)); - if (index == folder_combo_model_->GetItemCount() - 1) { - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBubble_EditFromCombobox"), profile_); - // GTK doesn't handle having the combo box destroyed from the changed - // signal. Since showing the editor also closes the bubble, delay this - // so that GTK can unwind. Specifically gtk_menu_shell_button_release - // will run, and we need to keep the combo box alive until then. - MessageLoop::current()->PostTask(FROM_HERE, - factory_.NewRunnableMethod(&BookmarkBubbleGtk::ShowEditor)); - } -} - -void BookmarkBubbleGtk::OnFolderPopupShown(GtkWidget* widget, - GParamSpec* property) { - // GtkComboBox grabs the keyboard and pointer when it displays its popup, - // which steals the grabs that InfoBubbleGtk had installed. When the popup is - // hidden, we notify InfoBubbleGtk so it can try to reacquire the grabs - // (otherwise, GTK won't activate our widgets when the user clicks in them). - gboolean popup_shown = FALSE; - g_object_get(G_OBJECT(folder_combo_), "popup-shown", &popup_shown, NULL); - if (!popup_shown) - bubble_->HandlePointerAndKeyboardUngrabbedByContent(); -} - -void BookmarkBubbleGtk::OnEditClicked(GtkWidget* widget) { - UserMetrics::RecordAction(UserMetricsAction("BookmarkBubble_Edit"), - profile_); - ShowEditor(); -} - -void BookmarkBubbleGtk::OnCloseClicked(GtkWidget* widget) { - bubble_->Close(); -} - -void BookmarkBubbleGtk::OnRemoveClicked(GtkWidget* widget) { - UserMetrics::RecordAction(UserMetricsAction("BookmarkBubble_Unstar"), - profile_); - - apply_edits_ = false; - remove_bookmark_ = true; - bubble_->Close(); -} - -void BookmarkBubbleGtk::ApplyEdits() { - // Set this to make sure we don't attempt to apply edits again. - apply_edits_ = false; - - BookmarkModel* model = profile_->GetBookmarkModel(); - const BookmarkNode* node = model->GetMostRecentlyAddedNodeForURL(url_); - if (node) { - const string16 new_title( - UTF8ToUTF16(gtk_entry_get_text(GTK_ENTRY(name_entry_)))); - - if (new_title != node->GetTitle()) { - model->SetTitle(node, new_title); - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBubble_ChangeTitleInBubble"), - profile_); - } - - int index = gtk_combo_box_get_active(GTK_COMBO_BOX(folder_combo_)); - - // Last index means 'Choose another folder...' - if (index < folder_combo_model_->GetItemCount() - 1) { - const BookmarkNode* new_parent = folder_combo_model_->GetNodeAt(index); - if (new_parent != node->GetParent()) { - UserMetrics::RecordAction( - UserMetricsAction("BookmarkBubble_ChangeParent"), profile_); - model->Move(node, new_parent, new_parent->GetChildCount()); - } - } - } -} - -std::string BookmarkBubbleGtk::GetTitle() { - BookmarkModel* bookmark_model= profile_->GetBookmarkModel(); - const BookmarkNode* node = - bookmark_model->GetMostRecentlyAddedNodeForURL(url_); - if (!node) { - NOTREACHED(); - return std::string(); - } - - return UTF16ToUTF8(node->GetTitle()); -} - -void BookmarkBubbleGtk::ShowEditor() { - const BookmarkNode* node = - profile_->GetBookmarkModel()->GetMostRecentlyAddedNodeForURL(url_); - - // Commit any edits now. - ApplyEdits(); - - // Closing might delete us, so we'll cache what we need on the stack. - Profile* profile = profile_; - GtkWindow* toplevel = GTK_WINDOW(gtk_widget_get_toplevel(anchor_)); - - // Close the bubble, deleting the C++ objects, etc. - bubble_->Close(); - - if (node) { - BookmarkEditor::Show(toplevel, profile, NULL, - BookmarkEditor::EditDetails(node), - BookmarkEditor::SHOW_TREE); - } -} - -void BookmarkBubbleGtk::InitFolderComboModel() { - folder_combo_model_.reset(new RecentlyUsedFoldersComboModel( - profile_->GetBookmarkModel(), - profile_->GetBookmarkModel()->GetMostRecentlyAddedNodeForURL(url_))); - - // We always have nodes + 1 entries in the combo. The last entry will be - // the 'Select another folder...' entry that opens the bookmark editor. - for (int i = 0; i < folder_combo_model_->GetItemCount(); ++i) { - gtk_combo_box_append_text(GTK_COMBO_BOX(folder_combo_), - UTF16ToUTF8(folder_combo_model_->GetItemAt(i)).c_str()); - } - - gtk_combo_box_set_active(GTK_COMBO_BOX(folder_combo_), - folder_combo_model_->node_parent_index()); -} |