Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

446 lines (357 sloc) 11.311 kb
/*
* CPPasteboard.j
* AppKit
*
* Created by Francisco Tolmasky.
* Copyright 2008, 280 North, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@import <Foundation/CPObject.j>
@import <Foundation/CPArray.j>
@import <Foundation/CPDictionary.j>
@import <Foundation/CPPropertyListSerialization.j>
CPGeneralPboard = @"CPGeneralPboard";
CPFontPboard = @"CPFontPboard";
CPRulerPboard = @"CPRulerPboard";
CPFindPboard = @"CPFindPboard";
CPDragPboard = @"CPDragPboard";
CPColorPboardType = @"CPColorPboardType";
CPFilenamesPboardType = @"CPFilenamesPboardType";
CPFontPboardType = @"CPFontPboardType";
CPHTMLPboardType = @"CPHTMLPboardType";
CPStringPboardType = @"CPStringPboardType";
CPURLPboardType = @"CPURLPboardType";
CPImagesPboardType = @"CPImagesPboardType";
CPVideosPboardType = @"CPVideosPboardType";
UTF8PboardType = @"public.utf8-plain-text";
// Deprecated
CPImagePboardType = @"CPImagePboardType";
var CPPasteboards = nil,
supportsNativePasteboard = NO;
/*!
@ingroup appkit
@class CPPasteboard
CPPasteBoard is the object responsible for cut/copy/paste and drag&drop operations.
*/
@implementation CPPasteboard : CPObject
{
CPArray _types;
CPDictionary _owners;
CPDictionary _provided;
unsigned _changeCount;
CPString _stateUID;
WebScriptObject _nativePasteboard;
}
/*
@ignore
*/
+ (void)initialize
{
if (self !== [CPPasteboard class])
return;
[self setVersion:1.0];
CPPasteboards = [CPDictionary dictionary];
if (typeof window.cpPasteboardWithName !== "undefined")
supportsNativePasteboard = YES;
}
/*!
Returns a new instance of a pasteboard
*/
+ (id)generalPasteboard
{
return [CPPasteboard pasteboardWithName:CPGeneralPboard];
}
/*!
Returns a pasteboard with the specified name. If the pasteboard doesn't exist, it will be created.
@param aName the name of the pasteboard
@return the requested pasteboard
*/
+ (id)pasteboardWithName:(CPString)aName
{
var pasteboard = [CPPasteboards objectForKey:aName];
if (pasteboard)
return pasteboard;
pasteboard = [[CPPasteboard alloc] _initWithName:aName];
[CPPasteboards setObject:pasteboard forKey:aName];
return pasteboard;
}
/* @ignore */
- (id)_initWithName:(CPString)aName
{
self = [super init];
if (self)
{
_name = aName;
_types = [];
_owners = [CPDictionary dictionary];
_provided = [CPDictionary dictionary];
_changeCount = 0;
if (supportsNativePasteboard)
{
_nativePasteboard = window.cpPasteboardWithName(aName);
[self _synchronizePasteboard];
}
}
return self;
}
/*!
Adds supported data types to the pasteboard
@param types the data types
@param anOwner the object that contains the data types
@return the pasteboard's change count
*/
- (unsigned)addTypes:(CPArray)types owner:(id)anOwner
{
var i = 0,
count = types.length;
for (; i < count; ++i)
{
var type = types[i];
if (![_owners objectForKey:type])
{
[_types addObject:type];
[_provided removeObjectForKey:type];
}
[_owners setObject:anOwner forKey:type];
}
if (_nativePasteboard)
{
var nativeTypes = [types copy];
if ([types containsObject:CPStringPboardType])
nativeTypes.push(UTF8PboardType);
_nativePasteboard.addTypes_(nativeTypes);
}
return ++_changeCount;
}
/*!
Sets the data types that this pasteboard will contain.
@param type the data types it will support
@param anOwner the object that contains the the data
@return the pasteboard's change count
*/
- (unsigned)declareTypes:(CPArray)types owner:(id)anOwner
{
[self _declareTypes:types owner:anOwner updateNativePasteboard:YES];
}
/*! @ignore */
- (unsigned)_declareTypes:(CPArray)types owner:(id)anOwner updateNativePasteboard:(BOOL)shouldUpdate
{
[_types setArray:types];
_owners = [CPDictionary dictionary];
_provided = [CPDictionary dictionary];
var count = _types.length;
while (count--)
[_owners setObject:anOwner forKey:_types[count]];
if (_nativePasteboard && shouldUpdate)
{
var nativeTypes = [types copy];
if ([types containsObject:CPStringPboardType])
nativeTypes.push(UTF8PboardType);
_nativePasteboard.declareTypes_(nativeTypes);
_changeCount = _nativePasteboard.changeCount();
}
return ++_changeCount;
}
/*!
Sets the pasteboard data for the specified type
@param aData the data
@param aType the data type being set
@return \c YES if the data was successfully written to the pasteboard
*/
- (BOOL)setData:(CPData)aData forType:(CPString)aType
{
[_provided setObject:aData forKey:aType];
if (aType === CPStringPboardType)
[self setData:aData forType:UTF8PboardType];
return YES;
}
/*!
Writes the specified property list as data for the specified type
@param aPropertyList the property list to write
@param aType the data type
@return \c YES if the property list was successfully written to the pasteboard
*/
- (BOOL)setPropertyList:(id)aPropertyList forType:(CPString)aType
{
return [self setData:[CPPropertyListSerialization dataFromPropertyList:aPropertyList format:CPPropertyList280NorthFormat_v1_0] forType:aType];
}
/*!
Sets the specified string as data for the specified type
@param aString the string to write
@param aType the data type
@return \c YES if the string was successfully written to the pasteboard
*/
- (void)setString:(CPString)aString forType:(CPString)aType
{
[self setPropertyList:aString forType:aType];
}
// Determining Types
/*!
Checks the pasteboard's types for a match with the types listen in the specified array. The array should
be ordered by the requestor's most preferred data type first.
@param anArray an array of requested types ordered by preference
@return the highest match with the pasteboard's supported types or \c nil if no match was found
*/
- (CPString)availableTypeFromArray:(CPArray)anArray
{
return [[self types] firstObjectCommonWithArray:anArray];
}
/*!
Returns the pasteboards supported types
*/
- (CPArray)types
{
[self _synchronizePasteboard];
return _types;
}
// Reading data
/*!
Returns the number of changes that have occurred to this pasteboard
*/
- (unsigned)changeCount
{
return _changeCount;
}
/*!
Returns the pasteboard data for the specified data type
@param aType the requested data type
@return the requested data or \c nil if the data doesn't exist
*/
- (CPData)dataForType:(CPString)aType
{
var data = [_provided objectForKey:aType];
if (data)
return data;
var owner = [_owners objectForKey:aType];
if (owner)
{
[owner pasteboard:self provideDataForType:aType];
return [_provided objectForKey:aType];
}
if (aType === CPStringPboardType)
return [self dataForType:UTF8PboardType];
return nil;
}
- (void)_synchronizePasteboard
{
if (_nativePasteboard && _nativePasteboard.changeCount() > _changeCount)
{
var nativeTypes = [_nativePasteboard.types() copy];
if ([nativeTypes containsObject:UTF8PboardType])
nativeTypes.push(CPStringPboardType);
[self _declareTypes:nativeTypes owner:self updateNativePasteboard:NO];
_changeCount = _nativePasteboard.changeCount();
}
}
/*! @ignore
method provided for integration with native pasteboard
*/
- (void)pasteboard:(CPPasteboard)aPasteboard provideDataForType:(CPString)aType
{
if (aType === CPStringPboardType)
{
var string = _nativePasteboard.stringForType_(UTF8PboardType);
[self setString:string forType:CPStringPboardType];
[self setString:string forType:UTF8PboardType];
}
else
[self setString:_nativePasteboard.stringForType_(aType) forType:aType];
}
/*!
Returns the property list for the specified data type
@param aType the requested data type
@return the property list or \c nil if the list was not found
*/
- (id)propertyListForType:(CPString)aType
{
var data = [self dataForType:aType];
if (data)
return [CPPropertyListSerialization propertyListFromData:data format:CPPropertyList280NorthFormat_v1_0];
return nil;
}
/*!
Returns the string for the specified data type
@param aType the requested data type
@return the string or \c nil if the string was not found
*/
- (CPString)stringForType:(CPString)aType
{
return [self propertyListForType:aType];
}
/* @ignore */
- (CPString)_generateStateUID
{
var bits = 32;
_stateUID = @"";
while (bits--)
_stateUID += FLOOR(RAND() * 16.0).toString(16).toUpperCase();
return _stateUID;
}
/* @ignore */
- (CPString)_stateUID
{
return _stateUID;
}
@end
#if PLATFORM(DOM)
var DOMDataTransferPasteboard = nil;
@implementation _CPDOMDataTransferPasteboard : CPPasteboard
{
DataTransfer _dataTransfer;
}
+ (_CPDOMDataTransferPasteboard)DOMDataTransferPasteboard
{
if (!DOMDataTransferPasteboard)
DOMDataTransferPasteboard = [[_CPDOMDataTransferPasteboard alloc] init];
return DOMDataTransferPasteboard;
}
- (void)_setDataTransfer:(DataTransfer)aDataTransfer
{
_dataTransfer = aDataTransfer;
}
- (void)_setPasteboard:(CPPasteboard)aPasteboard
{
_dataTransfer.clearData();
var types = [aPasteboard types],
count = types.length;
while (count--)
{
var type = types[count];
if (type === CPStringPboardType)
_dataTransfer.setData(type, [aPasteboard stringForType:type]);
else
_dataTransfer.setData(type, [[aPasteboard dataForType:type] rawString]);
}
}
- (CPArray)types
{
return Array.prototype.slice.apply(_dataTransfer.types);
}
- (CPData)dataForType:(CPString)aType
{
var dataString = _dataTransfer.getData(aType);
if (aType === CPStringPboardType)
return [CPData dataFromPropertyList:dataString format:kCFPropertyList280NorthFormat_v1_0];
return [CPData dataWithRawString:dataString];
}
- (id)propertyListForType:(CPString)aType
{
if (aType === CPStringPboardType)
return _dataTransfer.getData(aType);
return [CPPropertyListSerialization propertyListFromData:[self dataForType:aType] format:CPPropertyListUnknownFormat];
}
@end
#endif
Jump to Line
Something went wrong with that request. Please try again.