Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(447)

Side by Side Diff: ui/base/clipboard/clipboard_aura.cc

Issue 851853002: It is time. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Trying to reup because the last upload failed. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/base/clipboard/clipboard_aura.h ('k') | ui/base/clipboard/clipboard_aurax11.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/clipboard/clipboard_aura.h"
6
7 #include <list>
8
9 #include "base/basictypes.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/stl_util.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "third_party/skia/include/core/SkBitmap.h"
16 #include "ui/base/clipboard/custom_data_helper.h"
17 #include "ui/gfx/size.h"
18
19 namespace ui {
20
21 namespace {
22 const char kMimeTypeFilename[] = "chromium/filename";
23 const char kMimeTypeBitmap[] = "image/bmp";
24 const char kMimeTypePepperCustomData[] = "chromium/x-pepper-custom-data";
25 const char kMimeTypeWebkitSmartPaste[] = "chromium/x-webkit-paste";
26 const size_t kMaxClipboardSize = 1;
27
28 // Clipboard data format used by AuraClipboard.
29 enum AuraClipboardFormat {
30 TEXT = 1 << 0,
31 HTML = 1 << 1,
32 RTF = 1 << 2,
33 BOOKMARK = 1 << 3,
34 BITMAP = 1 << 4,
35 CUSTOM = 1 << 5,
36 WEB = 1 << 6,
37 };
38
39 // ClipboardData contains data copied to the Clipboard for a variety of formats.
40 // It mostly just provides APIs to cleanly access and manipulate this data.
41 class ClipboardData {
42 public:
43 ClipboardData()
44 : web_smart_paste_(false),
45 format_(0) {}
46
47 virtual ~ClipboardData() {}
48
49 // Bitmask of AuraClipboardFormat types.
50 int format() const { return format_; }
51
52 const std::string& text() const { return text_; }
53 void set_text(const std::string& text) {
54 text_ = text;
55 format_ |= TEXT;
56 }
57
58 const std::string& markup_data() const { return markup_data_; }
59 void set_markup_data(const std::string& markup_data) {
60 markup_data_ = markup_data;
61 format_ |= HTML;
62 }
63
64 const std::string& rtf_data() const { return rtf_data_; }
65 void SetRTFData(const std::string& rtf_data) {
66 rtf_data_ = rtf_data;
67 format_ |= RTF;
68 }
69
70 const std::string& url() const { return url_; }
71 void set_url(const std::string& url) {
72 url_ = url;
73 format_ |= HTML;
74 }
75
76 const std::string& bookmark_title() const { return bookmark_title_; }
77 void set_bookmark_title(const std::string& bookmark_title) {
78 bookmark_title_ = bookmark_title;
79 format_ |= BOOKMARK;
80 }
81
82 const std::string& bookmark_url() const { return bookmark_url_; }
83 void set_bookmark_url(const std::string& bookmark_url) {
84 bookmark_url_ = bookmark_url;
85 format_ |= BOOKMARK;
86 }
87
88 const SkBitmap& bitmap() const { return bitmap_; }
89 void SetBitmapData(const SkBitmap& bitmap) {
90 bitmap.copyTo(&bitmap_);
91 format_ |= BITMAP;
92 }
93
94 const std::string& custom_data_format() const { return custom_data_format_; }
95 const std::string& custom_data_data() const { return custom_data_data_; }
96 void SetCustomData(const std::string& data_format,
97 const std::string& data_data) {
98 if (data_data.size() == 0) {
99 custom_data_data_.clear();
100 custom_data_format_.clear();
101 return;
102 }
103 custom_data_data_ = data_data;
104 custom_data_format_ = data_format;
105 format_ |= CUSTOM;
106 }
107
108 bool web_smart_paste() const { return web_smart_paste_; }
109 void set_web_smart_paste(bool web_smart_paste) {
110 web_smart_paste_ = web_smart_paste;
111 format_ |= WEB;
112 }
113
114 private:
115 // Plain text in UTF8 format.
116 std::string text_;
117
118 // HTML markup data in UTF8 format.
119 std::string markup_data_;
120 std::string url_;
121
122 // RTF data.
123 std::string rtf_data_;
124
125 // Bookmark title in UTF8 format.
126 std::string bookmark_title_;
127 std::string bookmark_url_;
128
129 // Filenames.
130 std::vector<std::string> files_;
131
132 // Bitmap images.
133 SkBitmap bitmap_;
134
135 // Data with custom format.
136 std::string custom_data_format_;
137 std::string custom_data_data_;
138
139 // WebKit smart paste data.
140 bool web_smart_paste_;
141
142 int format_;
143
144 DISALLOW_COPY_AND_ASSIGN(ClipboardData);
145 };
146
147 // Platform clipboard implementation for Aura. This handles things like format
148 // conversion, versioning of clipboard items etc. The goal is to roughly provide
149 // a substitute to platform clipboards on other platforms such as GtkClipboard
150 // on gtk or winapi clipboard on win.
151 class AuraClipboard {
152 public:
153 AuraClipboard() : sequence_number_(0) {
154 }
155
156 ~AuraClipboard() {
157 Clear();
158 }
159
160 void Clear() {
161 sequence_number_++;
162 STLDeleteContainerPointers(data_list_.begin(), data_list_.end());
163 data_list_.clear();
164 }
165
166 uint64_t sequence_number() const {
167 return sequence_number_;
168 }
169
170 // Returns the data currently on the top of the clipboard stack, NULL if the
171 // clipboard stack is empty.
172 const ClipboardData* GetData() const {
173 if (data_list_.empty())
174 return NULL;
175 return data_list_.front();
176 }
177
178 // Returns true if the data on top of the clipboard stack has format |format|
179 // or another format that can be converted to |format|.
180 bool IsFormatAvailable(AuraClipboardFormat format) const {
181 switch (format) {
182 case TEXT:
183 return HasFormat(TEXT) || HasFormat(BOOKMARK);
184 default:
185 return HasFormat(format);
186 }
187 }
188
189 // Reads text from the data at the top of clipboard stack.
190 void ReadText(base::string16* result) const {
191 std::string utf8_result;
192 ReadAsciiText(&utf8_result);
193 *result = base::UTF8ToUTF16(utf8_result);
194 }
195
196 // Reads ascii text from the data at the top of clipboard stack.
197 void ReadAsciiText(std::string* result) const {
198 result->clear();
199 const ClipboardData* data = GetData();
200 if (!data)
201 return;
202 if (HasFormat(TEXT))
203 *result = data->text();
204 else if (HasFormat(HTML))
205 *result = data->markup_data();
206 else if (HasFormat(BOOKMARK))
207 *result = data->bookmark_url();
208 }
209
210 // Reads HTML from the data at the top of clipboard stack.
211 void ReadHTML(base::string16* markup,
212 std::string* src_url,
213 uint32* fragment_start,
214 uint32* fragment_end) const {
215 markup->clear();
216 if (src_url)
217 src_url->clear();
218 *fragment_start = 0;
219 *fragment_end = 0;
220
221 if (!HasFormat(HTML))
222 return;
223
224 const ClipboardData* data = GetData();
225 *markup = base::UTF8ToUTF16(data->markup_data());
226 *src_url = data->url();
227
228 *fragment_start = 0;
229 DCHECK_LE(markup->length(), kuint32max);
230 *fragment_end = static_cast<uint32>(markup->length());
231 }
232
233 // Reads RTF from the data at the top of clipboard stack.
234 void ReadRTF(std::string* result) const {
235 result->clear();
236 const ClipboardData* data = GetData();
237 if (!HasFormat(RTF))
238 return;
239
240 *result = data->rtf_data();
241 }
242
243 // Reads image from the data at the top of clipboard stack.
244 SkBitmap ReadImage() const {
245 SkBitmap img;
246 if (!HasFormat(BITMAP))
247 return img;
248
249 // A shallow copy should be fine here, but just to be safe...
250 const SkBitmap& clipboard_bitmap = GetData()->bitmap();
251 clipboard_bitmap.copyTo(&img);
252 return img;
253 }
254
255 // Reads data of type |type| from the data at the top of clipboard stack.
256 void ReadCustomData(const base::string16& type,
257 base::string16* result) const {
258 result->clear();
259 const ClipboardData* data = GetData();
260 if (!HasFormat(CUSTOM))
261 return;
262
263 ui::ReadCustomDataForType(data->custom_data_data().c_str(),
264 data->custom_data_data().size(),
265 type, result);
266 }
267
268 // Reads bookmark from the data at the top of clipboard stack.
269 void ReadBookmark(base::string16* title, std::string* url) const {
270 title->clear();
271 url->clear();
272 if (!HasFormat(BOOKMARK))
273 return;
274
275 const ClipboardData* data = GetData();
276 *title = base::UTF8ToUTF16(data->bookmark_title());
277 *url = data->bookmark_url();
278 }
279
280 void ReadData(const std::string& type, std::string* result) const {
281 result->clear();
282 const ClipboardData* data = GetData();
283 if (!HasFormat(CUSTOM) || type != data->custom_data_format())
284 return;
285
286 *result = data->custom_data_data();
287 }
288
289 // Writes |data| to the top of the clipboard stack.
290 void WriteData(ClipboardData* data) {
291 DCHECK(data);
292 AddToListEnsuringSize(data);
293 }
294
295 private:
296 // True if the data on top of the clipboard stack has format |format|.
297 bool HasFormat(AuraClipboardFormat format) const {
298 const ClipboardData* data = GetData();
299 if (!data)
300 return false;
301
302 return data->format() & format;
303 }
304
305 void AddToListEnsuringSize(ClipboardData* data) {
306 DCHECK(data);
307 sequence_number_++;
308 data_list_.push_front(data);
309
310 // If the size of list becomes more than the maximum allowed, we delete the
311 // last element.
312 if (data_list_.size() > kMaxClipboardSize) {
313 ClipboardData* last = data_list_.back();
314 data_list_.pop_back();
315 delete last;
316 }
317 }
318
319 // Stack containing various versions of ClipboardData.
320 std::list<ClipboardData*> data_list_;
321
322 // Sequence number uniquely identifying clipboard state.
323 uint64_t sequence_number_;
324
325 DISALLOW_COPY_AND_ASSIGN(AuraClipboard);
326 };
327
328 AuraClipboard* aura_clipboard = NULL;
329
330 AuraClipboard* GetClipboard() {
331 if (!aura_clipboard)
332 aura_clipboard = new AuraClipboard();
333 return aura_clipboard;
334 }
335
336 void DeleteClipboard() {
337 if (aura_clipboard)
338 delete aura_clipboard;
339 aura_clipboard = NULL;
340 }
341
342 // Helper class to build a ClipboardData object and write it to clipboard.
343 class ClipboardDataBuilder {
344 public:
345 static void CommitToClipboard() {
346 GetClipboard()->WriteData(GetCurrentData());
347 current_data_ = NULL;
348 }
349
350 static void WriteText(const char* text_data, size_t text_len) {
351 ClipboardData* data = GetCurrentData();
352 data->set_text(std::string(text_data, text_len));
353 }
354
355 static void WriteHTML(const char* markup_data,
356 size_t markup_len,
357 const char* url_data,
358 size_t url_len) {
359 ClipboardData* data = GetCurrentData();
360 data->set_markup_data(std::string(markup_data, markup_len));
361 data->set_url(std::string(url_data, url_len));
362 }
363
364 static void WriteRTF(const char* rtf_data, size_t rtf_len) {
365 ClipboardData* data = GetCurrentData();
366 data->SetRTFData(std::string(rtf_data, rtf_len));
367 }
368
369 static void WriteBookmark(const char* title_data,
370 size_t title_len,
371 const char* url_data,
372 size_t url_len) {
373 ClipboardData* data = GetCurrentData();
374 data->set_bookmark_title(std::string(title_data, title_len));
375 data->set_bookmark_url(std::string(url_data, url_len));
376 }
377
378 static void WriteWebSmartPaste() {
379 ClipboardData* data = GetCurrentData();
380 data->set_web_smart_paste(true);
381 }
382
383 static void WriteBitmap(const SkBitmap& bitmap) {
384 ClipboardData* data = GetCurrentData();
385 data->SetBitmapData(bitmap);
386 }
387
388 static void WriteData(const std::string& format,
389 const char* data_data,
390 size_t data_len) {
391 ClipboardData* data = GetCurrentData();
392 data->SetCustomData(format, std::string(data_data, data_len));
393 }
394
395 private:
396 static ClipboardData* GetCurrentData() {
397 if (!current_data_)
398 current_data_ = new ClipboardData;
399 return current_data_;
400 }
401
402 static ClipboardData* current_data_;
403 };
404
405 ClipboardData* ClipboardDataBuilder::current_data_ = NULL;
406
407 } // namespace
408
409 // Clipboard::FormatType implementation.
410 Clipboard::FormatType::FormatType() {
411 }
412
413 Clipboard::FormatType::FormatType(const std::string& native_format)
414 : data_(native_format) {
415 }
416
417 Clipboard::FormatType::~FormatType() {
418 }
419
420 std::string Clipboard::FormatType::Serialize() const {
421 return data_;
422 }
423
424 // static
425 Clipboard::FormatType Clipboard::FormatType::Deserialize(
426 const std::string& serialization) {
427 return FormatType(serialization);
428 }
429
430 bool Clipboard::FormatType::operator<(const FormatType& other) const {
431 return data_ < other.data_;
432 }
433
434 bool Clipboard::FormatType::Equals(const FormatType& other) const {
435 return data_ == other.data_;
436 }
437
438 // Various predefined FormatTypes.
439 // static
440 Clipboard::FormatType Clipboard::GetFormatType(
441 const std::string& format_string) {
442 return FormatType::Deserialize(format_string);
443 }
444
445 // static
446 const Clipboard::FormatType& Clipboard::GetUrlFormatType() {
447 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeURIList));
448 return type;
449 }
450
451 // static
452 const Clipboard::FormatType& Clipboard::GetUrlWFormatType() {
453 return GetUrlFormatType();
454 }
455
456 // static
457 const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() {
458 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeText));
459 return type;
460 }
461
462 // static
463 const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() {
464 return GetPlainTextFormatType();
465 }
466
467 // static
468 const Clipboard::FormatType& Clipboard::GetFilenameFormatType() {
469 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeFilename));
470 return type;
471 }
472
473 // static
474 const Clipboard::FormatType& Clipboard::GetFilenameWFormatType() {
475 return Clipboard::GetFilenameFormatType();
476 }
477
478 // static
479 const Clipboard::FormatType& Clipboard::GetHtmlFormatType() {
480 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeHTML));
481 return type;
482 }
483
484 // static
485 const Clipboard::FormatType& Clipboard::GetRtfFormatType() {
486 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeRTF));
487 return type;
488 }
489
490 // static
491 const Clipboard::FormatType& Clipboard::GetBitmapFormatType() {
492 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeBitmap));
493 return type;
494 }
495
496 // static
497 const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() {
498 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebkitSmartPaste));
499 return type;
500 }
501
502 // static
503 const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() {
504 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypeWebCustomData));
505 return type;
506 }
507
508 // static
509 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() {
510 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kMimeTypePepperCustomData));
511 return type;
512 }
513
514 // Clipboard factory method.
515 Clipboard* Clipboard::Create() {
516 return new ClipboardAura;
517 }
518
519 // ClipboardAura implementation.
520 ClipboardAura::ClipboardAura() {
521 DCHECK(CalledOnValidThread());
522 // Make sure clipboard is created.
523 GetClipboard();
524 }
525
526 ClipboardAura::~ClipboardAura() {
527 DCHECK(CalledOnValidThread());
528 DeleteClipboard();
529 }
530
531 uint64 ClipboardAura::GetSequenceNumber(ClipboardType type) {
532 DCHECK(CalledOnValidThread());
533 return GetClipboard()->sequence_number();
534 }
535
536 bool ClipboardAura::IsFormatAvailable(const FormatType& format,
537 ClipboardType type) const {
538 DCHECK(CalledOnValidThread());
539 DCHECK(IsSupportedClipboardType(type));
540 AuraClipboard* clipboard = GetClipboard();
541 if (GetPlainTextFormatType().Equals(format) ||
542 GetUrlFormatType().Equals(format))
543 return clipboard->IsFormatAvailable(TEXT);
544 else if (GetHtmlFormatType().Equals(format))
545 return clipboard->IsFormatAvailable(HTML);
546 else if (GetRtfFormatType().Equals(format))
547 return clipboard->IsFormatAvailable(RTF);
548 else if (GetBitmapFormatType().Equals(format))
549 return clipboard->IsFormatAvailable(BITMAP);
550 else if (GetWebKitSmartPasteFormatType().Equals(format))
551 return clipboard->IsFormatAvailable(WEB);
552 else {
553 const ClipboardData* data = clipboard->GetData();
554 if (data && data->custom_data_format() == format.ToString())
555 return true;
556 }
557 return false;
558 }
559
560 void ClipboardAura::Clear(ClipboardType type) {
561 DCHECK(CalledOnValidThread());
562 DCHECK(IsSupportedClipboardType(type));
563 AuraClipboard* clipboard = GetClipboard();
564 clipboard->Clear();
565 }
566
567 void ClipboardAura::ReadAvailableTypes(ClipboardType type,
568 std::vector<base::string16>* types,
569 bool* contains_filenames) const {
570 DCHECK(CalledOnValidThread());
571 if (!types || !contains_filenames) {
572 NOTREACHED();
573 return;
574 }
575
576 types->clear();
577 *contains_filenames = false;
578 if (IsFormatAvailable(GetPlainTextFormatType(), type))
579 types->push_back(base::UTF8ToUTF16(GetPlainTextFormatType().ToString()));
580 if (IsFormatAvailable(GetHtmlFormatType(), type))
581 types->push_back(base::UTF8ToUTF16(GetHtmlFormatType().ToString()));
582 if (IsFormatAvailable(GetRtfFormatType(), type))
583 types->push_back(base::UTF8ToUTF16(GetRtfFormatType().ToString()));
584 if (IsFormatAvailable(GetBitmapFormatType(), type))
585 types->push_back(base::UTF8ToUTF16(kMimeTypePNG));
586
587 AuraClipboard* clipboard = GetClipboard();
588 if (clipboard->IsFormatAvailable(CUSTOM) && clipboard->GetData()) {
589 ui::ReadCustomDataTypes(clipboard->GetData()->custom_data_data().c_str(),
590 clipboard->GetData()->custom_data_data().size(), types);
591 }
592 }
593
594 void ClipboardAura::ReadText(ClipboardType type, base::string16* result) const {
595 DCHECK(CalledOnValidThread());
596 GetClipboard()->ReadText(result);
597 }
598
599 void ClipboardAura::ReadAsciiText(ClipboardType type,
600 std::string* result) const {
601 DCHECK(CalledOnValidThread());
602 GetClipboard()->ReadAsciiText(result);
603 }
604
605 void ClipboardAura::ReadHTML(ClipboardType type,
606 base::string16* markup,
607 std::string* src_url,
608 uint32* fragment_start,
609 uint32* fragment_end) const {
610 DCHECK(CalledOnValidThread());
611 GetClipboard()->ReadHTML(markup, src_url, fragment_start, fragment_end);
612 }
613
614 void ClipboardAura::ReadRTF(ClipboardType type, std::string* result) const {
615 DCHECK(CalledOnValidThread());
616 GetClipboard()->ReadRTF(result);
617 }
618
619 SkBitmap ClipboardAura::ReadImage(ClipboardType type) const {
620 DCHECK(CalledOnValidThread());
621 return GetClipboard()->ReadImage();
622 }
623
624 void ClipboardAura::ReadCustomData(ClipboardType clipboard_type,
625 const base::string16& type,
626 base::string16* result) const {
627 DCHECK(CalledOnValidThread());
628 GetClipboard()->ReadCustomData(type, result);
629 }
630
631 void ClipboardAura::ReadBookmark(base::string16* title,
632 std::string* url) const {
633 DCHECK(CalledOnValidThread());
634 GetClipboard()->ReadBookmark(title, url);
635 }
636
637 void ClipboardAura::ReadData(const FormatType& format,
638 std::string* result) const {
639 DCHECK(CalledOnValidThread());
640 GetClipboard()->ReadData(format.ToString(), result);
641 }
642
643 void ClipboardAura::WriteObjects(ClipboardType type, const ObjectMap& objects) {
644 DCHECK(CalledOnValidThread());
645 DCHECK(IsSupportedClipboardType(type));
646 for (ObjectMap::const_iterator iter = objects.begin(); iter != objects.end();
647 ++iter) {
648 DispatchObject(static_cast<ObjectType>(iter->first), iter->second);
649 }
650 ClipboardDataBuilder::CommitToClipboard();
651 }
652
653 void ClipboardAura::WriteText(const char* text_data, size_t text_len) {
654 ClipboardDataBuilder::WriteText(text_data, text_len);
655 }
656
657 void ClipboardAura::WriteHTML(const char* markup_data,
658 size_t markup_len,
659 const char* url_data,
660 size_t url_len) {
661 ClipboardDataBuilder::WriteHTML(markup_data, markup_len, url_data, url_len);
662 }
663
664 void ClipboardAura::WriteRTF(const char* rtf_data, size_t data_len) {
665 ClipboardDataBuilder::WriteRTF(rtf_data, data_len);
666 }
667
668 void ClipboardAura::WriteBookmark(const char* title_data,
669 size_t title_len,
670 const char* url_data,
671 size_t url_len) {
672 ClipboardDataBuilder::WriteBookmark(title_data, title_len, url_data, url_len);
673 }
674
675 void ClipboardAura::WriteWebSmartPaste() {
676 ClipboardDataBuilder::WriteWebSmartPaste();
677 }
678
679 void ClipboardAura::WriteBitmap(const SkBitmap& bitmap) {
680 ClipboardDataBuilder::WriteBitmap(bitmap);
681 }
682
683 void ClipboardAura::WriteData(const FormatType& format,
684 const char* data_data,
685 size_t data_len) {
686 ClipboardDataBuilder::WriteData(format.ToString(), data_data, data_len);
687 }
688
689 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/clipboard/clipboard_aura.h ('k') | ui/base/clipboard/clipboard_aurax11.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698