| 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 |