macOS Save and Open Dialog Classes for accessing more properties

It’s still got some issues. I’m working through the logic to make sure I’m not eliminating events what should be duplicated… like the Validate and UserEnteredFilename events.

It’s an oversight. Thanks for bringing it to my attention.

No problem, the same issue exists in macOSLib as I said. I was beginning to think there was some hidden saving to be had :slight_smile:

Just had a hard crash from it. Unmodified. Pretty sure the sequence was as follows. I’ve created an issue on your repro so you can check it out at your leisure. Full crash log attached to issue.

  • Run
  • Press button 1
  • Change the file type a few times
  • Press cancel
  • Press button 2
  • Click on the show options button
  • Click on the file type
  • Bang!
-------------------------------------
Translated Report (Full Report Below)
-------------------------------------

Process:               My Application.debug [99240]
Path:                  /Users/USER/Downloads/*/My Application.debug.app/Contents/MacOS/My Application.debug
Identifier:            My Application.debug
Version:               ???
Code Type:             ARM-64 (Native)
Parent Process:        launchd [1]
User ID:               504

Date/Time:             2023-02-06 14:26:13.7647 +0000
OS Version:            macOS 13.2 (22D49)
Report Version:        12
Anonymous UUID:        F92937B4-B744-046A-E67E-AC0DEC19787D

Sleep/Wake UUID:       0B8A1D33-59B3-4227-97BE-EA19D97BAE70

Time Awake Since Boot: 900000 seconds
Time Since Wake:       849403 seconds

System Integrity Protection: enabled

Notes:
dyld_process_snapshot_create_for_process failed with 5

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000010
Exception Codes:       0x0000000000000001, 0x0000000000000010

Termination Reason:    Namespace SIGNAL, Code 11 Segmentation fault: 11
Terminating Process:   exc handler [99240]

VM Region Info: 0x10 is not in any region.  Bytes before following region: 105553518919664
      REGION TYPE                    START - END         [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      UNUSED SPACE AT START
--->  
      MALLOC_NANO (reserved)   600018000000-600020000000 [128.0M] rw-/rwx SM=NUL  ...(unallocated)

Error Formulating Crash Report:
dyld_process_snapshot_create_for_process failed with 5

Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib               	       0x1a4d8d820 objc_msgSend + 32
1   My Application.debug          	       0x102b8c48c NSSavePanelGTO.=Filter%%o<NSSavePanelGTO>A1o<FileType> + 5268 (/NSSavePanelGTO:129)
2   My Application.debug          	       0x102b6a2e8 Window1.Window1.SaveAccessories1_FileTypeChanged%%o<Window1.Window1>o<SaveAccessories.SaveAccessories>o<FileType> + 392 (/Window1:173)
3   My Application.debug          	       0x102b75430 Delegate.IM_Invoke%%o<SaveAccessories.SaveAccessories>o<FileType> + 68
4   My Application.debug          	       0x102b7548c AddHandler.Stub.36%%o<FileType> + 72
5   My Application.debug          	       0x102b831bc SaveAccessories.SaveAccessories.FileTypesPopup_SelectionChanged%%o<SaveAccessories.SaveAccessories>o<DesktopPopupMenu>o<DesktopMenuItem> + 608 (/SaveAccessories:51)
6   My Application.debug          	       0x102b84ad4 Delegate.IM_Invoke%%o<DesktopPopupMenu>o<DesktopMenuItem> + 68
7   My Application.debug          	       0x102b84b30 AddHandler.Stub.20%%o<DesktopMenuItem> + 72
8   XojoFramework                 	       0x103b517f4 ComboBox::Change() + 312
9   XojoFramework                 	       0x103b51684 PopupMenu::Change() + 88
10  AppKit                        	       0x1a8606c24 -[NSApplication(NSResponder) sendAction:to:from:] + 440

heh. If you look at the logic in SaveAccessories1.FileTypeChanged, it specifically uses mSaveDialog. Problem is that the other dialogs use their own instances so the object has been closed and is no longer valid. I’ll update the example code to avoid this problem.

1 Like

I’ve merged all of those changes back into main as everything appears to be working as intended now.

2 Likes

I think you’re missing removing the new handlers from the object when it closes:

Private Sub NSSavePanel_ItemsSelected(obj as NSSavePanelGTO, items() as FolderItem)
  // New handlers
  RemoveHandler obj.DirectoryChanged, AddressOf NSSavePanel_DirectoryChanged
  RemoveHandler obj.SelectionChanged, AddressOf NSSavePanel_SelectionChanged
  RemoveHandler obj.ShouldEnableItem, AddressOf NSSavePanel_ShouldEnableItem
  RemoveHandler obj.UserEnteredFilename, AddressOf NSSavePanel_UserEnteredFilename
  RemoveHandler obj.ValidateItem, AddressOf NSSavePanel_ValidateItem
  RemoveHandler obj.WillExpand, AddressOf NSSavePanel_WillExpand
  
  RemoveHandler obj.ItemsSelected, AddressOf NSSavePanel_ItemsSelected
  
  UpdateFileList(items)
  
  label1.Text = "Option 1: " + SaveAccessories1.Option1Value.ToString + _
  " Option 2: " + SaveAccessories1.Option2Value.ToString
End Sub

Yeah, I think I’m going to change those to delegate methods so the class can tell if you’ve implemented them and only register for the methods you want. That way the delegate class and methods can work the way that they’re supposed to, your code won’t have to be altered very much and we can omit with the RemoveHandler calls altogether.

ok, those changes have been made and we’re now using delegates instead of events.

2 Likes

@Greg_O That second issue is still happening in the latest code. Sorry. Please don’t feel you have to look at this right away, I know you’re trying to do something else…

I’ve tracked down the issue and branched, fixed and created a pull request.

2 Likes

My latest discovery is that altering a controls top causes it to vanish. Most likely due to Xojo not being aware of the acccesory views true location. I’m going to look at getting the control frame and work up a solution. I’ll feed back to the repro if I get anything useful.

I’m sorry, altering which control’s top. Controls are positioned relative to the containing view.

If you need to change anything, I suggest either setting a new assessory or using a page panel though.

Controls on the accessory view. I need to enables / disable options based on file type. Ideally I would hide those not relevant to the current type. I was then attempting to close up the gaps. Shrinking the height. All seemed to be ok till I started loosing controls. All properties said they were at the right coordinates and visible, but you can’t see them. I’ll post a layout tomorrow. 2am at the mo.

Make sure the locks are all reset before you resize, but I seem to remember that there’s a method you need to call if the accessory view is going to be resized.

Maybe related to the fact that the Y coordinate starts at bottom on Cocoa?

So, here’s what I’m attempting to do. Currently my application was a window for import and export settings. You choose a file with the standard file picker and then it configures and shows a second dialog box to set your parameters to complete the import. The application handles spreadsheet style datasets. This is the raw dialog in Xojo:

Configured for xlsx files it looks like this:

Configured for text or CSV files is looks like this:

The panel at the bottom is a preview of how the file would look loaded. It updates as you change settings. All of this has been working very well, however, I’ve always wanted to make it into an accessory view.

Looking at the top block of controls some are relevant to more than one file type, others are specific to one type. I’ve been able to make the sheet work fine if I just hide the options that don’t apply. They reappear when needed for a change in type. The dialog will work in two modes. Import and Export. In export mode you choose the file type from the popup menu and set the options, give the file a name and click OK.

In import mode there would be no file type picker, you click on a file and choose the options required, the preview updates, click OK and import happens.

OK, now for the code. I have a enum which maps row numbers to control tops.

Public Enum Rows
Invisible = -1
Row1 = 40
Row2 = 72
Row3 = 104
Row4 = 136
Row5 = 168
Row6 = 200
Row7 = 233
Row8 = 275
End Enum

Each parameter row has a method for locating, hiding, showing its self:

Private Sub SetRowDelimiter(TheRow as Rows)
  If TheRow = Rows.Invisible Then
    lblDelimeter.Visible = False
    popDelimiter.Visible = False
    txtDelimeter.Visible = False
  Else
    lblDelimeter.Visible = True
    popDelimiter.Visible = True
    txtDelimeter.Visible = True
    lblDelimeter.Top = Integer( TheRow )
    popDelimiter.Top = Integer( TheRow )
    txtDelimeter.Top = Integer( TheRow )
  End If  
End Sub

The ConfigureForType method deals with putting the right things in the right place:

Case App.kFileTypeText

  SetRowAll9s Rows.Invisible
  SetRowWorksheets Rows.Invisible
  
  SetRowFileTypes Rows.Row1
  SetRowTranspose Rows.Row2
  SetRowHeadings Rows.Row3
  SetRowMissingValue Rows.Row4
  SetRowDelimiter Rows.Row5
  SetRowEncoding Rows.Row6

  SetRowPreview Rows.Invisible

Everything works fine in a window. If I try and do it in an accessory view then the controls disappear and never reappear in odd patterns when I try and set values to control.top. If I never adjust top then everything is able to show and hide well. Resizing the height of the view works without issue.

I’m going to suggest again that you try a page panel, but I also think you should reconsider the amount of data you’re trying to present. I’m not sure you’d be able to select a file and configure it on an 11" MacBook Air.

Make sure that cast is doing what you think it should. I seem to remember needing to use CType instead of a direct cast in the last few years.

The page panel looks horribly like a windows Wizzard to me. Not at all nice. I’ll have a think. CType does seem to have made a slight improvement. Still looking at it. According to the debugger everything is fine.

As @Arnaud_N mentioned above, things could get wonky because it’s embedded in a non-Xojo view.

Have you tried setting top without changing the value to see if it stays?

For now I’ve given up on moving items around. I’ve a near working example. Export:

Import:

It’s not fully operational, but it is close. I need to get the preview working and making the panel central for export. I think I’ve solved the problem with height, even on an 11" machine with some lateral thinking.