OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/clipboard.h" | |
6 | |
7 #import <Cocoa/Cocoa.h> | |
8 | |
9 #include "base/file_path.h" | |
10 #include "base/logging.h" | |
11 #include "base/string_util.h" | |
12 #include "base/sys_string_conversions.h" | |
13 | |
14 namespace { | |
15 | |
16 // Would be nice if this were in UTCoreTypes.h, but it isn't | |
17 const NSString* kUTTypeURLName = @"public.url-name"; | |
18 | |
19 // Tells us if WebKit was the last to write to the pasteboard. There's no | |
20 // actual data associated with this type. | |
21 const NSString *kWebSmartPastePboardType = @"NeXT smart paste pasteboard type"; | |
22 | |
23 NSPasteboard* GetPasteboard() { | |
24 // The pasteboard should not be nil in a UI session, but this handy DCHECK | |
25 // can help track down problems if someone tries using clipboard code outside | |
26 // of a UI session. | |
27 NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; | |
28 DCHECK(pasteboard); | |
29 return pasteboard; | |
30 } | |
31 | |
32 } // namespace | |
33 | |
34 Clipboard::Clipboard() { | |
35 } | |
36 | |
37 Clipboard::~Clipboard() { | |
38 } | |
39 | |
40 void Clipboard::WriteObjects(const ObjectMap& objects) { | |
41 NSPasteboard* pb = GetPasteboard(); | |
42 [pb declareTypes:[NSArray array] owner:nil]; | |
43 | |
44 for (ObjectMap::const_iterator iter = objects.begin(); | |
45 iter != objects.end(); ++iter) { | |
46 DispatchObject(static_cast<ObjectType>(iter->first), iter->second); | |
47 } | |
48 | |
49 } | |
50 | |
51 void Clipboard::WriteText(const char* text_data, size_t text_len) { | |
52 std::string text_str(text_data, text_len); | |
53 NSString *text = base::SysUTF8ToNSString(text_str); | |
54 NSPasteboard* pb = GetPasteboard(); | |
55 [pb addTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil]; | |
56 [pb setString:text forType:NSStringPboardType]; | |
57 } | |
58 | |
59 void Clipboard::WriteHTML(const char* markup_data, | |
60 size_t markup_len, | |
61 const char* url_data, | |
62 size_t url_len) { | |
63 std::string html_fragment_str(markup_data, markup_len); | |
64 NSString *html_fragment = base::SysUTF8ToNSString(html_fragment_str); | |
65 | |
66 // TODO(avi): url_data? | |
67 NSPasteboard* pb = GetPasteboard(); | |
68 [pb addTypes:[NSArray arrayWithObject:NSHTMLPboardType] owner:nil]; | |
69 [pb setString:html_fragment forType:NSHTMLPboardType]; | |
70 } | |
71 | |
72 void Clipboard::WriteBookmark(const char* title_data, | |
73 size_t title_len, | |
74 const char* url_data, | |
75 size_t url_len) { | |
76 std::string title_str(title_data, title_len); | |
77 NSString *title = base::SysUTF8ToNSString(title_str); | |
78 std::string url_str(url_data, url_len); | |
79 NSString *url = base::SysUTF8ToNSString(url_str); | |
80 | |
81 // TODO(playmobil): In the Windows version of this function, an HTML | |
82 // representation of the bookmark is also added to the clipboard, to support | |
83 // drag and drop of web shortcuts. I don't think we need to do this on the | |
84 // Mac, but we should double check later on. | |
85 NSURL* nsurl = [NSURL URLWithString:url]; | |
86 | |
87 NSPasteboard* pb = GetPasteboard(); | |
88 // passing UTIs into the pasteboard methods is valid >= 10.5 | |
89 [pb addTypes:[NSArray arrayWithObjects:NSURLPboardType, | |
90 kUTTypeURLName, | |
91 nil] | |
92 owner:nil]; | |
93 [nsurl writeToPasteboard:pb]; | |
94 [pb setString:title forType:kUTTypeURLName]; | |
95 } | |
96 | |
97 void Clipboard::WriteFiles(const char* file_data, size_t file_len) { | |
98 NSMutableArray* fileList = [NSMutableArray arrayWithCapacity:1]; | |
99 | |
100 // Offset of current filename from start of file_data array. | |
101 size_t current_filename_offset = 0; | |
102 | |
103 // file_data is double null terminated (see table at top of clipboard.h). | |
104 // So this loop can ignore the second null terminator, thus file_len - 1. | |
105 // TODO(playmobil): If we need a loop like this on other platforms then split | |
106 // this out into a common function that outputs a std::vector<const char*>. | |
107 for (size_t i = 0; i < file_len - 1; ++i) { | |
108 if (file_data[i] == '\0') { | |
109 const char* filename = &file_data[current_filename_offset]; | |
110 [fileList addObject:[NSString stringWithUTF8String:filename]]; | |
111 | |
112 current_filename_offset = i + 1; | |
113 continue; | |
114 } | |
115 } | |
116 | |
117 NSPasteboard* pb = GetPasteboard(); | |
118 [pb addTypes:[NSArray arrayWithObject:NSFilenamesPboardType] owner:nil]; | |
119 [pb setPropertyList:fileList forType:NSFilenamesPboardType]; | |
120 } | |
121 | |
122 // Write an extra flavor that signifies WebKit was the last to modify the | |
123 // pasteboard. This flavor has no data. | |
124 void Clipboard::WriteWebSmartPaste() { | |
125 NSPasteboard* pb = GetPasteboard(); | |
126 NSString* format = base::SysUTF8ToNSString(GetWebKitSmartPasteFormatType()); | |
127 [pb addTypes:[NSArray arrayWithObject:format] owner:nil]; | |
128 [pb setData:nil forType:format]; | |
129 } | |
130 | |
131 bool Clipboard::IsFormatAvailable(const Clipboard::FormatType& format, | |
132 Clipboard::Buffer buffer) const { | |
133 DCHECK_EQ(buffer, BUFFER_STANDARD); | |
134 NSString* format_ns = base::SysUTF8ToNSString(format); | |
135 | |
136 NSPasteboard* pb = GetPasteboard(); | |
137 NSArray* types = [pb types]; | |
138 | |
139 return [types containsObject:format_ns]; | |
140 } | |
141 | |
142 void Clipboard::ReadText(Clipboard::Buffer buffer, string16* result) const { | |
143 DCHECK_EQ(buffer, BUFFER_STANDARD); | |
144 NSPasteboard* pb = GetPasteboard(); | |
145 NSString* contents = [pb stringForType:NSStringPboardType]; | |
146 | |
147 UTF8ToUTF16([contents UTF8String], | |
148 [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], | |
149 result); | |
150 } | |
151 | |
152 void Clipboard::ReadAsciiText(Clipboard::Buffer buffer, | |
153 std::string* result) const { | |
154 DCHECK_EQ(buffer, BUFFER_STANDARD); | |
155 NSPasteboard* pb = GetPasteboard(); | |
156 NSString* contents = [pb stringForType:NSStringPboardType]; | |
157 | |
158 if (!contents) | |
159 result->clear(); | |
160 else | |
161 result->assign([contents UTF8String]); | |
162 } | |
163 | |
164 void Clipboard::ReadHTML(Clipboard::Buffer buffer, string16* markup, | |
165 std::string* src_url) const { | |
166 DCHECK_EQ(buffer, BUFFER_STANDARD); | |
167 if (markup) { | |
168 NSPasteboard* pb = GetPasteboard(); | |
169 NSArray *supportedTypes = [NSArray arrayWithObjects:NSHTMLPboardType, | |
170 NSStringPboardType, | |
171 nil]; | |
172 NSString *bestType = [pb availableTypeFromArray:supportedTypes]; | |
173 NSString* contents = [pb stringForType:bestType]; | |
174 UTF8ToUTF16([contents UTF8String], | |
175 [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], | |
176 markup); | |
177 } | |
178 | |
179 // TODO(avi): src_url? | |
180 if (src_url) | |
181 src_url->clear(); | |
182 } | |
183 | |
184 void Clipboard::ReadBookmark(string16* title, std::string* url) const { | |
185 NSPasteboard* pb = GetPasteboard(); | |
186 | |
187 if (title) { | |
188 NSString* contents = [pb stringForType:kUTTypeURLName]; | |
189 UTF8ToUTF16([contents UTF8String], | |
190 [contents lengthOfBytesUsingEncoding:NSUTF8StringEncoding], | |
191 title); | |
192 } | |
193 | |
194 if (url) { | |
195 NSString* url_string = [[NSURL URLFromPasteboard:pb] absoluteString]; | |
196 if (!url_string) | |
197 url->clear(); | |
198 else | |
199 url->assign([url_string UTF8String]); | |
200 } | |
201 } | |
202 | |
203 void Clipboard::ReadFile(FilePath* file) const { | |
204 if (!file) { | |
205 NOTREACHED(); | |
206 return; | |
207 } | |
208 | |
209 *file = FilePath(); | |
210 std::vector<FilePath> files; | |
211 ReadFiles(&files); | |
212 | |
213 // Take the first file, if available. | |
214 if (!files.empty()) | |
215 *file = files[0]; | |
216 } | |
217 | |
218 void Clipboard::ReadFiles(std::vector<FilePath>* files) const { | |
219 if (!files) { | |
220 NOTREACHED(); | |
221 return; | |
222 } | |
223 | |
224 files->clear(); | |
225 | |
226 NSPasteboard* pb = GetPasteboard(); | |
227 NSArray* fileList = [pb propertyListForType:NSFilenamesPboardType]; | |
228 | |
229 for (unsigned int i = 0; i < [fileList count]; ++i) { | |
230 std::string file = [[fileList objectAtIndex:i] UTF8String]; | |
231 files->push_back(FilePath(file)); | |
232 } | |
233 } | |
234 | |
235 // static | |
236 Clipboard::FormatType Clipboard::GetUrlFormatType() { | |
237 static const std::string type = base::SysNSStringToUTF8(NSURLPboardType); | |
238 return type; | |
239 } | |
240 | |
241 // static | |
242 Clipboard::FormatType Clipboard::GetUrlWFormatType() { | |
243 static const std::string type = base::SysNSStringToUTF8(NSURLPboardType); | |
244 return type; | |
245 } | |
246 | |
247 // static | |
248 Clipboard::FormatType Clipboard::GetPlainTextFormatType() { | |
249 static const std::string type = base::SysNSStringToUTF8(NSStringPboardType); | |
250 return type; | |
251 } | |
252 | |
253 // static | |
254 Clipboard::FormatType Clipboard::GetPlainTextWFormatType() { | |
255 static const std::string type = base::SysNSStringToUTF8(NSStringPboardType); | |
256 return type; | |
257 } | |
258 | |
259 // static | |
260 Clipboard::FormatType Clipboard::GetFilenameFormatType() { | |
261 static const std::string type = | |
262 base::SysNSStringToUTF8(NSFilenamesPboardType); | |
263 return type; | |
264 } | |
265 | |
266 // static | |
267 Clipboard::FormatType Clipboard::GetFilenameWFormatType() { | |
268 static const std::string type = | |
269 base::SysNSStringToUTF8(NSFilenamesPboardType); | |
270 return type; | |
271 } | |
272 | |
273 // static | |
274 Clipboard::FormatType Clipboard::GetHtmlFormatType() { | |
275 static const std::string type = base::SysNSStringToUTF8(NSHTMLPboardType); | |
276 return type; | |
277 } | |
278 | |
279 // static | |
280 Clipboard::FormatType Clipboard::GetWebKitSmartPasteFormatType() { | |
281 static const std::string type = | |
282 base::SysNSStringToUTF8(kWebSmartPastePboardType); | |
283 return type; | |
284 } | |
OLD | NEW |