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