Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLakshmi Shanmugam2019-06-19 10:38:37 +0000
committerLakshmi Shanmugam2019-06-21 08:02:09 +0000
commita4d824f51a06535bde5014bd6d0f86bdd7da903a (patch)
tree567279c14274a4ba43504558955388260498d334
parent16b819334eff1e3f82dcb60bfa8ca7c5d8b144dd (diff)
downloadeclipse.platform.swt-a4d824f51a06535bde5014bd6d0f86bdd7da903a.tar.gz
eclipse.platform.swt-a4d824f51a06535bde5014bd6d0f86bdd7da903a.tar.xz
eclipse.platform.swt-a4d824f51a06535bde5014bd6d0f86bdd7da903a.zip
Bug 443089: Save Dialog doesn't handle files with multipart extensions
Reverted code changes made for Bug 347430. Don't use setAllowedFileType to set the filter extensions to the NSSavePanel as it doesn't support multi-part extensions such as tar.gz. Used delegate method panel:userEnteredFilename:confirmed: to handle the overwrite case when name field has filename without extension. Cocoa APIs in general don't support multi-part extensions. However, SWT FileDialog needs to support them. Hence, add the required extensions manually on save and selection change. Change-Id: I221f75476f1c1d263f64da239845c325b436bfca
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras9
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSSavePanel.java5
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/Selector.java2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java7
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/FileDialog.java157
6 files changed, 133 insertions, 49 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras
index 7b9dae576e..47078eb055 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras
@@ -2809,6 +2809,9 @@
<method selector="filename" swt_gen="true">
<retval swt_gen="true"></retval>
</method>
+ <method selector="nameFieldStringValue" swt_gen="true">
+ <retval swt_gen="true"></retval>
+ </method>
<method selector="runModal" swt_gen="true">
<retval swt_gen="true"></retval>
</method>
@@ -5317,6 +5320,12 @@
<arg swt_gen="true"></arg>
<retval swt_gen="true"></retval>
</method>
+ <method selector="panel:userEnteredFilename:confirmed:" swt_gen="true">
+ <arg swt_gen="true"></arg>
+ <arg swt_gen="true"></arg>
+ <arg swt_gen="true"></arg>
+ <retval swt_gen="true"></retval>
+ </method>
</informal_protocol>
<informal_protocol name="NSOutlineViewDataSource" swt_gen="mixed">
<method selector="outlineView:acceptDrop:item:childIndex:" swt_gen="true">
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSSavePanel.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSSavePanel.java
index f7afd38ea4..8df3efdbd9 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSSavePanel.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSSavePanel.java
@@ -32,6 +32,11 @@ public NSString filename() {
return result != 0 ? new NSString(result) : null;
}
+public NSString nameFieldStringValue() {
+ long result = OS.objc_msgSend(this.id, OS.sel_nameFieldStringValue);
+ return result != 0 ? new NSString(result) : null;
+}
+
public long runModal() {
return OS.objc_msgSend(this.id, OS.sel_runModal);
}
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 65ecd5c95e..2e5314cd3d 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
@@ -1641,6 +1641,7 @@ public static final long sel_moveUp_ = Selector.sel_moveUp_.value;
public static final long sel_mutableCopy = Selector.sel_mutableCopy.value;
public static final long sel_mutableString = Selector.sel_mutableString.value;
public static final long sel_name = Selector.sel_name.value;
+public static final long sel_nameFieldStringValue = Selector.sel_nameFieldStringValue.value;
public static final long sel_needsPanelToBecomeKey = Selector.sel_needsPanelToBecomeKey.value;
public static final long sel_nextEventMatchingMask_untilDate_inMode_dequeue_ = Selector.sel_nextEventMatchingMask_untilDate_inMode_dequeue_.value;
public static final long sel_nextObject = Selector.sel_nextObject.value;
@@ -1714,6 +1715,7 @@ public static final long sel_pageDown_ = Selector.sel_pageDown_.value;
public static final long sel_pageTitle = Selector.sel_pageTitle.value;
public static final long sel_pageUp_ = Selector.sel_pageUp_.value;
public static final long sel_panel_shouldEnableURL_ = Selector.sel_panel_shouldEnableURL_.value;
+public static final long sel_panel_userEnteredFilename_confirmed_ = Selector.sel_panel_userEnteredFilename_confirmed_.value;
public static final long sel_panelConvertFont_ = Selector.sel_panelConvertFont_.value;
public static final long sel_paperSize = Selector.sel_paperSize.value;
public static final long sel_paragraphs = Selector.sel_paragraphs.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 f4ab9558ca..058b4cf9fe 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
@@ -752,6 +752,7 @@ public enum Selector {
, sel_mutableCopy("mutableCopy")
, sel_mutableString("mutableString")
, sel_name("name")
+ , sel_nameFieldStringValue("nameFieldStringValue")
, sel_needsPanelToBecomeKey("needsPanelToBecomeKey")
, sel_nextEventMatchingMask_untilDate_inMode_dequeue_("nextEventMatchingMask:untilDate:inMode:dequeue:")
, sel_nextObject("nextObject")
@@ -825,6 +826,7 @@ public enum Selector {
, sel_pageTitle("pageTitle")
, sel_pageUp_("pageUp:")
, sel_panel_shouldEnableURL_("panel:shouldEnableURL:")
+ , sel_panel_userEnteredFilename_confirmed_("panel:userEnteredFilename:confirmed:")
, sel_panelConvertFont_("panelConvertFont:")
, sel_paperSize("paperSize")
, sel_paragraphs("paragraphs")
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
index 85d658609e..6c17840e06 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Display.java
@@ -2688,6 +2688,8 @@ void initClasses () {
OS.class_addIvar(cls, SWT_OBJECT, size, (byte)align, types);
OS.class_addMethod(cls, OS.sel_sendSelection_, dialogProc3, "@:@");
OS.class_addMethod(cls, OS.sel_panel_shouldEnableURL_, dialogProc4, "@:@@");
+ OS.class_addMethod(cls, OS.sel_panel_userEnteredFilename_confirmed_, dialogProc5, "@:@@");
+
OS.objc_registerClassPair(cls);
className = "SWTOutlineView";
@@ -5758,6 +5760,11 @@ static long dialogProc(long id, long sel, long arg0, long arg1, long arg2) {
if (dialog == null) return 0;
dialog.panelDidEnd_returnCode_contextInfo(id, sel, arg0, arg1, arg2);
}
+ if (sel == OS.sel_panel_userEnteredFilename_confirmed_) {
+ FileDialog dialog = (FileDialog)OS.JNIGetObject(jniRef[0]);
+ if (dialog == null) return 0;
+ return dialog.panel_userEnteredFilename_confirmed(id, sel, arg0, arg1, arg2);
+ }
return 0;
}
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 cb9ab4f46f..aa26a4bbb1 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
@@ -121,6 +121,43 @@ long _overwriteExistingFileCheck (long id, long sel, long str) {
}
/**
+ * 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) {
+ NSString ext = filename.pathExtension();
+ while (ext != null && ext.length() > 0) {
+ filename = filename.stringByDeletingPathExtension();
+ ext = filename.pathExtension();
+ }
+ }
+ return filename;
+}
+
+/**
* Returns the path of the first file that was
* selected in the dialog relative to the filter path, or an
* empty string if no such file has been selected.
@@ -207,6 +244,37 @@ public boolean getOverwrite () {
return overwrite;
}
+/**
+ * Returns the extension selected in the filter pop-up. When the filter has multiple extensions,
+ * the first extension us returned.
+ * 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;
+ }
+ 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);
+ }
+ return filter;
+ }
+ }
+ }
+ return null;
+}
+
void handleResponse (long response) {
if (parent != null && (style & SWT.SHEET) != 0) {
NSApplication.sharedApplication().stopModal();
@@ -214,15 +282,14 @@ void handleResponse (long response) {
Display display = parent != null ? parent.getDisplay() : Display.getCurrent();
display.setModalDialog(null);
- if (popup != null) {
- filterIndex = (int)popup.indexOfSelectedItem();
- } else {
- filterIndex = -1;
- }
-
if (response == OS.NSFileHandlingPanelOKButton) {
NSString filename = panel.filename();
if ((style & SWT.SAVE) != 0) {
+ /*
+ * This code is intentionally commented. The extension is now appended in the
+ * delegate method: panel_userEnteredFilename_confirmed
+ */
+ //filename = appendSelectedExtension(filename);
fullPath = filename.getString();
fileNames = new String [1];
fileName = fileNames [0] = filename.lastPathComponent().getString();
@@ -321,9 +388,6 @@ public String open () {
widget.sizeToFit();
panel.setAccessoryView(widget);
popup = widget;
-
- setAllowedFileType(filterExtensions[selectionIndex]);
- panel.setAllowsOtherFileTypes(true);
panel.setTreatsFilePackagesAsDirectories(shouldTreatAppAsDirectory(filterExtensions[selectionIndex]));
} else {
panel.setTreatsFilePackagesAsDirectories(false);
@@ -336,6 +400,11 @@ public String open () {
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);
@@ -395,6 +464,23 @@ long panel_shouldEnableURL (long id, long sel, long arg0, long arg1) {
return 1;
}
+long panel_userEnteredFilename_confirmed (long id, long sel, long sender, long filename, long okFlag) {
+ /*
+ * From documentation: This delegate method is called when user confirmed
+ * a filename choice by clicking Save in a Save panel. It's called before any
+ * required extension is appended to the filename and before the Save panel asks
+ * the user to replace an existing file, if applicable.
+ *
+ * If the filename in the File Dialog's name field has no extension, then the extension from the filter will be
+ * applied on Save. Add the extension here, so that the NSSavePanel can use this filename with extension
+ * for validation and show the replace existing file dialog, if required.
+ */
+ if (okFlag == 0) return filename;
+ NSString filenameWithExtension = new NSString(filename);
+ filenameWithExtension = appendSelectedExtension(filenameWithExtension);
+ return filenameWithExtension.id;
+}
+
void releaseHandles() {
if (!overwrite) {
if (method != 0) OS.method_setImplementation(method, methodImpl);
@@ -424,52 +510,24 @@ void sendSelection (long id, long sel, long arg) {
if (filterExtensions != null && filterExtensions.length > 0) {
String fileTypes = filterExtensions[(int)popup.indexOfSelectedItem ()];
panel.setTreatsFilePackagesAsDirectories (shouldTreatAppAsDirectory (fileTypes));
- setAllowedFileType (fileTypes);
- }
- panel.validateVisibleColumns ();
-}
-
-void setAllowedFileType (String fileTypes) {
- if (fileTypes == null) return;
-
- StringTokenizer fileTypesToken = new StringTokenizer(fileTypes, String.valueOf(EXTENSION_SEPARATOR));
- NSMutableArray allowedFileTypes = NSMutableArray.arrayWithCapacity(1);
-
- while(fileTypesToken.hasMoreTokens()) {
- String fileType = fileTypesToken.nextToken();
- if (fileType.equals("*") || fileType.equals("*.*")) {
- panel.setAllowedFileTypes(null);
- return;
- }
- if (fileType.startsWith("*.")) {
- fileType = fileType.substring(2);
- } else if (fileType.startsWith(".")) {
- fileType = fileType.substring(1);
- }
- /*
- * In Cocoa, only the part of the file name after the last extension divider (.)
- * is considered as extension. But, SWT FileDialog supports extensions with more than one (.).
- * When files with extensions which have more than 1 separator are filtered, they are not
- * shown as enabled in the File Open Dialog. For example, using tar.gz in the filter
- * extension doesn't show the tar.gz files enabled in the FileDialog.
- *
- * The workaround is for Open FileDialog, add only the extension after the last (.) as the allowed
- * file type. For example, for tar.gz, only gz is added as the allowed file type.
- */
- if ((style & SWT.SAVE) == 0) {
- int index = fileType.lastIndexOf(".");
- if (index != -1 && ((index + 1) < fileType.length())) {
- fileType = fileType.substring(index + 1);
+ /* Update the name field in the dialog with the correct extension */
+ 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);
+ }
}
+ return;
}
- allowedFileTypes.addObject(NSString.stringWith(fileType));
}
-
- panel.setAllowedFileTypes(allowedFileTypes);
+ panel.validateVisibleColumns ();
}
-
/**
* Set the initial filename which the dialog will
* select by default when opened to the argument,
@@ -597,4 +655,5 @@ boolean shouldTreatAppAsDirectory (String extensions) {
}
return true;
}
+
}

Back to the top