OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 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/clipboard/clipboard.h" |
| 6 |
| 7 #include "base/logging.h" |
| 8 #include "base/utf_string_conversions.h" |
| 9 #include "third_party/skia/include/core/SkBitmap.h" |
| 10 #include "ui/gfx/linux_util.h" |
| 11 #include "ui/gfx/size.h" |
| 12 |
| 13 namespace ui { |
| 14 |
| 15 namespace { |
| 16 const char kMimeTypeBitmap[] = "image/bmp"; |
| 17 const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste"; |
| 18 |
| 19 // ClipboardData contains data copied to the Clipboard for a variety of formats. |
| 20 // It mostly just provides APIs to cleanly access and manipulate this data. |
| 21 class ClipboardData { |
| 22 public: |
| 23 ClipboardData() |
| 24 : bitmap_data_(), |
| 25 custom_data_data_(), |
| 26 custom_data_len_(0), |
| 27 web_smart_paste_(false) {} |
| 28 |
| 29 virtual ~ClipboardData() {} |
| 30 |
| 31 const std::string& text() const { return text_; } |
| 32 void set_text(const std::string& text) { text_ = text; } |
| 33 |
| 34 const std::string& markup_data() const { return markup_data_; } |
| 35 void set_markup_data(const std::string& markup_data) { |
| 36 markup_data_ = markup_data; |
| 37 } |
| 38 |
| 39 const std::string& url() const { return url_; } |
| 40 void set_url(const std::string& url) { url_ = url; } |
| 41 |
| 42 const std::string& bookmark_title() const { return bookmark_title_; } |
| 43 void set_bookmark_title(const std::string& bookmark_title) { |
| 44 bookmark_title_ = bookmark_title; |
| 45 } |
| 46 |
| 47 const std::string& bookmark_url() const { return bookmark_url_; } |
| 48 void set_bookmark_url(const std::string& bookmark_url) { |
| 49 bookmark_url_ = bookmark_url; |
| 50 } |
| 51 |
| 52 uint8_t* bitmap_data() const { return bitmap_data_.get(); } |
| 53 const gfx::Size& bitmap_size() const { return bitmap_size_; } |
| 54 void SetBitmapData(const char* pixel_data, const char* size_data) { |
| 55 bitmap_size_ = *reinterpret_cast<const gfx::Size*>(size_data); |
| 56 |
| 57 // We assume 4-byte pixel data. |
| 58 size_t bitmap_data_len = 4 * bitmap_size_.width() * bitmap_size_.height(); |
| 59 bitmap_data_.reset(new uint8_t[bitmap_data_len]); |
| 60 memcpy(bitmap_data_.get(), pixel_data, bitmap_data_len); |
| 61 } |
| 62 |
| 63 const std::string& custom_data_format() const { return custom_data_format_; } |
| 64 char* custom_data_data() const { return custom_data_data_.get(); } |
| 65 size_t custom_data_len() const { return custom_data_len_; } |
| 66 |
| 67 void SetCustomData(const std::string& data_format, |
| 68 const char* data_data, |
| 69 size_t data_len) { |
| 70 custom_data_len_ = data_len; |
| 71 if (custom_data_len_ == 0) { |
| 72 custom_data_data_.reset(); |
| 73 custom_data_format_.clear(); |
| 74 return; |
| 75 } |
| 76 custom_data_data_.reset(new char[custom_data_len_]); |
| 77 memcpy(custom_data_data_.get(), data_data, custom_data_len_); |
| 78 custom_data_format_ = data_format; |
| 79 } |
| 80 |
| 81 bool web_smart_paste() const { return web_smart_paste_; } |
| 82 void set_web_smart_paste(bool web_smart_paste) { |
| 83 web_smart_paste_ = web_smart_paste; |
| 84 } |
| 85 |
| 86 private: |
| 87 // Plain text in UTF8 format. |
| 88 std::string text_; |
| 89 |
| 90 // HTML markup data in UTF8 format. |
| 91 std::string markup_data_; |
| 92 std::string url_; |
| 93 |
| 94 // Bookmark title in UTF8 format. |
| 95 std::string bookmark_title_; |
| 96 std::string bookmark_url_; |
| 97 |
| 98 // Bitmap images. |
| 99 scoped_array<uint8_t> bitmap_data_; |
| 100 gfx::Size bitmap_size_; |
| 101 |
| 102 // Data with custom format. |
| 103 std::string custom_data_format_; |
| 104 scoped_array<char> custom_data_data_; |
| 105 size_t custom_data_len_; |
| 106 |
| 107 // WebKit smart paste data. |
| 108 bool web_smart_paste_; |
| 109 |
| 110 DISALLOW_COPY_AND_ASSIGN(ClipboardData); |
| 111 }; |
| 112 |
| 113 ClipboardData* clipboard_data = NULL; |
| 114 |
| 115 ClipboardData* GetClipboardData() { |
| 116 if (!clipboard_data) |
| 117 clipboard_data = new ClipboardData(); |
| 118 return clipboard_data; |
| 119 } |
| 120 |
| 121 void DeleteClipboardData() { |
| 122 if (clipboard_data) |
| 123 delete clipboard_data; |
| 124 clipboard_data = NULL; |
| 125 } |
| 126 |
| 127 } // namespace |
| 128 |
| 129 // TODO(varunjain): Complete implementation: |
| 130 // 1. Handle different types of BUFFERs. |
| 131 // 2. Do we need to care about concurrency here? Can there be multiple instances |
| 132 // of ui::Clipboard? Ask oshima. |
| 133 // 3. Implement File types. |
| 134 // 4. Handle conversion between types. |
| 135 |
| 136 Clipboard::Clipboard() { |
| 137 // Make sure clipboard is created. |
| 138 GetClipboardData(); |
| 139 } |
| 140 |
| 141 Clipboard::~Clipboard() { |
| 142 } |
| 143 |
| 144 void Clipboard::WriteObjects(const ObjectMap& objects) { |
| 145 // We need to overwrite previous data. Probably best to just delete |
| 146 // everything and start fresh. |
| 147 DeleteClipboardData(); |
| 148 for (ObjectMap::const_iterator iter = objects.begin(); |
| 149 iter != objects.end(); ++iter) { |
| 150 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); |
| 151 } |
| 152 } |
| 153 |
| 154 void Clipboard::WriteObjects(const ObjectMap& objects, |
| 155 base::ProcessHandle process) { |
| 156 NOTIMPLEMENTED(); |
| 157 } |
| 158 |
| 159 bool Clipboard::IsFormatAvailable(const FormatType& format, |
| 160 Buffer buffer) const { |
| 161 ClipboardData* data = GetClipboardData(); |
| 162 if (GetPlainTextFormatType() == format) |
| 163 return !data->text().empty(); |
| 164 else if (GetHtmlFormatType() == format) |
| 165 return !data->markup_data().empty() || !data->url().empty(); |
| 166 else if (GetBitmapFormatType() == format) |
| 167 return !!data->bitmap_data(); |
| 168 else if (GetWebKitSmartPasteFormatType() == format) |
| 169 return data->web_smart_paste(); |
| 170 else if (data->custom_data_format() == format) |
| 171 return true; |
| 172 return false; |
| 173 } |
| 174 |
| 175 bool Clipboard::IsFormatAvailableByString(const std::string& format, |
| 176 Buffer buffer) const { |
| 177 return IsFormatAvailable(format, buffer); |
| 178 } |
| 179 |
| 180 void Clipboard::ReadAvailableTypes(Buffer buffer, std::vector<string16>* types, |
| 181 bool* contains_filenames) const { |
| 182 if (!types || !contains_filenames) { |
| 183 NOTREACHED(); |
| 184 return; |
| 185 } |
| 186 |
| 187 types->clear(); |
| 188 if (IsFormatAvailable(GetPlainTextFormatType(), buffer)) |
| 189 types->push_back(UTF8ToUTF16(GetPlainTextFormatType())); |
| 190 if (IsFormatAvailable(GetHtmlFormatType(), buffer)) |
| 191 types->push_back(UTF8ToUTF16(GetHtmlFormatType())); |
| 192 if (IsFormatAvailable(GetBitmapFormatType(), buffer)) |
| 193 types->push_back(UTF8ToUTF16(GetBitmapFormatType())); |
| 194 if (IsFormatAvailable(GetWebKitSmartPasteFormatType(), buffer)) |
| 195 types->push_back(UTF8ToUTF16(GetWebKitSmartPasteFormatType())); |
| 196 *contains_filenames = false; |
| 197 } |
| 198 |
| 199 void Clipboard::ReadText(Buffer buffer, string16* result) const { |
| 200 *result = UTF8ToUTF16(GetClipboardData()->text()); |
| 201 } |
| 202 |
| 203 void Clipboard::ReadAsciiText(Buffer buffer, std::string* result) const { |
| 204 *result = GetClipboardData()->text(); |
| 205 } |
| 206 |
| 207 void Clipboard::ReadHTML(Buffer buffer, |
| 208 string16* markup, |
| 209 std::string* src_url, |
| 210 uint32* fragment_start, |
| 211 uint32* fragment_end) const { |
| 212 markup->clear(); |
| 213 if (src_url) |
| 214 src_url->clear(); |
| 215 *fragment_start = 0; |
| 216 *fragment_end = 0; |
| 217 |
| 218 *markup = UTF8ToUTF16(GetClipboardData()->markup_data()); |
| 219 *src_url = GetClipboardData()->url(); |
| 220 |
| 221 *fragment_start = 0; |
| 222 DCHECK(markup->length() <= kuint32max); |
| 223 *fragment_end = static_cast<uint32>(markup->length()); |
| 224 |
| 225 } |
| 226 |
| 227 SkBitmap Clipboard::ReadImage(Buffer buffer) const { |
| 228 const gfx::Size size = GetClipboardData()->bitmap_size(); |
| 229 uint8_t* bitmap = GetClipboardData()->bitmap_data(); |
| 230 SkBitmap image; |
| 231 image.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height(), 0); |
| 232 image.allocPixels(); |
| 233 image.eraseARGB(0, 0, 0, 0); |
| 234 int byte_counter = 0; |
| 235 for (int i = 0; i < size.height(); ++i) { |
| 236 for (int j = 0; j < size.width(); ++j) { |
| 237 uint32* pixel = image.getAddr32(j, i); |
| 238 *pixel = (bitmap[byte_counter] << 0) + /* R */ |
| 239 (bitmap[byte_counter + 1] << 8) + /* G */ |
| 240 (bitmap[byte_counter + 2] << 16) + /* B */ |
| 241 (bitmap[byte_counter + 3] << 24); /* A */ |
| 242 byte_counter += 4; |
| 243 } |
| 244 } |
| 245 return image; |
| 246 } |
| 247 |
| 248 void Clipboard::ReadBookmark(string16* title, std::string* url) const { |
| 249 *title = UTF8ToUTF16(GetClipboardData()->bookmark_title()); |
| 250 *url = GetClipboardData()->bookmark_url(); |
| 251 } |
| 252 |
| 253 void Clipboard::ReadFile(FilePath* file) const { |
| 254 NOTIMPLEMENTED(); |
| 255 } |
| 256 |
| 257 void Clipboard::ReadFiles(std::vector<FilePath>* files) const { |
| 258 NOTIMPLEMENTED(); |
| 259 } |
| 260 |
| 261 void Clipboard::ReadData(const std::string& format, std::string* result) { |
| 262 result->clear(); |
| 263 ClipboardData* data = GetClipboardData(); |
| 264 if (data->custom_data_format() == format) |
| 265 *result = std::string(data->custom_data_data(), data->custom_data_len()); |
| 266 } |
| 267 |
| 268 uint64 Clipboard::GetSequenceNumber() { |
| 269 NOTIMPLEMENTED(); |
| 270 return 0; |
| 271 } |
| 272 |
| 273 void Clipboard::WriteText(const char* text_data, size_t text_len) { |
| 274 GetClipboardData()->set_text(std::string(text_data, text_len)); |
| 275 } |
| 276 |
| 277 void Clipboard::WriteHTML(const char* markup_data, |
| 278 size_t markup_len, |
| 279 const char* url_data, |
| 280 size_t url_len) { |
| 281 GetClipboardData()->set_markup_data(std::string(markup_data, markup_len)); |
| 282 GetClipboardData()->set_url(std::string(url_data, url_len)); |
| 283 } |
| 284 |
| 285 void Clipboard::WriteBookmark(const char* title_data, |
| 286 size_t title_len, |
| 287 const char* url_data, |
| 288 size_t url_len) { |
| 289 GetClipboardData()->set_bookmark_title(std::string(title_data, title_len)); |
| 290 GetClipboardData()->set_bookmark_url(std::string(url_data, url_len)); |
| 291 } |
| 292 |
| 293 void Clipboard::WriteWebSmartPaste() { |
| 294 GetClipboardData()->set_web_smart_paste(true); |
| 295 } |
| 296 |
| 297 void Clipboard::WriteBitmap(const char* pixel_data, const char* size_data) { |
| 298 GetClipboardData()->SetBitmapData(pixel_data, size_data); |
| 299 } |
| 300 |
| 301 void Clipboard::WriteData(const char* format_name, size_t format_len, |
| 302 const char* data_data, size_t data_len) { |
| 303 GetClipboardData()->SetCustomData(std::string(format_name, format_len), |
| 304 data_data, data_len); |
| 305 } |
| 306 |
| 307 // static |
| 308 Clipboard::FormatType Clipboard::GetPlainTextFormatType() { |
| 309 return std::string(kMimeTypeText); |
| 310 } |
| 311 |
| 312 // static |
| 313 Clipboard::FormatType Clipboard::GetPlainTextWFormatType() { |
| 314 return GetPlainTextFormatType(); |
| 315 } |
| 316 |
| 317 // static |
| 318 Clipboard::FormatType Clipboard::GetHtmlFormatType() { |
| 319 return std::string(kMimeTypeHTML); |
| 320 } |
| 321 |
| 322 // static |
| 323 Clipboard::FormatType Clipboard::GetBitmapFormatType() { |
| 324 return std::string(kMimeTypeBitmap); |
| 325 } |
| 326 |
| 327 // static |
| 328 Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { |
| 329 return std::string(kMimeTypeWebkitSmartPaste); |
| 330 } |
| 331 |
| 332 } // namespace ui |
OLD | NEW |