This source file includes following definitions.
- format_
- format
- text
- set_text
- markup_data
- set_markup_data
- rtf_data
- SetRTFData
- url
- set_url
- bookmark_title
- set_bookmark_title
- bookmark_url
- set_bookmark_url
- bitmap
- SetBitmapData
- custom_data_format
- custom_data_data
- SetCustomData
- web_smart_paste
- set_web_smart_paste
- Clear
- sequence_number
- GetData
- IsFormatAvailable
- ReadText
- ReadAsciiText
- ReadHTML
- ReadRTF
- ReadImage
- ReadCustomData
- ReadBookmark
- ReadData
- WriteData
- HasFormat
- AddToListEnsuringSize
- GetClipboard
- DeleteClipboard
- CommitToClipboard
- WriteText
- WriteHTML
- WriteRTF
- WriteBookmark
- WriteWebSmartPaste
- WriteBitmap
- WriteData
- GetCurrentData
- Serialize
- Deserialize
- Equals
- WriteObjects
- IsFormatAvailable
- Clear
- ReadAvailableTypes
- ReadText
- ReadAsciiText
- ReadHTML
- ReadRTF
- ReadImage
- ReadCustomData
- ReadBookmark
- ReadData
- GetSequenceNumber
- WriteText
- WriteHTML
- WriteRTF
- WriteBookmark
- WriteWebSmartPaste
- WriteBitmap
- WriteData
- GetFormatType
- GetUrlFormatType
- GetUrlWFormatType
- GetPlainTextFormatType
- GetPlainTextWFormatType
- GetFilenameFormatType
- GetFilenameWFormatType
- GetHtmlFormatType
- GetRtfFormatType
- GetBitmapFormatType
- GetWebKitSmartPasteFormatType
- GetWebCustomDataFormatType
- GetPepperCustomDataFormatType
#include "ui/base/clipboard/clipboard.h"
#include <list>
#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/gfx/size.h"
namespace ui {
namespace {
const char kMimeTypeFilename[] = "chromium/filename";
const char kMimeTypeBitmap[] = "image/bmp";
const char kMimeTypePepperCustomData[] = "chromium/x-pepper-custom-data";
const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste";
const size_t kMaxClipboardSize = 1;
enum AuraClipboardFormat {
TEXT = 1 << 0,
HTML = 1 << 1,
RTF = 1 << 2,
BOOKMARK = 1 << 3,
BITMAP = 1 << 4,
CUSTOM = 1 << 5,
WEB = 1 << 6,
};
class ClipboardData {
public:
ClipboardData()
: web_smart_paste_(false),
format_(0) {}
virtual ~ClipboardData() {}
int format() const { return format_; }
const std::string& text() const { return text_; }
void set_text(const std::string& text) {
text_ = text;
format_ |= TEXT;
}
const std::string& markup_data() const { return markup_data_; }
void set_markup_data(const std::string& markup_data) {
markup_data_ = markup_data;
format_ |= HTML;
}
const std::string& rtf_data() const { return rtf_data_; }
void SetRTFData(const std::string& rtf_data) {
rtf_data_ = rtf_data;
format_ |= RTF;
}
const std::string& url() const { return url_; }
void set_url(const std::string& url) {
url_ = url;
format_ |= HTML;
}
const std::string& bookmark_title() const { return bookmark_title_; }
void set_bookmark_title(const std::string& bookmark_title) {
bookmark_title_ = bookmark_title;
format_ |= BOOKMARK;
}
const std::string& bookmark_url() const { return bookmark_url_; }
void set_bookmark_url(const std::string& bookmark_url) {
bookmark_url_ = bookmark_url;
format_ |= BOOKMARK;
}
const SkBitmap& bitmap() const { return bitmap_; }
void SetBitmapData(const SkBitmap& bitmap) {
bitmap.copyTo(&bitmap_);
format_ |= BITMAP;
}
const std::string& custom_data_format() const { return custom_data_format_; }
const std::string& custom_data_data() const { return custom_data_data_; }
void SetCustomData(const std::string& data_format,
const std::string& data_data) {
if (data_data.size() == 0) {
custom_data_data_.clear();
custom_data_format_.clear();
return;
}
custom_data_data_ = data_data;
custom_data_format_ = data_format;
format_ |= CUSTOM;
}
bool web_smart_paste() const { return web_smart_paste_; }
void set_web_smart_paste(bool web_smart_paste) {
web_smart_paste_ = web_smart_paste;
format_ |= WEB;
}
private:
std::string text_;
std::string markup_data_;
std::string url_;
std::string rtf_data_;
std::string bookmark_title_;
std::string bookmark_url_;
std::vector<std::string> files_;
SkBitmap bitmap_;
std::string custom_data_format_;
std::string custom_data_data_;
bool web_smart_paste_;
int format_;
DISALLOW_COPY_AND_ASSIGN(ClipboardData);
};
class AuraClipboard {
public:
AuraClipboard() : sequence_number_(0) {
}
~AuraClipboard() {
Clear();
}
void Clear() {
sequence_number_++;
STLDeleteContainerPointers(data_list_.begin(), data_list_.end());
data_list_.clear();
}
uint64_t sequence_number() const {
return sequence_number_;
}
const ClipboardData* GetData() const {
if (data_list_.empty())
return NULL;
return data_list_.front();
}
bool IsFormatAvailable(AuraClipboardFormat format) const {
switch (format) {
case TEXT:
return HasFormat(TEXT) || HasFormat(BOOKMARK);
default:
return HasFormat(format);
}
}
void ReadText(base::string16* result) const {
std::string utf8_result;
ReadAsciiText(&utf8_result);
*result = base::UTF8ToUTF16(utf8_result);
}
void ReadAsciiText(std::string* result) const {
result->clear();
const ClipboardData* data = GetData();
if (!data)
return;
if (HasFormat(TEXT))
*result = data->text();
else if (HasFormat(HTML))
*result = data->markup_data();
else if (HasFormat(BOOKMARK))
*result = data->bookmark_url();
}
void ReadHTML(base::string16* markup,
std::string* src_url,
uint32* fragment_start,
uint32* fragment_end) const {
markup->clear();
if (src_url)
src_url->clear();
*fragment_start = 0;
*fragment_end = 0;
if (!HasFormat(HTML))
return;
const ClipboardData* data = GetData();
*markup = base::UTF8ToUTF16(data->markup_data());
*src_url = data->url();
*fragment_start = 0;
DCHECK_LE(markup->length(), kuint32max);
*fragment_end = static_cast<uint32>(markup->length());
}
void ReadRTF(std::string* result) const {
result->clear();
const ClipboardData* data = GetData();
if (!HasFormat(RTF))
return;
*result = data->rtf_data();
}
SkBitmap ReadImage() const {
SkBitmap img;
if (!HasFormat(BITMAP))
return img;
const SkBitmap& clipboard_bitmap = GetData()->bitmap();
clipboard_bitmap.copyTo(&img);
return img;
}
void ReadCustomData(const base::string16& type,
base::string16* result) const {
result->clear();
const ClipboardData* data = GetData();
if (!HasFormat(CUSTOM))
return;
ui::ReadCustomDataForType(data->custom_data_data().c_str(),
data->custom_data_data().size(),
type, result);
}
void ReadBookmark(base::string16* title, std::string* url) const {
title->clear();
url->clear();
if (!HasFormat(BOOKMARK))
return;
const ClipboardData* data = GetData();
*title = base::UTF8ToUTF16(data->bookmark_title());
*url = data->bookmark_url();
}
void ReadData(const std::string& type, std::string* result) const {
result->clear();
const ClipboardData* data = GetData();
if (!HasFormat(CUSTOM) || type != data->custom_data_format())
return;
*result = data->custom_data_data();
}
void WriteData(ClipboardData* data) {
DCHECK(data);
AddToListEnsuringSize(data);
}
private:
bool HasFormat(AuraClipboardFormat format) const {
const ClipboardData* data = GetData();
if (!data)
return false;
return data->format() & format;
}
void AddToListEnsuringSize(ClipboardData* data) {
DCHECK(data);
sequence_number_++;
data_list_.push_front(data);
if (data_list_.size() > kMaxClipboardSize) {
ClipboardData* last = data_list_.back();
data_list_.pop_back();
delete last;
}
}
std::list<ClipboardData*> data_list_;
uint64_t sequence_number_;
DISALLOW_COPY_AND_ASSIGN(AuraClipboard);
};
AuraClipboard* aura_clipboard = NULL;
AuraClipboard* GetClipboard() {
if (!aura_clipboard)
aura_clipboard = new AuraClipboard();
return aura_clipboard;
}
void DeleteClipboard() {
if (aura_clipboard)
delete aura_clipboard;
aura_clipboard = NULL;
}
class ClipboardDataBuilder {
public:
static void CommitToClipboard() {
GetClipboard()->WriteData(GetCurrentData());
current_data_ = NULL;
}
static void WriteText(const char* text_data, size_t text_len) {
ClipboardData* data = GetCurrentData();
data->set_text(std::string(text_data, text_len));
}
static void WriteHTML(const char* markup_data,
size_t markup_len,
const char* url_data,
size_t url_len) {
ClipboardData* data = GetCurrentData();
data->set_markup_data(std::string(markup_data, markup_len));
data->set_url(std::string(url_data, url_len));
}
static void WriteRTF(const char* rtf_data, size_t rtf_len) {
ClipboardData* data = GetCurrentData();
data->SetRTFData(std::string(rtf_data, rtf_len));
}
static void WriteBookmark(const char* title_data,
size_t title_len,
const char* url_data,
size_t url_len) {
ClipboardData* data = GetCurrentData();
data->set_bookmark_title(std::string(title_data, title_len));
data->set_bookmark_url(std::string(url_data, url_len));
}
static void WriteWebSmartPaste() {
ClipboardData* data = GetCurrentData();
data->set_web_smart_paste(true);
}
static void WriteBitmap(const SkBitmap& bitmap) {
ClipboardData* data = GetCurrentData();
data->SetBitmapData(bitmap);
}
static void WriteData(const std::string& format,
const char* data_data,
size_t data_len) {
ClipboardData* data = GetCurrentData();
data->SetCustomData(format, std::string(data_data, data_len));
}
private:
static ClipboardData* GetCurrentData() {
if (!current_data_)
current_data_ = new ClipboardData;
return current_data_;
}
static ClipboardData* current_data_;
};
ClipboardData* ClipboardDataBuilder::current_data_ = NULL;
}
Clipboard::FormatType::FormatType() {
}
Clipboard::FormatType::FormatType(const std::string& native_format)
: data_(native_format) {
}
Clipboard::FormatType::~FormatType() {
}
std::string Clipboard::FormatType::Serialize() const {
return data_;
}
Clipboard::FormatType Clipboard::FormatType::Deserialize(
const std::string& serialization) {
return FormatType(serialization);
}
bool Clipboard::FormatType::operator<(const FormatType& other) const {
return data_ < other.data_;
}
bool Clipboard::FormatType::Equals(const FormatType& other) const {
return data_ == other.data_;
}
Clipboard::Clipboard() {
DCHECK(CalledOnValidThread());
GetClipboard();
}
Clipboard::~Clipboard() {
DCHECK(CalledOnValidThread());
DeleteClipboard();
}
void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) {
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardType(type));
for (ObjectMap::const_iterator iter = objects.begin();
iter != objects.end(); ++iter) {
DispatchObject(static_cast<ObjectType>(iter->first), iter->second);
}
ClipboardDataBuilder::CommitToClipboard();
}
bool Clipboard::IsFormatAvailable(const FormatType& format,
ClipboardType type) const {
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardType(type));
AuraClipboard* clipboard = GetClipboard();
if (GetPlainTextFormatType().Equals(format) ||
GetUrlFormatType().Equals(format))
return clipboard->IsFormatAvailable(TEXT);
else if (GetHtmlFormatType().Equals(format))
return clipboard->IsFormatAvailable(HTML);
else if (GetRtfFormatType().Equals(format))
return clipboard->IsFormatAvailable(RTF);
else if (GetBitmapFormatType().Equals(format))
return clipboard->IsFormatAvailable(BITMAP);
else if (GetWebKitSmartPasteFormatType().Equals(format))
return clipboard->IsFormatAvailable(WEB);
else {
const ClipboardData* data = clipboard->GetData();
if (data && data->custom_data_format() == format.ToString())
return true;
}
return false;
}
void Clipboard::Clear(ClipboardType type) {
DCHECK(CalledOnValidThread());
DCHECK(IsSupportedClipboardType(type));
AuraClipboard* clipboard = GetClipboard();
clipboard->Clear();
}
void Clipboard::ReadAvailableTypes(ClipboardType type,
std::vector<base::string16>* types,
bool* contains_filenames) const {
DCHECK(CalledOnValidThread());
if (!types || !contains_filenames) {
NOTREACHED();
return;
}
types->clear();
*contains_filenames = false;
if (IsFormatAvailable(GetPlainTextFormatType(), type))
types->push_back(base::UTF8ToUTF16(GetPlainTextFormatType().ToString()));
if (IsFormatAvailable(GetHtmlFormatType(), type))
types->push_back(base::UTF8ToUTF16(GetHtmlFormatType().ToString()));
if (IsFormatAvailable(GetRtfFormatType(), type))
types->push_back(base::UTF8ToUTF16(GetRtfFormatType().ToString()));
if (IsFormatAvailable(GetBitmapFormatType(), type))
types->push_back(base::UTF8ToUTF16(kMimeTypePNG));
AuraClipboard* clipboard = GetClipboard();
if (clipboard->IsFormatAvailable(CUSTOM) && clipboard->GetData()) {
ui::ReadCustomDataTypes(clipboard->GetData()->custom_data_data().c_str(),
clipboard->GetData()->custom_data_data().size(), types);
}
}
void Clipboard::ReadText(ClipboardType type, base::string16* result) const {
DCHECK(CalledOnValidThread());
GetClipboard()->ReadText(result);
}
void Clipboard::ReadAsciiText(ClipboardType type, std::string* result) const {
DCHECK(CalledOnValidThread());
GetClipboard()->ReadAsciiText(result);
}
void Clipboard::ReadHTML(ClipboardType type,
base::string16* markup,
std::string* src_url,
uint32* fragment_start,
uint32* fragment_end) const {
DCHECK(CalledOnValidThread());
GetClipboard()->ReadHTML(markup, src_url, fragment_start, fragment_end);
}
void Clipboard::ReadRTF(ClipboardType type, std::string* result) const {
DCHECK(CalledOnValidThread());
GetClipboard()->ReadRTF(result);
}
SkBitmap Clipboard::ReadImage(ClipboardType type) const {
DCHECK(CalledOnValidThread());
return GetClipboard()->ReadImage();
}
void Clipboard::ReadCustomData(ClipboardType clipboard_type,
const base::string16& type,
base::string16* result) const {
DCHECK(CalledOnValidThread());
GetClipboard()->ReadCustomData(type, result);
}
void Clipboard::ReadBookmark(base::string16* title, std::string* url) const {
DCHECK(CalledOnValidThread());
GetClipboard()->ReadBookmark(title, url);
}
void Clipboard::ReadData(const FormatType& format, std::string* result) const {
DCHECK(CalledOnValidThread());
GetClipboard()->ReadData(format.ToString(), result);
}
uint64 Clipboard::GetSequenceNumber(ClipboardType type) {
DCHECK(CalledOnValidThread());
return GetClipboard()->sequence_number();
}
void Clipboard::WriteText(const char* text_data, size_t text_len) {
ClipboardDataBuilder::WriteText(text_data, text_len);
}
void Clipboard::WriteHTML(const char* markup_data,
size_t markup_len,
const char* url_data,
size_t url_len) {
ClipboardDataBuilder::WriteHTML(markup_data, markup_len, url_data, url_len);
}
void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) {
ClipboardDataBuilder::WriteRTF(rtf_data, data_len);
}
void Clipboard::WriteBookmark(const char* title_data,
size_t title_len,
const char* url_data,
size_t url_len) {
ClipboardDataBuilder::WriteBookmark(title_data, title_len, url_data, url_len);
}
void Clipboard::WriteWebSmartPaste() {
ClipboardDataBuilder::WriteWebSmartPaste();
}
void Clipboard::WriteBitmap(const SkBitmap& bitmap) {
ClipboardDataBuilder::WriteBitmap(bitmap);
}
void Clipboard::WriteData(const FormatType& format,
const char* data_data,
size_t data_len) {
ClipboardDataBuilder::WriteData(format.ToString(), data_data, data_len);
}
Clipboard::FormatType Clipboard::GetFormatType(
const std::string& format_string) {
return FormatType::Deserialize(format_string);
}
const Clipboard::FormatType& Clipboard::GetUrlFormatType() {
CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeURIList));
return type;
}
const Clipboard::FormatType& Clipboard::GetUrlWFormatType() {
return GetUrlFormatType();
}
const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() {
CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeText));
return type;
}
const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() {
return GetPlainTextFormatType();
}
const Clipboard::FormatType& Clipboard::GetFilenameFormatType() {
CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeFilename));
return type;
}
const Clipboard::FormatType& Clipboard::GetFilenameWFormatType() {
return Clipboard::GetFilenameFormatType();
}
const Clipboard::FormatType& Clipboard::GetHtmlFormatType() {
CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeHTML));
return type;
}
const Clipboard::FormatType& Clipboard::GetRtfFormatType() {
CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeRTF));
return type;
}
const Clipboard::FormatType& Clipboard::GetBitmapFormatType() {
CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeBitmap));
return type;
}
const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() {
CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebkitSmartPaste));
return type;
}
const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() {
CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomData));
return type;
}
const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() {
CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData));
return type;
}
}