How to open document in “Untitled” window instead of new one

Have you noticed how TextEdit or TextMate will open an existing file in the “Untitled” window, if it is empty? I thought this was a default behaviour of the multi-document architecture of AppKit. While writing multi-document support for ImageFramer 3 (ImageFramer 2 is a single-document application) I noticed that it always opens a document in a new window, even if I have not touched the default empty document.

After some research I’ve found the following facts:

  • NSDocumentController always opens documents in a new window by default
  • TextEdit uses a lot of custom code to manage this behavior. TextEdit is an open sourced examples which is installed with Xcode, at /Developer/Examples/TextEdit/. I didn’t want such a complicated solution for myself.

I ended up implementing my own solution for my case. It might not suit your needs but could help choose the correct path for you.

My solution maybe unique to me since ImageFramer’s document are images and not some custom format. In ImageFramer version 3 I’ll be saving the framing designs in Core Data inside the application, so they’re not regular documents by default.

I have a method in my NSDocument subclass that loads the image into the already existing document. So the image is not read in - (BOOL)readFromURL:ofType:error: but rather at a later stage, in - (void)windowControllerDidLoadNib: (NSWindowController *)aController method. There I check [self fileURL]. If it’s not nil, then I import the image into the document. If it’s nil, I load the default one and it becomes the “Untitled” document.

So what did I do to open images in the same window instead of the default one? I had to make changes in 2 classes:

1. In my NSDocument subclass I setup a method isDefaultImage which does what its name implies. I then set it to YES if I load the default image file. In general case you could name it
- (BOOL)isReplaceableDocument and handle all logic there. For example, you might want to return NO here if user has modified the document and you don’t want him to loose his changes.

2. In NSDocumentController subclass, I overloaded openDocumentWithContentsOfURL:display:error:. Here’s the whole method:

- (id)openDocumentWithContentsOfURL:(NSURL *)absoluteURL display:(BOOL)displayDocument error:(NSError **)outError
    if (![[self currentDocument] isDefaultImage])
        return [super openDocumentWithContentsOfURL:absoluteURL display:displayDocument error:outError];
    else {
        [[self currentDocument] importImage:absoluteURL];
        [[self currentDocument] setFileURL:absoluteURL];
        return [self currentDocument];

So, if I can’t replace to document, I just call super and return its result. If I can replace, I ask the current document to import the image, replacing my placeholder image. Then I set document’s URL to the provided one, so that it won’t stay as Untitled and will place the icon on the titlebar of the window.

That’s all.

Granted, in TextEdit example they take a more complex path, which probably may be better for them. From what I gathered, they create a new document manually and then copy the window controller from the Untitled document (they call it transient) to the new document. There’s more code there and you probably should take a look there to see if it suits you better.

DMG for distribution incompatibilty on Snow Leopard?

Do you use DMG to distribute your software for download?
Do you create it using a script, by creating a template DMG and then replacing its content upon release?

If you do, which I fully endorse, and you’ve created your template in Finder on Snow Leopard, read below.

In the last couple of days before the ininitial release of Cashculator to the public I’ve been struggling with the DMG creating process. I thought I’d already mastered it. After all, I’ve been already doing it with ImageFramer. So I prepared my template, copied the .DS_Store file from it (I used this process with ImageFramer) and script handled it all fine for me. I look at the final opened DMG and I see the following image (which is what I indended it to be):

Cashculator DMG background

Cashculator DMG background

I send it to the server and let my partner Kosta check it on his machine. He’s using Leopard and not the Snowy kind. He send me back the following image, which is far from what I thought it to be:

Cashculator DMG on Leopard

Cashculator DMG on Leopard

Not good. So I tried this way and that way. I even moved to another system, where I first create the DMG and use  the DMG itself as the template, without exracting .DS_Store first. Nothing helped on Leopard.

So we met and he brought the Leopard machine with him. I open the DMG, press Cmd-J and see that Finder thinks there’s no backgrond image and icon sizes are different.

After some research I came to the conclusion that DMGs created on Snow Leopard don’t show the same at all on Leopard. Frightened, I also tested my ImageFramer releases, which also sport a new background since the release of Snow Leopard. To my shock, it was also totally wrong on Leopard. That’s not how I wanted to convey the first impression of ImageFramer to potential customers.

The solution, of course, was to create the DMG on Leopard and use it as template instead. I ran the new template through my scripts and reopened the final DMG on Leopard to check. It was fine. Finally.

Today I did the same with ImageFramer‘s DMG. For some reason, the one from Leopard showed without background on my Snow Leopard machine. I only added the background again and saved the DMG. It worked fine on Leopard too.

That’s it. So, if you use a similar technique for creating DMG, check them on Leopard and on Snow Leopard before shipping to avoid later embarrassment.

Pin It on Pinterest