webclipboard_impl.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
1// Copyright (c) 2009 The Chromium Authors. All rights reserved.  Use of this
2// source code is governed by a BSD-style license that can be found in the
3// LICENSE file.
4
5#include "webkit/glue/webclipboard_impl.h"
6
7#include "app/clipboard/clipboard.h"
8#include "base/logging.h"
9#include "base/string_util.h"
10#include "base/utf_string_conversions.h"
11#include "googleurl/src/gurl.h"
12#include "net/base/escape.h"
13#include "third_party/skia/include/core/SkBitmap.h"
14#include "third_party/WebKit/WebKit/chromium/public/WebImage.h"
15#include "third_party/WebKit/WebKit/chromium/public/WebSize.h"
16#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
17#include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
18#include "third_party/WebKit/WebKit/chromium/public/WebVector.h"
19#include "webkit/glue/scoped_clipboard_writer_glue.h"
20#include "webkit/glue/webkit_glue.h"
21
22#if WEBKIT_USING_CG
23#include "skia/ext/skia_utils_mac.h"
24#endif
25
26using WebKit::WebClipboard;
27using WebKit::WebImage;
28using WebKit::WebString;
29using WebKit::WebURL;
30using WebKit::WebVector;
31
32namespace webkit_glue {
33
34// Static
35std::string WebClipboardImpl::URLToMarkup(const WebURL& url,
36    const WebString& title) {
37  std::string markup("<a href=\"");
38  markup.append(url.spec());
39  markup.append("\">");
40  // TODO(darin): HTML escape this
41  markup.append(EscapeForHTML(UTF16ToUTF8(title)));
42  markup.append("</a>");
43  return markup;
44}
45
46// Static
47std::string WebClipboardImpl::URLToImageMarkup(const WebURL& url,
48    const WebString& title) {
49  std::string markup("<img src=\"");
50  markup.append(url.spec());
51  markup.append("\"");
52  if (!title.isEmpty()) {
53    markup.append(" alt=\"");
54    markup.append(EscapeForHTML(UTF16ToUTF8(title)));
55    markup.append("\"");
56  }
57  markup.append("/>");
58  return markup;
59}
60
61bool WebClipboardImpl::isFormatAvailable(Format format, Buffer buffer) {
62  Clipboard::FormatType format_type;
63  Clipboard::Buffer buffer_type;
64
65  switch (format) {
66    case FormatHTML:
67      format_type = Clipboard::GetHtmlFormatType();
68      break;
69    case FormatSmartPaste:
70      format_type = Clipboard::GetWebKitSmartPasteFormatType();
71      break;
72    case FormatBookmark:
73#if defined(OS_WIN) || defined(OS_MACOSX)
74      format_type = Clipboard::GetUrlWFormatType();
75      break;
76#endif
77    default:
78      NOTREACHED();
79      return false;
80  }
81
82  if (!ConvertBufferType(buffer, &buffer_type))
83    return false;
84
85  return ClipboardIsFormatAvailable(format_type, buffer_type);
86}
87
88WebString WebClipboardImpl::readPlainText(Buffer buffer) {
89  Clipboard::Buffer buffer_type;
90  if (!ConvertBufferType(buffer, &buffer_type))
91    return WebString();
92
93  if (ClipboardIsFormatAvailable(Clipboard::GetPlainTextWFormatType(),
94                                 buffer_type)) {
95    string16 text;
96    ClipboardReadText(buffer_type, &text);
97    if (!text.empty())
98      return text;
99  }
100
101  if (ClipboardIsFormatAvailable(Clipboard::GetPlainTextFormatType(),
102                                 buffer_type)) {
103    std::string text;
104    ClipboardReadAsciiText(buffer_type, &text);
105    if (!text.empty())
106      return ASCIIToUTF16(text);
107  }
108
109  return WebString();
110}
111
112WebString WebClipboardImpl::readHTML(Buffer buffer, WebURL* source_url) {
113  Clipboard::Buffer buffer_type;
114  if (!ConvertBufferType(buffer, &buffer_type))
115    return WebString();
116
117  string16 html_stdstr;
118  GURL gurl;
119  ClipboardReadHTML(buffer_type, &html_stdstr, &gurl);
120  *source_url = gurl;
121  return html_stdstr;
122}
123
124void WebClipboardImpl::writeHTML(
125    const WebString& html_text, const WebURL& source_url,
126    const WebString& plain_text, bool write_smart_paste) {
127  ScopedClipboardWriterGlue scw(ClipboardGetClipboard());
128  scw.WriteHTML(html_text, source_url.spec());
129  scw.WriteText(plain_text);
130
131  if (write_smart_paste)
132    scw.WriteWebSmartPaste();
133}
134
135void WebClipboardImpl::writePlainText(const WebString& plain_text) {
136  ScopedClipboardWriterGlue scw(ClipboardGetClipboard());
137  scw.WriteText(plain_text);
138}
139
140void WebClipboardImpl::writeURL(const WebURL& url, const WebString& title) {
141  ScopedClipboardWriterGlue scw(ClipboardGetClipboard());
142
143  scw.WriteBookmark(title, url.spec());
144  scw.WriteHTML(UTF8ToUTF16(URLToMarkup(url, title)), "");
145  scw.WriteText(UTF8ToUTF16(url.spec()));
146}
147
148void WebClipboardImpl::writeImage(
149    const WebImage& image, const WebURL& url, const WebString& title) {
150  ScopedClipboardWriterGlue scw(ClipboardGetClipboard());
151
152  if (!image.isNull()) {
153#if WEBKIT_USING_SKIA
154    const SkBitmap& bitmap = image.getSkBitmap();
155#elif WEBKIT_USING_CG
156    const SkBitmap& bitmap = gfx::CGImageToSkBitmap(image.getCGImageRef());
157#endif
158    SkAutoLockPixels locked(bitmap);
159    scw.WriteBitmapFromPixels(bitmap.getPixels(), image.size());
160  }
161
162  // When writing the image, we also write the image markup so that pasting
163  // into rich text editors, such as Gmail, reveals the image. We also don't
164  // want to call writeText(), since some applications (WordPad) don't pick the
165  // image if there is also a text format on the clipboard.
166  if (!url.isEmpty()) {
167    scw.WriteBookmark(title, url.spec());
168    scw.WriteHTML(UTF8ToUTF16(URLToImageMarkup(url, title)), "");
169  }
170}
171
172void WebClipboardImpl::writeData(const WebKit::WebDragData& data) {
173  // TODO(dcheng): Implement this stub.
174}
175
176WebVector<WebString> WebClipboardImpl::readAvailableTypes(
177    Buffer buffer, bool* contains_filenames) {
178  Clipboard::Buffer buffer_type;
179  std::vector<string16> types;
180  if (ConvertBufferType(buffer, &buffer_type)) {
181    ClipboardReadAvailableTypes(buffer_type, &types, contains_filenames);
182  }
183  return types;
184}
185
186bool WebClipboardImpl::readData(Buffer buffer, const WebString& type,
187                                WebString* data, WebString* metadata) {
188  Clipboard::Buffer buffer_type;
189  if (!ConvertBufferType(buffer, &buffer_type))
190    return false;
191
192  string16 data_out;
193  string16 metadata_out;
194  bool result = ClipboardReadData(buffer_type, type, &data_out, &metadata_out);
195  if (result) {
196    *data = data_out;
197    *metadata = metadata_out;
198  }
199  return result;
200}
201
202WebVector<WebString> WebClipboardImpl::readFilenames(Buffer buffer) {
203  Clipboard::Buffer buffer_type;
204  std::vector<string16> filenames;
205  if (ConvertBufferType(buffer, &buffer_type)) {
206    ClipboardReadFilenames(buffer_type, &filenames);
207  }
208  return filenames;
209}
210
211bool WebClipboardImpl::ConvertBufferType(Buffer buffer,
212                                         Clipboard::Buffer* result) {
213  switch (buffer) {
214    case BufferStandard:
215      *result = Clipboard::BUFFER_STANDARD;
216      break;
217    case BufferDrag:
218      *result = Clipboard::BUFFER_DRAG;
219    case BufferSelection:
220#if defined(USE_X11)
221      *result = Clipboard::BUFFER_SELECTION;
222      break;
223#endif
224    default:
225      NOTREACHED();
226      return false;
227  }
228  return true;
229}
230
231}  // namespace webkit_glue
232