diff options
| author | Lakshmi Shanmugam | 2021-02-08 23:28:49 +0000 |
|---|---|---|
| committer | Lakshmi P Shanmugam | 2021-02-09 22:19:46 +0000 |
| commit | 6200f83b8527d9fc8a48005cdd1b0626f1933490 (patch) | |
| tree | 91204ce156298acb09fc808f0234c6608694274f | |
| parent | 6bed44d9f31533564d66ec5b749a579262309923 (diff) | |
| download | eclipse.platform.swt-6200f83b8527d9fc8a48005cdd1b0626f1933490.tar.gz eclipse.platform.swt-6200f83b8527d9fc8a48005cdd1b0626f1933490.tar.xz eclipse.platform.swt-6200f83b8527d9fc8a48005cdd1b0626f1933490.zip | |
Bug 567754 - File dialog does not change file name when switching file
type
As of macOS 10.15, all apps have the sandbox versions of the Open/Save
panels even if they are not sandboxed. This means you can't
setNameFieldStringValue; an unsecure app might change the filename when
the user was not expecting it.
Use setAllowedFileType for NSSavePanel, instead of trying to explicitly
append the selected extension.
The side effect of using setAllowedFileType is that if a multi-part
extension (such as tar.gz) is selected in Save Dialog's extension
pop-up, only the last part (gz) is considered as the extension. This is
because, Mac doesn't support multi-part extensions, it only
considers the last part of the extension.
Change-Id: I7df8dd81d44bbf1d04f6275dc54933da66ad7f6b
5 files changed, 68 insertions, 64 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/FoundationFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/FoundationFull.bridgesupport.extras index 3f0f40bb04..5579aeeb55 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/FoundationFull.bridgesupport.extras +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/FoundationFull.bridgesupport.extras @@ -391,6 +391,11 @@ <arg swt_gen="true"></arg> <retval swt_gen="true"></retval> </method> + <method selector="insertObject:atIndex:" swt_gen="true"> + <arg swt_gen="true"></arg> + <arg swt_gen="true"></arg> + <retval swt_gen="true"></retval> + </method> <method selector="removeLastObject" swt_gen="true"> <retval swt_gen="true"></retval> </method> diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSMutableArray.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSMutableArray.java index 1d7d38375f..86e8250137 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSMutableArray.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSMutableArray.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2019 IBM Corporation and others. + * Copyright (c) 2000, 2021 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -45,6 +45,10 @@ public NSMutableArray initWithCapacity(long numItems) { return result == this.id ? this : (result != 0 ? new NSMutableArray(result) : null); } +public void insertObject(id anObject, long index) { + OS.objc_msgSend(this.id, OS.sel_insertObject_atIndex_, anObject != null ? anObject.id : 0, index); +} + public void removeLastObject() { OS.objc_msgSend(this.id, OS.sel_removeLastObject); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java index ec6ba7ae8d..6b0336bc1e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java @@ -1286,6 +1286,7 @@ public static final long sel_insertColor_key_atIndex_ = Selector.sel_insertColor public static final long sel_insertItem_atIndex_ = Selector.sel_insertItem_atIndex_.value; public static final long sel_insertItemWithItemIdentifier_atIndex_ = Selector.sel_insertItemWithItemIdentifier_atIndex_.value; public static final long sel_insertItemWithObjectValue_atIndex_ = Selector.sel_insertItemWithObjectValue_atIndex_.value; +public static final long sel_insertObject_atIndex_ = Selector.sel_insertObject_atIndex_.value; public static final long sel_insertTabViewItem_atIndex_ = Selector.sel_insertTabViewItem_atIndex_.value; public static final long sel_insertText_ = Selector.sel_insertText_.value; public static final long sel_insertText_replacementRange_ = Selector.sel_insertText_replacementRange_.value; diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/Selector.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/Selector.java index 01082e35d5..66e88bf837 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/Selector.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/Selector.java @@ -559,6 +559,7 @@ public enum Selector { , sel_insertItem_atIndex_("insertItem:atIndex:") , sel_insertItemWithItemIdentifier_atIndex_("insertItemWithItemIdentifier:atIndex:") , sel_insertItemWithObjectValue_atIndex_("insertItemWithObjectValue:atIndex:") + , sel_insertObject_atIndex_("insertObject:atIndex:") , sel_insertTabViewItem_atIndex_("insertTabViewItem:atIndex:") , sel_insertText_("insertText:") , sel_insertText_replacementRange_("insertText:replacementRange:") diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/FileDialog.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/FileDialog.java index dbe3ce1cd8..ad7dbd00a2 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/FileDialog.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/FileDialog.java @@ -60,6 +60,7 @@ public class FileDialog extends Dialog { long methodImpl_performKeyEquivalent = 0; boolean overwrite = false; static final char EXTENSION_SEPARATOR = ';'; + private String selectedExtension; /** * Constructs a new instance of this class given only its parent. @@ -134,37 +135,15 @@ long _performKeyEquivalent (long id, long sel, long event) { } /** - * Appends the extension to the filename, only if the filename has no extension already. - */ -private NSString appendExtension (NSString filename, String extension) { - if (filename != null && extension != null) { - NSString ext = filename.pathExtension(); - if (ext == null || ext.length() == 0) { - filename = filename.stringByAppendingPathExtension(NSString.stringWith(extension)); - } - } - return filename; -} - -/** * Appends the extension selected in the filter pop-up to the filename, * only if the filename has no extension already. */ private NSString appendSelectedExtension (NSString filename) { String extension = getSelectedExtension(); - return appendExtension(filename, extension); -} - -/** - * Returns the filename without the extension from the full file path. - */ -private NSString fileNameWithoutExtension (NSString filePath) { - NSString filename = filePath.lastPathComponent(); - if (filename != null) { + if (filename != null && extension != null) { NSString ext = filename.pathExtension(); - while (ext != null && ext.length() > 0) { - filename = filename.stringByDeletingPathExtension(); - ext = filename.pathExtension(); + if (ext == null || ext.length() == 0) { + filename = filename.stringByAppendingPathExtension(NSString.stringWith(extension)); } } return filename; @@ -263,26 +242,44 @@ public boolean getOverwrite () { * Returns null if no extension is selected or if the selected filter is * or *.* */ private String getSelectedExtension () { - if (popup != null) { - filterIndex = (int)popup.indexOfSelectedItem(); - } else { - filterIndex = -1; - } + return selectedExtension; +} + +private NSMutableArray getSelectedExtensions () { + int filterIndex = popup != null ? (int)popup.indexOfSelectedItem() : -1; if (filterExtensions != null && filterExtensions.length != 0) { if (0 <= filterIndex && filterIndex < filterExtensions.length) { String exts = filterExtensions [filterIndex]; - int length = exts.length (); int index = exts.indexOf (EXTENSION_SEPARATOR); - if (index == -1) index = length; - String filter = exts.substring (0, index).trim (); - if (!filter.equals ("*") && !filter.equals ("*.*")) { - if (filter.startsWith ("*.")) { - filter = filter.substring (2); - } else if (filter.startsWith (".")) { - filter = filter.substring (1); + String[] extensions = index != -1 ? exts.split(";") : new String[] {exts}; + + int length = extensions.length; + NSMutableArray allowedFileTypes = NSMutableArray.arrayWithCapacity(length); + for (int j = length - 1; j >= 0; j--) { + String ext = extensions[j]; + String filter = ext.trim (); + if (!filter.equals ("*") && !filter.equals ("*.*")) { + if (filter.startsWith ("*.")) { + filter = filter.substring (2); + } else if (filter.startsWith (".")) { + filter = filter.substring (1); + } + selectedExtension = filter; + /* + * Mac doesn't support multi-part extensions, use only the last part as + * extension in this case. + */ + int i = filter.lastIndexOf("."); + if (i != -1 && ((i + 1) < filter.length())) { + filter = filter.substring(i + 1); + } + allowedFileTypes.insertObject(NSString.stringWith(filter), 0); + } else { + selectedExtension = null; + return null; } - return filter; } + return allowedFileTypes; } } return null; @@ -295,6 +292,8 @@ void handleResponse (long response) { Display display = parent != null ? parent.getDisplay() : Display.getCurrent(); display.setModalDialog(null); + filterIndex = popup != null ? (int)popup.indexOfSelectedItem() : -1; + if (response == OS.NSFileHandlingPanelOKButton) { NSString filename = panel.filename(); if ((style & SWT.SAVE) != 0) { @@ -376,6 +375,14 @@ public String open () { } panel.setCanCreateDirectories(true); + panel.setTitle(NSString.stringWith(title != null ? title : "")); + if (filterPath != null && filterPath.length() > 0) { + NSString dir = NSString.stringWith(filterPath); + panel.setDirectoryURL(NSURL.fileURLWithPath(dir)); + } + if (fileName != null && fileName.length() > 0) { + panel.setNameFieldStringValue(NSString.stringWith(fileName)); + } /* * This line is intentionally commented. Don't show hidden files forcefully, * instead allow File dialog to use the system preference. @@ -411,23 +418,14 @@ public String open () { panel.setAccessoryView(widget); popup = widget; panel.setTreatsFilePackagesAsDirectories(shouldTreatAppAsDirectory(filterExtensions[selectionIndex])); + if ((style & SWT.SAVE) != 0) { + NSArray extensions = getSelectedExtensions(); + if (extensions != null) panel.setAllowedFileTypes(extensions); + panel.setAllowsOtherFileTypes(true); + } } else { panel.setTreatsFilePackagesAsDirectories(false); } - panel.setTitle(NSString.stringWith(title != null ? title : "")); - if (filterPath != null && filterPath.length() > 0) { - NSString dir = NSString.stringWith(filterPath); - panel.setDirectoryURL(NSURL.fileURLWithPath(dir)); - } - if (fileName != null && fileName.length() > 0) { - panel.setNameFieldStringValue(NSString.stringWith(fileName)); - } - NSString nameFieldStringValue = panel.nameFieldStringValue(); - if (nameFieldStringValue != null) { - nameFieldStringValue = appendSelectedExtension(nameFieldStringValue); - panel.setNameFieldStringValue(nameFieldStringValue); - } - Display display = parent != null ? parent.getDisplay() : Display.getCurrent(); display.setModalDialog(this, panel); if (parent != null && (style & SWT.SHEET) != 0) { @@ -541,17 +539,12 @@ void sendSelection (long id, long sel, long arg) { String fileTypes = filterExtensions[(int)popup.indexOfSelectedItem ()]; panel.setTreatsFilePackagesAsDirectories (shouldTreatAppAsDirectory (fileTypes)); - /* Update the name field in the dialog with the correct extension */ + /* + * Update the allowed file types in the dialog. If extension is not hidden, this + * updates the extension in the name field. + */ if ((style & SWT.SAVE) != 0) { - String selectedExt = getSelectedExtension(); - if (selectedExt != null) { - NSString filePath = panel.filename(); - if (filePath != null) { - NSString filenameNoExt = fileNameWithoutExtension(filePath); - NSString filename = appendExtension(filenameNoExt, selectedExt); - if (filename != null) panel.setNameFieldStringValue(filename); - } - } + panel.setAllowedFileTypes(getSelectedExtensions()); return; } } |
