views:

163

answers:

2

I am working on a document-based Cocoa application. At startup, the user is presented with a "welcome panel" (of type NSPanel) with buttons for common actions like "Create New Document" and "Open Existing Document". These actions are linked to the first responder's newDocument: and openDocument: actions, respectively, just like the matching items in the File menu.

Everything works as expected...with three caveats:

  1. The welcome panel is not dismissed when creating or opening a new document.
  2. Document windows do not have focus when they are created.
  3. Open document windows do not have the open file represented in the window title bar; likewise, new document windows do not get created with titles like "Untitled", "Untitled 2", "Untitled 3", etc., as expected. (I'm mentioning this not only because it's annoying, but because it may yield some insight into what's going wrong.)

I have partially solved #1 by making my application controller a delegate of the welcome panel. When clicking the "Open Existing Document" button, the panel resigns its key status (since a file browser dialog is being opened), so I can close the panel in the delegate's windowDidResignKey: method. However, I can't figure out how to close the panel when creating a new document, since I can't find a notification that is posted, or a delegate method that is called, when creating a new document. And ultimately, #2 is still a problem, since the document windows don't gain focus when they're created.

I have only subclassed NSDocument -- I'm not using a custom document or window controller at all. I've also tried changing the panel to an NSWindow, thinking that an NSWindow may behave differently, but the same problems are occurring.

A: 

Instead of linking to the first responder's default actions, just create custom action method in your window controller and set your buttons to trigger those actions. In your method, you need to close the welcome window and then create a new document.

Something like this:

- (IBAction)createNewDocument:(id)sender
{
    //this will close the window if you're using NSWindowController
    [self close];
    [[NSDocumentController sharedDocumentController] newDocument:sender];
}

Or if you're not using an NSWindowController for your welcome window you can just message the window directly:

- (IBAction)createNewDocument:(id)sender
{
    //assume you have a "window" outlet connected to your welcome window
    [window orderOut:sender];
    [[NSDocumentController sharedDocumentController] newDocument:sender];
}
Rob Keniger
That works, save for item #2: The document window does not have focus when it appears. Any ideas on how to make that happen?
mipadi
Try calling the `-newDocument` method in the next event loop: `[[NSDocumentController sharedDocumentController] performSelector:@selector(newDocument:) withObject:sender afterDelay:0];`
Rob Keniger
Hm, that didn't work, either.
mipadi
In that case you might want to try the `-openUntitledDocumentAndDisplay:error:` method of `NSDocumentController` instead of `-newDocument:`. It returns an `NSDocument` object, which you can then get the window for via its window controller. You can then tell the window to order front using the `-makeKeyAndOrderFront:` method of `NSWindow`. It does seem a bit odd that you are needing to do this though, normally this should "just work".
Rob Keniger
A: 

Make a custom document controller, and have it know about your Starting Points panel's controller, and hide the window in addDocument: and show it again (if no other documents remain) in removeDocument:.

This is what we did in Adium Xtras Creator. That code is under a BSD license (unlike Adium proper), so you can borrow it if you want.

Peter Hosey
This fixed the first problem, but the second -- that new/opened document windows don't have focus upon creation -- still exists. Any ideas what may be causing that issue?
mipadi
Nope. Adium Xtras Creator doesn't have that problem. Are the new windows not key, not main, or not either?
Peter Hosey