Initial revision
[ssr] / StraySrc / Glass / !Glass / c / tfile
1 /*
2 * tfile.c
3 *
4 * Control of template files
5 *
6 * © 1994-1998 Straylight
7 */
8
9 /*----- Licensing note ----------------------------------------------------*
10 *
11 * This file is part of Straylight's Glass.
12 *
13 * Glass is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * Glass is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with Glass. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 /*
31 * ANSI standard headers
32 */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 /*
39 * Steel headers
40 */
41
42 #define _STDAPP
43 #define _XFER
44 #define _LOWLVL
45 #include "steel/Steel.h"
46
47 #include "steel/viewer.h"
48 #include "steel/mem.h"
49 #include "steel/nopoll.h"
50 #include "steel/flex.h"
51 #include "steel/akbd.h"
52 #include "steel/alarm.h"
53 #include "steel/bbc.h"
54 #include "steel/buffer.h"
55 #include "steel/font.h"
56
57 /*
58 * Glass headers
59 */
60
61 #include "gStruct.h"
62 #include "gIcons.h"
63 #include "gMenus.h"
64
65 #include "glass.h"
66 #include "toolbox.h"
67 #include "intMsgs.h"
68 #include "tfile.h"
69 #include "gPrefs.h"
70 #include "gSprite.h"
71 #include "indir.h"
72 #include "window.h"
73 #include "editWin.h"
74 #include "iconData.h"
75
76 /*----- Constants ---------------------------------------------------------*/
77
78 #define tfile__FILEHEIGHT 892 /* Height to open first template window */
79 #define tfile__FILEX 200 /* x position of template file windows */
80 #define tfile__FILETOP 940 /* Height after files wrap around */
81
82 #define tfile__WINDHEIGHT 872 /* Height to create first window */
83 #define tfile__WINDX 450 /* x position of template windows */
84 #define tfile__WINDTOP 920 /* Height after windows wrap around */
85
86 /*----- Static global variables -------------------------------------------*/
87
88 static int tfile__unsavedFiles; /* Number of files not saved */
89 static int tfile__fileHeight=tfile__FILEHEIGHT;
90 /* Height to open next template window */
91 static int tfile__windHeight=tfile__WINDHEIGHT;
92 static int tfile__selectSize; /* Size in bytes of current selection */
93 static int tfile__selectIcons; /* Number of icons in current selection */
94 static int tfile__selectIndSz; /* Indirected data size for selection */
95 static char tfile__grabName[15]; /* Name for the grabbed window */static glass_tfile *tfile__selOwner; /* Owner of the current selection */
96
97 /*----- Support routines --------------------------------------------------*/
98
99 /*
100 * void tfile__tidyFonts(viewer_icon i,void *handle)
101 *
102 * Use
103 * Closes down the fonts on a particular template file.
104 *
105 * Parameters
106 * viewer_icon i == the icon (ignored)
107 * void *handle == the file to close
108 */
109
110 static void tfile__tidyFonts(viewer_icon ic,void *handle)
111 {
112 int i,j;
113 glass_windPointer *w=handle;
114 unused(ic);
115 if (w->antiAliased)
116 {
117 for (i=0;i<256;i++)
118 {
119 for (j=0;j<w->fonts[i];j++)
120 wimpt_noerr(font_lose(i));
121 }
122 }
123 w->antiAliased=FALSE;
124 }
125
126 /*
127 * void tfile__reFindFonts(viewer_icon ic,void *handle)
128 *
129 * Use
130 * Scans the given window, refinding all the fonts it used. This is
131 * because (at present) on a mode change, the aspect ratio can become
132 * utterly trashed. I can't afford to wait until the Font Manager gets
133 * rewritten to work properly, so I have to do it myself...
134 *
135 * After this call, the window needs recreating if it's being displayed.
136 * It will pick up the Open_Window_Request, and recreate on that if it
137 * finds it has some fonts in it.
138 *
139 * This call also resets the antiAliased flag if it finds no fonts in a
140 * window.
141 *
142 * Parameters
143 * viewer_icon ic == the viewer icon of the window to rescan (ignored)
144 * void *handle == an undercover glass_windPointer * to the window
145 */
146
147 static void tfile__reFindFonts(viewer_icon ic,void *handle)
148 {
149 glass_windPointer *w=handle;
150 int i;
151 int icf;
152 os_regset r;
153 int fhand;
154 int newhand;
155 BOOL usedAFont=FALSE;
156 char buff[50];
157 unused(ic);
158
159 if (!w->antiAliased)
160 return;
161 icf=w->def->desc.w.titleflags;
162 if (icf & wimp_IFONT)
163 {
164 usedAFont=TRUE;
165 fhand=(icf>>24) & 0xff;
166 r.r[0]=fhand;
167 r.r[1]=(int)buff;
168 wimpt_noerr(os_swix(XFont_ReadDefn,&r));
169 r.r[4]=r.r[5]=0;
170 if (!wimpt_complain(os_swix(XFont_FindFont,&r)))
171 {
172 newhand=r.r[0];
173 r.r[0]=fhand;
174 wimpt_noerr(os_swix(XFont_LoseFont,&r));
175 w->fonts[fhand]--;
176 w->fonts[newhand]++;
177 w->def->desc.w.titleflags=(icf & 0x00ffffff) | (newhand<<24);
178 }
179 }
180 for (i=0;i<w->def->desc.w.nicons;i++)
181 {
182 icf=w->def->i[i].i.flags;
183 if (icf & wimp_IFONT)
184 {
185 usedAFont=TRUE;
186 fhand=(icf>>24) & 0xff;
187 r.r[0]=fhand;
188 r.r[1]=(int)buff;
189 wimpt_noerr(os_swix(XFont_ReadDefn,&r));
190 r.r[4]=r.r[5]=0;
191 if (!wimpt_complain(os_swix(XFont_FindFont,&r)))
192 {
193 newhand=r.r[0];
194 r.r[0]=fhand;
195 wimpt_noerr(os_swix(XFont_LoseFont,&r));
196 w->fonts[fhand]--;
197 w->fonts[newhand]++;
198 w->def->i[i].i.flags=(icf & 0x00ffffff) | (newhand<<24);
199 }
200 }
201 }
202 w->antiAliased=usedAFont;
203 }
204
205 /*
206 * void tfile__gainSelection(glass_tfile *t)
207 *
208 * Use
209 * Hands the current tfile selection and the input focus to the specified
210 * template file.
211 *
212 * Note that the selection model here is more complex than it is in window,
213 * since the focus tfile may not coincide with the selection owner (since
214 * menu clicks move the selection owner, but not the focus).
215 *
216 * Parameters
217 * glass_tfile *t == the template to which we give the focus
218 */
219
220 static void tfile__gainSelection(glass_tfile *t)
221 {
222 wimp_caretstr c;
223 if (t!=tfile__selOwner)
224 {
225 if (tfile__selOwner)
226 viewer_selectAll(tfile__selOwner->v,FALSE);
227 tfile__selOwner=t;
228 }
229 if (t)
230 {
231 c.w=viewer_syshandle(t->v);
232 c.i=-1;
233 c.x=-250;
234 c.y=0;
235 c.index=-1;
236 c.height=0x02000000;
237 wimpt_noerr(wimp_set_caret_pos(&c));
238 }
239 }
240
241 /*
242 * void tfile__doDeleteWindow(void *handle)
243 *
244 * Use
245 * Deletes, trashes and exterminates a window.
246 *
247 * Parameters
248 * void *handle == the window to eliminate
249 */
250
251 static void tfile__doDeleteWindow(void *handle)
252 {
253 int i;
254 glass_windPointer *w=handle;
255 window_hasBeenDeleted(w);
256 if (w->def->desc.w.titleflags & wimp_INDIRECT)
257 {
258 indir_free(w->def->desc.w.title.indirecttext.buffer);
259 if ((w->def->desc.w.titleflags & wimp_ITEXT) &&
260 (w->def->desc.w.title.indirecttext.validstring!=(char *)-1))
261 indir_free(w->def->desc.w.title.indirecttext.validstring);
262 }
263 for (i=0;i<w->def->desc.w.nicons;i++)
264 {
265 if (w->def->i[i].i.flags & wimp_INDIRECT)
266 {
267 indir_free(w->def->i[i].i.data.indirecttext.buffer);
268 if ((w->def->i[i].i.flags & wimp_ITEXT) &&
269 (w->def->i[i].i.data.indirecttext.validstring!=(char *)-1))
270 indir_free(w->def->i[i].i.data.indirecttext.validstring);
271 }
272 }
273 if (w->def)
274 flex_free((flex_ptr)&w->def);
275 if (w->h)
276 {
277 win_register_event_handler(w->h,0,0);
278 win_activedec();
279 wimpt_noerr(wimp_delete_wind(w->h));
280 }
281 tfile__tidyFonts(0,w);
282 mem_free(w);
283 }
284
285 /*
286 * void tfile__deleteTemplateFile(void *handle)
287 *
288 * Use
289 * Trashes the named template file.
290 *
291 * Parameters
292 * void *handle == the template file to murder
293 */
294
295 static void tfile__deleteTemplateFile(void *handle)
296 {
297 glass_tfile *t=handle;
298 intMsgs_send(glass_DELETEFILE,t);
299 if (t==tfile__selOwner)
300 tfile__selOwner=0;
301 gSprite_kill(t);
302 if (t->alts)
303 tfile__unsavedFiles--;
304 viewer_delete(t->v,tfile__doDeleteWindow);
305 if (t->autod)
306 dbox_delete(t->autod);
307 if (t->autoAlarm)
308 alarm_remove(t->autoAlarm,t);
309 mem_free(t);
310 flex_compact();
311 }
312
313 /*
314 * glass_windPointer *tfile__newWindow(glass_tfile *t,char *name)
315 *
316 * Use
317 * Creates a new window entry in the template file specified. It is up to
318 * the caller to write the window definition.
319 *
320 * Parameters
321 * glass_tfile *t == the template file to add the window to
322 * char *name == the name of the window
323 *
324 * Returns
325 * A pointer to the window structure
326 */
327
328 static glass_windPointer *tfile__newWindow(glass_tfile *t,char *name)
329 {
330 glass_windPointer *w;
331 int i;
332 static int serial; /* Serial number - monotonic increasing */
333 mem_useUser(indir_alloc,indir_free);
334 w=mem_alloc(sizeof(glass_windPointer));
335 if (!w)
336 {
337 werr(FALSE,msgs_lookup("tfNEMCRT"));
338 mem_useMalloc();
339 return (0);
340 }
341 strcpy(w->id,name);
342 w->def=0;
343 w->t=t;
344 w->h=0;
345 w->edit=0;
346 w->size=0;
347 w->gridx=gPrefs_current()->gWidth;
348 w->gridy=gPrefs_current()->gHeight;
349 w->gridShow=gPrefs_current()->gDisp;
350 w->gridLock=gPrefs_current()->gLock;
351 w->serial=serial++; /* Increment serial number count */
352 for (i=0;i<glass_GUIDELIMIT;i++)
353 w->guide[i].active=FALSE;
354 w->antiAliased=FALSE;
355 for (i=0;i<256;i++)
356 w->fonts[i]=0;
357 if (w->i=viewer_addIcon(t->v,name,"tmpltvicon",TRUE,w),!w->i)
358 {
359 mem_free(w);
360 mem_useMalloc();
361 return (0);
362 }
363 viewer_setFiletype(w->i,0xfec);
364 mem_useMalloc();
365 return (w);
366 }
367
368 /*
369 * void tfile__size(viewer_icon i,void *handle)
370 *
371 * Use
372 * Adds the size of the window given by handle to the global variables
373 * tfile__selectSize and tfile__selectIndSz.
374 *
375 * Parameters
376 * viewer_icon i == the viewer icon handle (ignored)
377 * void *handle == the window to count
378 */
379
380 static void tfile__size(viewer_icon i,void *handle)
381 {
382 glass_windPointer *w=handle;
383 unused(i);
384 tfile__selectSize+=w->size;
385 tfile__selectIndSz+=w->size-
386 sizeof(glass_window)-
387 (w->def->desc.w.nicons-1)*
388 sizeof(glass_iconDescription);
389 }
390
391 /*
392 * void tfile__icons(viewer_icon i,void *handle)
393 *
394 * Use
395 * Adds the number of icons in the window given by handle to the global
396 * variable tfile__selectIcons.
397 *
398 * Parameters
399 * viewer_icon i == the viewer icon handle (ignored)
400 * void *handle == the window to count
401 */
402
403 static void tfile__icons(viewer_icon i,void *handle)
404 {
405 glass_windPointer *w=handle;
406 unused(i);
407 tfile__selectIcons+=w->def->desc.w.nicons;
408 }
409
410 /*
411 * BOOL tfile__create(char *new,void *handle)
412 *
413 * Use
414 * Creates a new window.
415 *
416 * Parameters
417 * char *new == the name for the new window
418 * void *handle == pointer to the tfile
419 */
420
421 static BOOL tfile__create(char *new,void *handle)
422 {
423 glass_tfile *t=handle;
424 viewer_icon icn;
425 glass_windPointer *wnew;
426 wimp_wind *w=&template_find("default")->window;
427
428 icn=viewer_findIcon(t->v,new);
429 if (icn==viewer_NOICON)
430 {
431 wnew=tfile__newWindow(t,new);
432 if (!wnew)
433 return (FALSE);
434 tfile_markAsAltered(t);
435 wnew->size=sizeof(glass_window)-sizeof(glass_iconDescription);
436 if (!flex_alloc((flex_ptr)&wnew->def,wnew->size))
437 {
438 viewer_removeIcon(wnew->i);
439 mem_free(wnew);
440 werr(FALSE,msgs_lookup("tfNEMCRT"));
441 return (FALSE);
442 }
443 wnew->def->desc.w=*w;
444 wnew->def->desc.w.nicons=0;
445 if (!iconData_handleFont(wnew,&wnew->def->desc.w.titleflags))
446 werr(FALSE,msgs_lookup("tfFERC"));
447 if (wnew->def->desc.w.titleflags & wimp_IFONT)
448 {
449 wnew->antiAliased=TRUE;
450 wnew->fonts[(wnew->def->desc.w.titleflags>>24) & 0xff]++;
451 }
452 if (!iconData_processIcon(wnew,-1,0,TRUE,0))
453 {
454 werr(FALSE,msgs_lookup("tfNEMCRT"));
455 tfile_deleteWindow(0,wnew);
456 return (FALSE);
457 }
458 wnew->def->desc.w.box.y1=tfile__windHeight;
459 wnew->def->desc.w.box.y0=tfile__windHeight +
460 wnew->def->desc.w.ex.y0 -
461 wnew->def->desc.w.ex.y1;
462 wnew->def->desc.w.box.x0=tfile__WINDX;
463 wnew->def->desc.w.box.x1=tfile__WINDX -
464 wnew->def->desc.w.ex.x0 +
465 wnew->def->desc.w.ex.x1;
466 if (wnew->def->desc.w.box.y0<tfile__windHeight-500)
467 wnew->def->desc.w.box.y0=tfile__windHeight-500;
468 if (wnew->def->desc.w.box.x1>tfile__WINDX+700)
469 wnew->def->desc.w.box.x1=tfile__WINDX+700;
470 wnew->def->desc.w.scx=wnew->def->desc.w.ex.x0;
471 wnew->def->desc.w.scy=wnew->def->desc.w.ex.y1;
472 tfile__windHeight-=48;
473 if (tfile__windHeight<632)
474 tfile__windHeight=tfile__WINDTOP;
475
476 return (TRUE);
477 }
478 note(msgs_lookup("tfNAE"),viewer_textOfIcon(icn));
479 return (FALSE);
480 }
481
482 /*
483 * char *tfile__grabData(char *ptr,void *handle)
484 *
485 * Use
486 * Grabs data from the destination task, as required when setting up a
487 * grabbed window.
488 *
489 * Parameters
490 * char *ptr == pointer to data string (in other task's workspace)
491 * void *handle == not a pointer at all, actually the source task's handle
492 *
493 * Returns
494 * A pointer to a string in my own workspace (static char array)
495 */
496
497 static char *tfile__grabData(char *ptr,void *handle)
498 {
499 char *buff=buffer_find();
500 wimp_t t=(int)handle;
501 if (t)
502 {
503 if (wimp_transferblock(t,ptr,wimpt_task(),buff,256))
504 return ("<error>");
505 }
506 else
507 return ("<indirected>");
508 return (buff);
509 }
510
511 /*
512 * void tfile__grab(wimp_mousestr *m,void *handle)
513 *
514 * Use
515 * Grabs a window definition, inserting it neatly into the template file.
516 *
517 * Parameters
518 * wimp_mousestr *m == info about the window
519 * void *handle == pointer to destination template file
520 */
521
522 static void tfile__grab(wimp_mousestr *m,void *handle)
523 {
524 glass_tfile *t=handle;
525 glass_windPointer *wnew;
526 wimp_winfo *w;
527 os_regset r;
528 int numicons;
529 wimp_t task;
530 wimp_msgstr msg;
531 int i;
532 int ioff;
533 BOOL fonterr=FALSE;
534
535 wnew=tfile__newWindow(t,tfile__grabName);
536 if (!wnew)
537 return;
538 tfile_markAsAltered(t);
539 if (wimpt_getVersion()>=300) /* RISC OS 3 allows 'safe' GetWindowInfos */
540 w=mem_alloc(sizeof(wimp_winfo));
541 else
542 w=mem_alloc(sizeof(wimp_winfo)+200*sizeof(wimp_icon));
543 if (!w)
544 {
545 werr(FALSE,msgs_lookup("tfNEMGW"));
546 viewer_removeIcon(wnew->i);
547 mem_free(wnew);
548 return;
549 }
550 w->w=m->w;
551 r.r[1]=(int)w;
552 if (wimpt_getVersion()>=300)
553 r.r[1]++; /* RO3 - only window header, not icons */
554 wimpt_noerr(os_swix(XWimp_GetWindowInfo,&r)); /* Get the information */
555 numicons=w->info.nicons;
556 mem_free(w);
557 wnew->size=sizeof(glass_window)+
558 (numicons-1)*sizeof(glass_iconDescription);
559 if (!flex_alloc((flex_ptr)&w,
560 sizeof(wimp_winfo)+numicons*sizeof(wimp_icon)))
561 {
562 viewer_removeIcon(wnew->i);
563 mem_free(wnew);
564 werr(FALSE,msgs_lookup("tfNEMGW"));
565 return;
566 }
567 if (!flex_alloc((flex_ptr)&wnew->def,wnew->size))
568 {
569 flex_free((flex_ptr)&w);
570 viewer_removeIcon(wnew->i);
571 mem_free(wnew);
572 werr(FALSE,msgs_lookup("tfNEMGW"));
573 return;
574 }
575 w->w=m->w;
576 r.r[1]=(int)w;
577 wimpt_noerr(os_swix(XWimp_GetWindowInfo,&r)); /* Read the window properly*/
578
579 msg.hdr.size=20;
580 msg.hdr.your_ref=0;
581 msg.hdr.action=0;
582 r.r[0]=19;
583 r.r[1]=(int)&msg;
584 r.r[2]=m->w;
585 r.r[3]=m->i;
586 if (os_swix(XWimp_SendMessage,&r))
587 task=0;
588 else
589 task=r.r[2];
590
591 wnew->def->desc.w=w->info;
592 wnew->def->desc.w.nicons=0;
593 if (!iconData_handleFont(wnew,&wnew->def->desc.w.titleflags) && !fonterr)
594 {
595 werr(FALSE,msgs_lookup("tfFERG"));
596 fonterr=TRUE;
597 }
598 if (!iconData_processIcon(wnew,-1,tfile__grabData,TRUE,(void *)task))
599 {
600 flex_free((flex_ptr)&w);
601 tfile_deleteWindow(0,wnew);
602 werr(FALSE,msgs_lookup("tfNEMGW"));
603 return;
604 }
605
606 ioff=sizeof(wimp_winfo);
607 for (i=0;i<numicons;i++)
608 {
609 wnew->def->i[i].i=*_ptr(wimp_icon,w,ioff);
610 wnew->def->i[i].edit=0;
611 if (!iconData_handleFont(wnew,&wnew->def->i[i].i.flags) && !fonterr)
612 {
613 werr(FALSE,msgs_lookup("tfFERG"));
614 fonterr=TRUE;
615 }
616 if (!iconData_processIcon(wnew,i,tfile__grabData,TRUE,(void *)task))
617 {
618 flex_free((flex_ptr)&w);
619 tfile_deleteWindow(0,wnew);
620 werr(FALSE,msgs_lookup("tfNEMGW"));
621 return;
622 }
623 wnew->def->desc.w.nicons++;
624 ioff+=sizeof(wimp_icon);
625 }
626 flex_free((flex_ptr)&w);
627 }
628
629 /*
630 * BOOL tfile__grabGetName(char *name,void *handle)
631 *
632 * Use
633 * Handles the writable box for a grab window job and starts the grab op
634 *
635 * Parameters
636 * char *name == the user's name for the window
637 * void *handle == the template file to grab to
638 *
639 * Returns
640 * TRUE if the name was valid and the grab has been set up
641 */
642
643 static BOOL tfile__grabGetName(char *name,void *handle)
644 {
645 glass_tfile *t=handle;
646 viewer_icon icn;
647
648 icn=viewer_findIcon(t->v,name);
649 if (icn==viewer_NOICON)
650 {
651 strcpy(tfile__grabName,name);
652 event_clear_current_menu();
653 window_grab(tfile__grab,t);
654 return (TRUE);
655 }
656 note(msgs_lookup("tfNAE"),
657 viewer_textOfIcon(icn));
658 return (FALSE);
659 }
660
661 /*
662 * BOOL tfile__copy(char *new,void *handle)
663 *
664 * Use
665 * Copies the specified window
666 *
667 * Parameters
668 * char *new == the name for the new window
669 * void *handle == pointer to the window structure
670 */
671
672 static BOOL tfile__copy(char *new,void *handle)
673 {
674 glass_windPointer *w=handle;
675 viewer_icon icn;
676 glass_windPointer *wnew;
677 int i;
678 int numicons;
679 BOOL fonterr=FALSE;
680
681 icn=viewer_findIcon(w->t->v,new);
682 if (icn==viewer_NOICON)
683 {
684 wnew=tfile__newWindow(w->t,new);
685 if (!wnew)
686 return (FALSE);
687 tfile_markAsAltered(w->t);
688 wnew->size=w->size;
689 numicons=w->def->desc.w.nicons;
690 if (!flex_alloc((flex_ptr)&wnew->def,
691 sizeof(glass_window)
692 +(numicons-1)*sizeof(glass_iconDescription)))
693 {
694 viewer_removeIcon(wnew->i);
695 mem_free(wnew);
696 werr(FALSE,msgs_lookup("tfNEMCW"));
697 return (FALSE);
698 }
699 memcpy
700 (
701 wnew->def,
702 w->def,
703 sizeof(glass_window)+(numicons-1)*sizeof(glass_iconDescription)
704 );
705 wnew->def->desc.w.nicons=0;
706 if (!iconData_handleFont(wnew,&wnew->def->desc.w.titleflags) && !fonterr)
707 {
708 werr(FALSE,msgs_lookup("tfFERCP"));
709 fonterr=TRUE;
710 }
711 if (!iconData_processIcon(wnew,-1,0,FALSE,0))
712 {
713 werr(FALSE,msgs_lookup("tfNEMCW"));
714 tfile_deleteWindow(0,wnew);
715 return (FALSE);
716 }
717 for (i=0;i<numicons;i++)
718 {
719 if (!iconData_handleFont(wnew,&wnew->def->i[i].i.flags) && !fonterr)
720 {
721 werr(FALSE,msgs_lookup("tfFERCP"));
722 fonterr=TRUE;
723 }
724 if (!iconData_processIcon(wnew,i,0,FALSE,0))
725 {
726 werr(FALSE,msgs_lookup("tfNEMCW"));
727 tfile_deleteWindow(0,wnew);
728 return (FALSE);
729 }
730 wnew->def->desc.w.nicons++;
731 }
732 return (TRUE);
733 }
734 note(msgs_lookup("tfNAE"),
735 viewer_textOfIcon(icn));
736 return (FALSE);
737 }
738
739 /*
740 * void tfile__openWindows(viewer_icon i,void *handle)
741 *
742 * Use
743 * Opens a window. This is called when the user drags icons to the icon
744 * bar and expects them to be displayed.
745 *
746 * Parameters
747 * viewer_icon i == the icon handle of the icon representing the window
748 * (ignored)
749 * void *handle == pointer to the window's static information
750 */
751
752 static void tfile__openWindows(viewer_icon i,void *handle)
753 {
754 glass_windPointer *w=handle;
755 unused(i);
756 window_open(w,FALSE);
757 }
758
759 /*----- Variables used during the save process ----------------------------*/
760
761 #ifndef glass_DEMO
762
763 static void **tfile__flex; /* A flex block for saving data */
764 static int tfile__flexSize; /* Size of the flex block */
765 static int tfile__flexUsed; /* How much of the block has been used */
766 static BOOL tfile__abortSave; /* If TRUE, abort the save process */
767 static int tfile__nextIndex; /* Offset to next free index entry */
768 static char tfile__fontbinding[256]; /* Conversion realh -> internh */
769 static char tfile__backbinding[256]; /* Reverse font binding */
770 static char tfile__nextFont; /* The next free internal font handle */
771
772 /*----- Save templates support routines -----------------------------------*/
773
774 /*
775 * This section contains the actual code to save a template file or
776 * selection.
777 */
778
779 /*
780 * BOOL tfile__saveAlloc(int size)
781 *
782 * Use
783 * Ensures that a certain quantity of space is present in the save flex
784 * block.
785 *
786 * Parameters
787 * int size == the size required in bytes
788 *
789 * Returns
790 * TRUE if successful, or FALSE if allocation failed. An error is also
791 * reported.
792 */
793
794 static BOOL tfile__saveAlloc(int size)
795 {
796 int szreqd;
797 if (tfile__flexSize-tfile__flexUsed>size)
798 return (TRUE);
799 szreqd=(tfile__flexUsed+size+8191) & ~8191;
800 if (!flex_extend(tfile__flex,szreqd))
801 {
802 werr(FALSE,msgs_lookup("tfNEMST"));
803 return (FALSE);
804 }
805 tfile__flexSize=szreqd;
806 return (TRUE);
807 }
808
809 /*
810 * BOOL tfile__addBlock(void *p,size_t sz)
811 *
812 * Use
813 * Adds a block of data to the end of the save block.
814 *
815 * Parameters
816 * void *p == pointer to the block
817 * size_t sz == the size of the block
818 *
819 * Returns
820 * TRUE if successful
821 */
822
823 static BOOL tfile__addBlock(void *p,size_t sz)
824 {
825 if (!tfile__saveAlloc(sz))
826 return (FALSE);
827 memcpy(_ptr(void,*tfile__flex,tfile__flexUsed),p,sz);
828 tfile__flexUsed+=sz;
829 return (TRUE);
830 }
831
832 #define tfile__writeString(s,off) \
833 { \
834 strcpy(charptr(*tfile__flex,off),s); \
835 charptr(*tfile__flex,off)[strlen(s)]=13; \
836 }
837
838 /*
839 * BOOL tfile__addString(char *s)
840 *
841 * Use
842 * Adds a ctrl-terminated string to the end of the save block.
843 *
844 * Parameters
845 * char *s == pointer to the string to store
846 *
847 * Returns
848 * TRUE if successful
849 */
850
851 static BOOL tfile__addString(char *s)
852 {
853 int len;
854 utils_ctermToNterm(s);
855 len=strlen(s);
856 if (!tfile__saveAlloc(len+1))
857 return (FALSE);
858 tfile__writeString(s,tfile__flexUsed);
859 tfile__flexUsed+=len+1;
860 return (TRUE);
861 }
862
863 /*
864 * void tfile__processWindow(viewer_icon icn,void *handle)
865 *
866 * Use
867 * Saves the window given onto the end of the flex block being used for
868 * such a purpose. A save may be aborted by setting the variable
869 * tfile__abortSave.
870 *
871 * Parameters
872 * viewer_icon icn == the icon representing the window to be saved (ignored)
873 * void *handle == pointer to the window structure in memory
874 */
875
876 static void tfile__processWindow(viewer_icon icn,void *handle)
877 {
878 int start;
879 int i;
880 int idef;
881 int ifont,rfont;
882 glass_windPointer *w=handle;
883 unused(icn);
884 if (tfile__abortSave)
885 return;
886 while (tfile__flexUsed & 3)
887 *charptr(*tfile__flex,tfile__flexUsed++)=0;
888
889 /* --- Start on the index --- */
890 intptr(*tfile__flex,tfile__nextIndex)[0]=start=tfile__flexUsed;
891 intptr(*tfile__flex,tfile__nextIndex)[2]=1;
892 tfile__writeString(w->id,tfile__nextIndex+12);
893
894 /* --- Now copy the window and icons --- */
895 if (!tfile__addBlock(&w->def->desc.w,sizeof(wimp_wind)))
896 {
897 tfile__abortSave=TRUE;
898 return;
899 }
900 for (i=0;i<w->def->desc.w.nicons;i++)
901 {
902 if (!tfile__addBlock(&w->def->i[i].i,sizeof(wimp_icon)))
903 {
904 tfile__abortSave=TRUE;
905 return;
906 }
907 }
908
909 /* --- Process window def for indirection and fonts --- */
910 _ptr(wimp_wind,*tfile__flex,start)->spritearea=(void *)1;
911 if (w->def->desc.w.titleflags & wimp_IFONT)
912 {
913 rfont=w->def->desc.w.titleflags >> 24;
914 if (tfile__fontbinding[rfont])
915 ifont=tfile__fontbinding[rfont];
916 else
917 {
918 ifont=tfile__fontbinding[rfont]=tfile__nextFont++;
919 tfile__backbinding[ifont]=rfont;
920 }
921 _ptr(wimp_wind,*tfile__flex,start) -> titleflags=
922 (w->def->desc.w.titleflags & 0x00ffffff) | (ifont << 24);
923 }
924 if (w->def->desc.w.titleflags & wimp_INDIRECT)
925 {
926 _ptr(wimp_wind,*tfile__flex,start) -> title.indirecttext.buffer=
927 (char *)(tfile__flexUsed-start);
928 if (!tfile__addString(w->def->desc.w.title.indirecttext.buffer))
929 {
930 tfile__abortSave=TRUE;
931 return;
932 }
933 if (w->def->desc.w.titleflags & wimp_ITEXT)
934 {
935 if (w->def->desc.w.title.indirecttext.validstring!=(char *)-1)
936 {
937 _ptr(wimp_wind,*tfile__flex,start)->title.indirecttext.validstring=
938 (char *)(tfile__flexUsed-start);
939 if (!tfile__addString(w->def->desc.w.title.indirecttext.validstring))
940 {
941 tfile__abortSave=TRUE;
942 return;
943 }
944 }
945 }
946 else if (w->def->desc.w.titleflags & wimp_ISPRITE)
947 {
948 _ptr(wimp_wind,*tfile__flex,start)->title.indirectsprite.spritearea=
949 (void *)1;
950 }
951 }
952
953 /* --- Now the same for the icons --- */
954 idef=start+sizeof(wimp_wind);
955 for (i=0;i<w->def->desc.w.nicons;i++)
956 {
957 if (w->def->i[i].i.flags & wimp_IFONT)
958 {
959 rfont=w->def->i[i].i.flags >> 24;
960 if (tfile__fontbinding[rfont])
961 ifont=tfile__fontbinding[rfont];
962 else
963 {
964 ifont=tfile__fontbinding[rfont]=tfile__nextFont++;
965 tfile__backbinding[ifont]=rfont;
966 }
967 _ptr(wimp_icon,*tfile__flex,idef)->flags=
968 (w->def->i[i].i.flags & 0x00ffffff) | (ifont << 24);
969 }
970 if (w->def->i[i].i.flags & wimp_INDIRECT)
971 {
972 _ptr(wimp_icon,*tfile__flex,idef)->data.indirecttext.buffer=
973 (char *)(tfile__flexUsed-start);
974 if (!tfile__addString(w->def->i[i].i.data.indirecttext.buffer))
975 {
976 tfile__abortSave=TRUE;
977 return;
978 }
979 if (w->def->i[i].i.flags & wimp_ITEXT)
980 {
981 if (w->def->i[i].i.data.indirecttext.validstring!=(char *)-1)
982 {
983 _ptr(wimp_icon,*tfile__flex,idef)->data.indirecttext.validstring=
984 (char *)(tfile__flexUsed-start);
985 if (!tfile__addString(w->def->i[i].i.data.
986 indirecttext.validstring))
987 {
988 tfile__abortSave=TRUE;
989 return;
990 }
991 }
992 }
993 else if (w->def->i[i].i.flags & wimp_ISPRITE)
994 {
995 _ptr(wimp_icon,*tfile__flex,idef)->data.indirectsprite.spritearea=
996 (void *)1;
997 }
998 }
999 idef+=sizeof(wimp_icon);
1000 }
1001 intptr(*tfile__flex,tfile__nextIndex)[1]=tfile__flexUsed-start;
1002 tfile__nextIndex+=24;
1003 }
1004
1005 /*
1006 * BOOL tfile__setupSave(glass_tfile *t,
1007 * glass_windPointer *w,
1008 * void **p,
1009 * BOOL onlySelected)
1010 *
1011 * Use
1012 * Sets up a flex block for saving a template file, selection or single
1013 * window. To save a template file or selection, set t==tfile, w==0. To
1014 * save a window, set t==0, w==window.
1015 *
1016 * Parameters
1017 * glass_tfile *t == the template file that we're saving
1018 * glass_windPointer *w == the window we're saving
1019 * void **p == pointer used as flex anchor (free after use yourself)
1020 * BOOL onlySelected == do we only save the selected templates?
1021 *
1022 * Returns
1023 * TRUE if operation completed successfully
1024 */
1025
1026 static BOOL tfile__setupSave(glass_tfile *t,
1027 glass_windPointer *w,
1028 void **p,
1029 BOOL onlySelected)
1030 {
1031 int i;
1032 int numwin;
1033 os_regset r;
1034 char buff[40];
1035 if (!flex_alloc(p,tfile__selectSize))
1036 {
1037 werr(FALSE,msgs_lookup("tfNEMST"));
1038 return (FALSE);
1039 }
1040 tfile__flex=p;
1041 tfile__flexSize=tfile__selectSize;
1042 tfile__flexUsed=0;
1043 tfile__abortSave=FALSE;
1044 for (i=0;i<256;i++)
1045 {
1046 tfile__fontbinding[i]=0;
1047 tfile__backbinding[i]=0;
1048 }
1049 tfile__nextFont=1;
1050
1051 /* --- Header --- */
1052 if (!tfile__saveAlloc(16))
1053 {
1054 flex_free(p);
1055 return (FALSE);
1056 }
1057 intptr(*tfile__flex,0)[0]=-1;
1058 intptr(*tfile__flex,0)[1]=0;
1059 intptr(*tfile__flex,0)[2]=0;
1060 intptr(*tfile__flex,0)[3]=0;
1061 tfile__flexUsed+=16;
1062
1063 /* --- Set up index entries --- */
1064 if (t)
1065 {
1066 if (onlySelected)
1067 numwin=viewer_selected(t->v);
1068 else
1069 numwin=viewer_icons(t->v);
1070 }
1071 else
1072 numwin=1;
1073 if (!tfile__saveAlloc(24*numwin+4))
1074 {
1075 flex_free(p);
1076 return (FALSE);
1077 }
1078
1079 /* --- Now insert window and icon definitions --- */
1080 tfile__nextIndex=16;
1081 tfile__flexUsed+=24*numwin+4;
1082 if (t)
1083 viewer_doForIcons(t->v,onlySelected,tfile__processWindow);
1084 else
1085 tfile__processWindow(0,w);
1086 if (tfile__abortSave)
1087 {
1088 flex_free(p);
1089 return (FALSE);
1090 }
1091
1092 /* --- Terminate the index and fill in the fonts --- */
1093 intptr(*tfile__flex,tfile__nextIndex)[0]=0;
1094 if (tfile__nextFont!=1)
1095 {
1096 tfile__flexUsed=(tfile__flexUsed+3) & (~3);
1097 if (!tfile__saveAlloc(48*(tfile__nextFont-1)))
1098 {
1099 flex_free(p);
1100 return (FALSE);
1101 }
1102 intptr(*tfile__flex,0)[0]=tfile__flexUsed;
1103 for (i=1;i<tfile__nextFont;i++)
1104 {
1105 r.r[0]=tfile__backbinding[i];
1106 r.r[1]=(int)buff;
1107 wimpt_noerr(os_swix(XFont_ReadDefn,&r));
1108 intptr(*tfile__flex,tfile__flexUsed)[0]=r.r[2];
1109 intptr(*tfile__flex,tfile__flexUsed)[1]=r.r[3];
1110 tfile__writeString(buff,tfile__flexUsed+8);
1111 tfile__flexUsed+=48;
1112 }
1113 }
1114 return (TRUE);
1115 }
1116
1117 /*
1118 * BOOL tfile__saveTemplates(char *filename,void *handle)
1119 *
1120 * Use
1121 * Saves a template file to disk
1122 *
1123 * Parameters
1124 * char *filename == the file to save to
1125 * void *handle == pointer to the template file
1126 *
1127 * Returns
1128 * TRUE if successful
1129 */
1130
1131 static BOOL tfile__saveTemplates(char *filename,void *handle)
1132 {
1133 void *p;
1134 os_filestr f;
1135 glass_tfile *t=handle;
1136 if
1137 (
1138 gPrefs_current()->cSave &&
1139 saveas_file_is_safe() &&
1140 utils_caselessCmp(filename,t->filename)!=0 &&
1141 res_fileExists(filename)
1142 )
1143 {
1144 if (!warning(msgs_lookup("tfSOFP"),msgs_lookup("tfSOF"),filename))
1145 return (FALSE);
1146 }
1147 if (!tfile__setupSave(t,0,&p,FALSE))
1148 return (FALSE);
1149 f.action=10;
1150 f.name=filename;
1151 f.loadaddr=0xfec;
1152 f.start=(int)p;
1153 f.end=f.start+tfile__flexUsed;
1154 if (utils_complain(os_file(&f),msgs_lookup("tfERT")))
1155 {
1156 flex_free(&p);
1157 return (FALSE);
1158 }
1159 else
1160 {
1161 flex_free(&p);
1162 if (saveas_file_is_safe())
1163 tfile_markAsSaved(t,filename);
1164 return (TRUE);
1165 }
1166 }
1167
1168 /*
1169 * BOOL tfile__sendTemplates(void *handle,int *maxbuf)
1170 *
1171 * Use
1172 * Saves a template file to another application via RAM transfer
1173 *
1174 * Parameters
1175 * void *handle == pointer to the template file
1176 * int *maxbuf == pointer to receiving app's buffer size
1177 *
1178 * Returns
1179 * TRUE if successful
1180 */
1181
1182 static BOOL tfile__sendTemplates(void *handle,int *maxbuf)
1183 {
1184 void *p;
1185 glass_tfile *t=handle;
1186 if (!tfile__setupSave(t,0,&p,FALSE))
1187 return (FALSE);
1188 if (xfersend_sendBlock(p,tfile__flexUsed,maxbuf))
1189 {
1190 flex_free(&p);
1191 return (TRUE);
1192 }
1193 else
1194 {
1195 flex_free(&p);
1196 return (FALSE);
1197 }
1198 }
1199
1200 /*
1201 * BOOL tfile__saveSelection(char *filename,void *handle)
1202 *
1203 * Use
1204 * Saves a template selection to disk
1205 *
1206 * Parameters
1207 * char *filename == the file to save to
1208 * void *handle == pointer to the template file
1209 *
1210 * Returns
1211 * TRUE if successful
1212 */
1213
1214 static BOOL tfile__saveSelection(char *filename,void *handle)
1215 {
1216 void *p;
1217 os_filestr f;
1218 glass_tfile *t=handle;
1219 if
1220 (
1221 gPrefs_current()->cSave &&
1222 saveas_file_is_safe() &&
1223 res_fileExists(filename)
1224 )
1225 {
1226 if (!warning(msgs_lookup("tfSOFP"),msgs_lookup("tfSOF"),filename))
1227 return (FALSE);
1228 }
1229 if (!tfile__setupSave(t,0,&p,TRUE))
1230 return (FALSE);
1231 f.action=10;
1232 f.name=filename;
1233 f.loadaddr=0xfec;
1234 f.start=(int)p;
1235 f.end=f.start+tfile__flexUsed;
1236 if (utils_complain(os_file(&f),msgs_lookup("tfERT")))
1237 {
1238 flex_free(&p);
1239 return (FALSE);
1240 }
1241 else
1242 {
1243 flex_free(&p);
1244 return (TRUE);
1245 }
1246 }
1247
1248 /*
1249 * BOOL tfile__sendSelection(void *handle,int *maxbuf)
1250 *
1251 * Use
1252 * Saves a template selection to another application via RAM transfer
1253 *
1254 * Parameters
1255 * void *handle == pointer to the template file
1256 * int *maxbuf == pointer to receiving app's buffer size
1257 *
1258 * Returns
1259 * TRUE if successful
1260 */
1261
1262 static BOOL tfile__sendSelection(void *handle,int *maxbuf)
1263 {
1264 void *p;
1265 glass_tfile *t=handle;
1266 if (!tfile__setupSave(t,0,&p,TRUE))
1267 return (FALSE);
1268 if (xfersend_sendBlock(p,tfile__flexUsed,maxbuf))
1269 {
1270 flex_free(&p);
1271 return (TRUE);
1272 }
1273 else
1274 {
1275 flex_free(&p);
1276 return (FALSE);
1277 }
1278 }
1279
1280 /*
1281 * BOOL tfile__saveWindow(char *filename,void *handle)
1282 *
1283 * Use
1284 * Saves a template selection to disk
1285 *
1286 * Parameters
1287 * char *filename == the file to save to
1288 * void *handle == pointer to the window
1289 *
1290 * Returns
1291 * TRUE if successful
1292 */
1293
1294 static BOOL tfile__saveWindow(char *filename,void *handle)
1295 {
1296 void *p;
1297 os_filestr f;
1298 glass_windPointer *w=handle;
1299 if
1300 (
1301 gPrefs_current()->cSave &&
1302 saveas_file_is_safe() &&
1303 res_fileExists(filename)
1304 )
1305 {
1306 if (!warning(msgs_lookup("tfSOFP"),msgs_lookup("tfSOF"),filename))
1307 return (FALSE);
1308 }
1309 if (!tfile__setupSave(0,w,&p,TRUE))
1310 return (FALSE);
1311 f.action=10;
1312 f.name=filename;
1313 f.loadaddr=0xfec;
1314 f.start=(int)p;
1315 f.end=f.start+tfile__flexUsed;
1316 if (utils_complain(os_file(&f),msgs_lookup("tfERT")))
1317 {
1318 flex_free(&p);
1319 return (FALSE);
1320 }
1321 else
1322 {
1323 flex_free(&p);
1324 return (TRUE);
1325 }
1326 }
1327
1328 /*
1329 * BOOL tfile__sendWindow(void *handle,int *maxbuf)
1330 *
1331 * Use
1332 * Saves a template selection to another application via RAM transfer
1333 *
1334 * Parameters
1335 * void *handle == pointer to the window
1336 * int *maxbuf == pointer to receiving app's buffer size
1337 *
1338 * Returns
1339 * TRUE if successful
1340 */
1341
1342 static BOOL tfile__sendWindow(void *handle,int *maxbuf)
1343 {
1344 void *p;
1345 glass_windPointer *w=handle;
1346 if (!tfile__setupSave(0,w,&p,TRUE))
1347 return (FALSE);
1348 if (xfersend_sendBlock(p,tfile__flexUsed,maxbuf))
1349 {
1350 flex_free(&p);
1351 return (TRUE);
1352 }
1353 else
1354 {
1355 flex_free(&p);
1356 return (FALSE);
1357 }
1358 }
1359
1360 #else
1361
1362 static BOOL tfile__demoSave(void)
1363 {
1364 note(msgs_lookup("tfCSID"));
1365 }
1366
1367 static BOOL tfile__saveTemplates(char *filename,void *handle)
1368 {
1369 unused(filename);
1370 unused(handle);
1371 return (tfile__demoSave());
1372 }
1373
1374 static BOOL tfile__sendTemplates(void *handle,int *maxbuf)
1375 {
1376 unused(handle);
1377 unused(maxbuf);
1378 return (tfile__demoSave());
1379 }
1380
1381 static BOOL tfile__saveSelection(char *filename,void *handle)
1382 {
1383 unused(filename);
1384 unused(handle);
1385 return (tfile__demoSave());
1386 }
1387
1388 static BOOL tfile__sendSelection(void *handle,int *maxbuf)
1389 {
1390 unused(handle);
1391 unused(maxbuf);
1392 return (tfile__demoSave());
1393 }
1394
1395 static BOOL tfile__saveWindow(char *filename,void *handle)
1396 {
1397 unused(filename);
1398 unused(handle);
1399 return (tfile__demoSave());
1400 }
1401
1402 static BOOL tfile__sendWindow(void *handle,int *maxbuf)
1403 {
1404 unused(handle);
1405 unused(maxbuf);
1406 return (tfile__demoSave());
1407 }
1408
1409 #endif
1410
1411 /*----- Autosave handling -------------------------------------------------*
1412 *
1413 * This is here to avoid having to prototype the save code
1414 */
1415
1416 /*
1417 * void tfile__closeQbox(int now,void *handle)
1418 *
1419 * Use
1420 * Closes the autosave message dialogue box.
1421 *
1422 * Parameters
1423 * int now == the time now (ignored)
1424 * void *handle == dialogue box handle
1425 */
1426
1427 static void tfile__closeQbox(int now,void *handle)
1428 {
1429 unused(now);
1430 dbox_delete((dbox)handle);
1431 }
1432
1433 /*
1434 * void tfile__autoHandler(dbox d,dbox_field f,void *handle)
1435 *
1436 * Use
1437 * Handles events for the autosave prompt box
1438 *
1439 * Parameters
1440 * dbox d == the dbox's handle
1441 * dbox_field f == what happened
1442 * void *handle == pointer to the template file
1443 */
1444
1445 static void tfile__autoHandler(dbox d,dbox_field f,void *handle)
1446 {
1447 glass_tfile *t=handle;
1448 wimp_wstate s;
1449 switch (f)
1450 {
1451 case glass_APSAVE:
1452 if (strchr(t->filename,'.'))
1453 {
1454 dbox_clickicon(d,f);
1455 wimpt_noerr(wimp_get_wind_state(dbox_syshandle(d),&s));
1456 dbox_hide(d);
1457 if (!tfile__saveTemplates(t->filename,t))
1458 wimpt_noerr(wimp_open_wind(&s.o));
1459 dbox_unclick();
1460 break;
1461 }
1462 /* If no path, drop through to saveas... */
1463 case glass_APSAVEAS:
1464 dbox_clickicon(d,glass_APSAVEAS);
1465 dbox_unclick();
1466 tfile_saveTemplates(t);
1467 break;
1468 case glass_APCANCEL:
1469 dbox_clickicon(d,f);
1470 dbox_hide(d);
1471 dbox_unclick();
1472 /* Intentional drop through */
1473 case dbox_CLOSE:
1474 dbox_delete(d);
1475 t->autod=0;
1476 break;
1477 }
1478 }
1479
1480 /*
1481 * void tfile__doAutosave(glass_tfile *t)
1482 *
1483 * Use
1484 * Starts an autosave for the given template file. Multiple autosaves
1485 * are permitted simultaneously. Stick that in Impression's pipeline and
1486 * process it...
1487 *
1488 * Parameters
1489 * glass_tfile *t == the template file to autosave
1490 */
1491
1492 static void tfile__doAutosave(int now,void *handle)
1493 {
1494 BOOL useDbox;
1495 dbox qwin;
1496 int at;
1497 glass_tfile *t=handle;
1498 unused(now);
1499 useDbox=gPrefs_current()->aPrompt;
1500 if (t->loaded==FALSE || t->autoSaved==FALSE)
1501 useDbox=TRUE;
1502 if (t->autoAlarm)
1503 alarm_remove(t->autoAlarm,t);
1504 t->autoAlarm=0;
1505 t->autoTime=0;
1506 t->alts=-1;
1507 if (useDbox)
1508 {
1509 if (t->autod)
1510 return;
1511 t->autod=dbox_create("autoPrompt");
1512 if (!t->autod)
1513 {
1514 if (at=gPrefs_autoTiming(),at)
1515 {
1516 t->autoTime=alarm_timenow();
1517 t->autoAlarm=t->autoTime+at;
1518 alarm_set(t->autoAlarm,tfile__doAutosave,t);
1519 }
1520 return;
1521 }
1522 dbox_setfield(t->autod,glass_APNAME,"%.%s",t->filename);
1523 dbox_shadeicon(t->autod,glass_APSAVE,!strchr(t->filename,'.'));
1524 dbox_eventHandler(t->autod,tfile__autoHandler,t);
1525 dbox_openDisplaced(t->autod);
1526 }
1527 else
1528 {
1529 qwin=dbox_create("autoMessage");
1530 if (qwin)
1531 {
1532 dbox_setfield(qwin,glass_AMNAME,"%.%s",t->filename);
1533 dbox_display(qwin,dbox_MENU_CENTRE);
1534 nopoll_showDbox(qwin,nopoll_CENTRE);
1535 alarm_set(alarm_timenow()+100,tfile__closeQbox,qwin);
1536 }
1537 tfile__saveTemplates(t->filename,t);
1538 }
1539 }
1540
1541 /*----- Event handlers ----------------------------------------------------*/
1542
1543 /*
1544 * void tfile__close(glass_tfile *t,BOOL checkMouse)
1545 *
1546 * Use
1547 * Closes a template file, asking user for confirmation etc.
1548 *
1549 * Parameters
1550 * glass_tfile *t == the template file to kill
1551 * BOOL checkMouse == whether to check the mouse buttons to open the parent
1552 */
1553
1554 static void tfile__close(glass_tfile *t,BOOL checkMouse)
1555 {
1556 wimp_mousestr m;
1557 char buff[256];
1558 char *name;
1559 event_clear_current_menu(); /* The menu will be closed - it will try */
1560 /* to deselect an non-existant item... */
1561 if (checkMouse)
1562 {
1563 wimpt_noerr(wimp_get_point_info(&m));
1564 if (m.bbits==wimp_BRIGHT && t->loaded)
1565 {
1566 sprintf(buff,"Filer_OpenDir %s",t->filename);
1567 utils_leafname(buff)[-1]=0;
1568 os_cli(buff);
1569 }
1570 if (m.bbits==wimp_BRIGHT && akbd_pollsh())
1571 return;
1572 }
1573 if (t->alts && gPrefs_current()->cClose)
1574 {
1575 if (t->loaded)
1576 name=t->filename;
1577 else
1578 name=msgs_lookup("tfTMP");
1579 tfile__selectSize=0;
1580 viewer_doForIcons(t->v,FALSE,tfile__size);
1581 viewer_clickSelect(t->v,viewer_NOICON,wimp_BMID);
1582 saveWarn(t->loaded,
1583 tfile__deleteTemplateFile,
1584 msgs_lookup("tfSVTIT"),
1585 name,0xfec,
1586 tfile__selectSize,
1587 tfile__saveTemplates,
1588 tfile__sendTemplates,
1589 0,
1590 t);
1591 }
1592 else
1593 tfile__deleteTemplateFile(t); /* Destroy the underlying data */
1594 }
1595
1596 /*
1597 * void tfile__redrawViewer(viewer_icon i,wimp_redrawstr *r,
1598 * wimp_box *box,char *text,char *sprite,BOOL selected,void *handle)
1599 *
1600 * Use
1601 * Redraws a small icon in the viewer window.
1602 *
1603 * Parameters
1604 * viewer_icon i == the icon I'm redrawing
1605 * wimp_redrawstr *r == the redraw structure
1606 * wimp_box *box == the box to fit it in
1607 * char *text == the text to draw
1608 * char *sprite == the sprite to draw (ignored)
1609 * BOOL selected == whether the icon is selected
1610 * void *handle == pointer to the template file
1611 */
1612
1613 static void tfile__redrawViewer(viewer_icon i,
1614 wimp_redrawstr *r,
1615 wimp_box *box,
1616 char *text,
1617 char *sprite,
1618 BOOL selected,
1619 void *handle)
1620 {
1621 wimp_icon icn={0,0,0,0,0x17000113,""};
1622 unused(i);
1623 unused(r);
1624 unused(sprite);
1625 unused(handle);
1626 icn.box=*box;
1627 icn.flags|=(selected<<21);
1628 icn.data.indirecttext.buffer=text;
1629 icn.data.indirecttext.validstring="Ssmtmpltvicon";
1630 icn.data.indirecttext.bufflen=13;
1631 wimpt_noerr(wimp_ploticon(&icn));
1632 }
1633
1634 /*
1635 * int tfile__sort(void *a,void *b)
1636 *
1637 * Use
1638 * Compares two windows in the current sorting method.
1639 *
1640 * Parameters
1641 * void *a == pointer to the first window
1642 * void *b == pointer to the second window
1643 *
1644 * Returns
1645 * Somehow 'a-b'.
1646 */
1647
1648 static int tfile__sort(void *a,void *b)
1649 {
1650 glass_windPointer *x=a;
1651 glass_windPointer *y=b;
1652 int result=0;
1653 switch (x->t->sort)
1654 {
1655 case gPrefs_NAME:
1656 result=utils_caselessCmp(x->id,y->id);
1657 break;
1658 case gPrefs_SIZE:
1659 result=y->size-x->size;
1660 break;
1661 case gPrefs_ICONS:
1662 result=y->def->desc.w.nicons-x->def->desc.w.nicons;
1663 break;
1664 case gPrefs_NOSORT:
1665 result=x->serial-y->serial;
1666 break;
1667 }
1668 if (!result)
1669 result=utils_caselessCmp(x->id,y->id);
1670 return (result);
1671 }
1672
1673 /*
1674 * void tfile__tfileMenuHelp(int hit[],void *handle)
1675 *
1676 * Use
1677 * Responds to help requests for template file menu.
1678 *
1679 * Parameters
1680 * int hit[] == array of menu selections
1681 * void *handle == pointer to template file control block
1682 */
1683
1684 static void tfile__tfileMenuHelp(int hit[],void *handle)
1685 {
1686 unused(handle);
1687 help_startHelp();
1688 help_readFromMenu("tfmhTF",hit);
1689 help_endHelp();
1690 }
1691
1692 /*
1693 * void tfile__tfileMenuHandler(int hit[],void *handle)
1694 *
1695 * Use
1696 * Responds to menu events for template file menu.
1697 *
1698 * Parameters
1699 * int hit[] == array of menu selections
1700 * void *handle == pointer to template file control block
1701 */
1702
1703 static void tfile__tfileMenuHandler(int hit[],void *handle)
1704 {
1705 glass_tfile *t=handle;
1706 char buff[15];
1707 dbox d;
1708 unused(t);
1709 switch (hit[0])
1710 {
1711 case 0:
1712 viewer_clickSelect(t->v,viewer_NOICON,wimp_BMID);
1713 break;
1714 case glass_TFINFO:
1715 if (d=dbox_create("fileInfo"),d)
1716 {
1717 dbox_setfield(d,glass_FINAME,"%.%s",t->filename);
1718 tfile__selectSize=0;
1719 tfile__selectIndSz=0;
1720 viewer_doForIcons(t->v,FALSE,tfile__size);
1721 dbox_setfield(d,
1722 glass_FISIZE,
1723 "%s",
1724 utils_cvtSize(tfile__selectSize));
1725 dbox_setfield(d,
1726 glass_FIINDSZ,
1727 "%s",
1728 utils_cvtSize(tfile__selectIndSz));
1729 dbox_setfield(d,glass_FIWINDOWS,"%i",viewer_icons(t->v));
1730 dbox_setfield(d,
1731 glass_FIMODIFIED,
1732 "%s",
1733 msgs_lookup(t->alts ? "yes" : "no"));
1734 mbox(d,"tfhFI");
1735 }
1736 break;
1737 case glass_TFDISP:
1738 switch (hit[1])
1739 {
1740 case glass_TFDLARGE:
1741 if (t->isz!=gPrefs_LARGE)
1742 {
1743 t->isz=gPrefs_LARGE;
1744 viewer_setIconSize(t->v,200,112);
1745 viewer_redrawHandler(t->v,0,t);
1746 }
1747 break;
1748 case glass_TFDSMALL:
1749 if (t->isz!=gPrefs_SMALL)
1750 {
1751 t->isz=gPrefs_SMALL;
1752 viewer_setIconSize(t->v,248,36);
1753 viewer_redrawHandler(t->v,tfile__redrawViewer,t);
1754 }
1755 break;
1756 case glass_TFDSORTNAME:
1757 if (t->sort!=gPrefs_NAME)
1758 {
1759 t->sort=gPrefs_NAME;
1760 viewer_setCompare(t->v,tfile__sort);
1761 }
1762 break;
1763 case glass_TFDSORTSIZE:
1764 if (t->sort!=gPrefs_SIZE)
1765 {
1766 t->sort=gPrefs_SIZE;
1767 viewer_setCompare(t->v,tfile__sort);
1768 }
1769 break;
1770 case glass_TFDSORTICONS:
1771 if (t->sort!=gPrefs_ICONS)
1772 {
1773 t->sort=gPrefs_ICONS;
1774 viewer_setCompare(t->v,tfile__sort);
1775 }
1776 break;
1777 case glass_TFDNOSORT:
1778 if (t->sort!=gPrefs_NOSORT)
1779 {
1780 t->sort=gPrefs_NOSORT;
1781 viewer_setCompare(t->v,tfile__sort);
1782 }
1783 break;
1784 }
1785 break;
1786 case glass_TFSEL:
1787 switch (hit[1])
1788 {
1789 case glass_TFSELINFO:
1790 if (viewer_selected(t->v)==1)
1791 tfile_windowInfo((glass_windPointer *)
1792 viewer_iconHandle(viewer_firstSelected(t->v)));
1793 else
1794 {
1795 if (d=dbox_create("selInfo"),d)
1796 {
1797 tfile__selectSize=0;
1798 tfile__selectIndSz=0;
1799 viewer_doForIcons(t->v,TRUE,tfile__size);
1800 dbox_setfield(d,
1801 glass_SISIZE,
1802 "%s",
1803 utils_cvtSize(tfile__selectSize));
1804 dbox_setfield(d,
1805 glass_SIINDSZ,
1806 "%s",
1807 utils_cvtSize(tfile__selectIndSz));
1808 tfile__selectIcons=0;
1809 viewer_doForIcons(t->v,TRUE,tfile__icons);
1810 dbox_setfield(d,glass_SIICONS,"%i",tfile__selectIcons);
1811 dbox_setfield(d,glass_SINUM,"%i",viewer_selected(t->v));
1812 mbox(d,"tfhSI");
1813 }
1814 }
1815 break;
1816 case glass_TFSELEDIT:
1817 editWindow(viewer_iconHandle(viewer_firstSelected(t->v)));
1818 break;
1819 case glass_TFSELCOPY:
1820 writable
1821 (
1822 msgs_lookup("tfCOPY"),
1823 viewer_textOfIcon(viewer_firstSelected(t->v)),
1824 buff,
1825 tfile__copy,
1826 viewer_iconHandle(viewer_firstSelected(t->v))
1827 );
1828 break;
1829 case glass_TFSELRENAME:
1830 writable
1831 (
1832 msgs_lookup("tfREN"),
1833 viewer_textOfIcon(viewer_firstSelected(t->v)),
1834 buff,
1835 tfile_rename,
1836 viewer_iconHandle(viewer_firstSelected(t->v))
1837 );
1838 break;
1839 case glass_TFSELSAVE:
1840 tfile__selectSize=0;
1841 viewer_doForIcons(t->v,TRUE,tfile__size);
1842 saveas(msgs_lookup("tfSVSEL"),
1843 msgs_lookup("tfSEL"),
1844 0xfec,
1845 tfile__selectSize,
1846 tfile__saveSelection,
1847 tfile__sendSelection,
1848 0,
1849 t);
1850 break;
1851 case glass_TFSELDELETE:
1852 if (gPrefs_current()->cDelWind)
1853 {
1854 if (!warning(msgs_lookup("tfDELWP"),msgs_lookup("tfDELW")))
1855 break;
1856 }
1857 viewer_doForIcons(t->v,TRUE,tfile_deleteWindow);
1858 tfile_markAsAltered(t);
1859 break;
1860 }
1861 break;
1862 case glass_TFSELALL:
1863 tfile__gainSelection(t);
1864 viewer_selectAll(t->v,TRUE);
1865 break;
1866 case glass_TFCLRSEL:
1867 viewer_selectAll(t->v,FALSE);
1868 break;
1869 case glass_TFSAVE:
1870 tfile_saveTemplates(t);
1871 break;
1872 case glass_TFCREATE:
1873 writable(msgs_lookup("tfCRT"),"",buff,tfile__create,t);
1874 break;
1875 case glass_TFGRAB:
1876 writable(msgs_lookup("tfGRAB"),"",buff,tfile__grabGetName,t);
1877 break;
1878 case glass_TFSHWSPR:
1879 gSprite_display(t);
1880 break;
1881 default:
1882 break;
1883 }
1884 }
1885
1886 /*
1887 * menu tfile__tfileMenuMaker(void *handle)
1888 *
1889 * Use
1890 * Generates the menu for a template file window.
1891 *
1892 * Parameters
1893 * void *handle == the template file window to deal with
1894 *
1895 * Returns
1896 * A pointer to the menu structure to display.
1897 */
1898
1899 static menu tfile__tfileMenuMaker(void *handle)
1900 {
1901 static menu m; /* The main menu pointer */
1902 static menu disp; /* Submenu for display options */
1903 static menu windsm; /* Submenu for window options */
1904 #ifdef glass_NOTLAZY
1905 static menu stylesm; /* Submenu for styles options */
1906 #endif
1907 static char windName[50]; /* Buffer for window name */
1908 glass_tfile *t=handle;
1909 glass_windPointer *w;
1910
1911 if (!m) /* Do we have to create the menu? */
1912 {
1913 m=menu_new("Glass",msgs_lookup("tfM"));
1914 disp=menu_new(msgs_lookup("tfDSPT"),
1915 msgs_lookup("tfDSPM"));
1916 windsm=menu_new("_",msgs_lookup("tfWS"));
1917 #ifdef glass_NOTLAZY
1918 stylesm=menu_new(msgs_lookup("tfISST:Icon styles"),
1919 msgs_lookup("tfISS:"
1920 "Edit style...,"
1921 "New style...,"
1922 ">Save..."));
1923 #endif
1924 menu_submenu(m,glass_TFSEL,windsm);
1925 #ifdef glass_NOTLAZY
1926 menu_submenu(m,glass_TFSTYLES,stylesm);
1927 #endif
1928 menu_submenu(m,glass_TFDISP,disp);
1929 menu_redirectItem(m,glass_TFSEL,windName,50,0);
1930 }
1931 menu_minWidth(m,0);
1932 viewer_setupMenu(t->v,
1933 msgs_lookup("tfWIN"),
1934 m,
1935 glass_TFSEL,
1936 windName);
1937 switch (viewer_selected(t->v))
1938 {
1939 case 0:
1940 menu_setflags(m,glass_TFCLRSEL,FALSE,TRUE);
1941 menu_setflags(m,glass_TFSELALL,FALSE,!viewer_icons(t->v));
1942 menu_settitle(windsm,msgs_lookup("tfWIN"));
1943 menu_setflags(windsm,glass_TFSELINFO,FALSE,TRUE);
1944 menu_setflags(windsm,glass_TFSELEDIT,FALSE,TRUE);
1945 menu_setflags(windsm,glass_TFSELCOPY,FALSE,TRUE);
1946 menu_setflags(windsm,glass_TFSELRENAME,FALSE,TRUE);
1947 menu_setflags(windsm,glass_TFSELSAVE,FALSE,TRUE);
1948 menu_setflags(windsm,glass_TFSELDELETE,FALSE,TRUE);
1949 break;
1950 case 1:
1951 w=viewer_iconHandle(viewer_firstSelected(t->v));
1952 menu_setflags(m,glass_TFCLRSEL,FALSE,FALSE);
1953 menu_setflags(m,glass_TFSELALL,FALSE,FALSE);
1954 menu_settitle(windsm,msgs_lookup("tfWIN"));
1955 menu_setflags(windsm,glass_TFSELINFO,FALSE,FALSE);
1956 #ifndef glass_DEMO
1957 menu_setflags(windsm,glass_TFSELEDIT,FALSE,w->testMode);
1958 #else
1959 menu_setflags(windsm,glass_TFSELEDIT,FALSE,FALSE);
1960 #endif
1961 menu_setflags(windsm,glass_TFSELCOPY,FALSE,FALSE);
1962 menu_setflags(windsm,glass_TFSELRENAME,FALSE,FALSE);
1963 menu_setflags(windsm,glass_TFSELSAVE,FALSE,FALSE);
1964 menu_setflags(windsm,glass_TFSELDELETE,FALSE,FALSE);
1965 break;
1966 default:
1967 menu_setflags(m,glass_TFCLRSEL,FALSE,FALSE);
1968 menu_setflags(m,glass_TFSELALL,FALSE,FALSE);
1969 menu_settitle(windsm,msgs_lookup("tfSEL"));
1970 menu_setflags(windsm,glass_TFSELINFO,FALSE,FALSE);
1971 menu_setflags(windsm,glass_TFSELEDIT,FALSE,TRUE);
1972 menu_setflags(windsm,glass_TFSELCOPY,FALSE,TRUE);
1973 menu_setflags(windsm,glass_TFSELRENAME,FALSE,TRUE);
1974 menu_setflags(windsm,glass_TFSELSAVE,FALSE,FALSE);
1975 menu_setflags(windsm,glass_TFSELDELETE,FALSE,FALSE);
1976 break;
1977 }
1978 menu_setflags(m,glass_TFSHWSPR,FALSE,!t->vs);
1979 menu_setflags(m,glass_TFGRAB,FALSE,window_grabbing());
1980 menu_setflags(disp,glass_TFDLARGE,t->isz==gPrefs_LARGE,FALSE);
1981 menu_setflags(disp,glass_TFDSMALL,t->isz==gPrefs_SMALL,FALSE);
1982 menu_setflags(disp,glass_TFDSORTNAME,t->sort==gPrefs_NAME,FALSE);
1983 menu_setflags(disp,glass_TFDSORTSIZE,t->sort==gPrefs_SIZE,FALSE);
1984 menu_setflags(disp,glass_TFDSORTICONS,t->sort==gPrefs_ICONS,FALSE);
1985 menu_setflags(disp,glass_TFDNOSORT,t->sort==gPrefs_NOSORT,FALSE);
1986 return (m);
1987 }
1988
1989 /*
1990 * void tfile__simMenu(glass_tfile *t,int hit1,int hit2)
1991 *
1992 * Use
1993 * Simulates a menu hit on a template file window
1994 *
1995 * Parameters
1996 * glass_tfile *t == the template file the event is destined for
1997 * int hit1 == the main menu entry number
1998 * int hit2 == the submenu entry number
1999 */
2000
2001 static void tfile__simMenu(glass_tfile *t,int hit1,int hit2)
2002 {
2003 wimp_menustr *m=menu_syshandle(tfile__tfileMenuMaker(t));
2004 wimp_menuitem *i=(wimp_menuitem *)(m+1)+(hit1-1);
2005 int mnu[3];
2006 mnu[0]=hit1;
2007 mnu[1]=hit2;
2008 mnu[2]=0;
2009
2010 if ((int)i->submenu==-1 || hit2==0)
2011 {
2012 if (i->iconflags & wimp_INOSELECT)
2013 {
2014 bbc_vdu(7);
2015 return;
2016 }
2017 else
2018 mnu[1]=0;
2019 }
2020 else
2021 {
2022 i=(wimp_menuitem *)(i->submenu+1)+(hit2-1);
2023 if (i->iconflags & wimp_INOSELECT)
2024 {
2025 bbc_vdu(7);
2026 return;
2027 }
2028 }
2029 tfile__tfileMenuHandler(mnu,t);
2030 }
2031
2032 /*
2033 * BOOL tfile__dragUnknowns(wimp_eventstr *e,void *handle)
2034 *
2035 * Use
2036 * Handles unknown events during the period of dragging viewer icons
2037 * around. It will respond to the following drags:
2038 *
2039 * A drag to a blank area of icon bar will open the windows.
2040 *
2041 * Otherwise, a selection save will be started, and the windows packaged
2042 * off to another application.
2043 *
2044 * Parameters
2045 * wimp_eventstr *e == the event to look at
2046 * void *handle == the template file we're dragging from
2047 *
2048 * Returns
2049 * TRUE if the drag has been processed
2050 */
2051
2052 static BOOL tfile__dragUnknowns(wimp_eventstr *e,void *handle)
2053 {
2054 glass_tfile *t=handle;
2055 wimp_mousestr m;
2056 BOOL handled=FALSE;
2057 switch (e->e)
2058 {
2059 case wimp_EUSERDRAG:
2060 handled=TRUE;
2061 win_remove_unknown_event_processor(tfile__dragUnknowns,t);
2062 wimpt_noerr(wimp_get_point_info(&m));
2063 if (m.w==viewer_syshandle(t->v))
2064 break;
2065 if (m.w==-2 && m.i==-1)
2066 viewer_doForIcons(t->v,TRUE,tfile__openWindows);
2067 else
2068 {
2069 tfile__selectSize=0;
2070 viewer_doForIcons(t->v,TRUE,tfile__size);
2071 wimpt_fake_event(e); /* Fool xfersend to send data */
2072 xfersend(0xFEC,
2073 msgs_lookup("tfSEL"),
2074 tfile__selectSize,
2075 tfile__saveSelection,
2076 tfile__sendSelection,
2077 0,
2078 e,
2079 t);
2080 }
2081 viewer_selectAll(t->v,FALSE);
2082 break;
2083 }
2084 return (handled);
2085 }
2086
2087 /*
2088 * BOOL tfile__raw(viewer v,wimp_eventstr *e,void *handle)
2089 *
2090 * Use
2091 * Handles intMsgs from other parts of the system
2092 *
2093 * Parameters
2094 * viewer v == the handle for the viewer window
2095 * wimp_eventstr *e == the event to process
2096 * void *handle == the template file
2097 *
2098 * Returns
2099 * TRUE if event was processed
2100 */
2101
2102 static BOOL tfile__raw(viewer v,wimp_eventstr *e,void *handle)
2103 {
2104 BOOL handled=FALSE;
2105 char *filename;
2106 int estsize;
2107 int filetype;
2108 void *p;
2109 glass_tfile *t=handle;
2110 int at;
2111 switch (e->e)
2112 {
2113 case wimp_EKEY:
2114 switch (e->data.key.chcode)
2115 {
2116 case akbd_Fn+1+akbd_Sh: /* sF1 */
2117 tfile__simMenu(t,glass_TFINFO,0);
2118 handled=TRUE;
2119 break;
2120 case 1: /* ^A */
2121 tfile__simMenu(t,glass_TFSELALL,0);
2122 handled=TRUE;
2123 break;
2124 case 26: /* ^Z */
2125 tfile__simMenu(t,glass_TFCLRSEL,0);
2126 handled=TRUE;
2127 break;
2128 case akbd_Fn+3: /* F3 */
2129 tfile__simMenu(t,glass_TFSAVE,0);
2130 handled=TRUE;
2131 break;
2132 case 14: /* ^N */
2133 tfile__simMenu(t,glass_TFCREATE,0);
2134 handled=TRUE;
2135 break;
2136 case 7: /* ^G */
2137 tfile__simMenu(t,glass_TFGRAB,0);
2138 handled=TRUE;
2139 break;
2140 case 19: /* ^S */
2141 tfile__simMenu(t,glass_TFSHWSPR,0);
2142 handled=TRUE;
2143 break;
2144
2145 case akbd_Fn+5: /* F5 */
2146 tfile__simMenu(t,glass_TFDISP,glass_TFDLARGE);
2147 handled=TRUE;
2148 break;
2149 case akbd_Fn+5+akbd_Sh: /* sF5 */
2150 tfile__simMenu(t,glass_TFDISP,glass_TFDSMALL);
2151 handled=TRUE;
2152 break;
2153 case akbd_Fn+6: /* F6 */
2154 tfile__simMenu(t,glass_TFDISP,glass_TFDSORTNAME);
2155 handled=TRUE;
2156 break;
2157 case akbd_Fn+6+akbd_Sh: /* sF6 */
2158 tfile__simMenu(t,glass_TFDISP,glass_TFDSORTSIZE);
2159 handled=TRUE;
2160 break;
2161 case akbd_Fn+6+akbd_Ctl:/* ^F6 */
2162 tfile__simMenu(t,glass_TFDISP,glass_TFDSORTICONS);
2163 handled=TRUE;
2164 break;
2165 case akbd_Fn+6+akbd_Ctl+akbd_Sh:/* s^F6 */
2166 tfile__simMenu(t,glass_TFDISP,glass_TFDNOSORT);
2167 handled=TRUE;
2168 break;
2169
2170 case akbd_Fn+1+akbd_Ctl:/* ^F1 */
2171 tfile__simMenu(t,glass_TFSEL,glass_TFSELINFO);
2172 handled=TRUE;
2173 break;
2174 case 5: /* ^E */
2175 tfile__simMenu(t,glass_TFSEL,glass_TFSELEDIT);
2176 handled=TRUE;
2177 break;
2178 case 3: /* ^C */
2179 tfile__simMenu(t,glass_TFSEL,glass_TFSELCOPY);
2180 handled=TRUE;
2181 break;
2182 case 18: /* ^R */
2183 tfile__simMenu(t,glass_TFSEL,glass_TFSELRENAME);
2184 handled=TRUE;
2185 break;
2186 case akbd_Fn+3+akbd_Sh: /* sF3 */
2187 tfile__simMenu(t,glass_TFSEL,glass_TFSELSAVE);
2188 handled=TRUE;
2189 break;
2190 case 24: /* ^X */
2191 tfile__simMenu(t,glass_TFSEL,glass_TFSELDELETE);
2192 handled=TRUE;
2193 break;
2194
2195 case akbd_Fn+2+akbd_Ctl:/* ^F2 */
2196 tfile__close(t,FALSE);
2197 handled=TRUE;
2198 break;
2199 }
2200 break;
2201 case wimp_ESEND:
2202 case wimp_ESENDWANTACK:
2203 switch (e->data.msg.hdr.action)
2204 {
2205 case wimp_MDATASAVE:
2206 filetype=xferrecv_checkimport(&estsize);
2207 switch (filetype)
2208 {
2209 case 0xfec: /* Template files */
2210 if (xferrecv_returnImportedBlock(&p)!=-1)
2211 {
2212 tfile_markAsAltered(t);
2213 tfile_mergeFromMemory(&p,t);
2214 flex_free(&p);
2215 }
2216 break;
2217 case 0xff9: /* Sprite files (I think) */
2218 if (t->vs)
2219 {
2220 if (xferrecv_returnImportedBlock(&p)!=-1)
2221 {
2222 gSprite_mergeFromMemory(t,&p);
2223 flex_free(&p);
2224 }
2225 }
2226 break;
2227 }
2228 break;
2229 case wimp_MDATALOAD:
2230 filetype=xferrecv_checkinsert(&filename);
2231 switch (filetype)
2232 {
2233 case 0xfec: /* Template files */
2234 tfile_mergeFromFile(filename,t);
2235 tfile_markAsAltered(t);
2236 xferrecv_insertfileok();
2237 break;
2238 case 0xff9: /* Sprite files (I think) */
2239 if (t->vs)
2240 {
2241 gSprite_mergeFromFile(t,filename);
2242 xferrecv_insertfileok();
2243 }
2244 break;
2245 }
2246 break;
2247 case wimp_MINTERNAL:
2248 switch (e->data.msg.data.words[0])
2249 {
2250 case glass_KILLFILES:
2251 tfile__deleteTemplateFile(t);
2252 break;
2253 case glass_CLOSEDOWN:
2254 viewer_doForIcons(v,FALSE,tfile__tidyFonts);
2255 handled=TRUE;
2256 break;
2257 case glass_MODECHANGE:
2258 viewer_doForIcons(v,FALSE,tfile__reFindFonts);
2259 handled=TRUE;
2260 break;
2261 case glass_AUTOSAVE:
2262 if (t->autoAlarm)
2263 alarm_remove(t->autoAlarm,t);
2264 t->autoAlarm=0;
2265 if (t->autoTime)
2266 {
2267 if (at=gPrefs_autoTiming(),at)
2268 {
2269 t->autoAlarm=t->autoTime+at;
2270 alarm_set(t->autoAlarm,tfile__doAutosave,t);
2271 }
2272 }
2273 if (gPrefs_current()->aAlts!=0 &&
2274 t->alts>=gPrefs_current()->aAlts)
2275 tfile__doAutosave(0,t);
2276 break;
2277 }
2278 break;
2279 }
2280 break;
2281 }
2282 return (handled);
2283 }
2284
2285 /*
2286 * void tfile__tfileHandler(viewer v,
2287 * viewer_icon i,
2288 * wimp_bbits b,
2289 * void *vhandle,
2290 * void *ihandle)
2291 *
2292 * Use
2293 * Handles events for a template file window (including things like menu
2294 * clicks).
2295 *
2296 * Parameters
2297 * viewer v == the viewer that the event happened to
2298 * viewer_icon i == the icon it happened to
2299 * wimp_bbits b == the mouse button status
2300 * void *vhandle == pointer to the template file structure
2301 * void *ihandle == pointer to the window pointer structure
2302 */
2303
2304 static void tfile__tfileHandler(viewer v,
2305 viewer_icon i,
2306 wimp_bbits b,
2307 void *vhandle,
2308 void *ihandle)
2309 {
2310 glass_tfile *t=vhandle;
2311 glass_windPointer *wp=ihandle;
2312 switch ((int)i)
2313 {
2314 case (int)viewer_CLOSE: /* If the user closes the window */
2315 tfile__close(t,TRUE); /* Try to close it :-) */
2316 break;
2317 case (int)viewer_HELP: /* Help request for the window */
2318 help_startHelp(); /* Prepare a reply */
2319 help_addLine(msgs_lookup("tfhTF"));
2320 help_endHelp(); /* Send the message to Help application */
2321 break;
2322 default:
2323 if (b!=wimp_BMID)
2324 {
2325 tfile__gainSelection(t);
2326 viewer_clickSelect(v,i,b);
2327 }
2328 switch (b)
2329 {
2330 case wimp_BMID:
2331 if (t==tfile__selOwner ||
2332 !tfile__selOwner ||
2333 !viewer_selected(tfile__selOwner->v) )
2334 {
2335 tfile__selOwner=t;
2336 viewer_clickSelect(v,i,b);
2337 }
2338 menu_make(tfile__tfileMenuMaker,
2339 tfile__tfileMenuHandler,
2340 tfile__tfileMenuHelp,
2341 t);
2342 break;
2343 case wimp_BLEFT:
2344 if (i!=viewer_NOICON)
2345 {
2346 if (akbd_pollsh() && wp->h)
2347 window_close(wp);
2348 else
2349 window_open(wp,FALSE); /* Open the window on-screen */
2350 viewer_selectIcon(i,FALSE); /* And deslect the icon */
2351 }
2352 break;
2353 case wimp_BRIGHT:
2354 if (i!=viewer_NOICON)
2355 {
2356 if (akbd_pollsh() && wp->h)
2357 window_close(wp);
2358 else
2359 window_open(wp,TRUE); /* Open the window on-screen */
2360 viewer_selectIcon(i,FALSE); /* And deslect the icon */
2361 }
2362 break;
2363 case wimp_BDRAGLEFT:
2364 case wimp_BDRAGRIGHT:
2365 if (i!=viewer_NOICON)
2366 {
2367 tfile_dragSelected(i,b,"tpackage");
2368 win_add_unknown_event_processor(tfile__dragUnknowns,t);
2369 }
2370 break;
2371 }
2372 break;
2373 }
2374 }
2375
2376 /*----- External routines -------------------------------------------------*/
2377
2378 /*
2379 * BOOL tfile_okToQuit(BOOL ask)
2380 *
2381 * Use
2382 * Ensures that it is 'safe' for Glass to quit.
2383 *
2384 * Parameters
2385 * BOOL ask == should I open a dialogue to ask the user?
2386 *
2387 * Returns
2388 * TRUE if it is safe to quit, or FALSE if not.
2389 */
2390
2391 BOOL tfile_okToQuit(BOOL ask)
2392 {
2393 char *q;
2394 if (tfile__unsavedFiles==0 || !gPrefs_current()->cQuit)
2395 return (TRUE);
2396 else if (ask==FALSE)
2397 return (FALSE);
2398 else if (tfile__unsavedFiles==1)
2399 q=msgs_lookup("tfOTQ1");
2400 else
2401 q=msgs_lookup("tfOTQM");
2402 return (warning(msgs_lookup("tfOTQP"),q,tfile__unsavedFiles));
2403 }
2404
2405 /*
2406 * void tfile_markAsAltered(glass_tfile *t)
2407 *
2408 * Use
2409 * Marks down another alteration for the template file, changing the window
2410 * title if required etc. Also handles stuff for autosave etc.
2411 *
2412 * Parameters
2413 * glass_tfile *t == the template file to alter
2414 */
2415
2416 void tfile_markAsAltered(glass_tfile *t)
2417 {
2418 char buff[256];
2419 int at;
2420 t->alts++;
2421 if (t->alts==1 || t->alts==0)
2422 {
2423 sprintf(buff,"%s *",t->filename);
2424 viewer_settitle(t->v,buff);
2425 if (t->alts==1)
2426 tfile__unsavedFiles++;
2427 t->alts=1;
2428 }
2429 if (t->sort==gPrefs_SIZE || t->sort==gPrefs_ICONS)
2430 viewer_setCompare(t->v,tfile__sort);
2431 if (!t->autoTime)
2432 {
2433 t->autoTime=alarm_timenow();
2434 if (at=gPrefs_autoTiming(),at)
2435 {
2436 t->autoAlarm=t->autoTime+at;
2437 alarm_set(t->autoAlarm,tfile__doAutosave,t);
2438 }
2439 else
2440 t->autoAlarm=0;
2441 }
2442 if (gPrefs_current()->aAlts!=0 && t->alts>=gPrefs_current()->aAlts)
2443 tfile__doAutosave(0,t);
2444 }
2445
2446 /*
2447 * void tfile_markAsSaved(glass_tfile *t,char *newTitle)
2448 *
2449 * Use
2450 * Marks a template file as having been saved. Turns off autosave and
2451 * things.
2452 *
2453 * Parameters
2454 * glass_tfile *t == the file to mark
2455 * char *newtitle == the new title to give to the window
2456 */
2457
2458 void tfile_markAsSaved(glass_tfile *t,char *newTitle)
2459 {
2460 char buff[256];
2461 if (t->alts)
2462 {
2463 t->alts=0;
2464 tfile__unsavedFiles--;
2465 }
2466 t->loaded=TRUE;
2467 strcpy(t->filename,newTitle);
2468 viewer_settitle(t->v,newTitle);
2469 intMsgs_send(glass_SAVEFILE,t);
2470 if (t->vs)
2471 {
2472 sprintf(buff,msgs_lookup("spVT"),newTitle);
2473 viewer_settitle(t->vs,buff);
2474 }
2475 if (t->autoAlarm)
2476 alarm_remove(t->autoAlarm,t);
2477 t->autoAlarm=0;
2478 t->autoTime=0;
2479 if (t->autod)
2480 {
2481 dbox_deleteNoUpdate(t->autod);
2482 t->autoSaved=TRUE;
2483 t->autod=0;
2484 }
2485 }
2486
2487 /*
2488 * void tfile_windowInfo(glass_windPointer *w)
2489 *
2490 * Use
2491 * Displays an info box for a single window
2492 *
2493 * Parameters
2494 * glass_windPointer *w == the window to display info on
2495 */
2496
2497 void tfile_windowInfo(glass_windPointer *w)
2498 {
2499 dbox d=dbox_create("windInfo");
2500 if (!d)
2501 return;
2502 dbox_setfield(d,glass_WINAME,"%s",w->id);
2503 dbox_setfield(d,glass_WISIZE,"%s",utils_cvtSize(w->size));
2504 dbox_setfield(d,
2505 glass_WIINDSZ,
2506 "%s",
2507 utils_cvtSize(w->size-
2508 sizeof(glass_window)-
2509 (w->def->desc.w.nicons-1)*
2510 sizeof(glass_iconDescription)));
2511 dbox_setfield(d,glass_WIICONS,"%i",w->def->desc.w.nicons);
2512 mbox(d,"tfhWI");
2513 }
2514
2515 /*
2516 * void tfile_deleteWindow(glass_windPointer *w)
2517 *
2518 * Use
2519 * Deletes a single window.
2520 *
2521 * Parameters
2522 * viewer_icon i == the icon to get
2523 * void *handle == the window to eliminate (as a glass_windPointer *)
2524 */
2525
2526 void tfile_deleteWindow(viewer_icon i,void *handle)
2527 {
2528 glass_windPointer *w=handle;
2529 unused(i);
2530 intMsgs_send(glass_DELETEWINDOW,w);
2531 viewer_removeIcon(w->i);
2532 tfile__doDeleteWindow(w);
2533 }
2534
2535 /*
2536 * BOOL tfile_rename(char *newName,void *handle)
2537 *
2538 * Use
2539 * Renames the specified window
2540 *
2541 * Parameters
2542 * char *newName == the new name of the window
2543 * void *handle == pointer to the window structure
2544 */
2545
2546 BOOL tfile_rename(char *newName,void *handle)
2547 {
2548 glass_windPointer *w=handle;
2549 viewer_icon i;
2550 if (strcmp(newName,w->id)==0)
2551 return (TRUE);
2552 i=viewer_findIcon(w->t->v,newName);
2553 if (i==viewer_NOICON || i==w->i)
2554 {
2555 viewer_removeIcon(w->i);
2556 mem_useUser(indir_alloc,indir_free);
2557 strcpy(w->id,newName);
2558 i=viewer_addIcon(w->t->v,newName,"tmpltvicon",TRUE,w);
2559 viewer_setFiletype(i,0xfec);
2560 mem_useMalloc();
2561 w->i=i;
2562 intMsgs_send(glass_RENAME,w);
2563 tfile_markAsAltered(w->t);
2564 event_clear_current_menu();
2565 return (TRUE);
2566 }
2567 note(msgs_lookup("tfNAE"),
2568 viewer_textOfIcon(i));
2569 return (FALSE);
2570 }
2571
2572 /*
2573 * void tfile_saveTemplates(glass_tfile *t)
2574 *
2575 * Use
2576 * Saves a template file using a standard dialogue box
2577 *
2578 * Parameters
2579 * glass_tfile *t == the template file to save
2580 */
2581
2582 void tfile_saveTemplates(glass_tfile *t)
2583 {
2584 char *name;
2585 if (t->loaded)
2586 name=t->filename;
2587 else
2588 name=msgs_lookup("tfTMP");
2589 tfile__selectSize=0;
2590 viewer_doForIcons(t->v,FALSE,tfile__size);
2591 saveas(msgs_lookup("tfSVTIT"),
2592 name,
2593 0xfec,
2594 tfile__selectSize,
2595 tfile__saveTemplates,
2596 tfile__sendTemplates,
2597 0,
2598 t);
2599 }
2600
2601 /*
2602 * void tfile_saveWindow(glass_windPointer *w)
2603 *
2604 * Use
2605 * Saves a single window using a standard dialogue box
2606 *
2607 * Parameters
2608 * glass_windPointer *w == pointer to the window to save
2609 */
2610
2611 void tfile_saveWindow(glass_windPointer *w)
2612 {
2613 tfile__selectSize=w->size;
2614 saveas(msgs_lookup("tfSVWTIT"),
2615 msgs_lookup("tfWIN"),
2616 0xfec,
2617 w->size,
2618 tfile__saveWindow,
2619 tfile__sendWindow,
2620 0,
2621 w);
2622 }
2623
2624 /*
2625 * BOOL tfile_mergeFromMemory(void **p,glass_tfile *t)
2626 *
2627 * Use
2628 * Actually does a merge operation. The target file is a glass_tfile in
2629 * memory (internal format) and the source file is a memory image of a
2630 * normal template file.
2631 *
2632 * Parameters
2633 * void **p == a flex anchor pointer to the source file
2634 * glass_tfile *t == a pointer to the destination file
2635 *
2636 * Returns
2637 * TRUE for success
2638 */
2639
2640 typedef struct { char **p; int offset; } tfile__datPackage;
2641
2642 static char *tfile__dataProc(char *data,void *handle)
2643 {
2644 tfile__datPackage *p=handle;
2645 return (((int)data)+*(p->p)+p->offset);
2646 }
2647
2648 BOOL tfile_mergeFromMemory(void **p,glass_tfile *t)
2649 {
2650 int fontData; /* Offset of font ata from start of file */
2651 glass_windPointer *w; /* For each window we come across */
2652 int index; /* Current index entry we're looking at */
2653 int objoff; /* Offset of window we're looking at */
2654 int iconoff; /* Offset of icon we're looking at */
2655 wimp_iconflags icf; /* Icon flags for something or other */
2656 int fheight; /* Height of a font required */
2657 int fwidth; /* Width of a font required */
2658 int fhandle; /* Font handle */
2659 int fptr; /* Offset of font name */
2660 char name[13]; /* For the name of the template */
2661
2662 int objtype; /* Type of current template entry */
2663 BOOL foundOdd=FALSE; /* Found an odd type of data yet? */
2664 int numicons; /* Number of icons in a window */
2665 int i; /* A loop counter */
2666 viewer_icon icn; /* Icon for checking for duplicates */
2667 BOOL fquiet=FALSE; /* Shut up about font failures. */
2668 tfile__datPackage pk;
2669
2670 fontData=*intptr(*p,0); /* Offset of font data from *p */
2671 for (index=16;*intptr(*p,index);index+=24) /* Go through index entries */
2672 {
2673 objoff=*intptr(*p,index); /* Offset of this entry */
2674 objtype=*intptr(*p,index+8); /* Type of this entry */
2675 switch (objtype) /* Which type is it? */
2676 {
2677 case 1: /* Window */
2678 pk.p=(char **)p;
2679 pk.offset=objoff;
2680
2681 memcpy(name,charptr(*p,index+12),12);
2682 name[12]=0;
2683 utils_ctermToNterm(name);
2684 if (icn=viewer_findIcon(t->v,name),icn)
2685 tfile_deleteWindow(icn,viewer_iconHandle(icn));
2686 if (w=tfile__newWindow(t,name),!w)
2687 return (FALSE); /* Failed to create the window */
2688 memcpy(&numicons,intptr(*p,objoff+84),sizeof(int));
2689 w->size=sizeof(glass_window)+
2690 (numicons-1)*sizeof(glass_iconDescription);
2691 if (!flex_alloc((flex_ptr)&w->def,w->size))
2692 {
2693 viewer_removeIcon(w->i);
2694 mem_free(w);
2695 werr(FALSE,msgs_lookup("tfNEMTL"));
2696 return (FALSE);
2697 }
2698 memcpy(&w->def->desc.w,_ptr(void,*p,objoff),sizeof(wimp_wind));
2699 icf=w->def->desc.w.titleflags; /* Get title icon flags */
2700 if (icf & wimp_IFONT) /* Handle anti-aliased fonts */
2701 {
2702 fhandle=(icf & 0xff000000) >> 24; /* Get internal font handle */
2703 fptr=fontData+(fhandle-1)*48; /* Get pointer */
2704 /* Bug fix - not word aligned!! */
2705 memcpy(&fwidth,intptr(*p,fptr)+0,sizeof(int));
2706 memcpy(&fheight,intptr(*p,fptr)+1,sizeof(int));
2707 utils_ctermToNterm(charptr(*p,fptr+8)); /* Font name */
2708 if (font_find(charptr(*p,fptr+8),fwidth,fheight,0,0,&fhandle))
2709 {
2710 if (!fquiet)
2711 {
2712 werr(FALSE,msgs_lookup("tfCFF"));
2713 fquiet=TRUE;
2714 }
2715 icf&=~wimp_IFONT; /* Stop anti-aliasing (gives odd colours) */
2716 }
2717 else
2718 {
2719 icf=(icf & 0x00ffffff) | (fhandle << 24);
2720 w->antiAliased=TRUE;
2721 w->fonts[fhandle]++;
2722 }
2723 w->def->desc.w.titleflags=icf;
2724 }
2725 w->def->desc.w.nicons=0; /* Don't want deletion routine dying */
2726 if (!iconData_processIcon(w,-1,tfile__dataProc,TRUE,&pk))
2727 {
2728 werr(FALSE,msgs_lookup("tfNEMTL"));
2729 tfile_deleteWindow(0,w);
2730 return (FALSE);
2731 }
2732 iconoff=objoff+88; /* Point to first icon definition */
2733 for (i=0;i<numicons;i++)
2734 {
2735 memcpy(&w->def->i[i].i,charptr(*p,iconoff),sizeof(wimp_icon));
2736 w->def->i[i].selected=FALSE;
2737 w->def->i[i].edit=0;
2738 icf=w->def->i[i].i.flags; /* Get title icon flags */
2739 if (icf & wimp_IFONT) /* Handle anti-aliased fonts */
2740 {
2741 fhandle=(icf & 0xff000000) >> 24; /* Get internal font handle */
2742 fptr=fontData+(fhandle-1)*48; /* Get pointer */
2743 /* Bug fix - not word aligned!! */
2744 memcpy(&fwidth,intptr(*p,fptr)+0,sizeof(int));
2745 memcpy(&fheight,intptr(*p,fptr)+1,sizeof(int));
2746 utils_ctermToNterm(charptr(*p,fptr+8)); /* Font name */
2747 if (font_find(charptr(*p,fptr+8),fwidth,fheight,0,0,&fhandle))
2748 {
2749 if (!fquiet)
2750 {
2751 werr(FALSE,msgs_lookup("tfCFF"));
2752 fquiet=TRUE;
2753 }
2754 icf&=~wimp_IFONT; /* Stop anti-aliasing */
2755 }
2756 else
2757 {
2758 icf=(icf & 0x00ffffff) | (fhandle << 24);
2759 w->antiAliased=TRUE;
2760 w->fonts[fhandle]++;
2761 }
2762 w->def->i[i].i.flags=icf;
2763 }
2764 if (!iconData_processIcon(w,i,tfile__dataProc,TRUE,&pk))
2765 {
2766 werr(FALSE,msgs_lookup("tfNEMTL"));
2767 tfile_deleteWindow(0,w);
2768 return (FALSE);
2769 }
2770 w->def->desc.w.nicons++; /* Tidy up next icon along */
2771 iconoff+=sizeof(wimp_icon); /* Move pointer along */
2772 }
2773 break;
2774 default: /* Anything we don't know - tell the user */
2775 if (!foundOdd) /* Don't generate the message again */
2776 {
2777 werr(FALSE,msgs_lookup("tfUTEC"));
2778 foundOdd=TRUE; /* Stop message repeating */
2779 }
2780 break;
2781 }
2782 }
2783 return (TRUE);
2784 }
2785
2786 /*
2787 * BOOL tfile_mergeFromFile(char *file,glass_tfile *t)
2788 *
2789 * Use
2790 * Merges the template file given into the given template file structure.
2791 *
2792 * Parameters
2793 * char *file == the file to load
2794 * glass_tfile *t == the template file structure to merge with
2795 */
2796
2797 BOOL tfile_mergeFromFile(char *file,glass_tfile *t)
2798 {
2799 os_filestr f; /* Going to make some OS_File calls */
2800 void *p; /* p will point to the file in memory */
2801 f.action=17; /* Read catalogue information for file */
2802 f.name=file; /* Point to file name to find out about */
2803 if (utils_complain(os_file(&f),
2804 msgs_lookup("tfELF")))
2805 {
2806 return (FALSE);
2807 }
2808 if (!flex_alloc(&p,f.start))
2809 {
2810 werr(FALSE,msgs_lookup("tfNEMTL"));
2811 return (FALSE);
2812 }
2813 f.action=16; /* Load the file */
2814 f.loadaddr=(int)p; /* Where to load the file */
2815 f.execaddr=0; /* Load it there!!! */
2816 if (utils_complain(os_file(&f),
2817 msgs_lookup("tfELF")))
2818 {
2819 flex_free(&p);
2820 flex_compact();
2821 return (FALSE);
2822 }
2823 tfile_mergeFromMemory(&p,t); /* Now do the merge */
2824 flex_free(&p);
2825 flex_compact();
2826 return (TRUE);
2827 }
2828
2829 /*
2830 * glass_tfile *tfile_createTemplateFile(char *name)
2831 *
2832 * Use
2833 * Creates a template file with the given name, but doesn't open its viewer.
2834 *
2835 * Returns
2836 * A pointer to the file structure, or zero as failure.
2837 */
2838
2839 glass_tfile *tfile_createTemplateFile(char *name)
2840 {
2841 glass_tfile *t;
2842 int ix,iy;
2843 mem_useUser(indir_alloc,indir_free);
2844 t=mem_alloc(sizeof(glass_tfile));
2845 if (!t) /* Allocates memory for file structure */
2846 {
2847 werr(FALSE,msgs_lookup("tfNEMTF"));
2848 mem_useMalloc();
2849 return (0);
2850 }
2851 ix=(gPrefs_current()->fIcons==gPrefs_LARGE) ? 200 : 248;
2852 iy=(gPrefs_current()->fIcons==gPrefs_LARGE) ? 112 : 36;
2853 if
2854 (
2855 t->v=viewer_create /* Now create the viewer window */
2856 (
2857 tfile__FILEX, /* Coords to open window */
2858 tfile__fileHeight,
2859 ix, /* Width of 'icons' */
2860 iy, /* Height of 'icons' */
2861 resspr_area(), /* Sprite area for 'icons' */
2862 name, /* What to display in the title bar */
2863 msgs_lookup("tfBANR") /* Viewer banner line */
2864 ),
2865 !t->v /* TRUE if creation failed */
2866 )
2867 {
2868 mem_free(t); /* Dispose of unwanted file structure */
2869 mem_useMalloc();
2870 return (0); /* Inform caller we buggered it up */
2871 }
2872 mem_useMalloc();
2873 strcpy(t->filename,name); /* Remember the name */
2874 t->alts=0; /* No alterations yet */
2875 t->loaded=FALSE; /* They can change this if they need to */
2876 t->autoSaved=FALSE; /* Not been autosaved yet */
2877 t->autod=0; /* No autosave dialogue box */
2878 t->autoTime=0; /* No autosave time */
2879 t->autoAlarm=0; /* No autosave alarm */
2880 t->isz=gPrefs_current()->fIcons;
2881 t->sort=gPrefs_current()->fSort;
2882 viewer_eventHandler(t->v,tfile__tfileHandler,t); /* Add event handler */
2883 viewer_rawEventHandler(t->v,tfile__raw,t); /* Raw, for broadcasts */
2884 viewer_redrawHandler(t->v,
2885 t->isz==gPrefs_LARGE ? 0 : tfile__redrawViewer,
2886 t);
2887 viewer_setCompare(t->v,tfile__sort);
2888 tfile__fileHeight-=48; /* Displace the next file window */
2889 if (tfile__fileHeight<652) /* Start at the top again if too low */
2890 tfile__fileHeight=tfile__FILETOP;
2891 gSprite_new(t);
2892 return (t);
2893 }
2894
2895 /*
2896 * glass_tfile *tfile_loadFromMemory(void **p,char *name)
2897 *
2898 * Use
2899 * Loads a file from memory, i.e. from another application via RAM
2900 * transfer.
2901 *
2902 * Parameters
2903 * void **p == the memory block that contains the file to load.
2904 * char *name == the name to give to the file.
2905 *
2906 * Returns
2907 * A pointer to the template file, or 0
2908 */
2909
2910 glass_tfile *tfile_loadFromMemory(void **p,char *name)
2911 {
2912 glass_tfile *t=tfile_createTemplateFile(name);
2913 if (!t)
2914 return (0);
2915 t->loaded=TRUE;
2916 if (!tfile_mergeFromMemory(p,t))
2917 {
2918 tfile__deleteTemplateFile(t);
2919 return (0);
2920 }
2921 if (t->sort==gPrefs_SIZE || t->sort==gPrefs_ICONS)
2922 viewer_setCompare(t->v,tfile__sort);
2923 viewer_display(t->v); /* Show the viewer window in its glory */
2924 return (t);
2925 }
2926
2927 /*
2928 * glass_tfile *tfile_loadFromFile(char *file,char *name)
2929 *
2930 * Use
2931 * Loads a template file into memory, translating the file into Glass's
2932 * internal format. It does not create any windows, although it does
2933 * allocate font handles.
2934 *
2935 * Parameters
2936 * char *file == the name of the file to load
2937 * char *name == the name to insert in the title bar
2938 *
2939 * Returns
2940 * A pointer to the structure definition, or 0 for failure. Note that this
2941 * will only occur if no windows could be loaded.
2942 */
2943
2944 glass_tfile *tfile_loadFromFile(char *file,char *name)
2945 {
2946 glass_tfile *t=tfile_createTemplateFile(name);
2947 char buff[256];
2948 char fbuff[256];
2949 char *parent;
2950 if (!t)
2951 return (0);
2952 t->loaded=TRUE;
2953 if (!tfile_mergeFromFile(file,t))
2954 {
2955 tfile__deleteTemplateFile(t);
2956 return (0);
2957 }
2958 strcpy(fbuff,name);
2959 utils_leafname(fbuff)[-1]=0;
2960 parent=utils_leafname(fbuff);
2961 parent[-1]=0;
2962 if (gPrefs_current()->sLoadPSpr)
2963 {
2964 sprintf(buff,"%s.%s.!Sprites",fbuff,parent);
2965 if (res_fileExists(buff))
2966 gSprite_mergeFromFile(t,buff);
2967 else
2968 {
2969 sprintf(buff,"%s.!Sprites",fbuff);
2970 if (res_fileExists(buff))
2971 gSprite_mergeFromFile(t,buff);
2972 }
2973 }
2974 if (gPrefs_current()->sLoadSpr)
2975 {
2976 sprintf(buff,"%s.%s.Sprites",fbuff,parent);
2977 if (res_fileExists(buff))
2978 gSprite_mergeFromFile(t,buff);
2979 }
2980 viewer_display(t->v); /* Show the viewer window in its glory */
2981 return (t);
2982 }
2983
2984 /*
2985 * void tfile_dragSelected(viewer_icon i,wimp_bbits b,char *package)
2986 *
2987 * Use
2988 * As for viewer_dragSelected, but uses the specified sprite as the
2989 * 'package' sprite is solid sprite drags are enabled.
2990 *
2991 * Parameters
2992 * viewer_icon i == the icon to drag
2993 * wimp_bbits b == the button status that started it off
2994 * char *package == the sprite to use for a package drag
2995 */
2996
2997 void tfile_dragSelected(viewer_icon i,wimp_bbits b,char *package)
2998 {
2999 sprite_id sid;
3000 sid.s.name=package;
3001 sid.tag=0;
3002 sprite_rename(resspr_area(),&sid,"package");
3003 viewer_dragSelected(i,b);
3004 sid.s.name="package";
3005 sprite_rename(resspr_area(),&sid,package);
3006 }