diff options
Diffstat (limited to 'chrome/browser/gtk/bookmark_manager_gtk.cc')
-rw-r--r-- | chrome/browser/gtk/bookmark_manager_gtk.cc | 251 |
1 files changed, 208 insertions, 43 deletions
diff --git a/chrome/browser/gtk/bookmark_manager_gtk.cc b/chrome/browser/gtk/bookmark_manager_gtk.cc index 3618e77..a591cf2 100644 --- a/chrome/browser/gtk/bookmark_manager_gtk.cc +++ b/chrome/browser/gtk/bookmark_manager_gtk.cc @@ -72,21 +72,106 @@ void BookmarkManagerGtk::Show(Profile* profile) { } void BookmarkManagerGtk::BookmarkManagerGtk::Loaded(BookmarkModel* model) { - SuppressUpdatesToRightStore(); BuildLeftStore(); - AllowUpdatesToRightStore(); + BuildRightStore(); + g_signal_connect(left_selection(), "changed", + G_CALLBACK(OnLeftSelectionChanged), this); } void BookmarkManagerGtk::BookmarkModelBeingDeleted(BookmarkModel* model) { gtk_widget_destroy(window_); } +void BookmarkManagerGtk::BookmarkNodeMoved(BookmarkModel* model, + BookmarkNode* old_parent, + int old_index, + BookmarkNode* new_parent, + int new_index) { + BookmarkNodeRemoved(model, old_parent, old_index, + new_parent->GetChild(new_index)); + BookmarkNodeAdded(model, new_parent, new_index); +} + +void BookmarkManagerGtk::BookmarkNodeAdded(BookmarkModel* model, + BookmarkNode* parent, + int index) { + BookmarkNode* node = parent->GetChild(index); + // Update left store. + if (node->is_folder()) { + GtkTreeIter iter; + gtk_tree_model_get_iter_first(GTK_TREE_MODEL(left_store_), &iter); + + if (RecursiveFind(GTK_TREE_MODEL(left_store_), &iter, parent->id())) + bookmark_utils::AddToTreeStoreAt(node, 0, left_store_, NULL, &iter); + } + + // Update right store. + if (parent->id() == GetFolder()->id()) { + GtkTreeIter iter; + gtk_tree_model_get_iter_first(GTK_TREE_MODEL(right_store_), &iter); + + if (RecursiveFind(GTK_TREE_MODEL(right_store_), &iter, + parent->GetChild(index - 1)->id())) { + AppendNodeToRightStore(node, &iter); + } + } +} + +void BookmarkManagerGtk::BookmarkNodeRemoved(BookmarkModel* model, + BookmarkNode* parent, + int index) { + NOTREACHED(); +} + +void BookmarkManagerGtk::BookmarkNodeRemoved(BookmarkModel* model, + BookmarkNode* parent, + int old_index, + BookmarkNode* node) { + if (node->is_folder()) { + GtkTreeIter iter; + gtk_tree_model_get_iter_first(GTK_TREE_MODEL(left_store_), &iter); + + if (RecursiveFind(GTK_TREE_MODEL(left_store_), &iter, node->id())) { + // If we are deleting the currently selected folder, set the selection to + // its parent. + if (gtk_tree_selection_iter_is_selected(left_selection(), &iter)) { + GtkTreeIter parent; + gtk_tree_model_iter_parent(GTK_TREE_MODEL(left_store_), &parent, &iter); + gtk_tree_selection_select_iter(left_selection(), &parent); + } + + gtk_tree_store_remove(left_store_, &iter); + } + } + + GtkTreeIter iter; + gtk_tree_model_get_iter_first(GTK_TREE_MODEL(right_store_), &iter); + + if (RecursiveFind(GTK_TREE_MODEL(right_store_), &iter, node->id())) + gtk_list_store_remove(right_store_, &iter); +} + +void BookmarkManagerGtk::BookmarkNodeChanged(BookmarkModel* model, + BookmarkNode* node) { + // TODO(estade): implement. +} + +void BookmarkManagerGtk::BookmarkNodeChildrenReordered(BookmarkModel* model, + BookmarkNode* node) { + if (node->id() == GetFolder()->id()) + BuildRightStore(); +} + +void BookmarkManagerGtk::BookmarkNodeFavIconLoaded(BookmarkModel* model, + BookmarkNode* node) { + // TODO(estade): implement. +} + // BookmarkManagerGtk, private ------------------------------------------------- BookmarkManagerGtk::BookmarkManagerGtk(Profile* profile) : profile_(profile), - model_(profile->GetBookmarkModel()), - update_suppressions_(0) { + model_(profile->GetBookmarkModel()) { InitWidgets(); g_signal_connect(window_, "destroy", G_CALLBACK(OnWindowDestroy), this); @@ -173,6 +258,17 @@ GtkWidget* BookmarkManagerGtk::MakeLeftPane() { gtk_tree_view_append_column(GTK_TREE_VIEW(left_tree_view_), icon_column); gtk_tree_view_append_column(GTK_TREE_VIEW(left_tree_view_), name_column); + // The left side is only a drag destination (not a source). + gtk_drag_dest_set(left_tree_view_, GTK_DEST_DEFAULT_DROP, + bookmark_utils::kTargetTable, + bookmark_utils::kTargetTableSize, + GDK_ACTION_MOVE); + + g_signal_connect(left_tree_view_, "drag-data-received", + G_CALLBACK(&OnLeftTreeViewDragReceived), this); + g_signal_connect(left_tree_view_, "drag-motion", + G_CALLBACK(&OnLeftTreeViewDragMotion), this); + GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); @@ -189,6 +285,8 @@ GtkWidget* BookmarkManagerGtk::MakeRightPane() { G_TYPE_STRING, G_TYPE_INT); GtkTreeViewColumn* title_column = gtk_tree_view_column_new(); + gtk_tree_view_column_set_title(title_column, + l10n_util::GetStringUTF8(IDS_BOOKMARK_TABLE_TITLE).c_str()); GtkCellRenderer* image_renderer = gtk_cell_renderer_pixbuf_new(); gtk_tree_view_column_pack_start(title_column, image_renderer, FALSE); gtk_tree_view_column_add_attribute(title_column, image_renderer, @@ -206,8 +304,6 @@ GtkWidget* BookmarkManagerGtk::MakeRightPane() { g_object_unref(right_store_); gtk_tree_view_append_column(GTK_TREE_VIEW(right_tree_view_), title_column); gtk_tree_view_append_column(GTK_TREE_VIEW(right_tree_view_), url_column); - g_signal_connect(left_selection(), "changed", - G_CALLBACK(OnLeftSelectionChanged), this); g_signal_connect(right_selection(), "changed", G_CALLBACK(OnRightSelectionChanged), this); @@ -221,16 +317,14 @@ GtkWidget* BookmarkManagerGtk::MakeRightPane() { bookmark_utils::kTargetTableSize, GDK_ACTION_MOVE); g_signal_connect(right_tree_view_, "drag-data-get", - G_CALLBACK(&OnTreeViewDragGet), this); + G_CALLBACK(&OnRightTreeViewDragGet), this); g_signal_connect(right_tree_view_, "drag-data-received", - G_CALLBACK(&OnTreeViewDragReceived), this); + G_CALLBACK(&OnRightTreeViewDragReceived), this); g_signal_connect(right_tree_view_, "drag-motion", - G_CALLBACK(&OnTreeViewDragMotion), this); + G_CALLBACK(&OnRightTreeViewDragMotion), 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); + G_CALLBACK(&OnRightTreeViewDragBegin), this); GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), @@ -252,9 +346,6 @@ void BookmarkManagerGtk::BuildLeftStore() { } void BookmarkManagerGtk::BuildRightStore() { - if (update_suppressions_ > 0) - return; - BookmarkNode* node = GetFolder(); // TODO(estade): eventually we may hit a fake node here (recently bookmarked // or search), but until then we require that node != NULL. @@ -304,7 +395,7 @@ std::vector<BookmarkNode*> BookmarkManagerGtk::GetRightSelection() { } void BookmarkManagerGtk::AppendNodeToRightStore(BookmarkNode* node, - GtkTreeIter* iter) { + GtkTreeIter* iter) { GdkPixbuf* pixbuf = bookmark_utils::GetPixbufForNode(node, model_); gtk_list_store_append(right_store_, iter); gtk_list_store_set(right_store_, iter, @@ -315,16 +406,37 @@ void BookmarkManagerGtk::AppendNodeToRightStore(BookmarkNode* node, g_object_unref(pixbuf); } -void BookmarkManagerGtk::SuppressUpdatesToRightStore() { - update_suppressions_++; -} +bool BookmarkManagerGtk::RecursiveFind(GtkTreeModel* model, GtkTreeIter* iter, + int target) { + GValue value = { 0, }; + bool left = model == GTK_TREE_MODEL(left_store_); + if (left) + gtk_tree_model_get_value(model, iter, bookmark_utils::ITEM_ID, &value); + else + gtk_tree_model_get_value(model, iter, RIGHT_PANE_ID, &value); + int id = g_value_get_int(&value); + g_value_unset(&value); -void BookmarkManagerGtk::AllowUpdatesToRightStore() { - update_suppressions_--; - DCHECK_GE(update_suppressions_, 0); + if (id == target) { + return true; + } - if (update_suppressions_ <= 0) - BuildRightStore(); + GtkTreeIter child; + // Check the first child. + if (gtk_tree_model_iter_children(model, &child, iter)) { + if (RecursiveFind(model, &child, target)) { + *iter = child; + return true; + } + } + + // Check siblings. + while (gtk_tree_model_iter_next(model, iter)) { + if (RecursiveFind(model, iter, target)) + return true; + } + + return false; } // static @@ -348,8 +460,76 @@ void BookmarkManagerGtk::OnRightSelectionChanged(GtkTreeSelection* selection, bookmark_manager->GetRightSelection()); } +// statuc +void BookmarkManagerGtk::OnLeftTreeViewDragReceived( + GtkWidget* tree_view, GdkDragContext* context, gint x, gint y, + GtkSelectionData* selection_data, guint target_type, guint time, + BookmarkManagerGtk* bm) { + gboolean dnd_success = FALSE; + gboolean delete_selection_data = FALSE; + + std::vector<BookmarkNode*> nodes = + bookmark_utils::GetNodesFromSelection(context, selection_data, + target_type, + bm->profile_, + &delete_selection_data, + &dnd_success); + + if (nodes.empty()) { + gtk_drag_finish(context, FALSE, delete_selection_data, time); + return; + } + + GtkTreePath* path; + GtkTreeViewDropPosition pos; + gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(tree_view), x, y, + &path, &pos); + if (!path) { + gtk_drag_finish(context, FALSE, delete_selection_data, time); + return; + } + + GtkTreeIter iter; + gtk_tree_model_get_iter(GTK_TREE_MODEL(bm->left_store_), &iter, path); + BookmarkNode* folder = bm->GetNodeAt(GTK_TREE_MODEL(bm->left_store_), &iter); + 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 (!folder->HasAncestor(*it)) + bm->model_->Move(*it, folder, 0); + } + + gtk_tree_path_free(path); + gtk_drag_finish(context, dnd_success, delete_selection_data, time); +} + // static -void BookmarkManagerGtk::OnTreeViewDragGet( +gboolean BookmarkManagerGtk::OnLeftTreeViewDragMotion(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); + + if (path) { + // Only allow INTO. + if (pos == GTK_TREE_VIEW_DROP_BEFORE) + pos = GTK_TREE_VIEW_DROP_INTO_OR_BEFORE; + else if (pos == GTK_TREE_VIEW_DROP_AFTER) + pos = GTK_TREE_VIEW_DROP_INTO_OR_AFTER; + gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(tree_view), path, pos); + } else { + return FALSE; + } + + gdk_drag_status(context, GDK_ACTION_MOVE, time); + gtk_tree_path_free(path); + return TRUE; +} + +// static +void BookmarkManagerGtk::OnRightTreeViewDragGet( GtkWidget* tree_view, GdkDragContext* context, GtkSelectionData* selection_data, guint target_type, guint time, BookmarkManagerGtk* bookmark_manager) { @@ -360,7 +540,7 @@ void BookmarkManagerGtk::OnTreeViewDragGet( } // static -void BookmarkManagerGtk::OnTreeViewDragReceived( +void BookmarkManagerGtk::OnRightTreeViewDragReceived( GtkWidget* tree_view, GdkDragContext* context, gint x, gint y, GtkSelectionData* selection_data, guint target_type, guint time, BookmarkManagerGtk* bm) { @@ -379,8 +559,6 @@ void BookmarkManagerGtk::OnTreeViewDragReceived( return; } - // TODO(estade): Support drops on the left side tree view. - DCHECK_EQ(tree_view, bm->right_tree_view_); GtkTreePath* path; GtkTreeViewDropPosition pos; gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(tree_view), x, y, @@ -421,40 +599,27 @@ void BookmarkManagerGtk::OnTreeViewDragReceived( gtk_tree_path_get_indices(path)[gtk_tree_path_get_depth(path) - 1]; } - bm->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->AllowUpdatesToRightStore(); gtk_tree_path_free(path); gtk_drag_finish(context, dnd_success, delete_selection_data, time); } // static -void BookmarkManagerGtk::OnTreeViewDragBegin( +void BookmarkManagerGtk::OnRightTreeViewDragBegin( 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( +gboolean BookmarkManagerGtk::OnRightTreeViewDragMotion( GtkWidget* tree_view, GdkDragContext* context, gint x, gint y, guint time, BookmarkManagerGtk* bm) { GtkTreePath* path; |