Some pasteboard fixes and lots of documentation.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@17045 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2003-06-27 11:13:30 +00:00
parent 58bbd40023
commit 11fd5099ac
4 changed files with 247 additions and 40 deletions

View file

@ -1,3 +1,8 @@
2003-06-27 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSPasteboard.m: Documented all methods, fixed minor bugs
writign fiels to pastebaords, implemented ([+typesFilterableTo:])
2003-06-26 Ludovic Marcotte <ludovic@Sophos.ca> 2003-06-26 Ludovic Marcotte <ludovic@Sophos.ca>
* Fixed the transparency of Images/common_ret.tiff * Fixed the transparency of Images/common_ret.tiff

View file

@ -66,6 +66,7 @@
- (BOOL) application: (NSApplication*)theApp - (BOOL) application: (NSApplication*)theApp
printFile: (NSString*)file; printFile: (NSString*)file;
- (void) doService: (NSMenuItem*)item; - (void) doService: (NSMenuItem*)item;
- (NSDictionary*) filters;
- (BOOL) hasRegisteredTypes: (NSDictionary*)service; - (BOOL) hasRegisteredTypes: (NSDictionary*)service;
- (NSString*) item2title: (NSMenuItem*)item; - (NSString*) item2title: (NSMenuItem*)item;
- (void) loadServices; - (void) loadServices;

View file

@ -545,6 +545,14 @@ static NSString *disabledName = @".GNUstepDisabled";
} }
} }
/**
* Return a dictionary of information about registered filter services.
*/
- (NSDictionary*) filters
{
return [_allServices objectForKey: @"ByFilter"];
}
- (BOOL) hasRegisteredTypes: (NSDictionary*)service - (BOOL) hasRegisteredTypes: (NSDictionary*)service
{ {
NSArray *sendTypes = [service objectForKey: @"NSSendTypes"]; NSArray *sendTypes = [service objectForKey: @"NSSendTypes"];
@ -1438,7 +1446,10 @@ NSShowsServicesMenuItem(NSString *name)
/** /**
* A services providing application may use this to update the list of * A services providing application may use this to update the list of
* services it provides. * services it provides.<br />
* In order to update the services advertised, the application must
* create a <em>.service</em> bundle and place it in
* <code>~/Library/Services</code> before invoking this function.
*/ */
void void
NSUpdateDynamicServices(void) NSUpdateDynamicServices(void)

View file

@ -3,7 +3,7 @@
<abstract>Implementation of class for communicating with the <abstract>Implementation of class for communicating with the
pasteboard server.</abstract> pasteboard server.</abstract>
Copyright (C) 1997,1999 Free Software Foundation, Inc. Copyright (C) 1997,1999,2003 Free Software Foundation, Inc.
Author: Richard Frith-Macdonald <richard@brainstorm.co.uk> Author: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Date: 1997 Date: 1997
@ -48,9 +48,11 @@
#include <Foundation/NSUserDefaults.h> #include <Foundation/NSUserDefaults.h>
#include <Foundation/NSMethodSignature.h> #include <Foundation/NSMethodSignature.h>
#include <Foundation/NSRunLoop.h> #include <Foundation/NSRunLoop.h>
#include <Foundation/NSSet.h>
#include <Foundation/NSTask.h> #include <Foundation/NSTask.h>
#include <Foundation/NSTimer.h> #include <Foundation/NSTimer.h>
#include "gnustep/gui/GSServicesManager.h"
#include "gnustep/gui/GSPasteboardServer.h" #include "gnustep/gui/GSPasteboardServer.h"
@interface NSPasteboard (Private) @interface NSPasteboard (Private)
@ -276,11 +278,28 @@ static NSMapTable *mimeMap = NULL;
return p; return p;
} }
/**
* Returns the general pasteboard found by calling +pasteboardWithName:
* with NSGeneralPboard as the name.
*/
+ (NSPasteboard*) generalPasteboard + (NSPasteboard*) generalPasteboard
{ {
return [self pasteboardWithName: NSGeneralPboard]; return [self pasteboardWithName: NSGeneralPboard];
} }
/**
* <p>Returns the pastebaord for the specified name. Creates a new pasreboard
* if (and only if) one with the given name does not exist.
* </p>
* Standard pastebaord names are -
* <list>
* <item>NSGeneralPboard</item>
* <item>NSFontPboard</item>
* <item>NSRulerPboard</item>
* <item>NSFindPboard</item>
* <item>NSDragPboard</item>
* </list>
*/
+ (NSPasteboard*) pasteboardWithName: (NSString*)aName + (NSPasteboard*) pasteboardWithName: (NSString*)aName
{ {
NS_DURING NS_DURING
@ -306,6 +325,10 @@ static NSMapTable *mimeMap = NULL;
return nil; return nil;
} }
/**
* Creates and returns a new pasteboard with a name guaranteed to be unique
* within the pasteboard server.
*/
+ (NSPasteboard*) pasteboardWithUniqueName + (NSPasteboard*) pasteboardWithUniqueName
{ {
NS_DURING NS_DURING
@ -337,8 +360,14 @@ static NSMapTable *mimeMap = NULL;
return nil; return nil;
} }
/* /**
* Getting Data in Different Formats * <p>Returns a pasteboard from which the data (of the specified type)
* can be read in all the types to which it can be converted by
* filter services.
* </p>
* <p>Also registers the pasteboard as providing information of the
* specified type.
* </p>
*/ */
+ (NSPasteboard*) pasteboardByFilteringData: (NSData*)data + (NSPasteboard*) pasteboardByFilteringData: (NSData*)data
ofType: (NSString*)type ofType: (NSString*)type
@ -374,6 +403,13 @@ static NSMapTable *mimeMap = NULL;
return nil; return nil;
} }
/**
* <p>Creates and returns a pasteboard from which the data in the named
* file can be read in all the types to which it can be converted by
* filter services.<br />
* The type of data in the file is inferred from the file extension.
* </p>
*/
+ (NSPasteboard*) pasteboardByFilteringFile: (NSString*)filename + (NSPasteboard*) pasteboardByFilteringFile: (NSString*)filename
{ {
NSData *data; NSData *data;
@ -412,6 +448,17 @@ static NSMapTable *mimeMap = NULL;
return nil; return nil;
} }
/**
* <p>Creates and returns a pasteboard in where the data contained in pboard
* is available for reading in as many types as it can be converted to by
* available filter services. This normally expands on the range of types
* available in pboard.
* </p>
* <p>NB. This only permits a singlke level of filtering ... if pboard was
* previously returned by another filtering method, it is returned instead
* of a new pastebaord.
* </p>
*/
+ (NSPasteboard*) pasteboardByFilteringTypesInPasteboard: (NSPasteboard*)pboard + (NSPasteboard*) pasteboardByFilteringTypesInPasteboard: (NSPasteboard*)pboard
{ {
NS_DURING NS_DURING
@ -448,22 +495,36 @@ static NSMapTable *mimeMap = NULL;
return nil; return nil;
} }
/**
* Returns an array of the types to which data of the specified type
* can be converted by registered filter services.<br />
* The original type is always present in this array.<br />
* Raises an exception if type is nil.
*/
+ (NSArray*) typesFilterableTo: (NSString*)type + (NSArray*) typesFilterableTo: (NSString*)type
{ {
NSArray* types = nil; NSMutableSet *types = [NSMutableSet setWithCapacity: 8];
NSDictionary *info = [[GSServicesManager manager] filters];
NSEnumerator *enumerator = [info objectEnumerator];
NS_DURING [types addObject: type]; // Always include original type
/*
* Step through the filters looking for those which handle the type
*/
while ((info = [enumerator nextObject]) != nil)
{ {
types = [[self _pbs] typesFilterableTo: type]; NSArray *sendTypes = [info objectForKey: @"NSSendTypes"];
if ([sendTypes containsObject: type] == YES)
{
NSArray *returnTypes = [info objectForKey: @"NSReturnTypes"];
[types addObjectsFromArray: returnTypes];
}
} }
NS_HANDLER
{ return [types allObjects];
types = nil;
[NSException raise: NSPasteboardCommunicationException
format: @"%@", [localException reason]];
}
NS_ENDHANDLER
return types;
} }
/* /*
@ -486,22 +547,43 @@ static NSMapTable *mimeMap = NULL;
[super dealloc]; [super dealloc];
} }
/**
* Releases the receiver in the pastebaord server so that no other application
* can use the pasteboard. This should not be called for any of the standard
* pasteboards, only for temporary ones.
*/
- (void) releaseGlobally - (void) releaseGlobally
{ {
if ([name isEqualToString: NSGeneralPboard] == YES
|| [name isEqualToString: NSFontPboard] == YES
|| [name isEqualToString: NSRulerPboard] == YES
|| [name isEqualToString: NSFindPboard] == YES
|| [name isEqualToString: NSDragPboard] == YES)
{
[NSException raise: NSGenericException
format: @"Illegal attempt to globally release %@", name];
}
[target releaseGlobally]; [target releaseGlobally];
[pasteboards removeObjectForKey: name]; [pasteboards removeObjectForKey: name];
} }
/* /**
* Referring to a Pasteboard by Name * Returns the pasteboard name for the receiver.
*/ */
- (NSString*) name - (NSString*) name
{ {
return name; return name;
} }
/* /**
* Writing Data * <p>Adds newTypes to the pasteboard and declares newOwner to be the owner
* of the pasteboard. Use only after -declareTypes:owner: has been called
* for the same owner, because the new owner may not support all the types
* declared by a previous owner.
* </p>
* <p>Returns the new change count for the pastebaord, or zero if an error
* occurs.
* </p>
*/ */
- (int) addTypes: (NSArray*)newTypes - (int) addTypes: (NSArray*)newTypes
owner: (id)newOwner owner: (id)newOwner
@ -529,6 +611,14 @@ static NSMapTable *mimeMap = NULL;
return count; return count;
} }
/**
* <p>Sets the owner of the pastebaord to be newOwner and declares newTypes
* as the types of data supported by it.
* </p>
* <p>Returns the new change count for the pastebaord, or zero if an error
* occurs.
* </p>
*/
- (int) declareTypes: (NSArray*)newTypes - (int) declareTypes: (NSArray*)newTypes
owner: (id)newOwner owner: (id)newOwner
{ {
@ -566,6 +656,15 @@ static NSMapTable *mimeMap = NULL;
RELEASE(super); RELEASE(super);
} }
/**
* <p>Writes data of type dataType to the pasteboard server so that other
* applications can read it. The dataType must be one of the types
* previously declared for the pastebaord.
* </p>
* <p>Returns YES on success, NO if the data could not be written for some
* reason.
* </p>
*/
- (BOOL) setData: (NSData*)data - (BOOL) setData: (NSData*)data
forType: (NSString*)dataType forType: (NSString*)dataType
{ {
@ -588,6 +687,10 @@ static NSMapTable *mimeMap = NULL;
return ok; return ok;
} }
/**
* Serialises the data in the supplied property list and writes it to the
* pastebaord server using the -setData:forType: method.
*/
- (BOOL) setPropertyList: (id)propertyList - (BOOL) setPropertyList: (id)propertyList
forType: (NSString*)dataType forType: (NSString*)dataType
{ {
@ -596,27 +699,50 @@ static NSMapTable *mimeMap = NULL;
return [self setData: d forType: dataType]; return [self setData: d forType: dataType];
} }
/**
* Writes string it to the pastebaord server using the
* -setPropertyList:forType: method.
*/
- (BOOL) setString: (NSString*)string - (BOOL) setString: (NSString*)string
forType: (NSString*)dataType forType: (NSString*)dataType
{ {
return [self setPropertyList: string forType: dataType]; return [self setPropertyList: string forType: dataType];
} }
/**
* Writes the contents of the file filename to the pasteboard server
* after declaring the type NSFileContentsPboardType as well as a type
* based on the file extension (given by the NSCreateFileContentsPboardType()
* function) if there is one.
*/
- (BOOL) writeFileContents: (NSString*)filename - (BOOL) writeFileContents: (NSString*)filename
{ {
NSFileWrapper *wrapper; NSFileWrapper *wrapper;
NSData *data; NSData *data;
NSString *type; NSArray *types;
NSString *ext = [filename pathExtension];
BOOL ok = NO; BOOL ok = NO;
wrapper = [[NSFileWrapper alloc] initWithPath: filename]; wrapper = [[NSFileWrapper alloc] initWithPath: filename];
data = [wrapper serializedRepresentation]; data = [wrapper serializedRepresentation];
RELEASE(wrapper); RELEASE(wrapper);
type = NSCreateFileContentsPboardType([filename pathExtension]); if ([ext length] > 0)
{
types = [NSArray arrayWithObjects: NSFileContentsPboardType,
NSCreateFileContentsPboardType(ext), nil];
}
else
{
types = [NSArray arrayWithObject: NSFileContentsPboardType];
}
if ([self declareTypes: types owner: owner] == 0)
{
return NO; // Unable to declare types.
}
NS_DURING NS_DURING
{ {
ok = [target setData: data ok = [target setData: data
forType: type forType: NSFileContentsPboardType
isFile: YES isFile: YES
oldCount: changeCount]; oldCount: changeCount];
} }
@ -630,11 +756,20 @@ static NSMapTable *mimeMap = NULL;
return ok; return ok;
} }
/**
* <p>Writes the contents of the file wrapper to the pasteboard server
* after declaring the type NSFileContentsPboardType as well as a type
* based on the file extension of the wrappers preferred filename.
* </p>
* <p>Raises an exception if there is no preferred filename.
* </p>
*/
- (BOOL) writeFileWrapper: (NSFileWrapper *)wrapper - (BOOL) writeFileWrapper: (NSFileWrapper *)wrapper
{ {
NSString *filename = [wrapper preferredFilename]; NSString *filename = [wrapper preferredFilename];
NSData *data; NSData *data;
NSString *type; NSArray *types;
NSString *ext = [filename pathExtension];
BOOL ok = NO; BOOL ok = NO;
if (filename == nil) if (filename == nil)
@ -643,13 +778,24 @@ static NSMapTable *mimeMap = NULL;
format: @"Cannot put file on pastboard with " format: @"Cannot put file on pastboard with "
@"no preferred filename"]; @"no preferred filename"];
} }
data = [wrapper serializedRepresentation]; data = [wrapper serializedRepresentation];
type = NSCreateFileContentsPboardType([filename pathExtension]); if ([ext length] > 0)
{
types = [NSArray arrayWithObjects: NSFileContentsPboardType,
NSCreateFileContentsPboardType(ext), nil];
}
else
{
types = [NSArray arrayWithObject: NSFileContentsPboardType];
}
if ([self declareTypes: types owner: owner] == 0)
{
return NO; // Unable to declare types.
}
NS_DURING NS_DURING
{ {
ok = [target setData: data ok = [target setData: data
forType: type forType: NSFileContentsPboardType
isFile: YES isFile: YES
oldCount: changeCount]; oldCount: changeCount];
} }
@ -663,8 +809,9 @@ static NSMapTable *mimeMap = NULL;
return ok; return ok;
} }
/* /**
* Determining Types * Returns the first type listed in types which the receiver has been
* declared to support.
*/ */
- (NSString*) availableTypeFromArray: (NSArray*)types - (NSString*) availableTypeFromArray: (NSArray*)types
{ {
@ -688,6 +835,9 @@ static NSMapTable *mimeMap = NULL;
return type; return type;
} }
/**
* Returns all the types that the receiver has been declared to support.
*/
- (NSArray*) types - (NSArray*) types
{ {
NSArray *result = nil; NSArray *result = nil;
@ -709,8 +859,9 @@ static NSMapTable *mimeMap = NULL;
return result; return result;
} }
/* /**
* Reading Data * Returns the change count for the receiving pastebaord. This count
* is incremented whenever the owner of the pastebaord is changed.
*/ */
- (int) changeCount - (int) changeCount
{ {
@ -730,6 +881,11 @@ static NSMapTable *mimeMap = NULL;
return changeCount; return changeCount;
} }
/**
* Returns data from the pasteboard of the specified dataType, or nil
* if no such data is available.<br />
* May raise an exception if communication with the pasteboard server fails.
*/
- (NSData*) dataForType: (NSString*)dataType - (NSData*) dataForType: (NSString*)dataType
{ {
NSData *d = nil; NSData *d = nil;
@ -750,6 +906,10 @@ static NSMapTable *mimeMap = NULL;
return d; return d;
} }
/**
* Calls -dataForType: to obtain data (expected to be a serialized property
* list) and returns the object produced by deserializing it.
*/
- (id) propertyListForType: (NSString*)dataType - (id) propertyListForType: (NSString*)dataType
{ {
NSData *d = [self dataForType: dataType]; NSData *d = [self dataForType: dataType];
@ -761,6 +921,10 @@ static NSMapTable *mimeMap = NULL;
return nil; return nil;
} }
/**
* Obtains data of the specified dataType from the pastebaord, deserializes
* it to the specified filename and returns the file name (or nil on failure).
*/
- (NSString*) readFileContentsType: (NSString*)type - (NSString*) readFileContentsType: (NSString*)type
toFile: (NSString*)filename toFile: (NSString*)filename
{ {
@ -789,7 +953,11 @@ static NSMapTable *mimeMap = NULL;
return filename; return filename;
} }
- (NSFileWrapper *)readFileWrapper /**
* Obtains data of the specified dataType from the pastebaord, deserializes
* it and returns the resulting file wrapper (or nil).
*/
- (NSFileWrapper*) readFileWrapper
{ {
NSData *d = [self dataForType: NSFileContentsPboardType]; NSData *d = [self dataForType: NSFileContentsPboardType];
@ -800,9 +968,19 @@ static NSMapTable *mimeMap = NULL;
AUTORELEASE([[NSFileWrapper alloc] initWithSerializedRepresentation: d]); AUTORELEASE([[NSFileWrapper alloc] initWithSerializedRepresentation: d]);
} }
/**
* Obtains data of the specified dataType from the pastebaord, deserializes
* it and returns the resulting string (or nil).
*/
- (NSString*) stringForType: (NSString*)dataType - (NSString*) stringForType: (NSString*)dataType
{ {
return [self propertyListForType: dataType]; NSString *s = [self propertyListForType: dataType];
if ([s isKindOfClass: [NSString class]] == NO)
{
s = nil;
}
return s;
} }
/* /*
@ -827,12 +1005,12 @@ static NSMapTable *mimeMap = NULL;
@implementation NSPasteboard (GNUstepExtensions) @implementation NSPasteboard (GNUstepExtensions)
/* /**
* Once the '[-setChangeCount: ]' message has been sent to an NSPasteboard * Once the -setChangeCount: message has been sent to an NSPasteboard
* the object will gain an extra GNUstep behaviour - when geting data * the object will gain an extra GNUstep behaviour - when geting data
* from the pasteboard, the data need no longer be from the latest * from the pasteboard, the data need no longer be from the latest
* version but may be a version from a previous representation with * version but may be a version from a previous representation with
* the specified change count. * the specified change count.
*/ */
- (void) setChangeCount: (int)count - (void) setChangeCount: (int)count
{ {
@ -840,6 +1018,10 @@ static NSMapTable *mimeMap = NULL;
changeCount = count; changeCount = count;
} }
/**
* Sets the number of changes for which pasteboard data is kept.<br />
* This is 1 by default.
*/
- (void) setHistory: (unsigned)length - (void) setHistory: (unsigned)length
{ {
NS_DURING NS_DURING
@ -877,7 +1059,7 @@ static NSMapTable *mimeMap = NULL;
(void *)@"text/plain"); (void *)@"text/plain");
} }
/* /**
* Return the mapping for pasteboard->mime, or return the original pasteboard * Return the mapping for pasteboard->mime, or return the original pasteboard
* type if no mapping is found * type if no mapping is found
*/ */
@ -897,7 +1079,7 @@ static NSMapTable *mimeMap = NULL;
return mime; return mime;
} }
/* /**
* Return the mapping for mime->pasteboard, or return the original pasteboard * Return the mapping for mime->pasteboard, or return the original pasteboard
* type if no mapping is found. This method may not have a one-to-one * type if no mapping is found. This method may not have a one-to-one
* mapping * mapping
@ -950,12 +1132,20 @@ static NSMapTable *mimeMap = NULL;
static NSString* contentsPrefix = @"NSTypedFileContentsPboardType:"; static NSString* contentsPrefix = @"NSTypedFileContentsPboardType:";
static NSString* namePrefix = @"NSTypedFilenamesPboardType:"; static NSString* namePrefix = @"NSTypedFilenamesPboardType:";
/**
* Returns a standardised pasteboard type for file contents,
* formed from the supplied file extension.
*/
NSString* NSString*
NSCreateFileContentsPboardType(NSString *fileType) NSCreateFileContentsPboardType(NSString *fileType)
{ {
return [NSString stringWithFormat: @"%@%@", contentsPrefix, fileType]; return [NSString stringWithFormat: @"%@%@", contentsPrefix, fileType];
} }
/**
* Returns a standardised pasteboard type for file names,
* formed from the supplied file extension.
*/
NSString* NSString*
NSCreateFilenamePboardType(NSString *filename) NSCreateFilenamePboardType(NSString *filename)
{ {