API 0.9.5
AppKit/CPPasteboard.j
Go to the documentation of this file.
00001 /*
00002  * CPPasteboard.j
00003  * AppKit
00004  *
00005  * Created by Francisco Tolmasky.
00006  * Copyright 2008, 280 North, Inc.
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 
00024 
00025 CPGeneralPboard         = @"CPGeneralPboard";
00026 CPFontPboard            = @"CPFontPboard";
00027 CPRulerPboard           = @"CPRulerPboard";
00028 CPFindPboard            = @"CPFindPboard";
00029 CPDragPboard            = @"CPDragPboard";
00030 
00031 CPColorPboardType       = @"CPColorPboardType";
00032 CPFilenamesPboardType   = @"CPFilenamesPboardType";
00033 CPFontPboardType        = @"CPFontPboardType";
00034 CPHTMLPboardType        = @"CPHTMLPboardType";
00035 CPStringPboardType      = @"CPStringPboardType";
00036 CPURLPboardType         = @"CPURLPboardType";
00037 CPImagesPboardType      = @"CPImagesPboardType";
00038 CPVideosPboardType      = @"CPVideosPboardType";
00039 
00040 UTF8PboardType          = @"public.utf8-plain-text";
00041 
00042 // Deprecated
00043 CPImagePboardType       = @"CPImagePboardType";
00044 
00045 
00046 var CPPasteboards = nil,
00047     supportsNativePasteboard = NO;
00048 
00055 @implementation CPPasteboard : CPObject
00056 {
00057     CPArray         _types;
00058     CPDictionary    _owners;
00059     CPDictionary    _provided;
00060 
00061     unsigned        _changeCount;
00062     CPString        _stateUID;
00063 
00064     WebScriptObject _nativePasteboard;
00065 }
00066 
00067 /*
00068     @ignore
00069 */
00070 + (void)initialize
00071 {
00072     if (self != [CPPasteboard class])
00073         return;
00074 
00075     [self setVersion:1.0];
00076 
00077     CPPasteboards = [CPDictionary dictionary];
00078 
00079     if (typeof window.cpPasteboardWithName !== "undefined")
00080         supportsNativePasteboard = YES;
00081 }
00082 
00086 + (id)generalPasteboard
00087 {
00088     return [CPPasteboard pasteboardWithName:CPGeneralPboard];
00089 }
00090 
00096 + (id)pasteboardWithName:(CPString)aName
00097 {
00098     var pasteboard = [CPPasteboards objectForKey:aName];
00099 
00100     if (pasteboard)
00101         return pasteboard;
00102 
00103     pasteboard = [[CPPasteboard alloc] _initWithName:aName];
00104     [CPPasteboards setObject:pasteboard forKey:aName];
00105 
00106     return pasteboard;
00107 }
00108 
00109 /* @ignore */
00110 - (id)_initWithName:(CPString)aName
00111 {
00112     self = [super init];
00113 
00114     if (self)
00115     {
00116         _name = aName;
00117         _types = [];
00118 
00119         _owners = [CPDictionary dictionary];
00120         _provided = [CPDictionary dictionary];
00121 
00122         _changeCount = 0;
00123 
00124         if (supportsNativePasteboard)
00125         {
00126             _nativePasteboard = window.cpPasteboardWithName(aName);
00127             [self _synchronizePasteboard];
00128         }
00129     }
00130 
00131     return self;
00132 }
00133 
00140 - (unsigned)addTypes:(CPArray)types owner:(id)anOwner
00141 {
00142     var i = 0,
00143         count = types.length;
00144 
00145     for (; i < count; ++i)
00146     {
00147         var type = types[i];
00148 
00149         if (![_owners objectForKey:type])
00150         {
00151             [_types addObject:type];
00152             [_provided removeObjectForKey:type];
00153         }
00154 
00155         [_owners setObject:anOwner forKey:type];
00156     }
00157 
00158     if (_nativePasteboard)
00159     {
00160         var nativeTypes = [types copy];
00161         if ([types containsObject:CPStringPboardType])
00162             nativeTypes.push(UTF8PboardType);
00163 
00164         _nativePasteboard.addTypes_(nativeTypes);
00165     }
00166 
00167     return ++_changeCount;
00168 }
00169 
00176 - (unsigned)declareTypes:(CPArray)types owner:(id)anOwner
00177 {
00178     [self _declareTypes:types owner:anOwner updateNativePasteboard:YES];
00179 }
00180 
00182 - (unsigned)_declareTypes:(CPArray)types owner:(id)anOwner updateNativePasteboard:(BOOL)shouldUpdate
00183 {
00184     [_types setArray:types];
00185 
00186     _owners = [CPDictionary dictionary];
00187     _provided = [CPDictionary dictionary];
00188 
00189     var count = _types.length;
00190 
00191     while (count--)
00192         [_owners setObject:anOwner forKey:_types[count]];
00193 
00194     if (_nativePasteboard && shouldUpdate)
00195     {
00196         var nativeTypes = [types copy];
00197         if ([types containsObject:CPStringPboardType])
00198             nativeTypes.push(UTF8PboardType);
00199 
00200         _nativePasteboard.declareTypes_(nativeTypes);
00201         _changeCount = _nativePasteboard.changeCount();
00202     }
00203     return ++_changeCount;
00204 }
00205 
00212 - (BOOL)setData:(CPData)aData forType:(CPString)aType
00213 {
00214     [_provided setObject:aData forKey:aType];
00215 
00216     if (aType === CPStringPboardType)
00217         [self setData:aData forType:UTF8PboardType];
00218 
00219     return YES;
00220 }
00221 
00228 - (BOOL)setPropertyList:(id)aPropertyList forType:(CPString)aType
00229 {
00230     return [self setData:[CPPropertyListSerialization dataFromPropertyList:aPropertyList format:CPPropertyList280NorthFormat_v1_0] forType:aType];
00231 }
00232 
00239 - (void)setString:(CPString)aString forType:(CPString)aType
00240 {
00241     [self setPropertyList:aString forType:aType];
00242 }
00243 
00244 // Determining Types
00251 - (CPString)availableTypeFromArray:(CPArray)anArray
00252 {
00253     return [[self types] firstObjectCommonWithArray:anArray];
00254 }
00255 
00259 - (CPArray)types
00260 {
00261     [self _synchronizePasteboard];
00262     return _types;
00263 }
00264 
00265 // Reading data
00269 - (unsigned)changeCount
00270 {
00271     return _changeCount;
00272 }
00273 
00279 - (CPData)dataForType:(CPString)aType
00280 {
00281     var data = [_provided objectForKey:aType];
00282 
00283     if (data)
00284         return data;
00285 
00286     var owner = [_owners objectForKey:aType];
00287 
00288     if (owner)
00289     {
00290         [owner pasteboard:self provideDataForType:aType];
00291         return [_provided objectForKey:aType];
00292     }
00293 
00294     if (aType === CPStringPboardType)
00295         return [self dataForType:UTF8PboardType];
00296 
00297     return nil;
00298 }
00299 
00300 - (void)_synchronizePasteboard
00301 {
00302     if (_nativePasteboard && _nativePasteboard.changeCount() > _changeCount)
00303     {
00304         var nativeTypes = [_nativePasteboard.types() copy];
00305         if ([nativeTypes containsObject:UTF8PboardType])
00306             nativeTypes.push(CPStringPboardType);
00307 
00308         [self _declareTypes:nativeTypes owner:self updateNativePasteboard:NO];
00309 
00310         _changeCount = _nativePasteboard.changeCount();
00311     }
00312 }
00313 
00317 - (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
00318 {
00319     if (aType === CPStringPboardType)
00320     {
00321         var string = _nativePasteboard.stringForType_(UTF8PboardType);
00322 
00323         [self setString:string forType:CPStringPboardType];
00324         [self setString:string forType:UTF8PboardType];
00325     }
00326     else
00327         [self setString:_nativePasteboard.stringForType_(aType) forType:aType];
00328 }
00329 
00335 - (id)propertyListForType:(CPString)aType
00336 {
00337     var data = [self dataForType:aType];
00338 
00339     if (data)
00340         return [CPPropertyListSerialization propertyListFromData:data format:CPPropertyList280NorthFormat_v1_0];
00341 
00342     return nil;
00343 }
00344 
00350 - (CPString)stringForType:(CPString)aType
00351 {
00352     return [self propertyListForType:aType];
00353 }
00354 
00355 /* @ignore */
00356 - (CPString)_generateStateUID
00357 {
00358     var bits = 32;
00359 
00360     _stateUID = @"";
00361 
00362     while (bits--)
00363         _stateUID += FLOOR(RAND() * 16.0).toString(16).toUpperCase();
00364 
00365     return _stateUID;
00366 }
00367 
00368 /* @ignore */
00369 - (CPString)_stateUID
00370 {
00371     return _stateUID;
00372 }
00373 
00374 @end
00375 
00376 #if PLATFORM(DOM)
00377 
00378 var DOMDataTransferPasteboard = nil;
00379 
00380 @implementation _CPDOMDataTransferPasteboard : CPPasteboard
00381 {
00382     DataTransfer    _dataTransfer;
00383 }
00384 
00385 + (_CPDOMDataTransferPasteboard)DOMDataTransferPasteboard
00386 {
00387     if (!DOMDataTransferPasteboard)
00388         DOMDataTransferPasteboard = [[_CPDOMDataTransferPasteboard alloc] init];
00389 
00390     return DOMDataTransferPasteboard;
00391 }
00392 
00393 - (void)_setDataTransfer:(DataTransfer)aDataTransfer
00394 {
00395     _dataTransfer = aDataTransfer;
00396 }
00397 
00398 - (void)_setPasteboard:(CPPasteboard)aPasteboard
00399 {
00400     _dataTransfer.clearData();
00401 
00402     var types = [aPasteboard types],
00403         count = types.length;
00404 
00405     while (count--)
00406     {
00407         var type = types[count];
00408 
00409         if (type === CPStringPboardType)
00410             _dataTransfer.setData(type, [aPasteboard stringForType:type]);
00411         else
00412             _dataTransfer.setData(type, [[aPasteboard dataForType:type] rawString]);
00413     }
00414 }
00415 
00416 - (CPArray)types
00417 {
00418     return Array.prototype.slice.apply(_dataTransfer.types);
00419 }
00420 
00421 - (CPData)dataForType:(CPString)aType
00422 {
00423     var dataString = _dataTransfer.getData(aType);
00424 
00425     if (aType === CPStringPboardType)
00426         return [CPData dataFromPropertyList:dataString format:kCFPropertyList280NorthFormat_v1_0];
00427 
00428     return [CPData dataWithRawString:dataString];
00429 }
00430 
00431 - (id)propertyListForType:(CPString)aType
00432 {
00433     if (aType === CPStringPboardType)
00434         return _dataTransfer.getData(aType);
00435 
00436     return [CPPropertyListSerialization propertyListFromData:[self dataForType:aType] format:CPPropertyListUnknownFormat];
00437 }
00438 
00439 @end
00440 
00441 #endif
 All Classes Files Functions Variables Defines