| 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_mac.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" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/mac/mac_util.h" | 12 #include "base/mac/mac_util.h" |
| 13 #include "base/mac/scoped_cftyperef.h" | 13 #include "base/mac/scoped_cftyperef.h" |
| 14 #import "base/mac/scoped_nsexception_enabler.h" | 14 #import "base/mac/scoped_nsexception_enabler.h" |
| 15 #include "base/mac/scoped_nsobject.h" | 15 #include "base/mac/scoped_nsobject.h" |
| (...skipping 27 matching lines...) Expand all 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 |
| 91 Clipboard::Clipboard() { | 92 // Miscellaneous Clipboard definitions. |
| 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 // static |
| 169 Clipboard* Clipboard::Create() { |
| 170 return new ClipboardMac; |
| 171 } |
| 172 |
| 173 // ClipboardMac implementation. |
| 174 ClipboardMac::ClipboardMac() { |
| 92 DCHECK(CalledOnValidThread()); | 175 DCHECK(CalledOnValidThread()); |
| 93 } | 176 } |
| 94 | 177 |
| 95 Clipboard::~Clipboard() { | 178 ClipboardMac::~ClipboardMac() { |
| 96 DCHECK(CalledOnValidThread()); | 179 DCHECK(CalledOnValidThread()); |
| 97 } | 180 } |
| 98 | 181 |
| 99 void Clipboard::WriteObjects(ClipboardType type, const ObjectMap& objects) { | 182 uint64 ClipboardMac::GetSequenceNumber(ClipboardType type) { |
| 100 DCHECK(CalledOnValidThread()); | 183 DCHECK(CalledOnValidThread()); |
| 101 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 184 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
| 102 | 185 |
| 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) { | |
| 197 DCHECK(CalledOnValidThread()); | |
| 198 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | |
| 199 | |
| 200 NSPasteboard* pb = GetPasteboard(); | 186 NSPasteboard* pb = GetPasteboard(); |
| 201 return [pb changeCount]; | 187 return [pb changeCount]; |
| 202 } | 188 } |
| 203 | 189 |
| 204 bool Clipboard::IsFormatAvailable(const FormatType& format, | 190 bool ClipboardMac::IsFormatAvailable(const FormatType& format, |
| 205 ClipboardType type) const { | 191 ClipboardType type) const { |
| 206 DCHECK(CalledOnValidThread()); | 192 DCHECK(CalledOnValidThread()); |
| 207 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 193 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
| 208 | 194 |
| 209 NSPasteboard* pb = GetPasteboard(); | 195 NSPasteboard* pb = GetPasteboard(); |
| 210 NSArray* types = [pb types]; | 196 NSArray* types = [pb types]; |
| 211 | 197 |
| 212 // Safari only places RTF on the pasteboard, never HTML. We can convert RTF | 198 // Safari only places RTF on the pasteboard, never HTML. We can convert RTF |
| 213 // to HTML, so the presence of either indicates success when looking for HTML. | 199 // to HTML, so the presence of either indicates success when looking for HTML. |
| 214 if ([format.ToNSString() isEqualToString:NSHTMLPboardType]) { | 200 if ([format.ToNSString() isEqualToString:NSHTMLPboardType]) { |
| 215 return [types containsObject:NSHTMLPboardType] || | 201 return [types containsObject:NSHTMLPboardType] || |
| 216 [types containsObject:NSRTFPboardType]; | 202 [types containsObject:NSRTFPboardType]; |
| 217 } | 203 } |
| 218 return [types containsObject:format.ToNSString()]; | 204 return [types containsObject:format.ToNSString()]; |
| 219 } | 205 } |
| 220 | 206 |
| 221 void Clipboard::Clear(ClipboardType type) { | 207 void ClipboardMac::Clear(ClipboardType type) { |
| 222 DCHECK(CalledOnValidThread()); | 208 DCHECK(CalledOnValidThread()); |
| 223 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 209 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
| 224 | 210 |
| 225 NSPasteboard* pb = GetPasteboard(); | 211 NSPasteboard* pb = GetPasteboard(); |
| 226 [pb declareTypes:[NSArray array] owner:nil]; | 212 [pb declareTypes:[NSArray array] owner:nil]; |
| 227 } | 213 } |
| 228 | 214 |
| 229 void Clipboard::ReadAvailableTypes(ClipboardType type, | 215 void ClipboardMac::ReadAvailableTypes(ClipboardType type, |
| 230 std::vector<base::string16>* types, | 216 std::vector<base::string16>* types, |
| 231 bool* contains_filenames) const { | 217 bool* contains_filenames) const { |
| 232 DCHECK(CalledOnValidThread()); | 218 DCHECK(CalledOnValidThread()); |
| 233 types->clear(); | 219 types->clear(); |
| 234 if (IsFormatAvailable(Clipboard::GetPlainTextFormatType(), type)) | 220 if (IsFormatAvailable(Clipboard::GetPlainTextFormatType(), type)) |
| 235 types->push_back(base::UTF8ToUTF16(kMimeTypeText)); | 221 types->push_back(base::UTF8ToUTF16(kMimeTypeText)); |
| 236 if (IsFormatAvailable(Clipboard::GetHtmlFormatType(), type)) | 222 if (IsFormatAvailable(Clipboard::GetHtmlFormatType(), type)) |
| 237 types->push_back(base::UTF8ToUTF16(kMimeTypeHTML)); | 223 types->push_back(base::UTF8ToUTF16(kMimeTypeHTML)); |
| 238 if (IsFormatAvailable(Clipboard::GetRtfFormatType(), type)) | 224 if (IsFormatAvailable(Clipboard::GetRtfFormatType(), type)) |
| 239 types->push_back(base::UTF8ToUTF16(kMimeTypeRTF)); | 225 types->push_back(base::UTF8ToUTF16(kMimeTypeRTF)); |
| 240 if ([NSImage canInitWithPasteboard:GetPasteboard()]) | 226 if ([NSImage canInitWithPasteboard:GetPasteboard()]) |
| 241 types->push_back(base::UTF8ToUTF16(kMimeTypePNG)); | 227 types->push_back(base::UTF8ToUTF16(kMimeTypePNG)); |
| 242 *contains_filenames = false; | 228 *contains_filenames = false; |
| 243 | 229 |
| 244 NSPasteboard* pb = GetPasteboard(); | 230 NSPasteboard* pb = GetPasteboard(); |
| 245 if ([[pb types] containsObject:kWebCustomDataPboardType]) { | 231 if ([[pb types] containsObject:kWebCustomDataPboardType]) { |
| 246 NSData* data = [pb dataForType:kWebCustomDataPboardType]; | 232 NSData* data = [pb dataForType:kWebCustomDataPboardType]; |
| 247 if ([data length]) | 233 if ([data length]) |
| 248 ReadCustomDataTypes([data bytes], [data length], types); | 234 ReadCustomDataTypes([data bytes], [data length], types); |
| 249 } | 235 } |
| 250 } | 236 } |
| 251 | 237 |
| 252 void Clipboard::ReadText(ClipboardType type, base::string16* result) const { | 238 void ClipboardMac::ReadText(ClipboardType type, base::string16* result) const { |
| 253 DCHECK(CalledOnValidThread()); | 239 DCHECK(CalledOnValidThread()); |
| 254 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 240 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
| 255 NSPasteboard* pb = GetPasteboard(); | 241 NSPasteboard* pb = GetPasteboard(); |
| 256 NSString* contents = [pb stringForType:NSStringPboardType]; | 242 NSString* contents = [pb stringForType:NSStringPboardType]; |
| 257 | 243 |
| 258 *result = base::SysNSStringToUTF16(contents); | 244 *result = base::SysNSStringToUTF16(contents); |
| 259 } | 245 } |
| 260 | 246 |
| 261 void Clipboard::ReadAsciiText(ClipboardType type, std::string* result) const { | 247 void ClipboardMac::ReadAsciiText(ClipboardType type, |
| 248 std::string* result) const { |
| 262 DCHECK(CalledOnValidThread()); | 249 DCHECK(CalledOnValidThread()); |
| 263 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 250 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
| 264 NSPasteboard* pb = GetPasteboard(); | 251 NSPasteboard* pb = GetPasteboard(); |
| 265 NSString* contents = [pb stringForType:NSStringPboardType]; | 252 NSString* contents = [pb stringForType:NSStringPboardType]; |
| 266 | 253 |
| 267 if (!contents) | 254 if (!contents) |
| 268 result->clear(); | 255 result->clear(); |
| 269 else | 256 else |
| 270 result->assign([contents UTF8String]); | 257 result->assign([contents UTF8String]); |
| 271 } | 258 } |
| 272 | 259 |
| 273 void Clipboard::ReadHTML(ClipboardType type, | 260 void ClipboardMac::ReadHTML(ClipboardType type, |
| 274 base::string16* markup, | 261 base::string16* markup, |
| 275 std::string* src_url, | 262 std::string* src_url, |
| 276 uint32* fragment_start, | 263 uint32* fragment_start, |
| 277 uint32* fragment_end) const { | 264 uint32* fragment_end) const { |
| 278 DCHECK(CalledOnValidThread()); | 265 DCHECK(CalledOnValidThread()); |
| 279 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 266 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
| 280 | 267 |
| 281 // TODO(avi): src_url? | 268 // TODO(avi): src_url? |
| 282 markup->clear(); | 269 markup->clear(); |
| 283 if (src_url) | 270 if (src_url) |
| 284 src_url->clear(); | 271 src_url->clear(); |
| 285 | 272 |
| 286 NSPasteboard* pb = GetPasteboard(); | 273 NSPasteboard* pb = GetPasteboard(); |
| 287 NSArray* supportedTypes = [NSArray arrayWithObjects:NSHTMLPboardType, | 274 NSArray* supportedTypes = [NSArray arrayWithObjects:NSHTMLPboardType, |
| 288 NSRTFPboardType, | 275 NSRTFPboardType, |
| 289 NSStringPboardType, | 276 NSStringPboardType, |
| 290 nil]; | 277 nil]; |
| 291 NSString* bestType = [pb availableTypeFromArray:supportedTypes]; | 278 NSString* bestType = [pb availableTypeFromArray:supportedTypes]; |
| 292 if (bestType) { | 279 if (bestType) { |
| 293 NSString* contents = [pb stringForType:bestType]; | 280 NSString* contents = [pb stringForType:bestType]; |
| 294 if ([bestType isEqualToString:NSRTFPboardType]) | 281 if ([bestType isEqualToString:NSRTFPboardType]) |
| 295 contents = [pb htmlFromRtf]; | 282 contents = [pb htmlFromRtf]; |
| 296 *markup = base::SysNSStringToUTF16(contents); | 283 *markup = base::SysNSStringToUTF16(contents); |
| 297 } | 284 } |
| 298 | 285 |
| 299 *fragment_start = 0; | 286 *fragment_start = 0; |
| 300 DCHECK(markup->length() <= kuint32max); | 287 DCHECK(markup->length() <= kuint32max); |
| 301 *fragment_end = static_cast<uint32>(markup->length()); | 288 *fragment_end = static_cast<uint32>(markup->length()); |
| 302 } | 289 } |
| 303 | 290 |
| 304 void Clipboard::ReadRTF(ClipboardType type, std::string* result) const { | 291 void ClipboardMac::ReadRTF(ClipboardType type, std::string* result) const { |
| 305 DCHECK(CalledOnValidThread()); | 292 DCHECK(CalledOnValidThread()); |
| 306 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 293 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
| 307 | 294 |
| 308 return ReadData(GetRtfFormatType(), result); | 295 return ReadData(GetRtfFormatType(), result); |
| 309 } | 296 } |
| 310 | 297 |
| 311 SkBitmap Clipboard::ReadImage(ClipboardType type) const { | 298 SkBitmap ClipboardMac::ReadImage(ClipboardType type) const { |
| 312 DCHECK(CalledOnValidThread()); | 299 DCHECK(CalledOnValidThread()); |
| 313 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); | 300 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
| 314 | 301 |
| 315 // If the pasteboard's image data is not to its liking, the guts of NSImage | 302 // If the pasteboard's image data is not to its liking, the guts of NSImage |
| 316 // may throw, and that exception will leak. Prevent a crash in that case; | 303 // may throw, and that exception will leak. Prevent a crash in that case; |
| 317 // a blank image is better. | 304 // a blank image is better. |
| 318 base::scoped_nsobject<NSImage> image(base::mac::RunBlockIgnoringExceptions(^{ | 305 base::scoped_nsobject<NSImage> image(base::mac::RunBlockIgnoringExceptions(^{ |
| 319 return [[NSImage alloc] initWithPasteboard:GetPasteboard()]; | 306 return [[NSImage alloc] initWithPasteboard:GetPasteboard()]; |
| 320 })); | 307 })); |
| 321 SkBitmap bitmap; | 308 SkBitmap bitmap; |
| 322 if (image.get()) { | 309 if (image.get()) { |
| 323 bitmap = gfx::NSImageToSkBitmapWithColorSpace( | 310 bitmap = gfx::NSImageToSkBitmapWithColorSpace( |
| 324 image.get(), /*is_opaque=*/ false, base::mac::GetSystemColorSpace()); | 311 image.get(), /*is_opaque=*/ false, base::mac::GetSystemColorSpace()); |
| 325 } | 312 } |
| 326 return bitmap; | 313 return bitmap; |
| 327 } | 314 } |
| 328 | 315 |
| 329 void Clipboard::ReadCustomData(ClipboardType clipboard_type, | 316 void ClipboardMac::ReadCustomData(ClipboardType clipboard_type, |
| 330 const base::string16& type, | 317 const base::string16& type, |
| 331 base::string16* result) const { | 318 base::string16* result) const { |
| 332 DCHECK(CalledOnValidThread()); | 319 DCHECK(CalledOnValidThread()); |
| 333 DCHECK_EQ(clipboard_type, CLIPBOARD_TYPE_COPY_PASTE); | 320 DCHECK_EQ(clipboard_type, CLIPBOARD_TYPE_COPY_PASTE); |
| 334 | 321 |
| 335 NSPasteboard* pb = GetPasteboard(); | 322 NSPasteboard* pb = GetPasteboard(); |
| 336 if ([[pb types] containsObject:kWebCustomDataPboardType]) { | 323 if ([[pb types] containsObject:kWebCustomDataPboardType]) { |
| 337 NSData* data = [pb dataForType:kWebCustomDataPboardType]; | 324 NSData* data = [pb dataForType:kWebCustomDataPboardType]; |
| 338 if ([data length]) | 325 if ([data length]) |
| 339 ReadCustomDataForType([data bytes], [data length], type, result); | 326 ReadCustomDataForType([data bytes], [data length], type, result); |
| 340 } | 327 } |
| 341 } | 328 } |
| 342 | 329 |
| 343 void Clipboard::ReadBookmark(base::string16* title, std::string* url) const { | 330 void ClipboardMac::ReadBookmark(base::string16* title, std::string* url) const { |
| 344 DCHECK(CalledOnValidThread()); | 331 DCHECK(CalledOnValidThread()); |
| 345 NSPasteboard* pb = GetPasteboard(); | 332 NSPasteboard* pb = GetPasteboard(); |
| 346 | 333 |
| 347 if (title) { | 334 if (title) { |
| 348 NSString* contents = [pb stringForType:kUTTypeURLName]; | 335 NSString* contents = [pb stringForType:kUTTypeURLName]; |
| 349 *title = base::SysNSStringToUTF16(contents); | 336 *title = base::SysNSStringToUTF16(contents); |
| 350 } | 337 } |
| 351 | 338 |
| 352 if (url) { | 339 if (url) { |
| 353 NSString* url_string = [[NSURL URLFromPasteboard:pb] absoluteString]; | 340 NSString* url_string = [[NSURL URLFromPasteboard:pb] absoluteString]; |
| 354 if (!url_string) | 341 if (!url_string) |
| 355 url->clear(); | 342 url->clear(); |
| 356 else | 343 else |
| 357 url->assign([url_string UTF8String]); | 344 url->assign([url_string UTF8String]); |
| 358 } | 345 } |
| 359 } | 346 } |
| 360 | 347 |
| 361 void Clipboard::ReadData(const FormatType& format, std::string* result) const { | 348 void ClipboardMac::ReadData(const FormatType& format, |
| 349 std::string* result) const { |
| 362 DCHECK(CalledOnValidThread()); | 350 DCHECK(CalledOnValidThread()); |
| 363 NSPasteboard* pb = GetPasteboard(); | 351 NSPasteboard* pb = GetPasteboard(); |
| 364 NSData* data = [pb dataForType:format.ToNSString()]; | 352 NSData* data = [pb dataForType:format.ToNSString()]; |
| 365 if ([data length]) | 353 if ([data length]) |
| 366 result->assign(static_cast<const char*>([data bytes]), [data length]); | 354 result->assign(static_cast<const char*>([data bytes]), [data length]); |
| 367 } | 355 } |
| 368 | 356 |
| 369 // static | 357 void ClipboardMac::WriteObjects(ClipboardType type, const ObjectMap& objects) { |
| 370 Clipboard::FormatType Clipboard::GetFormatType( | 358 DCHECK(CalledOnValidThread()); |
| 371 const std::string& format_string) { | 359 DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); |
| 372 return FormatType::Deserialize(format_string); | 360 |
| 361 NSPasteboard* pb = GetPasteboard(); |
| 362 [pb declareTypes:[NSArray array] owner:nil]; |
| 363 |
| 364 for (ObjectMap::const_iterator iter = objects.begin(); iter != objects.end(); |
| 365 ++iter) { |
| 366 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); |
| 367 } |
| 373 } | 368 } |
| 374 | 369 |
| 375 // static | 370 void ClipboardMac::WriteText(const char* text_data, size_t text_len) { |
| 376 const Clipboard::FormatType& Clipboard::GetUrlFormatType() { | 371 std::string text_str(text_data, text_len); |
| 377 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSURLPboardType)); | 372 NSString* text = base::SysUTF8ToNSString(text_str); |
| 378 return type; | 373 NSPasteboard* pb = GetPasteboard(); |
| 374 [pb addTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; |
| 375 [pb setString:text forType:NSStringPboardType]; |
| 379 } | 376 } |
| 380 | 377 |
| 381 // static | 378 void ClipboardMac::WriteHTML(const char* markup_data, |
| 382 const Clipboard::FormatType& Clipboard::GetUrlWFormatType() { | 379 size_t markup_len, |
| 383 return GetUrlFormatType(); | 380 const char* url_data, |
| 381 size_t url_len) { |
| 382 // We need to mark it as utf-8. (see crbug.com/11957) |
| 383 std::string html_fragment_str("<meta charset='utf-8'>"); |
| 384 html_fragment_str.append(markup_data, markup_len); |
| 385 NSString* html_fragment = base::SysUTF8ToNSString(html_fragment_str); |
| 386 |
| 387 // TODO(avi): url_data? |
| 388 NSPasteboard* pb = GetPasteboard(); |
| 389 [pb addTypes:[NSArray arrayWithObject:NSHTMLPboardType] owner:nil]; |
| 390 [pb setString:html_fragment forType:NSHTMLPboardType]; |
| 384 } | 391 } |
| 385 | 392 |
| 386 // static | 393 void ClipboardMac::WriteRTF(const char* rtf_data, size_t data_len) { |
| 387 const Clipboard::FormatType& Clipboard::GetPlainTextFormatType() { | 394 WriteData(GetRtfFormatType(), rtf_data, data_len); |
| 388 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSStringPboardType)); | |
| 389 return type; | |
| 390 } | 395 } |
| 391 | 396 |
| 392 // static | 397 void ClipboardMac::WriteBookmark(const char* title_data, |
| 393 const Clipboard::FormatType& Clipboard::GetPlainTextWFormatType() { | 398 size_t title_len, |
| 394 return GetPlainTextFormatType(); | 399 const char* url_data, |
| 400 size_t url_len) { |
| 401 std::string title_str(title_data, title_len); |
| 402 NSString* title = base::SysUTF8ToNSString(title_str); |
| 403 std::string url_str(url_data, url_len); |
| 404 NSString* url = base::SysUTF8ToNSString(url_str); |
| 405 |
| 406 // TODO(playmobil): In the Windows version of this function, an HTML |
| 407 // representation of the bookmark is also added to the clipboard, to support |
| 408 // drag and drop of web shortcuts. I don't think we need to do this on the |
| 409 // Mac, but we should double check later on. |
| 410 NSURL* nsurl = [NSURL URLWithString:url]; |
| 411 |
| 412 NSPasteboard* pb = GetPasteboard(); |
| 413 // passing UTIs into the pasteboard methods is valid >= 10.5 |
| 414 [pb addTypes:[NSArray arrayWithObjects:NSURLPboardType, kUTTypeURLName, nil] |
| 415 owner:nil]; |
| 416 [nsurl writeToPasteboard:pb]; |
| 417 [pb setString:title forType:kUTTypeURLName]; |
| 395 } | 418 } |
| 396 | 419 |
| 397 // static | 420 void ClipboardMac::WriteBitmap(const SkBitmap& bitmap) { |
| 398 const Clipboard::FormatType& Clipboard::GetFilenameFormatType() { | 421 NSImage* image = gfx::SkBitmapToNSImageWithColorSpace( |
| 399 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSFilenamesPboardType)); | 422 bitmap, base::mac::GetSystemColorSpace()); |
| 400 return type; | 423 // An API to ask the NSImage to write itself to the clipboard comes in 10.6 :( |
| 424 // For now, spit out the image as a TIFF. |
| 425 NSPasteboard* pb = GetPasteboard(); |
| 426 [pb addTypes:[NSArray arrayWithObject:NSTIFFPboardType] owner:nil]; |
| 427 NSData* tiff_data = [image TIFFRepresentation]; |
| 428 LOG_IF(ERROR, tiff_data == NULL) << "Failed to allocate image for clipboard"; |
| 429 if (tiff_data) { |
| 430 [pb setData:tiff_data forType:NSTIFFPboardType]; |
| 431 } |
| 401 } | 432 } |
| 402 | 433 |
| 403 // static | 434 void ClipboardMac::WriteData(const FormatType& format, |
| 404 const Clipboard::FormatType& Clipboard::GetFilenameWFormatType() { | 435 const char* data_data, |
| 405 return GetFilenameFormatType(); | 436 size_t data_len) { |
| 437 NSPasteboard* pb = GetPasteboard(); |
| 438 [pb addTypes:[NSArray arrayWithObject:format.ToNSString()] owner:nil]; |
| 439 [pb setData:[NSData dataWithBytes:data_data length:data_len] |
| 440 forType:format.ToNSString()]; |
| 406 } | 441 } |
| 407 | 442 |
| 408 // static | 443 // Write an extra flavor that signifies WebKit was the last to modify the |
| 409 const Clipboard::FormatType& Clipboard::GetHtmlFormatType() { | 444 // pasteboard. This flavor has no data. |
| 410 CR_DEFINE_STATIC_LOCAL(FormatType, type, (NSHTMLPboardType)); | 445 void ClipboardMac::WriteWebSmartPaste() { |
| 411 return type; | 446 NSPasteboard* pb = GetPasteboard(); |
| 412 } | 447 NSString* format = GetWebKitSmartPasteFormatType().ToNSString(); |
| 413 | 448 [pb addTypes:[NSArray arrayWithObject:format] owner:nil]; |
| 414 // static | 449 [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 } | 450 } |
| 443 | 451 |
| 444 } // namespace ui | 452 } // namespace ui |
| OLD | NEW |