Subversion Repositories filter_foundry

Rev

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
}