Line data Source code
1 : /* -*- coding: utf-8 -*- */
2 : /* Copyright (C) 2000-2012 by George Williams */
3 : /*
4 : * Redistribution and use in source and binary forms, with or without
5 : * modification, are permitted provided that the following conditions are met:
6 :
7 : * Redistributions of source code must retain the above copyright notice, this
8 : * list of conditions and the following disclaimer.
9 :
10 : * Redistributions in binary form must reproduce the above copyright notice,
11 : * this list of conditions and the following disclaimer in the documentation
12 : * and/or other materials provided with the distribution.
13 :
14 : * The name of the author may not be used to endorse or promote products
15 : * derived from this software without specific prior written permission.
16 :
17 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 : */
28 : #include "fontforgeui.h"
29 : #include "namelist.h"
30 : #include "scripting.h"
31 :
32 : #include <stdlib.h>
33 : #include <string.h>
34 : #include <ustring.h>
35 : #include <gdraw.h>
36 : #include <gwidget.h>
37 : #include <ggadget.h>
38 :
39 : extern NameList *force_names_when_opening;
40 : int default_font_filter_index=0;
41 : struct openfilefilters *user_font_filters = NULL;
42 :
43 : struct openfilefilters def_font_filters[] = {
44 : {
45 : N_("All Fonts"),
46 : /* any these files... */
47 : "*.{"
48 : "pfa,"
49 : "pfb,"
50 : "pt3,"
51 : "t42,"
52 : "sfd,"
53 : "ufo,"
54 : "ttf,"
55 : "bdf,"
56 : "otf,"
57 : "otb,"
58 : "cff,"
59 : "cef,"
60 : "gai,"
61 : #ifndef _NO_LIBPNG
62 : "woff,"
63 : #endif
64 : "svg,"
65 : "ufo,"
66 : "pf3,"
67 : "ttc,"
68 : "gsf,"
69 : "cid,"
70 : "bin,"
71 : "hqx,"
72 : "dfont,"
73 : "mf,"
74 : "ik,"
75 : "fon,"
76 : "fnt,"
77 : "pcf,"
78 : "pmf,"
79 : "[0-9]*pk,"
80 : /* I used to say "*gf" but that also matched xgf (xgridfit) files -- which ff can't open */
81 : "[0-9]*gf,"
82 : "pdb"
83 : "}"
84 : /* With any of these methods of compression */
85 : "{.gz,.Z,.bz2,.lzma,}"
86 : },
87 : {
88 : N_("Outline Fonts"),
89 : "*.{"
90 : "pfa,"
91 : "pfb,"
92 : "pt3,"
93 : "t42,"
94 : "sfd,"
95 : "ufo,"
96 : "ttf,"
97 : "otf,"
98 : "cff,"
99 : "cef,"
100 : "gai,"
101 : #ifndef _NO_LIBPNG
102 : "woff,"
103 : #endif
104 : "svg,"
105 : "ufo,"
106 : "pf3,"
107 : "ttc,"
108 : "gsf,"
109 : "cid,"
110 : "bin,"
111 : "hqx,"
112 : "dfont,"
113 : "mf,"
114 : "ik"
115 : "}"
116 : "{.gz,.Z,.bz2,.lzma,}"
117 : },
118 : {
119 : N_("Bitmap Fonts"),
120 : "*.{"
121 : "bdf,"
122 : "otb,"
123 : "bin,"
124 : "hqx,"
125 : "fon,"
126 : "fnt,"
127 : "pcf,"
128 : "pmf,"
129 : "*pk,"
130 : "*gf,"
131 : "pdb"
132 : "}"
133 : "{.gz,.Z,.bz2,.lzma,}"
134 : },
135 : { NU_("ΤεΧ Bitmap Fonts"), "*{pk,gf}" },
136 : { N_("PostScript"), "*.{pfa,pfb,t42,otf,cef,cff,gai,pf3,pt3,gsf,cid}{.gz,.Z,.bz,.bz2,.lzma,}" },
137 : { N_("TrueType"), "*.{ttf,t42,ttc}{.gz,.Z,.bz,.bz2,.lzma,}" },
138 : #ifdef _NO_LIBPNG
139 : { N_("OpenType"), "*.{ttf,otf}{.gz,.Z,.bz,.bz2,.lzma,}" },
140 : #else
141 : { N_("OpenType"), "*.{ttf,otf,woff}{.gz,.Z,.bz,.bz2,.lzma,}" },
142 : #endif
143 : { N_("Type1"), "*.{pfa,pfb,gsf,cid}{.gz,.Z,.bz2,.lzma,}" },
144 : { N_("Type2"), "*.{otf,cef,cff,gai}{.gz,.Z,.bz2,.lzma,}" },
145 : { N_("Type3"), "*.{pf3,pt3}{.gz,.Z,.bz2,.lzma,}" },
146 : { N_("SVG"), "*.svg{.gz,.Z,.bz2,.lzma,}" },
147 : { N_("Unified Font Object"), "*.ufo" },
148 : { N_("FontForge's SFD"), "*.sfd{.gz,.Z,.bz2,.lzma,}" },
149 : { N_("Backup SFD"), "*.sfd~" },
150 : { N_("Extract from PDF"), "*.pdf{.gz,.Z,.bz2,.lzma,}" },
151 : { "-", NULL },
152 : { N_("Archives"), "*.{zip,tgz,tbz,tbz2,tar.gz,tar.bz,tar.bz2,tar}" },
153 : { N_("All Files"), "*" },
154 : { NULL, NULL }
155 : };
156 :
157 0 : static GTextInfo **StandardFilters(void) {
158 : int k, cnt, i;
159 : GTextInfo **ti;
160 :
161 : /* Make two passes thru outer loop. The first pass determines the
162 : * interim count of how many entries will be generated and then
163 : * allocates an array with 3 entries more than that. The second
164 : * pass ( if(k) ) accumulates the data values, then adds a trailer,
165 : * to return in the GTextInfo** structure 'ti'.
166 : */
167 0 : for ( k=0; k<2; ++k ) {
168 0 : cnt = 0;
169 0 : for ( i=0; def_font_filters[i].name!=NULL; ++i ) {
170 0 : if ( k ) {
171 0 : ti[cnt] = calloc(1,sizeof(GTextInfo));
172 0 : ti[cnt]->userdata = def_font_filters[i].filter;
173 0 : ti[cnt]->fg = ti[cnt]->bg = COLOR_DEFAULT;
174 0 : if ( *(char *) def_font_filters[i].name == '-' )
175 0 : ti[cnt]->line = true;
176 : else
177 0 : ti[cnt]->text = utf82u_copy(_(def_font_filters[i].name));
178 : }
179 0 : ++cnt;
180 : }
181 0 : if ( user_font_filters!=NULL ) {
182 0 : if ( k ) {
183 0 : ti[cnt] = calloc(1,sizeof(GTextInfo));
184 0 : ti[cnt]->fg = ti[cnt]->bg = COLOR_DEFAULT;
185 : /* Don't translate this name */
186 0 : ti[cnt]->line = true;
187 : }
188 0 : ++cnt;
189 0 : for ( i=0; user_font_filters[i].name!=NULL; ++i ) {
190 0 : if ( k ) {
191 0 : ti[cnt] = calloc(1,sizeof(GTextInfo));
192 0 : ti[cnt]->userdata = user_font_filters[i].filter;
193 0 : ti[cnt]->fg = ti[cnt]->bg = COLOR_DEFAULT;
194 : /* Don't translate this name */
195 0 : if ( *(char *) user_font_filters[i].name == '-' )
196 0 : ti[cnt]->line = true;
197 : else
198 0 : ti[cnt]->text = utf82u_copy(user_font_filters[i].name);
199 : }
200 0 : ++cnt;
201 : }
202 : }
203 0 : if ( k ) {
204 0 : ti[cnt] = calloc(1,sizeof(GTextInfo));
205 0 : ti[cnt]->fg = ti[cnt]->bg = COLOR_DEFAULT;
206 0 : ti[cnt++]->line = true;
207 0 : ti[cnt] = calloc(1,sizeof(GTextInfo));
208 0 : ti[cnt]->userdata = (void *) -1;
209 0 : ti[cnt]->fg = ti[cnt]->bg = COLOR_DEFAULT;
210 0 : ti[cnt++]->text = utf82u_copy(_("Edit Filter List"));
211 0 : ti[cnt] = calloc(1,sizeof(GTextInfo));
212 : } else
213 0 : ti = malloc((cnt+3)*sizeof(GTextInfo *));
214 : }
215 0 : ti[default_font_filter_index]->selected = true;
216 0 : return( ti );
217 : }
218 :
219 : struct filter_d {
220 : int done;
221 : GGadget *gme;
222 : };
223 :
224 0 : static int Filter_Cancel(GGadget *g, GEvent *e) {
225 : GWindow gw;
226 : struct filter_d *d;
227 :
228 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
229 0 : gw = GGadgetGetWindow(g);
230 0 : d = GDrawGetUserData(gw);
231 0 : d->done = true;
232 : }
233 0 : return( true );
234 : }
235 :
236 0 : static int Filter_OK(GGadget *g, GEvent *e) {
237 : struct filter_d *d;
238 : struct matrix_data *md;
239 : int rows,i,cnt;
240 :
241 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
242 0 : if ( user_font_filters!=NULL ) {
243 0 : for ( i=0; user_font_filters[i].name!=NULL; ++i ) {
244 0 : free(user_font_filters[i].name);
245 0 : free(user_font_filters[i].filter);
246 : }
247 0 : free(user_font_filters);
248 0 : user_font_filters = NULL;
249 : }
250 0 : d = GDrawGetUserData(GGadgetGetWindow(g));
251 0 : md = GMatrixEditGet(d->gme,&rows);
252 0 : for ( i=cnt=0; i<rows; ++i )
253 0 : if ( !md[2*i].frozen )
254 0 : ++cnt;
255 0 : if ( cnt!=0 ) {
256 0 : user_font_filters = malloc((cnt+1)*sizeof(struct openfilefilters));
257 0 : for ( i=cnt=0; i<rows; ++i ) if ( !md[2*i].frozen ) {
258 0 : user_font_filters[cnt].name = copy(md[2*i].u.md_str);
259 0 : user_font_filters[cnt].filter = copy(md[2*i+1].u.md_str);
260 0 : ++cnt;
261 : }
262 0 : user_font_filters[cnt].name = user_font_filters[cnt].filter = NULL;
263 : }
264 0 : SavePrefs(true);
265 0 : d->done = true;
266 : }
267 0 : return( true );
268 : }
269 :
270 0 : static int filter_e_h(GWindow gw, GEvent *event) {
271 0 : if ( event->type==et_close ) {
272 0 : struct filter_d *d = GDrawGetUserData(gw);
273 0 : d->done = true;
274 0 : } else if ( event->type == et_char ) {
275 0 : return( false );
276 : }
277 0 : return( true );
278 : }
279 :
280 0 : static int filter_candelete(GGadget *g, int r) {
281 : struct matrix_data *md;
282 : int rows;
283 :
284 0 : md = GMatrixEditGet(g,&rows);
285 0 : if ( r>=rows )
286 0 : return( false );
287 :
288 0 : return( !md[2*r].frozen );
289 : }
290 :
291 0 : static void FilterDlg(void) {
292 : static struct col_init cols[] = {
293 : { me_string, NULL, NULL, NULL, N_("Name") },
294 : { me_string, NULL, NULL, NULL, N_("Filter") }
295 : };
296 : static int inited = false;
297 : static struct matrixinit mi = {
298 : 2, cols,
299 : 0, NULL,
300 : NULL,
301 : filter_candelete,
302 : NULL,
303 : NULL,
304 : NULL,
305 : NULL
306 : };
307 : struct matrix_data *md;
308 : int k, cnt, i, ptwidth;
309 : GGadgetCreateData gcd[3], boxes[3], *varray[7], *harray[7];
310 : GTextInfo label[3];
311 : GRect pos;
312 : GWindow gw;
313 : GWindowAttrs wattrs;
314 : struct filter_d d;
315 :
316 0 : if ( !inited ) {
317 0 : inited = true;
318 0 : cols[0].title = _(cols[0].title);
319 0 : cols[1].title = _(cols[1].title);
320 : }
321 :
322 0 : for ( k=0; k<2; ++k ) {
323 0 : cnt = 0;
324 0 : for ( i=0; def_font_filters[i].name!=NULL; ++i ) {
325 0 : if ( *(char *) def_font_filters[i].name != '-' ) {
326 0 : if ( k ) {
327 0 : md[2*cnt].u.md_str = copy(_(def_font_filters[i].name));
328 0 : md[2*cnt].frozen = true;
329 0 : md[2*cnt+1].u.md_str = copy(def_font_filters[i].filter);
330 0 : md[2*cnt+1].frozen = true;
331 : }
332 0 : ++cnt;
333 : }
334 : }
335 0 : if ( user_font_filters!=NULL ) {
336 0 : for ( i=0; user_font_filters[i].name!=NULL; ++i ) {
337 0 : if ( *(char *) user_font_filters[i].name != '-' ) {
338 0 : if ( k ) {
339 0 : md[2*cnt].u.md_str = copy(user_font_filters[i].name);
340 0 : md[2*cnt].frozen = false;
341 0 : md[2*cnt+1].u.md_str = copy(user_font_filters[i].filter);
342 0 : md[2*cnt+1].frozen = false;
343 : }
344 0 : ++cnt;
345 : }
346 : }
347 : }
348 0 : if ( !k )
349 0 : md = calloc(2*cnt,sizeof(struct matrix_data));
350 : }
351 0 : mi.initial_row_cnt = cnt;
352 0 : mi.matrix_data = md;
353 :
354 :
355 0 : memset(&d,'\0',sizeof(d));
356 :
357 0 : memset(&wattrs,0,sizeof(wattrs));
358 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_restrict|wam_isdlg;
359 0 : wattrs.event_masks = ~(1<<et_charup);
360 0 : wattrs.restrict_input_to_me = 1;
361 0 : wattrs.is_dlg = true;
362 0 : wattrs.undercursor = 1;
363 0 : wattrs.cursor = ct_pointer;
364 0 : wattrs.utf8_window_title = _("Edit Font Filters");
365 0 : pos.x = pos.y = 0;
366 0 : ptwidth = 2*GIntGetResource(_NUM_Buttonsize)+GGadgetScale(60);
367 0 : pos.width =GDrawPointsToPixels(NULL,ptwidth);
368 0 : pos.height = GDrawPointsToPixels(NULL,90);
369 0 : gw = GDrawCreateTopWindow(NULL,&pos,filter_e_h,&d,&wattrs);
370 :
371 :
372 0 : memset(&label,0,sizeof(label));
373 0 : memset(&gcd,0,sizeof(gcd));
374 0 : memset(&boxes,0,sizeof(boxes));
375 :
376 0 : gcd[0].gd.pos.x = 10; gcd[0].gd.pos.y = 6;
377 0 : gcd[0].gd.pos.width = 300; gcd[0].gd.pos.height = 200;
378 0 : gcd[0].gd.flags = gg_visible | gg_enabled;
379 0 : gcd[0].creator = GMatrixEditCreate;
380 0 : gcd[0].gd.u.matrix = &mi;
381 0 : varray[0] = &gcd[0]; varray[1] = NULL;
382 :
383 0 : gcd[1].gd.pos.x = 20-3; gcd[1].gd.pos.y = 90-35-3;
384 0 : gcd[1].gd.pos.width = -1; gcd[1].gd.pos.height = 0;
385 0 : gcd[1].gd.flags = gg_visible | gg_enabled | gg_but_default;
386 0 : label[1].text = (unichar_t *) _("_OK");
387 0 : label[1].text_is_1byte = true;
388 0 : label[1].text_in_resource = true;
389 0 : gcd[1].gd.label = &label[1];
390 0 : gcd[1].gd.handle_controlevent = Filter_OK;
391 0 : gcd[1].creator = GButtonCreate;
392 0 : harray[0] = GCD_Glue; harray[1] = &gcd[1]; harray[2] = GCD_Glue;
393 :
394 0 : gcd[2].gd.pos.x = -20; gcd[2].gd.pos.y = 90-35;
395 0 : gcd[2].gd.pos.width = -1; gcd[2].gd.pos.height = 0;
396 0 : gcd[2].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
397 0 : label[2].text = (unichar_t *) _("_Cancel");
398 0 : label[2].text_is_1byte = true;
399 0 : label[2].text_in_resource = true;
400 0 : gcd[2].gd.label = &label[2];
401 0 : gcd[2].gd.handle_controlevent = Filter_Cancel;
402 0 : gcd[2].creator = GButtonCreate;
403 0 : harray[3] = GCD_Glue; harray[4] = &gcd[2]; harray[5] = GCD_Glue;
404 0 : harray[6] = NULL;
405 0 : varray[2] = &boxes[2]; varray[3] = NULL;
406 0 : varray[4] = NULL;
407 :
408 0 : boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
409 0 : boxes[0].gd.flags = gg_enabled|gg_visible;
410 0 : boxes[0].gd.u.boxelements = varray;
411 0 : boxes[0].creator = GHVGroupCreate;
412 :
413 0 : boxes[2].gd.flags = gg_enabled|gg_visible;
414 0 : boxes[2].gd.u.boxelements = harray;
415 0 : boxes[2].creator = GHBoxCreate;
416 :
417 :
418 0 : GGadgetsCreate(gw,boxes);
419 0 : GHVBoxSetExpandableRow(boxes[0].ret,0);
420 0 : GHVBoxSetExpandableCol(boxes[2].ret,gb_expandgluesame);
421 0 : GHVBoxFitWindow(boxes[0].ret);
422 0 : GMatrixEditSetNewText(gcd[0].ret,S_("Filter|New"));
423 0 : d.gme = gcd[0].ret;
424 :
425 0 : GDrawSetVisible(gw,true);
426 0 : while ( !d.done )
427 0 : GDrawProcessOneEvent(NULL);
428 0 : GDrawDestroyWindow(gw);
429 :
430 0 : for ( i=0; i<cnt; ++i ) {
431 0 : free(md[2*i].u.md_str);
432 0 : free(md[2*i+1].u.md_str);
433 : }
434 0 : free(md);
435 0 : }
436 :
437 : struct gfc_data {
438 : int done;
439 : unichar_t *ret;
440 : GGadget *gfc;
441 : GGadget *rename;
442 : int filename_popup_pos;
443 : unichar_t *lastpopupfontname;
444 : };
445 :
446 0 : static int GFD_Ok(GGadget *g, GEvent *e) {
447 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
448 0 : struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
449 : GGadget *tf;
450 0 : GFileChooserGetChildren(d->gfc,NULL,NULL,&tf);
451 0 : if ( *_GGadgetGetTitle(tf)!='\0' ) {
452 : extern int allow_utf8_glyphnames;
453 0 : GTextInfo *ti = GGadgetGetListItemSelected(d->rename);
454 0 : char *nlname = u2utf8_copy(ti->text);
455 0 : force_names_when_opening = NameListByName(nlname);
456 0 : free(nlname);
457 0 : if ( force_names_when_opening!=NULL && force_names_when_opening->uses_unicode &&
458 0 : !allow_utf8_glyphnames) {
459 0 : ff_post_error(_("Namelist contains non-ASCII names"),_("Glyph names should be limited to characters in the ASCII character set, but there are names in this namelist which use characters outside that range."));
460 0 : return(true);
461 : }
462 0 : d->done = true;
463 0 : d->ret = GGadgetGetTitle(d->gfc);
464 :
465 : // Trim trailing '/' if its there and put that string back as
466 : // the d->gfc string.
467 0 : int tmplen = u_strlen( d->ret );
468 0 : if( tmplen > 0 ) {
469 0 : if( d->ret[ tmplen-1 ] == '/' ) {
470 0 : unichar_t* tmp = u_copy( d->ret );
471 0 : tmp[ tmplen-1 ] = '\0';
472 0 : GGadgetSetTitle(d->gfc, tmp);
473 0 : free(tmp);
474 0 : d->ret = GGadgetGetTitle(d->gfc);
475 : }
476 : }
477 : }
478 : }
479 0 : return( true );
480 : }
481 :
482 0 : static int GFD_New(GGadget *g, GEvent *e) {
483 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
484 0 : struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
485 0 : d->done = true;
486 0 : GDrawSetVisible(GGadgetGetWindow(g),false);
487 0 : FontNew();
488 : }
489 0 : return( true );
490 : }
491 :
492 0 : static int GFD_Cancel(GGadget *g, GEvent *e) {
493 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
494 0 : struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
495 0 : d->done = true;
496 : }
497 0 : return( true );
498 : }
499 :
500 0 : static int GFD_FilterSelected(GGadget *g, GEvent *e) {
501 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
502 0 : struct gfc_data *d = GDrawGetUserData(GGadgetGetWindow(g));
503 0 : GTextInfo *ti = GGadgetGetListItemSelected(g);
504 0 : if ( ti->userdata==NULL )
505 : /* They selected a line. Dull */;
506 0 : else if ( ti->userdata == (void *) -1 ) {
507 0 : FilterDlg();
508 0 : GGadgetSetList(g,StandardFilters(),true);
509 : } else {
510 0 : unichar_t *temp = utf82u_copy(ti->userdata);
511 0 : GFileChooserSetFilterText(d->gfc,temp);
512 0 : free(temp);
513 0 : temp = GFileChooserGetDir(d->gfc);
514 0 : GFileChooserSetDir(d->gfc,temp);
515 0 : free(temp);
516 0 : default_font_filter_index = GGadgetGetFirstListSelectedItem(g);
517 0 : SavePrefs(true);
518 : }
519 : }
520 0 : return( true );
521 : }
522 :
523 0 : static int WithinList(struct gfc_data *d,GEvent *event) {
524 : GRect size;
525 : GGadget *list;
526 : int32 pos;
527 : unichar_t *ufile;
528 : char *file, **fontnames;
529 : int cnt, len;
530 : unichar_t *msg;
531 :
532 0 : if ( event->type!=et_mousemove )
533 0 : return( false );
534 :
535 0 : GFileChooserGetChildren(d->gfc,NULL, &list, NULL);
536 0 : if ( list==NULL )
537 0 : return( false );
538 0 : if ( !GGadgetWithin(list,event->u.mouse.x,event->u.mouse.y) )
539 0 : return( false );
540 0 : pos = GListIndexFromY(list,event->u.mouse.y);
541 0 : if ( pos == d->filename_popup_pos )
542 0 : return( pos!=-1 );
543 0 : if ( pos==-1 || GFileChooserPosIsDir(d->gfc,pos)) {
544 0 : d->filename_popup_pos = -1;
545 0 : return( pos!=-1 );
546 : }
547 0 : ufile = GFileChooserFileNameOfPos(d->gfc,pos);
548 0 : if ( ufile==NULL )
549 0 : return( true );
550 0 : file = u2def_copy(ufile);
551 0 : free(ufile);
552 :
553 0 : fontnames = GetFontNames(file, 0);
554 0 : if ( fontnames==NULL || fontnames[0]==NULL )
555 0 : msg = uc_copy( "???" );
556 : else {
557 0 : len = 0;
558 0 : for ( cnt=0; fontnames[cnt]!=NULL; ++cnt )
559 0 : len += strlen(fontnames[cnt])+1;
560 0 : msg = malloc((len+2)*sizeof(unichar_t));
561 0 : len = 0;
562 0 : for ( cnt=0; fontnames[cnt]!=NULL; ++cnt ) {
563 0 : uc_strcpy(msg+len,fontnames[cnt]);
564 0 : len += strlen(fontnames[cnt]);
565 0 : msg[len++] = '\n';
566 : }
567 0 : msg[len-1] = '\0';
568 : }
569 0 : GGadgetPreparePopup(GGadgetGetWindow(d->gfc),msg);
570 0 : if ( fontnames!=NULL ) {
571 0 : for ( cnt=0; fontnames[cnt]!=NULL; ++cnt ) {
572 0 : free(fontnames[cnt]);
573 : }
574 0 : free(fontnames);
575 : }
576 0 : free(file);
577 0 : free(d->lastpopupfontname);
578 0 : d->lastpopupfontname = msg;
579 0 : return( true );
580 : }
581 :
582 0 : static int e_h(GWindow gw, GEvent *event) {
583 0 : if ( event->type==et_close ) {
584 0 : struct gfc_data *d = GDrawGetUserData(gw);
585 0 : d->done = true;
586 0 : } else if ( event->type == et_map ) {
587 : /* Above palettes */
588 0 : GDrawRaise(gw);
589 0 : } else if ( event->type == et_char ) {
590 0 : return( false );
591 0 : } else if ( event->type == et_mousemove ||
592 0 : (event->type==et_mousedown && event->u.mouse.button==3 )) {
593 0 : struct gfc_data *d = GDrawGetUserData(gw);
594 0 : if ( !WithinList(d,event) )
595 0 : GFileChooserPopupCheck(d->gfc,event);
596 0 : } else if (( event->type==et_mouseup || event->type==et_mousedown ) &&
597 0 : (event->u.mouse.button>=4 && event->u.mouse.button<=7) ) {
598 0 : struct gfc_data *d = GDrawGetUserData(gw);
599 0 : return( GGadgetDispatchEvent((GGadget *) (d->gfc),event));
600 0 : } else if ( event->type == et_resize ) {
601 : GRect r, size;
602 0 : struct gfc_data *d = GDrawGetUserData(gw);
603 0 : if ( d->gfc!=NULL ) {
604 0 : GDrawGetSize(gw,&size);
605 0 : GGadgetGetSize(d->gfc,&r);
606 0 : GGadgetResize(d->gfc,size.width-2*r.x,r.height);
607 : }
608 : }
609 0 : return( event->type!=et_char );
610 : }
611 :
612 0 : unichar_t *FVOpenFont(char *title, const char *defaultfile, int mult) {
613 : GRect pos;
614 : int i, filter, renamei;
615 : GWindow gw;
616 : GWindowAttrs wattrs;
617 : GGadgetCreateData gcd[11], boxes[5], *varray[9], *harray1[7], *harray2[4], *harray3[9];
618 : GTextInfo label[10];
619 : struct gfc_data d;
620 0 : int bs = GIntGetResource(_NUM_Buttonsize), bsbigger, totwid, spacing;
621 : GGadget *tf;
622 : unichar_t *temp;
623 : char **nlnames;
624 : GTextInfo *namelistnames, **filts;
625 : int cnt;
626 :
627 0 : memset(&d,'\0',sizeof(d));
628 :
629 0 : memset(&wattrs,0,sizeof(wattrs));
630 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
631 0 : wattrs.event_masks = ~(1<<et_charup);
632 0 : wattrs.restrict_input_to_me = 1;
633 0 : wattrs.is_dlg = true;
634 0 : wattrs.undercursor = 1;
635 0 : wattrs.cursor = ct_pointer;
636 0 : wattrs.utf8_window_title = title;
637 0 : pos.x = pos.y = 0;
638 :
639 0 : totwid = GGadgetScale(295);
640 0 : bsbigger = 4*bs+4*14>totwid; totwid = bsbigger?4*bs+4*12:totwid;
641 0 : spacing = (totwid-4*bs-2*12)/3;
642 :
643 0 : pos.width = GDrawPointsToPixels(NULL,totwid);
644 0 : pos.height = GDrawPointsToPixels(NULL,247);
645 0 : gw = GDrawCreateTopWindow(NULL,&pos,e_h,&d,&wattrs);
646 :
647 0 : memset(&label,0,sizeof(label));
648 0 : memset(&gcd,0,sizeof(gcd));
649 0 : memset(&boxes,0,sizeof(boxes));
650 0 : i=0;
651 0 : gcd[i].gd.pos.x = 12; gcd[i].gd.pos.y = 6; gcd[i].gd.pos.width = totwid*100/GIntGetResource(_NUM_ScaleFactor)-24; gcd[i].gd.pos.height = 180;
652 0 : gcd[i].gd.flags = gg_visible | gg_enabled;
653 0 : if ( RecentFiles[0]!=NULL )
654 0 : gcd[i].gd.flags = gg_visible | gg_enabled | gg_file_pulldown;
655 0 : if ( mult )
656 0 : gcd[i].gd.flags |= gg_file_multiple;
657 0 : varray[0] = &gcd[i]; varray[1] = NULL;
658 0 : gcd[i++].creator = GFileChooserCreate;
659 :
660 0 : label[i].text = (unichar_t *) _("Filter:");
661 0 : label[i].text_is_1byte = true;
662 0 : gcd[i].gd.label = &label[i];
663 0 : gcd[i].gd.pos.x = 8; gcd[i].gd.pos.y = 188+6;
664 0 : gcd[i].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
665 0 : gcd[i].gd.popup_msg = (unichar_t *) _("Display files of this type" );
666 0 : harray1[0] = GCD_Glue; harray1[1] = &gcd[i];
667 0 : gcd[i++].creator = GLabelCreate;
668 :
669 0 : gcd[i].gd.pos.x = 0; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y-6;
670 0 : gcd[i].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
671 0 : gcd[i].gd.popup_msg = (unichar_t *) _("Display files of this type");
672 0 : gcd[i].gd.handle_controlevent = GFD_FilterSelected;
673 0 : harray1[2] = &gcd[i]; harray1[3] = GCD_Glue; harray1[4] = GCD_Glue; harray1[5] = GCD_Glue; harray1[6] = NULL;
674 0 : gcd[i++].creator = GListButtonCreate;
675 :
676 0 : boxes[2].gd.flags = gg_visible | gg_enabled;
677 0 : boxes[2].gd.u.boxelements = harray1;
678 0 : boxes[2].creator = GHBoxCreate;
679 0 : varray[2] = &boxes[2]; varray[3] = NULL;
680 :
681 0 : label[i].text = (unichar_t *) _("Force glyph names to:");
682 0 : label[i].text_is_1byte = true;
683 0 : gcd[i].gd.label = &label[i];
684 0 : gcd[i].gd.pos.x = 8; gcd[i].gd.pos.y = 188+6;
685 0 : gcd[i].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
686 0 : gcd[i].gd.popup_msg = (unichar_t *) _("In the saved font, force all glyph names to match those in the specified namelist");
687 0 : harray2[0] = &gcd[i];
688 0 : gcd[i++].creator = GLabelCreate;
689 :
690 0 : renamei = i;
691 0 : gcd[i].gd.pos.x = 0; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y-6;
692 0 : gcd[i].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
693 0 : gcd[i].gd.popup_msg = (unichar_t *) _("In the saved font, force all glyph names to match those in the specified namelist");
694 0 : gcd[i].creator = GListButtonCreate;
695 0 : nlnames = AllNamelistNames();
696 0 : for ( cnt=0; nlnames[cnt]!=NULL; ++cnt);
697 0 : namelistnames = calloc(cnt+3,sizeof(GTextInfo));
698 0 : namelistnames[0].text = (unichar_t *) _("No Rename");
699 0 : namelistnames[0].text_is_1byte = true;
700 0 : if ( force_names_when_opening==NULL ) {
701 0 : namelistnames[0].selected = true;
702 0 : gcd[i].gd.label = &namelistnames[0];
703 : }
704 0 : namelistnames[1].line = true;
705 0 : for ( cnt=0; nlnames[cnt]!=NULL; ++cnt) {
706 0 : namelistnames[cnt+2].text = (unichar_t *) nlnames[cnt];
707 0 : namelistnames[cnt+2].text_is_1byte = true;
708 0 : if ( force_names_when_opening!=NULL &&
709 0 : strcmp(_(force_names_when_opening->title),nlnames[cnt])==0 ) {
710 0 : namelistnames[cnt+2].selected = true;
711 0 : gcd[i].gd.label = &namelistnames[cnt+2];
712 : }
713 : }
714 0 : harray2[1] = &gcd[i]; harray2[2] = GCD_Glue; harray2[3] = NULL;
715 0 : gcd[i++].gd.u.list = namelistnames;
716 :
717 0 : boxes[3].gd.flags = gg_visible | gg_enabled;
718 0 : boxes[3].gd.u.boxelements = harray2;
719 0 : boxes[3].creator = GHBoxCreate;
720 0 : varray[4] = &boxes[3]; varray[5] = NULL;
721 :
722 0 : gcd[i].gd.pos.x = 12; gcd[i].gd.pos.y = 216-3;
723 0 : gcd[i].gd.pos.width = -1;
724 0 : gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_default;
725 0 : label[i].text = (unichar_t *) _("_OK");
726 0 : label[i].text_is_1byte = true;
727 0 : label[i].text_in_resource = true;
728 0 : gcd[i].gd.mnemonic = 'O';
729 0 : gcd[i].gd.label = &label[i];
730 0 : gcd[i].gd.handle_controlevent = GFD_Ok;
731 0 : harray3[0] = GCD_Glue; harray3[1] = &gcd[i];
732 0 : gcd[i++].creator = GButtonCreate;
733 :
734 0 : gcd[i].gd.pos.x = -(spacing+bs)*100/GIntGetResource(_NUM_ScaleFactor)-12; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y+3;
735 0 : gcd[i].gd.pos.width = -1;
736 0 : gcd[i].gd.flags = gg_visible | gg_enabled;
737 0 : label[i].text = (unichar_t *) S_("Font|_New");
738 0 : label[i].text_is_1byte = true;
739 0 : label[i].text_in_resource = true;
740 0 : gcd[i].gd.mnemonic = 'N';
741 0 : gcd[i].gd.label = &label[i];
742 0 : gcd[i].gd.handle_controlevent = GFD_New;
743 0 : harray3[2] = GCD_Glue; harray3[3] = &gcd[i];
744 0 : gcd[i++].creator = GButtonCreate;
745 :
746 0 : filter = i;
747 0 : gcd[i].gd.pos.x = (spacing+bs)*100/GIntGetResource(_NUM_ScaleFactor)+12; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y;
748 0 : gcd[i].gd.pos.width = -1;
749 0 : gcd[i].gd.flags = /* gg_visible |*/ gg_enabled;
750 0 : label[i].text = (unichar_t *) _("_Filter");
751 0 : label[i].text_is_1byte = true;
752 0 : label[i].text_in_resource = true;
753 0 : gcd[i].gd.mnemonic = 'F';
754 0 : gcd[i].gd.label = &label[i];
755 0 : gcd[i].gd.handle_controlevent = GFileChooserFilterEh;
756 0 : harray3[4] = &gcd[i];
757 0 : gcd[i++].creator = GButtonCreate;
758 :
759 0 : gcd[i].gd.pos.x = -12; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y;
760 0 : gcd[i].gd.pos.width = -1;
761 0 : gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
762 0 : label[i].text = (unichar_t *) _("_Cancel");
763 0 : label[i].text_is_1byte = true;
764 0 : label[i].text_in_resource = true;
765 0 : gcd[i].gd.label = &label[i];
766 0 : gcd[i].gd.mnemonic = 'C';
767 0 : gcd[i].gd.handle_controlevent = GFD_Cancel;
768 0 : harray3[5] = GCD_Glue; harray3[6] = &gcd[i]; harray3[7] = GCD_Glue; harray3[8] = NULL;
769 0 : gcd[i++].creator = GButtonCreate;
770 :
771 0 : boxes[4].gd.flags = gg_visible | gg_enabled;
772 0 : boxes[4].gd.u.boxelements = harray3;
773 0 : boxes[4].creator = GHBoxCreate;
774 0 : varray[6] = &boxes[4]; varray[7] = NULL;
775 0 : varray[8] = NULL;
776 :
777 0 : boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
778 0 : boxes[0].gd.flags = gg_visible | gg_enabled;
779 0 : boxes[0].gd.u.boxelements = varray;
780 0 : boxes[0].creator = GHVGroupCreate;
781 :
782 0 : gcd[i].gd.pos.x = 2; gcd[i].gd.pos.y = 2;
783 0 : gcd[i].gd.pos.width = pos.width-4; gcd[i].gd.pos.height = pos.height-4;
784 0 : gcd[i].gd.flags = gg_enabled | gg_visible | gg_pos_in_pixels;
785 0 : gcd[i++].creator = GGroupCreate;
786 :
787 0 : GGadgetsCreate(gw,boxes);
788 :
789 0 : d.gfc = gcd[0].ret;
790 0 : d.rename = gcd[renamei].ret;
791 :
792 0 : filts = StandardFilters();
793 0 : GGadgetSetList(harray1[2]->ret,filts,true);
794 0 : GHVBoxSetExpandableRow(boxes[0].ret,0);
795 0 : GHVBoxSetExpandableCol(boxes[2].ret,gb_expandglue);
796 0 : GHVBoxSetExpandableCol(boxes[3].ret,gb_expandglue);
797 0 : GHVBoxSetExpandableCol(boxes[4].ret,gb_expandgluesame);
798 0 : GHVBoxFitWindow(boxes[0].ret);
799 0 : free(namelistnames);
800 0 : GGadgetSetUserData(gcd[filter].ret,gcd[0].ret);
801 :
802 0 : GFileChooserConnectButtons(gcd[0].ret,harray3[1]->ret,gcd[filter].ret);
803 0 : temp = utf82u_copy(filts[default_font_filter_index]->userdata);
804 0 : GFileChooserSetFilterText(gcd[0].ret,temp);
805 0 : free(temp);
806 0 : GFileChooserGetChildren(gcd[0].ret,NULL, NULL, &tf);
807 0 : if ( RecentFiles[0]!=NULL ) {
808 0 : GGadgetSetList(tf,GTextInfoFromChars(RecentFiles,RECENT_MAX),false);
809 : }
810 0 : GGadgetSetTitle8(gcd[0].ret,defaultfile);
811 :
812 0 : GWidgetHidePalettes();
813 0 : GDrawSetVisible(gw,true);
814 0 : while ( !d.done )
815 0 : GDrawProcessOneEvent(NULL);
816 0 : GDrawDestroyWindow(gw);
817 0 : GDrawProcessPendingEvents(NULL); /* Give the window a chance to vanish... */
818 0 : GDrawSync(NULL);
819 0 : GDrawProcessPendingEvents(NULL); /* Give the window a chance to vanish... */
820 0 : free( d.lastpopupfontname );
821 0 : GTextInfoArrayFree(filts);
822 0 : for ( cnt=0; nlnames[cnt]!=NULL; ++cnt) {
823 0 : free(nlnames[cnt]);
824 : }
825 0 : free(nlnames);
826 0 : return(d.ret);
827 : }
|