Hi Wolfgang,
thanks for your patience. I still don't have it working, but I least
understand things a bit better.
Wolfgang Lux wrote:
Riccardo Mottola wrote:
Okay, looks like I have to explain myself once again.
When GNUstep presents a save panel (from the saveDocument, saveDocumentAs, and
saveDocumentTo actions), it ultimately presents an application modal save panel
going through the -runModalSavePanel:withAccessoryView: method. This gets the
default accessory view of the AppKit passed in and allows subclasses to modify
that accessory view or create a different view before calling the super class
implementation in NSDocument, which actually displays the panel.
Apple has switched to using document modals panels (aka sheets) for NSDocument
in MacOS X Public Beta and now calls
-runModalSavePanelForSaveOperation:delegate:didSaveSelector:contextInfo:
instead of -runModalSavePanel:withAccessoryView:. To allow customization of the
save panel, the new method calls -prepareSavePanel:. You can find this
information in Apple's older AppKit release notes.
Now GNUstep implements a strange mixture by calling the new method (and hence
-prepareSavePanel:) when a document save panel is to be presented and then
calling the old method from there.
Thanks for the explanation. GS tries to be compatible with both, but
since the order is different, when it comes up to prepareSavePanel, the
view is not initialized?
So, my idea (not spelled out explicitly) is that you override
-runModalSavePanel:withAccessoryView: to customize the accessory view under
GNUstep and to use -prepareSavePanel: to customize it under Cocoa when
-accessoryView returns a non-nil view.
I tried overriding it in MyDocument.m and it never gets called :(
It is called for me, i.e. on GNUstep not on Cocoa.
I attach my little patch for GS, code is easier than words sometimes.
My goal is to override in MyDocument and call the same method in the
WindowController. In case, i can make one or the other override
conditioned by an #ifdef if necessary.
I did not get a call into runModalSavePanel before because I got an
exception in the controller.
The output I get (with my patch) is:
2012-10-08 13:44:20.989 PRICE[2448] prepareSavePanel
2012-10-08 13:44:20.989 PRICE[2448] prepareSavePanel, original accessory
view class: (null)
2012-10-08 13:44:20.990 PRICE[2448] original content view: (null)
2012-10-08 13:44:20.990 PRICE[2448] new options view: h=-&- v=-&-
<NSView: 0x2b34a3c4> f={x = 1; y = 9; width = 348; height = 86} b={x =
0; y = 0; width = 348; height = 86}
2012-10-08 13:44:20.990 PRICE[2448] runModalSavePanel:
withAccessoryView. We should see this only on GS
2012-10-08 13:44:20.990 PRICE[2448] prepareSavePanel, original accessory
view class: NSView
2012-10-08 13:44:20.990 PRICE[2448] original content view: h=-&- v=--&
<NSView: 0x2b34a3c4> f={x = 0; y = 40; width = 348; height = 86} b={x =
0; y = 0; width = 348; height = 86}
2012-10-08 13:44:20.990 PRICE[2448] new options view: h=-&- v=--&
<NSView: 0x2b34a3c4> f={x = 0; y = 40; width = 348; height = 86} b={x =
0; y = 0; width = 348; height = 86}
2012-10-08 13:44:20.991 PRICE[2448] reported exception - <NSException:
0x2b33e144> NAME:NSInvalidArgumentException
REASON:addSubview:positioned:relativeTo: creates a loop in the views
tree! INFO:(null)
I am trying to take in account the differences between GS and Cocoa
recarding views and boxes, but something is still wrong there. Shouldn't
we in the long run just adopt Cocoa's behaviour?
In any case, i still have the problem that on Cocoa it doesn't work on
the second run for me, so anything is still a bit flaky.
Riccardo
? GS-accessoryView.patch
? PRICE.app
? PRICE.pcproj.backup
? obj
? PRICE.pcproj/multix.project
Index: MyDocument.m
===================================================================
RCS file: /cvsroot/price/PRICE-osx/MyDocument.m,v
retrieving revision 1.80
diff -u -r1.80 MyDocument.m
--- MyDocument.m 7 Oct 2012 20:22:08 -0000 1.80
+++ MyDocument.m 8 Oct 2012 13:46:54 -0000
@@ -366,8 +366,24 @@
[windowController changeSaveType:sender];
}
+
+/* we override this for GNUstep */
+- (NSInteger) runModalSavePanel: (NSSavePanel*)savePanel withAccessoryView:
(NSView*)accessoryView
+
+{
+ NSLog(@"runModalSavePanel: withAccessoryView. We should see this only on
GS");
+ [windowController setCompressionType:[self fileType]];
+ [windowController prepareSavePanel: savePanel];
+
+ /* we finally call super, but reget the accessory view since we changed it */
+ return [super runModalSavePanel:savePanel withAccessoryView:[savePanel
accessoryView]];
+}
+
+
+/* we override this for Cocoa */
- (BOOL) prepareSavePanel:(NSSavePanel *) panel
{
+ NSLog(@"prepareSavePanel");
[windowController setCompressionType:[self fileType]];
return [windowController prepareSavePanel: panel];
}
Index: PRWindowController.m
===================================================================
RCS file: /cvsroot/price/PRICE-osx/PRWindowController.m,v
retrieving revision 1.29
diff -u -r1.29 PRWindowController.m
--- PRWindowController.m 7 Oct 2012 20:22:09 -0000 1.29
+++ PRWindowController.m 8 Oct 2012 13:46:54 -0000
@@ -292,15 +292,29 @@
savePanel = panel;
NSLog (@"prepareSavePanel, original accessory view class: %@", [[panel
accessoryView] class]);
- originalContentView = [(NSBox *)[panel accessoryView] contentView];
+
+ /* Cocoa uses a NSBox, GNUstep does not */
+ if ([[panel accessoryView] isKindOfClass:[NSBox class]])
+ originalContentView = [(NSBox *)[panel accessoryView] contentView];
+ else
+ originalContentView = [panel accessoryView];
+
[originalContentView setFrameOrigin:NSMakePoint(0, 40)];
NSLog(@"original content view: %@", originalContentView);
NSLog(@"new options view: %@", saveOptionsView);
/* views coming froma NIB window need a retain */
[saveOptionsView retain];
- /* extract the view from the NSBox, add the content of the original
accessory view */
- newContentView = [(NSBox *)saveOptionsView contentView];
+
+ /* Cocoa uses a NSBox, GNUstep does not, we reflect this in the respective
GORM and NIB file */
+ if ([saveOptionsView isKindOfClass:[NSBox class]])
+ {
+ /* extract the view from the NSBox, add the content of the original
accessory view */
+ newContentView = [(NSBox *)saveOptionsView contentView];
+ }
+ else
+ newContentView = saveOptionsView;
+
[newContentView addSubview:originalContentView];
[panel setAccessoryView:newContentView];
_______________________________________________
Discuss-gnustep mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/discuss-gnustep