39 ! |
41 ! |
40 |
42 |
41 Object subclass:#MonitorInfo |
43 Object subclass:#MonitorInfo |
42 instanceVariableNames:'screenX screenY screenW screenH workX workY workW workH isPrimary |
44 instanceVariableNames:'screenX screenY screenW screenH workX workY workW workH isPrimary |
43 name' |
45 name' |
|
46 classVariableNames:'' |
|
47 poolDictionaries:'' |
|
48 privateIn:WinWorkstation |
|
49 ! |
|
50 |
|
51 Object subclass:#NativeFileDialogReturnData |
|
52 instanceVariableNames:'targetFileOrDirectory multiSelectBaseNames selectedFilterIndex' |
44 classVariableNames:'' |
53 classVariableNames:'' |
45 poolDictionaries:'' |
54 poolDictionaries:'' |
46 privateIn:WinWorkstation |
55 privateIn:WinWorkstation |
47 ! |
56 ! |
48 |
57 |
946 typedef struct fileDialogDataStruct { |
955 typedef struct fileDialogDataStruct { |
947 wchar_t filename[1000 * MAX_PATH]; // big buffer to support multiselect |
956 wchar_t filename[1000 * MAX_PATH]; // big buffer to support multiselect |
948 wchar_t directory[MAX_PATH]; |
957 wchar_t directory[MAX_PATH]; |
949 wchar_t title[MAX_PATH]; |
958 wchar_t title[MAX_PATH]; |
950 HWND owningWindow; |
959 HWND owningWindow; |
951 wchar_t filter[MAX_PATH]; |
960 wchar_t filter[10 * MAX_PATH]; // there could be many filters |
952 int filterIndex; |
961 int filterIndex; |
953 BOOL trueForSave; |
962 BOOL trueForSave; |
954 BOOL trueForMultiSelect; |
963 BOOL trueForMultiSelect; |
955 BOOL trueForPromptOverwrite; |
964 BOOL trueForPromptOverwrite; |
956 |
965 |
16626 "opens a native windows file dialog, |
16637 "opens a native windows file dialog, |
16627 supports unicode 16 strings (like windows does it for filenames) |
16638 supports unicode 16 strings (like windows does it for filenames) |
16628 returns nil or the full path to the selected file |
16639 returns nil or the full path to the selected file |
16629 see example at the end of the method code" |
16640 see example at the end of the method code" |
16630 |
16641 |
16631 |dialogTitle defaultBaseName defaultDirectory owningViewId windowGroup filterString null |
16642 |dialogTitle defaultBaseName defaultDirectory owningViewId windowGroup filterString filterArrayOrPairs |
16632 dataAddressAndThreadAddress dataAddress returnValue| |
16643 null filterStringParts |
|
16644 dataAddressAndThreadAddress dataAddress returnValue |
|
16645 nativeFileDialogReturnData targetFileOrDirectory multiSelectBaseNames selectedSuffixInfo selectedSuffix |
|
16646 needsSlash| |
16633 |
16647 |
16634 dialogTitleArg notEmptyOrNil ifTrue:[ |
16648 dialogTitleArg notEmptyOrNil ifTrue:[ |
16635 dialogTitle := dialogTitleArg asUnicode16String. |
16649 dialogTitle := dialogTitleArg asUnicode16String. |
16636 ]. |
16650 ]. |
16637 |
16651 |
16653 owningViewId := owningTopView id. |
16667 owningViewId := owningTopView id. |
16654 windowGroup := owningTopView windowGroup. |
16668 windowGroup := owningTopView windowGroup. |
16655 ]. |
16669 ]. |
16656 |
16670 |
16657 filterStringOrArrayOfPairs notEmptyOrNil ifTrue:[ |
16671 filterStringOrArrayOfPairs notEmptyOrNil ifTrue:[ |
16658 filterStringOrArrayOfPairs isString ifTrue:[ |
16672 null := (String new:1) |
16659 filterString := filterStringOrArrayOfPairs. |
16673 at:1 put:Character null; |
16660 ] ifFalse:[ |
16674 yourself. |
16661 null := (String new:1) |
16675 |
16662 at:1 put:Character null; |
16676 filterStringOrArrayOfPairs notNil ifTrue:[ |
16663 yourself. |
16677 filterStringOrArrayOfPairs isString ifTrue:[ |
16664 |
16678 filterString := filterStringOrArrayOfPairs. |
16665 filterString := ((filterStringOrArrayOfPairs |
16679 filterArrayOrPairs := OrderedCollection new. |
16666 collect:[:eachPair | |
16680 filterStringParts := filterStringOrArrayOfPairs subStrings:null. |
16667 eachPair first, null, eachPair second, null |
16681 |
16668 ]) |
16682 1 |
16669 asStringWith:''), null. |
16683 to:filterStringParts size |
|
16684 by:2 |
|
16685 do:[:index | |
|
16686 filterArrayOrPairs |
|
16687 add:(Array |
|
16688 with:(filterStringParts at:index) |
|
16689 with:(filterStringParts at:index + 1)). |
|
16690 ]. |
|
16691 ] ifFalse:[ |
|
16692 filterArrayOrPairs := filterStringOrArrayOfPairs. |
|
16693 filterString := ((filterStringOrArrayOfPairs |
|
16694 collect:[:eachPair | |
|
16695 eachPair first, null, eachPair second, null |
|
16696 ]) |
|
16697 asStringWith:''), null. |
|
16698 ]. |
|
16699 |
|
16700 filterString := filterString asUnicode16String. |
16670 ]. |
16701 ]. |
16671 |
|
16672 filterString := filterString asUnicode16String. |
|
16673 ]. |
16702 ]. |
16674 |
16703 |
16675 [ |
16704 [ |
16676 dataAddressAndThreadAddress := self |
16705 dataAddressAndThreadAddress := self |
16677 primNativeFileDialogWithTitle:dialogTitle |
16706 primNativeFileDialogWithTitle:dialogTitle |
16721 threadHandleAddress:dataAddressAndThreadAddress second. |
16750 threadHandleAddress:dataAddressAndThreadAddress second. |
16722 ]. |
16751 ]. |
16723 ]. |
16752 ]. |
16724 |
16753 |
16725 returnValue isEmptyOrNil ifTrue:[ |
16754 returnValue isEmptyOrNil ifTrue:[ |
|
16755 "dialog was aborted" |
16726 ^ nil |
16756 ^ nil |
16727 ]. |
16757 ]. |
16728 |
16758 |
16729 ^ returnValue |
16759 nativeFileDialogReturnData := returnValue. |
|
16760 targetFileOrDirectory := nativeFileDialogReturnData targetFileOrDirectory. |
|
16761 multiSelectBaseNames := nativeFileDialogReturnData multiSelectBaseNames. |
|
16762 multiSelectBaseNames notEmptyOrNil ifTrue:[ |
|
16763 needsSlash := targetFileOrDirectory last ~= $\. |
|
16764 |
|
16765 ^ (multiSelectBaseNames |
|
16766 subStrings:$|) |
|
16767 reject:[:each | each isEmptyOrNil] |
|
16768 thenCollect:[:each | |
|
16769 needsSlash ifTrue:[ |
|
16770 targetFileOrDirectory, '\', each |
|
16771 ] ifFalse:[ |
|
16772 targetFileOrDirectory, each |
|
16773 ] |
|
16774 ] |
|
16775 ]. |
|
16776 |
|
16777 (filterArrayOrPairs notEmptyOrNil |
|
16778 and:[targetFileOrDirectory asFilename suffix isEmptyOrNil]) ifTrue:[ |
|
16779 selectedSuffixInfo := filterArrayOrPairs |
|
16780 at:nativeFileDialogReturnData selectedFilterIndex |
|
16781 ifAbsent:nil. |
|
16782 |
|
16783 selectedSuffixInfo notNil ifTrue:[ |
|
16784 selectedSuffix := (selectedSuffixInfo second |
|
16785 subStrings:'.') |
|
16786 lastIfEmpty:nil. |
|
16787 |
|
16788 (selectedSuffix notNil |
|
16789 and:[selectedSuffix ~= '*']) ifTrue:[ |
|
16790 ^ targetFileOrDirectory, '.', selectedSuffix |
|
16791 ]. |
|
16792 |
|
16793 ]. |
|
16794 ]. |
|
16795 |
|
16796 ^ targetFileOrDirectory |
16730 |
16797 |
16731 " |
16798 " |
16732 ########### example1 without owning view ########## |
16799 ########### example1 without owning view ########## |
16733 |
16800 |
16734 |null| |
16801 |null| |
16743 'expecco Testsuite', null, '*.ets', null, |
16810 'expecco Testsuite', null, '*.ets', null, |
16744 'expecco Logfile', null, '*.elf', null, |
16811 'expecco Logfile', null, '*.elf', null, |
16745 'All', null, '*.*', null, |
16812 'All', null, '*.*', null, |
16746 null |
16813 null |
16747 filterIndex:3 |
16814 filterIndex:3 |
16748 trueForSave:false |
16815 trueForSave:true |
16749 trueForMultiSelect:nil |
16816 trueForMultiSelect:nil |
16750 trueForPromptOverwrite:nil |
16817 trueForPromptOverwrite:nil |
16751 |
16818 |
16752 ########### example2 without owning view and termination ########## |
16819 ########### example2 without owning view and termination ########## |
16753 |
16820 |
16859 primGetNativeFileDialogResultByDataAddress:dataAddress |
16926 primGetNativeFileDialogResultByDataAddress:dataAddress |
16860 "returns nil if the native file dialog is still open |
16927 "returns nil if the native file dialog is still open |
16861 returns an empty string if the file dialog was canceled |
16928 returns an empty string if the file dialog was canceled |
16862 returns the full path to the user selected file" |
16929 returns the full path to the user selected file" |
16863 |
16930 |
16864 |targetFileOrNil multiSelectValues needsSlash| |
16931 |targetFileOrNil multiSelectValues selectedFilterIndex |
|
16932 nativeFileDialogReturnData| |
16865 |
16933 |
16866 %{ /* STACK: 100000 */ |
16934 %{ /* STACK: 100000 */ |
16867 if (__isExternalAddress(dataAddress)) { |
16935 if (__isExternalAddress(dataAddress)) { |
16868 fileDialogData *pFdd = __externalAddressVal(dataAddress); |
16936 fileDialogData *pFdd = __externalAddressVal(dataAddress); |
16869 |
16937 |
16870 if (pFdd->fileDialogDidReturn) { |
16938 if (pFdd->fileDialogDidReturn) { |
16871 targetFileOrNil = __MKU16STRING(pFdd->filename); |
16939 targetFileOrNil = __MKU16STRING(pFdd->filename); |
16872 |
16940 |
16873 if ((!pFdd->trueForSave) && pFdd->trueForMultiSelect) { |
16941 if (pFdd->trueForSave) { |
16874 int len; |
16942 selectedFilterIndex = __MKINT(pFdd->filterIndex); |
16875 int pos; |
16943 } else { |
16876 |
16944 if (pFdd->trueForMultiSelect) { |
16877 wchar_t buffer[1000 * MAX_PATH]; // big buffer to support multiselect |
16945 int len; |
16878 ZeroMemory(buffer, sizeof(buffer)); |
16946 int pos; |
16879 |
16947 |
16880 len = wcslen(pFdd->filename); |
16948 wchar_t buffer[1000 * MAX_PATH]; // big buffer to support multiselect |
16881 pos = len + 1; |
16949 ZeroMemory(buffer, sizeof(buffer)); |
16882 |
16950 |
16883 while ((len = wcslen(&pFdd->filename[pos])) > 0) { |
16951 len = wcslen(pFdd->filename); |
16884 wcscat(buffer, &pFdd->filename[pos]); |
16952 pos = len + 1; |
16885 wcscat(buffer, L"|"); |
16953 |
16886 pos = pos + len + 1; |
16954 while ((len = wcslen(&pFdd->filename[pos])) > 0) { |
16887 wprintf(L"char '%ls'\n", buffer); |
16955 wcscat(buffer, &pFdd->filename[pos]); |
|
16956 wcscat(buffer, L"|"); |
|
16957 pos = pos + len + 1; |
|
16958 wprintf(L"char '%ls'\n", buffer); |
|
16959 } |
|
16960 |
|
16961 multiSelectValues = __MKU16STRING(buffer); |
16888 } |
16962 } |
16889 |
|
16890 multiSelectValues = __MKU16STRING(buffer); |
|
16891 } |
16963 } |
16892 |
16964 |
16893 free(pFdd); |
16965 free(pFdd); |
16894 } |
16966 } |
16895 } |
16967 } |
16897 |
16969 |
16898 targetFileOrNil isNil ifTrue:[ |
16970 targetFileOrNil isNil ifTrue:[ |
16899 ^ nil |
16971 ^ nil |
16900 ]. |
16972 ]. |
16901 targetFileOrNil isEmpty ifTrue:[ |
16973 targetFileOrNil isEmpty ifTrue:[ |
16902 ^ '' |
16974 ^ '' "/ to exit the while nil loop (indicated file dialog abort) |
16903 ]. |
16975 ]. |
16904 multiSelectValues isEmptyOrNil ifTrue:[ |
16976 |
16905 ^ targetFileOrNil |
16977 ^ NativeFileDialogReturnData new |
16906 ]. |
16978 targetFileOrDirectory:targetFileOrNil; |
16907 |
16979 multiSelectBaseNames:multiSelectValues; |
16908 needsSlash := targetFileOrNil last ~= $\. |
16980 selectedFilterIndex:selectedFilterIndex; |
16909 |
16981 yourself |
16910 ^ (multiSelectValues |
16982 |
16911 subStrings:$|) |
16983 "Modified (comment): / 26-10-2018 / 13:34:50 / sr" |
16912 reject:[:each | each isEmptyOrNil] |
|
16913 thenCollect:[:each | |
|
16914 needsSlash ifTrue:[ |
|
16915 targetFileOrNil, '\', each |
|
16916 ] ifFalse:[ |
|
16917 targetFileOrNil, each |
|
16918 ]. |
|
16919 ] |
|
16920 ! |
16984 ! |
16921 |
16985 |
16922 primNativeFileDialogWithTitle:dialogTitle |
16986 primNativeFileDialogWithTitle:dialogTitle |
16923 defaultBaseName:defaultBaseName |
16987 defaultBaseName:defaultBaseName |
16924 defaultDirectory:defaultDirectory |
16988 defaultDirectory:defaultDirectory |
20074 |
20138 |
20075 workY |
20139 workY |
20076 ^ workY |
20140 ^ workY |
20077 ! ! |
20141 ! ! |
20078 |
20142 |
|
20143 !WinWorkstation::NativeFileDialogReturnData class methodsFor:'documentation'! |
|
20144 |
|
20145 documentation |
|
20146 " |
|
20147 This class is used for the native file dialog. |
|
20148 Its just a better Dictionary to collect all required return data from the native file dialog |
|
20149 |
|
20150 [author:] |
|
20151 sr |
|
20152 |
|
20153 [instance variables:] |
|
20154 |
|
20155 [class variables:] |
|
20156 |
|
20157 [see also:] |
|
20158 |
|
20159 " |
|
20160 ! ! |
|
20161 |
|
20162 !WinWorkstation::NativeFileDialogReturnData methodsFor:'accessing'! |
|
20163 |
|
20164 multiSelectBaseNames |
|
20165 "when multiselect is on, here are the baseNames collected, |
|
20166 their directory is kept in targetFileOrDirectory" |
|
20167 ^ multiSelectBaseNames |
|
20168 |
|
20169 "Modified (comment): / 26-10-2018 / 13:30:04 / sr" |
|
20170 ! |
|
20171 |
|
20172 multiSelectBaseNames:something |
|
20173 "when multiselect is on, here are the baseNames collected, |
|
20174 their directory is kept in targetFileOrDirectory" |
|
20175 multiSelectBaseNames := something. |
|
20176 |
|
20177 "Modified (comment): / 26-10-2018 / 13:30:09 / sr" |
|
20178 ! |
|
20179 |
|
20180 selectedFilterIndex |
|
20181 "this is the index of the filter, which was selected by user (1 based). |
|
20182 only present when save (not open)" |
|
20183 ^ selectedFilterIndex |
|
20184 |
|
20185 "Modified (comment): / 26-10-2018 / 13:30:48 / sr" |
|
20186 ! |
|
20187 |
|
20188 selectedFilterIndex:something |
|
20189 "this is the index of the filter, which was selected by user (1 based). |
|
20190 only present when save (not open)" |
|
20191 selectedFilterIndex := something. |
|
20192 |
|
20193 "Modified (comment): / 26-10-2018 / 13:30:55 / sr" |
|
20194 ! |
|
20195 |
|
20196 targetFileOrDirectory |
|
20197 "the selected file or when mutliselect the directory" |
|
20198 ^ targetFileOrDirectory |
|
20199 |
|
20200 "Modified (comment): / 26-10-2018 / 13:31:13 / sr" |
|
20201 ! |
|
20202 |
|
20203 targetFileOrDirectory:something |
|
20204 "the selected file or when mutliselect the directory" |
|
20205 targetFileOrDirectory := something. |
|
20206 |
|
20207 "Modified (comment): / 26-10-2018 / 13:31:16 / sr" |
|
20208 ! ! |
|
20209 |
20079 !WinWorkstation::PrinterDeviceContextHandle class methodsFor:'documentation'! |
20210 !WinWorkstation::PrinterDeviceContextHandle class methodsFor:'documentation'! |
20080 |
20211 |
20081 documentation |
20212 documentation |
20082 " |
20213 " |
20083 This is used as a finalization handle for printer contexts |
20214 This is used as a finalization handle for printer contexts |