1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ui/base/dragdrop/os_exchange_data_provider_aura.h"
6
7#include "base/logging.h"
8#include "base/strings/utf_string_conversions.h"
9#include "net/base/net_util.h"
10#include "ui/base/clipboard/clipboard.h"
11#include "ui/base/clipboard/scoped_clipboard_writer.h"
12#include "ui/base/dragdrop/file_info.h"
13
14namespace ui {
15
16OSExchangeDataProviderAura::OSExchangeDataProviderAura()
17    : formats_(0) {
18}
19
20OSExchangeDataProviderAura::~OSExchangeDataProviderAura() {}
21
22OSExchangeData::Provider* OSExchangeDataProviderAura::Clone() const {
23  OSExchangeDataProviderAura* ret = new OSExchangeDataProviderAura();
24  ret->formats_ = formats_;
25  ret->string_ = string_;
26  ret->url_ = url_;
27  ret->title_ = title_;
28  ret->filenames_ = filenames_;
29  ret->pickle_data_ = pickle_data_;
30  // We skip copying the drag images.
31  ret->html_ = html_;
32  ret->base_url_ = base_url_;
33
34  return ret;
35}
36
37void OSExchangeDataProviderAura::MarkOriginatedFromRenderer() {
38  // TODO(dcheng): Currently unneeded because ChromeOS Aura correctly separates
39  // URL and filename metadata, and does not implement the DownloadURL protocol.
40}
41
42bool OSExchangeDataProviderAura::DidOriginateFromRenderer() const {
43  return false;
44}
45
46void OSExchangeDataProviderAura::SetString(const base::string16& data) {
47  string_ = data;
48  formats_ |= OSExchangeData::STRING;
49}
50
51void OSExchangeDataProviderAura::SetURL(const GURL& url,
52                                        const base::string16& title) {
53  url_ = url;
54  title_ = title;
55  formats_ |= OSExchangeData::URL;
56
57  SetString(base::UTF8ToUTF16(url.spec()));
58}
59
60void OSExchangeDataProviderAura::SetFilename(const base::FilePath& path) {
61  filenames_.clear();
62  filenames_.push_back(FileInfo(path, base::FilePath()));
63  formats_ |= OSExchangeData::FILE_NAME;
64}
65
66void OSExchangeDataProviderAura::SetFilenames(
67    const std::vector<FileInfo>& filenames) {
68  filenames_ = filenames;
69  formats_ |= OSExchangeData::FILE_NAME;
70}
71
72void OSExchangeDataProviderAura::SetPickledData(
73    const OSExchangeData::CustomFormat& format,
74    const Pickle& data) {
75  pickle_data_[format] = data;
76  formats_ |= OSExchangeData::PICKLED_DATA;
77}
78
79bool OSExchangeDataProviderAura::GetString(base::string16* data) const {
80  if ((formats_ & OSExchangeData::STRING) == 0)
81    return false;
82  *data = string_;
83  return true;
84}
85
86bool OSExchangeDataProviderAura::GetURLAndTitle(
87    OSExchangeData::FilenameToURLPolicy policy,
88    GURL* url,
89    base::string16* title) const {
90  // TODO(dcheng): implement filename conversion.
91  if ((formats_ & OSExchangeData::URL) == 0) {
92    title->clear();
93    return GetPlainTextURL(url);
94  }
95
96  if (!url_.is_valid())
97    return false;
98
99  *url = url_;
100  *title = title_;
101  return true;
102}
103
104bool OSExchangeDataProviderAura::GetFilename(base::FilePath* path) const {
105  if ((formats_ & OSExchangeData::FILE_NAME) == 0)
106    return false;
107  DCHECK(!filenames_.empty());
108  *path = filenames_[0].path;
109  return true;
110}
111
112bool OSExchangeDataProviderAura::GetFilenames(
113    std::vector<FileInfo>* filenames) const {
114  if ((formats_ & OSExchangeData::FILE_NAME) == 0)
115    return false;
116  *filenames = filenames_;
117  return true;
118}
119
120bool OSExchangeDataProviderAura::GetPickledData(
121    const OSExchangeData::CustomFormat& format,
122    Pickle* data) const {
123  PickleData::const_iterator i = pickle_data_.find(format);
124  if (i == pickle_data_.end())
125    return false;
126
127  *data = i->second;
128  return true;
129}
130
131bool OSExchangeDataProviderAura::HasString() const {
132  return (formats_ & OSExchangeData::STRING) != 0;
133}
134
135bool OSExchangeDataProviderAura::HasURL(
136    OSExchangeData::FilenameToURLPolicy policy) const {
137  // TODO(dcheng): implement filename conversion.
138  if ((formats_ & OSExchangeData::URL) != 0) {
139    return true;
140  }
141  // No URL, see if we have plain text that can be parsed as a URL.
142  return GetPlainTextURL(NULL);
143}
144
145bool OSExchangeDataProviderAura::HasFile() const {
146  return (formats_ & OSExchangeData::FILE_NAME) != 0;
147}
148
149bool OSExchangeDataProviderAura::HasCustomFormat(
150    const OSExchangeData::CustomFormat& format) const {
151  return pickle_data_.find(format) != pickle_data_.end();
152}
153
154void OSExchangeDataProviderAura::SetHtml(const base::string16& html,
155                                         const GURL& base_url) {
156  formats_ |= OSExchangeData::HTML;
157  html_ = html;
158  base_url_ = base_url;
159}
160
161bool OSExchangeDataProviderAura::GetHtml(base::string16* html,
162                                         GURL* base_url) const {
163  if ((formats_ & OSExchangeData::HTML) == 0)
164    return false;
165  *html = html_;
166  *base_url = base_url_;
167  return true;
168}
169
170bool OSExchangeDataProviderAura::HasHtml() const {
171  return ((formats_ & OSExchangeData::HTML) != 0);
172}
173
174void OSExchangeDataProviderAura::SetDragImage(
175    const gfx::ImageSkia& image,
176    const gfx::Vector2d& cursor_offset) {
177  drag_image_ = image;
178  drag_image_offset_ = cursor_offset;
179}
180
181const gfx::ImageSkia& OSExchangeDataProviderAura::GetDragImage() const {
182  return drag_image_;
183}
184
185const gfx::Vector2d&
186OSExchangeDataProviderAura::GetDragImageOffset() const {
187  return drag_image_offset_;
188}
189
190bool OSExchangeDataProviderAura::GetPlainTextURL(GURL* url) const {
191  if ((formats_ & OSExchangeData::STRING) == 0)
192    return false;
193
194  GURL test_url(string_);
195  if (!test_url.is_valid())
196    return false;
197
198  if (url)
199    *url = test_url;
200  return true;
201}
202
203///////////////////////////////////////////////////////////////////////////////
204// OSExchangeData, public:
205
206// static
207OSExchangeData::Provider* OSExchangeData::CreateProvider() {
208  return new OSExchangeDataProviderAura();
209}
210
211}  // namespace ui
212