OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/base/clipboard/clipboard.h" | 5 #include "ui/base/clipboard/clipboard.h" |
6 | 6 |
7 #import <Cocoa/Cocoa.h> | 7 #import <Cocoa/Cocoa.h> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 // The pasteboard should not be nil in a UI session, but this handy DCHECK | 43 // The pasteboard should not be nil in a UI session, but this handy DCHECK |
44 // can help track down problems if someone tries using clipboard code outside | 44 // can help track down problems if someone tries using clipboard code outside |
45 // of a UI session. | 45 // of a UI session. |
46 NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; | 46 NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; |
47 DCHECK(pasteboard); | 47 DCHECK(pasteboard); |
48 return pasteboard; | 48 return pasteboard; |
49 } | 49 } |
50 | 50 |
51 } // namespace | 51 } // namespace |
52 | 52 |
| 53 // Clipboard::FormatType implementation. |
53 Clipboard::FormatType::FormatType() : data_(nil) { | 54 Clipboard::FormatType::FormatType() : data_(nil) { |
54 } | 55 } |
55 | 56 |
56 Clipboard::FormatType::FormatType(NSString* native_format) | 57 Clipboard::FormatType::FormatType(NSString* native_format) |
57 : data_([native_format retain]) { | 58 : data_([native_format retain]) { |
58 } | 59 } |
59 | 60 |
60 Clipboard::FormatType::FormatType(const FormatType& other) | 61 Clipboard::FormatType::FormatType(const FormatType& other) |
61 : data_([other.data_ retain]) { | 62 : data_([other.data_ retain]) { |
62 } | 63 } |
(...skipping 18 matching lines...) Expand all Loading... |
81 std::string Clipboard::FormatType::Serialize() const { | 82 std::string Clipboard::FormatType::Serialize() const { |
82 return base::SysNSStringToUTF8(data_); | 83 return base::SysNSStringToUTF8(data_); |
83 } | 84 } |
84 | 85 |
85 // static | 86 // static |
86 Clipboard::FormatType Clipboard::FormatType::Deserialize( | 87 Clipboard::FormatType Clipboard::FormatType::Deserialize( |
87 const std::string& serialization) { | 88 const std::string& serialization) { |
88 return FormatType(base::SysUTF8ToNSString(serialization)); | 89 return FormatType(base::SysUTF8ToNSString(serialization)); |
89 } | 90 } |
90 | 91 |
| 92 // Various predefined FormatTypes. |
| 93 // static |
| 94 Clipboard::FormatType Clipboard::GetFormatType( |
| 95 const std::string& format_string) { |
| 96 return FormatType::Deserialize(format_string); |
| 97 } |
| 98 |
| 99 // static |
| 100 const Clipboard::FormatType& Clipboard::GetUrlFormatType() { |
| 101 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSURLPboardType)); |
| 102 return type; |
| 103 } |
| 104 |
| 105 // static |
| 106 const Clipboard::FormatType& Clipboard::GetUrlWFormatType() { |
| 107 return GetUrlFormatType(); |
| 108 } |
| 109 |
| 110 // static |
| 111 const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() { |
| 112 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSStringPboardType)); |
| 113 return type; |
| 114 } |
| 115 |
| 116 // static |
| 117 const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() { |
| 118 return GetPlainTextFormatType(); |
| 119 } |
| 120 |
| 121 // static |
| 122 const Clipboard::FormatType& Clipboard::GetFilenameFormatType() { |
| 123 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSFilenamesPboardType)); |
| 124 return type; |
| 125 } |
| 126 |
| 127 // static |
| 128 const Clipboard::FormatType& Clipboard::GetFilenameWFormatType() { |
| 129 return GetFilenameFormatType(); |
| 130 } |
| 131 |
| 132 // static |
| 133 const Clipboard::FormatType& Clipboard::GetHtmlFormatType() { |
| 134 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSHTMLPboardType)); |
| 135 return type; |
| 136 } |
| 137 |
| 138 // static |
| 139 const Clipboard::FormatType& Clipboard::GetRtfFormatType() { |
| 140 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSRTFPboardType)); |
| 141 return type; |
| 142 } |
| 143 |
| 144 // static |
| 145 const Clipboard::FormatType& Clipboard::GetBitmapFormatType() { |
| 146 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSTIFFPboardType)); |
| 147 return type; |
| 148 } |
| 149 |
| 150 // static |
| 151 const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() { |
| 152 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kWebSmartPastePboardType)); |
| 153 return type; |
| 154 } |
| 155 |
| 156 // static |
| 157 const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() { |
| 158 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kWebCustomDataPboardType)); |
| 159 return type; |
| 160 } |
| 161 |
| 162 // static |
| 163 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { |
| 164 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kPepperCustomDataPboardType)); |
| 165 return type; |
| 166 } |
| 167 |
| 168 // Clipboard implementation. |
91 Clipboard::Clipboard() { | 169 Clipboard::Clipboard() { |
92 DCHECK(CalledOnValidThread()); | 170 DCHECK(CalledOnValidThread()); |
93 } | 171 } |
94 | 172 |
95 Clipboard::~Clipboard() { | 173 Clipboard::~Clipboard() { |
96 DCHECK(CalledOnValidThread()); | 174 DCHECK(CalledOnValidThread()); |
97 } | 175 } |
98 | 176 |
99 void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) { | |
100 DCHECK(CalledOnValidThread()); | |
101 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | |
102 | |
103 NSPasteboard* pb = GetPasteboard(); | |
104 [pb declareTypes:[NSArray array] owner:nil]; | |
105 | |
106 for (ObjectMap::const_iterator iter = objects.begin(); | |
107 iter != objects.end(); ++iter) { | |
108 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); | |
109 } | |
110 } | |
111 | |
112 void Clipboard::WriteText(const char* text_data, size_t text_len) { | |
113 std::string text_str(text_data, text_len); | |
114 NSString *text = base::SysUTF8ToNSString(text_str); | |
115 NSPasteboard* pb = GetPasteboard(); | |
116 [pb addTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; | |
117 [pb setString:text forType:NSStringPboardType]; | |
118 } | |
119 | |
120 void Clipboard::WriteHTML(const char* markup_data, | |
121 size_t markup_len, | |
122 const char* url_data, | |
123 size_t url_len) { | |
124 // We need to mark it as utf-8. (see crbug.com/11957) | |
125 std::string html_fragment_str("<meta charset='utf-8'>"); | |
126 html_fragment_str.append(markup_data, markup_len); | |
127 NSString *html_fragment = base::SysUTF8ToNSString(html_fragment_str); | |
128 | |
129 // TODO(avi): url_data? | |
130 NSPasteboard* pb = GetPasteboard(); | |
131 [pb addTypes:[NSArray arrayWithObject:NSHTMLPboardType] owner:nil]; | |
132 [pb setString:html_fragment forType:NSHTMLPboardType]; | |
133 } | |
134 | |
135 void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { | |
136 WriteData(GetRtfFormatType(), rtf_data, data_len); | |
137 } | |
138 | |
139 void Clipboard::WriteBookmark(const char* title_data, | |
140 size_t title_len, | |
141 const char* url_data, | |
142 size_t url_len) { | |
143 std::string title_str(title_data, title_len); | |
144 NSString *title = base::SysUTF8ToNSString(title_str); | |
145 std::string url_str(url_data, url_len); | |
146 NSString *url = base::SysUTF8ToNSString(url_str); | |
147 | |
148 // TODO(playmobil): In the Windows version of this function, an HTML | |
149 // representation of the bookmark is also added to the clipboard, to support | |
150 // drag and drop of web shortcuts. I don't think we need to do this on the | |
151 // Mac, but we should double check later on. | |
152 NSURL* nsurl = [NSURL URLWithString:url]; | |
153 | |
154 NSPasteboard* pb = GetPasteboard(); | |
155 // passing UTIs into the pasteboard methods is valid >= 10.5 | |
156 [pb addTypes:[NSArray arrayWithObjects:NSURLPboardType, | |
157 kUTTypeURLName, | |
158 nil] | |
159 owner:nil]; | |
160 [nsurl writeToPasteboard:pb]; | |
161 [pb setString:title forType:kUTTypeURLName]; | |
162 } | |
163 | |
164 void Clipboard::WriteBitmap(const SkBitmap& bitmap) { | |
165 NSImage* image = gfx::SkBitmapToNSImageWithColorSpace( | |
166 bitmap, base::mac::GetSystemColorSpace()); | |
167 // An API to ask the NSImage to write itself to the clipboard comes in 10.6 :( | |
168 // For now, spit out the image as a TIFF. | |
169 NSPasteboard* pb = GetPasteboard(); | |
170 [pb addTypes:[NSArray arrayWithObject:NSTIFFPboardType] owner:nil]; | |
171 NSData *tiff_data = [image TIFFRepresentation]; | |
172 LOG_IF(ERROR, tiff_data == NULL) << "Failed to allocate image for clipboard"; | |
173 if (tiff_data) { | |
174 [pb setData:tiff_data forType:NSTIFFPboardType]; | |
175 } | |
176 } | |
177 | |
178 void Clipboard::WriteData(const FormatType& format, | |
179 const char* data_data, | |
180 size_t data_len) { | |
181 NSPasteboard* pb = GetPasteboard(); | |
182 [pb addTypes:[NSArray arrayWithObject:format.ToNSString()] owner:nil]; | |
183 [pb setData:[NSData dataWithBytes:data_data length:data_len] | |
184 forType:format.ToNSString()]; | |
185 } | |
186 | |
187 // Write an extra flavor that signifies WebKit was the last to modify the | |
188 // pasteboard. This flavor has no data. | |
189 void Clipboard::WriteWebSmartPaste() { | |
190 NSPasteboard* pb = GetPasteboard(); | |
191 NSString* format = GetWebKitSmartPasteFormatType().ToNSString(); | |
192 [pb addTypes:[NSArray arrayWithObject:format] owner:nil]; | |
193 [pb setData:nil forType:format]; | |
194 } | |
195 | |
196 uint64 Clipboard::GetSequenceNumber(ClipboardType type) { | 177 uint64 Clipboard::GetSequenceNumber(ClipboardType type) { |
197 DCHECK(CalledOnValidThread()); | 178 DCHECK(CalledOnValidThread()); |
198 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 179 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
199 | 180 |
200 NSPasteboard* pb = GetPasteboard(); | 181 NSPasteboard* pb = GetPasteboard(); |
201 return [pb changeCount]; | 182 return [pb changeCount]; |
202 } | 183 } |
203 | 184 |
204 bool Clipboard::IsFormatAvailable(const FormatType& format, | 185 bool Clipboard::IsFormatAvailable(const FormatType& format, |
205 ClipboardType type) const { | 186 ClipboardType type) const { |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 } | 340 } |
360 | 341 |
361 void Clipboard::ReadData(const FormatType& format, std::string* result) const { | 342 void Clipboard::ReadData(const FormatType& format, std::string* result) const { |
362 DCHECK(CalledOnValidThread()); | 343 DCHECK(CalledOnValidThread()); |
363 NSPasteboard* pb = GetPasteboard(); | 344 NSPasteboard* pb = GetPasteboard(); |
364 NSData* data = [pb dataForType:format.ToNSString()]; | 345 NSData* data = [pb dataForType:format.ToNSString()]; |
365 if ([data length]) | 346 if ([data length]) |
366 result->assign(static_cast<const char*>([data bytes]), [data length]); | 347 result->assign(static_cast<const char*>([data bytes]), [data length]); |
367 } | 348 } |
368 | 349 |
369 // static | 350 void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) { |
370 Clipboard::FormatType Clipboard::GetFormatType( | 351 DCHECK(CalledOnValidThread()); |
371 const std::string& format_string) { | 352 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
372 return FormatType::Deserialize(format_string); | 353 |
| 354 NSPasteboard* pb = GetPasteboard(); |
| 355 [pb declareTypes:[NSArray array] owner:nil]; |
| 356 |
| 357 for (ObjectMap::const_iterator iter = objects.begin(); |
| 358 iter != objects.end(); ++iter) { |
| 359 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); |
| 360 } |
373 } | 361 } |
374 | 362 |
375 // static | 363 void Clipboard::WriteText(const char* text_data, size_t text_len) { |
376 const Clipboard::FormatType& Clipboard::GetUrlFormatType() { | 364 std::string text_str(text_data, text_len); |
377 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSURLPboardType)); | 365 NSString *text = base::SysUTF8ToNSString(text_str); |
378 return type; | 366 NSPasteboard* pb = GetPasteboard(); |
| 367 [pb addTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; |
| 368 [pb setString:text forType:NSStringPboardType]; |
379 } | 369 } |
380 | 370 |
381 // static | 371 void Clipboard::WriteHTML(const char* markup_data, |
382 const Clipboard::FormatType& Clipboard::GetUrlWFormatType() { | 372 size_t markup_len, |
383 return GetUrlFormatType(); | 373 const char* url_data, |
| 374 size_t url_len) { |
| 375 // We need to mark it as utf-8. (see crbug.com/11957) |
| 376 std::string html_fragment_str("<meta charset='utf-8'>"); |
| 377 html_fragment_str.append(markup_data, markup_len); |
| 378 NSString *html_fragment = base::SysUTF8ToNSString(html_fragment_str); |
| 379 |
| 380 // TODO(avi): url_data? |
| 381 NSPasteboard* pb = GetPasteboard(); |
| 382 [pb addTypes:[NSArray arrayWithObject:NSHTMLPboardType] owner:nil]; |
| 383 [pb setString:html_fragment forType:NSHTMLPboardType]; |
384 } | 384 } |
385 | 385 |
386 // static | 386 void Clipboard::WriteRTF(const char* rtf_data, size_t data_len) { |
387 const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() { | 387 WriteData(GetRtfFormatType(), rtf_data, data_len); |
388 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSStringPboardType)); | |
389 return type; | |
390 } | 388 } |
391 | 389 |
392 // static | 390 void Clipboard::WriteBookmark(const char* title_data, |
393 const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() { | 391 size_t title_len, |
394 return GetPlainTextFormatType(); | 392 const char* url_data, |
| 393 size_t url_len) { |
| 394 std::string title_str(title_data, title_len); |
| 395 NSString *title = base::SysUTF8ToNSString(title_str); |
| 396 std::string url_str(url_data, url_len); |
| 397 NSString *url = base::SysUTF8ToNSString(url_str); |
| 398 |
| 399 // TODO(playmobil): In the Windows version of this function, an HTML |
| 400 // representation of the bookmark is also added to the clipboard, to support |
| 401 // drag and drop of web shortcuts. I don't think we need to do this on the |
| 402 // Mac, but we should double check later on. |
| 403 NSURL* nsurl = [NSURL URLWithString:url]; |
| 404 |
| 405 NSPasteboard* pb = GetPasteboard(); |
| 406 // passing UTIs into the pasteboard methods is valid >= 10.5 |
| 407 [pb addTypes:[NSArray arrayWithObjects:NSURLPboardType, |
| 408 kUTTypeURLName, |
| 409 nil] |
| 410 owner:nil]; |
| 411 [nsurl writeToPasteboard:pb]; |
| 412 [pb setString:title forType:kUTTypeURLName]; |
395 } | 413 } |
396 | 414 |
397 // static | 415 void Clipboard::WriteBitmap(const SkBitmap& bitmap) { |
398 const Clipboard::FormatType& Clipboard::GetFilenameFormatType() { | 416 NSImage* image = gfx::SkBitmapToNSImageWithColorSpace( |
399 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSFilenamesPboardType)); | 417 bitmap, base::mac::GetSystemColorSpace()); |
400 return type; | 418 // An API to ask the NSImage to write itself to the clipboard comes in 10.6 :( |
| 419 // For now, spit out the image as a TIFF. |
| 420 NSPasteboard* pb = GetPasteboard(); |
| 421 [pb addTypes:[NSArray arrayWithObject:NSTIFFPboardType] owner:nil]; |
| 422 NSData *tiff_data = [image TIFFRepresentation]; |
| 423 LOG_IF(ERROR, tiff_data == NULL) << "Failed to allocate image for clipboard"; |
| 424 if (tiff_data) { |
| 425 [pb setData:tiff_data forType:NSTIFFPboardType]; |
| 426 } |
401 } | 427 } |
402 | 428 |
403 // static | 429 void Clipboard::WriteData(const FormatType& format, |
404 const Clipboard::FormatType& Clipboard::GetFilenameWFormatType() { | 430 const char* data_data, |
405 return GetFilenameFormatType(); | 431 size_t data_len) { |
| 432 NSPasteboard* pb = GetPasteboard(); |
| 433 [pb addTypes:[NSArray arrayWithObject:format.ToNSString()] owner:nil]; |
| 434 [pb setData:[NSData dataWithBytes:data_data length:data_len] |
| 435 forType:format.ToNSString()]; |
406 } | 436 } |
407 | 437 |
408 // static | 438 // Write an extra flavor that signifies WebKit was the last to modify the |
409 const Clipboard::FormatType& Clipboard::GetHtmlFormatType() { | 439 // pasteboard. This flavor has no data. |
410 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSHTMLPboardType)); | 440 void Clipboard::WriteWebSmartPaste() { |
411 return type; | 441 NSPasteboard* pb = GetPasteboard(); |
412 } | 442 NSString* format = GetWebKitSmartPasteFormatType().ToNSString(); |
413 | 443 [pb addTypes:[NSArray arrayWithObject:format] owner:nil]; |
414 // static | 444 [pb setData:nil forType:format]; |
415 const Clipboard::FormatType& Clipboard::GetRtfFormatType() { | |
416 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSRTFPboardType)); | |
417 return type; | |
418 } | |
419 | |
420 // static | |
421 const Clipboard::FormatType& Clipboard::GetBitmapFormatType() { | |
422 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSTIFFPboardType)); | |
423 return type; | |
424 } | |
425 | |
426 // static | |
427 const Clipboard::FormatType& Clipboard::GetWebKitSmartPasteFormatType() { | |
428 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kWebSmartPastePboardType)); | |
429 return type; | |
430 } | |
431 | |
432 // static | |
433 const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() { | |
434 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kWebCustomDataPboardType)); | |
435 return type; | |
436 } | |
437 | |
438 // static | |
439 const Clipboard::FormatType& Clipboard::GetPepperCustomDataFormatType() { | |
440 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kPepperCustomDataPboardType)); | |
441 return type; | |
442 } | 445 } |
443 | 446 |
444 } // namespace ui | 447 } // namespace ui |
OLD | NEW |