NSSavePanel delegate

zootbobbalu

Registered
I have a document based Cocoa app created in PB and I would like to set the delegate for the shared NSSavePanel the entire application uses.

I'm assuming that the NSSavePanel returned from:

id savePanel = [NSSavePanel savePanel]

will be the shared NSSavePanel (the documentation says this is the case), but when I try to set the savePanel delegate to the window controller, the window controller does not receive delegate messages.

The documentation also states that NSSavePanel will check to make sure that all the delegate methods are implemented before changing where the delegate instance points to, so I made sure that all methods are implemented.

- (NSComparisonResult)panel:(id)sender compareFilename:(NSString *)fileName1 with:(NSString *)fileName2 caseSensitive:(BOOL)flag {
NSLog(@"fileName1: %@ fileName: %@", fileName1, fileName2);
return [fileName1 compare:fileName2];
}
- (BOOL)panel:(id)sender isValidFilename:(NSString *)filename {
NSLog(@"savePanel isValidFilename: filename: %@", filename);
return YES;
}
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename {
NSLog(@"savePanel shouldShowFilename: filename: %@", filename);
return YES;
}
- (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag {
NSLog(@"savePanel filename: %@", filename);
return filename;
}
- (void)panel:(id)sender willExpand:(BOOL)expanding {
}

when I build/run the app nothing gets logged by the savePanel delegate when I save a document. I set the savePanel delegate by overriding the NSDocument saveDocument: method.

-(void)saveDocument:(id)sender {
id savePanel=[NSSavePanel savePanel];
[savePanel setDelegate:windowController];
NSLog(@"saveDocument: savePanelDelegate: %@ savePanel: %@", [[savePanel delegate] description], [savePanel description]);
[super saveDocument:sender];
}
- (NSData *)dataRepresentationOfType:(NSString *)aType {
NSLog(@"dataRep: savePanelDelegate: %@", [[[NSSavePanel savePanel] delegate] description]);
return docData;
}


the following gets logged when I run and save a document:

2002-12-19 09:56:54.675 DocApp?[4901] saveDocument: savePanelDelegate: (MyWindowController: 0x19800c0) savePanel: (NSSavePanel: 0x1a14550)

2002-12-19 09:56:59.606 DocApp?[4901] dataRep: savePanelDelegate: (null)

(for those of you really paying attention I had to modify the object descriptions in these logs so that I could get the text to show up in this post - object descriptions are placed between less than greater than characters not parenthesis);

If you noticed, the savePanel delegate was successfully changed to the window controller (MyWindowController?), but the savePanel delegate is set back to null by the time the document is asked to return the data that needs to be saved.

the application state is:

window delegate = window controller
NSApp delegate = document controller

any ideas what I'm doing wrong?
 
Nevermind, I figured it out. For anyone wondering how I set the savePanel delegate please read on.....

If you want to change the delegate for the shared save panel in a document based application, you need to set the delegate in the document method:

-(BOOL)prepareSavePanel:(NSSavePanel *)_savePanel {
[_savePanel setDelegate:windowController];
}

the windowController instance variable was set in the following method:

- (void)makeWindowControllers
{
windowController = [[[MyWindowController alloc] initWithWindowNibName:mad:"myWindow"] autorelease];
[windowController setViewPanel:viewPanel];
[self addWindowController:windowController];
}

MyWindowController is a subclass of NSWindowController.

setting the savePanel delegate to an object you can modify is very useful if your application creates projects (not single documents). You can obtain the filename the user wishes to save the project as with the savePanel delegate method:

- (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag;

this delegate method can be used to create a folder with the filename, then create a new filename by taking the last path component of the filename and appending it to the newly created folder. This new filename is then returned to the savePanel to save the data that your document returns in the method:

- (NSData *)dataRepresentationOfType:(NSString *)aType;

This is probably how iMovie saves a movie project.
 
Back
Top