--- a/WinWorkstation.st Fri Oct 26 09:42:08 2018 +0200
+++ b/WinWorkstation.st Fri Oct 26 13:50:02 2018 +0200
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"
COPYRIGHT (c) 1996 by Claus Gittinger
All Rights Reserved
@@ -46,6 +48,13 @@
privateIn:WinWorkstation
!
+Object subclass:#NativeFileDialogReturnData
+ instanceVariableNames:'targetFileOrDirectory multiSelectBaseNames selectedFilterIndex'
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:WinWorkstation
+!
+
DeviceHandle subclass:#PrinterDeviceContextHandle
instanceVariableNames:''
classVariableNames:''
@@ -948,7 +957,7 @@
wchar_t directory[MAX_PATH];
wchar_t title[MAX_PATH];
HWND owningWindow;
- wchar_t filter[MAX_PATH];
+ wchar_t filter[10 * MAX_PATH]; // there could be many filters
int filterIndex;
BOOL trueForSave;
BOOL trueForMultiSelect;
@@ -994,7 +1003,9 @@
hasResult = GetOpenFileNameW(&ofn);
}
- if (!hasResult) {
+ if (hasResult) {
+ pFdd->filterIndex = ofn.nFilterIndex;
+ } else {
ZeroMemory(&pFdd->filename, sizeof(pFdd->filename));
}
@@ -2163,7 +2174,7 @@
}
goto again;
}
- /* fail evtl. später ändern und in st verzögert aufrufen
+ /* fail evtl. später ändern und in st verzögert aufrufen
*/
console_fprintf(stderr, "WinWorkstation [info]: UnregisterClass %s failed.\n",(char*)ev->ev_arg1);
}
@@ -16628,8 +16639,11 @@
returns nil or the full path to the selected file
see example at the end of the method code"
- |dialogTitle defaultBaseName defaultDirectory owningViewId windowGroup filterString null
- dataAddressAndThreadAddress dataAddress returnValue|
+ |dialogTitle defaultBaseName defaultDirectory owningViewId windowGroup filterString filterArrayOrPairs
+ null filterStringParts
+ dataAddressAndThreadAddress dataAddress returnValue
+ nativeFileDialogReturnData targetFileOrDirectory multiSelectBaseNames selectedSuffixInfo selectedSuffix
+ needsSlash|
dialogTitleArg notEmptyOrNil ifTrue:[
dialogTitle := dialogTitleArg asUnicode16String.
@@ -16655,21 +16669,36 @@
].
filterStringOrArrayOfPairs notEmptyOrNil ifTrue:[
- filterStringOrArrayOfPairs isString ifTrue:[
- filterString := filterStringOrArrayOfPairs.
- ] ifFalse:[
- null := (String new:1)
- at:1 put:Character null;
- yourself.
-
- filterString := ((filterStringOrArrayOfPairs
- collect:[:eachPair |
- eachPair first, null, eachPair second, null
- ])
- asStringWith:''), null.
+ null := (String new:1)
+ at:1 put:Character null;
+ yourself.
+
+ filterStringOrArrayOfPairs notNil ifTrue:[
+ filterStringOrArrayOfPairs isString ifTrue:[
+ filterString := filterStringOrArrayOfPairs.
+ filterArrayOrPairs := OrderedCollection new.
+ filterStringParts := filterStringOrArrayOfPairs subStrings:null.
+
+ 1
+ to:filterStringParts size
+ by:2
+ do:[:index |
+ filterArrayOrPairs
+ add:(Array
+ with:(filterStringParts at:index)
+ with:(filterStringParts at:index + 1)).
+ ].
+ ] ifFalse:[
+ filterArrayOrPairs := filterStringOrArrayOfPairs.
+ filterString := ((filterStringOrArrayOfPairs
+ collect:[:eachPair |
+ eachPair first, null, eachPair second, null
+ ])
+ asStringWith:''), null.
+ ].
+
+ filterString := filterString asUnicode16String.
].
-
- filterString := filterString asUnicode16String.
].
[
@@ -16723,10 +16752,48 @@
].
returnValue isEmptyOrNil ifTrue:[
+ "dialog was aborted"
^ nil
].
- ^ returnValue
+ nativeFileDialogReturnData := returnValue.
+ targetFileOrDirectory := nativeFileDialogReturnData targetFileOrDirectory.
+ multiSelectBaseNames := nativeFileDialogReturnData multiSelectBaseNames.
+ multiSelectBaseNames notEmptyOrNil ifTrue:[
+ needsSlash := targetFileOrDirectory last ~= $\.
+
+ ^ (multiSelectBaseNames
+ subStrings:$|)
+ reject:[:each | each isEmptyOrNil]
+ thenCollect:[:each |
+ needsSlash ifTrue:[
+ targetFileOrDirectory, '\', each
+ ] ifFalse:[
+ targetFileOrDirectory, each
+ ]
+ ]
+ ].
+
+ (filterArrayOrPairs notEmptyOrNil
+ and:[targetFileOrDirectory asFilename suffix isEmptyOrNil]) ifTrue:[
+ selectedSuffixInfo := filterArrayOrPairs
+ at:nativeFileDialogReturnData selectedFilterIndex
+ ifAbsent:nil.
+
+ selectedSuffixInfo notNil ifTrue:[
+ selectedSuffix := (selectedSuffixInfo second
+ subStrings:'.')
+ lastIfEmpty:nil.
+
+ (selectedSuffix notNil
+ and:[selectedSuffix ~= '*']) ifTrue:[
+ ^ targetFileOrDirectory, '.', selectedSuffix
+ ].
+
+ ].
+ ].
+
+ ^ targetFileOrDirectory
"
########### example1 without owning view ##########
@@ -16745,7 +16812,7 @@
'All', null, '*.*', null,
null
filterIndex:3
- trueForSave:false
+ trueForSave:true
trueForMultiSelect:nil
trueForPromptOverwrite:nil
@@ -16824,7 +16891,7 @@
"
"Created: / 25-10-2018 / 10:54:52 / sr"
- "Modified: / 26-10-2018 / 09:35:38 / sr"
+ "Modified: / 26-10-2018 / 13:48:31 / sr"
!
primCloseNativeFileDialogByDataAddress:dataAddress
@@ -16861,7 +16928,8 @@
returns an empty string if the file dialog was canceled
returns the full path to the user selected file"
- |targetFileOrNil multiSelectValues needsSlash|
+ |targetFileOrNil multiSelectValues selectedFilterIndex
+ nativeFileDialogReturnData|
%{ /* STACK: 100000 */
if (__isExternalAddress(dataAddress)) {
@@ -16870,24 +16938,28 @@
if (pFdd->fileDialogDidReturn) {
targetFileOrNil = __MKU16STRING(pFdd->filename);
- if ((!pFdd->trueForSave) && pFdd->trueForMultiSelect) {
- int len;
- int pos;
-
- wchar_t buffer[1000 * MAX_PATH]; // big buffer to support multiselect
- ZeroMemory(buffer, sizeof(buffer));
-
- len = wcslen(pFdd->filename);
- pos = len + 1;
-
- while ((len = wcslen(&pFdd->filename[pos])) > 0) {
- wcscat(buffer, &pFdd->filename[pos]);
- wcscat(buffer, L"|");
- pos = pos + len + 1;
- wprintf(L"char '%ls'\n", buffer);
- }
-
- multiSelectValues = __MKU16STRING(buffer);
+ if (pFdd->trueForSave) {
+ selectedFilterIndex = __MKINT(pFdd->filterIndex);
+ } else {
+ if (pFdd->trueForMultiSelect) {
+ int len;
+ int pos;
+
+ wchar_t buffer[1000 * MAX_PATH]; // big buffer to support multiselect
+ ZeroMemory(buffer, sizeof(buffer));
+
+ len = wcslen(pFdd->filename);
+ pos = len + 1;
+
+ while ((len = wcslen(&pFdd->filename[pos])) > 0) {
+ wcscat(buffer, &pFdd->filename[pos]);
+ wcscat(buffer, L"|");
+ pos = pos + len + 1;
+ wprintf(L"char '%ls'\n", buffer);
+ }
+
+ multiSelectValues = __MKU16STRING(buffer);
+ }
}
free(pFdd);
@@ -16899,24 +16971,16 @@
^ nil
].
targetFileOrNil isEmpty ifTrue:[
- ^ ''
- ].
- multiSelectValues isEmptyOrNil ifTrue:[
- ^ targetFileOrNil
- ].
-
- needsSlash := targetFileOrNil last ~= $\.
-
- ^ (multiSelectValues
- subStrings:$|)
- reject:[:each | each isEmptyOrNil]
- thenCollect:[:each |
- needsSlash ifTrue:[
- targetFileOrNil, '\', each
- ] ifFalse:[
- targetFileOrNil, each
- ].
- ]
+ ^ '' "/ to exit the while nil loop (indicated file dialog abort)
+ ].
+
+ ^ NativeFileDialogReturnData new
+ targetFileOrDirectory:targetFileOrNil;
+ multiSelectBaseNames:multiSelectValues;
+ selectedFilterIndex:selectedFilterIndex;
+ yourself
+
+ "Modified (comment): / 26-10-2018 / 13:34:50 / sr"
!
primNativeFileDialogWithTitle:dialogTitle
@@ -19692,7 +19756,7 @@
}
%}
"
- (StandardSystemView new label:'äöü') open
+ (StandardSystemView new label:'äöü') open
"
!
@@ -20076,6 +20140,73 @@
^ workY
! !
+!WinWorkstation::NativeFileDialogReturnData class methodsFor:'documentation'!
+
+documentation
+"
+ This class is used for the native file dialog.
+ Its just a better Dictionary to collect all required return data from the native file dialog
+
+ [author:]
+ sr
+
+ [instance variables:]
+
+ [class variables:]
+
+ [see also:]
+
+"
+! !
+
+!WinWorkstation::NativeFileDialogReturnData methodsFor:'accessing'!
+
+multiSelectBaseNames
+ "when multiselect is on, here are the baseNames collected,
+ their directory is kept in targetFileOrDirectory"
+ ^ multiSelectBaseNames
+
+ "Modified (comment): / 26-10-2018 / 13:30:04 / sr"
+!
+
+multiSelectBaseNames:something
+ "when multiselect is on, here are the baseNames collected,
+ their directory is kept in targetFileOrDirectory"
+ multiSelectBaseNames := something.
+
+ "Modified (comment): / 26-10-2018 / 13:30:09 / sr"
+!
+
+selectedFilterIndex
+ "this is the index of the filter, which was selected by user (1 based).
+ only present when save (not open)"
+ ^ selectedFilterIndex
+
+ "Modified (comment): / 26-10-2018 / 13:30:48 / sr"
+!
+
+selectedFilterIndex:something
+ "this is the index of the filter, which was selected by user (1 based).
+ only present when save (not open)"
+ selectedFilterIndex := something.
+
+ "Modified (comment): / 26-10-2018 / 13:30:55 / sr"
+!
+
+targetFileOrDirectory
+ "the selected file or when mutliselect the directory"
+ ^ targetFileOrDirectory
+
+ "Modified (comment): / 26-10-2018 / 13:31:13 / sr"
+!
+
+targetFileOrDirectory:something
+ "the selected file or when mutliselect the directory"
+ targetFileOrDirectory := something.
+
+ "Modified (comment): / 26-10-2018 / 13:31:16 / sr"
+! !
+
!WinWorkstation::PrinterDeviceContextHandle class methodsFor:'documentation'!
documentation