PDA

View Full Version : Displaying a Progress Sheet




knightlie
May 14, 2012, 02:20 AM
I have a task object which carries out an operation which takes an undetermined amount of time, so I want to display a "working" message in a sheet along with an indeterminate progress bar. The Task object has a reference to an NSDocument-subclass which has methods for showing and hiding the sheet in the document window.

When I call the sheet opening method nothing happens because I'm hogging the event loop - how do I call the method in such a way as to have the sheet appear? I assume it's something along the lines of a performSelector: method, but I can't find which one to use.



JoshDC
May 14, 2012, 05:37 AM
I take it you're using NSTask's -waitUntilExit method? It's this which is causing the application to become unresponsive. If you're targeting 10.7, you can use NSTask's terminationHandler to perform actions after it's finished. Otherwise you can register your document to be notified when the task ends:

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/OperatingSystem/Tasks/endingtask.html#//apple_ref/doc/uid/20000804

knightlie
May 14, 2012, 09:00 AM
I take it you're using NSTask's -waitUntilExit method? It's this which is causing the application to become unresponsive. If you're targeting 10.7, you can use NSTask's terminationHandler to perform actions after it's finished. Otherwise you can register your document to be notified when the task ends:

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/OperatingSystem/Tasks/endingtask.html#//apple_ref/doc/uid/20000804

Nothing that complicated. The NSDocument subclass simply calls an execute method of a class which carries out an operation, say cloning selected entities, and this class may or may not need to show the progress sheet. I need to be able to call the NSDocument subclass' showProgressSheet method and have the sheet actually appear. I may also need to update the progress bat on that sheet in the same way.

In .NET I'd call Application.DoEvents, in Delphi I'd call Application.processMessages.

jared_kipe
May 14, 2012, 09:38 AM
You could detach a new thread, and have that thread perform methods on the main thread to display and manipulate the sheet.

JoshDC
May 14, 2012, 09:43 AM
My bad, saw "task object" and assumed NSTask. There's no equivalent to DoEvents, so you're probably best doing it on a separate thread. The objects NSOperationQueue, NSOperation and its subclasses are likely the easiest way to do this. The Concurrency Programming Guide (https://developer.apple.com/library/mac/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40008091-CH1-SW1) from Apple will help.

If you're using Core Data, it isn't thread-safe by default so requires additional considerations.

knightlie
May 14, 2012, 02:26 PM
Okay, I think NSOperationQueue is what I need, with operations to show the sheet, do the work and hide the sheet. Thanks for your help guys.