Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

petron

macrumors member
Original poster
May 22, 2009
95
0
Malmo, Sweden
Hi,
I have a NSDocument application.

Recently I added an Modal Dialog at the start up and a side effect appeared.

The Modal Dialog appear and when entering what needed there it is closed, and the main application take over the control. The side effect is that I am not able to close the application after the Modal Dialog has been opened and closed. CMD-Q does not work, In the menu the Quit command is grayed out.

If I do not activate the Modal Dialog there are no problems with the Quit.

Dialog controller looks like this:

Code:
#import "DialogController.h"
@implementation DialogController

- (id)init
{
    [super init];
    return self;
}

- (NSString *)showStartUpDialog:(NSWindow *)window
{
    if (!myStartupDialog) {
        [NSBundle loadNibNamed:@"MyStartUpDialog" owner:self];
    }
    [NSApp beginSheet: myStartupDialog
       modalForWindow: window
        modalDelegate: nil
       didEndSelector: nil
          contextInfo: nil];
    [NSApp runModalForWindow: myStartupDialog];
    // Dialog is up here.
    [NSApp endSheet: myStartupDialog];
    [myStartupDialog orderOut: self];
    return logFileName;
}

- (IBAction)endDialogSheetAndCreate:(id)sender
{
    logFileName = [fileNameField stringValue];
    if ([logFileName length] <= 0) {
        logFileName = nil;
    }
    [NSApp stopModal];
}

- (IBAction)endDialogSheetAndCancel:(id)sender
{
    logFileName = nil;
    [NSApp stopModal];
}
@end

Any tip out there ?

Thanks in advance.
/petron
 
Code:
#import "DialogController.h"
@implementation DialogController

- (id)init
{
    [super init];
    return self;
}
This is wrong. See the "Implementing Initializers" section of this doc:
http://developer.apple.com/mac/libr...nceptual/ObjectiveC/Articles/ocAllocInit.html


Code:
    [NSApp beginSheet: myStartupDialog
       modalForWindow: window
        modalDelegate: nil
       didEndSelector: nil
          contextInfo: nil];
    [NSApp runModalForWindow: myStartupDialog];
This code is wrong. You must choose either a modal sheet or a modal dialog, not both. A modal sheet would be attached to a window and be document-modal. A modal dialog would be free-standing and be application-modal. I can't tell which one you intend.


Code:
    [NSApp endSheet: myStartupDialog];
    [myStartupDialog orderOut: self];
If the earlier modal-beginning code weren't wrong, then this would be wrong. You'd have to end the modalities in the reverse order in which you began them.


Code:
- (IBAction)endDialogSheetAndCreate:(id)sender
{
    logFileName = [fileNameField stringValue];
    if ([logFileName length] <= 0) {
        logFileName = nil;
    }
    [NSApp stopModal];
}

- (IBAction)endDialogSheetAndCancel:(id)sender
{
    logFileName = nil;
    [NSApp stopModal];
}
I can't tell if these are right or wrong or somewhere in between.


If you aren't working from a book, a tutorial, or a working example, you probably should be. You should also read the Companion Guide on working with sheets, and read about the differences between document-modal and application-modal in Apple's Human Interface Guidelines. There are links to all those docs in the NSApplication class reference:

http://developer.apple.com/Mac/libr.../NSApplication_Class/Reference/Reference.html
 
Hi Chown33,
Thanks for the comments.

Part 1. Good point, You are right, the init part is not good one, but it does not make much harm neither. In my case I can drop the whole init part since I do not have any thing to add into the init part. I do not need to override it.

Part 2. I have to admit that I am confused regarding the other comments.

Based on the doc from Apple:

http://developer.apple.com/mac/libr...eptual/Sheets/Tasks/UsingAppModalDialogs.html

My code is very similar. It may be wrong but It would be good to know what do you mean by your comments. I may misunderstood the DOC and mixed up things.

I will try to go through it again and see if I missed the point.
If you compare my code with the Apple's code there are not much differences.
For example The sequence of ..endSheet.. and ..orderOut.. are the same.

Could you please clarify your statement.

I will read the article again and maybe I will understand your comments better.

B.R.
/petron
 
hm, that is odd code by Apple. I've never seen beginSheet and runModalForWindow used together. It's either one or the other.

Anyways, to run a sheet you only need the beginSheet method. To close the sheet, use
Code:
[NSApp endSheet:theWindow];
[theWindow orderOut:nil]; // or some other variation
 
Hi Kainjow,

I' am reading the documentation right now. I did not found any good solutions, but thanks for comments.

I would like to understand what is going on... other wise i will be doing the same problem again and again.

I tried your tip, but it even works worse... No dialog shows up.

/piotr
 
Can you post your updated code? And are you getting any messages in the console?
 
Hi Kainjow,

Not much to add, Since you mentioned that you did not seen this contraction with both beginSheet and runModalForWindow, I tried to remove the runModalForWindow. But then I do not get the dialog window up.

As mentioned before in the original code:
The dialog Window shows up.
The return string get updated when pressing create,
The return string gets nil when pressed cancel.
The dialog ends its live
The mainNSDocument window takes over the control, but what seems wrong that the possibility to quit app is gone. Seems like I have modality problem.
Maybe some hot the stopModal does not work?

If you look at the example from the Apple Docs I did in a very similar way, so the construction is not taken from the air. Though I made something wrong since I still do not understand the whole process.

Thanks for bearing with me...
B.R.
/petron
 
I may have been too quick to call the code wrong. Still, parts of it seem ill-advised at best.

The description accompanying Apple's code makes it clear that this should display a sheet attached to a document window, but the behavior will be app-modal. That's very odd. It's not a normal app-modal dialog, and I don't recall ever seeing an app-modal sheet in any app I've used. Nor have I ever coded a sheet so it acts app-modal. I see no advantage to an app-modal sheet, as opposed to the more common free-standing app-modal dialog window. I think an app-modal sheet would just lead to confusion.

When I've used a free-standing app-modal dialog via runModalForWindow, I invariably call close() on the dialog's NSWindowController, after the modal session has ended. I do not call orderOut on the window.

I have been in situations where a document-modal sheet must be hidden because in that particular case the hiding wasn't done automatically, at the time I wanted it done. In those cases I call orderOut on the sheet to dismiss it.

Instead of removing the runModalWindow code, I suggest removing the beginSheet code and sticking to a plain ordinary free-standing app-modal dialog window. I also suggest calling close on the controller, rather than orderOut on the window.

The problem may not even be in the posted code. It may instead be related to when and where the dialog is presented, i.e. exactly when showStartUpDialog is called. If that's done in the wrong place, then the app may end up in the wrong state. I would put the call in applicationDidFinishLaunching. I have made mistakes that caused the Quit menu-item to be left disabled. There was no single cause I can point to; it depends on what's happening and when.

Finally, it's difficult to investigate the problem or any possible solutions because there isn't enough code to compile, and we'd have to guess what all the missing parts are. Please consider posting the project with its source and xib files. If you can't post the entire project, consider stripping out all except the parts that show the problem and posting that. Obviously, do this on a duplicate of your original project.
 
Hi Chown33
Thanks for the comments .
I am on the run and have the access to the internet only via
iPod touch for a while.
I will start to investigate your ideas when back to my place and
my Mac
merry Xmas
/petron
 
Hi to helpers..

The problems is solved now. I wanted to publish the project but I wanted to make a simple and small one. With a main App and a modal dialog window.

When creating and coping the code I discovered the problem.

The problems has been introduced when creating the second XIB file. I wrongly created the Dialog.XIB using the Application XIB template in the XCODE. One should obviously use either Empty XIB template or Window XIB template.

The application works perfect with published code. The exception is the init method that has been changed.

Thanks for bearing with me.
/petron
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.