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 |