summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/gtk/bookmark_bubble_gtk.cc155
-rw-r--r--chrome/browser/gtk/bookmark_bubble_gtk.h44
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.cc2
-rw-r--r--chrome/browser/gtk/browser_toolbar_gtk.h1
-rw-r--r--chrome/browser/gtk/toolbar_star_toggle_gtk.cc8
-rw-r--r--chrome/browser/gtk/toolbar_star_toggle_gtk.h6
6 files changed, 171 insertions, 45 deletions
diff --git a/chrome/browser/gtk/bookmark_bubble_gtk.cc b/chrome/browser/gtk/bookmark_bubble_gtk.cc
index 310f00b..040a8f8 100644
--- a/chrome/browser/gtk/bookmark_bubble_gtk.cc
+++ b/chrome/browser/gtk/bookmark_bubble_gtk.cc
@@ -10,8 +10,13 @@
#include "app/resource_bundle.h"
#include "base/basictypes.h"
#include "base/logging.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/gtk/gtk_chrome_link_button.h"
#include "chrome/browser/gtk/info_bubble_gtk.h"
+#include "chrome/browser/metrics/user_metrics.h"
+#include "chrome/browser/profile.h"
#include "grit/generated_resources.h"
namespace {
@@ -20,16 +25,6 @@ namespace {
// keeps track of the currently open bubble, or NULL if none is open.
BookmarkBubbleGtk* g_bubble = NULL;
-// TODO(deanm): Just a temporary state to keep track of the last entry in the
-// combo box. This makes sure we are catching the closing events right and
-// saving the state.
-gint g_last_active = 0;
-
-void HandleCloseButton(GtkWidget* widget,
- gpointer user_data) {
- reinterpret_cast<InfoBubbleGtk*>(user_data)->Close();
-}
-
} // namespace
// static
@@ -50,8 +45,6 @@ void BookmarkBubbleGtk::Show(GtkWindow* transient_toplevel,
void BookmarkBubbleGtk::InfoBubbleClosing(InfoBubbleGtk* info_bubble,
bool closed_by_escape) {
- // Possibly commit any bookmark changes here...
- g_last_active = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_));
}
BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel,
@@ -59,10 +52,15 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel,
Profile* profile,
const GURL& url,
bool newly_bookmarked)
- : profile_(profile),
- newly_bookmarked_(newly_bookmarked),
+ : url_(url),
+ profile_(profile),
content_(NULL),
- combo_(NULL) {
+ name_entry_(NULL),
+ folder_combo_(NULL),
+ bubble_(NULL),
+ 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());
@@ -77,6 +75,10 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel,
GtkWidget* close_button = gtk_button_new_with_label(
l10n_util::GetStringUTF8(IDS_CLOSE).c_str());
+ // Our content is arrange 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);
GtkWidget* top = gtk_hbox_new(FALSE, 0);
@@ -86,16 +88,23 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel,
gtk_box_pack_start(GTK_BOX(top), remove_button,
FALSE, FALSE, 0);
- // Use a combo box just to make sure popup windows work in the bubble content
- // and we're not fighting with the bubble for the grab.
- combo_ = gtk_combo_box_new_text();
- gtk_combo_box_append_text(GTK_COMBO_BOX(combo_), "entry 1");
- gtk_combo_box_append_text(GTK_COMBO_BOX(combo_), "entry 2");
- gtk_combo_box_append_text(GTK_COMBO_BOX(combo_), "entry 3");
- gtk_combo_box_set_active(GTK_COMBO_BOX(combo_), g_last_active);
-
- GtkWidget* name_entry = gtk_entry_new();
-
+ // TODO(deanm): We should show the bookmark bar folder along with the top
+ // other choices and an entry to go into the bookmark editor. Since we don't
+ // have the editor up yet on Linux, just show the bookmark bar for now.
+ BookmarkModel* model = profile_->GetBookmarkModel();
+ BookmarkNode* bookmark_bar = model->GetBookmarkBarNode();
+ folder_combo_ = gtk_combo_box_new_text();
+ gtk_combo_box_append_text(GTK_COMBO_BOX(folder_combo_),
+ WideToUTF8(bookmark_bar->GetTitle()).c_str());
+ // We default to the bookmark bar, so make it the active selection.
+ gtk_combo_box_set_active(GTK_COMBO_BOX(folder_combo_), 0);
+
+ // 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_table_new(2, 2, FALSE);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
gtk_table_set_col_spacings(GTK_TABLE(table), 10);
@@ -103,16 +112,18 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel,
name_label,
0, 1, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(table),
- name_entry,
+ name_entry_,
1, 2, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(table),
folder_label,
0, 1, 1, 2);
gtk_table_attach_defaults(GTK_TABLE(table),
- combo_,
+ folder_combo_,
1, 2, 1, 2);
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,
@@ -126,19 +137,21 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWindow* transient_toplevel,
// We want the focus to start on the entry, not on the remove button.
gtk_container_set_focus_child(GTK_CONTAINER(content), table);
- g_signal_connect(content, "destroy",
- G_CALLBACK(&HandleDestroyThunk), this);
-
- // TODO(deanm): In the future we might want to hang on to the returned
- // InfoBubble so that we can call Close() on it.
- InfoBubbleGtk* bubble = InfoBubbleGtk::Show(transient_toplevel,
- rect, content, this);
- if (!bubble) {
+ bubble_ = InfoBubbleGtk::Show(transient_toplevel,
+ rect, content, this);
+ if (!bubble_) {
NOTREACHED();
+ return;
}
+ g_signal_connect(content, "destroy",
+ G_CALLBACK(&HandleDestroyThunk), this);
+ g_signal_connect(name_entry_, "activate",
+ G_CALLBACK(&HandleNameActivateThunk), this);
g_signal_connect(close_button, "clicked",
- G_CALLBACK(&HandleCloseButton), bubble);
+ G_CALLBACK(&HandleCloseButtonThunk), this);
+ g_signal_connect(remove_button, "clicked",
+ G_CALLBACK(&HandleRemoveButtonThunk), this);
}
BookmarkBubbleGtk::~BookmarkBubbleGtk() {
@@ -146,6 +159,15 @@ BookmarkBubbleGtk::~BookmarkBubbleGtk() {
DCHECK(g_bubble);
g_bubble = NULL;
+
+ if (apply_edits_) {
+ ApplyEdits();
+ } else if (remove_bookmark_) {
+ BookmarkModel* model = profile_->GetBookmarkModel();
+ BookmarkNode* node = model->GetMostRecentlyAddedNodeForURL(url_);
+ if (node)
+ model->Remove(node->GetParent(), node->GetParent()->IndexOfChild(node));
+ }
}
gboolean BookmarkBubbleGtk::HandleDestroy() {
@@ -155,3 +177,64 @@ gboolean BookmarkBubbleGtk::HandleDestroy() {
delete this;
return FALSE; // Propagate.
}
+
+void BookmarkBubbleGtk::HandleNameActivate() {
+ bubble_->Close();
+}
+
+void BookmarkBubbleGtk::HandleCloseButton() {
+ bubble_->Close();
+}
+
+void BookmarkBubbleGtk::HandleRemoveButton() {
+ UserMetrics::RecordAction(L"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();
+ BookmarkNode* node = model->GetMostRecentlyAddedNodeForURL(url_);
+ if (node) {
+ // NOTE: Would be nice to save a strlen and use gtk_entry_get_text_length,
+ // but it is fairly new and not always in our GTK version.
+ const std::wstring new_title(
+ UTF8ToWide(gtk_entry_get_text(GTK_ENTRY(name_entry_))));
+
+ if (new_title != node->GetTitle()) {
+ model->SetTitle(node, new_title);
+ UserMetrics::RecordAction(L"BookmarkBubble_ChangeTitleInBubble",
+ profile_);
+ }
+
+// TODO(deanm): We need to get the Bookmark editor running on Linux.
+#if 0
+ // Last index means 'Choose another folder...'
+ if (parent_combobox_->selected_item() <
+ parent_model_.GetItemCount(parent_combobox_) - 1) {
+ BookmarkNode* new_parent =
+ parent_model_.GetNodeAt(parent_combobox_->selected_item());
+ if (new_parent != node->GetParent()) {
+ UserMetrics::RecordAction(L"BookmarkBubble_ChangeParent", profile_);
+ model->Move(node, new_parent, new_parent->GetChildCount());
+ }
+ }
+#endif
+ }
+}
+
+std::string BookmarkBubbleGtk::GetTitle() {
+ BookmarkModel* bookmark_model= profile_->GetBookmarkModel();
+ BookmarkNode* node = bookmark_model->GetMostRecentlyAddedNodeForURL(url_);
+ if (!node) {
+ NOTREACHED();
+ return std::string();
+ }
+
+ return WideToUTF8(node->GetTitle());
+}
diff --git a/chrome/browser/gtk/bookmark_bubble_gtk.h b/chrome/browser/gtk/bookmark_bubble_gtk.h
index 5192413..3dd0291 100644
--- a/chrome/browser/gtk/bookmark_bubble_gtk.h
+++ b/chrome/browser/gtk/bookmark_bubble_gtk.h
@@ -53,20 +53,56 @@ class BookmarkBubbleGtk : public InfoBubbleGtkDelegate {
}
// Notified when |content_| is destroyed so we can delete our instance.
gboolean HandleDestroy();
-
+
+ static void HandleNameActivateThunk(GtkWidget* widget,
+ gpointer user_data) {
+ return reinterpret_cast<BookmarkBubbleGtk*>(user_data)->
+ HandleNameActivate();
+ }
+ void HandleNameActivate();
+
+ static void HandleCloseButtonThunk(GtkWidget* widget,
+ gpointer user_data) {
+ return reinterpret_cast<BookmarkBubbleGtk*>(user_data)->
+ HandleCloseButton();
+ }
+ void HandleCloseButton();
+
+ static void HandleRemoveButtonThunk(GtkWidget* widget,
+ gpointer user_data) {
+ return reinterpret_cast<BookmarkBubbleGtk*>(user_data)->
+ HandleRemoveButton();
+ }
+ void HandleRemoveButton();
+
+ // Update the bookmark with any edits that have been made.
+ void ApplyEdits();
+
+ // Return the UTF8 encoded title for the current |url_|.
+ std::string GetTitle();
+
// The URL of the bookmark.
GURL url_;
// Our current profile (used to access the bookmark system).
Profile* profile_;
- // Whether the bubble is creating or editing an existing bookmark.
- bool newly_bookmarked_;
// We let the InfoBubble own our content, and then we delete ourself
// when the widget is destroyed (when the InfoBubble is destroyed).
GtkWidget* content_;
+ // The GtkEntry for editing the bookmark name / title.
+ GtkWidget* name_entry_;
+
// The combo box for selecting the bookmark folder.
- GtkWidget* combo_;
+ GtkWidget* folder_combo_;
+
+ InfoBubbleGtk* bubble_;
+
+ // Whether the bubble is creating or editing an existing bookmark.
+ bool newly_bookmarked_;
+ // When closing the window, whether we should update or remove the bookmark.
+ bool apply_edits_;
+ bool remove_bookmark_;
DISALLOW_COPY_AND_ASSIGN(BookmarkBubbleGtk);
};
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc
index e9eeded..8d53112 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.cc
+++ b/chrome/browser/gtk/browser_toolbar_gtk.cc
@@ -292,7 +292,7 @@ CustomDrawButton* BrowserToolbarGtk::BuildToolbarButton(
ToolbarStarToggleGtk* BrowserToolbarGtk::BuildStarButton(
const std::string& localized_tooltip) {
- ToolbarStarToggleGtk* button = new ToolbarStarToggleGtk;
+ ToolbarStarToggleGtk* button = new ToolbarStarToggleGtk(this);
gtk_widget_set_tooltip_text(button->widget(),
localized_tooltip.c_str());
diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h
index 6a2a3aa..8f7542d 100644
--- a/chrome/browser/gtk/browser_toolbar_gtk.h
+++ b/chrome/browser/gtk/browser_toolbar_gtk.h
@@ -64,6 +64,7 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver,
const NotificationSource& source,
const NotificationDetails& details);
+ Profile* profile() { return profile_; }
void SetProfile(Profile* profile);
// Message that we should react to a state change.
diff --git a/chrome/browser/gtk/toolbar_star_toggle_gtk.cc b/chrome/browser/gtk/toolbar_star_toggle_gtk.cc
index 4e03454..77c5732 100644
--- a/chrome/browser/gtk/toolbar_star_toggle_gtk.cc
+++ b/chrome/browser/gtk/toolbar_star_toggle_gtk.cc
@@ -7,10 +7,12 @@
#include "app/resource_bundle.h"
#include "base/gfx/rect.h"
#include "chrome/browser/gtk/bookmark_bubble_gtk.h"
+#include "chrome/browser/gtk/browser_toolbar_gtk.h"
#include "grit/theme_resources.h"
-ToolbarStarToggleGtk::ToolbarStarToggleGtk()
- : widget_(gtk_button_new()),
+ToolbarStarToggleGtk::ToolbarStarToggleGtk(BrowserToolbarGtk* host)
+ : host_(host),
+ widget_(gtk_button_new()),
is_starred_(false),
unstarred_(IDR_STAR, IDR_STAR_P, IDR_STAR_H, IDR_STAR_D),
starred_(IDR_STARRED, IDR_STARRED_P, IDR_STARRED_H, 0) {
@@ -42,7 +44,7 @@ void ToolbarStarToggleGtk::ShowStarBubble(const GURL& url,
BookmarkBubbleGtk::Show(GTK_WINDOW(gtk_widget_get_toplevel(widget)),
gfx::Rect(x, y, width, height),
- NULL,
+ host_->profile(),
url,
newly_bookmarked);
}
diff --git a/chrome/browser/gtk/toolbar_star_toggle_gtk.h b/chrome/browser/gtk/toolbar_star_toggle_gtk.h
index dec5cd9..afa61a3 100644
--- a/chrome/browser/gtk/toolbar_star_toggle_gtk.h
+++ b/chrome/browser/gtk/toolbar_star_toggle_gtk.h
@@ -11,12 +11,13 @@
#include "chrome/browser/gtk/custom_button.h"
#include "chrome/common/owned_widget_gtk.h"
+class BrowserToolbarGtk;
class GURL;
// Displays the bookmark star button, which toggles between two images.
class ToolbarStarToggleGtk {
public:
- ToolbarStarToggleGtk();
+ ToolbarStarToggleGtk(BrowserToolbarGtk* host);
~ToolbarStarToggleGtk();
// If the bubble isn't showing, shows it above the star button.
@@ -31,6 +32,9 @@ class ToolbarStarToggleGtk {
static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* e,
ToolbarStarToggleGtk* obj);
+ // The browser toolbar hosting this widget, for getting the current profile.
+ BrowserToolbarGtk* host_;
+
// The actual button widget.
OwnedWidgetGtk widget_;