mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 19:00:47 +00:00
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:
parent
c8916fd438
commit
51e03c6d17
4 changed files with 267 additions and 201 deletions
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue