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, &gtk_util::kGdkBlack);
293513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    gtk_widget_modify_fg(label, GTK_STATE_PRELIGHT, &gtk_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