Search code examples
objective-cmacoscocoansopenpanel

NSOpenPanel restrict already selected file


I have added NSOpenPanel for selecting folders. But I want achieve following cases:
1. Restrict user to select already selected folders.
2. Restrict user to select sub folders if parent folder already selected.

Or if above cases are not possible then how can check whether parent folder of current selected folder is already selected or not?

//Panel related code
    aPanel = [NSOpenPanel openPanel];
    [aPanel setMessage:@"Choose folders"];
    [aPanel setPrompt:@"Select"];
    [aPanel setNameFieldLabel:@"Location"];
    [aPanel setAllowsMultipleSelection:YES];
    [aPanel setCanChooseDirectories:YES];
    [aPanel setDirectoryURL:[NSURL fileURLWithPath:NSHomeDirectory()]];
    [aPanel setDelegate:self];
    dispatch_async(dispatch_get_main_queue(), ^
    {
        [aPanel beginSheetModalForWindow:self.view.window completionHandler:^(NSInteger result)
        {
            if (result == NSFileHandlingPanelOKButton)
            {
                for (NSURL *folderPath in [aPanel URLs])
                {
                    [files addObject:[folderPath path]];
                }
            }
        }];
    });

//Filter method handle
    - (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url {
        BOOL result = YES;
        for (NSString *urlPath in files) {
            result  = result && ( [url.path hasPrefix:urlPath] ||  [urlPath isEqualTo:url.path] ? NO : YES);
        }
        return result;
    }

Here files is old selected folder list having string type paths


Solution

  • Have you added NSLog() calls, or used the debugger, to see what is going on? Think again about the conditions under which you need shouldEnableURL to return YES/NO. For example consider:

    • I think you want to return YES if any of the paths in files and the URL being checked meet some condition. Any suggests or (||) yet your logic uses and (&&). Also any suggests you can return directly within the loop as once your condition is met with one path from files there is no need to test the others.
    • Use of the ternary conditional operator ? :
      • What is the precedence of this compared to ||, i.e. does your expression evaluate as (a || b) ? NO : YES or as a || (b ? NO : YES)?
      • Don't write e ? NO : YES, instead use the Boolean not operator as in !e

    By considering the above and using NSLog()/the debugger you should quickly be able to determine the logic required to return the Boolean value you need (whatever it is).

    HTH