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  if (HasString())
48    return;
49
50  string_ = data;
51  formats_ |= OSExchangeData::STRING;
52}
53
54void OSExchangeDataProviderAura::SetURL(const GURL& url,
55                                        const base::string16& title) {
56  url_ = url;
57  title_ = title;
58  formats_ |= OSExchangeData::URL;
59
60  SetString(base::UTF8ToUTF16(url.spec()));
61}
62
63void OSExchangeDataProviderAura::SetFilename(const base::FilePath& path) {
64  filenames_.clear();
65  filenames_.push_back(FileInfo(path, base::FilePath()));
66  formats_ |= OSExchangeData::FILE_NAME;
67}
68
69void OSExchangeDataProviderAura::SetFilenames(
70    const std::vector<FileInfo>& filenames) {
71  filenames_ = filenames;
72  formats_ |= OSExchangeData::FILE_NAME;
73}
74
75void OSExchangeDataProviderAura::SetPickledData(
76    const OSExchangeData::CustomFormat& format,
77    const Pickle& data) {
78  pickle_data_[format] = data;
79  formats_ |= OSExchangeData::PICKLED_DATA;
80}
81
82bool OSExchangeDataProviderAura::GetString(base::string16* data) const {
83  if ((formats_ & OSExchangeData::STRING) == 0)
84    return false;
85  *data = string_;
86  return true;
87}
88
89bool OSExchangeDataProviderAura::GetURLAndTitle(
90    OSExchangeData::FilenameToURLPolicy policy,
91    GURL* url,
92    base::string16* title) const {
93  // TODO(dcheng): implement filename conversion.
94  if ((formats_ & OSExchangeData::URL) == 0) {
95    title->clear();
96    return GetPlainTextURL(url);
97  }
98
99  if (!url_.is_valid())
100    return false;
101
102  *url = url_;
103  *title = title_;
104  return true;
105}
106
107bool OSExchangeDataProviderAura::GetFilename(base::FilePath* path) const {
108  if ((formats_ & OSExchangeData::FILE_NAME) == 0)
109    return false;
110  DCHECK(!filenames_.empty());
111  *path = filenames_[0].path;
112  return true;
113}
114
115bool OSExchangeDataProviderAura::GetFilenames(
116    std::vector<FileInfo>* filenames) const {
117  if ((formats_ & OSExchangeData::FILE_NAME) == 0)
118    return false;
119  *filenames = filenames_;
120  return true;
121}
122
123bool OSExchangeDataProviderAura::GetPickledData(
124    const OSExchangeData::CustomFormat& format,
125    Pickle* data) const {
126  PickleData::const_iterator i = pickle_data_.find(format);
127  if (i == pickle_data_.end())
128    return false;
129
130  *data = i->second;
131  return true;
132}
133
134bool OSExchangeDataProviderAura::HasString() const {
135  return (formats_ & OSExchangeData::STRING) != 0;
136}
137
138bool OSExchangeDataProviderAura::HasURL(
139    OSExchangeData::FilenameToURLPolicy policy) const {
140  // TODO(dcheng): implement filename conversion.
141  if ((formats_ & OSExchangeData::URL) != 0) {
142    return true;
143  }
144  // No URL, see if we have plain text that can be parsed as a URL.
145  return GetPlainTextURL(NULL);
146}
147
148bool OSExchangeDataProviderAura::HasFile() const {
149  return (formats_ & OSExchangeData::FILE_NAME) != 0;
150}
151
152bool OSExchangeDataProviderAura::HasCustomFormat(
153    const OSExchangeData::CustomFormat& format) const {
154  return pickle_data_.find(format) != pickle_data_.end();
155}
156
157void OSExchangeDataProviderAura::SetHtml(const base::string16& html,
158                                         const GURL& base_url) {
159  formats_ |= OSExchangeData::HTML;
160  html_ = html;
161  base_url_ = base_url;
162}
163
164bool OSExchangeDataProviderAura::GetHtml(base::string16* html,
165                                         GURL* base_url) const {
166  if ((formats_ & OSExchangeData::HTML) == 0)
167    return false;
168  *html = html_;
169  *base_url = base_url_;
170  return true;
171}
172
173bool OSExchangeDataProviderAura::HasHtml() const {
174  return ((formats_ & OSExchangeData::HTML) != 0);
175}
176
177void OSExchangeDataProviderAura::SetDragImage(
178    const gfx::ImageSkia& image,
179    const gfx::Vector2d& cursor_offset) {
180  drag_image_ = image;
181  drag_image_offset_ = cursor_offset;
182}
183
184const gfx::ImageSkia& OSExchangeDataProviderAura::GetDragImage() const {
185  return drag_image_;
186}
187
188const gfx::Vector2d&
189OSExchangeDataProviderAura::GetDragImageOffset() const {
190  return drag_image_offset_;
191}
192
193bool OSExchangeDataProviderAura::GetPlainTextURL(GURL* url) const {
194  if ((formats_ & OSExchangeData::STRING) == 0)
195    return false;
196
197  GURL test_url(string_);
198  if (!test_url.is_valid())
199    return false;
200
201  if (url)
202    *url = test_url;
203  return true;
204}
205
206///////////////////////////////////////////////////////////////////////////////
207// OSExchangeData, public:
208
209// static
210OSExchangeData::Provider* OSExchangeData::CreateProvider() {
211  return new OSExchangeDataProviderAura();
212}
213
214}  // namespace ui
215