[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] NSApplication -beginSheet:*:*:*:*:

From: Kazunobu Kuriyama
Subject: Re: [PATCH] NSApplication -beginSheet:*:*:*:*:
Date: Thu, 19 Feb 2004 14:04:30 +0900
User-agent: Mozilla/5.0 (X11; U; Linux i686; ja-JP; rv:1.4) Gecko/20030624 Netscape/7.1

Kazunobu Kuriyama wrote:

>However, the "wrong" cast might be due to some historical
>reason or something else I don't know about. If so, the
>patch would rather be harmful to the existing code.
>So I would be happy if someone could look into this point.
>- Kazunobu Kuriyama
I did it a little bit by myself and found the previous patch
doesn't work properly if, for example, NSApplication's
-endSheet:returnCode is used.

The bug was introduced by my fault assumption on the return
values of NSApplication's runModalForWindow:. I wrongly
assumed their possible values were NSRunStoppedResponse,
NSRunAbortedResponse, and NSRunContinuesResponse.

The attached patch corrects this.

I tried the new patch with example programs in Chapters 13
and 20 of Aaron Hillegass's "Cocoa Programming for Mac OS X",
and found it works fine not only for NSSavePanel/NSOpenPanel
but also for a sheet inherited directly from NSWindow.

- Kazunobu Kuriyama
Index: NSApplication.m
RCS file: /cvsroot/gnustep/gnustep/core/gui/Source/NSApplication.m,v
retrieving revision 1.261
diff -u -r1.261 NSApplication.m
--- NSApplication.m     27 Jan 2004 04:54:59 -0000      1.261
+++ NSApplication.m     19 Feb 2004 04:06:00 -0000
@@ -56,6 +56,7 @@
 #include "AppKit/NSPasteboard.h"
 #include "AppKit/NSFontManager.h"
 #include "AppKit/NSPanel.h"
+#include "AppKit/NSSavePanel.h"
 #include "AppKit/NSEvent.h"
 #include "AppKit/NSImage.h"
 #include "AppKit/NSMenu.h"
@@ -1432,25 +1433,44 @@
   return [self runModalForWindow: theWindow];
+typedef void (*DidEndMethodType)(id, SEL, id, int, void *);
 - (void) beginSheet: (NSWindow *)sheet
      modalForWindow: (NSWindow *)docWindow
       modalDelegate: (id)modalDelegate
      didEndSelector: (SEL)didEndSelector
        contextInfo: (void *)contextInfo
-  // FIXME
-  int ret;
-  ret = [self runModalForWindow: sheet 
-             relativeToWindow: docWindow];
+  int ret = [self runModalForWindow: sheet
+                  relativeToWindow: docWindow];
   if ([modalDelegate respondsToSelector: didEndSelector])
-      void (*didEnd)(id, SEL, int, void*);
+      DidEndMethodType didEnd;     // method for didEndSelector
+      int              retCode;    // passed to didEnd
+      didEnd = (DidEndMethodType)[modalDelegate
+                                   methodForSelector: didEndSelector];
+      if ([sheet isKindOfClass: [NSSavePanel class]])
+       {
+         /* If the sheet is an instance of NSSavePanel or its subclass
+            (NSOpenPanel etc), -runModalForWindow: identically returns
+            NSRunStoppedResponse (0).  On the other hand, retCode is
+            required to be either NSCancelButton (0) or NSOKButton (1)
+            for the class, depending which button, Cancel or OK, was
+            pressed.  Hence, contrary to other sheet classes, the return
+            value of the method cannot be used as the value of retCode.
+            Instead, we use the status of the OK button on the panel. */
+         BOOL status = [[sheet valueForKey: @"_OKButtonPressed"] boolValue];
+         retCode = (status == NO) ? NSCancelButton : NSOKButton;
+       }
+      else
+       {
+         retCode = ret;
+       }
-      didEnd = (void (*)(id, SEL, int, void*))[modalDelegate 
-      didEnd(modalDelegate, didEndSelector, ret, contextInfo);
+      didEnd(modalDelegate, didEndSelector, sheet, retCode, contextInfo);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]