9

How do I prevent a window title from displaying "Edited" for an NSDocument which is dirty?

I'm managing saving and autosaving myself, using a web service, and just don't want the distraction in the title bar.

I've tried overriding:

  • NSDocument's -isDocumentEdited and -hasUnautosavedChanges always to return NO.
  • -[NSWindowController setDocumentEdited] to do nothing, or always to use NO regardless of the parameter's actual value.
  • -[NSWindowController synchronizeWindowTitleWithDocumentName] to do nothing.
  • -[NSWindow setDocumentEdited] to do nothing, or always to use NO regardless of the parameter's actual value.

In all cases, the title bar still changes to Edited when I make changes to a saved document.

If I override -[NSDocument updateChangeCount:] and -[NSDocument updateChangeCountWithToken:forSaveOperation:] to do nothing, I can prevent this from happening, but it affects saving, autosaving, and other document behaviors, too.

I also tried this:

[[self.window standardWindowButton: NSWindowDocumentVersionsButton] setTitle:nil];

That displayed a blank string instead of Edited, but the dash still appeared – the one which normally separates the document name and Edited.

Any idea how to pry apart this part of the window from the document?

paulmelnikow
  • 16,895
  • 8
  • 63
  • 114

3 Answers3

6

Several options:

  1. To get a pointer to the "dash", look for a TextField in [window.contentView.superview.subviews] with a stringValue equals to "-". You can set its text to an empty string as well.

    @implementation NSWindow (DashRetrivalMethod)
    - (NSTextField*)versionsDashTextField
    {
        NSTextField* res = nil;
        NSView* themeFrame = [self.contentView superview];
        for (NSView* tmp in [themeFrame subviews])
        {
            if ([tmp isKindOfClass:[NSTextField class]])
            {
                if ([[(NSTextField*)tmp stringValue] isEqualToString:@"—"])
                {
                      res = (NSTextField*)tmp;
                      break;
                }
            }
        }
        return res;
    }
    @end
    
  2. You can override NSWindow's -setRepresentedURL:. This would also affect the NSWindowDocumentIconButton and the popup menu, but you can manually create it if you want by: [NSWindow standardWindowButton: NSWindowDocumentIconButton].

  3. Override one of these three NSDocument's undocumented methods:

    // Always return here NO if you don't want the version button to appear. 
    // This seems to be the cleanest options, besides the fact that you are 
    /// overriding a private method.
    - (BOOL)_shouldShowAutosaveButtonForWindow:(NSWindow*)window;
    
    // Call super with NO
    - (void)_setShowAutosaveButton:(BOOL)flag; 
    
    // Here the button and the dash are actually created
    - (void)_endVersionsButtonUpdates; 
    
    // Here Cocoa hide or unhide the edited button
    - (void)_updateDocumentEditedAndAnimate:(BOOL)flag
    
Yoav
  • 5,962
  • 5
  • 39
  • 61
  • Excellent solution. @noa you should accept this one. Its awesome. Btw Ben-Uri, by override you mean swizzle right? – Noitidart Mar 02 '15 at 10:22
  • Thanks. No swizzle. Just implement them in your NSDocument subclass as suggested in the comment above each method prototype. – Yoav Mar 02 '15 at 14:24
1

Have you tried overriding NSDocuments - (BOOL)hasUnautosavedChanges in addition to overriding - (BOOL) isDocumentEdited?

thundersteele
  • 673
  • 3
  • 5
  • It's a good thought. After autosaving, though, Edited appears until the user explicitly initiates a Save operation, by Apple's design. That said, I tested it anyway: having both `-hasUnautosavedChanges` and `-isDocumentEdited` return NO, Edited appeared anyway. – paulmelnikow Apr 30 '12 at 22:19
  • Ok, this was my only idea unfortunately. I assume that dropping NSDocument as basis for the application, and only using NSDocumentController, would require a major rewrite of your application? – thundersteele Apr 30 '12 at 22:30
  • That's right. Reimplementing `-updateChangeCount:`, `-updateChangeCountForToken:forSaveOperation:`, `-isDocumentEdited` and `-hasUnautosavedChanges` might be feasible, but even that seems drastic, and potentially difficult to maintain. Not telling the document about its window is another possibility, but again, drastic. – paulmelnikow Apr 30 '12 at 22:36
0

Although this is a late answer, you can easily determine what is going to be the title of your NSDocument window by overriding

- (NSString *)windowTitleForDocumentDisplayName:(NSString *)displayName

in your NSWindowController and return the appropriate title.

You can do that also by overriding the property of your NSDocument:

- (NSString *)displayName

but this is not recommended by Apple, because that is normally used by the OS error handlers.

I added this answer, because none of the other answers really set me on the right path.

jvarela
  • 3,744
  • 1
  • 22
  • 43