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_utils_gtk.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/pickle.h" 83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string16.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_model.h" 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/bookmarks/bookmark_node_data.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/bookmarks/bookmark_utils.h" 1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_chrome_button.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/gtk/gtk_theme_service.h" 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_util.h" 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/dragdrop/gtk_dnd_util.h" 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h" 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/canvas_skia_paint.h" 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/font.h" 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/gtk_util.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Spacing between the favicon and the text. 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kBarButtonPadding = 4; 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Used in gtk_selection_data_set(). (I assume from this parameter that gtk has 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// to some really exotic hardware...) 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kBitsInAByte = 8; 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Maximum number of characters on a bookmark button. 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst size_t kMaxCharsOnAButton = 15; 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Max size of each component of the button tooltips. 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst size_t kMaxTooltipTitleLength = 100; 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst size_t kMaxTooltipURLLength = 400; 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Padding between the chrome button highlight border and the contents (favicon, 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// text). 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kButtonPaddingTop = 0; 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kButtonPaddingBottom = 0; 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kButtonPaddingLeft = 5; 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kButtonPaddingRight = 0; 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid* AsVoid(const BookmarkNode* node) { 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return const_cast<BookmarkNode*>(node); 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Creates the widget hierarchy for a bookmark button. 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid PackButton(GdkPixbuf* pixbuf, const string16& title, bool ellipsize, 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GtkThemeService* provider, GtkWidget* button) { 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* former_child = gtk_bin_get_child(GTK_BIN(button)); 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (former_child) 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_remove(GTK_CONTAINER(button), former_child); 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We pack the button manually (rather than using gtk_button_set_*) so that 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // we can have finer control over its label. 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf); 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* box = gtk_hbox_new(FALSE, kBarButtonPadding); 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(box), image, FALSE, FALSE, 0); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string label_string = UTF16ToUTF8(title); 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!label_string.empty()) { 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* label = gtk_label_new(label_string.c_str()); 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Until we switch to vector graphics, force the font size. 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::ForceFontSizePixels(label, 13.4); // 13.4px == 10pt @ 96dpi 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Ellipsize long bookmark names. 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ellipsize) { 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_label_set_max_width_chars(GTK_LABEL(label), kMaxCharsOnAButton); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END); 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_box_pack_start(GTK_BOX(box), label, FALSE, FALSE, 0); 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bookmark_utils::SetButtonTextColors(label, provider); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If we are not showing the label, don't set any padding, so that the icon 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // will just be centered. 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (label_string.c_str()) { 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kButtonPaddingTop, kButtonPaddingBottom, 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kButtonPaddingLeft, kButtonPaddingRight); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(alignment), box); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(button), alignment); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show_all(alignment); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kDragRepresentationWidth = 140; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstruct DragRepresentationData { 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkPixbuf* favicon; 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick string16 text; 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkColor text_color; 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DragRepresentationData(GdkPixbuf* favicon, 1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& text, 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkColor text_color) 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : favicon(favicon), 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch text(text), 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch text_color(text_color) { 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_ref(favicon); 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~DragRepresentationData() { 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_unref(favicon); 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(DragRepresentationData); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean OnDragIconExpose(GtkWidget* sender, 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkEventExpose* event, 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DragRepresentationData* data) { 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Clear the background. 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_t* cr = gdk_cairo_create(event->window); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_cairo_rectangle(cr, &event->area); 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_clip(cr); 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_paint(cr); 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gdk_cairo_set_source_pixbuf(cr, data->favicon, 0, 0); 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_paint(cr); 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cairo_destroy(cr); 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Paint the title text. 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gfx::CanvasSkiaPaint canvas(event, false); 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int text_x = gdk_pixbuf_get_width(data->favicon) + kBarButtonPadding; 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int text_width = sender->allocation.width - text_x; 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gfx::Font& base_font = rb.GetFont(ResourceBundle::BaseFont); 14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen canvas.DrawStringInt(data->text, base_font, data->text_color, 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch text_x, 0, text_width, sender->allocation.height); 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return TRUE; 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid OnDragIconDestroy(GtkWidget* drag_icon, 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DragRepresentationData* data) { 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_unref(drag_icon); 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delete data; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace bookmark_utils { 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kBookmarkNode[] = "bookmark-node"; 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGdkPixbuf* GetPixbufForNode(const BookmarkNode* node, BookmarkModel* model, 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool native) { 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkPixbuf* pixbuf; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (node->is_url()) { 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (model->GetFavicon(node).width() != 0) { 166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pixbuf = gfx::GdkPixbufFromSkBitmap(&model->GetFavicon(node)); 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pixbuf = GtkThemeService::GetDefaultFavicon(native); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_ref(pixbuf); 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pixbuf = GtkThemeService::GetFolderIcon(native); 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_ref(pixbuf); 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return pixbuf; 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWidget* GetDragRepresentation(GdkPixbuf* pixbuf, 1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const string16& title, 181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GtkThemeService* provider) { 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* window = gtk_window_new(GTK_WINDOW_POPUP); 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (gtk_util::IsScreenComposited() && 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::AddWindowAlphaChannel(window)) { 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DragRepresentationData* data = new DragRepresentationData( 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pixbuf, title, 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen provider->GetColor(ThemeService::COLOR_BOOKMARK_TEXT)); 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window, "expose-event", G_CALLBACK(OnDragIconExpose), 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data); 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_ref(window); 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_signal_connect(window, "destroy", G_CALLBACK(OnDragIconDestroy), data); 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const gfx::Font& base_font = rb.GetFont(ResourceBundle::BaseFont); 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_size_request(window, kDragRepresentationWidth, 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick base_font.GetHeight()); 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!provider->UseGtkTheme()) { 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick GdkColor color = provider->GetGdkColor( 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ThemeService::COLOR_TOOLBAR); 2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color); 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_realize(window); 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* frame = gtk_frame_new(NULL); 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT); 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(window), frame); 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* floating_button = provider->BuildChromeButton(); 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PackButton(pixbuf, title, true, provider, floating_button); 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_container_add(GTK_CONTAINER(frame), floating_button); 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_show_all(frame); 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return window; 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGtkWidget* GetDragRepresentationForNode(const BookmarkNode* node, 220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModel* model, 221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GtkThemeService* provider) { 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkPixbuf* pixbuf = GetPixbufForNode(node, model, provider->UseGtkTheme()); 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkWidget* widget = GetDragRepresentation(pixbuf, node->GetTitle(), provider); 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_unref(pixbuf); 225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return widget; 226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ConfigureButtonForNode(const BookmarkNode* node, BookmarkModel* model, 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GtkWidget* button, GtkThemeService* provider) { 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkPixbuf* pixbuf = bookmark_utils::GetPixbufForNode(node, model, 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch provider->UseGtkTheme()); 2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick PackButton(pixbuf, node->GetTitle(), node != model->other_node(), provider, 2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick button); 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_unref(pixbuf); 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string tooltip = BuildTooltipFor(node); 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!tooltip.empty()) 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_widget_set_tooltip_markup(button, tooltip.c_str()); 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_set_data(G_OBJECT(button), bookmark_utils::kBookmarkNode, 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch AsVoid(node)); 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string BuildTooltipFor(const BookmarkNode* node) { 245dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (node->is_folder()) 246dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return std::string(); 247dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& url = node->GetURL().possibly_invalid_spec(); 2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& title = UTF16ToUTF8(node->GetTitle()); 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string truncated_url = UTF16ToUTF8(l10n_util::TruncateString( 25221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen UTF8ToUTF16(url), kMaxTooltipURLLength)); 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gchar* escaped_url_cstr = g_markup_escape_text(truncated_url.c_str(), 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch truncated_url.size()); 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string escaped_url(escaped_url_cstr); 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_free(escaped_url_cstr); 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string tooltip; 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (url == title || title.empty()) { 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return escaped_url; 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 26221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen std::string truncated_title = UTF16ToUTF8(l10n_util::TruncateString( 26321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen node->GetTitle(), kMaxTooltipTitleLength)); 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gchar* escaped_title_cstr = g_markup_escape_text(truncated_title.c_str(), 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch truncated_title.size()); 266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string escaped_title(escaped_title_cstr); 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_free(escaped_title_cstr); 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!escaped_url.empty()) 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return std::string("<b>") + escaped_title + "</b>\n" + escaped_url; 271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return std::string("<b>") + escaped_title + "</b>"; 273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst BookmarkNode* BookmarkNodeForWidget(GtkWidget* widget) { 277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return reinterpret_cast<const BookmarkNode*>( 278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch g_object_get_data(G_OBJECT(widget), bookmark_utils::kBookmarkNode)); 279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SetButtonTextColors(GtkWidget* label, GtkThemeService* provider) { 282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (provider->UseGtkTheme()) { 283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_util::SetLabelColor(label, NULL); 284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkColor color = provider->GetGdkColor( 286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ThemeService::COLOR_BOOKMARK_TEXT); 287513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &color); 288513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch gtk_widget_modify_fg(label, GTK_STATE_INSENSITIVE, &color); 289513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 290513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // Because the prelight state is a white image that doesn't change by the 291513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch // theme, force the text color to black when it would be used. 292513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch gtk_widget_modify_fg(label, GTK_STATE_ACTIVE, >k_util::kGdkBlack); 293513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch gtk_widget_modify_fg(label, GTK_STATE_PRELIGHT, >k_util::kGdkBlack); 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// DnD-related ----------------------------------------------------------------- 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint GetCodeMask(bool folder) { 30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int rv = ui::CHROME_BOOKMARK_ITEM; 301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!folder) { 30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen rv |= ui::TEXT_URI_LIST | 30372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::TEXT_PLAIN | 30472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::NETSCAPE_URL; 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return rv; 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WriteBookmarkToSelection(const BookmarkNode* node, 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkSelectionData* selection_data, 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint target_type, 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile) { 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(node); 314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<const BookmarkNode*> nodes; 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes.push_back(node); 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WriteBookmarksToSelection(nodes, selection_data, target_type, profile); 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WriteBookmarksToSelection(const std::vector<const BookmarkNode*>& nodes, 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkSelectionData* selection_data, 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint target_type, 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile) { 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (target_type) { 32472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case ui::CHROME_BOOKMARK_ITEM: { 325201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BookmarkNodeData data(nodes); 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Pickle pickle; 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data.WriteToPickle(profile, &pickle); 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_selection_data_set(selection_data, selection_data->target, 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kBitsInAByte, 331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch static_cast<const guchar*>(pickle.data()), 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch pickle.size()); 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 33572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case ui::NETSCAPE_URL: { 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // _NETSCAPE_URL format is URL + \n + title. 3373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string utf8_text = nodes[0]->GetURL().spec() + "\n" + 3383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UTF16ToUTF8(nodes[0]->GetTitle()); 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_selection_data_set(selection_data, 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch selection_data->target, 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kBitsInAByte, 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<const guchar*>(utf8_text.c_str()), 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch utf8_text.length()); 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 34672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case ui::TEXT_URI_LIST: { 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gchar** uris = reinterpret_cast<gchar**>(malloc(sizeof(gchar*) * 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (nodes.size() + 1))); 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < nodes.size(); ++i) { 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the node is a folder, this will be empty. TODO(estade): figure out 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // if there are any ramifications to passing an empty URI. After a 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // little testing, it seems fine. 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GURL& url = nodes[i]->GetURL(); 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This const cast should be safe as gtk_selection_data_set_uris() 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // makes copies. 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uris[i] = const_cast<gchar*>(url.spec().c_str()); 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch uris[nodes.size()] = NULL; 359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_selection_data_set_uris(selection_data, uris); 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch free(uris); 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 36472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case ui::TEXT_PLAIN: { 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gtk_selection_data_set_text(selection_data, 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch nodes[0]->GetURL().spec().c_str(), -1); 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: { 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DLOG(ERROR) << "Unsupported drag get type!"; 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::vector<const BookmarkNode*> GetNodesFromSelection( 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GdkDragContext* context, 377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GtkSelectionData* selection_data, 378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch guint target_type, 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gboolean* delete_selection_data, 381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch gboolean* dnd_success) { 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (delete_selection_data) 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *delete_selection_data = FALSE; 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (dnd_success) 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *dnd_success = FALSE; 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (selection_data && selection_data->length > 0) { 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (context && delete_selection_data && context->action == GDK_ACTION_MOVE) 389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *delete_selection_data = TRUE; 390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (target_type) { 39272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen case ui::CHROME_BOOKMARK_ITEM: { 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (dnd_success) 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *dnd_success = TRUE; 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Pickle pickle(reinterpret_cast<char*>(selection_data->data), 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch selection_data->length); 397201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch BookmarkNodeData drag_data; 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch drag_data.ReadFromPickle(&pickle); 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return drag_data.GetNodes(profile); 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: { 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DLOG(ERROR) << "Unsupported drag received type: " << target_type; 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return std::vector<const BookmarkNode*>(); 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CreateNewBookmarkFromNamedUrl(GtkSelectionData* selection_data, 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModel* model, const BookmarkNode* parent, int idx) { 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url; 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 title; 41472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!ui::ExtractNamedURL(selection_data, &url, &title)) 415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick model->AddURL(parent, idx, title, url); 418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool CreateNewBookmarksFromURIList(GtkSelectionData* selection_data, 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BookmarkModel* model, const BookmarkNode* parent, int idx) { 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<GURL> urls; 42472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ui::ExtractURIList(selection_data, &urls); 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < urls.size(); ++i) { 42672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 title = GetNameForURL(urls[i]); 42772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen model->AddURL(parent, idx++, title, urls[i]); 428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool CreateNewBookmarkFromNetscapeURL(GtkSelectionData* selection_data, 43321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen BookmarkModel* model, const BookmarkNode* parent, int idx) { 43421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen GURL url; 43521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen string16 title; 43672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!ui::ExtractNetscapeURL(selection_data, &url, &title)) 43721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 43821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 43921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen model->AddURL(parent, idx, title, url); 44021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return true; 44121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen} 44221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace bookmark_utils 444