mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-05-31 20:00:48 +00:00
Clean up and completion of NSDocumentController.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@27415 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
4a710daca9
commit
6cfee381c1
4 changed files with 572 additions and 314 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2008-12-25 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
* Headers/AppKit/NSMenuItem.h: Declare to implement interface
|
||||
NSValidatedUserInterfaceItem.
|
||||
* Headers/AppKit/NSDocumentController.h: Change to use NSUInteger and
|
||||
NSInteger.
|
||||
* Source/NSDocumentController.m: Implement all Cocoa methods of this
|
||||
class and clean up the rest of the implementation.
|
||||
Partly using code by Nikolaus Schaller <hns@computer.org>.
|
||||
|
||||
2008-12-21 Adam Fedor <fedor@gnu.org>
|
||||
|
||||
* Version 0.16.0
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
@class NSOpenPanel;
|
||||
@class NSWindow;
|
||||
|
||||
@interface NSDocumentController : NSObject
|
||||
@interface NSDocumentController : NSObject <NSCoding>
|
||||
{
|
||||
@private
|
||||
NSMutableArray *_documents;
|
||||
|
@ -111,7 +111,7 @@
|
|||
- (IBAction)newDocument:(id)sender;
|
||||
- (IBAction)clearRecentDocuments:(id)sender;
|
||||
#if OS_API_VERSION(MAC_OS_X_VERSION_10_4, GS_API_LATEST)
|
||||
- (unsigned int) maximumRecentDocumentCount;
|
||||
- (NSUInteger) maximumRecentDocumentCount;
|
||||
#endif
|
||||
|
||||
/*" Recent Documents "*/
|
||||
|
@ -122,7 +122,7 @@
|
|||
/*" Open panel "*/
|
||||
- (NSArray *)URLsFromRunningOpenPanel;
|
||||
- (NSArray *)fileNamesFromRunningOpenPanel;
|
||||
- (int)runModalOpenPanel:(NSOpenPanel *)openPanel forTypes:(NSArray *)openableFileExtensions;
|
||||
- (NSInteger)runModalOpenPanel:(NSOpenPanel *)openPanel forTypes:(NSArray *)openableFileExtensions;
|
||||
|
||||
/*" Document management "*/
|
||||
- (void)addDocument:(NSDocument *)document;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#import <GNUstepBase/GSVersionMacros.h>
|
||||
|
||||
#include <Foundation/NSObject.h>
|
||||
#include <AppKit/NSUserInterfaceValidation.h>
|
||||
|
||||
@class NSAttributedString;
|
||||
@class NSString;
|
||||
|
@ -367,7 +368,7 @@
|
|||
|
||||
@end
|
||||
|
||||
@interface NSMenuItem : NSObject <NSMenuItem>
|
||||
@interface NSMenuItem : NSObject <NSMenuItem, NSValidatedUserInterfaceItem>
|
||||
{
|
||||
NSMenu *_menu;
|
||||
NSString *_title;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "AppKit/NSDocumentController.h"
|
||||
#include "AppKit/NSOpenPanel.h"
|
||||
#include "AppKit/NSApplication.h"
|
||||
#include "AppKit/NSMenu.h"
|
||||
#include "AppKit/NSMenuItem.h"
|
||||
#include "AppKit/NSWorkspace.h"
|
||||
#include "NSDocumentFrameworkPrivate.h"
|
||||
|
@ -61,8 +62,14 @@ static NSString *CFBundleTypeExtensions = @"CFBundleTypeExtensions";
|
|||
static NSString *CFBundleTypeName = @"CFBundleTypeName";
|
||||
static NSString *CFBundleTypeRole = @"CFBundleTypeRole";
|
||||
|
||||
// FIXME: Looks like this was changed to @"NSRecentDocumentRecords"
|
||||
static NSString *NSRecentDocuments = @"NSRecentDocuments";
|
||||
|
||||
static NSString *NSEditorRole = @"Editor";
|
||||
static NSString *NSViewerRole = @"Viewer";
|
||||
//static NSString *NSNoRole = @"None";
|
||||
//static NSString *NSShellRole = @"Shell";
|
||||
|
||||
static NSDocumentController *sharedController = nil;
|
||||
|
||||
#define TYPE_INFO(name) TypeInfoForName(_types, name)
|
||||
|
@ -108,6 +115,14 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
return nil;
|
||||
}
|
||||
|
||||
|
||||
@interface NSDocumentController (RecentsMenu)
|
||||
- (NSMenu *) _recentMenu;
|
||||
- (void) _updateOpenRecentMenu;
|
||||
- (IBAction) _openRecentDocument: (id)sender;
|
||||
@end
|
||||
|
||||
|
||||
/** <p>
|
||||
NSDocumentController is a class that controls a set of NSDocuments
|
||||
for an application. As an application delegate, it responds to the
|
||||
|
@ -159,7 +174,8 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
{
|
||||
if (sharedController == nil)
|
||||
{
|
||||
sharedController = [[self alloc] init];
|
||||
// -init sets sharedController
|
||||
[[self alloc] init];
|
||||
}
|
||||
|
||||
return sharedController;
|
||||
|
@ -256,12 +272,13 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
IMP meth2;
|
||||
|
||||
meth1 = [self methodForSelector: sel];
|
||||
meth2 = [[NSDocument class] instanceMethodForSelector: sel];
|
||||
meth2 = [[NSDocumentController class] instanceMethodForSelector: sel];
|
||||
|
||||
return (meth1 != meth2);
|
||||
}
|
||||
|
||||
#define OVERRIDDEN(sel) [self _hasOverridden: @selector(sel)]
|
||||
//#define OVERRIDDEN(sel) [self _hasOverridden: @selector(sel)]
|
||||
#define OVERRIDDEN(sel) ([self methodForSelector: @selector(sel)] != [[NSDocumentController class] instanceMethodForSelector: @selector(sel)])
|
||||
|
||||
- (BOOL) shouldCreateUI
|
||||
{
|
||||
|
@ -331,6 +348,13 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
error: (NSError **)err
|
||||
{
|
||||
Class documentClass = [self documentClassForType: type];
|
||||
|
||||
if (documentClass == nil)
|
||||
{
|
||||
// FIXME: Set err
|
||||
return nil;
|
||||
}
|
||||
|
||||
return AUTORELEASE([[documentClass alloc] initForURL: url
|
||||
withContentsOfURL: contents
|
||||
ofType: type
|
||||
|
@ -340,20 +364,40 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
- (id) makeDocumentWithContentsOfURL: (NSURL *)url
|
||||
ofType: (NSString *)type
|
||||
error: (NSError **)err
|
||||
{
|
||||
if (OVERRIDDEN(makeDocumentWithContentsOfFile:ofType:) && [url isFileURL])
|
||||
{
|
||||
return [self makeDocumentWithContentsOfFile: [url path] ofType: type];
|
||||
}
|
||||
else
|
||||
{
|
||||
Class documentClass = [self documentClassForType: type];
|
||||
|
||||
if (documentClass == nil)
|
||||
{
|
||||
// FIXME: Set err
|
||||
return nil;
|
||||
}
|
||||
return AUTORELEASE([[documentClass alloc] initWithContentsOfURL: url
|
||||
ofType: type
|
||||
error: err]);
|
||||
}
|
||||
}
|
||||
|
||||
- (id) makeUntitledDocumentOfType: (NSString *)type
|
||||
error: (NSError **)err
|
||||
{
|
||||
if (OVERRIDDEN(makeUntitledDocumentOfType:))
|
||||
{
|
||||
return [self makeUntitledDocumentOfType: type];
|
||||
}
|
||||
else
|
||||
{
|
||||
Class documentClass = [self documentClassForType: type];
|
||||
return AUTORELEASE([[documentClass alloc] initWithType: type
|
||||
error: err]);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) presentError: (NSError *)error
|
||||
{
|
||||
|
@ -383,19 +427,32 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
- (NSString*) defaultType
|
||||
{
|
||||
NSString *defaultName = nil;
|
||||
if ([_types count] == 0)
|
||||
{
|
||||
return nil; // raise exception?
|
||||
}
|
||||
int i, count = [_types count];
|
||||
|
||||
defaultName = [(NSDictionary*)[_types objectAtIndex: 0] objectForKey: NSNameKey];
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
NSDictionary *typeInfo = (NSDictionary*)[_types objectAtIndex: i];
|
||||
NSString *role;
|
||||
|
||||
role = [typeInfo objectForKey: NSRoleKey];
|
||||
if (role == nil)
|
||||
role = [typeInfo objectForKey: CFBundleTypeRole];
|
||||
|
||||
if ([role isEqual: NSEditorRole])
|
||||
{
|
||||
defaultName = [typeInfo objectForKey: NSNameKey];
|
||||
if (defaultName == nil)
|
||||
{
|
||||
defaultName = [(NSDictionary*)[_types objectAtIndex: 0] objectForKey: CFBundleTypeName];
|
||||
defaultName = [typeInfo objectForKey: CFBundleTypeName];
|
||||
}
|
||||
|
||||
return defaultName;
|
||||
}
|
||||
}
|
||||
|
||||
// none found
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) addDocument: (NSDocument *)document
|
||||
{
|
||||
|
@ -477,9 +534,7 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
|
||||
if (document == nil)
|
||||
{
|
||||
// Should we only do this if [url isFileURL] is YES?
|
||||
NSString *type = [self typeFromFileExtension:
|
||||
[[url path] pathExtension]];
|
||||
NSString *type = [self typeForContentsOfURL: url error: NULL];
|
||||
|
||||
document = [self makeDocumentWithContentsOfURL: url ofType: type];
|
||||
|
||||
|
@ -543,12 +598,10 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
display: (BOOL)display
|
||||
error: (NSError **)err
|
||||
{
|
||||
if (OVERRIDDEN(openDocumentWithContentsOfFile:display:))
|
||||
if (OVERRIDDEN(openDocumentWithContentsOfFile:display:) && [url isFileURL])
|
||||
{
|
||||
NSString *fileName;
|
||||
|
||||
fileName = [url path];
|
||||
return [self openDocumentWithContentsOfFile: fileName display: display];
|
||||
return [self openDocumentWithContentsOfFile: [url path]
|
||||
display: display];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -556,11 +609,16 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
|
||||
if (document == nil)
|
||||
{
|
||||
// Should we only do this if [url isFileURL] is YES?
|
||||
NSString *type = [self typeFromFileExtension:
|
||||
[[url path] pathExtension]];
|
||||
NSString *type = [self typeForContentsOfURL: url error: err];
|
||||
|
||||
document = [self makeDocumentWithContentsOfURL: url ofType: type error: err];
|
||||
if (type == nil)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
document = [self makeDocumentWithContentsOfURL: url
|
||||
ofType: type
|
||||
error: err];
|
||||
|
||||
if (document == nil)
|
||||
{
|
||||
|
@ -591,12 +649,15 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
withContentsOfURL: (NSURL *)contents
|
||||
error: (NSError **)err
|
||||
{
|
||||
if ([contents isFileURL])
|
||||
NSString *type = [self typeForContentsOfURL: contents error: err];
|
||||
id document;
|
||||
|
||||
if (type == nil)
|
||||
{
|
||||
NSString *type =
|
||||
[self typeFromFileExtension: [[contents path] pathExtension]];
|
||||
id document =
|
||||
[self makeDocumentForURL: url
|
||||
return NO;
|
||||
}
|
||||
|
||||
document = [self makeDocumentForURL: url
|
||||
withContentsOfURL: contents
|
||||
ofType: type
|
||||
error: err];
|
||||
|
@ -610,12 +671,6 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
}
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: set error
|
||||
*err = nil;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
@ -623,6 +678,7 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
- (NSOpenPanel *) _setupOpenPanel
|
||||
{
|
||||
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
|
||||
|
||||
[openPanel setDirectory: [self currentDirectory]];
|
||||
[openPanel setAllowsMultipleSelection: YES];
|
||||
return openPanel;
|
||||
|
@ -631,7 +687,7 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
/** Invokes [NSOpenPanel-runModalForTypes:] with the NSOpenPanel
|
||||
object openPanel, and passes the openableFileExtensions file types
|
||||
*/
|
||||
- (int) runModalOpenPanel: (NSOpenPanel *)openPanel
|
||||
- (NSInteger) runModalOpenPanel: (NSOpenPanel *)openPanel
|
||||
forTypes: (NSArray *)openableFileExtensions
|
||||
{
|
||||
return [openPanel runModalForTypes: openableFileExtensions];
|
||||
|
@ -645,6 +701,7 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
for (i = 0; i < count; i++)
|
||||
{
|
||||
NSDictionary *typeInfo = [_types objectAtIndex: i];
|
||||
|
||||
[array addObjectsFromArray: [typeInfo objectForKey: NSUnixExtensionsKey]];
|
||||
[array addObjectsFromArray: [typeInfo objectForKey: NSDOSExtensionsKey]];
|
||||
[array addObjectsFromArray: [typeInfo objectForKey: CFBundleTypeExtensions]];
|
||||
|
@ -687,7 +744,6 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (IBAction) saveAllDocuments: (id)sender
|
||||
{
|
||||
NSDocument *document;
|
||||
|
@ -702,23 +758,30 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
- (IBAction) openDocument: (id)sender
|
||||
{
|
||||
NSEnumerator *fileEnum;
|
||||
NSString *filename;
|
||||
NSError *err = nil;
|
||||
NSEnumerator *urlEnum;
|
||||
NSURL *url;
|
||||
|
||||
fileEnum = [[self fileNamesFromRunningOpenPanel] objectEnumerator];
|
||||
|
||||
while ((filename = [fileEnum nextObject]))
|
||||
urlEnum = [[self URLsFromRunningOpenPanel] objectEnumerator];
|
||||
while ((url = [urlEnum nextObject]))
|
||||
{
|
||||
[self openDocumentWithContentsOfFile: filename display: YES];
|
||||
[self openDocumentWithContentsOfURL: url display: YES error: &err];
|
||||
if (err && ![self presentError: err])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction) newDocument: (id)sender
|
||||
{
|
||||
[self openUntitledDocumentOfType: [self defaultType] display: YES];
|
||||
NSError *err = nil;
|
||||
|
||||
[self openUntitledDocumentAndDisplay: YES error: &err];
|
||||
if (err)
|
||||
[self presentError: err];
|
||||
}
|
||||
|
||||
|
||||
|
@ -748,11 +811,59 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
return YES;
|
||||
}
|
||||
|
||||
|
||||
// FIXME
|
||||
static BOOL _shouldClose = YES;
|
||||
|
||||
- (void) _document: (NSDocument *)doc
|
||||
shouldClose: (BOOL)shouldClose
|
||||
contextInfo: (void *)contextInfo
|
||||
{
|
||||
_shouldClose = shouldClose;
|
||||
}
|
||||
|
||||
- (void)closeAllDocumentsWithDelegate:(id)delegate
|
||||
didCloseAllSelector:(SEL)didAllCloseSelector
|
||||
contextInfo:(void *)contextInfo
|
||||
{
|
||||
//FIXME
|
||||
int count;
|
||||
BOOL closeAll = YES;
|
||||
|
||||
count = [_documents count];
|
||||
if (count > 0)
|
||||
{
|
||||
NSDocument *array[count];
|
||||
|
||||
[_documents getObjects: array];
|
||||
while (count-- > 0)
|
||||
{
|
||||
NSDocument *document = array[count];
|
||||
|
||||
// Initialize to known state
|
||||
_shouldClose = YES;
|
||||
[document canCloseDocumentWithDelegate: self
|
||||
shouldCloseSelector:
|
||||
@selector(_document:shouldClose:contextInfo:)
|
||||
contextInfo: contextInfo];
|
||||
if (_shouldClose)
|
||||
{
|
||||
[document close];
|
||||
}
|
||||
else
|
||||
{
|
||||
closeAll = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (delegate != nil && didAllCloseSelector != NULL)
|
||||
{
|
||||
void (*meth)(id, SEL, id, BOOL, void*);
|
||||
meth = (void (*)(id, SEL, id, BOOL, void*))[delegate methodForSelector:
|
||||
didAllCloseSelector];
|
||||
if (meth)
|
||||
meth(delegate, didAllCloseSelector, self, closeAll, contextInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/** If there are any unsaved documents, this method displays an alert
|
||||
|
@ -800,7 +911,34 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
didReviewAllSelector: (SEL)didReviewAllSelector
|
||||
contextInfo: (void *)contextInfo
|
||||
{
|
||||
NSString *cancelString = (cancellable)? ((NSString *)_(@"Cancel")) : ((NSString *)nil);
|
||||
int result = YES;
|
||||
|
||||
if (![self hasEditedDocuments])
|
||||
{
|
||||
if (delegate != nil && didReviewAllSelector != NULL)
|
||||
{
|
||||
void (*meth)(id, SEL, id, BOOL, void*);
|
||||
meth = (void (*)(id, SEL, id, BOOL, void*))[delegate methodForSelector:
|
||||
didReviewAllSelector];
|
||||
if (meth)
|
||||
meth(delegate, didReviewAllSelector, self, result, contextInfo);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
NSBeginAlertSheet(title,
|
||||
_(@"Review Unsaved"),
|
||||
cancelString,
|
||||
_(@"Quit Anyway"),
|
||||
nil,
|
||||
delegate,
|
||||
didReviewAllSelector,
|
||||
contextInfo,
|
||||
_(@"You have unsaved documents"),
|
||||
nil);
|
||||
}
|
||||
|
||||
|
||||
|
@ -845,7 +983,6 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
[self reviewUnsavedDocumentsWithAlertTitle: _(@"Power Off") cancellable: NO];
|
||||
}
|
||||
|
||||
|
||||
/** Returns an array of all open documents */
|
||||
- (NSArray *) documents
|
||||
{
|
||||
|
@ -958,12 +1095,9 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
|
||||
- (id) documentForURL: (NSURL *)url
|
||||
{
|
||||
if (OVERRIDDEN(documentForFileName:))
|
||||
if (OVERRIDDEN(documentForFileName:) && [url isFileURL])
|
||||
{
|
||||
NSString *fileName;
|
||||
|
||||
fileName = [url path];
|
||||
return [self documentForFileName: fileName];
|
||||
return [self documentForFileName: [url path]];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -985,23 +1119,30 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
|
||||
- (BOOL) validateMenuItem: (NSMenuItem *)anItem
|
||||
{
|
||||
if ([anItem action] == @selector(saveAllDocuments:))
|
||||
return [self validateUserInterfaceItem: anItem];
|
||||
}
|
||||
|
||||
- (BOOL) validateUserInterfaceItem: (id <NSValidatedUserInterfaceItem>)anItem
|
||||
{
|
||||
if (sel_eq([anItem action], @selector(saveAllDocuments:)))
|
||||
{
|
||||
return [self hasEditedDocuments];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)anItem
|
||||
{
|
||||
// FIXME
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSString *) displayNameForType: (NSString *)type
|
||||
{
|
||||
// FIXME: Is this needed?
|
||||
NSString *name = [TYPE_INFO(type) objectForKey: NSHumanReadableNameKey];
|
||||
|
||||
if (!name)
|
||||
{
|
||||
name = [[NSBundle mainBundle] localizedStringForKey: type
|
||||
value: type
|
||||
table: @"InfoPlist"];
|
||||
}
|
||||
|
||||
return name ? name : type;
|
||||
}
|
||||
|
||||
|
@ -1021,6 +1162,7 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
containsObject: fileExtension])
|
||||
{
|
||||
NSString *type = [typeInfo objectForKey: NSNameKey];
|
||||
|
||||
if(type == nil)
|
||||
{
|
||||
type = [typeInfo objectForKey: CFBundleTypeName];
|
||||
|
@ -1034,26 +1176,21 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
|
||||
- (NSString *) typeForContentsOfURL: (NSURL *)url error: (NSError **)err
|
||||
{
|
||||
// FIXME
|
||||
NSString *extension;
|
||||
|
||||
extension = [[url path] pathExtension];
|
||||
return [self typeFromFileExtension: extension];
|
||||
// FIXME: open connection and get response to determine mine/type
|
||||
// Should we only do this if [url isFileURL] is YES?
|
||||
return [self typeFromFileExtension: [[url path] pathExtension]];
|
||||
}
|
||||
|
||||
- (NSArray *) fileExtensionsFromType: (NSString *)type
|
||||
{
|
||||
NSDictionary *typeInfo = TYPE_INFO(type);
|
||||
NSArray *unixExtensions = [typeInfo objectForKey: NSUnixExtensionsKey];
|
||||
NSArray *dosExtensions = [typeInfo objectForKey: NSDOSExtensionsKey];
|
||||
NSArray *cfFileExtensions = [typeInfo objectForKey: CFBundleTypeExtensions];
|
||||
NSMutableArray *array = [NSMutableArray arrayWithCapacity: 3];
|
||||
|
||||
if (!dosExtensions && !unixExtensions) return cfFileExtensions;
|
||||
if (!dosExtensions) return unixExtensions;
|
||||
if (!unixExtensions) return dosExtensions;
|
||||
[array addObjectsFromArray: [typeInfo objectForKey: NSUnixExtensionsKey]];
|
||||
[array addObjectsFromArray: [typeInfo objectForKey: NSDOSExtensionsKey]];
|
||||
[array addObjectsFromArray: [typeInfo objectForKey: CFBundleTypeExtensions]];
|
||||
|
||||
return [[unixExtensions arrayByAddingObjectsFromArray: dosExtensions]
|
||||
arrayByAddingObjectsFromArray: cfFileExtensions];
|
||||
return array;
|
||||
}
|
||||
|
||||
- (Class) documentClassForType: (NSString *)type
|
||||
|
@ -1095,18 +1232,19 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
[_recent_documents removeAllObjects];
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
setObject: _recent_documents forKey: NSRecentDocuments];
|
||||
[self _updateOpenRecentMenu];
|
||||
}
|
||||
|
||||
// The number of remembered recent documents
|
||||
- (unsigned int) maximumRecentDocumentCount
|
||||
- (NSUInteger) maximumRecentDocumentCount
|
||||
{
|
||||
// FIXME: Should come from user defaults
|
||||
return 5;
|
||||
}
|
||||
|
||||
- (void) noteNewRecentDocument: (NSDocument *)aDocument
|
||||
{
|
||||
NSString *fileName = [aDocument fileName];
|
||||
NSURL *anURL = [NSURL fileURLWithPath: fileName];
|
||||
NSURL *anURL = [aDocument fileURL];
|
||||
|
||||
if (anURL != nil)
|
||||
[self noteNewRecentDocumentURL: anURL];
|
||||
|
@ -1129,6 +1267,7 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
|
||||
[_recent_documents addObject: anURL];
|
||||
|
||||
// Save the changed list
|
||||
a = [_recent_documents mutableCopy];
|
||||
index = [a count];
|
||||
while (index-- > 0)
|
||||
|
@ -1139,6 +1278,7 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
[[NSUserDefaults standardUserDefaults]
|
||||
setObject: a forKey: NSRecentDocuments];
|
||||
RELEASE(a);
|
||||
[self _updateOpenRecentMenu];
|
||||
}
|
||||
|
||||
- (NSArray *) recentDocumentURLs
|
||||
|
@ -1146,12 +1286,23 @@ static NSDictionary *TypeInfoForHumanReadableName (NSArray *types, NSString *typ
|
|||
return _recent_documents;
|
||||
}
|
||||
|
||||
//
|
||||
// NSCoding protocol
|
||||
//
|
||||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
- (id) initWithCoder: (NSCoder*)aDecoder
|
||||
{
|
||||
// FIXME
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSDocumentController (Private)
|
||||
static NSString *NSEditorRole = @"Editor";
|
||||
static NSString *NSViewerRole = @"Viewer";
|
||||
//static NSString *NSNoRole = @"None";
|
||||
|
||||
- (NSArray *) _editorAndViewerTypesForClass: (Class)documentClass
|
||||
{
|
||||
|
@ -1177,6 +1328,7 @@ static NSString *NSViewerRole = @"Viewer";
|
|||
|| [role isEqual: NSViewerRole]))
|
||||
{
|
||||
NSString *name = [typeInfo objectForKey: NSNameKey];
|
||||
|
||||
if(name == nil)
|
||||
{
|
||||
name = [typeInfo objectForKey: CFBundleTypeName];
|
||||
|
@ -1200,10 +1352,17 @@ static NSString *NSViewerRole = @"Viewer";
|
|||
NSString *className = [typeInfo objectForKey: NSDocumentClassKey];
|
||||
NSString *role = [typeInfo objectForKey: NSRoleKey];
|
||||
|
||||
// if the standard one isn't filled... check the CF key.
|
||||
if (role == nil)
|
||||
{
|
||||
role = [typeInfo objectForKey: CFBundleTypeRole];
|
||||
}
|
||||
|
||||
if ([docClassName isEqualToString: className] &&
|
||||
(role == nil || [role isEqual: NSEditorRole]))
|
||||
{
|
||||
NSString *name = [typeInfo objectForKey: NSNameKey];
|
||||
|
||||
if(name == nil)
|
||||
{
|
||||
name = [typeInfo objectForKey: CFBundleTypeName];
|
||||
|
@ -1393,3 +1552,91 @@ static NSString *processName;
|
|||
}
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSDocumentController (RecentsMenu)
|
||||
|
||||
- (NSMenu *) _recentMenu
|
||||
{
|
||||
// FIXME
|
||||
return nil;
|
||||
}
|
||||
|
||||
// should be handled by making us the delegate of the recent's menu
|
||||
- (void) _updateOpenRecentMenu
|
||||
{
|
||||
NSMenu *recentMenu;
|
||||
int i;
|
||||
|
||||
recentMenu = [self _recentMenu];
|
||||
if (!recentMenu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// don't update (to keep Clear List status consistent)
|
||||
[recentMenu setAutoenablesItems: NO];
|
||||
[recentMenu setMenuChangedMessagesEnabled: NO];
|
||||
|
||||
while ([recentMenu numberOfItems] > 0)
|
||||
[recentMenu removeItemAtIndex: 0]; // remove them all
|
||||
|
||||
for (i = [_recent_documents count]; i >= -2; i--)
|
||||
{
|
||||
// add all items incl. a Clear List item if needed
|
||||
NSMenuItem *item;
|
||||
|
||||
if (i == -1)
|
||||
{
|
||||
if ([_recent_documents count] == 0)
|
||||
continue; // skip if menu is empty
|
||||
item = (NSMenuItem *) [NSMenuItem separatorItem];
|
||||
// will release...
|
||||
RETAIN(item);
|
||||
}
|
||||
else if (i == -2)
|
||||
{
|
||||
item = [[NSMenuItem alloc] initWithTitle: _(@"Clear List")
|
||||
action: @selector(clearRecentDocuments:)
|
||||
keyEquivalent: nil];
|
||||
// disable for empty list
|
||||
[item setEnabled: [_recent_documents count] > 0];
|
||||
}
|
||||
else
|
||||
{
|
||||
// standard item
|
||||
NSURL *u = [_recent_documents objectAtIndex: i]; // get URL
|
||||
if ([u isFileURL])
|
||||
item = [[NSMenuItem alloc] initWithTitle: [[u path] lastPathComponent]
|
||||
action: @selector(_openRecentDocument:)
|
||||
keyEquivalent:nil];
|
||||
else
|
||||
item = [[NSMenuItem alloc] initWithTitle: [u relativeString]
|
||||
action: @selector(_openRecentDocument:)
|
||||
keyEquivalent:nil];
|
||||
[item setTag: i];
|
||||
}
|
||||
[item setTarget: self];
|
||||
[recentMenu addItem: item];
|
||||
RELEASE(item);
|
||||
}
|
||||
|
||||
[recentMenu setMenuChangedMessagesEnabled: YES];
|
||||
}
|
||||
|
||||
- (IBAction) _openRecentDocument: (id)sender
|
||||
{
|
||||
// action to open recent document by tag index
|
||||
NSURL *url;
|
||||
int idx = [sender tag];
|
||||
|
||||
if (idx < 0 || idx >= [_recent_documents count])
|
||||
{
|
||||
// something went wrong, ignore
|
||||
[self _updateOpenRecentMenu];
|
||||
return;
|
||||
}
|
||||
url = (NSURL *)[_recent_documents objectAtIndex: idx];
|
||||
[self openDocumentWithContentsOfURL: url display: YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue