mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 19:00:47 +00:00
Various partially completed works
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@4154 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
d179d675db
commit
0e88a90011
4 changed files with 822 additions and 365 deletions
|
@ -38,6 +38,18 @@
|
||||||
#include <AppKit/NSCachedImageRep.h>
|
#include <AppKit/NSCachedImageRep.h>
|
||||||
#include <AppKit/NSWindow.h>
|
#include <AppKit/NSWindow.h>
|
||||||
|
|
||||||
|
@interface GSCacheW : NSWindow
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GSCacheW
|
||||||
|
|
||||||
|
- (void) initDefaults
|
||||||
|
{
|
||||||
|
[super initDefaults];
|
||||||
|
menu_exclude = YES; // Don't show in windows menu.
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
/* Backend protocol - methods that must be implemented by the backend to
|
/* Backend protocol - methods that must be implemented by the backend to
|
||||||
complete the class */
|
complete the class */
|
||||||
@protocol NXCachedImageRepBackend
|
@protocol NXCachedImageRepBackend
|
||||||
|
@ -48,17 +60,26 @@
|
||||||
|
|
||||||
// Initializing an NSCachedImageRep
|
// Initializing an NSCachedImageRep
|
||||||
- (id) initWithSize: (NSSize)aSize
|
- (id) initWithSize: (NSSize)aSize
|
||||||
depth: (NSWindowDepth)aDepth
|
depth: (NSWindowDepth)aDepth
|
||||||
separate: (BOOL)separate
|
separate: (BOOL)separate
|
||||||
alpha: (BOOL)alpha
|
alpha: (BOOL)alpha
|
||||||
{
|
{
|
||||||
return nil;
|
NSWindow *win;
|
||||||
|
NSRect frame;
|
||||||
|
|
||||||
|
frame.origin = NSMakePoint(0,0);
|
||||||
|
frame.size = aSize;
|
||||||
|
win = [[GSCacheW alloc] initWithContentRect: frame
|
||||||
|
styleMask: NSBorderlessWindowMask
|
||||||
|
backing: NSBackingStoreRetained
|
||||||
|
defer: NO];
|
||||||
|
self = [self initWithWindow: win rect: frame];
|
||||||
|
[win release];
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- initWithWindow: (NSWindow *)win rect: (NSRect)rect
|
- (id) initWithWindow: (NSWindow *)win rect: (NSRect)rect
|
||||||
{
|
{
|
||||||
int style = NSClosableWindowMask;
|
|
||||||
|
|
||||||
[super init];
|
[super init];
|
||||||
|
|
||||||
_window = [win retain];
|
_window = [win retain];
|
||||||
|
@ -72,16 +93,17 @@
|
||||||
if (!_window)
|
if (!_window)
|
||||||
{
|
{
|
||||||
[NSException raise: NSInvalidArgumentException
|
[NSException raise: NSInvalidArgumentException
|
||||||
format: @"Must specify either window or rect when creating NSCachedImageRep"];
|
format: @"Must specify either window or rect when "
|
||||||
|
@"creating NSCachedImageRep"];
|
||||||
}
|
}
|
||||||
|
|
||||||
_rect = [_window frame];
|
_rect = [_window frame];
|
||||||
}
|
}
|
||||||
if (!_window)
|
if (!_window)
|
||||||
_window = [[NSWindow alloc] initWithContentRect: _rect
|
_window = [[GSCacheW alloc] initWithContentRect: _rect
|
||||||
styleMask: style
|
styleMask: NSBorderlessWindowMask
|
||||||
backing: NSBackingStoreRetained
|
backing: NSBackingStoreRetained
|
||||||
defer: NO];
|
defer: NO];
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +126,7 @@
|
||||||
|
|
||||||
- (BOOL)draw
|
- (BOOL)draw
|
||||||
{
|
{
|
||||||
|
NSCopyBits([_window gState], _rect, _rect.origin);
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
460
Source/NSImage.m
460
Source/NSImage.m
|
@ -43,6 +43,7 @@
|
||||||
#include <Foundation/NSString.h>
|
#include <Foundation/NSString.h>
|
||||||
|
|
||||||
#include <AppKit/NSImage.h>
|
#include <AppKit/NSImage.h>
|
||||||
|
#include <AppKit/AppKitExceptions.h>
|
||||||
#include <AppKit/NSBitmapImageRep.h>
|
#include <AppKit/NSBitmapImageRep.h>
|
||||||
#include <AppKit/NSCachedImageRep.h>
|
#include <AppKit/NSCachedImageRep.h>
|
||||||
#include <AppKit/NSView.h>
|
#include <AppKit/NSView.h>
|
||||||
|
@ -50,6 +51,8 @@
|
||||||
#include <AppKit/NSScreen.h>
|
#include <AppKit/NSScreen.h>
|
||||||
#include <AppKit/NSColor.h>
|
#include <AppKit/NSColor.h>
|
||||||
|
|
||||||
|
BOOL doesCaching = NO;
|
||||||
|
|
||||||
// Resource directories
|
// Resource directories
|
||||||
static NSString* gnustep_libdir = @GNUSTEP_INSTALL_LIBDIR;
|
static NSString* gnustep_libdir = @GNUSTEP_INSTALL_LIBDIR;
|
||||||
static NSString* NSImage_PATH = @"Images";
|
static NSString* NSImage_PATH = @"Images";
|
||||||
|
@ -65,59 +68,62 @@ static NSString* NSImage_PATH = @"Images";
|
||||||
fraction: (float)aFloat;
|
fraction: (float)aFloat;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
typedef struct _rep_data_t
|
@interface GSRepData : NSObject
|
||||||
{
|
{
|
||||||
NSString* fileName;
|
@public
|
||||||
id rep;
|
NSString *fileName;
|
||||||
id cache;
|
NSImageRep *rep;
|
||||||
id original;
|
NSImageRep *original;
|
||||||
BOOL validCache;
|
NSColor *bg;
|
||||||
} rep_data_t;
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GSRepData
|
||||||
|
- (id) copyWithZone: (NSZone*)z
|
||||||
|
{
|
||||||
|
GSRepData *c = (GSRepData*)NSCopyObject(self, 0, z);
|
||||||
|
|
||||||
|
if (c->fileName)
|
||||||
|
c->fileName = [c->fileName copy];
|
||||||
|
if (c->rep)
|
||||||
|
c->rep = [c->rep copy];
|
||||||
|
if (c->bg)
|
||||||
|
c->bg = [c->bg copy];
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
if (fileName)
|
||||||
|
[fileName release];
|
||||||
|
if (rep)
|
||||||
|
[rep release];
|
||||||
|
if (bg)
|
||||||
|
[bg release];
|
||||||
|
NSDeallocateObject(self);
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
NSArray *iterate_reps_for_types(NSArray *imageReps, SEL method);
|
NSArray *iterate_reps_for_types(NSArray *imageReps, SEL method);
|
||||||
|
|
||||||
/* Find the rep_data_t holding a representation */
|
/* Find the GSRepData object holding a representation */
|
||||||
rep_data_t
|
GSRepData*
|
||||||
repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
repd_for_rep(NSArray *_reps, NSImageRep *rep)
|
||||||
{
|
{
|
||||||
int i, count;
|
unsigned i, count;
|
||||||
rep_data_t repd;
|
GSRepData *repd;
|
||||||
|
|
||||||
count = [_reps count];
|
count = [_reps count];
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
[[_reps objectAtIndex: i] getValue: &repd];
|
repd = [_reps objectAtIndex: i];
|
||||||
if (repd.rep == rep)
|
if (repd->rep == rep)
|
||||||
return repd;
|
return repd;
|
||||||
}
|
}
|
||||||
[NSException raise: NSInternalInconsistencyException
|
[NSException raise: NSInternalInconsistencyException
|
||||||
format: @"Cannot find stored representation"];
|
format: @"Cannot find stored representation"];
|
||||||
/* NOT REACHED */
|
/* NOT REACHED */
|
||||||
return repd;
|
return nil;
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd)
|
|
||||||
{
|
|
||||||
int i, count;
|
|
||||||
rep_data_t repd;
|
|
||||||
BOOL found = NO;
|
|
||||||
|
|
||||||
count = [_reps count];
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
[[_reps objectAtIndex: i] getValue: &repd];
|
|
||||||
if (repd.rep == rep && !found)
|
|
||||||
{
|
|
||||||
[_reps replaceObjectAtIndex: i withObject:
|
|
||||||
[NSValue value: new_repd withObjCType: @encode(rep_data_t)]];
|
|
||||||
found = YES;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
[_reps addObject:
|
|
||||||
[NSValue value: new_repd withObjCType: @encode(rep_data_t)]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@interface NSImage (Backend) <NSImageBackend>
|
@interface NSImage (Backend) <NSImageBackend>
|
||||||
|
@ -140,10 +146,10 @@ static NSDictionary* nsmapping = nil;
|
||||||
{
|
{
|
||||||
if (self == [NSImage class])
|
if (self == [NSImage class])
|
||||||
{
|
{
|
||||||
NSBundle *system = [NSBundle bundleWithPath: gnustep_libdir];
|
NSBundle *system = [NSBundle bundleWithPath: gnustep_libdir];
|
||||||
NSString* path = [system pathForResource: @"nsmapping"
|
NSString *path = [system pathForResource: @"nsmapping"
|
||||||
ofType: @"strings"
|
ofType: @"strings"
|
||||||
inDirectory: NSImage_PATH];
|
inDirectory: NSImage_PATH];
|
||||||
// Initial version
|
// Initial version
|
||||||
[self setVersion: 1];
|
[self setVersion: 1];
|
||||||
|
|
||||||
|
@ -158,7 +164,7 @@ static NSDictionary* nsmapping = nil;
|
||||||
|
|
||||||
+ imageNamed: (NSString *)aName
|
+ imageNamed: (NSString *)aName
|
||||||
{
|
{
|
||||||
NSString* realName = [nsmapping objectForKey: aName];
|
NSString *realName = [nsmapping objectForKey: aName];
|
||||||
|
|
||||||
if (realName)
|
if (realName)
|
||||||
aName = realName;
|
aName = realName;
|
||||||
|
@ -215,8 +221,8 @@ static NSDictionary* nsmapping = nil;
|
||||||
|
|
||||||
if (ext)
|
if (ext)
|
||||||
path = [system pathForResource: the_name
|
path = [system pathForResource: the_name
|
||||||
ofType: ext
|
ofType: ext
|
||||||
inDirectory: NSImage_PATH];
|
inDirectory: NSImage_PATH];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
id o, e;
|
id o, e;
|
||||||
|
@ -229,8 +235,8 @@ static NSDictionary* nsmapping = nil;
|
||||||
while ((o = [e nextObject]))
|
while ((o = [e nextObject]))
|
||||||
{
|
{
|
||||||
path = [system pathForResource: the_name
|
path = [system pathForResource: the_name
|
||||||
ofType: o
|
ofType: o
|
||||||
inDirectory: NSImage_PATH];
|
inDirectory: NSImage_PATH];
|
||||||
if ([path length] != 0)
|
if ([path length] != 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -242,7 +248,7 @@ static NSDictionary* nsmapping = nil;
|
||||||
NSImage *image;
|
NSImage *image;
|
||||||
|
|
||||||
image = [[self allocWithZone: NSDefaultMallocZone()]
|
image = [[self allocWithZone: NSDefaultMallocZone()]
|
||||||
initByReferencingFile: path];
|
initByReferencingFile: path];
|
||||||
if (image)
|
if (image)
|
||||||
{
|
{
|
||||||
[image setName: aName];
|
[image setName: aName];
|
||||||
|
@ -463,8 +469,8 @@ static NSDictionary* nsmapping = nil;
|
||||||
// Determining How the Image is Drawn
|
// Determining How the Image is Drawn
|
||||||
- (BOOL) isValid
|
- (BOOL) isValid
|
||||||
{
|
{
|
||||||
BOOL valid = NO;
|
BOOL valid = NO;
|
||||||
int i, count;
|
unsigned i, count;
|
||||||
|
|
||||||
/* Go through all our representations and determine if at least one
|
/* Go through all our representations and determine if at least one
|
||||||
is a valid cache */
|
is a valid cache */
|
||||||
|
@ -472,9 +478,11 @@ static NSDictionary* nsmapping = nil;
|
||||||
count = [_reps count];
|
count = [_reps count];
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
rep_data_t repd;
|
GSRepData *repd = (GSRepData*)[_reps objectAtIndex: i];
|
||||||
[[_reps objectAtIndex: i] getValue: &repd];
|
|
||||||
valid |= repd.validCache;
|
if (repd->bg != nil
|
||||||
|
|| [repd->rep isKindOfClass: [NSCachedImageRep class]] == NO)
|
||||||
|
valid = YES;
|
||||||
}
|
}
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
@ -486,11 +494,14 @@ static NSDictionary* nsmapping = nil;
|
||||||
count = [_reps count];
|
count = [_reps count];
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
rep_data_t repd;
|
GSRepData *repd;
|
||||||
[[_reps objectAtIndex: i] getValue: &repd];
|
|
||||||
repd.validCache = NO;
|
repd = (GSRepData*)[_reps objectAtIndex: i];
|
||||||
[_reps replaceObjectAtIndex: i withObject:
|
if (repd->bg != nil)
|
||||||
[NSValue value: &repd withObjCType: @encode(rep_data_t)]];
|
{
|
||||||
|
[repd->bg release];
|
||||||
|
repd->bg = nil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +510,7 @@ static NSDictionary* nsmapping = nil;
|
||||||
_flags.scalable = flag;
|
_flags.scalable = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)scalesWhenResized
|
- (BOOL) scalesWhenResized
|
||||||
{
|
{
|
||||||
return _flags.scalable;
|
return _flags.scalable;
|
||||||
}
|
}
|
||||||
|
@ -513,8 +524,10 @@ static NSDictionary* nsmapping = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSColor *)backgroundColor
|
- (NSColor *) backgroundColor
|
||||||
{
|
{
|
||||||
|
if (_color == nil)
|
||||||
|
_color = [[NSColor clearColor] retain];
|
||||||
return _color;
|
return _color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -522,25 +535,24 @@ static NSDictionary* nsmapping = nil;
|
||||||
in and added to the representation list. */
|
in and added to the representation list. */
|
||||||
- _loadImageFilenames
|
- _loadImageFilenames
|
||||||
{
|
{
|
||||||
unsigned i, count;
|
unsigned i, count;
|
||||||
rep_data_t repd;
|
GSRepData *repd;
|
||||||
|
|
||||||
_syncLoad = NO;
|
_syncLoad = NO;
|
||||||
count = [_reps count];
|
count = [_reps count];
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
[[_reps objectAtIndex: i] getValue: &repd];
|
repd = (GSRepData*)[_reps objectAtIndex: i];
|
||||||
if (repd.fileName)
|
if (repd->fileName)
|
||||||
[self loadFromFile: repd.fileName];
|
[self loadFromFile: repd->fileName];
|
||||||
}
|
}
|
||||||
// Now get rid of them since they are already loaded
|
// Now get rid of them since they are already loaded
|
||||||
count = [_reps count];
|
count = [_reps count];
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
[[_reps objectAtIndex: count] getValue: &repd];
|
repd = (GSRepData*)[_reps objectAtIndex: count];
|
||||||
if (repd.fileName)
|
if (repd->fileName)
|
||||||
{
|
{
|
||||||
[repd.fileName release];
|
|
||||||
[_reps removeObjectAtIndex: count];
|
[_reps removeObjectAtIndex: count];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -553,50 +565,65 @@ static NSDictionary* nsmapping = nil;
|
||||||
// image (if there is one).
|
// image (if there is one).
|
||||||
- (NSImageRep *)_doImageCache
|
- (NSImageRep *)_doImageCache
|
||||||
{
|
{
|
||||||
NSImageRep *rep = nil;
|
NSImageRep *rep = nil;
|
||||||
rep_data_t repd;
|
GSRepData *repd;
|
||||||
|
|
||||||
repd = repd_for_rep(_reps, [self bestRepresentationForDevice: nil]);
|
repd = repd_for_rep(_reps, [self bestRepresentationForDevice: nil]);
|
||||||
rep = repd.rep;
|
rep = repd->rep;
|
||||||
if (repd.cache)
|
|
||||||
rep = repd.cache;
|
|
||||||
|
|
||||||
if (![rep isKindOfClass: [NSCachedImageRep class]])
|
if (doesCaching)
|
||||||
{
|
{
|
||||||
#if 0
|
/*
|
||||||
[self lockFocus];
|
* If this is not a cached image rep - create a cache to be used to
|
||||||
|
* render the image rep into, and switch to the cached rep.
|
||||||
|
*/
|
||||||
|
if ([rep isKindOfClass: [NSCachedImageRep class]] == NO)
|
||||||
{
|
{
|
||||||
rep_data_t cached;
|
NSScreen *cur = [NSScreen mainScreen];
|
||||||
NSRect bounds;
|
NSCachedImageRep *cachedRep;
|
||||||
_lockedView = [NSView focusView];
|
NSSize imageSize;
|
||||||
bounds = [_lockedView bounds];
|
|
||||||
[self _displayEraseRect: bounds view: _lockedView color: _color];
|
imageSize = [self size];
|
||||||
[self unlockFocus];
|
if (imageSize.width == 0 || imageSize.height == 0)
|
||||||
[[_reps lastObject] getValue: &cached];
|
return nil;
|
||||||
cached.original = rep;
|
|
||||||
cached.validCache = YES;
|
cachedRep = [[NSCachedImageRep alloc] initWithSize: _size
|
||||||
[_reps removeLastObject];
|
depth: [cur depth]
|
||||||
[_reps addObject:
|
separate: NO
|
||||||
[NSValue value: &cached withObjCType: @encode(rep_data_t)]];
|
alpha: NO];
|
||||||
}
|
[self addRepresentation: cachedRep];
|
||||||
#endif
|
[cachedRep release]; /* Retained in _reps array. */
|
||||||
}
|
repd = repd_for_rep(_reps, cachedRep);
|
||||||
else if (!repd.validCache)
|
repd->original = rep;
|
||||||
{
|
rep = repd->rep;
|
||||||
#if 0
|
}
|
||||||
[self lockFocusOnRepresentation: rep];
|
|
||||||
|
/*
|
||||||
|
* if the cache is not valid, it's background color will not exist
|
||||||
|
* and we must draw the background then render from the original
|
||||||
|
* image rep into the cache.
|
||||||
|
*/
|
||||||
|
if (repd->bg == nil)
|
||||||
{
|
{
|
||||||
NSRect bounds;
|
NSRect bounds;
|
||||||
|
|
||||||
|
[self lockFocusOnRepresentation: rep];
|
||||||
|
/*
|
||||||
|
* If this is not a cache - the lockFocus will have created a
|
||||||
|
* cache that we can use instead.
|
||||||
|
*/
|
||||||
|
if (repd->original == nil)
|
||||||
|
{
|
||||||
|
repd = repd_for_rep(_reps, [self lastRepresentation]);
|
||||||
|
}
|
||||||
bounds = [_lockedView bounds];
|
bounds = [_lockedView bounds];
|
||||||
[self _displayEraseRect: bounds view: _lockedView color: _color];
|
[_color set];
|
||||||
repd = repd_for_rep(_reps, rep);
|
NSEraseRect(bounds);
|
||||||
[self drawRepresentation: repd.original
|
[self drawRepresentation: repd->original
|
||||||
inRect: NSMakeRect(0, 0, _size.width, _size.height)];
|
inRect: NSMakeRect(0, 0, _size.width, _size.height)];
|
||||||
[self unlockFocus];
|
[self unlockFocus];
|
||||||
repd.validCache = YES;
|
repd->bg = [_color copy];
|
||||||
set_repd_for_rep(_reps, repd.rep, &repd);
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rep;
|
return rep;
|
||||||
|
@ -607,6 +634,7 @@ static NSDictionary* nsmapping = nil;
|
||||||
operation: (NSCompositingOperation)op;
|
operation: (NSCompositingOperation)op;
|
||||||
{
|
{
|
||||||
NSRect rect;
|
NSRect rect;
|
||||||
|
|
||||||
[self size];
|
[self size];
|
||||||
rect = NSMakeRect(0, 0, _size.width, _size.height);
|
rect = NSMakeRect(0, 0, _size.width, _size.height);
|
||||||
[self compositeToPoint: aPoint fromRect: rect operation: op];
|
[self compositeToPoint: aPoint fromRect: rect operation: op];
|
||||||
|
@ -623,9 +651,7 @@ static NSDictionary* nsmapping = nil;
|
||||||
// then we need to construct a subimage to draw
|
// then we need to construct a subimage to draw
|
||||||
|
|
||||||
rep = [self _doImageCache];
|
rep = [self _doImageCache];
|
||||||
[self lockFocusOnRepresentation: rep];
|
|
||||||
[self drawRepresentation: rep inRect: rect];
|
[self drawRepresentation: rep inRect: rect];
|
||||||
[self unlockFocus];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) dissolveToPoint: (NSPoint)aPoint fraction: (float)aFloat;
|
- (void) dissolveToPoint: (NSPoint)aPoint fraction: (float)aFloat;
|
||||||
|
@ -647,9 +673,7 @@ static NSDictionary* nsmapping = nil;
|
||||||
// then we need to construct a subimage to draw
|
// then we need to construct a subimage to draw
|
||||||
|
|
||||||
rep = [self _doImageCache];
|
rep = [self _doImageCache];
|
||||||
[self lockFocusOnRepresentation: rep];
|
|
||||||
[self drawRepresentation: rep inRect: rect];
|
[self drawRepresentation: rep inRect: rect];
|
||||||
[self unlockFocus];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)drawRepresentation: (NSImageRep *)imageRep inRect: (NSRect)rect
|
- (BOOL)drawRepresentation: (NSImageRep *)imageRep inRect: (NSRect)rect
|
||||||
|
@ -700,7 +724,7 @@ static NSDictionary* nsmapping = nil;
|
||||||
{
|
{
|
||||||
NSArray *array;
|
NSArray *array;
|
||||||
NSString *ext;
|
NSString *ext;
|
||||||
rep_data_t repd;
|
GSRepData *repd;
|
||||||
NSFileManager *manager = [NSFileManager defaultManager];
|
NSFileManager *manager = [NSFileManager defaultManager];
|
||||||
|
|
||||||
if ([manager fileExistsAtPath: fileName] == NO)
|
if ([manager fileExistsAtPath: fileName] == NO)
|
||||||
|
@ -714,8 +738,10 @@ static NSDictionary* nsmapping = nil;
|
||||||
array = [[self class] imageFileTypes];
|
array = [[self class] imageFileTypes];
|
||||||
if ([array indexOfObject: ext] == NSNotFound)
|
if ([array indexOfObject: ext] == NSNotFound)
|
||||||
return NO;
|
return NO;
|
||||||
repd.fileName = [fileName retain];
|
repd = [GSRepData new];
|
||||||
[_reps addObject: [NSValue value: &repd withObjCType: @encode(rep_data_t)]];
|
repd->fileName = [fileName retain];
|
||||||
|
[_reps addObject: repd];
|
||||||
|
[repd release];
|
||||||
_syncLoad = YES;
|
_syncLoad = YES;
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
@ -727,8 +753,8 @@ static NSDictionary* nsmapping = nil;
|
||||||
|
|
||||||
- (void) addRepresentations: (NSArray *)imageRepArray
|
- (void) addRepresentations: (NSArray *)imageRepArray
|
||||||
{
|
{
|
||||||
int i, count;
|
unsigned i, count;
|
||||||
rep_data_t repd;
|
GSRepData *repd;
|
||||||
|
|
||||||
if (!imageRepArray)
|
if (!imageRepArray)
|
||||||
return;
|
return;
|
||||||
|
@ -738,13 +764,10 @@ static NSDictionary* nsmapping = nil;
|
||||||
count = [imageRepArray count];
|
count = [imageRepArray count];
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
repd.fileName = NULL;
|
repd = [GSRepData new];
|
||||||
repd.rep = [[imageRepArray objectAtIndex: i] retain];
|
repd->rep = [[imageRepArray objectAtIndex: i] retain];
|
||||||
repd.cache = NULL;
|
[_reps addObject: repd];
|
||||||
repd.original = NULL;
|
[repd release];
|
||||||
repd.validCache = NO;
|
|
||||||
[_reps addObject:
|
|
||||||
[NSValue value: &repd withObjCType: @encode(rep_data_t)]];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,6 +780,7 @@ static NSDictionary* nsmapping = nil;
|
||||||
if (!imageSize.width || !imageSize.height)
|
if (!imageSize.width || !imageSize.height)
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
|
|
||||||
// FIXME: determine alpha? separate?
|
// FIXME: determine alpha? separate?
|
||||||
rep = [[NSCachedImageRep alloc] initWithSize: _size
|
rep = [[NSCachedImageRep alloc] initWithSize: _size
|
||||||
depth: depth
|
depth: depth
|
||||||
|
@ -768,21 +792,28 @@ static NSDictionary* nsmapping = nil;
|
||||||
|
|
||||||
- (void) removeRepresentation: (NSImageRep *)imageRep
|
- (void) removeRepresentation: (NSImageRep *)imageRep
|
||||||
{
|
{
|
||||||
int i, count;
|
unsigned i;
|
||||||
rep_data_t repd;
|
GSRepData *repd;
|
||||||
count = [_reps count];
|
|
||||||
for (i = 0; i < count; i++)
|
i = [_reps count];
|
||||||
|
while (i-- > 0)
|
||||||
{
|
{
|
||||||
[[_reps objectAtIndex: i] getValue: &repd];
|
repd = (GSRepData*)[_reps objectAtIndex: i];
|
||||||
if (repd.rep == imageRep)
|
if (repd->rep == imageRep)
|
||||||
[_reps removeObjectAtIndex: i];
|
{
|
||||||
|
[_reps removeObjectAtIndex: i];
|
||||||
|
}
|
||||||
|
else if (repd->original == imageRep)
|
||||||
|
{
|
||||||
|
repd->original = nil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) lockFocus
|
- (void) lockFocus
|
||||||
{
|
{
|
||||||
NSScreen *cur = [NSScreen mainScreen];
|
NSScreen *cur = [NSScreen mainScreen];
|
||||||
NSImageRep *rep;
|
NSImageRep *rep;
|
||||||
|
|
||||||
if (!(rep = [self bestRepresentationForDevice: nil]))
|
if (!(rep = [self bestRepresentationForDevice: nil]))
|
||||||
{
|
{
|
||||||
|
@ -794,107 +825,159 @@ static NSDictionary* nsmapping = nil;
|
||||||
|
|
||||||
- (void) lockFocusOnRepresentation: (NSImageRep *)imageRep
|
- (void) lockFocusOnRepresentation: (NSImageRep *)imageRep
|
||||||
{
|
{
|
||||||
#if 0
|
NSScreen *cur = [NSScreen mainScreen];
|
||||||
NSScreen *cur = [NSScreen mainScreen];
|
NSWindow *window;
|
||||||
NSWindow *window;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!imageRep)
|
if (!imageRep)
|
||||||
[NSException raise: NSInvalidArgumentException
|
[NSException raise: NSInvalidArgumentException
|
||||||
format: @"Cannot lock focus on nil rep"];
|
format: @"Cannot lock focus on nil rep"];
|
||||||
|
|
||||||
#if 0
|
if (doesCaching)
|
||||||
if (![imageRep isKindOfClass: [NSCachedImageRep class]])
|
|
||||||
{
|
{
|
||||||
rep_data_t repd, cached;
|
if (![imageRep isKindOfClass: [NSCachedImageRep class]])
|
||||||
int depth;
|
|
||||||
if (_flags.unboundedCacheDepth)
|
|
||||||
depth = [cur depth]; // FIXME: get depth correctly
|
|
||||||
else
|
|
||||||
depth = [cur depth];
|
|
||||||
if (![self useCacheWithDepth: depth])
|
|
||||||
{
|
{
|
||||||
[NSException raise: NSImageCacheException
|
GSRepData *repd, *cached;
|
||||||
format: @"Unable to create cache"];
|
int depth;
|
||||||
|
|
||||||
|
if (_flags.unboundedCacheDepth)
|
||||||
|
depth = [cur depth]; // FIXME: get depth correctly
|
||||||
|
else
|
||||||
|
depth = [cur depth];
|
||||||
|
if (![self useCacheWithDepth: depth])
|
||||||
|
{
|
||||||
|
[NSException raise: NSImageCacheException
|
||||||
|
format: @"Unable to create cache"];
|
||||||
|
}
|
||||||
|
cached = repd_for_rep(_reps, [self lastRepresentation]);
|
||||||
|
cached->original = imageRep;
|
||||||
|
imageRep = cached->rep;
|
||||||
}
|
}
|
||||||
repd = repd_for_rep(_reps, imageRep);
|
window = [(NSCachedImageRep *)imageRep window];
|
||||||
cached = repd_for_rep(_reps, [self lastRepresentation]);
|
_lockedView = [window contentView];
|
||||||
repd.cache = cached.rep;
|
[_lockedView lockFocus];
|
||||||
cached.original = repd.rep;
|
|
||||||
set_repd_for_rep(_reps, imageRep, &repd);
|
|
||||||
set_repd_for_rep(_reps, cached.rep, &cached);
|
|
||||||
imageRep = cached.rep;
|
|
||||||
}
|
}
|
||||||
window = [(NSCachedImageRep *)imageRep window];
|
|
||||||
_lockedView = [window contentView];
|
|
||||||
[_lockedView lockFocus];
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) unlockFocus
|
- (void) unlockFocus
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if (_lockedView)
|
if (_lockedView)
|
||||||
[_lockedView unlockFocus];
|
[_lockedView unlockFocus];
|
||||||
_lockedView = nil;
|
_lockedView = nil;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSImageRep *) lastRepresentation
|
- (NSImageRep *) lastRepresentation
|
||||||
{
|
{
|
||||||
// Reconstruct the repList if it has changed
|
// Reconstruct the rep list if it has changed
|
||||||
[self representations];
|
[self representations];
|
||||||
return [_repList lastObject];
|
return [_repList lastObject];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSImageRep*) bestRepresentationForDevice: (NSDictionary*)deviceDescription
|
- (NSImageRep*) bestRepresentationForDevice: (NSDictionary*)deviceDescription
|
||||||
{
|
{
|
||||||
id o, e;
|
NSImageRep *rep = nil;
|
||||||
NSImageRep *rep = nil;
|
unsigned count;
|
||||||
rep_data_t repd;
|
|
||||||
|
|
||||||
// Make sure we have the images loaded in
|
/* Make sure we have the images loaded in. */
|
||||||
if (_syncLoad)
|
if (_syncLoad)
|
||||||
[self _loadImageFilenames];
|
[self _loadImageFilenames];
|
||||||
|
|
||||||
if ([_reps count] == 0)
|
count = [_reps count];
|
||||||
return nil;
|
|
||||||
|
|
||||||
// What's the best representation? FIXME
|
|
||||||
e = [_reps objectEnumerator];
|
|
||||||
o = [e nextObject];
|
|
||||||
while (o)
|
|
||||||
{
|
|
||||||
[o getValue: &repd];
|
|
||||||
if ([repd.rep isKindOfClass: [NSBitmapImageRep class]])
|
|
||||||
rep = repd.rep;
|
|
||||||
o = [e nextObject];
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
[[_reps lastObject] getValue: &repd];
|
|
||||||
if (repd.cache)
|
|
||||||
rep = repd.cache;
|
|
||||||
else
|
|
||||||
rep = repd.rep;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
GSRepData *reps[count];
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* What's the best representation? FIXME
|
||||||
|
*/
|
||||||
|
[_reps getObjects: reps];
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
GSRepData *repd = reps[i];
|
||||||
|
|
||||||
|
if ([repd->rep isKindOfClass: [NSBitmapImageRep class]])
|
||||||
|
{
|
||||||
|
rep = repd->rep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we got a representation - see if we already have it cached.
|
||||||
|
*/
|
||||||
|
if (doesCaching)
|
||||||
|
{
|
||||||
|
if (rep != nil)
|
||||||
|
{
|
||||||
|
GSRepData *invalidCache = nil;
|
||||||
|
GSRepData *validCache = nil;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search the cached image reps for any whose original is our
|
||||||
|
* 'best' image rep. See if we can notice any invalidated
|
||||||
|
* cache as we go - if we don't find a valid cache, we want to
|
||||||
|
* re-use an invalidated one rather than createing a new one.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
GSRepData *repd = reps[i];
|
||||||
|
|
||||||
|
if (repd->original == rep)
|
||||||
|
{
|
||||||
|
if (repd->bg == nil)
|
||||||
|
{
|
||||||
|
invalidCache = repd;
|
||||||
|
}
|
||||||
|
else if ([repd->bg isEqual: _color] == YES)
|
||||||
|
{
|
||||||
|
validCache = repd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validCache)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If the image rep has transparencey and we are drawing
|
||||||
|
* without a background (background is clear) then the
|
||||||
|
* cache can't really be valid 'cos we might be drawing
|
||||||
|
* transparency on top of anything. So we invalidate
|
||||||
|
* the cache by removing the background color information.
|
||||||
|
*/
|
||||||
|
if ([rep hasAlpha]
|
||||||
|
&& [validCache->bg isEqual: [NSColor clearColor]])
|
||||||
|
{
|
||||||
|
[validCache->bg release];
|
||||||
|
validCache->bg = nil;
|
||||||
|
}
|
||||||
|
rep = validCache->rep;
|
||||||
|
}
|
||||||
|
else if (invalidCache)
|
||||||
|
{
|
||||||
|
rep = invalidCache->rep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *) representations
|
- (NSArray *) representations
|
||||||
{
|
{
|
||||||
unsigned i, count;
|
unsigned i, count;
|
||||||
|
|
||||||
if (!_repList)
|
if (!_repList)
|
||||||
_repList = [[NSMutableArray alloc] init];
|
_repList = [[NSMutableArray alloc] init];
|
||||||
if (_syncLoad)
|
if (_syncLoad)
|
||||||
[self _loadImageFilenames];
|
[self _loadImageFilenames];
|
||||||
count = [_reps count];
|
|
||||||
[_repList removeAllObjects];
|
[_repList removeAllObjects];
|
||||||
|
count = [_reps count];
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
rep_data_t repd;
|
GSRepData *repd = [_reps objectAtIndex: i];
|
||||||
[[_reps objectAtIndex: i] getValue: &repd];
|
|
||||||
[_repList addObject: repd.rep];
|
[_repList addObject: repd->rep];
|
||||||
}
|
}
|
||||||
return _repList;
|
return _repList;
|
||||||
}
|
}
|
||||||
|
@ -1000,10 +1083,9 @@ static NSDictionary* nsmapping = nil;
|
||||||
NSArray *
|
NSArray *
|
||||||
iterate_reps_for_types(NSArray* imageReps, SEL method)
|
iterate_reps_for_types(NSArray* imageReps, SEL method)
|
||||||
{
|
{
|
||||||
NSImageRep *rep;
|
NSImageRep *rep;
|
||||||
id e;
|
NSEnumerator *e;
|
||||||
// int i, count;
|
NSMutableArray *types;
|
||||||
NSMutableArray* types;
|
|
||||||
|
|
||||||
types = [NSMutableArray arrayWithCapacity: 2];
|
types = [NSMutableArray arrayWithCapacity: 2];
|
||||||
|
|
||||||
|
|
|
@ -279,17 +279,27 @@ static NSMutableArray* imageReps = NULL;
|
||||||
// Drawing the Image
|
// Drawing the Image
|
||||||
- (BOOL) draw
|
- (BOOL) draw
|
||||||
{
|
{
|
||||||
[self subclassResponsibility: _cmd];
|
return YES; /* Subclass should implement this. */
|
||||||
return NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) drawAtPoint: (NSPoint)aPoint
|
- (BOOL) drawAtPoint: (NSPoint)aPoint
|
||||||
{
|
{
|
||||||
return NO;
|
NSRect r;
|
||||||
|
|
||||||
|
if (aPoint.x == 0 && aPoint.y == 0)
|
||||||
|
return [self draw];
|
||||||
|
r.origin = aPoint;
|
||||||
|
r.size = size;
|
||||||
|
return [self drawInRect: r];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) drawInRect: (NSRect)aRect
|
- (BOOL) drawInRect: (NSRect)aRect
|
||||||
{
|
{
|
||||||
|
float x, y;
|
||||||
|
|
||||||
|
if (size.height == 0 || size.width == 0)
|
||||||
|
return NO;
|
||||||
|
/* FIXME - should scale and move as necessary. */
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,51 +43,29 @@
|
||||||
#include <Foundation/NSException.h>
|
#include <Foundation/NSException.h>
|
||||||
#include <Foundation/NSProcessInfo.h>
|
#include <Foundation/NSProcessInfo.h>
|
||||||
#include <Foundation/NSFileManager.h>
|
#include <Foundation/NSFileManager.h>
|
||||||
|
#include <Foundation/NSNotificationQueue.h>
|
||||||
|
|
||||||
#define stringify_it(X) #X
|
#define stringify_it(X) #X
|
||||||
#define mkpath(X) stringify_it(X) "/Tools"
|
#define mkpath(X) stringify_it(X) "/Tools"
|
||||||
|
|
||||||
static NSDictionary *applications = nil;
|
|
||||||
|
|
||||||
|
|
||||||
@implementation NSWorkspace
|
@implementation NSWorkspace
|
||||||
|
|
||||||
static NSWorkspace *sharedWorkspace = nil;
|
static NSWorkspace *sharedWorkspace = nil;
|
||||||
static NSNotificationCenter *workspaceCenter = nil;
|
static NSNotificationCenter *workspaceCenter = nil;
|
||||||
|
static NSMutableDictionary *iconMap = nil;
|
||||||
static BOOL userDefaultsChanged = NO;
|
static BOOL userDefaultsChanged = NO;
|
||||||
|
|
||||||
static NSString *appListName = @".GNUstepAppList";
|
static NSString *appListName = @"Services/.GNUstepAppList";
|
||||||
static NSString *appListPath = nil;
|
static NSString *appListPath = nil;
|
||||||
static NSDictionary *_suffixes = nil;
|
static NSDictionary *applications = nil;
|
||||||
static NSString *defaultIconPath = nil;
|
|
||||||
|
static NSString *extPrefName = @".GNUstepExtPrefs";
|
||||||
|
static NSString *extPrefPath = nil;
|
||||||
|
static NSDictionary *extPreferences = nil;
|
||||||
|
|
||||||
static NSString *_rootPath = @"/";
|
static NSString *_rootPath = @"/";
|
||||||
|
|
||||||
|
|
||||||
static NSString* gnustep_target_dir =
|
|
||||||
#ifdef GNUSTEP_TARGET_DIR
|
|
||||||
@GNUSTEP_TARGET_DIR;
|
|
||||||
#else
|
|
||||||
nil;
|
|
||||||
#endif
|
|
||||||
static NSString* gnustep_target_cpu =
|
|
||||||
#ifdef GNUSTEP_TARGET_CPU
|
|
||||||
@GNUSTEP_TARGET_CPU;
|
|
||||||
#else
|
|
||||||
nil;
|
|
||||||
#endif
|
|
||||||
static NSString* gnustep_target_os =
|
|
||||||
#ifdef GNUSTEP_TARGET_OS
|
|
||||||
@GNUSTEP_TARGET_OS;
|
|
||||||
#else
|
|
||||||
nil;
|
|
||||||
#endif
|
|
||||||
static NSString* library_combo =
|
|
||||||
#ifdef LIBRARY_COMBO
|
|
||||||
@LIBRARY_COMBO;
|
|
||||||
#else
|
|
||||||
nil;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Class methods
|
// Class methods
|
||||||
//
|
//
|
||||||
|
@ -97,6 +75,9 @@ static NSString* library_combo =
|
||||||
{
|
{
|
||||||
static BOOL beenHere;
|
static BOOL beenHere;
|
||||||
NSDictionary *env;
|
NSDictionary *env;
|
||||||
|
NSString *home;
|
||||||
|
NSData *data;
|
||||||
|
NSDictionary *dict;
|
||||||
|
|
||||||
// Initial version
|
// Initial version
|
||||||
[self setVersion: 1];
|
[self setVersion: 1];
|
||||||
|
@ -111,49 +92,44 @@ static NSString* library_combo =
|
||||||
beenHere = YES;
|
beenHere = YES;
|
||||||
|
|
||||||
workspaceCenter = [NSNotificationCenter new];
|
workspaceCenter = [NSNotificationCenter new];
|
||||||
|
iconMap = [NSMutableDictionary new];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The home directory for per-user information is given by
|
||||||
|
* the GNUSTEP_USER_ROOT environment variable, or is assumed
|
||||||
|
* to be the 'GNUstep' subdirectory of the users home directory.
|
||||||
|
*/
|
||||||
env = [[NSProcessInfo processInfo] environment];
|
env = [[NSProcessInfo processInfo] environment];
|
||||||
if (env)
|
if (!env || !(home = [env objectForKey: @"GNUSTEP_USER_ROOT"]))
|
||||||
{
|
{
|
||||||
NSString *str;
|
home = [NSString stringWithFormat: @"%@/GNUstep", NSHomeDirectory()];
|
||||||
NSData *data;
|
|
||||||
NSDictionary *newApps;
|
|
||||||
|
|
||||||
str = [env objectForKey: @"GNUSTEP_USER_ROOT"];
|
|
||||||
if (str == nil)
|
|
||||||
str = [NSString stringWithFormat: @"%@/GNUstep",
|
|
||||||
NSHomeDirectory()];
|
|
||||||
str = [str stringByAppendingPathComponent: @"Services"];
|
|
||||||
str = [str stringByAppendingPathComponent: appListName];
|
|
||||||
appListPath = [str retain];
|
|
||||||
|
|
||||||
if ((str = [env objectForKey: @"GNUSTEP_TARGET_DIR"]) != nil)
|
|
||||||
gnustep_target_dir = [str retain];
|
|
||||||
else if ((str = [env objectForKey: @"GNUSTEP_HOST_DIR"]) != nil)
|
|
||||||
gnustep_target_dir = [str retain];
|
|
||||||
|
|
||||||
if ((str = [env objectForKey: @"GNUSTEP_TARGET_CPU"]) != nil)
|
|
||||||
gnustep_target_cpu = [str retain];
|
|
||||||
else if ((str = [env objectForKey: @"GNUSTEP_HOST_CPU"]) != nil)
|
|
||||||
gnustep_target_cpu = [str retain];
|
|
||||||
|
|
||||||
if ((str = [env objectForKey: @"GNUSTEP_TARGET_OS"]) != nil)
|
|
||||||
gnustep_target_os = [str retain];
|
|
||||||
else if ((str = [env objectForKey: @"GNUSTEP_HOST_OS"]) != nil)
|
|
||||||
gnustep_target_os = [str retain];
|
|
||||||
|
|
||||||
if ((str = [env objectForKey: @"LIBRARY_COMBO"]) != nil)
|
|
||||||
library_combo = [str retain];
|
|
||||||
|
|
||||||
data = [NSData dataWithContentsOfFile: appListPath];
|
|
||||||
if (data)
|
|
||||||
newApps = [NSDeserializer deserializePropertyListFromData: data
|
|
||||||
mutableContainers: NO];
|
|
||||||
applications = [newApps retain];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_suffixes = [NSDictionary dictionaryWithContentsOfFile:@"Suffixes.plist"];
|
/*
|
||||||
_suffixes = [_suffixes retain];
|
* Load file extension preferences.
|
||||||
defaultIconPath = [_suffixes objectForKey: @"ICON_PATH"];
|
*/
|
||||||
|
extPrefPath = [home stringByAppendingPathComponent: extPrefName];
|
||||||
|
[extPrefPath retain];
|
||||||
|
data = [NSData dataWithContentsOfFile: extPrefPath];
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
dict = [NSDeserializer deserializePropertyListFromData: data
|
||||||
|
mutableContainers: NO];
|
||||||
|
extPreferences = [dict retain];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Load cached application information.
|
||||||
|
*/
|
||||||
|
appListPath = [home stringByAppendingPathComponent: appListName];
|
||||||
|
[appListPath retain];
|
||||||
|
data = [NSData dataWithContentsOfFile: appListPath];
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
dict = [NSDeserializer deserializePropertyListFromData: data
|
||||||
|
mutableContainers: NO];
|
||||||
|
applications = [dict retain];
|
||||||
|
}
|
||||||
|
|
||||||
[gnustep_global_lock unlock];
|
[gnustep_global_lock unlock];
|
||||||
}
|
}
|
||||||
|
@ -179,31 +155,46 @@ static NSString* library_combo =
|
||||||
sharedWorkspace =
|
sharedWorkspace =
|
||||||
(NSWorkspace*)NSAllocateObject(self, 0, NSDefaultMallocZone());
|
(NSWorkspace*)NSAllocateObject(self, 0, NSDefaultMallocZone());
|
||||||
|
|
||||||
|
[NSNotificationCenter addObserver: sharedWorkspace
|
||||||
|
selector: @selector(noteUserDefaultsChanged)
|
||||||
|
name: NSUserDefaultsDidChangeNotification
|
||||||
|
object: nil];
|
||||||
}
|
}
|
||||||
[gnustep_global_lock unlock];
|
[gnustep_global_lock unlock];
|
||||||
}
|
}
|
||||||
return sharedWorkspace;
|
return sharedWorkspace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NSImage*
|
||||||
|
extIconForApp(NSWorkspace *ws, NSString *appName, NSDictionary *typeInfo)
|
||||||
|
{
|
||||||
|
NSString *file = [typeInfo objectForKey: @"NSIcon"];
|
||||||
|
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
if ([file isAbsolutePath] == NO)
|
||||||
|
{
|
||||||
|
NSString *path;
|
||||||
|
|
||||||
|
path = [ws fullPathForApplication: appName];
|
||||||
|
file = [path stringByAppendingString: file];
|
||||||
|
}
|
||||||
|
if ([[NSFileManager defaultManager] isReadableFileAtPath: file] == YES)
|
||||||
|
{
|
||||||
|
return [[[NSImage alloc] initWithContentsOfFile: file] autorelease];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSImage*) _getImageWithName: (NSString *)name
|
- (NSImage*) _getImageWithName: (NSString *)name
|
||||||
alternate: (NSString *)alternate
|
alternate: (NSString *)alternate
|
||||||
{
|
{
|
||||||
NSString *iconName = nil;
|
|
||||||
NSImage *image = nil;
|
NSImage *image = nil;
|
||||||
|
|
||||||
iconName = (NSString *)[_suffixes objectForKey: name];
|
image = [NSImage imageNamed: name];
|
||||||
if (iconName != nil)
|
if (image == nil)
|
||||||
{
|
image = [NSImage imageNamed: alternate];
|
||||||
NSString *iconPath;
|
|
||||||
|
|
||||||
iconPath = [defaultIconPath stringByAppendingPathComponent: iconName];
|
|
||||||
image = [[NSImage alloc] initWithContentsOfFile: iconPath];
|
|
||||||
}
|
|
||||||
if ((image == nil) && (alternate != nil))
|
|
||||||
{
|
|
||||||
image = [[NSImage imageNamed: alternate] retain]; // !!! was retained
|
|
||||||
}
|
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,8 +205,8 @@ static NSString* library_combo =
|
||||||
|
|
||||||
if (image == nil)
|
if (image == nil)
|
||||||
{
|
{
|
||||||
image = [self _getImageWithName: @"FOLDER_ICON"
|
image = [[self _getImageWithName: @"Folder.tiff"
|
||||||
alternate: @"Folder.tiff"];
|
alternate: @"common_Folder.tiff"] retain];
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
@ -228,8 +219,8 @@ static NSString* library_combo =
|
||||||
|
|
||||||
if (image == nil)
|
if (image == nil)
|
||||||
{
|
{
|
||||||
image = [self _getImageWithName: @"UNKNOWN_ICON"
|
image = [[self _getImageWithName: @"Unknown.tiff"
|
||||||
alternate: @"Unknown"];
|
alternate: @"common_Unknown.tiff"] retain];
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
|
@ -242,13 +233,222 @@ static NSString* library_combo =
|
||||||
|
|
||||||
if (image == nil)
|
if (image == nil)
|
||||||
{
|
{
|
||||||
image = [self _getImageWithName: @"ROOT_ICON"
|
image = [[self _getImageWithName: @"Root_PC.tiff"
|
||||||
alternate: @"Unknown"];
|
alternate: @"common_Root_PC.tiff"] retain];
|
||||||
}
|
}
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSImage*) _iconForExtension: (NSString*)ext
|
||||||
|
{
|
||||||
|
NSImage *icon = nil;
|
||||||
|
|
||||||
|
if (ext == nil || [ext isEqualToString: @""])
|
||||||
|
return nil;
|
||||||
|
/*
|
||||||
|
* extensions are case-insensitive - convert to lowercase.
|
||||||
|
*/
|
||||||
|
ext = [ext lowercaseString];
|
||||||
|
if ((icon = [iconMap objectForKey: ext]) == nil)
|
||||||
|
{
|
||||||
|
NSDictionary *prefs;
|
||||||
|
NSDictionary *extInfo;
|
||||||
|
NSString *iconPath;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there is a user-specified preference for an image -
|
||||||
|
* try to use that one.
|
||||||
|
*/
|
||||||
|
prefs = [extPreferences objectForKey: ext];
|
||||||
|
iconPath = [prefs objectForKey: @"Icon"];
|
||||||
|
if (iconPath)
|
||||||
|
{
|
||||||
|
icon = [[NSImage alloc] initWithContentsOfFile: iconPath];
|
||||||
|
[icon autorelease];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (icon == nil && (extInfo = [self infoForExtension: ext]) != nil)
|
||||||
|
{
|
||||||
|
NSDictionary *typeInfo;
|
||||||
|
NSString *appName;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there are any application preferences given, try to use the
|
||||||
|
* icon for this file that is used by the preferred app.
|
||||||
|
*/
|
||||||
|
if (prefs)
|
||||||
|
{
|
||||||
|
if ((appName = [extInfo objectForKey: @"Editor"]) != nil)
|
||||||
|
{
|
||||||
|
typeInfo = [extInfo objectForKey: appName];
|
||||||
|
icon = extIconForApp(self, appName, typeInfo);
|
||||||
|
}
|
||||||
|
if (icon == nil
|
||||||
|
&& (appName = [extInfo objectForKey: @"Viewer"]) != nil)
|
||||||
|
{
|
||||||
|
typeInfo = [extInfo objectForKey: appName];
|
||||||
|
icon = extIconForApp(self, appName, typeInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (icon == nil)
|
||||||
|
{
|
||||||
|
NSEnumerator *enumerator;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Still no icon - try all the apps that handle this file
|
||||||
|
* extension.
|
||||||
|
*/
|
||||||
|
enumerator = [extInfo keyEnumerator];
|
||||||
|
while (icon == nil && (appName = [enumerator nextObject]) != nil)
|
||||||
|
{
|
||||||
|
typeInfo = [extInfo objectForKey: appName];
|
||||||
|
icon = extIconForApp(self, appName, typeInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (icon == nil)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nothing found at all - use the unknowntype icon.
|
||||||
|
*/
|
||||||
|
if (icon == nil)
|
||||||
|
{
|
||||||
|
icon = [self unknownFiletypeImage];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the icon in the cache for next time.
|
||||||
|
*/
|
||||||
|
if (icon != nil)
|
||||||
|
[iconMap setObject: icon forKey: ext];
|
||||||
|
}
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) _extension: (NSString*)ext
|
||||||
|
role: (NSString*)role
|
||||||
|
app: (NSString**)app
|
||||||
|
andInfo: (NSDictionary**)inf
|
||||||
|
{
|
||||||
|
NSEnumerator *enumerator;
|
||||||
|
NSString *appName = nil;
|
||||||
|
NSDictionary *apps;
|
||||||
|
NSDictionary *prefs;
|
||||||
|
NSDictionary *info;
|
||||||
|
|
||||||
|
ext = [ext lowercaseString];
|
||||||
|
apps = [self infoForExtension: ext];
|
||||||
|
if (apps == nil || [apps count] == 0)
|
||||||
|
return NO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look for the name of the preferred app in this role.
|
||||||
|
* A 'nil' roll is a wildcard - find the preferred Editor or Viewer.
|
||||||
|
*/
|
||||||
|
prefs = [extPreferences objectForKey: ext];
|
||||||
|
|
||||||
|
if (role == nil || [role isEqualToString: @"Editor"])
|
||||||
|
{
|
||||||
|
appName = [prefs objectForKey: @"Editor"];
|
||||||
|
if (appName)
|
||||||
|
{
|
||||||
|
info = [apps objectForKey: appName];
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
if (app)
|
||||||
|
*app = appName;
|
||||||
|
if (inf)
|
||||||
|
*inf = info;
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (role == nil || [role isEqualToString: @"Viewer"])
|
||||||
|
{
|
||||||
|
appName = [prefs objectForKey: @"Viewer"];
|
||||||
|
if (appName)
|
||||||
|
{
|
||||||
|
info = [apps objectForKey: appName];
|
||||||
|
if (info)
|
||||||
|
{
|
||||||
|
if (app)
|
||||||
|
*app = appName;
|
||||||
|
if (inf)
|
||||||
|
*inf = info;
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Go through the dictionary of apps that know about this file type and
|
||||||
|
* determine the best application to open the file by examining the
|
||||||
|
* type information for each app.
|
||||||
|
* The 'NSRole' field specifies what the app can do with the file - if it
|
||||||
|
* is missing, we assume an 'Editor' role.
|
||||||
|
*/
|
||||||
|
enumerator = [apps keyEnumerator];
|
||||||
|
|
||||||
|
if (role == nil)
|
||||||
|
{
|
||||||
|
BOOL found = NO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the requested role is 'nil', we can accept an app that is either
|
||||||
|
* an Editor (preferred) or a Viewer.
|
||||||
|
*/
|
||||||
|
while ((appName = [enumerator nextObject]) != nil)
|
||||||
|
{
|
||||||
|
NSString *str;
|
||||||
|
|
||||||
|
info = [apps objectForKey: appName];
|
||||||
|
str = [info objectForKey: @"NSRole"];
|
||||||
|
if (str == nil || [str isEqualToString: @"Editor"])
|
||||||
|
{
|
||||||
|
if (app)
|
||||||
|
*app = appName;
|
||||||
|
if (inf)
|
||||||
|
*inf = info;
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
else if ([str isEqualToString: @"Viewer"])
|
||||||
|
{
|
||||||
|
if (app)
|
||||||
|
*app = appName;
|
||||||
|
if (inf)
|
||||||
|
*inf = info;
|
||||||
|
found = YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while ((appName = [enumerator nextObject]) != nil)
|
||||||
|
{
|
||||||
|
NSString *str;
|
||||||
|
|
||||||
|
info = [apps objectForKey: appName];
|
||||||
|
str = [info objectForKey: @"NSRole"];
|
||||||
|
if ((str == nil && [role isEqualToString: @"Editor"])
|
||||||
|
|| [str isEqualToString: role])
|
||||||
|
{
|
||||||
|
if (app)
|
||||||
|
*app = appName;
|
||||||
|
if (inf)
|
||||||
|
*inf = info;
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Instance methods
|
// Instance methods
|
||||||
|
@ -272,21 +472,9 @@ static NSString* library_combo =
|
||||||
- (BOOL) openFile: (NSString *)fullPath
|
- (BOOL) openFile: (NSString *)fullPath
|
||||||
{
|
{
|
||||||
NSString *ext = [fullPath pathExtension];
|
NSString *ext = [fullPath pathExtension];
|
||||||
NSDictionary *map;
|
|
||||||
NSArray *apps;
|
|
||||||
NSString *appName;
|
NSString *appName;
|
||||||
|
|
||||||
/*
|
if ([self _extension: ext role: nil app: &appName andInfo: 0] == NO)
|
||||||
* Get the applications cache (generated by the make_services tool)
|
|
||||||
* and lookup the special entry that contains a dictionary of all
|
|
||||||
* file extensions recognised by GNUstep applications. Then find
|
|
||||||
* the array of applications that can handle our file.
|
|
||||||
*/
|
|
||||||
if (applications == nil)
|
|
||||||
[self findApplications];
|
|
||||||
map = [applications objectForKey: @"GSExtensionsMap"];
|
|
||||||
apps = [map objectForKey: ext];
|
|
||||||
if (apps == nil || [apps count] == 0)
|
|
||||||
{
|
{
|
||||||
NSRunAlertPanel(nil,
|
NSRunAlertPanel(nil,
|
||||||
[NSString stringWithFormat:
|
[NSString stringWithFormat:
|
||||||
|
@ -295,9 +483,6 @@ static NSString* library_combo =
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME - need a mechanism for determining default application */
|
|
||||||
appName = [apps objectAtIndex: 0];
|
|
||||||
|
|
||||||
return [self openFile: fullPath withApplication: appName];
|
return [self openFile: fullPath withApplication: appName];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,10 +554,10 @@ static NSString* library_combo =
|
||||||
// Manipulating Files
|
// Manipulating Files
|
||||||
//
|
//
|
||||||
- (BOOL) performFileOperation: (NSString *)operation
|
- (BOOL) performFileOperation: (NSString *)operation
|
||||||
source: (NSString *)source
|
source: (NSString *)source
|
||||||
destination: (NSString *)destination
|
destination: (NSString *)destination
|
||||||
files: (NSArray *)files
|
files: (NSArray *)files
|
||||||
tag: (int *)tag
|
tag: (int *)tag
|
||||||
{
|
{
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
@ -428,45 +613,64 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
|
||||||
NSImage *image = nil;
|
NSImage *image = nil;
|
||||||
BOOL isDir = NO;
|
BOOL isDir = NO;
|
||||||
NSString *iconPath = nil;
|
NSString *iconPath = nil;
|
||||||
NSString *pathExtension = nil;
|
NSString *pathExtension = [[aPath pathExtension] lowercaseString];
|
||||||
NSFileManager *mgr = [NSFileManager defaultManager];
|
NSFileManager *mgr = [NSFileManager defaultManager];
|
||||||
|
|
||||||
if ([mgr fileExistsAtPath: aPath isDirectory: &isDir] && isDir)
|
if ([mgr fileExistsAtPath: aPath isDirectory: &isDir] && isDir)
|
||||||
{
|
{
|
||||||
// we have a directory
|
if ([pathExtension isEqualToString: @"app"]
|
||||||
iconPath = [aPath stringByAppendingPathComponent: @".dir.tiff"];
|
|| [pathExtension isEqualToString: @"debug"]
|
||||||
|
|| [pathExtension isEqualToString: @"profile"])
|
||||||
NSLog(@"iconPath is '%@'", iconPath);
|
|
||||||
|
|
||||||
NS_DURING
|
|
||||||
{
|
{
|
||||||
image = [[NSImage alloc] initWithContentsOfFile: iconPath];
|
NSBundle *bundle;
|
||||||
[image autorelease];
|
|
||||||
}
|
|
||||||
NS_HANDLER
|
|
||||||
{
|
|
||||||
NSLog(@"BAD TIFF FILE '%@'", iconPath);
|
|
||||||
}
|
|
||||||
NS_ENDHANDLER
|
|
||||||
|
|
||||||
NSLog(@"aPath is '%@'", aPath);
|
bundle = [NSBundle bundleWithPath: aPath];
|
||||||
|
iconPath = [[bundle infoDictionary] objectForKey: @"NSIcon"];
|
||||||
|
if (iconPath && [iconPath isAbsolutePath] == NO)
|
||||||
if (((!image)
|
|
||||||
&& (pathExtension = [aPath pathExtension]))
|
|
||||||
&& ([pathExtension isEqual: @""] == NO))
|
|
||||||
{
|
|
||||||
if ((iconPath = [[_suffixes objectForKey: pathExtension]
|
|
||||||
objectForKey: @"ICON"]) != nil)
|
|
||||||
{
|
{
|
||||||
NSLog(@"using '%@'",
|
iconPath = [aPath stringByAppendingPathComponent: iconPath];
|
||||||
[defaultIconPath stringByAppendingPathComponent: iconPath]);
|
}
|
||||||
|
/*
|
||||||
|
* If there is no icon specified in the Info.plist for app
|
||||||
|
* try 'wrapper/app.tiff' and 'wrapper/.dir.tiff' as
|
||||||
|
* possible locations for the application icon.
|
||||||
|
*/
|
||||||
|
if (iconPath == nil)
|
||||||
|
{
|
||||||
|
NSString *str;
|
||||||
|
|
||||||
image = [[NSImage alloc] initWithContentsOfFile:
|
str = [[aPath lastPathComponent] stringByDeletingPathExtension];
|
||||||
[defaultIconPath stringByAppendingPathComponent: iconPath]];
|
iconPath = [aPath stringByAppendingPathComponent: str];
|
||||||
[image autorelease];
|
iconPath = [iconPath stringByAppendingPathExtension: @"tiff"];
|
||||||
|
if ([mgr isReadableFileAtPath: iconPath] == NO)
|
||||||
|
{
|
||||||
|
str = @".dir.tiff";
|
||||||
|
iconPath = [aPath stringByAppendingPathComponent: str];
|
||||||
|
if ([mgr isReadableFileAtPath: iconPath] == NO)
|
||||||
|
iconPath = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iconPath)
|
||||||
|
{
|
||||||
|
NS_DURING
|
||||||
|
{
|
||||||
|
image = [[NSImage alloc] initWithContentsOfFile: iconPath];
|
||||||
|
[image autorelease];
|
||||||
|
}
|
||||||
|
NS_HANDLER
|
||||||
|
{
|
||||||
|
NSLog(@"BAD TIFF FILE '%@'", iconPath);
|
||||||
|
}
|
||||||
|
NS_ENDHANDLER
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (image == nil)
|
||||||
|
{
|
||||||
|
image = [self _iconForExtension: pathExtension];
|
||||||
|
}
|
||||||
|
|
||||||
if (image == nil)
|
if (image == nil)
|
||||||
{
|
{
|
||||||
if ([aPath isEqual: _rootPath])
|
if ([aPath isEqual: _rootPath])
|
||||||
|
@ -475,23 +679,11 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
|
||||||
image= [self folderImage];
|
image= [self folderImage];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // not a directory
|
else
|
||||||
{
|
{
|
||||||
if (((!image) && (pathExtension = [aPath pathExtension]))
|
NSDebugLog(@"pathExtension is '%@'", pathExtension);
|
||||||
&& ([pathExtension isEqual: @""] == NO))
|
|
||||||
{
|
|
||||||
NSLog(@"pathExtension is '%@'",pathExtension);
|
|
||||||
if ((iconPath = [[_suffixes objectForKey: pathExtension]
|
|
||||||
objectForKey: @"ICON"]) != nil)
|
|
||||||
{
|
|
||||||
NSLog(@"using '%@'",
|
|
||||||
[defaultIconPath stringByAppendingPathComponent: iconPath]);
|
|
||||||
|
|
||||||
image = [[NSImage alloc] initWithContentsOfFile:
|
image = [self _iconForExtension: pathExtension];
|
||||||
[defaultIconPath stringByAppendingPathComponent: iconPath]];
|
|
||||||
[image autorelease];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image == nil)
|
if (image == nil)
|
||||||
|
@ -538,7 +730,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
|
||||||
{
|
{
|
||||||
static NSString *path = nil;
|
static NSString *path = nil;
|
||||||
NSData *data;
|
NSData *data;
|
||||||
NSDictionary *newApps;
|
NSDictionary *dict;
|
||||||
NSTask *task;
|
NSTask *task;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -552,14 +744,25 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
|
||||||
if (task != nil)
|
if (task != nil)
|
||||||
[task waitUntilExit];
|
[task waitUntilExit];
|
||||||
|
|
||||||
|
data = [NSData dataWithContentsOfFile: extPrefPath];
|
||||||
|
if (data)
|
||||||
|
{
|
||||||
|
dict = [NSDeserializer deserializePropertyListFromData: data
|
||||||
|
mutableContainers: NO];
|
||||||
|
ASSIGN(extPreferences, dict);
|
||||||
|
}
|
||||||
|
|
||||||
data = [NSData dataWithContentsOfFile: appListPath];
|
data = [NSData dataWithContentsOfFile: appListPath];
|
||||||
if (data)
|
if (data)
|
||||||
newApps = [NSDeserializer deserializePropertyListFromData: data
|
{
|
||||||
mutableContainers: NO];
|
dict = [NSDeserializer deserializePropertyListFromData: data
|
||||||
else
|
mutableContainers: NO];
|
||||||
newApps = [NSDictionary dictionary];
|
ASSIGN(applications, dict);
|
||||||
|
}
|
||||||
ASSIGN(applications, newApps);
|
/*
|
||||||
|
* Invalidate the cache of icons for file extensions.
|
||||||
|
*/
|
||||||
|
[iconMap removeAllObjects];
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -674,6 +877,7 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
|
||||||
- (void) noteUserDefaultsChanged
|
- (void) noteUserDefaultsChanged
|
||||||
{
|
{
|
||||||
userDefaultsChanged = YES;
|
userDefaultsChanged = YES;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) userDefaultsChanged
|
- (BOOL) userDefaultsChanged
|
||||||
|
@ -702,3 +906,141 @@ inFileViewerRootedAtPath: (NSString *)rootFullpath
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@implementation NSWorkspace (GNUstep)
|
||||||
|
|
||||||
|
- (NSString*) getBestAppInRole: (NSString*)role
|
||||||
|
forExtension: (NSString*)ext
|
||||||
|
{
|
||||||
|
NSString *appName = nil;
|
||||||
|
|
||||||
|
if (extPreferences != nil)
|
||||||
|
{
|
||||||
|
NSDictionary *inf;
|
||||||
|
|
||||||
|
inf = [extPreferences objectForKey: [ext lowercaseString]];
|
||||||
|
if (inf != nil)
|
||||||
|
{
|
||||||
|
if (role == nil)
|
||||||
|
{
|
||||||
|
appName = [inf objectForKey: @"Editor"];
|
||||||
|
if (appName == nil)
|
||||||
|
appName = [inf objectForKey: @"Viewer"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
appName = [inf objectForKey: role];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString*) getBestIconForExtension: (NSString*)ext
|
||||||
|
{
|
||||||
|
NSString *iconPath = nil;
|
||||||
|
|
||||||
|
if (extPreferences != nil)
|
||||||
|
{
|
||||||
|
NSDictionary *inf;
|
||||||
|
|
||||||
|
inf = [extPreferences objectForKey: [ext lowercaseString]];
|
||||||
|
if (inf != nil)
|
||||||
|
iconPath = [inf objectForKey: @"Icon"];
|
||||||
|
}
|
||||||
|
return iconPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary*) infoForExtension: (NSString*)ext
|
||||||
|
{
|
||||||
|
NSDictionary *map;
|
||||||
|
|
||||||
|
ext = [ext lowercaseString];
|
||||||
|
/*
|
||||||
|
* Get the applications cache (generated by the make_services tool)
|
||||||
|
* and lookup the special entry that contains a dictionary of all
|
||||||
|
* file extensions recognised by GNUstep applications. Then find
|
||||||
|
* the dictionary of applications that can handle our file.
|
||||||
|
*/
|
||||||
|
if (applications == nil)
|
||||||
|
[self findApplications];
|
||||||
|
map = [applications objectForKey: @"GSExtensionsMap"];
|
||||||
|
return [map objectForKey: ext];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setBestApp: (NSString*)appName
|
||||||
|
inRole: (NSString*)role
|
||||||
|
forExtension: (NSString*)ext
|
||||||
|
{
|
||||||
|
NSMutableDictionary *map;
|
||||||
|
NSMutableDictionary *inf;
|
||||||
|
NSData *data;
|
||||||
|
|
||||||
|
ext = [ext lowercaseString];
|
||||||
|
if (extPreferences)
|
||||||
|
map = [extPreferences mutableCopy];
|
||||||
|
else
|
||||||
|
map = [NSMutableDictionary new];
|
||||||
|
|
||||||
|
inf = [[map objectForKey: ext] mutableCopy];
|
||||||
|
if (inf == nil)
|
||||||
|
{
|
||||||
|
inf = [NSMutableDictionary new];
|
||||||
|
}
|
||||||
|
if (appName == nil)
|
||||||
|
{
|
||||||
|
if (role == nil)
|
||||||
|
{
|
||||||
|
NSString *iconPath = [inf objectForKey: @"Icon"];
|
||||||
|
|
||||||
|
[iconPath retain];
|
||||||
|
[inf removeAllObjects];
|
||||||
|
if (iconPath)
|
||||||
|
{
|
||||||
|
[inf setObject: iconPath forKey: @"Icon"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[inf removeObjectForKey: role];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[inf setObject: appName forKey: (role ? role : @"Editor")];
|
||||||
|
}
|
||||||
|
[map setObject: inf forKey: ext];
|
||||||
|
[inf release];
|
||||||
|
[extPreferences release];
|
||||||
|
extPreferences = inf;
|
||||||
|
data = [NSSerializer serializePropertyList: extPreferences];
|
||||||
|
[data writeToFile: extPrefPath atomically: YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setBestIcon: (NSString*)iconPath forExtension: (NSString*)ext
|
||||||
|
{
|
||||||
|
NSMutableDictionary *map;
|
||||||
|
NSMutableDictionary *inf;
|
||||||
|
NSData *data;
|
||||||
|
|
||||||
|
ext = [ext lowercaseString];
|
||||||
|
if (extPreferences)
|
||||||
|
map = [extPreferences mutableCopy];
|
||||||
|
else
|
||||||
|
map = [NSMutableDictionary new];
|
||||||
|
|
||||||
|
inf = [[map objectForKey: ext] mutableCopy];
|
||||||
|
if (inf == nil)
|
||||||
|
inf = [NSMutableDictionary new];
|
||||||
|
if (iconPath)
|
||||||
|
[inf setObject: iconPath forKey: @"Icon"];
|
||||||
|
else
|
||||||
|
[inf removeObjectForKey: @"Icon"];
|
||||||
|
[map setObject: inf forKey: ext];
|
||||||
|
[inf release];
|
||||||
|
[extPreferences release];
|
||||||
|
extPreferences = inf;
|
||||||
|
data = [NSSerializer serializePropertyList: extPreferences];
|
||||||
|
[data writeToFile: extPrefPath atomically: YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue