Lazarus

Programming => Widgetset => Cocoa => Topic started by: VTwin on May 30, 2020, 09:26:09 pm

Title: [SOLVED] TSaveDialog Cocoa bugs
Post by: VTwin on May 30, 2020, 09:26:09 pm
I see that TSaveDialog TypeChange event not firing bug was fixed. Thanks!

https://bugs.freepascal.org/view.php?id=36024

However, I have noticed a few remaining issues:

1. In Windows changing the type automatically changes the filename. Should this be the default behavior on Cocoa as well?

If not, two workarounds come to mind. One, suppress the Cocoa overwrite prompt, and check for an existing file after calling Execute, if so, display your own overwrite prompt. Two, use the TypeChange event to change the displayed file name. However:

2. Setting Options = [] does not suppress the overwrite prompt, so if I implement my own overwrite prompt, after calling Execute, sometimes the user gets two prompts.

3. The FilterIndex reports a seemingly arbitrary index instead if the correct one. This makes it impossible to change the file name in the TypeChange event so it has the correct extension.

I get the same behavior in current release, fixes, and trunk.

I have attached an example application, and would appreciate if anyone can confirm the behavior.

Thanks,
VTwin

Title: Re: TSaveDialog Cocoa bugs
Post by: skalogryz on May 31, 2020, 12:23:53 am
1. In Windows changing the type automatically changes the filename. Should this be the default behavior on Cocoa as well?
what file name does it change?
Title: Re: TSaveDialog Cocoa bugs
Post by: skalogryz on May 31, 2020, 12:36:21 am
3. The FilterIndex reports a seemingly arbitrary index instead if the correct one.
please try r63254
Title: Re: TSaveDialog Cocoa bugs
Post by: VTwin on May 31, 2020, 12:58:01 am
1. In Windows changing the type automatically changes the filename. Should this be the default behavior on Cocoa as well?
what file name does it change?

It automatically changes the file name displayed in the SaveDialog. For example if it is "test.png" it will be changed to "test.jpg" if that file type is selected. The FileName reported after Execute then will have that extension.
Title: Re: TSaveDialog Cocoa bugs
Post by: VTwin on May 31, 2020, 01:10:14 am
3. The FilterIndex reports a seemingly arbitrary index instead if the correct one.
please try r63254

Excellent. This has solved point 3.

Many thanks!
Title: Re: TSaveDialog Cocoa bugs
Post by: VTwin on May 31, 2020, 01:16:21 am
1. In Windows changing the type automatically changes the filename. Should this be the default behavior on Cocoa as well?
what file name does it change?

I will guess that the TypeChange event on Windows is implemented to change the FileName, similar to the second workaround I gave.
Title: Re: TSaveDialog Cocoa bugs
Post by: skalogryz on May 31, 2020, 01:16:48 am
It automatically changes the file name displayed in the SaveDialog. For example if it is "test.png" it will be changed to "test.jpg" if that file type is selected.
For me Windows SaveDialog only shows the file name without any extension.
(it doesn't matter if I select the existing file or type-in the name).
More over, if I type in "test.txt" (with a filter set to "Any Text (*.txt)|.txt", and then I change the filter, i.e. to "Any RTF file (*.rtf)|.rtf" - the extension disappears completely.

Windows 10.
Title: Re: TSaveDialog Cocoa bugs
Post by: skalogryz on May 31, 2020, 01:22:23 am
2. Setting Options = [] does not suppress the overwrite prompt, so if I implement my own overwrite prompt, after calling Execute, sometimes the user gets two prompts.
There's a particular issue with this one.

There's a sort of a workaround suggested in order to implement the feature
https://stackoverflow.com/questions/1930352/nssavepanel-squelching-the-confirm-replace-dialog/2390780

BUT, this workaround is no longer useful in 10.15 (https://developer.apple.com/documentation/appkit/nsopensavepaneldelegate/1524630-panel?language=objc):
Quote
In macOS 10.15 and later, you cannot change the filename that the user selects. Prior to macOS 10.15, you could sanitize the app's filename to remove undesirable characters or limit its length only if your app wasn't running in a sandbox.
Title: Re: TSaveDialog Cocoa bugs
Post by: VTwin on May 31, 2020, 01:53:34 am
It automatically changes the file name displayed in the SaveDialog. For example if it is "test.png" it will be changed to "test.jpg" if that file type is selected.
For me Windows SaveDialog only shows the file name without any extension.
(it doesn't matter if I select the existing file or type-in the name).
More over, if I type in "test.txt" (with a filter set to "Any Text (*.txt)|.txt", and then I change the filter, i.e. to "Any RTF file (*.rtf)|.rtf" - the extension disappears completely.

Windows 10.

I only have Windows 7 available, but I suspect the difference is that I have "Folder Options - View - Hide extensions for known file types" unchecked. I think the extension is there, but hidden.

Title: Re: TSaveDialog Cocoa bugs
Post by: VTwin on May 31, 2020, 02:07:18 am
2. Setting Options = [] does not suppress the overwrite prompt, so if I implement my own overwrite prompt, after calling Execute, sometimes the user gets two prompts.
There's a particular issue with this one.

There's a sort of a workaround suggested in order to implement the feature
https://stackoverflow.com/questions/1930352/nssavepanel-squelching-the-confirm-replace-dialog/2390780

BUT, this workaround is no longer useful in 10.15 (https://developer.apple.com/documentation/appkit/nsopensavepaneldelegate/1524630-panel?language=objc):
Quote
In macOS 10.15 and later, you cannot change the filename that the user selects. Prior to macOS 10.15, you could sanitize the app's filename to remove undesirable characters or limit its length only if your app wasn't running in a sandbox.

Ok, sigh. Dear Apple, can you please make developers lives more complicated?

In this case, does your fix still allow a file name change in the TypeChange event? Otherwise I'll continue to check after Execute.

Can I also just say that I hate the stupidity of operating systems hiding file extensions?

Thanks,
VTwin
Title: Re: TSaveDialog Cocoa bugs
Post by: skalogryz on May 31, 2020, 03:36:09 am
I will guess that the TypeChange event on Windows is implemented to change the FileName, similar to the second workaround I gave.
You should not need that.
With FilterIndex returning a value properly, LCL should take care of the file extensions handling.
Obviously, the file name specified in the file dialog should not have an extension specified.
Title: Re: TSaveDialog Cocoa bugs
Post by: skalogryz on May 31, 2020, 05:26:44 am
ok. I can see how to make the dialog change extensions, (but only if extension is specified in the file name box). It is a native system feature, yet, it requires the filtering of allowed file types to be rewritten.

Which is a good thing anyway! The proper solution was commented originally, with the comment:
Quote
setAllowedFileTypes generates misterious crashes on dialog close after combobox change if uncommented :(
I guess the time has come to clean it out!
...
upd: Unfortunately, there's another "not so easy". Complex file extensions ".tar.gz" won't work with setAllowedFileTypes.  so, it doesn't seem to happen.
Title: Re: TSaveDialog Cocoa bugs
Post by: VTwin on May 31, 2020, 07:26:15 pm
You should not need that.
With FilterIndex returning a value properly, LCL should take care of the file extensions handling.
Obviously, the file name specified in the file dialog should not have an extension specified.

ok. I can see how to make the dialog change extensions, (but only if extension is specified in the file name box). It is a native system feature, yet, it requires the filtering of allowed file types to be rewritten.

Excellent, yes I can figure out the selected extension without the TypeChange event. But I don't see the file extension changing in the dialog. If the file is named: 'text' and I select the '.jpg' extension, the dialog checks to see if 'text' exists, not 'text.jpg'.

So I still need to check if 'text.jpg' exists after the dialog closes. Therefore the native overwrite prompt does not seem useful, but I can not suppress it. Am I missing something?

If I DO implement the TypeChange event and change SaveDialog1.FileName to have the correct extension, it is not changed in the dialog, so that workaround does not work.

Thanks for your work on this!




Title: Re: TSaveDialog Cocoa bugs
Post by: VTwin on May 31, 2020, 07:34:17 pm
upd: Unfortunately, there's another "not so easy". Complex file extensions ".tar.gz" won't work with setAllowedFileTypes.  so, it doesn't seem to happen.

ChangeFileExt does not play well with '.tar.gz' either!
Title: Re: TSaveDialog Cocoa bugs
Post by: skalogryz on May 31, 2020, 07:43:45 pm
there already was an item about that
https://bugs.freepascal.org/view.php?id=32069

need to find the solution that satisfies both. (pretty much how win32 is working).

The issue as I can see is with macOS 10.15 in the first place.
Due to security issues, the file dialog is being executed in a separate process.

(For me it sounds a horrible software design... What kind of extra permissions are needed just to let a user to pick a file!)

But without this "security" change, some of the SavePanel APIs could be used to make things similar to Win32 behavior. (file extension change...etc...)
But with the "security" fix in place, some of the methods are on save/panel dialog no longer working.
I presume the data changes are not being forwarded to this "secured proxy" dialog. Maybe it will be fixed in the next OSX update?!
Title: Re: TSaveDialog Cocoa bugs
Post by: VTwin on June 01, 2020, 06:51:43 pm
I don't use the drop-in widget as the behavior is so OS dependent. I have a unit with a "RunSaveDlg" routine that creates one in code, with IFDEFs for the OS, and warning dialogs. I can use it in all my projects without having to remember the idiosyncrasies of each OS.

Windows does pretty much as expected, Linux does not give an overwrite warning (as far as I can tell), and Mac does this weird dance that we have been talking about, sometimes causing an extra warning box.

It does sound odd. Linux seems secure enough, what extra does Apple need? I get annoyed with Apple, but still own a few Macs, and it is not an option for me to not support them.

It is all workable, thanks!
TinyPortal © 2005-2018