Search code examples
nstextviewnsdocument

NSTextView how to disable 'You don’t own the file “xxx” and don’t have permission to write to it.'


I have an NSTextView in my document based application. If I open a file that I only have read permissions to and modify the contents of the NSTextView I receive a dialog stating:

You don’t own the file “xxx” and don’t have permission to write to it.

But this textview is not actually interacting with the document I opened. Is it possible to cancel this behaviour of a NSTextView somehow?


Solution

  • Code I came up with is as follows:

    #import <JRSwizzle/JRSwizzle.h>
    
    @implementation NSDocument (Swizzle)
    
    + (void) load
    {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            NSError * error = nil;
    
            SEL srcSelection = NSSelectorFromString(@"_checkAutosavingThenUpdateChangeCount:");
            SEL dstSelector = @selector(MyCheckAutosavingThenUpdateChangeCount:);
    
            [[NSDocument class] jr_swizzleMethod: srcSelection
                                          withMethod: dstSelector
                                               error: &error];
            NSLog(@"Error: %@", error);
        });
    } // End of load
    
    - (void) MyCheckAutosavingThenUpdateChangeCount: (unsigned long long) arg1
    {
        // On updateChangeCount, we are going to catch if the firstresponder is our query window.
        // If the first responder is, then we will not mark a change. This is for two reasons:
        // 1. This is an sqlite app. Editing the query editor dosen't actually update our
        // document.
        // 2. If we do mark the document as updated and the query editor marks a change, we get
        // a popup stating that the document cant be updated, needs to be duplicated, yada, yada.
        NSWindow * keyWindow = [[NSApplication sharedApplication] keyWindow];
        if(NULL != keyWindow)
        {
            NSResponder * responder = keyWindow.firstResponder;
            // My code uses a NSTextView subclass. For copy/paste I'm just entering NSTextView.
            if([responder isKindOfClass: NSClassFromString(@"NSTextView")])
            {
                return;
            }
        }
    
        [self MyCheckAutosavingThenUpdateChangeCount: arg1];
    } // End of MyCheckAutosavingThenUpdateChangeCount