Subversion Repositories filter_foundry

Rev

Rev 408 | Rev 422 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 408 Rev 419
1
/*
1
/*
2
    This file is part of "Filter Foundry", a filter plugin for Adobe Photoshop
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
3
    Copyright (C) 2003-2009 Toby Thain, toby@telegraphics.com.au
4
    Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft
4
    Copyright (C) 2018-2021 Daniel Marschall, ViaThinkSoft
5
 
5
 
6
    This program is free software; you can redistribute it and/or modify
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
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
8
    the Free Software Foundation; either version 2 of the License, or
9
    (at your option) any later version.
9
    (at your option) any later version.
10
 
10
 
11
    This program is distributed in the hope that it will be useful,
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
14
    GNU General Public License for more details.
15
 
15
 
16
    You should have received a copy of the GNU General Public License
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
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
18
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
*/
19
*/
20
 
20
 
21
/* This is PLATFORM INDEPENDENT user interface code - mainly dialog logic */
21
/* This is PLATFORM INDEPENDENT user interface code - mainly dialog logic */
22
 
22
 
23
#include "ff.h"
23
#include "ff.h"
24
 
24
 
25
#include "node.h"
25
#include "node.h"
26
#include "funcs.h"
26
#include "funcs.h"
27
#include "y.tab.h"
27
#include "y.tab.h"
28
#include "choosefile.h"
28
#include "choosefile.h"
29
#include "sprintf_tiny.h"
29
#include "sprintf_tiny.h"
30
#include "compat_string.h"
30
#include "compat_string.h"
31
 
31
 
32
#ifdef MAC_ENV
32
#ifdef MAC_ENV
33
        #include <plstringfuncs.h>
33
        #include <plstringfuncs.h>
34
#endif
34
#endif
35
 
35
 
36
Boolean doupdates = true;
36
Boolean doupdates = true;
37
 
37
 
38
void updateglobals(DIALOGREF dp);
38
void updateglobals(DIALOGREF dp);
39
struct node *updateexpr(DIALOGREF dp,int i);
39
struct node *updateexpr(DIALOGREF dp,int i);
40
void updatedialog(DIALOGREF dp);
40
void updatedialog(DIALOGREF dp);
41
void slidertextchanged(DIALOGREF dp,int item);
41
void slidertextchanged(DIALOGREF dp,int item);
42
void updatezoom(DIALOGREF dp);
42
void updatezoom(DIALOGREF dp);
43
 
43
 
44
void updatedialog(DIALOGREF dp){
44
void updatedialog(DIALOGREF dp){
45
        int i;
45
        int i;
46
 
46
 
47
        doupdates = false;
47
        doupdates = false;
48
 
48
 
49
        for(i = 0; i < 8; ++i){
49
        for(i = 0; i < 8; ++i){
50
                SETSLIDERVALUE(dp,FIRSTCTLITEM+i,slider[i]);
50
                SETSLIDERVALUE(dp,FIRSTCTLITEM+i,slider[i]);
51
                SETCTLTEXTINT(dp,FIRSTCTLTEXTITEM+i,slider[i],false);
51
                SETCTLTEXTINT(dp,FIRSTCTLTEXTITEM+i,slider[i],false);
52
        }
52
        }
53
 
53
 
54
        for(i = 0; i < 4; ++i){
54
        for(i = 0; i < 4; ++i){
55
                if(!gdata->standalone)
55
                if(!gdata->standalone)
56
                        SETCTLTEXT(dp,FIRSTEXPRITEM+i,expr[i] ? expr[i] : "");
56
                        SETCTLTEXT(dp,FIRSTEXPRITEM+i,expr[i] ? expr[i] : "");
57
                if(i < nplanes)
57
                if(i < nplanes)
58
                        updateexpr(dp,FIRSTEXPRITEM+i);
58
                        updateexpr(dp,FIRSTEXPRITEM+i);
59
        }
59
        }
60
 
60
 
61
        if(!gdata->standalone)
61
        if(!gdata->standalone)
62
                SELECTCTLTEXT(dp,FIRSTEXPRITEM,0,-1);
62
                SELECTCTLTEXT(dp,FIRSTEXPRITEM,0,-1);
63
 
63
 
64
        doupdates = true;
64
        doupdates = true;
65
}
65
}
66
 
66
 
67
/* copy dialog settings to global variables (sliders, expressions) */
67
/* copy dialog settings to global variables (sliders, expressions) */
68
 
68
 
69
void updateglobals(DIALOGREF dp){
69
void updateglobals(DIALOGREF dp){
70
        int i;
70
        int i;
71
        char s[MAXEXPR+1];
71
        char s[MAXEXPR+1];
72
 
72
 
73
        for(i = 0; i < 8; ++i)
73
        for(i = 0; i < 8; ++i)
74
                slider[i] = (value_type)(GETSLIDERVALUE(dp,FIRSTCTLITEM+i));
74
                slider[i] = (value_type)(GETSLIDERVALUE(dp,FIRSTCTLITEM+i));
75
 
75
 
76
        if(!gdata->standalone)
76
        if(!gdata->standalone)
77
                for(i = 0; i < 4; ++i){
77
                for(i = 0; i < 4; ++i){
78
                        /* stash expression strings */
78
                        /* stash expression strings */
79
                        if(GETCTLTEXT(dp,FIRSTEXPRITEM+i,s,MAXEXPR)){
79
                        if(GETCTLTEXT(dp,FIRSTEXPRITEM+i,s,MAXEXPR)){
80
                                if(expr[i])
80
                                if(expr[i])
81
                                        free(expr[i]);
81
                                        free(expr[i]);
82
                                expr[i] = _strdup(s);
82
                                expr[i] = _strdup(s);
83
                        }
83
                        }
84
                        if(!expr[i])
84
                        if(!expr[i])
85
                                expr[i] = _strdup("c");
85
                                expr[i] = _strdup("c");
86
                }
86
                }
87
}
87
}
88
 
88
 
89
struct node *updateexpr(DIALOGREF dp,int item){
89
struct node *updateexpr(DIALOGREF dp,int item){
90
        char s[MAXEXPR+1];
90
        char s[MAXEXPR+1];
91
        int i;
91
        int i;
92
 
92
 
93
        i = item - FIRSTEXPRITEM;
93
        i = item - FIRSTEXPRITEM;
94
 
94
 
95
        freetree(tree[i]);
95
        freetree(tree[i]);
96
 
96
 
97
        if(!gdata->standalone){
97
        if(!gdata->standalone){
98
                GETCTLTEXT(dp,item,s,MAXEXPR);
98
                GETCTLTEXT(dp,item,s,MAXEXPR);
99
 
99
 
100
                if(expr[i])
100
                if(expr[i])
101
                        free(expr[i]);
101
                        free(expr[i]);
102
                expr[i] = _strdup(s);
102
                expr[i] = _strdup(s);
103
        }
103
        }
104
 
104
 
105
        tree[i] = parseexpr(expr[i]);
105
        tree[i] = parseexpr(expr[i]);
106
 
106
 
107
        if(!gdata->standalone){
107
        if(!gdata->standalone){
108
                if(tree[i])
108
                if(tree[i])
109
                        HideDialogItem(dp,FIRSTICONITEM+i);
109
                        HideDialogItem(dp,FIRSTICONITEM+i);
110
                else{
110
                else{
111
                        err[i] = errstr;
111
                        err[i] = errstr;
112
                        errstart[i] = tokstart;
112
                        errstart[i] = tokstart;
113
                        errpos[i] = tokpos;
113
                        errpos[i] = tokpos;
114
                        ShowDialogItem(dp,FIRSTICONITEM+i);
114
                        ShowDialogItem(dp,FIRSTICONITEM+i);
115
                }
115
                }
116
        }
116
        }
117
        return tree[i];
117
        return tree[i];
118
}
118
}
119
 
119
 
120
void updatezoom(DIALOGREF dp){
120
void updatezoom(DIALOGREF dp){
121
        char s[10];
121
        char s[10];
122
        sprintf(s, "%d%%", (int)(100./zoomfactor));
122
        sprintf(s, "%d%%", (int)(100./zoomfactor));
123
        SETCTLTEXT(dp,ZOOMLEVELITEM,s);
123
        SETCTLTEXT(dp,ZOOMLEVELITEM,s);
124
        if(zoomfactor > 1.)
124
        if (zoomfactor > 1.)
125
                ShowDialogItem(dp,ZOOMINITEM);
125
                ENABLEDLGITEM(dp, ZOOMINITEM);   // ShowDialogItem(dp,ZOOMINITEM);
126
        else
126
        else
127
                HideDialogItem(dp,ZOOMINITEM);
127
                DISABLEDLGITEM(dp, ZOOMINITEM);  // HideDialogItem(dp, ZOOMINITEM);
128
        if(zoomfactor < fitzoom)
128
        if(zoomfactor < fitzoom)
129
                ShowDialogItem(dp,ZOOMOUTITEM);
129
                ENABLEDLGITEM(dp, ZOOMOUTITEM);  // ShowDialogItem(dp,ZOOMOUTITEM);
130
        else
130
        else
131
                HideDialogItem(dp,ZOOMOUTITEM);
131
                DISABLEDLGITEM(dp, ZOOMOUTITEM); // HideDialogItem(dp,ZOOMOUTITEM);
132
}
132
}
133
 
133
 
134
/* traverse expression tree, looking for constant references to sliders/maps */
134
/* traverse expression tree, looking for constant references to sliders/maps */
135
 
135
 
136
static int _checksl(struct node*p,int ctlflags[],int mapflags[]){
136
static int _checksl(struct node*p,int ctlflags[],int mapflags[]){
137
        int s, i, result;
137
        int s, i, result;
138
 
138
 
139
        result = 0;
139
        result = 0;
140
        if(p){
140
        if(p){
141
                if( (p->kind==TOK_FN1 && p->v.sym->fn == (pfunc_type)ff_ctl)
141
                if( (p->kind==TOK_FN1 && p->v.sym->fn == (pfunc_type)ff_ctl)
142
                 || (p->kind==TOK_FN3 && p->v.sym->fn == (pfunc_type)ff_val) ){
142
                 || (p->kind==TOK_FN3 && p->v.sym->fn == (pfunc_type)ff_val) ){
143
                        if(p->child[0]->kind == TOK_NUM){
143
                        if(p->child[0]->kind == TOK_NUM){
144
                                s = p->child[0]->v.value;
144
                                s = p->child[0]->v.value;
145
                                if(s>=0 && s<=7)
145
                                if(s>=0 && s<=7)
146
                                        ctlflags[s] = 1;
146
                                        ctlflags[s] = 1;
147
                        }else
147
                        }else
148
                                result |= CHECKSLIDERS_CTL_AMBIGUOUS; /* can't determine which ctl() */
148
                                result |= CHECKSLIDERS_CTL_AMBIGUOUS; /* can't determine which ctl() */
149
                }else if(p->kind==TOK_FN2 && p->v.sym->fn == (pfunc_type)ff_map){
149
                }else if(p->kind==TOK_FN2 && p->v.sym->fn == (pfunc_type)ff_map){
150
                        if(p->child[0]->kind == TOK_NUM){
150
                        if(p->child[0]->kind == TOK_NUM){
151
                                s = p->child[0]->v.value;
151
                                s = p->child[0]->v.value;
152
                                if(s>=0 && s<=3){
152
                                if(s>=0 && s<=3){
153
                                        mapflags[s] = 1;
153
                                        mapflags[s] = 1;
154
                                        ctlflags[s*2] = ctlflags[s*2+1] = 1;
154
                                        ctlflags[s*2] = ctlflags[s*2+1] = 1;
155
                                }
155
                                }
156
                        }else
156
                        }else
157
                                result |= CHECKSLIDERS_MAP_AMBIGUOUS; /* can't determine which map() */
157
                                result |= CHECKSLIDERS_MAP_AMBIGUOUS; /* can't determine which map() */
158
                 }
158
                 }
159
 
159
 
160
                for( i = 0 ; i < MAXCHILDREN ; ++i )
160
                for( i = 0 ; i < MAXCHILDREN ; ++i )
161
                        result |= _checksl(p->child[i],ctlflags,mapflags);
161
                        result |= _checksl(p->child[i],ctlflags,mapflags);
162
        }
162
        }
163
 
163
 
164
        return result;
164
        return result;
165
}
165
}
166
 
166
 
167
int checksliders(int exprs,int ctlflags[],int mapflags[]){
167
int checksliders(int exprs,int ctlflags[],int mapflags[]){
168
        int i, result;
168
        int i, result;
169
 
169
 
170
        result = 0;
170
        result = 0;
171
 
171
 
172
        for(i = 4; i--;)
172
        for(i = 4; i--;)
173
                mapflags[i] = 0;
173
                mapflags[i] = 0;
174
        for(i = 8; i--;)
174
        for(i = 8; i--;)
175
                ctlflags[i] = 0;
175
                ctlflags[i] = 0;
176
 
176
 
177
        for(i = 0; i < exprs; i++)
177
        for(i = 0; i < exprs; i++)
178
                result |= _checksl(tree[i],ctlflags,mapflags);
178
                result |= _checksl(tree[i],ctlflags,mapflags);
179
 
179
 
180
        return result;
180
        return result;
181
}
181
}
182
 
182
 
183
void slidermoved(DIALOGREF dp,int i){
183
void slidermoved(DIALOGREF dp,int i){
184
        int v = GETSLIDERVALUE(dp,i);
184
        int v = GETSLIDERVALUE(dp,i);
185
        i -= FIRSTCTLITEM;
185
        i -= FIRSTCTLITEM;
186
        slider[i] = v;
186
        slider[i] = v;
187
        SETCTLTEXTINT(dp,i+FIRSTCTLTEXTITEM,v,false);
187
        SETCTLTEXTINT(dp,i+FIRSTCTLTEXTITEM,v,false);
188
}
188
}
189
 
189
 
190
void slidertextchanged(DIALOGREF dp,int i){
190
void slidertextchanged(DIALOGREF dp,int i){
191
        int v = GETCTLTEXTINT(dp,i,NULL,false);
191
        int v = GETCTLTEXTINT(dp,i,NULL,false);
192
        i -= FIRSTCTLTEXTITEM;
192
        i -= FIRSTCTLTEXTITEM;
193
        SETSLIDERVALUE(dp,i+FIRSTCTLITEM,v);
193
        SETSLIDERVALUE(dp,i+FIRSTCTLITEM,v);
194
        slider[i] = v;
194
        slider[i] = v;
195
}
195
}
196
 
196
 
197
void maindlgupdate(DIALOGREF dp){
197
void maindlgupdate(DIALOGREF dp){
198
        int i,unknown,ctls[8],maps[4];
198
        int i,unknown,ctls[8],maps[4];
199
 
199
 
200
        unknown = checksliders(nplanes,ctls,maps);
200
        unknown = checksliders(nplanes,ctls,maps);
201
 
201
 
202
        for(i = 0; i < 8; i++)
202
        for(i = 0; i < 8; i++)
203
                if(unknown || ctls[i]){
203
                if(unknown || ctls[i]){
204
                        ENABLEDLGITEM(dp,FIRSTCTLITEM+i);
204
                        ENABLEDLGITEM(dp,FIRSTCTLITEM+i);
205
                        ENABLEDLGITEM(dp,FIRSTCTLLABELITEM+i);
205
                        ENABLEDLGITEM(dp,FIRSTCTLLABELITEM+i);
206
                        ShowDialogItem(dp,FIRSTCTLTEXTITEM+i); /* FIXME: this changes keyboard focus */
206
                        ShowDialogItem(dp,FIRSTCTLTEXTITEM+i); /* FIXME: this changes keyboard focus */
207
                }else{
207
                }else{
208
                        DISABLEDLGITEM(dp,FIRSTCTLITEM+i);
208
                        DISABLEDLGITEM(dp,FIRSTCTLITEM+i);
209
                        DISABLEDLGITEM(dp,FIRSTCTLLABELITEM+i);
209
                        DISABLEDLGITEM(dp,FIRSTCTLLABELITEM+i);
210
                        HideDialogItem(dp,FIRSTCTLTEXTITEM+i); /* FIXME: this changes keyboard focus */
210
                        HideDialogItem(dp,FIRSTCTLTEXTITEM+i); /* FIXME: this changes keyboard focus */
211
                }
211
                }
212
 
212
 
213
        for(i = 0; i < nplanes; i++)
213
        for(i = 0; i < nplanes; i++)
214
                if(!tree[i]){
214
                if(!tree[i]){
215
                        /* uh oh, couldn't parse one of the saved expressions...this is fatal */
215
                        /* uh oh, couldn't parse one of the saved expressions...this is fatal */
216
                        DISABLEDLGITEM(dp,IDOK);
216
                        DISABLEDLGITEM(dp,IDOK);
217
                        if(gdata->standalone){
217
                        if(gdata->standalone){
218
                                alertuser(_strdup("Can't run this filter (there is a problem with the saved expressions)."),_strdup(""));
218
                                alertuser(_strdup("Can't run this filter (there is a problem with the saved expressions)."),_strdup(""));
219
                        }else{
219
                        }else{
220
                                DISABLEDLGITEM(dp,SAVEITEM);
220
                                DISABLEDLGITEM(dp,SAVEITEM);
221
                                DISABLEDLGITEM(dp,MAKEITEM);
221
                                DISABLEDLGITEM(dp,MAKEITEM);
222
                        }
222
                        }
223
                        return;
223
                        return;
224
                }
224
                }
225
 
225
 
226
        /* we have valid expression trees in all slots...proceed! */
226
        /* we have valid expression trees in all slots...proceed! */
227
        updateglobals(dp);
227
        updateglobals(dp);
228
        if(setup(gpb))
228
        if(setup(gpb))
229
                recalc_preview(gpb,dp);
229
                recalc_preview(gpb,dp);
230
 
230
 
231
        ENABLEDLGITEM(dp,IDOK);
231
        ENABLEDLGITEM(dp,IDOK);
232
        if(!gdata->standalone){
232
        if(!gdata->standalone){
233
                ENABLEDLGITEM(dp,SAVEITEM);
233
                ENABLEDLGITEM(dp,SAVEITEM);
234
                ENABLEDLGITEM(dp,MAKEITEM);
234
                ENABLEDLGITEM(dp,MAKEITEM);
235
                ENABLEDLGITEM(dp,HELPITEM);
235
                ENABLEDLGITEM(dp,HELPITEM);
236
        }
236
        }
237
}
237
}
238
 
238
 
239
/* one-time initialisation of dialog box */
239
/* one-time initialisation of dialog box */
240
 
240
 
241
void maindlginit(DIALOGREF dp){
241
void maindlginit(DIALOGREF dp){
242
        char s[0x100];
242
        char s[0x100];
243
        int i;
243
        int i;
244
        const char *channelsuffixes[] = {
244
        const char *channelsuffixes[] = {
245
                "", "KA", "I", "RGBA",
245
                "", "KA", "I", "RGBA",
246
                "CMYK", "HSL", "HSB", "1234",
246
                "CMYK", "HSL", "HSB", "1234",
247
                "DA", "LabA"
247
                "DA", "LabA"
248
        };
248
        };
249
 
249
 
250
        /* hide unused expression items */
250
        /* hide unused expression items */
251
        if(gdata->standalone){
251
        if(gdata->standalone){
252
                SetDlgItemText(dp,PARAMAUTHORITEM,gdata->parm.szAuthor);
252
                SetDlgItemText(dp,PARAMAUTHORITEM,gdata->parm.szAuthor);
253
                SetDlgItemText(dp,PARAMCOPYITEM,gdata->parm.szCopyright);
253
                SetDlgItemText(dp,PARAMCOPYITEM,gdata->parm.szCopyright);
254
 
254
 
255
                // update labels for map() or ctl() sliders
255
                // update labels for map() or ctl() sliders
256
                for(i = 0; i < 8; ++i){
256
                for(i = 0; i < 8; ++i){
257
                        if(gdata->parm.map_used[i/2]){
257
                        if(gdata->parm.map_used[i/2]){
258
                                if((i&1) == 0){
258
                                if((i&1) == 0){
259
                                        // even (0, 2, 4, 6)
259
                                        // even (0, 2, 4, 6)
260
                                        strcpy(s,gdata->parm.szMap[i/2]);
260
                                        strcpy(s,gdata->parm.szMap[i/2]);
261
                                        SetDlgItemText(dp, FIRSTMAPLABELITEM+(i/2),s);
261
                                        SetDlgItemText(dp, FIRSTMAPLABELITEM+(i/2),s);
262
                                        HideDialogItem(dp, FIRSTCTLLABELITEM + i);
262
                                        HideDialogItem(dp, FIRSTCTLLABELITEM + i);
263
                                        HideDialogItem(dp, FIRSTCTLLABELITEM + i + 1);
263
                                        HideDialogItem(dp, FIRSTCTLLABELITEM + i + 1);
264
                                }
264
                                }
265
                        } else if(gdata->parm.ctl_used[i]){
265
                        } else if(gdata->parm.ctl_used[i]){
266
                                strcpy(s,gdata->parm.szCtl[i]);
266
                                strcpy(s,gdata->parm.szCtl[i]);
267
                                SetDlgItemText(dp, FIRSTCTLLABELITEM+i,s);
267
                                SetDlgItemText(dp, FIRSTCTLLABELITEM+i,s);
268
                                HideDialogItem(dp, FIRSTMAPLABELITEM + i/2);
268
                                HideDialogItem(dp, FIRSTMAPLABELITEM + i/2);
269
                        }else{
269
                        }else{
270
                                HideDialogItem(dp, FIRSTCTLITEM+i);
270
                                HideDialogItem(dp, FIRSTCTLITEM+i);
271
                                HideDialogItem(dp, FIRSTCTLTEXTITEM+i);
271
                                HideDialogItem(dp, FIRSTCTLTEXTITEM+i);
272
                                HideDialogItem(dp, FIRSTCTLLABELITEM + i);
272
                                HideDialogItem(dp, FIRSTCTLLABELITEM + i);
273
                                HideDialogItem(dp, FIRSTMAPLABELITEM + i/2);
273
                                HideDialogItem(dp, FIRSTMAPLABELITEM + i/2);
274
                        }
274
                        }
275
                }
275
                }
276
        }
276
        }
277
 
277
 
278
        strcpy(s,"X =");
278
        strcpy(s,"X =");
279
        for(i = 0; i < 4; ++i){
279
        for(i = 0; i < 4; ++i){
280
                if(i >= nplanes){
280
                if(i >= nplanes){
281
                        HideDialogItem(dp,FIRSTICONITEM+i);
281
                        HideDialogItem(dp,FIRSTICONITEM+i);
282
                        HideDialogItem(dp,FIRSTEXPRITEM+i);
282
                        HideDialogItem(dp,FIRSTEXPRITEM+i);
283
                        HideDialogItem(dp,FIRSTLABELITEM+i);
283
                        HideDialogItem(dp,FIRSTLABELITEM+i);
284
                }else{
284
                }else{
285
                        s[0] = channelsuffixes[gpb->imageMode][i];
285
                        s[0] = channelsuffixes[gpb->imageMode][i];
286
                        SetDlgItemText(dp,FIRSTLABELITEM+i,s);
286
                        SetDlgItemText(dp,FIRSTLABELITEM+i,s);
287
                }
287
                }
288
        }
288
        }
289
 
289
 
290
        if(setup_preview(gpb,nplanes)){
290
        if(setup_preview(gpb,nplanes)){
291
                // On very large images, processing a fully zoomed out preview (the initial default)
291
                // On very large images, processing a fully zoomed out preview (the initial default)
292
                // can cause out of memory errors, because Photoshop can't page in all data
292
                // can cause out of memory errors, because Photoshop can't page in all data
293
                // during advanceState. To prevent this problem, zoom in until we aren't
293
                // during advanceState. To prevent this problem, zoom in until we aren't
294
                // previewing more than say 10% of Photoshop's indicated maxSpace.
294
                // previewing more than say 10% of Photoshop's indicated maxSpace.
295
                // (e.g., on a 1GB WinXP system, PS CS2 reports 520MB maxSpace, so this will let us
295
                // (e.g., on a 1GB WinXP system, PS CS2 reports 520MB maxSpace, so this will let us
296
                // preview about 50MB of image data.)
296
                // preview about 50MB of image data.)
297
 
297
 
298
                /* Workaround: GIMP/PSPI sets maxSpace to 100 MB hardcoded, so the zoom is not adjusted correctly. */
298
                /* Workaround: GIMP/PSPI sets maxSpace to 100 MB hardcoded, so the zoom is not adjusted correctly. */
299
                int disable_zoom_memory_check;
299
                int disable_zoom_memory_check;
300
                disable_zoom_memory_check = !maxspace_available();
300
                disable_zoom_memory_check = !maxspace_available();
301
 
301
 
302
                if (!disable_zoom_memory_check) {
302
                if (!disable_zoom_memory_check) {
303
                        zoomfactor = sqrt(maxspace()/(10.*preview_w*preview_h*nplanes));
303
                        zoomfactor = sqrt(maxspace()/(10.*preview_w*preview_h*nplanes));
304
                        if(zoomfactor > fitzoom)
304
                        if(zoomfactor > fitzoom)
305
                                zoomfactor = fitzoom;
305
                                zoomfactor = fitzoom;
306
                        if(zoomfactor < 1.)
306
                        if(zoomfactor < 1.)
307
                                zoomfactor = 1.;
307
                                zoomfactor = 1.;
308
                } else {
308
                } else {
309
                        zoomfactor = fitzoom;
309
                        zoomfactor = fitzoom;
310
                }
310
                }
311
 
311
 
312
                updatezoom(dp);
312
                updatezoom(dp);
313
        }else{
313
        }else{
314
                HideDialogItem(dp,ZOOMINITEM);
314
                DISABLEDLGITEM(dp, ZOOMINITEM);    // HideDialogItem(dp,ZOOMINITEM);
315
                HideDialogItem(dp,ZOOMOUTITEM);
315
                DISABLEDLGITEM(dp, ZOOMOUTITEM);   // HideDialogItem(dp,ZOOMOUTITEM);
316
                HideDialogItem(dp,ZOOMLEVELITEM);
316
                DISABLEDLGITEM(dp, ZOOMLEVELITEM); // HideDialogItem(dp,ZOOMLEVELITEM);
317
        }
317
        }
318
 
318
 
319
        updatedialog(dp);
319
        updatedialog(dp);
320
        maindlgupdate(dp);
320
        maindlgupdate(dp);
321
}
321
}
322
 
322
 
323
 
323
 
324
/* process an item hit. return false if the dialog is finished; otherwise return true. */
324
/* process an item hit. return false if the dialog is finished; otherwise return true. */
325
 
325
 
326
Boolean maindlgitem(DIALOGREF dp,int item){
326
Boolean maindlgitem(DIALOGREF dp,int item){
327
        extern int previewerr;
327
        extern int previewerr;
328
 
328
 
329
        StandardFileReply sfr;
329
        StandardFileReply sfr;
330
        NavReplyRecord reply;
330
        NavReplyRecord reply;
331
        static OSType types[] = {TEXT_FILETYPE,PS_FILTER_FILETYPE};
331
        static OSType types[] = {TEXT_FILETYPE,PS_FILTER_FILETYPE};
332
        char *reason;
332
        char *reason;
333
        HINSTANCE hShellRes;
333
        HINSTANCE hShellRes;
334
        struct InternalState bakState;
334
        struct InternalState bakState;
335
 
335
 
336
        switch(item){
336
        switch(item){
337
#ifdef MAC_ENV
337
#ifdef MAC_ENV
338
        case ok:
338
        case ok:
339
        case cancel:
339
        case cancel:
340
#else
340
#else
341
        case IDOK:
341
        case IDOK:
342
        case IDCANCEL:
342
        case IDCANCEL:
343
#endif
343
#endif
344
                dispose_preview();
344
                dispose_preview();
345
                return false; // end dialog
345
                return false; // end dialog
346
        case OPENITEM:
346
        case OPENITEM:
347
                if(!gdata->standalone && choosefiletypes(
347
                if(!gdata->standalone && choosefiletypes(
348
                        #ifdef MAC_ENV
348
                        #ifdef MAC_ENV
349
                        (StringPtr)_strdup("\pChoose filter settings"), // "\p" means "Pascal string"
349
                        (StringPtr)_strdup("\pChoose filter settings"), // "\p" means "Pascal string"
350
                        #else
350
                        #else
351
                        (StringPtr)_strdup("\026Choose filter settings"),
351
                        (StringPtr)_strdup("\026Choose filter settings"),
352
                        #endif
352
                        #endif
353
                        &sfr,&reply,types,2,
353
                        &sfr,&reply,types,2,
354
                        "All supported files (*.afs, *.8bf, *.pff, *.prm, *.bin, *.rsrc, *.txt, *.ffx)\0*.afs;*.8bf;*.pff;*.prm;*.bin;*.rsrc;*.txt;*.ffx\0Filter Factory Settings (*.afs, *.txt)\0*.afs;*.txt\0PluginCommander or FFDecomp TXT file (*.txt)\0*.txt\0Filter Factory for Windows, Standalone Filter (*.8bf)\0*.8bf\0Premiere TF/FF Settings (*.pff)\0*.pff\0Premiere TT/FF for Windows, Standalone Filter (*.prm)\0*.prm\0FilterFactory for MacOS, Standalone Filter (*.bin, *.rsrc)\0*.bin\0\"Filters Unlimited\" filter (*.ffx)\0*.ffx\0All files (*.*)\0*.*\0\0"
354
                        "All supported files (*.afs, *.8bf, *.pff, *.prm, *.bin, *.rsrc, *.txt, *.ffx)\0*.afs;*.8bf;*.pff;*.prm;*.bin;*.rsrc;*.txt;*.ffx\0Filter Factory Settings (*.afs, *.txt)\0*.afs;*.txt\0PluginCommander or FFDecomp TXT file (*.txt)\0*.txt\0Filter Factory for Windows, Standalone Filter (*.8bf)\0*.8bf\0Premiere TF/FF Settings (*.pff)\0*.pff\0Premiere TT/FF for Windows, Standalone Filter (*.prm)\0*.prm\0FilterFactory for MacOS, Standalone Filter (*.bin, *.rsrc)\0*.bin\0\"Filters Unlimited\" filter (*.ffx)\0*.ffx\0All files (*.*)\0*.*\0\0"
355
                        #ifdef _WIN32
355
                        #ifdef _WIN32
356
                        ,gdata->hWndMainDlg
356
                        ,gdata->hWndMainDlg
357
                        #endif /* _WIN32 */
357
                        #endif /* _WIN32 */
358
                )){
358
                )){
359
                        // Backup everything, otherwise we might lose parameter data if the loading fails
359
                        // Backup everything, otherwise we might lose parameter data if the loading fails
360
                        bakState = saveInternalState();
360
                        bakState = saveInternalState();
361
 
361
 
362
                        if (loadfile(&sfr,&reason)) {
362
                        if (loadfile(&sfr,&reason)) {
363
                                updatedialog(dp);
363
                                updatedialog(dp);
364
                                maindlgupdate(dp);
364
                                maindlgupdate(dp);
365
                        }
365
                        }
366
                        else {
366
                        else {
367
                                alertuser(_strdup("Cannot load settings."), reason);
367
                                alertuser(_strdup("Cannot load settings."), reason);
368
 
368
 
369
                                // Restore
369
                                // Restore
370
                                restoreInternalState(bakState);
370
                                restoreInternalState(bakState);
371
                        }
371
                        }
372
                }
372
                }
373
                break;
373
                break;
374
        case SAVEITEM:
374
        case SAVEITEM:
375
                if(!gdata->standalone && putfile(
375
                if(!gdata->standalone && putfile(
376
                        #ifdef MAC_ENV
376
                        #ifdef MAC_ENV
377
                        (StringPtr)_strdup("\pSave filter settings"), // "\p" means "Pascal string"
377
                        (StringPtr)_strdup("\pSave filter settings"), // "\p" means "Pascal string"
378
                        #else
378
                        #else
379
                        (StringPtr)_strdup("\024Save filter settings"),
379
                        (StringPtr)_strdup("\024Save filter settings"),
380
                        #endif
380
                        #endif
381
                        (StringPtr)_strdup("\0"),
381
                        (StringPtr)_strdup("\0"),
382
                        TEXT_FILETYPE,SIG_SIMPLETEXT,&reply,&sfr,
382
                        TEXT_FILETYPE,SIG_SIMPLETEXT,&reply,&sfr,
383
                        "afs","All supported files (.afs, *.pff, .txt)\0*.afs;*.pff;*.txt\0Filter Factory Settings (*.afs)\0*.afs\0Premiere TF/FF Settings (*.pff)\0*.pff\0PluginCommander TXT file (*.txt)\0*.txt\0All files (*.*)\0*.*\0\0",1
383
                        "afs","All supported files (.afs, *.pff, .txt)\0*.afs;*.pff;*.txt\0Filter Factory Settings (*.afs)\0*.afs\0Premiere TF/FF Settings (*.pff)\0*.pff\0PluginCommander TXT file (*.txt)\0*.txt\0All files (*.*)\0*.*\0\0",1
384
                        #ifdef _WIN32
384
                        #ifdef _WIN32
385
                        ,gdata->hWndMainDlg
385
                        ,gdata->hWndMainDlg
386
                        #endif /* _WIN32 */
386
                        #endif /* _WIN32 */
387
                )){
387
                )){
388
                        if(savefile_afs_pff_picotxt(&sfr)) {
388
                        if(savefile_afs_pff_picotxt(&sfr)) {
389
                                completesave(&reply);
389
                                completesave(&reply);
390
 
390
 
391
                                if (fileHasExtension(&sfr, ".txt")) {
391
                                if (fileHasExtension(&sfr, ".txt")) {
392
                                        char filename[MAX_PATH];
392
                                        char filename[MAX_PATH];
393
 
393
 
394
                                        showmessage(_strdup("The file was successfully saved in the \"PluginCommander\" TXT format. The file will now be opened in a text editor, so that you can fill in the missing data: Category, Title, Copyright, Author, Filename, Slider/Map names."));
394
                                        showmessage(_strdup("The file was successfully saved in the \"PluginCommander\" TXT format. The file will now be opened in a text editor, so that you can fill in the missing data: Category, Title, Copyright, Author, Filename, Slider/Map names."));
395
 
395
 
396
                                        #ifdef MAC_ENV
396
                                        #ifdef MAC_ENV
397
                                        // TODO: Open text file instead
397
                                        // TODO: Open text file instead
398
                                        showmessage(_strdup("Please edit the file manually to enter the title, category, authorname, copyright, slidernames etc."));
398
                                        showmessage(_strdup("Please edit the file manually to enter the title, category, authorname, copyright, slidernames etc."));
399
                                        #else
399
                                        #else
400
                                        myp2cstrcpy(filename, sfr.sfFile.name);
400
                                        myp2cstrcpy(filename, sfr.sfFile.name);
401
                                        hShellRes = ShellExecuteA(
401
                                        hShellRes = ShellExecuteA(
402
                                                gdata->hWndMainDlg,
402
                                                gdata->hWndMainDlg,
403
                                                "open",
403
                                                "open",
404
                                                filename,
404
                                                filename,
405
                                                NULL,
405
                                                NULL,
406
                                                NULL,
406
                                                NULL,
407
                                                SW_SHOWNORMAL
407
                                                SW_SHOWNORMAL
408
                                        );
408
                                        );
409
                                        if (hShellRes <= (HINSTANCE)32) {
409
                                        if (hShellRes <= (HINSTANCE)32) {
410
                                                // MSDN states: "If the function succeeds, it returns a value greater than 32."
410
                                                // MSDN states: "If the function succeeds, it returns a value greater than 32."
411
 
411
 
412
                                                char s[100];
412
                                                char s[100];
413
                                                strcpy(s, "ShellExecuteA failed: ");
413
                                                strcpy(s, "ShellExecuteA failed: ");
414
                                                FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + strlen(s), 0x100, NULL);
414
                                                FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + strlen(s), 0x100, NULL);
415
                                                dbg(s);
415
                                                dbg(s);
416
 
416
 
417
                                                showmessage(_strdup("Please edit the file manually to enter the title, category, author, copyright, filename, slidernames etc."));
417
                                                showmessage(_strdup("Please edit the file manually to enter the title, category, author, copyright, filename, slidernames etc."));
418
                                        }
418
                                        }
419
                                        #endif
419
                                        #endif
420
                                }
420
                                }
421
 
421
 
422
                        }
422
                        }
423
                }
423
                }
424
                break;
424
                break;
425
        case MAKEITEM:
425
        case MAKEITEM:
426
                if (gdata->standalone) return true; // should not happen since the button should be grayed out
426
                if (gdata->standalone) return true; // should not happen since the button should be grayed out
427
 
427
 
428
                builddialog(gpb);
428
                builddialog(gpb);
429
 
429
 
430
                break;
430
                break;
431
        case HELPITEM:
431
        case HELPITEM:
432
                #ifdef MAC_ENV
432
                #ifdef MAC_ENV
433
                // TODO: Open web-browser instead
433
                // TODO: Open web-browser instead
434
                showmessage(_strdup("You can find the documentation here: https://github.com/danielmarschall/filter_foundry/tree/master/doc"));
434
                showmessage(_strdup("You can find the documentation here: https://github.com/danielmarschall/filter_foundry/tree/master/doc"));
435
                #else
435
                #else
436
                hShellRes = ShellExecuteA(
436
                hShellRes = ShellExecuteA(
437
                        gdata->hWndMainDlg,
437
                        gdata->hWndMainDlg,
438
                        "open",
438
                        "open",
439
                        "https://github.com/danielmarschall/filter_foundry/blob/master/doc/The%20Filter%20Foundry.pdf",
439
                        "https://github.com/danielmarschall/filter_foundry/blob/master/doc/The%20Filter%20Foundry.pdf",
440
                        NULL,
440
                        NULL,
441
                        NULL,
441
                        NULL,
442
                        SW_SHOWNORMAL
442
                        SW_SHOWNORMAL
443
                );
443
                );
444
                if (hShellRes == (HINSTANCE)ERROR_FILE_NOT_FOUND) {
444
                if (hShellRes == (HINSTANCE)ERROR_FILE_NOT_FOUND) {
445
                        // On Win98 we get ERROR_FILE_NOT_FOUND, but the browser still opens!
445
                        // On Win98 we get ERROR_FILE_NOT_FOUND, but the browser still opens!
446
                        // So we ignore it for now...
446
                        // So we ignore it for now...
447
                }
447
                }
448
                else if (hShellRes <= (HINSTANCE)32) {
448
                else if (hShellRes <= (HINSTANCE)32) {
449
                        // MSDN states: "If the function succeeds, it returns a value greater than 32."
449
                        // MSDN states: "If the function succeeds, it returns a value greater than 32."
450
 
450
 
451
                        char s[100];
451
                        char s[100];
452
                        strcpy(s, "ShellExecuteA failed: ");
452
                        strcpy(s, "ShellExecuteA failed: ");
453
                        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + strlen(s), 0x100, NULL);
453
                        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, s + strlen(s), 0x100, NULL);
454
                        dbg(s);
454
                        dbg(s);
455
 
455
 
456
                        showmessage(_strdup("You can find the documentation here: https://github.com/danielmarschall/filter_foundry/tree/master/doc"));
456
                        showmessage(_strdup("You can find the documentation here: https://github.com/danielmarschall/filter_foundry/tree/master/doc"));
457
                }
457
                }
458
                #endif
458
                #endif
459
                break;
459
                break;
460
        case ZOOMINITEM:
460
        case ZOOMINITEM:
461
                zoomfactor = zoomfactor > 2. ? zoomfactor/2. : 1.;
461
                zoomfactor = zoomfactor > 2. ? zoomfactor/2. : 1.;
462
                updatezoom(dp);
462
                updatezoom(dp);
463
                previewerr = false;
463
                previewerr = false;
464
                recalc_preview(gpb,dp);
464
                recalc_preview(gpb,dp);
465
                break;
465
                break;
466
        case ZOOMOUTITEM:
466
        case ZOOMOUTITEM:
467
                zoomfactor *= 2.;
467
                zoomfactor *= 2.;
468
                if(zoomfactor > fitzoom)
468
                if(zoomfactor > fitzoom)
469
                        zoomfactor = fitzoom;
469
                        zoomfactor = fitzoom;
470
                updatezoom(dp);
470
                updatezoom(dp);
471
                previewerr = false;
471
                previewerr = false;
472
                recalc_preview(gpb,dp);
472
                recalc_preview(gpb,dp);
473
                break;
473
                break;
474
        case ZOOMLEVELITEM:
474
        case ZOOMLEVELITEM:
475
                zoomfactor = zoomfactor > 1. ? 1. : (fitzoom < 1. ? 1. : fitzoom);
475
                zoomfactor = zoomfactor > 1. ? 1. : (fitzoom < 1. ? 1. : fitzoom);
476
                updatezoom(dp);
476
                updatezoom(dp);
477
                previewerr = false;
477
                previewerr = false;
478
                recalc_preview(gpb,dp);
478
                recalc_preview(gpb,dp);
479
                break;
479
                break;
480
        case FIRSTCTLITEM:
480
        case FIRSTCTLITEM:
481
        case FIRSTCTLITEM+1:
481
        case FIRSTCTLITEM+1:
482
        case FIRSTCTLITEM+2:
482
        case FIRSTCTLITEM+2:
483
        case FIRSTCTLITEM+3:
483
        case FIRSTCTLITEM+3:
484
        case FIRSTCTLITEM+4:
484
        case FIRSTCTLITEM+4:
485
        case FIRSTCTLITEM+5:
485
        case FIRSTCTLITEM+5:
486
        case FIRSTCTLITEM+6:
486
        case FIRSTCTLITEM+6:
487
        case FIRSTCTLITEM+7:
487
        case FIRSTCTLITEM+7:
488
                slidermoved(dp,item);
488
                slidermoved(dp,item);
489
                recalc_preview(gpb,dp);
489
                recalc_preview(gpb,dp);
490
                break;
490
                break;
491
        case FIRSTCTLTEXTITEM:
491
        case FIRSTCTLTEXTITEM:
492
        case FIRSTCTLTEXTITEM+1:
492
        case FIRSTCTLTEXTITEM+1:
493
        case FIRSTCTLTEXTITEM+2:
493
        case FIRSTCTLTEXTITEM+2:
494
        case FIRSTCTLTEXTITEM+3:
494
        case FIRSTCTLTEXTITEM+3:
495
        case FIRSTCTLTEXTITEM+4:
495
        case FIRSTCTLTEXTITEM+4:
496
        case FIRSTCTLTEXTITEM+5:
496
        case FIRSTCTLTEXTITEM+5:
497
        case FIRSTCTLTEXTITEM+6:
497
        case FIRSTCTLTEXTITEM+6:
498
        case FIRSTCTLTEXTITEM+7:
498
        case FIRSTCTLTEXTITEM+7:
499
                slidertextchanged(dp,item);
499
                slidertextchanged(dp,item);
500
                recalc_preview(gpb,dp);
500
                recalc_preview(gpb,dp);
501
                break;
501
                break;
502
        case FIRSTICONITEM:
502
        case FIRSTICONITEM:
503
        case FIRSTICONITEM+1:
503
        case FIRSTICONITEM+1:
504
        case FIRSTICONITEM+2:
504
        case FIRSTICONITEM+2:
505
        case FIRSTICONITEM+3:
505
        case FIRSTICONITEM+3:
506
                item -= FIRSTICONITEM;
506
                item -= FIRSTICONITEM;
507
                alertuser(err[item],_strdup(""));
507
                alertuser(err[item],_strdup(""));
508
                SELECTCTLTEXT(dp,FIRSTEXPRITEM+item,errstart[item],errpos[item]);
508
                SELECTCTLTEXT(dp,FIRSTEXPRITEM+item,errstart[item],errpos[item]);
509
                break;
509
                break;
510
        case FIRSTEXPRITEM:
510
        case FIRSTEXPRITEM:
511
        case FIRSTEXPRITEM+1:
511
        case FIRSTEXPRITEM+1:
512
        case FIRSTEXPRITEM+2:
512
        case FIRSTEXPRITEM+2:
513
        case FIRSTEXPRITEM+3:
513
        case FIRSTEXPRITEM+3:
514
                if((item-FIRSTEXPRITEM) < nplanes){
514
                if((item-FIRSTEXPRITEM) < nplanes){
515
                        updateexpr(dp,item);
515
                        updateexpr(dp,item);
516
                        maindlgupdate(dp);
516
                        maindlgupdate(dp);
517
                }
517
                }
518
                break;
518
                break;
519
        }
519
        }
520
 
520
 
521
        return true; // keep going
521
        return true; // keep going
522
}
522
}
523
 
523
 
524
Boolean alertuser(char *err,char *more){
524
Boolean alertuser(char *err,char *more){
525
        char *s = (char*)malloc(strlen(err)+strlen(more)+2),*q;
525
        char *s = (char*)malloc(strlen(err)+strlen(more)+2),*q;
526
        Boolean res;
526
        Boolean res;
527
 
527
 
528
        q = cat(s,err);
528
        q = cat(s,err);
529
        *q++ = LF;
529
        *q++ = LF;
530
        q = cat(q,more);
530
        q = cat(q,more);
531
        *q = 0;
531
        *q = 0;
532
        res = simplealert(s);
532
        res = simplealert(s);
533
        free(s);
533
        free(s);
534
        return res;
534
        return res;
535
}
535
}
536
 
536