Fixups to avoid crashes opening non-document-based apps.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@28844 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
rfm 2009-10-19 10:03:03 +00:00
parent c8916fd438
commit 51e03c6d17
4 changed files with 267 additions and 201 deletions

View file

@ -3,7 +3,13 @@
* Source/GSThemeTools.m: Fix last changes to compile again (variable * Source/GSThemeTools.m: Fix last changes to compile again (variable
declarations not at startof block only work on some compilers). declarations not at startof block only work on some compilers).
* Source/NSApplication.m: Fixup to show suppressed icon when app is * Source/NSApplication.m: Fixup to show suppressed icon when app is
deactivated. deactivated. Fix uninitialisaed variable causing crashes on failing
to use document controller to open an untitled document.
Drop non-standard method (which didn't work) for determining whether
we have a document based app.
* Source/NSDocumentController.m: Rewrite code for determining
whether the current app is document based. Cache singleton information
in static variables rether than ivars.
2009-10-19 Nicolas Roard <nicolas@roard.com> 2009-10-19 Nicolas Roard <nicolas@roard.com>
* Source/GSTheme.m: * Source/GSTheme.m:

View file

@ -31,7 +31,7 @@
#define _GNUstep_H_NSDocumentController #define _GNUstep_H_NSDocumentController
#import <GNUstepBase/GSVersionMacros.h> #import <GNUstepBase/GSVersionMacros.h>
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
#include <Foundation/NSObject.h> #include <Foundation/NSObject.h>
#include <AppKit/NSNibDeclarations.h> #include <AppKit/NSNibDeclarations.h>
@ -53,7 +53,7 @@
@private @private
NSMutableArray *_documents; NSMutableArray *_documents;
NSMutableArray *_recent_documents; NSMutableArray *_recent_documents;
NSArray *_types; // from info.plist with key NSTypes NSArray *_types; // from info.plist with key NSTypes
NSTimeInterval _autosavingDelay; NSTimeInterval _autosavingDelay;
struct __controller_flags { struct __controller_flags {
unsigned int should_create_ui:1; unsigned int should_create_ui:1;
@ -62,111 +62,129 @@
void *_reserved1; void *_reserved1;
} }
+ (id)sharedDocumentController; + (id) sharedDocumentController;
/*" document creation "*/ /*" document creation "*/
// doesn't create the windowControllers // doesn't create the windowControllers
- (id)makeUntitledDocumentOfType:(NSString *)type; - (id) makeUntitledDocumentOfType: (NSString*)type;
- (id)makeDocumentWithContentsOfFile:(NSString *)fileName ofType:(NSString *)type; - (id) makeDocumentWithContentsOfFile: (NSString*)fileName
ofType: (NSString*)type;
// creates window controllers // creates window controllers
- (id)openUntitledDocumentOfType:(NSString*)type display:(BOOL)display; - (id) openUntitledDocumentOfType: (NSString*)type
- (id)openDocumentWithContentsOfFile:(NSString *)fileName display:(BOOL)display; display: (BOOL)display;
- (id) openDocumentWithContentsOfFile: (NSString*)fileName
display: (BOOL)display;
- (id)makeDocumentWithContentsOfURL:(NSURL *)url ofType:(NSString *)type; - (id) makeDocumentWithContentsOfURL: (NSURL*)url
- (id)openDocumentWithContentsOfURL:(NSURL *)url display:(BOOL)display; ofType: (NSString*)type;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST) - (id) openDocumentWithContentsOfURL: (NSURL*)url
- (id)makeDocumentForURL:(NSURL *)url display: (BOOL)display;
withContentsOfURL:(NSURL *)contents #if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
ofType:(NSString *)type - (id) makeDocumentForURL: (NSURL*)url
error:(NSError **)err; withContentsOfURL: (NSURL*)contents
- (id)makeDocumentWithContentsOfURL:(NSURL *)url ofType: (NSString*)type
ofType:(NSString *)type error: (NSError**)err;
error:(NSError **)err; - (id) makeDocumentWithContentsOfURL: (NSURL*)url
- (id)makeUntitledDocumentOfType:(NSString *)type ofType: (NSString*)type
error:(NSError **)err; error: (NSError**)err;
- (id)openDocumentWithContentsOfURL:(NSURL *) url - (id) makeUntitledDocumentOfType: (NSString*)type
display:(BOOL) flag error: (NSError**)err;
error:(NSError **) err; - (id) openDocumentWithContentsOfURL: (NSURL*)url
- (id)openUntitledDocumentAndDisplay:(BOOL)flag display: (BOOL)flag
error:(NSError **)err; error: (NSError**)err;
- (BOOL)reopenDocumentForURL:(NSURL *)url - (id) openUntitledDocumentAndDisplay: (BOOL)flag
withContentsOfURL:(NSURL *)contents error: (NSError**)err;
error:(NSError **)err; - (BOOL) reopenDocumentForURL: (NSURL*)url
- (BOOL)presentError:(NSError *)err; withContentsOfURL: (NSURL*)contents
- (void)presentError:(NSError *)err error: (NSError**)err;
modalForWindow:(NSWindow *)win - (BOOL) presentError: (NSError*)err;
delegate:(id)delegate - (void) presentError: (NSError*)err
didPresentSelector:(SEL)sel modalForWindow: (NSWindow*)win
contextInfo:(void *)context; delegate: (id)delegate
- (NSError *)willPresentError:(NSError *)err; didPresentSelector: (SEL)sel
contextInfo: (void*)context;
- (NSError*) willPresentError: (NSError*)err;
#endif #endif
/*" With or without UI "*/ /*" With or without UI "*/
- (BOOL)shouldCreateUI; - (BOOL) shouldCreateUI;
- (void)setShouldCreateUI:(BOOL)flag; - (void) setShouldCreateUI: (BOOL)flag;
/*" Actions "*/ /*" Actions "*/
- (IBAction)saveAllDocuments:(id)sender; - (IBAction) saveAllDocuments: (id)sender;
- (IBAction)openDocument:(id)sender; - (IBAction) openDocument: (id)sender;
- (IBAction)newDocument:(id)sender; - (IBAction) newDocument: (id)sender;
- (IBAction)clearRecentDocuments:(id)sender; - (IBAction) clearRecentDocuments: (id)sender;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST) #if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
- (NSUInteger) maximumRecentDocumentCount; - (NSUInteger) maximumRecentDocumentCount;
#endif #endif
/*" Recent Documents "*/ /*" Recent Documents "*/
- (void)noteNewRecentDocument:(NSDocument *)aDocument; - (void) noteNewRecentDocument: (NSDocument*)aDocument;
- (void)noteNewRecentDocumentURL:(NSURL *)anURL; - (void) noteNewRecentDocumentURL: (NSURL*)anURL;
- (NSArray *)recentDocumentURLs; - (NSArray*) recentDocumentURLs;
/*" Open panel "*/ /*" Open panel "*/
- (NSArray *)URLsFromRunningOpenPanel; - (NSArray*) URLsFromRunningOpenPanel;
- (NSArray *)fileNamesFromRunningOpenPanel; - (NSArray*) fileNamesFromRunningOpenPanel;
- (NSInteger)runModalOpenPanel:(NSOpenPanel *)openPanel forTypes:(NSArray *)openableFileExtensions; - (NSInteger) runModalOpenPanel: (NSOpenPanel*)openPanel
forTypes: (NSArray*)openableFileExtensions;
/*" Document management "*/ /*" Document management "*/
- (void)addDocument:(NSDocument *)document; - (void) addDocument: (NSDocument*)document;
- (void)removeDocument:(NSDocument *)document; - (void) removeDocument: (NSDocument*)document;
- (BOOL)closeAllDocuments; - (BOOL) closeAllDocuments;
- (void)closeAllDocumentsWithDelegate:(id)delegate - (void) closeAllDocumentsWithDelegate: (id)delegate
didCloseAllSelector:(SEL)didAllCloseSelector didCloseAllSelector: (SEL)didAllCloseSelector
contextInfo:(void *)contextInfo; contextInfo: (void*)contextInfo;
- (BOOL)reviewUnsavedDocumentsWithAlertTitle:(NSString *)title cancellable:(BOOL)cancellable; - (BOOL) reviewUnsavedDocumentsWithAlertTitle: (NSString*)title
- (void)reviewUnsavedDocumentsWithAlertTitle:(NSString *)title cancellable: (BOOL)cancellable;
cancellable:(BOOL)cancellable - (void) reviewUnsavedDocumentsWithAlertTitle: (NSString*)title
delegate:(id)delegate cancellable: (BOOL)cancellable
didReviewAllSelector:(SEL)didReviewAllSelector delegate: (id)delegate
contextInfo:(void *)contextInfo; didReviewAllSelector: (SEL)didReviewAllSelector
- (NSArray *)documents; contextInfo: (void*)contextInfo;
- (BOOL)hasEditedDocuments; - (NSArray*) documents;
- (id)currentDocument; - (BOOL) hasEditedDocuments;
- (NSString *)currentDirectory; - (id) currentDocument;
- (id)documentForWindow:(NSWindow *)window; - (NSString*) currentDirectory;
- (id)documentForFileName:(NSString *)fileName; - (id) documentForWindow: (NSWindow*)window;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST) - (id) documentForFileName: (NSString*)fileName;
- (id)documentForURL:(NSURL *)url; #if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
- (id) documentForURL: (NSURL*)url;
#endif #endif
/*" Menu validation "*/ /*" Menu validation "*/
- (BOOL)validateMenuItem:(NSMenuItem *)anItem; - (BOOL) validateMenuItem: (NSMenuItem*)anItem;
- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem; - (BOOL) validateUserInterfaceItem: (id <NSValidatedUserInterfaceItem>)anItem;
/*" Types and extensions "*/ /*" Types and extensions "*/
- (NSString *)displayNameForType:(NSString *)type; - (NSString*) displayNameForType: (NSString*)type;
- (NSString *)typeFromFileExtension:(NSString *)fileExtension; - (NSString*) typeFromFileExtension: (NSString*)fileExtension;
- (NSArray *)fileExtensionsFromType:(NSString *)type; - (NSArray*) fileExtensionsFromType: (NSString*)type;
- (Class)documentClassForType:(NSString *)type; - (Class) documentClassForType: (NSString*)type;
#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
- (NSString *)defaultType; #if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
- (NSArray *)documentClassNames; /** Returns the first type found for which the application has an editor
- (NSString *)typeForContentsOfURL:(NSURL *)url error:(NSError **)err; * role.
*/
- (NSString*) defaultType;
/** Returns the names of the NSDocument subclasses handling documents
* in this application. This will be nil or empty if this is not a document
* based application.
*/
- (NSArray*) documentClassNames;
- (NSString*) typeForContentsOfURL: (NSURL*)url
error: (NSError**)err;
#endif #endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST) #if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
/* Autosaving */ /* Autosaving */
- (NSTimeInterval)autosavingDelay; - (NSTimeInterval) autosavingDelay;
- (void)setAutosavingDelay:(NSTimeInterval)autosavingDelay; - (void) setAutosavingDelay: (NSTimeInterval)autosavingDelay;
#endif #endif
@end @end

View file

@ -365,10 +365,6 @@ struct _NSModalSession {
NSModalSession previous; NSModalSession previous;
}; };
@interface NSDocumentController (ApplicationPrivate)
+ (BOOL) isDocumentBasedApplication;
@end
@interface NSApplication (Private) @interface NSApplication (Private)
- _appIconInit; - _appIconInit;
- (NSDictionary*) _notificationUserInfo; - (NSDictionary*) _notificationUserInfo;
@ -950,6 +946,7 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
{ {
NSBundle *mainBundle = [NSBundle mainBundle]; NSBundle *mainBundle = [NSBundle mainBundle];
NSDictionary *infoDict = [mainBundle infoDictionary]; NSDictionary *infoDict = [mainBundle infoDictionary];
NSDocumentController *sdc;
NSString *mainModelFile; NSString *mainModelFile;
NSString *appIconFile; NSString *appIconFile;
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults]; NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
@ -1104,11 +1101,10 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
* Instantiate the NSDocumentController if we are a doc-based app * Instantiate the NSDocumentController if we are a doc-based app
* and eventually reopen all autosaved documents * and eventually reopen all autosaved documents
*/ */
if ([NSDocumentController isDocumentBasedApplication]) sdc = [NSDocumentController sharedDocumentController];
if ([[sdc documentClassNames] count] > 0)
{ {
didAutoreopen = didAutoreopen = [sdc _reopenAutosavedDocuments];
[[NSDocumentController sharedDocumentController]
_reopenAutosavedDocuments];
} }
/* /*
@ -1135,23 +1131,21 @@ static NSSize scaledIconSizeForSize(NSSize imageSize)
@selector(applicationShouldOpenUntitledFile:)]) @selector(applicationShouldOpenUntitledFile:)])
{ {
if ([_delegate applicationShouldOpenUntitledFile: self] if ([_delegate applicationShouldOpenUntitledFile: self]
&& [_delegate respondsToSelector: && [_delegate respondsToSelector:
@selector(applicationOpenUntitledFile:)]) @selector(applicationOpenUntitledFile:)])
{ {
[_delegate applicationOpenUntitledFile: self]; [_delegate applicationOpenUntitledFile: self];
} }
} }
else if ([NSDocumentController isDocumentBasedApplication]) else if ([[sdc documentClassNames] count] > 0)
{ {
NSError *err; NSError *err = nil;
NSDocumentController *sdc =
[NSDocumentController sharedDocumentController];
if ([sdc openUntitledDocumentAndDisplay: YES error: &err] == nil && if ([sdc openUntitledDocumentAndDisplay: YES error: &err] == nil
[sdc presentError: err] == NO) && [sdc presentError: err] == NO)
{ {
[self terminate: self]; [self terminate: self];
} }
} }
} }
} }
@ -3376,11 +3370,13 @@ struct _DelegateWrapper
} }
else else
{ {
if ([NSDocumentController isDocumentBasedApplication]) NSDocumentController *sdc;
sdc = [NSDocumentController sharedDocumentController];
if ([[sdc documentClassNames] count] > 0)
{ {
if ([[NSDocumentController sharedDocumentController] if ([sdc reviewUnsavedDocumentsWithAlertTitle: _(@"Quit")
reviewUnsavedDocumentsWithAlertTitle: _(@"Quit") cancellable: YES] == YES)
cancellable: YES] == YES)
{ {
termination = NSTerminateNow; termination = NSTerminateNow;
} }
@ -3758,6 +3754,7 @@ struct _DelegateWrapper
keyWindow: (NSWindow *)keyWindow keyWindow: (NSWindow *)keyWindow
mainWindow: (NSWindow *)mainWindow mainWindow: (NSWindow *)mainWindow
{ {
NSDocumentController *sdc;
id resp, delegate; id resp, delegate;
NSWindow *window; NSWindow *window;
@ -3779,6 +3776,8 @@ struct _DelegateWrapper
if (window != nil) if (window != nil)
{ {
NSDocumentController *sdc;
/* traverse the responder chain including the window's delegate */ /* traverse the responder chain including the window's delegate */
resp = [window firstResponder]; resp = [window firstResponder];
while (resp != nil && resp != self) while (resp != nil && resp != self)
@ -3799,10 +3798,10 @@ struct _DelegateWrapper
} }
/* in a document based app try the window's document */ /* in a document based app try the window's document */
if ([NSDocumentController isDocumentBasedApplication]) sdc = [NSDocumentController sharedDocumentController];
if ([[sdc documentClassNames] count] > 0)
{ {
resp = [[NSDocumentController sharedDocumentController] resp = [sdc documentForWindow: window];
documentForWindow: window];
if (resp != nil && [resp respondsToSelector: aSelector]) if (resp != nil && [resp respondsToSelector: aSelector])
{ {
@ -3848,9 +3847,9 @@ struct _DelegateWrapper
} }
/* as a last resort in a document based app, try the document controller */ /* as a last resort in a document based app, try the document controller */
if ([NSDocumentController isDocumentBasedApplication] sdc = [NSDocumentController sharedDocumentController];
&& [[NSDocumentController sharedDocumentController] if ([[sdc documentClassNames] count] > 0
respondsToSelector: aSelector]) && [sdc respondsToSelector: aSelector])
{ {
return [NSDocumentController sharedDocumentController]; return [NSDocumentController sharedDocumentController];
} }

View file

@ -72,12 +72,16 @@ static NSString *NSViewerRole = @"Viewer";
static NSDocumentController *sharedController = nil; static NSDocumentController *sharedController = nil;
static NSArray *allTypes = nil;
static NSArray *classNames = nil;
#define TYPE_INFO(name) TypeInfoForName(_types, name) #define TYPE_INFO(name) TypeInfoForName(_types, name)
#define HR_TYPE_INFO(name) TypeInfoForHumanReadableName(_types, name) #define HR_TYPE_INFO(name) TypeInfoForHumanReadableName(_types, name)
static NSDictionary *TypeInfoForName (NSArray *types, NSString *typeName) static NSDictionary *TypeInfoForName (NSArray *types, NSString *typeName)
{ {
int i, count = [types count]; int i, count = [types count];
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
NSDictionary *dict = [types objectAtIndex: i]; NSDictionary *dict = [types objectAtIndex: i];
@ -86,7 +90,8 @@ static NSDictionary *TypeInfoForName (NSArray *types, NSString *typeName)
{ {
return dict; return dict;
} }
else if ([[dict objectForKey: CFBundleTypeName] isEqualToString: typeName]) else if ([[dict objectForKey: CFBundleTypeName]
isEqualToString: typeName])
{ {
return dict; return dict;
} }
@ -95,18 +100,22 @@ static NSDictionary *TypeInfoForName (NSArray *types, NSString *typeName)
return nil; return nil;
} }
static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typeName) static NSDictionary *
TypeInfoForHumanReadableName (NSArray *types, NSString *typeName)
{ {
int i, count = [types count]; int i, count = [types count];
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
NSDictionary *dict = [types objectAtIndex: i]; NSDictionary *dict = [types objectAtIndex: i];
if ([[dict objectForKey: NSHumanReadableNameKey] isEqualToString: typeName]) if ([[dict objectForKey: NSHumanReadableNameKey]
isEqualToString: typeName])
{ {
return dict; return dict;
} }
else if ([[dict objectForKey: CFBundleTypeName] isEqualToString: typeName]) else if ([[dict objectForKey: CFBundleTypeName]
isEqualToString: typeName])
{ {
return dict; return dict;
} }
@ -167,6 +176,76 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
*/ */
@implementation NSDocumentController @implementation NSDocumentController
+ (void) initialize
{
static BOOL beenHere = NO;
if (beenHere == NO)
{
NSArray *types;
beenHere = YES;
types = [[[NSBundle mainBundle] infoDictionary]
objectForKey: NSTypesKey];
if (types == nil)
{
types = [[[NSBundle mainBundle] infoDictionary]
objectForKey: CFBundleDocumentTypes];
}
if (YES == [types isKindOfClass: [NSArray class]])
{
unsigned count = [types count];
unsigned src;
unsigned dst = 0;
NSString *names[count];
NSDictionary *valid[count];
for (src = 0; src < count; src++)
{
NSDictionary *d = [types objectAtIndex: src];
if (YES == [d isKindOfClass: [NSDictionary class]])
{
NSString *name = [d objectForKey: NSDocumentClassKey];
/* Is this type handled by an NSDocument subclass?
*/
if (YES == [name isKindOfClass: [NSString class]])
{
Class c = NSClassFromString(name);
if (YES == [c isSubclassOfClass: [NSDocument class]])
{
names[dst] = name;
valid[dst++] = d;
}
else if (c == 0)
{
NSLog(@"NSDocumentClass %@ not found", name);
}
else
{
NSLog(@"NSDocumentClass %@ not NSDocument subclass",
name);
}
}
}
else
{
NSLog(@"Bad item at index %u in %@",
src, CFBundleDocumentTypes);
}
}
if (dst > 0)
{
classNames = [[NSArray alloc] initWithObjects: names count: dst];
allTypes = [[NSArray alloc] initWithObjects: valid count: dst];
}
}
}
}
/** Returns the shared instance of the document controller class. You /** Returns the shared instance of the document controller class. You
should always use this method to get the NSDocumentController. */ should always use this method to get the NSDocumentController. */
+ (id) sharedDocumentController + (id) sharedDocumentController
@ -180,30 +259,13 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
return sharedController; return sharedController;
} }
/* Private method for use by NSApplication to determine if it should
instantiate an NSDocumentController.
*/
+ (BOOL) isDocumentBasedApplication
{
return ([[[NSBundle mainBundle] infoDictionary] objectForKey: NSTypesKey] ||
[[[NSBundle mainBundle] infoDictionary] objectForKey: CFBundleDocumentTypes])
? YES : NO;
}
/** </init>Initializes the document controller class. The first /** </init>Initializes the document controller class. The first
instance of a document controller class that gets initialized instance of a document controller class that gets initialized
becomes the shared instance. becomes the shared instance.
*/ */
- init - init
{ {
NSDictionary *customDict = [[NSBundle mainBundle] infoDictionary]; _types = RETAIN(allTypes);
ASSIGN (_types, [customDict objectForKey: NSTypesKey]);
if(_types == nil)
{
ASSIGN(_types, [customDict objectForKey: CFBundleDocumentTypes]);
}
_documents = [[NSMutableArray alloc] init]; _documents = [[NSMutableArray alloc] init];
@ -413,11 +475,11 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
- (NSString*) defaultType - (NSString*) defaultType
{ {
NSString *defaultName = nil; NSString *defaultName = nil;
int i, count = [_types count]; int i, count = [_types count];
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
NSDictionary *typeInfo = (NSDictionary*)[_types objectAtIndex: i]; NSDictionary *typeInfo = (NSDictionary*)[_types objectAtIndex: i];
NSString *role; NSString *role;
role = [typeInfo objectForKey: NSRoleKey]; role = [typeInfo objectForKey: NSRoleKey];
@ -434,10 +496,10 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
return defaultName; return defaultName;
} }
} }
// none found // none found
return nil; return nil;
} }
- (void) addDocument: (NSDocument *)document - (void) addDocument: (NSDocument *)document
@ -1026,14 +1088,14 @@ static BOOL _shouldClose = YES;
directory = [[document fileName] stringByDeletingLastPathComponent]; directory = [[document fileName] stringByDeletingLastPathComponent];
} }
if (directory == nil || [directory isEqual: @""] if (directory == nil || [directory isEqual: @""]
|| [manager fileExistsAtPath: directory isDirectory: &isDir] == NO || [manager fileExistsAtPath: directory isDirectory: &isDir] == NO
|| isDir == NO) || isDir == NO)
{ {
directory = [[NSOpenPanel openPanel] directory]; directory = [[NSOpenPanel openPanel] directory];
} }
if (directory == nil || [directory isEqual: @""] if (directory == nil || [directory isEqual: @""]
|| [manager fileExistsAtPath: directory isDirectory: &isDir] == NO || [manager fileExistsAtPath: directory isDirectory: &isDir] == NO
|| isDir == NO) || isDir == NO)
{ {
directory = NSHomeDirectory (); directory = NSHomeDirectory ();
} }
@ -1151,15 +1213,15 @@ static BOOL _shouldClose = YES;
NSDictionary *typeInfo = [_types objectAtIndex: i]; NSDictionary *typeInfo = [_types objectAtIndex: i];
if ([[typeInfo objectForKey: NSUnixExtensionsKey] if ([[typeInfo objectForKey: NSUnixExtensionsKey]
containsObject: fileExtension] || containsObject: fileExtension]
[[typeInfo objectForKey: NSDOSExtensionsKey] || [[typeInfo objectForKey: NSDOSExtensionsKey]
containsObject: fileExtension] || containsObject: fileExtension]
[[typeInfo objectForKey: CFBundleTypeExtensions] || [[typeInfo objectForKey: CFBundleTypeExtensions]
containsObject: fileExtension]) containsObject: fileExtension])
{ {
NSString *type = [typeInfo objectForKey: NSNameKey]; NSString *type = [typeInfo objectForKey: NSNameKey];
if(type == nil) if (type == nil)
{ {
type = [typeInfo objectForKey: CFBundleTypeName]; type = [typeInfo objectForKey: CFBundleTypeName];
} }
@ -1174,7 +1236,7 @@ static BOOL _shouldClose = YES;
{ {
NSString *type = [self typeFromFileExtension: [[url path] pathExtension]]; NSString *type = [self typeFromFileExtension: [[url path] pathExtension]];
if([url isFileURL] == NO && type == nil) if ([url isFileURL] == NO && type == nil)
{ {
return [self defaultType]; return [self defaultType];
} }
@ -1201,30 +1263,9 @@ static BOOL _shouldClose = YES;
return className ? NSClassFromString(className) : Nil; return className ? NSClassFromString(className) : Nil;
} }
- (NSArray *)documentClassNames - (NSArray*) documentClassNames
{ {
int i, count = [_types count]; return classNames;
NSMutableArray *classNames;
classNames = [[NSMutableArray alloc] initWithCapacity: count];
for (i = 0; i < count; i++)
{
NSDictionary *typeInfo = [_types objectAtIndex: i];
NSString *className = [typeInfo objectForKey: NSDocumentClassKey];
if(className != nil)
{
[classNames addObject: className];
}
else
{
NSLog(@"WARN: The entry does not have an NSDocumentClass name defined: %@",
typeInfo);
}
}
return AUTORELEASE(classNames);
} }
@ -1330,7 +1371,7 @@ static BOOL _shouldClose = YES;
{ {
NSString *name = [typeInfo objectForKey: NSNameKey]; NSString *name = [typeInfo objectForKey: NSNameKey];
if(name == nil) if (name == nil)
{ {
name = [typeInfo objectForKey: CFBundleTypeName]; name = [typeInfo objectForKey: CFBundleTypeName];
} }
@ -1364,7 +1405,7 @@ static BOOL _shouldClose = YES;
{ {
NSString *name = [typeInfo objectForKey: NSNameKey]; NSString *name = [typeInfo objectForKey: NSNameKey];
if(name == nil) if (name == nil)
{ {
name = [typeInfo objectForKey: CFBundleTypeName]; name = [typeInfo objectForKey: CFBundleTypeName];
} }
@ -1386,7 +1427,7 @@ static BOOL _shouldClose = YES;
NSDictionary *typeInfo = HR_TYPE_INFO(typeHR); NSDictionary *typeInfo = HR_TYPE_INFO(typeHR);
NSString *type = [typeInfo objectForKey: NSNameKey]; NSString *type = [typeInfo objectForKey: NSNameKey];
if(type == nil) if (type == nil)
{ {
type = [typeInfo objectForKey: CFBundleTypeName]; type = [typeInfo objectForKey: CFBundleTypeName];
} }
@ -1572,29 +1613,30 @@ static NSString *processName = nil;
// should be handled by making us the delegate of the recent's menu // should be handled by making us the delegate of the recent's menu
- (void) _updateOpenRecentMenu - (void) _updateOpenRecentMenu
{ {
NSMenu *recentMenu; NSMenu *recentMenu;
int i; int i;
recentMenu = [self _recentMenu]; recentMenu = [self _recentMenu];
if (!recentMenu) if (!recentMenu)
{ {
return; return;
} }
// don't update (to keep Clear List status consistent) // don't update (to keep Clear List status consistent)
[recentMenu setAutoenablesItems: NO]; [recentMenu setAutoenablesItems: NO];
[recentMenu setMenuChangedMessagesEnabled: NO]; [recentMenu setMenuChangedMessagesEnabled: NO];
while ([recentMenu numberOfItems] > 0) while ([recentMenu numberOfItems] > 0)
[recentMenu removeItemAtIndex: 0]; // remove them all {
[recentMenu removeItemAtIndex: 0]; // remove them all
for (i = [_recent_documents count]; i >= -2; i--) }
{ for (i = [_recent_documents count]; i >= -2; i--)
{
// add all items incl. a Clear List item if needed // add all items incl. a Clear List item if needed
NSMenuItem *item; NSMenuItem *item;
if (i == -1) if (i == -1)
{ {
if ([_recent_documents count] == 0) if ([_recent_documents count] == 0)
continue; // skip if menu is empty continue; // skip if menu is empty
item = (NSMenuItem *) [NSMenuItem separatorItem]; item = (NSMenuItem *) [NSMenuItem separatorItem];
@ -1602,7 +1644,7 @@ static NSString *processName = nil;
RETAIN(item); RETAIN(item);
} }
else if (i == -2) else if (i == -2)
{ {
item = [[NSMenuItem alloc] initWithTitle: _(@"Clear List") item = [[NSMenuItem alloc] initWithTitle: _(@"Clear List")
action: @selector(clearRecentDocuments:) action: @selector(clearRecentDocuments:)
keyEquivalent: nil]; keyEquivalent: nil];
@ -1610,11 +1652,12 @@ static NSString *processName = nil;
[item setEnabled: [_recent_documents count] > 0]; [item setEnabled: [_recent_documents count] > 0];
} }
else else
{ {
// standard item // standard item
NSURL *u = [_recent_documents objectAtIndex: i]; // get URL NSURL *u = [_recent_documents objectAtIndex: i]; // get URL
if ([u isFileURL]) if ([u isFileURL])
item = [[NSMenuItem alloc] initWithTitle: [[u path] lastPathComponent] item = [[NSMenuItem alloc]
initWithTitle: [[u path] lastPathComponent]
action: @selector(_openRecentDocument:) action: @selector(_openRecentDocument:)
keyEquivalent:nil]; keyEquivalent:nil];
else else
@ -1626,24 +1669,24 @@ static NSString *processName = nil;
[item setTarget: self]; [item setTarget: self];
[recentMenu addItem: item]; [recentMenu addItem: item];
RELEASE(item); RELEASE(item);
} }
[recentMenu setMenuChangedMessagesEnabled: YES]; [recentMenu setMenuChangedMessagesEnabled: YES];
} }
- (IBAction) _openRecentDocument: (id)sender - (IBAction) _openRecentDocument: (id)sender
{ {
// action to open recent document by tag index // action to open recent document by tag index
NSURL *url; NSURL *url;
int idx = [sender tag]; int idx = [sender tag];
if (idx < 0 || idx >= [_recent_documents count]) if (idx < 0 || idx >= [_recent_documents count])
{ {
// something went wrong, ignore // something went wrong, ignore
[self _updateOpenRecentMenu]; [self _updateOpenRecentMenu];
return; return;
} }
url = (NSURL *)[_recent_documents objectAtIndex: idx]; url = (NSURL *)[_recent_documents objectAtIndex: idx];
[self openDocumentWithContentsOfURL: url display: YES]; [self openDocumentWithContentsOfURL: url display: YES];
} }