blob: e803c765ef394af68e904814abbdac3c0c8a3dd2 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/base/dragdrop/os_exchange_data_provider_non_backed.h"
#include <memory>
#include <string>
#include "base/check.h"
#include "base/containers/contains.h"
#include "base/files/file_path.h"
#include "base/strings/utf_string_conversions.h"
#include "build/chromeos_buildflags.h"
#include "net/base/filename_util.h"
#include "ui/base/clipboard/clipboard_format_type.h"
#include "ui/base/clipboard/file_info.h"
#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "url/gurl.h"
namespace ui {
OSExchangeDataProviderNonBacked::OSExchangeDataProviderNonBacked() = default;
OSExchangeDataProviderNonBacked::~OSExchangeDataProviderNonBacked() = default;
std::unique_ptr<OSExchangeDataProvider> OSExchangeDataProviderNonBacked::Clone()
const {
auto clone = std::make_unique<OSExchangeDataProviderNonBacked>();
clone->formats_ = formats_;
clone->string_ = string_;
clone->url_ = url_;
clone->title_ = title_;
clone->filenames_ = filenames_;
clone->pickle_data_ = pickle_data_;
// We skip copying the drag images.
clone->file_contents_filename_ = file_contents_filename_;
clone->file_contents_ = file_contents_;
clone->html_ = html_;
clone->base_url_ = base_url_;
clone->source_ =
source_ ? std::make_unique<ui::DataTransferEndpoint>(*source_.get())
: nullptr;
#if !BUILDFLAG(IS_CHROMEOS_ASH)
clone->originated_from_renderer_ = originated_from_renderer_;
#endif
return clone;
}
void OSExchangeDataProviderNonBacked::MarkOriginatedFromRenderer() {
// TODO(dcheng): Currently unneeded because ChromeOS Aura correctly separates
// URL and filename metadata, and does not implement the DownloadURL protocol.
#if !BUILDFLAG(IS_CHROMEOS_ASH)
originated_from_renderer_ = true;
#endif
}
bool OSExchangeDataProviderNonBacked::DidOriginateFromRenderer() const {
#if BUILDFLAG(IS_CHROMEOS_ASH)
return false;
#else
return originated_from_renderer_;
#endif
}
void OSExchangeDataProviderNonBacked::SetString(const std::u16string& data) {
if (HasString())
return;
string_ = data;
formats_ |= OSExchangeData::STRING;
}
void OSExchangeDataProviderNonBacked::SetURL(const GURL& url,
const std::u16string& title) {
url_ = url;
title_ = title;
formats_ |= OSExchangeData::URL;
SetString(base::UTF8ToUTF16(url.spec()));
}
void OSExchangeDataProviderNonBacked::SetFilename(const base::FilePath& path) {
filenames_.clear();
filenames_.push_back(FileInfo(path, base::FilePath()));
formats_ |= OSExchangeData::FILE_NAME;
}
void OSExchangeDataProviderNonBacked::SetFilenames(
const std::vector<FileInfo>& filenames) {
filenames_ = filenames;
formats_ |= OSExchangeData::FILE_NAME;
}
void OSExchangeDataProviderNonBacked::SetPickledData(
const ClipboardFormatType& format,
const base::Pickle& data) {
pickle_data_[format] = data;
formats_ |= OSExchangeData::PICKLED_DATA;
}
bool OSExchangeDataProviderNonBacked::GetString(std::u16string* data) const {
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
if (HasFile()) {
// Various Linux file managers both pass a list of file:// URIs and set the
// string representation to the URI. We explicitly don't want to return use
// this representation.
return false;
}
#endif // defined(OS_LINUX) || defined(OS_CHROMEOS)
if ((formats_ & OSExchangeData::STRING) == 0)
return false;
*data = string_;
return true;
}
bool OSExchangeDataProviderNonBacked::GetURLAndTitle(
FilenameToURLPolicy policy,
GURL* url,
std::u16string* title) const {
if ((formats_ & OSExchangeData::URL) == 0) {
title->clear();
return GetPlainTextURL(url) ||
(policy == FilenameToURLPolicy::CONVERT_FILENAMES &&
GetFileURL(url));
}
if (!url_.is_valid())
return false;
*url = url_;
*title = title_;
return true;
}
bool OSExchangeDataProviderNonBacked::GetFilename(base::FilePath* path) const {
if ((formats_ & OSExchangeData::FILE_NAME) == 0)
return false;
DCHECK(!filenames_.empty());
*path = filenames_[0].path;
return true;
}
bool OSExchangeDataProviderNonBacked::GetFilenames(
std::vector<FileInfo>* filenames) const {
if ((formats_ & OSExchangeData::FILE_NAME) == 0)
return false;
*filenames = filenames_;
return true;
}
bool OSExchangeDataProviderNonBacked::GetPickledData(
const ClipboardFormatType& format,
base::Pickle* data) const {
const auto i = pickle_data_.find(format);
if (i == pickle_data_.end())
return false;
*data = i->second;
return true;
}
bool OSExchangeDataProviderNonBacked::HasString() const {
return (formats_ & OSExchangeData::STRING) != 0;
}
bool OSExchangeDataProviderNonBacked::HasURL(FilenameToURLPolicy policy) const {
if ((formats_ & OSExchangeData::URL) != 0) {
return true;
}
// No URL, see if we have plain text that can be parsed as a URL.
return GetPlainTextURL(nullptr) ||
(policy == FilenameToURLPolicy::CONVERT_FILENAMES &&
GetFileURL(nullptr));
}
bool OSExchangeDataProviderNonBacked::HasFile() const {
return (formats_ & OSExchangeData::FILE_NAME) != 0;
}
bool OSExchangeDataProviderNonBacked::HasCustomFormat(
const ClipboardFormatType& format) const {
return base::Contains(pickle_data_, format);
}
void OSExchangeDataProviderNonBacked::SetFileContents(
const base::FilePath& filename,
const std::string& file_contents) {
file_contents_filename_ = filename;
file_contents_ = file_contents;
}
bool OSExchangeDataProviderNonBacked::GetFileContents(
base::FilePath* filename,
std::string* file_contents) const {
if (file_contents_filename_.empty()) {
return false;
}
*filename = file_contents_filename_;
*file_contents = file_contents_;
return true;
}
bool OSExchangeDataProviderNonBacked::HasFileContents() const {
return !file_contents_filename_.empty();
}
void OSExchangeDataProviderNonBacked::SetHtml(const std::u16string& html,
const GURL& base_url) {
formats_ |= OSExchangeData::HTML;
html_ = html;
base_url_ = base_url;
}
bool OSExchangeDataProviderNonBacked::GetHtml(std::u16string* html,
GURL* base_url) const {
if ((formats_ & OSExchangeData::HTML) == 0)
return false;
*html = html_;
*base_url = base_url_;
return true;
}
bool OSExchangeDataProviderNonBacked::HasHtml() const {
return ((formats_ & OSExchangeData::HTML) != 0);
}
void OSExchangeDataProviderNonBacked::SetDragImage(
const gfx::ImageSkia& image,
const gfx::Vector2d& cursor_offset) {
drag_image_ = image;
drag_image_offset_ = cursor_offset;
}
gfx::ImageSkia OSExchangeDataProviderNonBacked::GetDragImage() const {
return drag_image_;
}
gfx::Vector2d OSExchangeDataProviderNonBacked::GetDragImageOffset() const {
return drag_image_offset_;
}
bool OSExchangeDataProviderNonBacked::GetFileURL(GURL* url) const {
base::FilePath file_path;
if (!GetFilename(&file_path))
return false;
GURL test_url = net::FilePathToFileURL(file_path);
if (!test_url.is_valid())
return false;
if (url)
*url = test_url;
return true;
}
bool OSExchangeDataProviderNonBacked::GetPlainTextURL(GURL* url) const {
if ((formats_ & OSExchangeData::STRING) == 0)
return false;
GURL test_url(string_);
if (!test_url.is_valid())
return false;
if (url)
*url = test_url;
return true;
}
void OSExchangeDataProviderNonBacked::SetSource(
std::unique_ptr<DataTransferEndpoint> data_source) {
source_ = std::move(data_source);
}
DataTransferEndpoint* OSExchangeDataProviderNonBacked::GetSource() const {
return source_.get();
}
} // namespace ui