API  0.9.9
CPPasteboard.j
Go to the documentation of this file.
1 /*
2  * CPPasteboard.j
3  * AppKit
4  *
5  * Created by Francisco Tolmasky.
6  * Copyright 2008, 280 North, Inc.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 
24 
25 @typedef DataTransfer
26 
27 CPGeneralPboard = @"CPGeneralPboard";
28 CPFontPboard = @"CPFontPboard";
29 CPRulerPboard = @"CPRulerPboard";
30 CPFindPboard = @"CPFindPboard";
31 CPDragPboard = @"CPDragPboard";
32 
33 CPColorPboardType = @"CPColorPboardType";
34 CPFilenamesPboardType = @"CPFilenamesPboardType";
35 CPFontPboardType = @"CPFontPboardType";
36 CPHTMLPboardType = @"CPHTMLPboardType";
37 CPStringPboardType = @"CPStringPboardType";
38 CPURLPboardType = @"CPURLPboardType";
39 CPImagesPboardType = @"CPImagesPboardType";
40 CPVideosPboardType = @"CPVideosPboardType";
41 
42 UTF8PboardType = @"public.utf8-plain-text";
43 
44 // Deprecated
45 CPImagePboardType = @"CPImagePboardType";
46 
47 
48 var CPPasteboards = nil,
50 
56 @implementation CPPasteboard : CPObject
57 {
58  CPArray _types;
59  CPDictionary _owners;
60  CPDictionary _provided;
61 
62  unsigned _changeCount;
63  CPString _stateUID;
64 
65  CPWebScriptObject _nativePasteboard;
66 }
67 
68 /*
69  @ignore
70 */
71 + (void)initialize
72 {
73  if (self !== [CPPasteboard class])
74  return;
75 
76  [self setVersion:1.0];
77 
78  CPPasteboards = @{};
79 
80  if (typeof window.cpPasteboardWithName !== "undefined")
82 }
83 
88 {
89  return [CPPasteboard pasteboardWithName:CPGeneralPboard];
90 }
91 
97 + (id)pasteboardWithName:(CPString)aName
98 {
99  var pasteboard = [CPPasteboards objectForKey:aName];
100 
101  if (pasteboard)
102  return pasteboard;
103 
104  pasteboard = [[CPPasteboard alloc] _initWithName:aName];
105  [CPPasteboards setObject:pasteboard forKey:aName];
106 
107  return pasteboard;
108 }
109 
110 /* @ignore */
111 - (id)_initWithName:(CPString)aName
112 {
113  self = [super init];
114 
115  if (self)
116  {
117 // _name = aName;
118  _types = [];
119 
120  _owners = @{};
121  _provided = @{};
122 
123  _changeCount = 0;
124 
126  {
127  _nativePasteboard = window.cpPasteboardWithName(aName);
128  [self _synchronizePasteboard];
129  }
130  }
131 
132  return self;
133 }
134 
141 - (unsigned)addTypes:(CPArray)types owner:(id)anOwner
142 {
143  var i = 0,
144  count = types.length;
145 
146  for (; i < count; ++i)
147  {
148  var type = types[i];
149 
150  if (![_owners objectForKey:type])
151  {
152  [_types addObject:type];
153  [_provided removeObjectForKey:type];
154  }
155 
156  [_owners setObject:anOwner forKey:type];
157  }
158 
159  if (_nativePasteboard)
160  {
161  var nativeTypes = [types copy];
162  if ([types containsObject:CPStringPboardType])
163  nativeTypes.push(UTF8PboardType);
164 
165  _nativePasteboard.addTypes_(nativeTypes);
166  }
167 
168  return ++_changeCount;
169 }
170 
177 - (unsigned)declareTypes:(CPArray)types owner:(id)anOwner
178 {
179  [self _declareTypes:types owner:anOwner updateNativePasteboard:YES];
180 }
181 
183 - (unsigned)_declareTypes:(CPArray)types owner:(id)anOwner updateNativePasteboard:(BOOL)shouldUpdate
184 {
185  [_types setArray:types];
186 
187  _owners = @{};
188  _provided = @{};
189 
190  if (anOwner)
191  {
192  var count = _types.length;
193  while (count--)
194  [_owners setObject:anOwner forKey:_types[count]];
195  }
196 
197  if (_nativePasteboard && shouldUpdate)
198  {
199  var nativeTypes = [types copy];
200  if ([types containsObject:CPStringPboardType])
201  nativeTypes.push(UTF8PboardType);
202 
203  _nativePasteboard.declareTypes_(nativeTypes);
204  _changeCount = _nativePasteboard.changeCount();
205  }
206 
207  return ++_changeCount;
208 }
209 
216 - (BOOL)setData:(CPData)aData forType:(CPString)aType
217 {
218  [_provided setObject:aData forKey:aType];
219 
220  if (aType === CPStringPboardType)
221  [self setData:aData forType:UTF8PboardType];
222 
223  return YES;
224 }
225 
232 - (BOOL)setPropertyList:(id)aPropertyList forType:(CPString)aType
233 {
234  return [self setData:[CPPropertyListSerialization dataFromPropertyList:aPropertyList format:CPPropertyList280NorthFormat_v1_0] forType:aType];
235 }
236 
243 - (void)setString:(CPString)aString forType:(CPString)aType
244 {
245  // Putting a non-string on the string pasteboard can lead to strange crashes.
246  if (aString && aString.isa && ![aString isKindOfClass:CPString])
247  [CPException raise:CPInvalidArgumentException reason:"CPPasteboard setString:forType: must be called with a string."];
248 
249  [self setPropertyList:aString forType:aType];
250 }
251 
252 // Determining Types
259 - (CPString)availableTypeFromArray:(CPArray)anArray
260 {
261  return [anArray firstObjectCommonWithArray:[self types]];
262 }
263 
267 - (CPArray)types
268 {
269  [self _synchronizePasteboard];
270  return _types;
271 }
272 
273 // Reading data
277 - (unsigned)changeCount
278 {
279  return _changeCount;
280 }
281 
287 - (CPData)dataForType:(CPString)aType
288 {
289  var data = [_provided objectForKey:aType];
290 
291  if (data)
292  return data;
293 
294  var owner = [_owners objectForKey:aType];
295 
296  if (owner)
297  {
298  [owner pasteboard:self provideDataForType:aType];
299  return [_provided objectForKey:aType];
300  }
301 
302  if (aType === CPStringPboardType)
303  return [self dataForType:UTF8PboardType];
304 
305  return nil;
306 }
307 
308 - (void)_synchronizePasteboard
309 {
310  if (_nativePasteboard && _nativePasteboard.changeCount() > _changeCount)
311  {
312  var nativeTypes = [_nativePasteboard.types() copy];
313  if ([nativeTypes containsObject:UTF8PboardType])
314  nativeTypes.push(CPStringPboardType);
315 
316  [self _declareTypes:nativeTypes owner:self updateNativePasteboard:NO];
317 
318  _changeCount = _nativePasteboard.changeCount();
319  }
320 }
321 
325 - (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
326 {
327  if (aType === CPStringPboardType)
328  {
329  var string = _nativePasteboard.stringForType_(UTF8PboardType);
330 
331  [self setString:string forType:CPStringPboardType];
332  [self setString:string forType:UTF8PboardType];
333  }
334  else
335  [self setString:_nativePasteboard.stringForType_(aType) forType:aType];
336 }
337 
343 - (id)propertyListForType:(CPString)aType
344 {
345  var data = [self dataForType:aType];
346 
347  if (data)
348  return [CPPropertyListSerialization propertyListFromData:data format:CPPropertyList280NorthFormat_v1_0];
349 
350  return nil;
351 }
352 
358 - (CPString)stringForType:(CPString)aType
359 {
360  return [self propertyListForType:aType];
361 }
362 
363 /* @ignore */
364 - (CPString)_generateStateUID
365 {
366  var bits = 32;
367 
368  _stateUID = @"";
369 
370  while (bits--)
371  _stateUID += FLOOR(RAND() * 16.0).toString(16).toUpperCase();
372 
373  return _stateUID;
374 }
375 
376 /* @ignore */
377 - (CPString)_stateUID
378 {
379  return _stateUID;
380 }
381 
382 @end
383 
384 #if PLATFORM(DOM)
385 
386 var DOMDataTransferPasteboard = nil;
387 
388 @implementation _CPDOMDataTransferPasteboard : CPPasteboard
389 {
390  DataTransfer _dataTransfer;
391 }
392 
393 + (_CPDOMDataTransferPasteboard)DOMDataTransferPasteboard
394 {
395  if (!DOMDataTransferPasteboard)
396  DOMDataTransferPasteboard = [[_CPDOMDataTransferPasteboard alloc] init];
397 
398  return DOMDataTransferPasteboard;
399 }
400 
401 - (void)_setDataTransfer:(DataTransfer)aDataTransfer
402 {
403  _dataTransfer = aDataTransfer;
404 }
405 
406 - (void)_setPasteboard:(CPPasteboard)aPasteboard
407 {
408  _dataTransfer.clearData();
409 
410  var types = [aPasteboard types],
411  count = types.length;
412 
413  while (count--)
414  {
415  var type = types[count];
416 
417  if (type === CPStringPboardType)
418  _dataTransfer.setData(type, [aPasteboard stringForType:type]);
419  else
420  _dataTransfer.setData(type, [[aPasteboard dataForType:type] rawString]);
421  }
422 }
423 
424 - (CPArray)types
425 {
426  return Array.prototype.slice.apply(_dataTransfer.types);
427 }
428 
429 - (CPData)dataForType:(CPString)aType
430 {
431  var dataString = _dataTransfer.getData(aType);
432 
433  if (aType === CPStringPboardType)
434  return [CPData dataFromPropertyList:dataString format:kCFPropertyList280NorthFormat_v1_0];
435 
436  return [CPData dataWithRawString:dataString];
437 }
438 
439 - (id)propertyListForType:(CPString)aType
440 {
441  if (aType === CPStringPboardType)
442  return _dataTransfer.getData(aType);
443 
444  return [CPPropertyListSerialization propertyListFromData:[self dataForType:aType] format:CPPropertyListUnknownFormat];
445 }
446 
447 @end
448 
449 #endif
CPRulerPboard
Definition: CPPasteboard.j:29
UTF8PboardType
Definition: CPPasteboard.j:42
Used to implement exception handling (creating & raising).
Definition: CPException.h:2
CPImagePboardType
Definition: CPPasteboard.j:45
CPData dataFromPropertyList:format:(id aPlist, [format] CPPropertyListFormat aFormat)
CPStringPboardType
Definition: CPPasteboard.j:37
CPColorPboardType
Definition: CPPasteboard.j:33
id generalPasteboard()
Definition: CPPasteboard.j:87
var CPPasteboards
Definition: CPPasteboard.j:48
void setString:forType:(CPString aString, [forType] CPString aType)
Definition: CPPasteboard.j:243
BOOL setData:forType:(CPData aData, [forType] CPString aType)
Definition: CPPasteboard.j:216
A Cappuccino wrapper for any data type.
Definition: CPData.h:2
void raise:reason:(CPString aName, [reason] CPString aReason)
Definition: CPException.j:66
BOOL setPropertyList:forType:(id aPropertyList, [forType] CPString aType)
Definition: CPPasteboard.j:232
A mutable key-value pair collection.
Definition: CPDictionary.h:2
CPVideosPboardType
Definition: CPPasteboard.j:40
id propertyListFromData:format:(CPData data, [format] CPPropertyListFormat aFormat)
CPImagesPboardType
Definition: CPPasteboard.j:39
An immutable string (collection of characters).
Definition: CPString.h:2
void initialize()
Definition: CPPasteboard.j:71
CPArray types()
Definition: CPPasteboard.j:267
CPDragPboard
Definition: CPPasteboard.j:31
CPData dataWithRawString:(CPString aString)
Definition: CPData.j:45
CPFontPboard
Definition: CPPasteboard.j:28
id propertyListForType:(CPString aType)
Definition: CPPasteboard.j:343
CPURLPboardType
Definition: CPPasteboard.j:38
void setVersion:(int aVersion)
Definition: CPObject.j:500
CPFontPboardType
Definition: CPPasteboard.j:35
CPHTMLPboardType
Definition: CPPasteboard.j:36
DataTransfer CPGeneralPboard
Definition: CPPasteboard.j:27
id init()
Definition: CPObject.j:145
CPFilenamesPboardType
Definition: CPPasteboard.j:34
unsigned changeCount()
Definition: CPPasteboard.j:277
CPData dataForType:(CPString aType)
Definition: CPPasteboard.j:287
CPFindPboard
Definition: CPPasteboard.j:30
var supportsNativePasteboard
Definition: CPPasteboard.j:49
id pasteboardWithName:(CPString aName)
Definition: CPPasteboard.j:97
id alloc()
Definition: CPObject.j:130