| 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/file_path.h" | 10 #include "base/file_path.h" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 72 return base::SysNSStringToUTF8(data_); | 72 return base::SysNSStringToUTF8(data_); |
| 73 } | 73 } |
| 74 | 74 |
| 75 // static | 75 // static |
| 76 Clipboard::FormatType Clipboard::FormatType::Deserialize( | 76 Clipboard::FormatType Clipboard::FormatType::Deserialize( |
| 77 const std::string& serialization) { | 77 const std::string& serialization) { |
| 78 return FormatType(base::SysUTF8ToNSString(serialization)); | 78 return FormatType(base::SysUTF8ToNSString(serialization)); |
| 79 } | 79 } |
| 80 | 80 |
| 81 Clipboard::Clipboard() { | 81 Clipboard::Clipboard() { |
| 82 DCHECK(CalledOnValidThread()); |
| 82 } | 83 } |
| 83 | 84 |
| 84 Clipboard::~Clipboard() { | 85 Clipboard::~Clipboard() { |
| 86 DCHECK(CalledOnValidThread()); |
| 85 } | 87 } |
| 86 | 88 |
| 87 void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) { | 89 void Clipboard::WriteObjects(Buffer buffer, const ObjectMap& objects) { |
| 90 DCHECK(CalledOnValidThread()); |
| 88 DCHECK_EQ(buffer, BUFFER_STANDARD); | 91 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 89 | 92 |
| 90 NSPasteboard* pb = GetPasteboard(); | 93 NSPasteboard* pb = GetPasteboard(); |
| 91 [pb declareTypes:[NSArray array] owner:nil]; | 94 [pb declareTypes:[NSArray array] owner:nil]; |
| 92 | 95 |
| 93 for (ObjectMap::const_iterator iter = objects.begin(); | 96 for (ObjectMap::const_iterator iter = objects.begin(); |
| 94 iter != objects.end(); ++iter) { | 97 iter != objects.end(); ++iter) { |
| 95 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); | 98 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); |
| 96 } | 99 } |
| 97 } | 100 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 // Write an extra flavor that signifies WebKit was the last to modify the | 207 // Write an extra flavor that signifies WebKit was the last to modify the |
| 205 // pasteboard. This flavor has no data. | 208 // pasteboard. This flavor has no data. |
| 206 void Clipboard::WriteWebSmartPaste() { | 209 void Clipboard::WriteWebSmartPaste() { |
| 207 NSPasteboard* pb = GetPasteboard(); | 210 NSPasteboard* pb = GetPasteboard(); |
| 208 NSString* format = GetWebKitSmartPasteFormatType().ToNSString(); | 211 NSString* format = GetWebKitSmartPasteFormatType().ToNSString(); |
| 209 [pb addTypes:[NSArray arrayWithObject:format] owner:nil]; | 212 [pb addTypes:[NSArray arrayWithObject:format] owner:nil]; |
| 210 [pb setData:nil forType:format]; | 213 [pb setData:nil forType:format]; |
| 211 } | 214 } |
| 212 | 215 |
| 213 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { | 216 uint64 Clipboard::GetSequenceNumber(Buffer buffer) { |
| 217 DCHECK(CalledOnValidThread()); |
| 214 DCHECK_EQ(buffer, BUFFER_STANDARD); | 218 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 215 | 219 |
| 216 NSPasteboard* pb = GetPasteboard(); | 220 NSPasteboard* pb = GetPasteboard(); |
| 217 return [pb changeCount]; | 221 return [pb changeCount]; |
| 218 } | 222 } |
| 219 | 223 |
| 220 bool Clipboard::IsFormatAvailable(const FormatType& format, | 224 bool Clipboard::IsFormatAvailable(const FormatType& format, |
| 221 Buffer buffer) const { | 225 Buffer buffer) const { |
| 226 DCHECK(CalledOnValidThread()); |
| 222 DCHECK_EQ(buffer, BUFFER_STANDARD); | 227 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 223 | 228 |
| 224 NSPasteboard* pb = GetPasteboard(); | 229 NSPasteboard* pb = GetPasteboard(); |
| 225 NSArray* types = [pb types]; | 230 NSArray* types = [pb types]; |
| 226 | 231 |
| 227 // Safari only places RTF on the pasteboard, never HTML. We can convert RTF | 232 // Safari only places RTF on the pasteboard, never HTML. We can convert RTF |
| 228 // to HTML, so the presence of either indicates success when looking for HTML. | 233 // to HTML, so the presence of either indicates success when looking for HTML. |
| 229 if ([format.ToNSString() isEqualToString:NSHTMLPboardType]) { | 234 if ([format.ToNSString() isEqualToString:NSHTMLPboardType]) { |
| 230 return [types containsObject:NSHTMLPboardType] || | 235 return [types containsObject:NSHTMLPboardType] || |
| 231 [types containsObject:NSRTFPboardType]; | 236 [types containsObject:NSRTFPboardType]; |
| 232 } | 237 } |
| 233 return [types containsObject:format.ToNSString()]; | 238 return [types containsObject:format.ToNSString()]; |
| 234 } | 239 } |
| 235 | 240 |
| 236 void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, | 241 void Clipboard::ReadAvailableTypes(Clipboard::Buffer buffer, |
| 237 std::vector<string16>* types, | 242 std::vector<string16>* types, |
| 238 bool* contains_filenames) const { | 243 bool* contains_filenames) const { |
| 244 DCHECK(CalledOnValidThread()); |
| 239 types->clear(); | 245 types->clear(); |
| 240 if (IsFormatAvailable(Clipboard::GetPlainTextFormatType(), buffer)) | 246 if (IsFormatAvailable(Clipboard::GetPlainTextFormatType(), buffer)) |
| 241 types->push_back(UTF8ToUTF16(kMimeTypeText)); | 247 types->push_back(UTF8ToUTF16(kMimeTypeText)); |
| 242 if (IsFormatAvailable(Clipboard::GetHtmlFormatType(), buffer)) | 248 if (IsFormatAvailable(Clipboard::GetHtmlFormatType(), buffer)) |
| 243 types->push_back(UTF8ToUTF16(kMimeTypeHTML)); | 249 types->push_back(UTF8ToUTF16(kMimeTypeHTML)); |
| 244 if ([NSImage canInitWithPasteboard:GetPasteboard()]) | 250 if ([NSImage canInitWithPasteboard:GetPasteboard()]) |
| 245 types->push_back(UTF8ToUTF16(kMimeTypePNG)); | 251 types->push_back(UTF8ToUTF16(kMimeTypePNG)); |
| 246 *contains_filenames = false; | 252 *contains_filenames = false; |
| 247 | 253 |
| 248 NSPasteboard* pb = GetPasteboard(); | 254 NSPasteboard* pb = GetPasteboard(); |
| 249 if ([[pb types] containsObject:kWebCustomDataPboardType]) { | 255 if ([[pb types] containsObject:kWebCustomDataPboardType]) { |
| 250 NSData* data = [pb dataForType:kWebCustomDataPboardType]; | 256 NSData* data = [pb dataForType:kWebCustomDataPboardType]; |
| 251 if ([data length]) | 257 if ([data length]) |
| 252 ReadCustomDataTypes([data bytes], [data length], types); | 258 ReadCustomDataTypes([data bytes], [data length], types); |
| 253 } | 259 } |
| 254 } | 260 } |
| 255 | 261 |
| 256 void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { | 262 void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { |
| 263 DCHECK(CalledOnValidThread()); |
| 257 DCHECK_EQ(buffer, BUFFER_STANDARD); | 264 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 258 NSPasteboard* pb = GetPasteboard(); | 265 NSPasteboard* pb = GetPasteboard(); |
| 259 NSString* contents = [pb stringForType:NSStringPboardType]; | 266 NSString* contents = [pb stringForType:NSStringPboardType]; |
| 260 | 267 |
| 261 UTF8ToUTF16([contents UTF8String], | 268 UTF8ToUTF16([contents UTF8String], |
| 262 [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], | 269 [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], |
| 263 result); | 270 result); |
| 264 } | 271 } |
| 265 | 272 |
| 266 void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, | 273 void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, |
| 267 std::string* result) const { | 274 std::string* result) const { |
| 275 DCHECK(CalledOnValidThread()); |
| 268 DCHECK_EQ(buffer, BUFFER_STANDARD); | 276 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 269 NSPasteboard* pb = GetPasteboard(); | 277 NSPasteboard* pb = GetPasteboard(); |
| 270 NSString* contents = [pb stringForType:NSStringPboardType]; | 278 NSString* contents = [pb stringForType:NSStringPboardType]; |
| 271 | 279 |
| 272 if (!contents) | 280 if (!contents) |
| 273 result->clear(); | 281 result->clear(); |
| 274 else | 282 else |
| 275 result->assign([contents UTF8String]); | 283 result->assign([contents UTF8String]); |
| 276 } | 284 } |
| 277 | 285 |
| 278 void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, | 286 void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, |
| 279 std::string* src_url, uint32* fragment_start, | 287 std::string* src_url, uint32* fragment_start, |
| 280 uint32* fragment_end) const { | 288 uint32* fragment_end) const { |
| 289 DCHECK(CalledOnValidThread()); |
| 281 DCHECK_EQ(buffer, BUFFER_STANDARD); | 290 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 282 | 291 |
| 283 // TODO(avi): src_url? | 292 // TODO(avi): src_url? |
| 284 markup->clear(); | 293 markup->clear(); |
| 285 if (src_url) | 294 if (src_url) |
| 286 src_url->clear(); | 295 src_url->clear(); |
| 287 | 296 |
| 288 NSPasteboard* pb = GetPasteboard(); | 297 NSPasteboard* pb = GetPasteboard(); |
| 289 NSArray* supportedTypes = [NSArray arrayWithObjects:NSHTMLPboardType, | 298 NSArray* supportedTypes = [NSArray arrayWithObjects:NSHTMLPboardType, |
| 290 NSRTFPboardType, | 299 NSRTFPboardType, |
| 291 NSStringPboardType, | 300 NSStringPboardType, |
| 292 nil]; | 301 nil]; |
| 293 NSString* bestType = [pb availableTypeFromArray:supportedTypes]; | 302 NSString* bestType = [pb availableTypeFromArray:supportedTypes]; |
| 294 if (bestType) { | 303 if (bestType) { |
| 295 NSString* contents = [pb stringForType:bestType]; | 304 NSString* contents = [pb stringForType:bestType]; |
| 296 if ([bestType isEqualToString:NSRTFPboardType]) | 305 if ([bestType isEqualToString:NSRTFPboardType]) |
| 297 contents = [pb htmlFromRtf]; | 306 contents = [pb htmlFromRtf]; |
| 298 UTF8ToUTF16([contents UTF8String], | 307 UTF8ToUTF16([contents UTF8String], |
| 299 [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], | 308 [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], |
| 300 markup); | 309 markup); |
| 301 } | 310 } |
| 302 | 311 |
| 303 *fragment_start = 0; | 312 *fragment_start = 0; |
| 304 DCHECK(markup->length() <= kuint32max); | 313 DCHECK(markup->length() <= kuint32max); |
| 305 *fragment_end = static_cast<uint32>(markup->length()); | 314 *fragment_end = static_cast<uint32>(markup->length()); |
| 306 } | 315 } |
| 307 | 316 |
| 308 SkBitmap Clipboard::ReadImage(Buffer buffer) const { | 317 SkBitmap Clipboard::ReadImage(Buffer buffer) const { |
| 318 DCHECK(CalledOnValidThread()); |
| 309 DCHECK_EQ(buffer, BUFFER_STANDARD); | 319 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 310 | 320 |
| 311 scoped_nsobject<NSImage> image( | 321 scoped_nsobject<NSImage> image( |
| 312 [[NSImage alloc] initWithPasteboard:GetPasteboard()]); | 322 [[NSImage alloc] initWithPasteboard:GetPasteboard()]); |
| 313 if (!image.get()) | 323 if (!image.get()) |
| 314 return SkBitmap(); | 324 return SkBitmap(); |
| 315 | 325 |
| 316 gfx::ScopedNSGraphicsContextSaveGState scoped_state; | 326 gfx::ScopedNSGraphicsContextSaveGState scoped_state; |
| 317 [image setFlipped:YES]; | 327 [image setFlipped:YES]; |
| 318 int width = [image size].width; | 328 int width = [image size].width; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 329 fromRect:NSZeroRect | 339 fromRect:NSZeroRect |
| 330 operation:NSCompositeCopy | 340 operation:NSCompositeCopy |
| 331 fraction:1.0]; | 341 fraction:1.0]; |
| 332 } | 342 } |
| 333 return canvas.ExtractBitmap(); | 343 return canvas.ExtractBitmap(); |
| 334 } | 344 } |
| 335 | 345 |
| 336 void Clipboard::ReadCustomData(Buffer buffer, | 346 void Clipboard::ReadCustomData(Buffer buffer, |
| 337 const string16& type, | 347 const string16& type, |
| 338 string16* result) const { | 348 string16* result) const { |
| 349 DCHECK(CalledOnValidThread()); |
| 339 DCHECK_EQ(buffer, BUFFER_STANDARD); | 350 DCHECK_EQ(buffer, BUFFER_STANDARD); |
| 340 | 351 |
| 341 NSPasteboard* pb = GetPasteboard(); | 352 NSPasteboard* pb = GetPasteboard(); |
| 342 if ([[pb types] containsObject:kWebCustomDataPboardType]) { | 353 if ([[pb types] containsObject:kWebCustomDataPboardType]) { |
| 343 NSData* data = [pb dataForType:kWebCustomDataPboardType]; | 354 NSData* data = [pb dataForType:kWebCustomDataPboardType]; |
| 344 if ([data length]) | 355 if ([data length]) |
| 345 ReadCustomDataForType([data bytes], [data length], type, result); | 356 ReadCustomDataForType([data bytes], [data length], type, result); |
| 346 } | 357 } |
| 347 } | 358 } |
| 348 | 359 |
| 349 void Clipboard::ReadBookmark(string16* title, std::string* url) const { | 360 void Clipboard::ReadBookmark(string16* title, std::string* url) const { |
| 361 DCHECK(CalledOnValidThread()); |
| 350 NSPasteboard* pb = GetPasteboard(); | 362 NSPasteboard* pb = GetPasteboard(); |
| 351 | 363 |
| 352 if (title) { | 364 if (title) { |
| 353 NSString* contents = [pb stringForType:kUTTypeURLName]; | 365 NSString* contents = [pb stringForType:kUTTypeURLName]; |
| 354 UTF8ToUTF16([contents UTF8String], | 366 UTF8ToUTF16([contents UTF8String], |
| 355 [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], | 367 [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], |
| 356 title); | 368 title); |
| 357 } | 369 } |
| 358 | 370 |
| 359 if (url) { | 371 if (url) { |
| 360 NSString* url_string = [[NSURL URLFromPasteboard:pb] absoluteString]; | 372 NSString* url_string = [[NSURL URLFromPasteboard:pb] absoluteString]; |
| 361 if (!url_string) | 373 if (!url_string) |
| 362 url->clear(); | 374 url->clear(); |
| 363 else | 375 else |
| 364 url->assign([url_string UTF8String]); | 376 url->assign([url_string UTF8String]); |
| 365 } | 377 } |
| 366 } | 378 } |
| 367 | 379 |
| 368 void Clipboard::ReadData(const FormatType& format, std::string* result) const { | 380 void Clipboard::ReadData(const FormatType& format, std::string* result) const { |
| 381 DCHECK(CalledOnValidThread()); |
| 369 NSPasteboard* pb = GetPasteboard(); | 382 NSPasteboard* pb = GetPasteboard(); |
| 370 NSData* data = [pb dataForType:format.ToNSString()]; | 383 NSData* data = [pb dataForType:format.ToNSString()]; |
| 371 if ([data length]) | 384 if ([data length]) |
| 372 result->assign(static_cast<const char*>([data bytes]), [data length]); | 385 result->assign(static_cast<const char*>([data bytes]), [data length]); |
| 373 } | 386 } |
| 374 | 387 |
| 375 // static | 388 // static |
| 376 Clipboard::FormatType Clipboard::GetFormatType( | 389 Clipboard::FormatType Clipboard::GetFormatType( |
| 377 const std::string& format_string) { | 390 const std::string& format_string) { |
| 378 return FormatType::Deserialize(format_string); | 391 return FormatType::Deserialize(format_string); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 return type; | 442 return type; |
| 430 } | 443 } |
| 431 | 444 |
| 432 // static | 445 // static |
| 433 const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() { | 446 const Clipboard::FormatType& Clipboard::GetWebCustomDataFormatType() { |
| 434 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kWebCustomDataPboardType)); | 447 CR_DEFINE_STATIC_LOCAL(FormatType, type, (kWebCustomDataPboardType)); |
| 435 return type; | 448 return type; |
| 436 } | 449 } |
| 437 | 450 |
| 438 } // namespace ui | 451 } // namespace ui |
| OLD | NEW |