Re: NSDocumentController recentDocumentURLs hiding non-file based URLs
Re: NSDocumentController recentDocumentURLs hiding non-file based URLs
- Subject: Re: NSDocumentController recentDocumentURLs hiding non-file based URLs
- From: Ashley Clark <email@hidden>
- Date: Wed, 18 Apr 2007 10:02:12 -0500
- Resent-cc: Cocoa Dev List List <email@hidden>
- Resent-date: Fri, 20 Apr 2007 11:21:10 -0500
- Resent-date: Fri, 20 Apr 2007 11:21:16 -0500
- Resent-from: Ashley Clark <email@hidden>
- Resent-message-id: <email@hidden>
- Resent-to: Andrew Bush <email@hidden>
On Apr 18, 2007, at 6:37 AM, Andrew Bush wrote:
Hi Ashley,
Ive changed my mind about subclassing the document controller to
achieve this, but I haven't been able to get it working using your
advice, I can get my urls to show up only at the bottom of the
list, and it throws them out again as more standard file urls are
added.
It seems to be able to change the open recent menu at a lower level
than I can achieve.
If your offer of some further help and code is still open I would
very much appreciate it...I must be missing something stupid :)
thanks again.
Here's what I'm using. Basically, I manage my own list of recents and
in my menuNeedsUpdate: I cavalierly reset every item to what I
believe it should be. I also may have forgot to mention (and it's
been a while so I may be wrong in remembering this) but I think I had
to delete the Open Recent menu in my NIB and recreate it as a
standard menu and place my own Clear Menu item in it myself. In my
NIB it's not marked as a special menu in its' attributes, so you
might try that first.
Ashley
@implementation DatabaseDocumentController (ACRecentDocuments)
- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)
item
{
if ([item action] == @selector(clearRecentDocuments:))
return [recentDocumentURLs count] > 0;
return [super validateUserInterfaceItem:item];
}
- (void)clearRecentDocuments:(id)sender
{
[recentDocumentURLs removeAllObjects];
[self saveRecentDocuments];
}
- (NSArray *)recentDocumentURLs
{
return recentDocumentURLs;
}
- (void)noteNewRecentDocumentURL:(NSURL *)aURL
{
if (![aURL isFileURL] && ![aURL isDatabaseURL])
return;
[recentDocumentURLs removeObject:aURL];
[recentDocumentURLs insertObject:aURL atIndex:0];
int delta = [recentDocumentURLs count] - [self
maximumRecentDocumentCount];
while (delta > 0) {
[recentDocumentURLs removeLastObject];
delta--;
}
[self saveRecentDocuments];
}
@end
@implementation DatabaseDocumentController (NSMenuDelegate)
- (void)openRecentDocument:(id)sender
{
NSURL *url = [sender representedObject];
NSError *error = nil;
if (![self openDocumentWithContentsOfURL:[url absoluteURL]
display:YES error:&error]) {
[self presentError:error];
}
}
- (BOOL)menuHasKeyEquivalent:(NSMenu *)menu forEvent:(NSEvent *)event
target:(id *)target action:(SEL *)action
{
// our Open Recents menu has no Key Equivalents, use this to
avoid unneccessary database fetches
return NO;
}
- (void)menuNeedsUpdate:(NSMenu *)menu
{
// remove inaccessible files from array first
NSURL *url;
NSEnumerator *e = [recentDocumentURLs objectEnumerator];
NSError *error = nil;
BXDatabaseContext *context = [[BXDatabaseContext alloc]
initWithDefaultURI];
[context connectIfNeeded:&error];
if (error)
return;
NSMutableArray *toRemove = [NSMutableArray array];
while (url = [e nextObject])
if ([url isFileURL]) {
if ([[NSFileManager defaultManager] fileExistsAtPath:
[url path]])
[toRemove addObject:url];
} else {
error = nil;
id object = [context objectWithID:[BXDatabaseObjectID
IDWithURI:url inContext:context] error:&error];
if (!object)
[toRemove addObject:url];
}
[recentDocumentURLs removeObjectsInArray:toRemove];
int numberOfRecentDocumentsInMenu = ([menu numberOfItems] == 1 ?
0 : [menu numberOfItems] - 2);
int delta = ([recentDocumentURLs count]) -
numberOfRecentDocumentsInMenu;
if (delta > 0) {
while (delta) {
[menu insertItem:[[[NSMenuItem alloc] initWithTitle:@""
action:nil keyEquivalent:@""] autorelease] atIndex:0];
delta--;
numberOfRecentDocumentsInMenu++;
}
} else if (delta < 0) {
while (delta) {
[menu removeItemAtIndex:0];
delta++;
numberOfRecentDocumentsInMenu--;
}
}
BOOL hasSeparator = [[menu
itemAtIndex:numberOfRecentDocumentsInMenu] isSeparatorItem];
if (numberOfRecentDocumentsInMenu) {
if (!hasSeparator)
[menu insertItem:[NSMenuItem separatorItem]
atIndex:numberOfRecentDocumentsInMenu];
} else if (hasSeparator)
[menu removeItemAtIndex:numberOfRecentDocumentsInMenu];
int i;
for (i = 0; i < numberOfRecentDocumentsInMenu; i++) {
NSMenuItem *item = [menu itemAtIndex:i];
url = [recentDocumentURLs objectAtIndex:i];
[item setTarget:self];
[item setAction:@selector(openRecentDocument:)];
[item setRepresentedObject:url];
if ([url isFileURL]) {
NSImage *icon = [[NSWorkspace sharedWorkspace]
iconForFile:[url path]];
[icon setSize:NSMakeSize(16, 16)];
[item setImage:icon];
[item setTitle:[[NSFileManager defaultManager]
displayNameAtPath:[url path]]];
} else {
NSImage *icon = [[NSWorkspace sharedWorkspace]
iconForFileType:[[[url path] lastPathComponent] lowercaseString]];
[icon setSize:NSMakeSize(16, 16)];
[item setImage:icon];
error = nil;
id object = [context objectWithID:[BXDatabaseObjectID
IDWithURI:url inContext:context] error:&error];
if (!object) {
[item setTitle:[NSString stringWithFormat:@"error
fetching (%@): %@", [url absoluteString], [error
localizedDescription]]];
} else {
if ([object respondsToSelector:@selector(displayName)])
[item setTitle:[object displayName]];
else
[item setTitle:[url absoluteString]];
}
}
}
[context release];
}
@end
Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden