Index: chrome/browser/gtk/bookmark_editor_gtk.cc |
diff --git a/chrome/browser/gtk/bookmark_editor_gtk.cc b/chrome/browser/gtk/bookmark_editor_gtk.cc |
index 5aafc6c73609a2f6f1f46e0564502f71fc2d146f..f7cf7610cbedff42088e74fa834d25123cfa3fa7 100644 |
--- a/chrome/browser/gtk/bookmark_editor_gtk.cc |
+++ b/chrome/browser/gtk/bookmark_editor_gtk.cc |
@@ -7,6 +7,7 @@ |
#include <gtk/gtk.h> |
#include "app/l10n_util.h" |
+#include "app/menus/simple_menu_model.h" |
#include "base/basictypes.h" |
#include "base/logging.h" |
#include "base/string_util.h" |
@@ -17,6 +18,7 @@ |
#include "chrome/browser/gtk/bookmark_utils_gtk.h" |
#include "chrome/browser/gtk/gtk_theme_provider.h" |
#include "chrome/browser/gtk/gtk_util.h" |
+#include "chrome/browser/gtk/menu_gtk.h" |
#include "chrome/browser/history/history.h" |
#include "chrome/browser/net/url_fixer_upper.h" |
#include "chrome/browser/profile.h" |
@@ -37,6 +39,127 @@ static const int kTreeHeight = 150; |
} // namespace |
+class BookmarkEditorGtk::ContextMenuController |
+ : public menus::SimpleMenuModel::Delegate { |
+ public: |
+ explicit ContextMenuController(BookmarkEditorGtk* editor) |
+ : editor_(editor), |
+ running_menu_for_root_(false) { |
+ menu_model_.reset(new menus::SimpleMenuModel(this)); |
+ menu_model_->AddItemWithStringId(COMMAND_EDIT, IDS_EDIT); |
+ menu_model_->AddItemWithStringId( |
+ COMMAND_NEW_FOLDER, |
+ IDS_BOOMARK_EDITOR_NEW_FOLDER_MENU_ITEM); |
+ menu_.reset(new MenuGtk(NULL, menu_model_.get())); |
+ } |
+ virtual ~ContextMenuController() {} |
+ |
+ void RunMenu() { |
+ const BookmarkNode* selected_node = GetSelectedNode(); |
+ if (selected_node) |
+ running_menu_for_root_ = selected_node->GetParent()->IsRoot(); |
+ menu_->PopupAsContext(gtk_get_current_event_time()); |
+ } |
+ |
+ void Cancel() { |
+ editor_ = NULL; |
+ menu_->Cancel(); |
+ } |
+ |
+ private: |
+ enum ContextMenuCommand { |
+ COMMAND_EDIT, |
+ COMMAND_NEW_FOLDER |
+ }; |
+ |
+ // Overridden from menus::SimpleMenuModel::Delegate: |
+ virtual bool IsCommandIdEnabled(int command_id) const { |
+ return !(command_id == COMMAND_EDIT && running_menu_for_root_) && |
+ (editor_ != NULL); |
+ } |
+ |
+ virtual bool IsCommandIdChecked(int command_id) const { |
+ return false; |
+ } |
+ |
+ virtual bool GetAcceleratorForCommandId(int command_id, |
+ menus::Accelerator* accelerator) { |
+ return false; |
+ } |
+ |
+ virtual void ExecuteCommand(int command_id) { |
+ if (!editor_) |
+ return; |
+ |
+ switch (command_id) { |
+ case COMMAND_EDIT: { |
+ GtkTreeIter iter; |
+ if (!gtk_tree_selection_get_selected(editor_->tree_selection_, |
+ NULL, |
+ &iter)) { |
+ return; |
+ } |
+ |
+ GtkTreePath* path = gtk_tree_model_get_path( |
+ GTK_TREE_MODEL(editor_->tree_store_), &iter); |
+ gtk_tree_view_expand_to_path(GTK_TREE_VIEW(editor_->tree_view_), path); |
+ |
+ // Make the folder name editable. |
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(editor_->tree_view_), path, |
+ gtk_tree_view_get_column(GTK_TREE_VIEW(editor_->tree_view_), 0), |
+ TRUE); |
+ |
+ gtk_tree_path_free(path); |
+ break; |
+ } |
+ case COMMAND_NEW_FOLDER: |
+ editor_->NewFolder(); |
+ break; |
+ default: |
+ NOTREACHED(); |
+ break; |
+ } |
+ } |
+ |
+ int64 GetRowIdAt(GtkTreeModel* model, GtkTreeIter* iter) { |
+ GValue value = { 0, }; |
+ gtk_tree_model_get_value(model, iter, bookmark_utils::ITEM_ID, &value); |
+ int64 id = g_value_get_int64(&value); |
+ g_value_unset(&value); |
+ return id; |
+ } |
+ |
+ const BookmarkNode* GetNodeAt(GtkTreeModel* model, GtkTreeIter* iter) { |
+ int64 id = GetRowIdAt(model, iter); |
+ return (id > 0) ? editor_->bb_model_->GetNodeByID(id) : NULL; |
+ } |
+ |
+ const BookmarkNode* GetSelectedNode() { |
+ GtkTreeModel* model; |
+ GtkTreeIter iter; |
+ if (!gtk_tree_selection_get_selected(editor_->tree_selection_, |
+ &model, |
+ &iter)) { |
+ return NULL; |
+ } |
+ |
+ return GetNodeAt(model, &iter); |
+ } |
+ |
+ // The model and view for the right click context menu. |
+ scoped_ptr<menus::SimpleMenuModel> menu_model_; |
+ scoped_ptr<MenuGtk> menu_; |
+ |
+ // The context menu was brought up for. Set to NULL when the menu is canceled. |
+ BookmarkEditorGtk* editor_; |
+ |
+ // If true, we're running the menu for the bookmark bar or other bookmarks |
+ // nodes. |
+ bool running_menu_for_root_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ContextMenuController); |
+}; |
+ |
// static |
void BookmarkEditor::Show(gfx::NativeWindow parent_hwnd, |
Profile* profile, |
@@ -181,6 +304,8 @@ void BookmarkEditorGtk::Init(GtkWindow* parent_window) { |
tree_view_ = bookmark_utils::MakeTreeViewForStore(tree_store_); |
gtk_widget_set_size_request(tree_view_, kTreeWidth, kTreeHeight); |
tree_selection_ = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view_)); |
+ g_signal_connect(tree_view_, "button-press-event", |
+ G_CALLBACK(OnTreeViewButtonPressEventThunk), this); |
GtkTreePath* path = NULL; |
if (selected_id) { |
@@ -396,6 +521,25 @@ void BookmarkEditorGtk::OnEntryChanged(GtkWidget* entry) { |
} |
void BookmarkEditorGtk::OnNewFolderClicked(GtkWidget* button) { |
+ NewFolder(); |
+} |
+ |
+gboolean BookmarkEditorGtk::OnTreeViewButtonPressEvent(GtkWidget* widget, |
+ GdkEventButton* event) { |
+ if (event->button == 3) |
+ ShowContextMenu(); |
+ |
+ return FALSE; |
+} |
+ |
+void BookmarkEditorGtk::ShowContextMenu() { |
+ if (!menu_controller_.get()) |
+ menu_controller_.reset(new ContextMenuController(this)); |
+ |
+ menu_controller_->RunMenu(); |
+} |
+ |
+void BookmarkEditorGtk::NewFolder() { |
GtkTreeIter iter; |
if (!gtk_tree_selection_get_selected(tree_selection_, |
NULL, |