Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: chrome/browser/gtk/bookmark_tree_model.cc

Issue 6251001: Move chrome/browser/gtk/ to chrome/browser/ui/gtk/... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/gtk/bookmark_tree_model.h ('k') | chrome/browser/gtk/bookmark_utils_gtk.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/gtk/bookmark_tree_model.h"
6
7 #include <gtk/gtk.h>
8
9 #include "base/string_util.h"
10 #include "base/utf_string_conversions.h"
11 #include "chrome/browser/bookmarks/bookmark_model.h"
12 #include "chrome/browser/gtk/bookmark_utils_gtk.h"
13 #include "chrome/browser/gtk/gtk_theme_provider.h"
14
15 namespace {
16
17 const char* kCellRendererTextKey = "__CELL_RENDERER_TEXT__";
18
19 void AddSingleNodeToTreeStore(GtkTreeStore* store, const BookmarkNode* node,
20 GtkTreeIter *iter, GtkTreeIter* parent) {
21 gtk_tree_store_append(store, iter, parent);
22 // It would be easy to show a different icon when the folder is open (as they
23 // do on Windows, for example), using pixbuf-expander-closed and
24 // pixbuf-expander-open. Unfortunately there is no GTK_STOCK_OPEN_DIRECTORY
25 // (and indeed, Nautilus does not render an expanded directory any
26 // differently).
27 gtk_tree_store_set(store, iter,
28 bookmark_utils::FOLDER_ICON, GtkThemeProvider::GetFolderIcon(true),
29 bookmark_utils::FOLDER_NAME,
30 UTF16ToUTF8(node->GetTitle()).c_str(),
31 bookmark_utils::ITEM_ID, node->id(),
32 // We don't want to use node->is_folder() because that would let the
33 // user edit "Bookmarks Bar" and "Other Bookmarks".
34 bookmark_utils::IS_EDITABLE, node->type() == BookmarkNode::FOLDER,
35 -1);
36 }
37
38 // Helper function for CommitTreeStoreDifferencesBetween() which recursively
39 // merges changes back from a GtkTreeStore into a tree of BookmarkNodes. This
40 // function only works on non-root nodes; our caller handles that special case.
41 void RecursiveResolve(BookmarkModel* bb_model, const BookmarkNode* bb_node,
42 GtkTreeModel* tree_model, GtkTreeIter* parent_iter,
43 GtkTreePath* selected_path,
44 const BookmarkNode** selected_node) {
45 GtkTreePath* current_path = gtk_tree_model_get_path(tree_model, parent_iter);
46 if (gtk_tree_path_compare(current_path, selected_path) == 0)
47 *selected_node = bb_node;
48 gtk_tree_path_free(current_path);
49
50 GtkTreeIter child_iter;
51 if (gtk_tree_model_iter_children(tree_model, &child_iter, parent_iter)) {
52 do {
53 int64 id = bookmark_utils::GetIdFromTreeIter(tree_model, &child_iter);
54 string16 title =
55 bookmark_utils::GetTitleFromTreeIter(tree_model, &child_iter);
56 const BookmarkNode* child_bb_node = NULL;
57 if (id == 0) {
58 child_bb_node = bb_model->AddGroup(bb_node, bb_node->GetChildCount(),
59 title);
60 } else {
61 // Existing node, reset the title (BBModel ignores changes if the title
62 // is the same).
63 for (int j = 0; j < bb_node->GetChildCount(); ++j) {
64 const BookmarkNode* node = bb_node->GetChild(j);
65 if (node->is_folder() && node->id() == id) {
66 child_bb_node = node;
67 break;
68 }
69 }
70 DCHECK(child_bb_node);
71 bb_model->SetTitle(child_bb_node, title);
72 }
73 RecursiveResolve(bb_model, child_bb_node,
74 tree_model, &child_iter,
75 selected_path, selected_node);
76 } while (gtk_tree_model_iter_next(tree_model, &child_iter));
77 }
78 }
79
80 // Update the folder name in the GtkTreeStore.
81 void OnFolderNameEdited(GtkCellRendererText* render,
82 gchar* path, gchar* new_folder_name, GtkTreeStore* tree_store) {
83 GtkTreeIter folder_iter;
84 GtkTreePath* tree_path = gtk_tree_path_new_from_string(path);
85 gboolean rv = gtk_tree_model_get_iter(GTK_TREE_MODEL(tree_store),
86 &folder_iter, tree_path);
87 DCHECK(rv);
88 gtk_tree_store_set(tree_store, &folder_iter,
89 bookmark_utils::FOLDER_NAME, new_folder_name,
90 -1);
91 gtk_tree_path_free(tree_path);
92 }
93
94 } // namespace
95
96 namespace bookmark_utils {
97
98 GtkTreeStore* MakeFolderTreeStore() {
99 return gtk_tree_store_new(FOLDER_STORE_NUM_COLUMNS, GDK_TYPE_PIXBUF,
100 G_TYPE_STRING, G_TYPE_INT64, G_TYPE_BOOLEAN);
101 }
102
103 void AddToTreeStore(BookmarkModel* model, int64 selected_id,
104 GtkTreeStore* store, GtkTreeIter* selected_iter) {
105 const BookmarkNode* root_node = model->root_node();
106 for (int i = 0; i < root_node->GetChildCount(); ++i) {
107 AddToTreeStoreAt(root_node->GetChild(i), selected_id, store, selected_iter,
108 NULL);
109 }
110 }
111
112 GtkWidget* MakeTreeViewForStore(GtkTreeStore* store) {
113 GtkTreeViewColumn* column = gtk_tree_view_column_new();
114 GtkCellRenderer* image_renderer = gtk_cell_renderer_pixbuf_new();
115 gtk_tree_view_column_pack_start(column, image_renderer, FALSE);
116 gtk_tree_view_column_add_attribute(column, image_renderer,
117 "pixbuf", FOLDER_ICON);
118 GtkCellRenderer* text_renderer = gtk_cell_renderer_text_new();
119 g_object_set(text_renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
120 g_signal_connect(text_renderer, "edited", G_CALLBACK(OnFolderNameEdited),
121 store);
122 gtk_tree_view_column_pack_start(column, text_renderer, TRUE);
123 gtk_tree_view_column_set_attributes(column, text_renderer,
124 "text", FOLDER_NAME,
125 "editable", IS_EDITABLE,
126 NULL);
127
128 GtkWidget* tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
129 // Let |tree_view| own the store.
130 g_object_unref(store);
131 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), FALSE);
132 gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
133 g_object_set_data(G_OBJECT(tree_view), kCellRendererTextKey, text_renderer);
134 return tree_view;
135 }
136
137 GtkCellRenderer* GetCellRendererText(GtkTreeView* tree_view) {
138 return static_cast<GtkCellRenderer*>(
139 g_object_get_data(G_OBJECT(tree_view), kCellRendererTextKey));
140 }
141
142 void AddToTreeStoreAt(const BookmarkNode* node, int64 selected_id,
143 GtkTreeStore* store, GtkTreeIter* selected_iter,
144 GtkTreeIter* parent) {
145 if (!node->is_folder())
146 return;
147
148 GtkTreeIter iter;
149 AddSingleNodeToTreeStore(store, node, &iter, parent);
150 if (selected_iter && node->id() == selected_id) {
151 // Save the iterator. Since we're using a GtkTreeStore, we're
152 // guaranteed that the iterator will remain valid as long as the above
153 // appended item exists.
154 *selected_iter = iter;
155 }
156
157 for (int i = 0; i < node->GetChildCount(); ++i) {
158 AddToTreeStoreAt(node->GetChild(i), selected_id, store, selected_iter,
159 &iter);
160 }
161 }
162
163 const BookmarkNode* CommitTreeStoreDifferencesBetween(
164 BookmarkModel* bb_model, GtkTreeStore* tree_store, GtkTreeIter* selected) {
165 const BookmarkNode* node_to_return = NULL;
166 GtkTreeModel* tree_model = GTK_TREE_MODEL(tree_store);
167
168 GtkTreePath* selected_path = gtk_tree_model_get_path(tree_model, selected);
169
170 GtkTreeIter tree_root;
171 if (!gtk_tree_model_get_iter_first(tree_model, &tree_root))
172 NOTREACHED() << "Impossible missing bookmarks case";
173
174 // The top level of this tree is weird and needs to be special cased. The
175 // BookmarksNode tree is rooted on a root node while the GtkTreeStore has a
176 // set of top level nodes that are the root BookmarksNode's children. These
177 // items in the top level are not editable and therefore don't need the extra
178 // complexity of trying to modify their title.
179 const BookmarkNode* root_node = bb_model->root_node();
180 do {
181 DCHECK(GetIdFromTreeIter(tree_model, &tree_root) != 0)
182 << "It should be impossible to add another toplevel node";
183
184 int64 id = GetIdFromTreeIter(tree_model, &tree_root);
185 const BookmarkNode* child_node = NULL;
186 for (int j = 0; j < root_node->GetChildCount(); ++j) {
187 const BookmarkNode* node = root_node->GetChild(j);
188 if (node->is_folder() && node->id() == id) {
189 child_node = node;
190 break;
191 }
192 }
193 DCHECK(child_node);
194
195 GtkTreeIter child_iter = tree_root;
196 RecursiveResolve(bb_model, child_node, tree_model, &child_iter,
197 selected_path, &node_to_return);
198 } while (gtk_tree_model_iter_next(tree_model, &tree_root));
199
200 gtk_tree_path_free(selected_path);
201 return node_to_return;
202 }
203
204 int64 GetIdFromTreeIter(GtkTreeModel* model, GtkTreeIter* iter) {
205 GValue value = { 0, };
206 int64 ret_val = -1;
207 gtk_tree_model_get_value(model, iter, ITEM_ID, &value);
208 if (G_VALUE_HOLDS_INT64(&value))
209 ret_val = g_value_get_int64(&value);
210 else
211 NOTREACHED() << "Impossible type mismatch";
212
213 return ret_val;
214 }
215
216 string16 GetTitleFromTreeIter(GtkTreeModel* model, GtkTreeIter* iter) {
217 GValue value = { 0, };
218 string16 ret_val;
219 gtk_tree_model_get_value(model, iter, FOLDER_NAME, &value);
220 if (G_VALUE_HOLDS_STRING(&value)) {
221 const gchar* utf8str = g_value_get_string(&value);
222 ret_val = UTF8ToUTF16(utf8str);
223 g_value_unset(&value);
224 } else {
225 NOTREACHED() << "Impossible type mismatch";
226 }
227
228 return ret_val;
229 }
230
231 } // namespace bookmark_utils
OLDNEW
« no previous file with comments | « chrome/browser/gtk/bookmark_tree_model.h ('k') | chrome/browser/gtk/bookmark_utils_gtk.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698