Rev 393 | Rev 456 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
259 | daniel-mar | 1 | /* |
2 | This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop |
||
3 | Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au |
||
4 | Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft |
||
5 | |||
6 | This program is free software; you can redistribute it and/or modify |
||
7 | it under the terms of the GNU General Public License as published by |
||
8 | the Free Software Foundation; either version 2 of the License, or |
||
9 | (at your option) any later version. |
||
10 | |||
11 | This program is distributed in the hope that it will be useful, |
||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
14 | GNU General Public License for more details. |
||
15 | |||
16 | You should have received a copy of the GNU General Public License |
||
17 | along with this program; if not, write to the Free Software |
||
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
19 | */ |
||
20 | |||
21 | /* This is PLATFORM INDEPENDENT user interface code - mainly dialog logic */ |
||
22 | |||
23 | #include "ff.h" |
||
365 | daniel-mar | 24 | #include "compat_string.h" |
259 | daniel-mar | 25 | |
26 | int ctls[8],maps[4]; |
||
27 | int checksliders_result; |
||
28 | |||
29 | /* one-time initialisation of dialog box */ |
||
30 | |||
31 | void builddlginit(DIALOGREF dp){ |
||
32 | int i; |
||
33 | char s[0x100]; |
||
34 | |||
35 | if(gdata->parmloaded){ |
||
444 | daniel-mar | 36 | SetDlgItemTextA(dp,CATEGORYITEM, gdata->parm.szCategory); |
37 | SetDlgItemTextA(dp,TITLEITEM, gdata->parm.szTitle); |
||
38 | SetDlgItemTextA(dp,COPYRIGHTITEM,gdata->parm.szCopyright); |
||
39 | SetDlgItemTextA(dp,AUTHORITEM, gdata->parm.szAuthor); |
||
259 | daniel-mar | 40 | for(i=0;i<4;++i){ |
444 | daniel-mar | 41 | SetDlgItemTextA(dp,FIRSTMAPNAMEITEM+i,gdata->parm.szMap[i]); |
259 | daniel-mar | 42 | } |
43 | for(i=0;i<8;++i){ |
||
444 | daniel-mar | 44 | SetDlgItemTextA(dp,FIRSTCTLNAMEITEM+i,gdata->parm.szCtl[i]); |
259 | daniel-mar | 45 | } |
46 | }else{ |
||
47 | /* strictly speaking this is not needed on the Mac, |
||
48 | we can set initial values statically in the rez description */ |
||
444 | daniel-mar | 49 | SetDlgItemTextA(dp,CATEGORYITEM, "Filter Foundry"); |
50 | SetDlgItemTextA(dp,TITLEITEM, "Untitled"); |
||
51 | SetDlgItemTextA(dp,COPYRIGHTITEM,""); //"Filter Foundry Copyright (C) 2003-2009 Toby Thain, 2018-" RELEASE_YEAR " Daniel Marschall" |
||
52 | SetDlgItemTextA(dp,AUTHORITEM, "Anonymous"); |
||
259 | daniel-mar | 53 | strcpy(s,"Map X"); |
54 | for(i = 0; i < 4; ++i){ |
||
55 | s[4] = '0'+i; |
||
444 | daniel-mar | 56 | SetDlgItemTextA(dp,FIRSTMAPNAMEITEM+i,s); |
259 | daniel-mar | 57 | } |
58 | strcpy(s,"ctl(X)"); |
||
59 | for(i = 0; i < 8; ++i){ |
||
60 | s[4] = '0'+i; |
||
444 | daniel-mar | 61 | SetDlgItemTextA(dp,FIRSTCTLNAMEITEM+i,s); |
259 | daniel-mar | 62 | } |
63 | } |
||
64 | |||
65 | checksliders_result = checksliders(4,ctls,maps); |
||
66 | for(i = 4; i--;){ |
||
67 | DISABLEDLGITEM(dp,FIRSTMAPCHECKITEM+i); |
||
68 | if(maps[i] || (checksliders_result & CHECKSLIDERS_MAP_AMBIGUOUS)) |
||
69 | CHECKDLGBUTTON(dp,FIRSTMAPCHECKITEM+i,true); |
||
70 | else |
||
71 | HideDialogItem(dp,FIRSTMAPNAMEITEM+i); |
||
72 | } |
||
73 | for(i = 8; i--;){ |
||
74 | DISABLEDLGITEM(dp,FIRSTCTLCHECKITEM+i); |
||
75 | if((ctls[i] || (checksliders_result & CHECKSLIDERS_CTL_AMBIGUOUS)) && |
||
76 | // When map() is activated, we don't need ctl labels, |
||
77 | // since the standalone filter will only show map labels |
||
78 | !maps[i/2] && |
||
79 | (!(checksliders_result & CHECKSLIDERS_MAP_AMBIGUOUS)) |
||
80 | ) |
||
81 | CHECKDLGBUTTON(dp,FIRSTCTLCHECKITEM+i,true); |
||
82 | else |
||
83 | HideDialogItem(dp,FIRSTCTLNAMEITEM+i); |
||
84 | } |
||
85 | |||
339 | daniel-mar | 86 | CHECKDLGBUTTON(dp, PROTECTITEM, 0); // TODO: should we remember the last setting? |
87 | |||
259 | daniel-mar | 88 | SELECTDLGITEMTEXT(dp,TITLEITEM,0,-1); |
89 | } |
||
90 | |||
444 | daniel-mar | 91 | Boolean containsUnicodeInput(DIALOGREF dp, int item) { |
92 | enum { MAXFIELD = 0x100 }; |
||
93 | char s[MAXFIELD + 1]; |
||
94 | wchar_t sw[MAXFIELD + 1]; |
||
95 | size_t i; |
||
259 | daniel-mar | 96 | |
444 | daniel-mar | 97 | GetDlgItemTextA(dp, item, s, MAXFIELD); |
98 | GetDlgItemTextW(dp, item, sw, MAXFIELD); |
||
99 | for (i = 0; i < strlen(s); i++) { |
||
100 | if (((wchar_t)s[i] != sw[i]) && (s[i] == '?')) { |
||
101 | return true; |
||
102 | } |
||
103 | } |
||
104 | |||
105 | return false; |
||
106 | } |
||
107 | |||
108 | Boolean containsExtCharset(DIALOGREF dp, int item) { |
||
109 | enum { MAXFIELD = 0x100 }; |
||
110 | char s[MAXFIELD + 1]; |
||
111 | size_t i; |
||
112 | |||
113 | GetDlgItemTextA(dp, item, s, MAXFIELD); |
||
114 | for (i = 0; i < strlen(s); i++) { |
||
115 | if ((unsigned char)s[i] > (unsigned char)0x7F) { |
||
116 | return true; |
||
117 | } |
||
118 | } |
||
119 | |||
120 | return false; |
||
121 | } |
||
122 | |||
259 | daniel-mar | 123 | /* process an item hit. return false if the dialog is finished; otherwise return true. */ |
124 | |||
125 | Boolean builddlgitem(DIALOGREF dp,int item){ |
||
126 | enum{MAXFIELD=0x100}; |
||
127 | char s[MAXFIELD+1]; |
||
128 | int i,needui; |
||
444 | daniel-mar | 129 | TCHAR fname[MAX_PATH + 1]; |
365 | daniel-mar | 130 | StandardFileReply sfr; |
131 | NavReplyRecord reply; |
||
444 | daniel-mar | 132 | #ifdef UNICODE |
133 | Boolean unicode; |
||
134 | #endif |
||
135 | Boolean extCharset; |
||
259 | daniel-mar | 136 | |
137 | switch(item){ |
||
363 | daniel-mar | 138 | #ifdef MAC_ENV |
139 | case ok: |
||
140 | #else |
||
259 | daniel-mar | 141 | case IDOK: |
363 | daniel-mar | 142 | #endif |
259 | daniel-mar | 143 | // Do a few checks first |
444 | daniel-mar | 144 | GetDlgItemTextA(dp, CATEGORYITEM, s, MAXFIELD); |
259 | daniel-mar | 145 | if (strlen(s) == 0) { |
444 | daniel-mar | 146 | simplealert((TCHAR*)TEXT("Category must not be empty!")); |
363 | daniel-mar | 147 | return true; // don't continue (i.e. don't call EndDialog). Let the user correct the input |
259 | daniel-mar | 148 | } |
444 | daniel-mar | 149 | GetDlgItemTextA(dp, TITLEITEM, s, MAXFIELD); |
259 | daniel-mar | 150 | if (strlen(s) == 0) { |
444 | daniel-mar | 151 | simplealert((TCHAR*)TEXT("Title must not be empty!")); |
363 | daniel-mar | 152 | return true; // don't continue (i.e. don't call EndDialog). Let the user correct the input |
259 | daniel-mar | 153 | } |
154 | |||
444 | daniel-mar | 155 | // The PiPL and PARM structure does only define single byte charsets |
156 | #ifdef UNICODE |
||
157 | unicode = |
||
158 | containsUnicodeInput(dp, CATEGORYITEM) || |
||
159 | containsUnicodeInput(dp, TITLEITEM) || |
||
160 | containsUnicodeInput(dp, COPYRIGHTITEM) || |
||
161 | containsUnicodeInput(dp, AUTHORITEM); |
||
162 | #endif |
||
163 | extCharset = |
||
164 | containsExtCharset(dp, CATEGORYITEM) || |
||
165 | containsExtCharset(dp, TITLEITEM) || |
||
166 | containsExtCharset(dp, COPYRIGHTITEM) || |
||
167 | containsExtCharset(dp, AUTHORITEM); |
||
168 | |||
169 | // The AETE structure does only define single byte charsets |
||
170 | for (i = 0; i < 8; ++i) { |
||
171 | if (ctls[i] || (checksliders_result & CHECKSLIDERS_CTL_AMBIGUOUS)) { |
||
172 | #ifdef UNICODE |
||
173 | unicode |= containsUnicodeInput(dp, FIRSTCTLNAMEITEM + i); |
||
174 | #endif |
||
175 | extCharset |= containsExtCharset(dp, FIRSTCTLNAMEITEM + i); |
||
176 | } |
||
177 | } |
||
178 | for (i = 0; i < 4; ++i) { |
||
179 | if (maps[i] || (checksliders_result & CHECKSLIDERS_MAP_AMBIGUOUS)) { |
||
180 | #ifdef UNICODE |
||
181 | unicode |= containsUnicodeInput(dp, FIRSTMAPNAMEITEM + i); |
||
182 | #endif |
||
183 | extCharset |= containsExtCharset(dp, FIRSTMAPNAMEITEM + i); |
||
184 | } |
||
185 | } |
||
186 | |||
187 | #ifdef UNICODE |
||
188 | if (unicode) { |
||
189 | simplewarning((TCHAR*)TEXT("The internal structures of Photoshop and Filter Factory are not compatible with Unicode characters. It is highly recommended that you only use characters of your current charset. Unicode characters will be converted into question mark symbols.")); |
||
190 | } |
||
191 | else |
||
192 | #endif |
||
193 | if (extCharset) { |
||
194 | simplewarning((TCHAR*)TEXT("You were using characters of an extended charset. The characters might look correct on your machine, but on a machine in a different country, the characters might look wrong. Please consider using the ASCII character set only (i.e. Latin characters without accent marks).")); |
||
195 | } |
||
196 | |||
259 | daniel-mar | 197 | // Now begin |
198 | memset(&gdata->parm,0,sizeof(PARM_T)); |
||
444 | daniel-mar | 199 | GetDlgItemTextA(dp,CATEGORYITEM,gdata->parm.szCategory,MAXFIELD-4/*ProtectFlag*/); |
200 | GetDlgItemTextA(dp,TITLEITEM,gdata->parm.szTitle,MAXFIELD); |
||
201 | GetDlgItemTextA(dp,COPYRIGHTITEM,gdata->parm.szCopyright,MAXFIELD); |
||
202 | GetDlgItemTextA(dp,AUTHORITEM,gdata->parm.szAuthor,MAXFIELD); |
||
259 | daniel-mar | 203 | gdata->parm.cbSize = PARM_SIZE; |
204 | gdata->parm.standalone = 1; //0=original FF, 1=standalone filter |
||
205 | needui = 0; |
||
376 | daniel-mar | 206 | // Sliders |
259 | daniel-mar | 207 | for(i = 0; i < 8; ++i){ |
208 | gdata->parm.val[i] = slider[i]; |
||
209 | gdata->parm.ctl_used[i] = ctls[i] || (checksliders_result & CHECKSLIDERS_CTL_AMBIGUOUS); |
||
210 | needui |= gdata->parm.ctl_used[i]; |
||
444 | daniel-mar | 211 | GetDlgItemTextA(dp,FIRSTCTLNAMEITEM+i, gdata->parm.szCtl[i],MAXFIELD); |
259 | daniel-mar | 212 | } |
376 | daniel-mar | 213 | // Maps |
214 | for (i = 0; i < 4; ++i) { |
||
259 | daniel-mar | 215 | gdata->parm.map_used[i] = maps[i] || (checksliders_result & CHECKSLIDERS_MAP_AMBIGUOUS); |
216 | needui |= gdata->parm.map_used[i]; |
||
444 | daniel-mar | 217 | GetDlgItemTextA(dp, FIRSTMAPNAMEITEM + i, gdata->parm.szMap[i], MAXFIELD); |
376 | daniel-mar | 218 | } |
219 | // Expressions |
||
220 | for (i = 0; i < 4; ++i) { |
||
368 | daniel-mar | 221 | if (!expr[i]) { |
444 | daniel-mar | 222 | simplealert((TCHAR*)TEXT("Bug! see builddlgitem")); |
368 | daniel-mar | 223 | return true; // keep going. Let the user try again |
224 | } |
||
393 | daniel-mar | 225 | if (strlen(expr[i]) >= sizeof(gdata->parm.szFormula[i])) { |
368 | daniel-mar | 226 | if (i == 0) { |
444 | daniel-mar | 227 | simplealert((TCHAR*)TEXT("Attention! The formula for channel R was too long (longer than 1023 characters) and was truncated.")); |
368 | daniel-mar | 228 | } |
229 | else if (i == 1) { |
||
444 | daniel-mar | 230 | simplealert((TCHAR*)TEXT("Attention! The formula for channel G was too long (longer than 1023 characters) and was truncated.")); |
368 | daniel-mar | 231 | } |
232 | else if (i == 2) { |
||
444 | daniel-mar | 233 | simplealert((TCHAR*)TEXT("Attention! The formula for channel B was too long (longer than 1023 characters) and was truncated.")); |
368 | daniel-mar | 234 | } |
235 | else if (i == 3) { |
||
444 | daniel-mar | 236 | simplealert((TCHAR*)TEXT("Attention! The formula for channel A was too long (longer than 1023 characters) and was truncated.")); |
368 | daniel-mar | 237 | } |
393 | daniel-mar | 238 | expr[i][sizeof(gdata->parm.szFormula[i]) - 1] = '\0'; |
368 | daniel-mar | 239 | } |
393 | daniel-mar | 240 | strcpy(gdata->parm.szFormula[i], expr[i]); |
259 | daniel-mar | 241 | } |
242 | gdata->parm.popDialog = needui; //true if need to pop a parameter dialog |
||
243 | gdata->parm.unknown1 = gdata->parm.unknown2 = gdata->parm.unknown3 = 0; |
||
244 | gdata->parm.iProtected = ISDLGBUTTONCHECKED(dp,PROTECTITEM); // == 1 means protected |
||
245 | gdata->obfusc = ISDLGBUTTONCHECKED(dp,PROTECTITEM); |
||
365 | daniel-mar | 246 | |
444 | daniel-mar | 247 | // TODO: Unicode! |
248 | //xstrcpy(fname, gdata->parm.szTitle); |
||
249 | /* |
||
250 | for (i = 0; i < (int)strlen(gdata->parm.szTitle); i++) { |
||
251 | fname[i] = gdata->parm.szTitle[i]; |
||
252 | fname[i + 1] = 0; |
||
253 | } |
||
254 | */ |
||
255 | GetDlgItemText(dp, TITLEITEM, fname, MAXFIELD); |
||
256 | |||
365 | daniel-mar | 257 | #ifdef MACMACHO |
393 | daniel-mar | 258 | strcat(fname, ".plugin"); |
365 | daniel-mar | 259 | #endif |
260 | if (putfile( |
||
261 | #ifdef MAC_ENV |
||
262 | (StringPtr)_strdup("\pMake standalone filter"), // "\p" means "Pascal string" |
||
393 | daniel-mar | 263 | (StringPtr)myc2pstr(_strdup(fname)), |
444 | daniel-mar | 264 | PS_FILTER_FILETYPE, kPhotoshopSignature, & reply, & sfr, |
365 | daniel-mar | 265 | "8bf", "Filter plugin file (.8bf)\0*.8bf\0\0", 1 |
444 | daniel-mar | 266 | #else |
267 | TEXT("Make standalone filter"), |
||
268 | fname, |
||
269 | PS_FILTER_FILETYPE, kPhotoshopSignature, & reply, & sfr, |
||
270 | TEXT("8bf"), |
||
271 | TEXT("Filter plugin file (.8bf)\0*.8bf\0\0"), 1 |
||
365 | daniel-mar | 272 | , (HWND)dp |
444 | daniel-mar | 273 | #endif |
365 | daniel-mar | 274 | )) { |
275 | make_standalone(&sfr); |
||
276 | } |
||
277 | else { |
||
278 | return true; // keep going. Let the user correct their input |
||
279 | } |
||
280 | |||
381 | daniel-mar | 281 | return false; // end dialog |
363 | daniel-mar | 282 | #ifdef MAC_ENV |
283 | case cancel: |
||
284 | #else |
||
259 | daniel-mar | 285 | case IDCANCEL: |
363 | daniel-mar | 286 | #endif |
259 | daniel-mar | 287 | return false; // end dialog |
288 | case PROTECTITEM: |
||
289 | CHECKDLGBUTTON(dp, item, ISDLGBUTTONCHECKED(dp,item) ^ 1); |
||
290 | break; |
||
291 | } |
||
292 | |||
293 | return true; // keep going |
||
294 | } |