bug-gnustep
[Top][All Lists]
Advanced

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

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


From: Kazunobu Kuriyama
Subject: [PATCH] NSApplication -beginSheet:*:*:*:*:
Date: Wed, 18 Feb 2004 17:33:05 +0900
User-agent: Mozilla/5.0 (X11; U; Linux i686; ja-JP; rv:1.4) Gecko/20030624 Netscape/7.1

Hi,

Attached is a patch against NSApplication's

- (void)beginSheet: (NSWindow *)sheet
modalForWindow: (NSWindow *)docWindow
modalDelegate: (id)modalDelegate
didEndSelector: (SEL)didEndSelector
contextInfo: (void *)contextInfo;

I made the patch so that NSSavePanel/NSOpenPanel's

- (void)beginSheetForDirectory: (NSString *)path
file: (NSString *)name
types: (NSArray *)types
modalForWindow: (NSWindow *)docWindow
modalDelegate: (id)delegate
didEndSelector: (SEL)didEndSelector
contextInfo: (void *)contextInfo;

can properly work.

In the original code, didEndSelector is wrongly cast to
to the function pointer
void (*)(id, SEL, int, void *), (1)
not to the one:
void (*)(id, SEL, id, int, void *) (2)

We need a cast to (2) because, by spec, didEndSelector must
have the signature:

- (void)didEndMethod: (NSWindow *)sheet
returnCode: (int)returnCode
contextInfo: (void)contextInfo;

where didEndMethod is savePanelDidEnd or openPanelDidEnd.

In addition, by spec, the value of the 4th argument of (2)
is expected to be either NSOKButton or NSCancelButton.
However, the original code directly passes the return value
of [NSApplication -runModalForWindow:relativeToWindow:] to it,
which is nothing to do with the status of the buttons on the
panel at all. :-(

Due to these reasons, "didEndMethod" won't work even if
you implement it correctly in your program.

The patch fixes them; it works fine for me. :-)

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
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     18 Feb 2004 07:43:17 -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,6 +1433,8 @@
   return [self runModalForWindow: theWindow];
 }
 
+typedef void (*DidEndSelectorType)(id, SEL, id, int, void *);
+
 - (void) beginSheet: (NSWindow *)sheet
      modalForWindow: (NSWindow *)docWindow
       modalDelegate: (id)modalDelegate
@@ -1442,15 +1445,31 @@
   int ret;
 
   ret = [self runModalForWindow: sheet 
-             relativeToWindow: docWindow];
+              relativeToWindow: docWindow];
+  if (ret != NSRunStoppedResponse)
+    {
+      return;
+    }
 
   if ([modalDelegate respondsToSelector: didEndSelector])
     {
-      void (*didEnd)(id, SEL, int, void*);
-
-      didEnd = (void (*)(id, SEL, int, void*))[modalDelegate 
methodForSelector: 
-                                                                
didEndSelector];
-      didEnd(modalDelegate, didEndSelector, ret, contextInfo);
+      DidEndSelectorType didEnd;
+      BOOL status;
+      int code;            // Either NSCancelButton or NSOKButton is possible.
+
+      if ([sheet isKindOfClass: [NSSavePanel class]] == NO)
+       {
+         return;
+       }
+      // N.B.  The following code explicitly depends on an ivar of NSSavePanel.
+      // This is due to lack of an appropriate accessor to the ivar.
+      status = [[sheet valueForKey: @"_OKButtonPressed"] boolValue];
+      code = (status == NO) ? NSCancelButton : NSOKButton;
+
+      didEnd = (DidEndSelectorType)[modalDelegate
+                                           methodForSelector: didEndSelector];
+      didEnd(modalDelegate, didEndSelector,
+            sheet, code, contextInfo);
     }
 }
 

reply via email to

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