summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-08 18:21:13 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-08 18:21:13 +0000
commit55fcfecae5b94e21f98227c421d7d1525d2ba41d (patch)
treefcb2e0af616f5a60e094d58cc03f5a493397ee8b
parente662ade1be2692f710ad9dba1bafc179d29c3400 (diff)
downloadchromium_src-55fcfecae5b94e21f98227c421d7d1525d2ba41d.zip
chromium_src-55fcfecae5b94e21f98227c421d7d1525d2ba41d.tar.gz
chromium_src-55fcfecae5b94e21f98227c421d7d1525d2ba41d.tar.bz2
GTK: More drag support for bookmark manager.
- drag into folders - improve pre-drop highlighting - use default drag icon instead of row bitmap for tree view row drag. Review URL: http://codereview.chromium.org/118357 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17880 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/gtk/bookmark_manager_gtk.cc101
-rw-r--r--chrome/browser/gtk/bookmark_manager_gtk.h28
2 files changed, 107 insertions, 22 deletions
diff --git a/chrome/browser/gtk/bookmark_manager_gtk.cc b/chrome/browser/gtk/bookmark_manager_gtk.cc
index 7c864c6..8b6a62a 100644
--- a/chrome/browser/gtk/bookmark_manager_gtk.cc
+++ b/chrome/browser/gtk/bookmark_manager_gtk.cc
@@ -72,9 +72,9 @@ void BookmarkManagerGtk::Show(Profile* profile) {
}
void BookmarkManagerGtk::BookmarkManagerGtk::Loaded(BookmarkModel* model) {
- ToggleUpdatesToRightStore();
+ SuppressUpdatesToRightStore();
BuildLeftStore();
- ToggleUpdatesToRightStore();
+ AllowUpdatesToRightStore();
}
void BookmarkManagerGtk::BookmarkModelBeingDeleted(BookmarkModel* model) {
@@ -86,7 +86,7 @@ void BookmarkManagerGtk::BookmarkModelBeingDeleted(BookmarkModel* model) {
BookmarkManagerGtk::BookmarkManagerGtk(Profile* profile)
: profile_(profile),
model_(profile->GetBookmarkModel()),
- update_right_store_(true) {
+ updates_suppressions_(0) {
InitWidgets();
g_signal_connect(window_, "destroy",
G_CALLBACK(OnWindowDestroy), this);
@@ -224,6 +224,13 @@ GtkWidget* BookmarkManagerGtk::MakeRightPane() {
G_CALLBACK(&OnTreeViewDragGet), this);
g_signal_connect(right_tree_view_, "drag-data-received",
G_CALLBACK(&OnTreeViewDragReceived), this);
+ g_signal_connect(right_tree_view_, "drag-motion",
+ G_CALLBACK(&OnTreeViewDragMotion), this);
+ // Connect after so we can overwrite the drag icon.
+ g_signal_connect_after(right_tree_view_, "drag-begin",
+ G_CALLBACK(&OnTreeViewDragBegin), this);
+ g_signal_connect(right_tree_view_, "drag-end",
+ G_CALLBACK(&OnTreeViewDragEnd), this);
GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
@@ -245,7 +252,7 @@ void BookmarkManagerGtk::BuildLeftStore() {
}
void BookmarkManagerGtk::BuildRightStore() {
- if (!update_right_store_)
+ if (update_suppressions_ > 0)
return;
BookmarkNode* node = GetFolder();
@@ -308,9 +315,15 @@ void BookmarkManagerGtk::AppendNodeToRightStore(BookmarkNode* node,
g_object_unref(pixbuf);
}
-void BookmarkManagerGtk::ToggleUpdatesToRightStore() {
- update_right_store_ = !update_right_store_;
- if (update_right_store_)
+void BookmarkManagerGtk::SuppressUpdatesToRightStore() {
+ update_suppressions_++;
+}
+
+void BookmarkManagerGtk::AllowUpdatesToRightStore() {
+ update_suppressions_--;
+ DCHECK_GE(update_suppressions_, 0);
+
+ if (update_suppressions_ <= 0)
BuildRightStore();
}
@@ -376,6 +389,10 @@ void BookmarkManagerGtk::OnTreeViewDragReceived(
bool drop_before = pos == GTK_TREE_VIEW_DROP_BEFORE;
bool drop_after = pos == GTK_TREE_VIEW_DROP_AFTER;
+ // The parent folder and index therein to drop the nodes.
+ BookmarkNode* parent = NULL;
+ int idx = -1;
+
// |path| will be null when we are looking at an empty folder.
if (!drop_before && !drop_after && path) {
GtkTreeIter iter;
@@ -383,7 +400,8 @@ void BookmarkManagerGtk::OnTreeViewDragReceived(
gtk_tree_model_get_iter(model, &iter, path);
BookmarkNode* node = bm->GetNodeAt(model, &iter);
if (node->is_folder()) {
- // TODO(estade): drop into the folder.
+ parent = node;
+ idx = parent->GetChildCount();
} else {
drop_before = pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE;
drop_after = pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER;
@@ -397,17 +415,70 @@ void BookmarkManagerGtk::OnTreeViewDragReceived(
else
gtk_tree_path_next(path);
}
- int idx = !path ? 0 :
+ // We will get a null path when the drop is below the lowest row.
+ parent = bm->GetFolder();
+ idx = !path ? parent->GetChildCount() :
gtk_tree_path_get_indices(path)[gtk_tree_path_get_depth(path) - 1];
- BookmarkNode* parent = bm->GetFolder();
+ }
- bm->ToggleUpdatesToRightStore();
- for (std::vector<BookmarkNode*>::iterator it = nodes.begin();
- it != nodes.end(); ++it) {
+ br->SuppressUpdatesToRightStore();
+ for (std::vector<BookmarkNode*>::iterator it = nodes.begin();
+ it != nodes.end(); ++it) {
+ // Don't try to drop a node into one of its descendants.
+ if (!parent->HasAncestor(*it))
bm->model_->Move(*it, parent, idx++);
- }
- bm->ToggleUpdatesToRightStore();
}
+ bookmark_manager->AllowUpdatesToRightStore();
+ gtk_tree_path_free(path);
gtk_drag_finish(context, dnd_success, delete_selection_data, time);
}
+
+// static
+void BookmarkManagerGtk::OnTreeViewDragBegin(
+ GtkWidget* tree_view,
+ GdkDragContext* drag_context,
+ BookmarkManagerGtk* bookmark_manager) {
+ gtk_drag_set_icon_stock(drag_context, GTK_STOCK_DND, 0, 0);
+ // Balanced in OnTreeViewDragEnd().
+ bookmark_manager->SuppressUpdatesToRightStore();
+}
+
+// static
+void BookmarkManagerGtk::OnTreeViewDragEnd(
+ GtkWidget* tree_view,
+ GdkDragContext* drag_context,
+ BookmarkManagerGtk* bookmark_manager) {
+ // Balanced in OnTreeViewDragBegin().
+ bookmark_manager->AllowUpdatesToRightStore();
+}
+
+// static
+gboolean BookmarkManagerGtk::OnTreeViewDragMotion(
+ GtkWidget* tree_view, GdkDragContext* context, gint x, gint y, guint time,
+ BookmarkManagerGtk* bm) {
+ GtkTreePath* path;
+ GtkTreeViewDropPosition pos;
+ gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(tree_view), x, y,
+ &path, &pos);
+
+ BookmarkNode* parent = bm->GetSelectedNode(bm->left_selection());
+ if (path) {
+ int idx =
+ gtk_tree_path_get_indices(path)[gtk_tree_path_get_depth(path) - 1];
+ // Only allow INTO if the node is a folder.
+ if (parent->GetChild(idx)->is_url()) {
+ if (pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE)
+ pos = GTK_TREE_VIEW_DROP_BEFORE;
+ else if (pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER)
+ pos = GTK_TREE_VIEW_DROP_AFTER;
+ }
+ gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(tree_view), path, pos);
+ } else {
+ // We allow a drop if the drag is over the bottom of the tree view,
+ // but we don't draw any indication.
+ }
+
+ gdk_drag_status(context, GDK_ACTION_MOVE, time);
+ return TRUE;
+}
diff --git a/chrome/browser/gtk/bookmark_manager_gtk.h b/chrome/browser/gtk/bookmark_manager_gtk.h
index bb3028d..dd47091 100644
--- a/chrome/browser/gtk/bookmark_manager_gtk.h
+++ b/chrome/browser/gtk/bookmark_manager_gtk.h
@@ -87,9 +87,11 @@ class BookmarkManagerGtk : public BookmarkModelObserver {
return gtk_tree_view_get_selection(GTK_TREE_VIEW(right_tree_view_));
}
- // Use this to temporarily disable updating the right store. When this is
- // called again, the right store will be updated once.
- void ToggleUpdatesToRightStore();
+ // Use these to temporarily disable updating the right store. You can stack
+ // calls to Suppress(), but they should always be matched by an equal number
+ // of calls to Allow().
+ void SuppressUpdatesToRightStore();
+ void AllowUpdatesToRightStore();
static void OnLeftSelectionChanged(GtkTreeSelection* selection,
BookmarkManagerGtk* bookmark_manager);
@@ -103,9 +105,21 @@ class BookmarkManagerGtk : public BookmarkModelObserver {
BookmarkManagerGtk* bookmark_manager);
static void OnTreeViewDragReceived(
- GtkWidget* tree_view, GdkDragContext* context, gint x, gint y,
- GtkSelectionData* selection_data, guint target_type, guint time,
- BookmarkManagerGtk* bookmark_manager);
+ GtkWidget* tree_view, GdkDragContext* context, gint x, gint y,
+ GtkSelectionData* selection_data, guint target_type, guint time,
+ BookmarkManagerGtk* bookmark_manager);
+
+ static void OnTreeViewDragBegin(GtkWidget* tree_view,
+ GdkDragContext* drag_context,
+ BookmarkManagerGtk* bookmark_manager);
+
+ static void OnTreeViewDragEnd(GtkWidget* tree_view,
+ GdkDragContext* drag_context,
+ BookmarkManagerGtk* bookmark_manager);
+
+ static gboolean OnTreeViewDragMotion(GtkWidget* tree_view,
+ GdkDragContext* context, gint x, gint y, guint time,
+ BookmarkManagerGtk* bookmark_manager);
GtkWidget* window_;
Profile* profile_;
@@ -122,7 +136,7 @@ class BookmarkManagerGtk : public BookmarkModelObserver {
};
GtkTreeStore* left_store_;
GtkListStore* right_store_;
- bool update_right_store_;
+ int update_suppressions_;
scoped_ptr<BookmarkContextMenu> organize_menu_;
};