NSOpenPanel question

In order to implement some functionality that customers are asking for, I’m having to switch over to using the NSOpenPanel. So far so good.

However I want it to operate much like OpenDialog does, when calling “showModalWithin”. The closet function I could find is “beginSheetModalForWindow” and using Joe’s blocks plugin I was able to get this working, except it’s not modal! The rat of code continues to execute once the panel has been displayed.

Any tips, advise or suggestions on making it modal?

I don’t think native modals stop code execution. It was super helpful with MacDust because the code could run in a thread while the sheetmodal kept the user from changing any settings (and displayed a progress bar.)

Multiple times I’ve found Xojo’s interrupt code for a modal behavior to be more or less “in my way” since I can’t use a modal to display progress, and then close it when done.

I opened up my snippet library and found beginWithCompletionHandler: which may be of help. This method calls a block after the panel has closed (where you could run whatever you wanted to happen “after” the modal.)

Also, curious, what are the functionality differences between OpenDialog and NSOpenPanel?

Hi Tim,
Thanks for the suggestions. I understand what you mean about a sheet progress window, but in this case it’s an open dialog and so I would rather not have any code executed until the user has made their choice. Basically I want to introduce this without having to change too much of my Xojo application code (which uses the modal sheet version of the OpenDialog quite a lot).

beginWithCompletionHandler fires the block at the end, the same as beginSheetModalForWindow… There has to be something I’m missing.

The main request is to allow the user to select files and folders in a single dialog, as opposed to using two separate dialogs. The second request (in this area) is to select hidden files.

Life is so funny, because I’ve been struggling with the same question on the last weekend. The usual strategy of polling does NOT work. Then I gave up. So if you find a solution I would be interested, too.

What about instead of the step-by-step and pausing on the modal, moving the actions after the modal to a separate method?

// Set up the open panel like it was OpenDialog xOpenPanel.title = "" [...] // onComplete xOpenPanel.completionAction = WeakAddressOf takeMyFiles
and somehow pass the files to takeMyFiles? (clearly this includes your customized opendialog -> NSOpenPanel stuff)

That way there’s nothing else to execute while the user is selecting files.

Currently, how it’s working.

[code]// — Configure the OpenPanel
~
declare sub beginSheetModalForWindow lib AppKit selector “beginSheetModalForWindow:completionHandler:” ( handle as Ptr, window as integer, completionHandler as Ptr )

dim myBlock as Ptr = ObjcBlocks.createBlock( AddressOf completionHandler )

beginSheetModalForWindow( handle, inWindow.handle, myBlock )

objcBLocks.releaseBlock( myBlock )
[/code]

any code directly after objcBlocks.releaseBlock is immediately called once the panel is shown.

The block calls an additional method “completionHandler” only when the panel is closed.

For the time being, I’ve turned it into a class and put my processing in the completionHandler method.

I tried app.currentThread.suspend (but app.currentThread returns nil unless there is actually a thread).

i tried using a loop and then storing the values in the completionHandler and checking them at the end of the loop, completionHandler then never fires, even if I use the dreaded doEvents.

Awesome! There is an option in the NSOpenPanel to resolve Aliases! This means that now when a user selects an Alias I can bookmark the file. As opposed to before, where I can bookmark the Alias, but I don’t have access to the original file :slight_smile:

Imo this should be added to the Xojo opendialog too !
I too struggle with this

We have that in openDialogMBS too.

And for NSOpenPanel to run modal why not use the runModal methods?

See
http://www.monkeybreadsoftware.net/class-nsopenpanelmbs.shtml

AFAIK runModal does indeed display a modal dialog, but not a sheet modal window.

I looked this morning and couldn’t find the documentation for a NSOpenPanel in the MBS, which is why I embarked on making my own.

Just had a look at your docs, compared with Apple’s docs, all the runModal except runModal were deprecated in 10.6.

https://developer.apple.com/library/prerelease/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSSavePanel_Class/index.html#//apple_ref/occ/cl/NSSavePanel

I played with this a bit and I think Modal means something different for sheets. This seems to speak to that idea…
https://developer.apple.com/library/mac/documentation/cocoa/Conceptual/Sheets/Concepts/AboutSheets.html

and

runModal does the application modal style but of course they can’t be sheets. It might be better to switch to an event based implementation instead of fighting apples design, again assuming this is correctly interpreted. :slight_smile:

@William: Grr… thanks for the info. Like the beloved “ThreadAccessingUIException” this means more spaghetti code.

@Will Shank it certainly seems to operate that way.

And yes it does seemed to make spaghetti code… AddHandler to the rescue.

I updated my feedback request for the handle to the underlying NSSavePanel, to include the OpenDialog exposing the handle to the underlying NSOpenPanel. Please sign on.

feedback://showreport?report_id=30959