add casts to zune macros to silence some warnings
[tangerine.git] / workbench / libs / asl / filereqhooks.c
bloba19dbe44cf18240bf95ef0f04f171cf030da208b
1 /*
2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
3 $Id$
5 File requester specific code.
6 */
9 #include <proto/exec.h>
10 #include <proto/dos.h>
11 #include <proto/utility.h>
12 #include <proto/intuition.h>
13 #include <proto/graphics.h>
14 #include <proto/gadtools.h>
15 #include <exec/memory.h>
16 #include <dos/dos.h>
17 #include <intuition/screens.h>
18 #include <intuition/icclass.h>
19 #include <intuition/gadgetclass.h>
20 #include <graphics/gfx.h>
21 #include <devices/rawkeycodes.h>
22 #include <libraries/gadtools.h>
23 #include <workbench/startup.h>
24 #include <string.h>
26 #include "asl_intern.h"
27 #include "filereqhooks.h"
28 #include "layout.h"
29 #include "filereqsupport.h"
30 #include "specialreq.h"
32 #if USE_SHARED_COOLIMAGES
33 #include <libraries/coolimages.h>
34 #include <proto/coolimages.h>
35 #else
36 #include "coolimages.h"
37 #endif
39 #define CATCOMP_NUMBERS
40 #include "strings.h"
42 #define SDEBUG 0
43 #define DEBUG 0
45 #include <aros/debug.h>
47 /*****************************************************************************************/
49 STATIC BOOL FRGadInit(struct LayoutData *, struct AslBase_intern *);
50 STATIC BOOL FRGadLayout(struct LayoutData *, struct AslBase_intern *);
51 STATIC VOID FRGadCleanup(struct LayoutData *, struct AslBase_intern *);
52 STATIC ULONG FRHandleEvents(struct LayoutData *, struct AslBase_intern *);
53 STATIC ULONG FRGetSelectedFiles(struct LayoutData *, struct AslBase_intern *AslBase);
55 /*****************************************************************************************/
57 #define ID_BUTOK ID_MAINBUTTON_OK
58 #define ID_BUTVOLUMES ID_MAINBUTTON_MIDDLELEFT
59 #define ID_BUTPARENT ID_MAINBUTTON_MIDDLERIGHT
60 #define ID_BUTCANCEL ID_MAINBUTTON_CANCEL
62 #define ID_LISTVIEW 1
63 #define ID_STRDRAWER 2
64 #define ID_STRPATTERN 3
65 #define ID_STRFILE 4
67 #undef NUMBUTS
68 #define NUMBUTS 4L
70 #define CLASS_ASLBASE ((struct AslBase_intern *)cl->cl_UserData)
71 #define HOOK_ASLBASE ((struct AslBase_intern *)hook->h_Data)
73 #define AslBase HOOK_ASLBASE
75 /*****************************************************************************************/
77 AROS_UFH3(IPTR, ASLFRRenderHook,
78 AROS_UFHA(struct Hook *, hook, A0),
79 AROS_UFHA(struct ASLLVFileReqNode *,node, A2),
80 AROS_UFHA(struct ASLLVDrawMsg *, msg, A1)
83 AROS_USERFUNC_INIT
85 IPTR retval;
87 if (msg->lvdm_MethodID == LV_DRAW)
89 struct DrawInfo *dri = msg->lvdm_DrawInfo;
90 struct RastPort *rp = msg->lvdm_RastPort;
92 WORD min_x = msg->lvdm_Bounds.MinX;
93 WORD min_y = msg->lvdm_Bounds.MinY;
94 WORD max_x = msg->lvdm_Bounds.MaxX;
95 WORD max_y = msg->lvdm_Bounds.MaxY;
97 UWORD erasepen = BACKGROUNDPEN;
98 UWORD textpen = TEXTPEN;
100 if (node) switch(node->type)
102 case ASLLV_FRNTYPE_DIRECTORY:
103 if (node->subtype > 0) textpen = SHINEPEN;
104 break;
105 case ASLLV_FRNTYPE_VOLUMES:
106 switch(node->subtype)
108 case DLT_DIRECTORY:
109 case DLT_LATE:
110 case DLT_NONBINDING:
111 textpen = SHINEPEN;
112 break;
114 break;
117 SetDrMd(rp, JAM1);
119 switch (msg->lvdm_State)
121 case ASLLVR_SELECTED:
122 erasepen = FILLPEN;
123 textpen = FILLTEXTPEN;
125 /* Fall through */
127 case ASLLVR_NORMAL:
129 WORD numfit;
130 struct TextExtent te;
132 SetAPen(rp, dri->dri_Pens[erasepen]);
133 RectFill(rp, min_x, min_y, max_x, max_y);
135 if (node)
137 struct LayoutData *ld = ((struct LayoutData *)node->userdata);
138 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
139 WORD i;
141 SetFont(rp, ld->ld_Font);
143 min_x += BORDERLVITEMSPACINGX;
144 min_y += BORDERLVITEMSPACINGY;
146 max_x -= BORDERLVITEMSPACINGX;
147 max_y -= BORDERLVITEMSPACINGY;
149 for(i = 0; i < ASLLV_MAXCOLUMNS;i++)
151 WORD x;
152 UWORD len;
154 if (node->text[i] == NULL) continue;
156 len = strlen(node->text[i]);
158 switch(udata->LVColumnAlign[i])
160 case ASLLV_ALIGN_RIGHT:
161 x = min_x + udata->LVColumnWidth[i] -
162 TextLength(rp, node->text[i], len);
163 break;
165 default:
166 x = min_x;
167 break;
170 if (x > max_x) break;
172 numfit = TextFit(rp,
173 node->text[i],
174 len,
175 &te,
176 NULL,
178 max_x - x + 1,
179 max_y - min_y + 1);
181 if (numfit < len) numfit++;
183 if (numfit < 1) break;
185 SetAPen(rp, dri->dri_Pens[textpen]);
187 /* Render text */
188 Move(rp, x, min_y + rp->Font->tf_Baseline);
189 Text(rp, node->text[i], numfit);
191 min_x += udata->LVColumnWidth[i] + rp->TxWidth * 2;
193 } /* for(i = 0; i < ASLLV_MAXCOLUMNS;i++) */
195 } /* if (node) */
197 } break;
199 } /* switch (msg->lvdm_State) */
201 retval = ASLLVCB_OK;
203 } /* if (msg->lvdm_MethodID == LV_DRAW) */
204 else
206 retval = ASLLVCB_UNKNOWN;
209 return retval;
211 AROS_USERFUNC_EXIT
214 /*****************************************************************************************/
216 #undef AslBase
218 /*****************************************************************************************/
220 AROS_UFH3(VOID, FRTagHook,
221 AROS_UFHA(struct Hook *, hook, A0),
222 AROS_UFHA(struct ParseTagArgs *, pta, A2),
223 AROS_UFHA(struct AslBase_intern *, AslBase, A1)
226 AROS_USERFUNC_INIT
228 struct TagItem *tag;
229 const struct TagItem *tstate;
230 struct IntFileReq *ifreq;
231 IPTR tidata;
233 EnterFunc(bug("FRTagHook(hook=%p, pta=%p)\n", hook, pta));
235 ifreq = (struct IntFileReq *)pta->pta_IntReq;
237 tstate = pta->pta_Tags;
238 while ((tag = NextTagItem(&tstate)) != NULL)
240 tidata = tag->ti_Data;
242 switch (tag->ti_Tag)
244 /* The tags that are put "in a row" are defined as the same value,
245 and therefor we only use one of them, but the effect is for all of them
247 case ASLFR_InitialDrawer:
248 /* case ASL_Dir: Obsolete */
249 if (tidata)
250 ifreq->ifr_Drawer = (STRPTR)tidata;
251 break;
253 case ASLFR_InitialFile:
254 /* case ASL_File: Obsolete */
255 if (tidata)
256 ifreq->ifr_File = (STRPTR)tidata;
257 break;
259 case ASLFR_InitialPattern:
260 /* case ASL_Pattern: Obsolete */
261 if (tidata)
262 ifreq->ifr_Pattern = (STRPTR)tidata;
263 break;
265 case ASLFR_UserData:
266 ((struct FileRequester *)pta->pta_Req)->fr_UserData = (APTR)tidata;
267 break;
269 /* Options */
271 case ASLFR_Flags1:
272 ifreq->ifr_Flags1 = (UBYTE)tidata;
273 /* Extract some flags that are common to all requester types and
274 put them into IntReq->ir_Flags
276 if (ifreq->ifr_Flags1 & FRF_PRIVATEIDCMP)
277 GetIR(ifreq)->ir_Flags |= IF_PRIVATEIDCMP;
278 else
279 GetIR(ifreq)->ir_Flags &= ~IF_PRIVATEIDCMP;
280 break;
282 case ASLFR_Flags2:
283 ifreq->ifr_Flags2 = (UBYTE)tidata;
284 break;
286 case ASLFR_DoSaveMode:
287 if (tidata)
288 ifreq->ifr_Flags1 |= FRF_DOSAVEMODE;
289 else
290 ifreq->ifr_Flags1 &= ~FRF_DOSAVEMODE;
291 break;
293 case ASLFR_DoMultiSelect:
294 if (tidata)
295 ifreq->ifr_Flags1 |= FRF_DOMULTISELECT;
296 else
297 ifreq->ifr_Flags1 &= ~FRF_DOMULTISELECT;
298 break;
300 case ASLFR_DoPatterns:
301 if (tidata)
302 ifreq->ifr_Flags1 |= FRF_DOPATTERNS;
303 else
304 ifreq->ifr_Flags1 &= ~FRF_DOPATTERNS;
305 break;
307 case ASLFR_DrawersOnly:
308 if (tidata)
309 ifreq->ifr_Flags2 |= FRF_DRAWERSONLY;
310 else
311 ifreq->ifr_Flags2 &= ~FRF_DRAWERSONLY;
312 break;
314 case ASLFR_FilterFunc:
315 ifreq->ifr_FilterFunc = (struct Hook *)tidata;
316 ifreq->ifr_Flags1 |= FRF_FILTERFUNC;
317 break;
319 case ASLFR_RejectIcons:
320 if (tidata)
321 ifreq->ifr_Flags2 |= FRF_REJECTICONS;
322 else
323 ifreq->ifr_Flags2 &= ~FRF_REJECTICONS;
324 break;
326 case ASLFR_RejectPattern:
327 if (tidata)
328 ifreq->ifr_RejectPattern = (STRPTR)tidata;
329 break;
331 case ASLFR_AcceptPattern:
332 if (tidata)
333 ifreq->ifr_AcceptPattern = (STRPTR)tidata;
334 break;
336 case ASLFR_FilterDrawers:
337 if (tidata)
338 ifreq->ifr_Flags2 |= FRF_FILTERDRAWERS;
339 else
340 ifreq->ifr_Flags2 &= ~FRF_FILTERDRAWERS;
341 break;
343 case ASLFR_HookFunc:
344 ifreq->ifr_HookFunc = (APTR)tidata;
345 break;
347 case ASLFR_SetSortBy:
348 ifreq->ifr_SortBy = tidata;
349 break;
351 case ASLFR_GetSortBy:
352 ifreq->ifr_GetSortBy = (ULONG *)tidata;
353 break;
355 case ASLFR_SetSortOrder:
356 ifreq->ifr_SortOrder = tidata;
357 break;
359 case ASLFR_GetSortOrder:
360 ifreq->ifr_GetSortOrder = (ULONG *)tidata;
361 break;
363 case ASLFR_SetSortDrawers:
364 ifreq->ifr_SortDrawers = tidata;
365 break;
367 case ASLFR_GetSortDrawers:
368 ifreq->ifr_GetSortDrawers = (ULONG *)tidata;
369 break;
371 case ASLFR_InitialShowVolumes:
372 ifreq->ifr_InitialShowVolumes = tidata ? TRUE : FALSE;
373 break;
375 default:
376 break;
378 } /* switch (tag->ti_Tag) */
380 } /* while ((tag = NextTagItem(&tstate)) != 0) */
382 /* DrawersOnly excludes multiselect */
384 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY)
386 ifreq->ifr_Flags1 &= ~FRF_DOMULTISELECT;
389 ReturnVoid("FRTagHook");
391 AROS_USERFUNC_EXIT
394 /*****************************************************************************************/
396 AROS_UFH3(ULONG, FRGadgetryHook,
397 AROS_UFHA(struct Hook *, hook, A0),
398 AROS_UFHA(struct LayoutData *, ld, A2),
399 AROS_UFHA(struct AslBase_intern *, AslBase, A1)
402 AROS_USERFUNC_INIT
404 ULONG retval;
406 switch (ld->ld_Command)
408 case LDCMD_INIT:
409 retval = (ULONG)FRGadInit(ld, ASLB(AslBase));
410 break;
412 case LDCMD_LAYOUT:
413 retval = (ULONG)FRGadLayout(ld, ASLB(AslBase));
414 break;
416 case LDCMD_HANDLEEVENTS:
417 retval = (ULONG)FRHandleEvents(ld, ASLB(AslBase));
418 break;
420 case LDCMD_CLEANUP:
421 FRGadCleanup(ld, ASLB(AslBase));
422 retval = GHRET_OK;
423 break;
425 default:
426 retval = GHRET_FAIL;
427 break;
430 return (retval);
432 AROS_USERFUNC_EXIT
435 /*****************************************************************************************/
437 struct ButtonInfo
439 WORD gadid;
440 char *text;
441 #if USE_SHARED_COOLIMAGES
442 ULONG coolid;
443 Object **objvar;
444 const struct CoolImage *coolimage;
445 #else
446 const struct CoolImage *coolimage;
447 Object **objvar;
448 #endif
451 /*****************************************************************************************/
453 STATIC BOOL FRGadInit(struct LayoutData *ld, struct AslBase_intern *AslBase)
455 struct FRUserData *udata = ld->ld_UserData;
456 struct IntFileReq *ifreq = (struct IntFileReq *)ld->ld_IntReq;
457 #if USE_SHARED_COOLIMAGES
458 ULONG okid = (GetIR(ifreq)->ir_Flags & IF_USER_POSTEXT) ? COOL_USEIMAGE_ID :
459 ((ifreq->ifr_Flags1 & FRF_DOSAVEMODE) ? COOL_SAVEIMAGE_ID :
460 COOL_LOADIMAGE_ID);
461 struct ButtonInfo bi[NUMBUTS] =
463 { ID_BUTOK , GetIR(ifreq)->ir_PositiveText , okid , &udata->OKBut },
464 { ID_BUTVOLUMES , NULL , COOL_DOTIMAGE_ID , &udata->VolumesBut },
465 { ID_BUTPARENT , NULL , COOL_DOTIMAGE_ID , &udata->ParentBut },
466 { ID_BUTCANCEL , GetIR(ifreq)->ir_NegativeText , COOL_CANCELIMAGE_ID , &udata->CancelBut }
468 #else
469 const struct CoolImage *okimage = (GetIR(ifreq)->ir_Flags & IF_USER_POSTEXT) ? &cool_useimage :
470 ((ifreq->ifr_Flags1 & FRF_DOSAVEMODE) ? &cool_saveimage :
471 &cool_loadimage);
472 struct ButtonInfo bi[NUMBUTS] =
474 { ID_BUTOK , GetIR(ifreq)->ir_PositiveText , okimage , &udata->OKBut },
475 { ID_BUTVOLUMES , NULL , &cool_dotimage , &udata->VolumesBut },
476 { ID_BUTPARENT , NULL , &cool_dotimage , &udata->ParentBut },
477 { ID_BUTCANCEL , GetIR(ifreq)->ir_NegativeText , &cool_cancelimage , &udata->CancelBut }
479 #endif
480 Object *gad;
481 STRPTR butstr[NUMBUTS];
482 LONG error = ERROR_NO_FREE_STORE;
483 WORD gadrows, x, y, w, h, i, y2;
485 NEWLIST(&udata->ListviewList);
487 udata->StringEditHook.h_Entry = (APTR)AROS_ASMSYMNAME(StringEditFunc);
488 udata->StringEditHook.h_SubEntry = NULL;
489 udata->StringEditHook.h_Data = AslBase;
491 udata->ListviewHook.h_Entry = (APTR)AROS_ASMSYMNAME(ASLFRRenderHook);
492 udata->ListviewHook.h_SubEntry = NULL;
493 udata->ListviewHook.h_Data = AslBase;
495 /* calc. min. size */
497 if (!bi[0].text) bi[0].text = GetString(MSG_FILEREQ_POSITIVE_GAD, GetIR(ifreq)->ir_Catalog, AslBase);
498 bi[1].text = GetString(MSG_FILEREQ_VOLUMES_GAD, GetIR(ifreq)->ir_Catalog, AslBase);
499 bi[2].text = GetString(MSG_FILEREQ_PARENT_GAD, GetIR(ifreq)->ir_Catalog, AslBase);
500 if (!bi[3].text) bi[3].text = GetString(MSG_FILEREQ_NEGATIVE_GAD, GetIR(ifreq)->ir_Catalog, AslBase);
503 w = 0;
504 for(i = 0; i < NUMBUTS; i++)
506 x = TextLength(&ld->ld_DummyRP, bi[i].text, strlen(bi[i].text));
508 #if FREQ_COOL_BUTTONS
509 #if USE_SHARED_COOLIMAGES
510 if (CoolImagesBase)
512 bi[i].coolimage = (const struct CoolImage *)COOL_ObtainImageA(bi[i].coolid, NULL);
515 if (CoolImagesBase)
516 #endif
517 if (ld->ld_TrueColor)
519 x += IMAGEBUTTONEXTRAWIDTH + bi[i].coolimage->width;
521 #endif
523 if (x > w) w = x;
526 udata->ButWidth = w + BUTTONEXTRAWIDTH;
528 ld->ld_ButWidth = udata->ButWidth;
529 ld->ld_NumButtons = 4;
531 #if FREQ_COOL_BUTTONS
533 #if USE_SHARED_COOLIMAGES
534 if (CoolImagesBase)
536 #endif
537 y = BUTTONEXTRAHEIGHT + ld->ld_Font->tf_YSize;
538 if (ld->ld_TrueColor)
540 y2 = IMAGEBUTTONEXTRAHEIGHT + DEF_COOLIMAGEHEIGHT;
541 } else {
542 y2 = 0;
544 udata->ButHeight = (y > y2) ? y : y2;
545 #if USE_SHARED_COOLIMAGES
547 else
549 udata->ButHeight = BUTTONEXTRAHEIGHT + ld->ld_Font->tf_YSize;
551 #endif
553 #else
554 udata->ButHeight = BUTTONEXTRAHEIGHT + ld->ld_Font->tf_YSize;
555 #endif
557 gadrows = 3; /* button row + file string + drawer string */
558 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS) gadrows++;
559 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY) gadrows--;
561 ld->ld_MinWidth = OUTERSPACINGX * 2 +
562 GADGETSPACINGX * 3 +
563 udata->ButWidth * NUMBUTS;
565 ld->ld_MinHeight = OUTERSPACINGY * 2 +
566 (GADGETSPACINGY + udata->ButHeight) * gadrows +
567 BORDERLVSPACINGY * 2 +
568 (ld->ld_Font->tf_YSize + BORDERLVITEMSPACINGY * 2) * FREQ_MIN_VISIBLELINES;
570 /* make listview gadget */
572 x = ld->ld_WBorLeft + OUTERSPACINGX;
573 y = ld->ld_WBorTop + OUTERSPACINGY;
574 w = -ld->ld_WBorRight - ld->ld_WBorLeft - OUTERSPACINGX * 2 - PROPSIZE;
575 h = -ld->ld_WBorBottom - ld->ld_WBorTop - OUTERSPACINGY * 2 -
576 udata->ButHeight * gadrows -
577 GADGETSPACINGY * gadrows;
580 struct TagItem lv_tags[] =
582 {GA_Left , x },
583 {GA_Top , y },
584 {GA_RelWidth , w },
585 {GA_RelHeight , h },
586 {GA_UserData , (IPTR)ld },
587 {GA_ID , ID_LISTVIEW },
588 {GA_RelVerify , TRUE },
589 {ASLLV_CallBack , (IPTR)&udata->ListviewHook },
590 {ASLLV_DoMultiSelect, (ifreq->ifr_Flags1 & FRF_DOMULTISELECT) },
591 {TAG_DONE }
594 udata->Listview = gad = NewObjectA(AslBase->asllistviewclass, NULL, lv_tags);
595 if (!udata->Listview) goto failure;
599 /* make scroller gadget for listview */
601 x = -ld->ld_WBorRight - OUTERSPACINGX - PROPSIZE + 1;
602 y = ld->ld_WBorTop + OUTERSPACINGY;
603 w = PROPSIZE;
604 h = -ld->ld_WBorBottom - ld->ld_WBorTop - OUTERSPACINGY * 2 -
605 udata->ButHeight * gadrows -
606 GADGETSPACINGY * gadrows;
608 struct TagItem scroller_tags[] =
610 {GA_RelRight , x },
611 {GA_Top , y },
612 {GA_Width , w },
613 {GA_RelHeight , h },
614 {GA_ID , ID_LISTVIEW },
615 {PGA_NewLook , TRUE },
616 {PGA_Borderless , TRUE },
617 {PGA_Freedom , FREEVERT },
618 {PGA_Top , 0 },
619 {PGA_Total , 20 },
620 {PGA_Visible , 1 },
621 {GA_Previous , (IPTR)gad },
622 {TAG_DONE }
625 if (!makescrollergadget(&udata->ScrollGad, ld, scroller_tags, AslBase)) goto failure;
626 gad = udata->ScrollGad.arrow2;
629 connectscrollerandlistview(&udata->ScrollGad, udata->Listview, AslBase);
631 /* make button row */
633 y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight + 1;
636 struct TagItem button_tags[] =
638 {GA_Text , 0 },
639 {GA_Previous , 0 },
640 {GA_ID , 0 },
641 #if FREQ_COOL_BUTTONS
642 {ASLBT_CoolImage , 0 },
643 #else
644 {TAG_IGNORE , 0 },
645 #endif
646 {GA_UserData , (IPTR)ld },
647 {GA_Left , 0 },
648 {GA_RelBottom , y },
649 {GA_Width , udata->ButWidth },
650 {GA_Height , udata->ButHeight },
651 {GA_RelVerify , TRUE },
652 {GA_Image , 0 }, /* means we want a frame */
653 {TAG_DONE }
656 for(i = 0; i < NUMBUTS; i++)
658 button_tags[0].ti_Data = (IPTR)bi[i].text;
659 button_tags[1].ti_Data = (IPTR)gad;
660 button_tags[2].ti_Data = bi[i].gadid;
662 #if USE_SHARED_COOLIMAGES
663 if (CoolImagesBase == NULL) button_tags[3].ti_Tag = TAG_IGNORE;
664 #endif
665 button_tags[3].ti_Data = (IPTR)bi[i].coolimage;
667 *(bi[i].objvar) = gad = NewObjectA(AslBase->aslbuttonclass, NULL, button_tags);
668 if (!gad) goto failure;
673 /* make labels */
676 struct LabelInfo
678 BOOL doit;
679 STRPTR text;
680 Object **objvar;
681 } li [] =
683 {TRUE, (STRPTR)MSG_FILEREQ_PATTERN_LABEL, &udata->PatternLabel },
684 {TRUE, (STRPTR)MSG_FILEREQ_DRAWER_LABEL , &udata->DrawerLabel },
685 {TRUE, (STRPTR)MSG_FILEREQ_FILE_LABEL , &udata->FileLabel }
688 struct TagItem label_tags[] =
690 {GA_Left , 0 },
691 {GA_RelBottom , 0 },
692 {GA_Width , 0 },
693 {GA_Height , udata->ButHeight },
694 {GA_Text , 0 },
695 {GA_Previous , (IPTR)gad },
696 {GA_UserData , (IPTR)ld },
697 {GA_Disabled , TRUE },
698 {TAG_DONE }
701 for(i = 0; i < 3; i++)
703 li[i].text = GetString((LONG)li[i].text, GetIR(ifreq)->ir_Catalog, AslBase);
706 /* Drawer label is always there */
708 w = TextLength(&ld->ld_DummyRP, li[1].text, strlen(li[1].text)) +
709 LABELSPACINGX +
710 ld->ld_Font->tf_XSize * 2; /* Frame symbol showing directory scan activity */
712 i = 0;
713 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS)
715 butstr[i++] = li[0].text;
717 else
719 li[0].doit = FALSE;
722 if (!(ifreq->ifr_Flags2 & FRF_DRAWERSONLY))
724 butstr[i++] = li[2].text;
726 else
728 li[2].doit = FALSE;
731 if (i)
733 x = BiggestTextLength(butstr, i, &(ld->ld_DummyRP), AslBase);
734 if (x > w) w = x;
737 x = ld->ld_WBorLeft + OUTERSPACINGX;
738 y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight -
739 (udata->ButHeight + GADGETSPACINGY) * (gadrows - 1) + 1;
741 label_tags[1].ti_Data = y;
743 for(i = 0; i < 3;i++)
745 if (!li[i].doit) continue;
747 if (i == 1) y2 = y;
749 label_tags[2].ti_Data = TextLength(&ld->ld_DummyRP, li[i].text, strlen(li[i].text));
750 label_tags[0].ti_Data = x + w - label_tags[2].ti_Data;
751 label_tags[4].ti_Data = (IPTR)li[i].text;
752 label_tags[5].ti_Data = (IPTR)gad;
754 *(li[i].objvar) = gad = NewObjectA(AslBase->aslbuttonclass, NULL, label_tags);
755 if (!gad) goto failure;
757 y += udata->ButHeight + GADGETSPACINGY;
758 label_tags[1].ti_Data = y;
762 /* Directory Scan Symbol */
765 struct TagItem sym_tags[] =
767 {GA_Left , x },
768 {GA_RelBottom , y2 + 1 },
769 {GA_Width , ld->ld_Font->tf_XSize * 2 },
770 {GA_Height , udata->ButHeight - 2 },
771 {GA_Image , 0 }, /* means we want a frame */
772 {GA_Previous , (IPTR)gad },
773 {GA_Disabled , TRUE },
774 {GA_UserData , (IPTR)ld },
775 {TAG_DONE }
778 udata->DirectoryScanSymbol = gad = NewObjectA(AslBase->aslbuttonclass, NULL, sym_tags);
779 if (!udata->DirectoryScanSymbol) goto failure;
782 /* make string gadgets */
784 y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight -
785 (udata->ButHeight + GADGETSPACINGY) * (gadrows - 1) + 1;
786 x = ld->ld_WBorLeft + OUTERSPACINGX + w + LABELSPACINGX;
788 w = -ld->ld_WBorLeft - ld->ld_WBorRight - OUTERSPACINGX * 2 -
789 w - LABELSPACINGX;
792 struct StrInfo
794 WORD gadid;
795 char *text;
796 WORD maxchars;
797 Object **objvar;
798 } si [] =
800 {ID_STRPATTERN, ifreq->ifr_Pattern, MAX_PATTERN_LEN, &udata->PatternGad },
801 {ID_STRDRAWER , ifreq->ifr_Drawer , MAX_PATH_LEN , &udata->PathGad },
802 {ID_STRFILE , ifreq->ifr_File , MAX_FILE_LEN , &udata->FileGad },
805 struct TagItem string_tags[] =
807 {GA_Left , x },
808 {GA_RelBottom , y },
809 {GA_RelWidth , w },
810 {GA_Height , udata->ButHeight },
811 {GA_Previous , (IPTR)gad },
812 {STRINGA_TextVal , (IPTR)ifreq->ifr_Pattern },
813 {STRINGA_MaxChars , MAX_PATTERN_LEN },
814 {GA_ID , ID_STRPATTERN },
815 {GA_RelVerify , TRUE },
816 {GA_UserData , (IPTR)ld },
817 {GA_TabCycle , TRUE },
818 {STRINGA_EditHook , (IPTR)&udata->StringEditHook },
819 {STRINGA_Font , (IPTR)ld->ld_Font },
820 {TAG_DONE }
823 if (!(ifreq->ifr_Flags1 & FRF_DOPATTERNS)) si[0].gadid = 0;
824 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY) si[2].gadid = 0;
826 for(i = 0;i < 3; i++)
828 if (si[i].gadid == 0) continue;
830 string_tags[4].ti_Data = (IPTR)gad;
831 string_tags[5].ti_Data = (IPTR)si[i].text;
832 string_tags[6].ti_Data = si[i].maxchars;
833 string_tags[7].ti_Data = si[i].gadid;
835 *(si[i].objvar) = gad = NewObjectA(AslBase->aslstringclass, NULL, string_tags);
836 if (!gad) goto failure;
838 y += udata->ButHeight + GADGETSPACINGY;
839 string_tags[1].ti_Data = y;
843 #if AVOID_FLICKER
845 struct TagItem eraser_tags[] =
847 {GA_Previous, (IPTR)gad},
848 {TAG_DONE}
851 udata->EraserGad = gad = NewObjectA(AslBase->asleraserclass, NULL, eraser_tags);
852 /* Doesn't matter if this failed */
854 #endif
856 if (ifreq->ifr_InitialShowVolumes)
858 FRGetVolumes(ld, AslBase);
859 } else {
860 FRNewPath((STRPTR)ifreq->ifr_Drawer, ld, AslBase);
863 SetAttrs(udata->Listview, ASLLV_Labels, (IPTR)&udata->ListviewList,
864 TAG_DONE);
866 ld->ld_GList = (struct Gadget *)udata->Listview;
868 /* Menus */
870 struct NewMenu nm[] =
872 {NM_TITLE, (STRPTR)MSG_FILEREQ_MEN_CONTROL }, /* 0 */
873 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_LASTNAME , 0 , 0 , 0 , (APTR)FRMEN_LASTNAME }, /* 1 */
874 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_NEXTNAME , 0, 0 , 0 , (APTR)FRMEN_NEXTNAME }, /* 2 */
875 {NM_ITEM, NM_BARLABEL }, /* 3 */
876 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_RESTORE , 0, 0 , 0 , (APTR)FRMEN_RESTORE }, /* 4 */
877 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_PARENT , 0, 0 , 0 , (APTR)FRMEN_PARENT }, /* 5 */
878 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_VOLUMES , 0, 0 , 0 , (APTR)FRMEN_VOLUMES }, /* 6 */
879 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_UPDATE , 0, 0 , 0 , (APTR)FRMEN_UPDATE }, /* 7 */
880 {NM_ITEM, NM_BARLABEL }, /* 8 */
881 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_DELETE , 0, 0 , 0 , (APTR)FRMEN_DELETE }, /* 9 */
882 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_CREATEDRAWER , 0, 0 , 0 , (APTR)FRMEN_NEWDRAWER }, /* 10 */
883 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_RENAME , 0, 0 , 0 , (APTR)FRMEN_RENAME }, /* 11 */
884 {NM_ITEM, NM_BARLABEL }, /* 12 */
885 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_SELECT , 0, 0 , 0 , (APTR)FRMEN_SELECT }, /* 13 */
886 {NM_ITEM, NM_BARLABEL }, /* 14 */
887 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_OK , 0, 0 , 0 , (APTR)FRMEN_OK }, /* 15 */
888 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_CANCEL , 0, 0 , 0 , (APTR)FRMEN_CANCEL }, /* 16 */
889 {NM_TITLE, (STRPTR)MSG_FILEREQ_MEN_FILELIST }, /* 17 */
890 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTNAME , 0, CHECKIT , 2 + 4 , (APTR)FRMEN_BYNAME }, /* 18 */
891 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDATE , 0, CHECKIT , 1 + 4 , (APTR)FRMEN_BYDATE }, /* 19 */
892 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTSIZE , 0, CHECKIT , 1 + 2 , (APTR)FRMEN_BYSIZE }, /* 20 */
893 {NM_ITEM, NM_BARLABEL }, /* 21 */
894 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTUP , 0, CHECKIT , 32 , (APTR)FRMEN_ASCENDING }, /* 22 */
895 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDOWN , 0, CHECKIT , 16 , (APTR)FRMEN_DESCENDING }, /* 23 */
896 {NM_ITEM, NM_BARLABEL }, /* 24 */
897 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDRAWERFIRST , 0, CHECKIT , 256 + 512 , (APTR)FRMEN_DRAWERSFIRST }, /* 25 */
898 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDRAWERSAME , 0, CHECKIT , 128 + 512 , (APTR)FRMEN_DRAWERSMIX }, /* 26 */
899 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDRAWERLAST , 0, CHECKIT , 128 + 256 , (APTR)FRMEN_DRAWERSLAST }, /* 27 */
900 {NM_END } /* 28 */
903 struct TagItem menu_tags[] =
905 {GTMN_NewLookMenus , TRUE },
906 {GTMN_TextAttr , (IPTR)GetIR(ifreq)->ir_TextAttr },
907 {TAG_DONE }
910 if (menu_tags[1].ti_Data == 0) menu_tags[1].ti_Tag = TAG_IGNORE;
912 LocalizeMenus(nm, GetIR(ifreq)->ir_Catalog, AslBase);
914 nm[18 + ifreq->ifr_SortBy ].nm_Flags |= CHECKED;
915 nm[22 + ifreq->ifr_SortOrder ].nm_Flags |= CHECKED;
916 nm[25 + ifreq->ifr_SortDrawers].nm_Flags |= CHECKED;
918 /* Show "Select" menu item only if this is a multiselect file requester.
919 The orig Amiga asl.library disables (ghosts) the item, but why
920 show it if it cannot be used anyway. */
922 if (!(ifreq->ifr_Flags1 & FRF_DOMULTISELECT))
924 nm[13].nm_Type = NM_IGNORE;
925 nm[14].nm_Type = NM_IGNORE;
928 /* No Rename in drawersonly requesters */
930 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY)
932 nm[11].nm_Type = NM_IGNORE;
935 /* Don't fail, if menus cannot be created/layouted, because a requester
936 without menus is still better than no requester at all */
938 if ((ld->ld_Menu = CreateMenusA(nm, NULL)))
940 if (!LayoutMenusA(ld->ld_Menu, ld->ld_VisualInfo, menu_tags))
942 FreeMenus(ld->ld_Menu);ld->ld_Menu = NULL;
947 SetIoErr(0);
949 ReturnBool ("FRGadInit", TRUE);
951 failure:
952 D(bug("failure\n"));
954 FRGadCleanup(ld, ASLB(AslBase));
956 SetIoErr(error);
958 ReturnBool ("FRGadInit", FALSE);
962 /*****************************************************************************************/
964 STATIC BOOL FRGadLayout(struct LayoutData *ld, struct AslBase_intern *AslBase)
966 FRActivateMainStringGadget(ld, AslBase);
968 ReturnBool ("FRGadLayout", TRUE );
971 /*****************************************************************************************/
973 STATIC VOID FRClickOnVolumes(struct LayoutData *ld, struct AslBase_intern *AslBase)
975 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
977 if (udata->Flags & FRFLG_SHOWING_VOLUMES)
979 union
981 UBYTE *dir;
982 IPTR baz;
983 } foo;
985 GetAttr(STRINGA_TextVal, udata->PathGad, &foo.baz);
986 FRGetDirectory(foo.dir, ld, AslBase);
987 } else {
988 FRGetVolumes(ld, AslBase);
992 /*****************************************************************************************/
994 STATIC ULONG FRHandleEvents(struct LayoutData *ld, struct AslBase_intern *AslBase)
996 struct IntuiMessage *imsg;
997 ULONG retval = GHRET_OK;
998 struct FRUserData *udata;
999 struct IntFileReq *ifreq;
1000 WORD gadid;
1002 EnterFunc(bug("FRHandleEvents: Class: %d\n", imsg->Class));
1004 udata = (struct FRUserData *)ld->ld_UserData;
1005 ifreq = (struct IntFileReq *)ld->ld_IntReq;
1007 imsg = ld->ld_Event;
1009 switch (imsg->Class)
1011 case IDCMP_CLOSEWINDOW:
1012 retval = FALSE;
1013 break;
1015 case IDCMP_MOUSEBUTTONS:
1016 FRActivateMainStringGadget(ld, AslBase);
1017 break;
1019 case IDCMP_RAWKEY:
1020 switch (imsg->Code)
1022 case CURSORUP:
1023 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, 0, AslBase);
1024 break;
1026 case RAWKEY_PAGEUP:
1027 FRChangeActiveLVItem(ld, -1, IEQUALIFIER_LSHIFT, 0, AslBase);
1028 break;
1030 case RAWKEY_HOME:
1031 FRChangeActiveLVItem(ld, -1, IEQUALIFIER_LALT, 0, AslBase);
1032 break;
1034 case RAWKEY_NM_WHEEL_UP:
1035 FRChangeActiveLVItem(ld, -3, imsg->Qualifier, 0, AslBase);
1036 break;
1038 case CURSORDOWN:
1039 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, 0, AslBase);
1040 break;
1042 case RAWKEY_PAGEDOWN:
1043 FRChangeActiveLVItem(ld, 1, IEQUALIFIER_LSHIFT, 0, AslBase);
1044 break;
1046 case RAWKEY_END:
1047 FRChangeActiveLVItem(ld, 1, IEQUALIFIER_LALT, 0, AslBase);
1048 break;
1050 case RAWKEY_NM_WHEEL_DOWN:
1051 FRChangeActiveLVItem(ld, 3, imsg->Qualifier, 0, AslBase);
1052 break;
1055 break;
1057 case IDCMP_VANILLAKEY:
1058 switch(imsg->Code)
1060 case 27:
1061 retval = FALSE;
1062 break;
1064 break;
1066 case IDCMP_GADGETUP:
1067 gadid = ((struct Gadget *)imsg->IAddress)->GadgetID;
1069 D(bug("GADGETUP! gadgetid=%d\n", gadid));
1071 switch (gadid)
1073 case ID_BUTCANCEL:
1074 retval = FALSE;
1075 break;
1077 case ID_BUTVOLUMES:
1078 FRClickOnVolumes(ld, AslBase);
1079 break;
1081 case ID_BUTPARENT:
1082 FRParentPath(ld, AslBase);
1083 break;
1085 case ID_STRFILE:
1086 if (imsg->Code == STRINGCODE_CURSORUP)
1088 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, (struct Gadget *)udata->FileGad, AslBase);
1089 break;
1091 else if (imsg->Code == STRINGCODE_CURSORDOWN)
1093 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, (struct Gadget *)udata->FileGad, AslBase);
1094 break;
1096 else if ((imsg->Code == 0) || (imsg->Code == 9))
1098 char filestring[MAX_FILE_LEN], checkstring[MAX_FILE_LEN], *file;
1099 BOOL fall_through = (imsg->Code == 9) ? FALSE : TRUE;
1100 BOOL has_colon = FALSE;
1101 BOOL has_slash = FALSE;
1103 GetAttr(STRINGA_TextVal, udata->FileGad, (IPTR *)&file);
1104 strcpy(filestring, file);
1106 has_colon = strchr(filestring, ':') ? TRUE : FALSE;
1107 has_slash = strchr(filestring, '/') ? TRUE : FALSE;
1109 if (has_colon || has_slash)
1111 fall_through = FALSE;
1113 if (strcmp(filestring, ":") == 0)
1115 FRNewPath(filestring, ld, AslBase);
1116 FRSetFile("", ld, AslBase);
1117 } else if (stricmp(filestring, "/") == 0)
1119 FRParentPath(ld, AslBase);
1120 FRSetFile("", ld, AslBase);
1121 } else {
1122 BPTR lock;
1123 BOOL isfile = TRUE;
1125 if (has_colon)
1127 strcpy(checkstring, filestring);
1128 } else {
1129 char *dir;
1131 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&dir);
1133 strcpy(checkstring, dir);
1134 AddPart(checkstring, filestring, MAX_FILE_LEN);
1137 if ((lock = Lock(checkstring, ACCESS_READ)))
1139 struct FileInfoBlock *fib;
1140 BOOL isfile = FALSE;
1142 if ((fib = AllocDosObject(DOS_FIB, NULL)))
1144 if (Examine(lock, fib))
1146 if (fib->fib_DirEntryType > 0) isfile = FALSE;
1148 FreeDosObject(DOS_FIB, fib);
1150 UnLock(lock);
1153 if (isfile)
1155 char *fp = FilePart(checkstring);
1156 char fpc = *fp;
1158 *fp = '\0';
1159 FRNewPath(checkstring, ld, AslBase);
1161 *fp = fpc;
1162 FRSetFile(fp, ld, AslBase);
1164 } else {
1165 FRNewPath(filestring, ld, AslBase);
1166 FRSetFile("", ld, AslBase);
1170 ActivateGadget((struct Gadget *)udata->FileGad, ld->ld_Window, NULL);
1172 } /* has colon or slash */
1174 if (!fall_through) break;
1176 } /* if ((imsg->Code == 0) || (imsg->Code == 9)) */
1177 else
1179 break;
1182 /* fall through */
1184 case ID_BUTOK:
1185 retval = FRGetSelectedFiles(ld, ASLB(AslBase));
1186 break;
1188 case ID_STRPATTERN:
1189 if (imsg->Code == STRINGCODE_CURSORUP)
1191 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, (struct Gadget *)udata->PatternGad, AslBase);
1192 break;
1194 else if (imsg->Code == STRINGCODE_CURSORDOWN)
1196 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, (struct Gadget *)udata->PatternGad, AslBase);
1197 break;
1199 else if ((imsg->Code == 0) || (imsg->Code == 9))
1201 if (imsg->Code == 0) ActivateGadget((struct Gadget *)udata->PathGad, ld->ld_Window, NULL);
1202 /* fall through to ID_STRDRAWER */
1204 else
1206 break;
1208 /* no break here!! */
1210 case ID_STRDRAWER:
1211 if (imsg->Code == STRINGCODE_CURSORUP)
1213 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, (struct Gadget *)udata->PathGad, AslBase);
1215 else if (imsg->Code == STRINGCODE_CURSORDOWN)
1217 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, (struct Gadget *)udata->PathGad, AslBase);
1219 else if ((imsg->Code == 0) || (imsg->Code == 9))
1221 UBYTE *dir;
1223 if ((imsg->Code == 0) && (gadid == ID_STRDRAWER))
1225 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY)
1227 retval = FRGetSelectedFiles(ld, ASLB(AslBase));
1228 break;
1229 } else {
1230 ActivateGadget((struct Gadget *)udata->FileGad, ld->ld_Window, NULL);
1233 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&dir);
1234 FRNewPath(dir, ld, AslBase);
1236 break;
1238 case ID_LISTVIEW:
1240 struct ASLLVFileReqNode *node;
1241 IPTR active;
1243 GetAttr(ASLLV_Active, udata->Listview, &active);
1245 if ((node = (struct ASLLVFileReqNode *)FindListNode(&udata->ListviewList, (WORD)active)))
1247 switch(node->type)
1249 case ASLLV_FRNTYPE_VOLUMES:
1250 FRNewPath((STRPTR)node->text[0], ld, AslBase);
1251 break;
1253 case ASLLV_FRNTYPE_DIRECTORY:
1254 if (node->subtype > 0)
1256 FRAddPath((STRPTR)node->text[0], ld, AslBase);
1257 } else {
1258 FRSetFile((STRPTR)node->text[0], ld, AslBase);
1260 if (imsg->Code) /* TRUE if double clicked */
1262 retval = FRGetSelectedFiles(ld, AslBase);
1265 break;
1267 } /* switch(node->type) */
1269 } /* if ((node = (struct ASLLVFileReqNode *)FindNode(&udata->ListviewList, (WORD)active))) */
1271 FRActivateMainStringGadget(ld, AslBase);
1274 break;
1276 } /* switch (gadget ID) */
1278 break; /* case IDCMP_GADGETUP: */
1280 case IDCMP_MENUPICK:
1281 if (ld->ld_Menu)
1283 UWORD men = imsg->Code;
1285 while(men != MENUNULL)
1287 struct MenuItem *item;
1288 BOOL resort = FALSE;
1290 if ((item = ItemAddress(ld->ld_Menu, men)))
1292 switch((IPTR)GTMENUITEM_USERDATA(item))
1294 /* Control menu */
1296 case FRMEN_LASTNAME:
1297 FRChangeActiveLVItem(ld, -1, 0, 0, AslBase);
1298 break;
1300 case FRMEN_NEXTNAME:
1301 FRChangeActiveLVItem(ld, 1, 0, 0, AslBase);
1302 break;
1304 case FRMEN_RESTORE:
1305 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS)
1307 FRSetPattern(ifreq->ifr_Pattern, ld, AslBase);
1309 if (!(ifreq->ifr_Flags2 & FRF_DRAWERSONLY))
1311 FRSetFile(ifreq->ifr_File, ld, AslBase);
1313 FRNewPath(ifreq->ifr_Drawer, ld, AslBase);
1314 break;
1316 case FRMEN_PARENT:
1317 FRParentPath(ld, AslBase);
1318 break;
1320 case FRMEN_VOLUMES:
1321 FRClickOnVolumes(ld, AslBase);
1322 break;
1324 case FRMEN_UPDATE:
1325 /* WARNING: a bit hacky */
1326 udata->Flags ^= FRFLG_SHOWING_VOLUMES;
1327 FRClickOnVolumes(ld, AslBase);
1328 break;
1330 case FRMEN_DELETE:
1331 FRDeleteRequester(ld, AslBase);
1332 break;
1334 case FRMEN_NEWDRAWER:
1335 FRNewDrawerRequester(ld, AslBase);
1336 break;
1338 case FRMEN_RENAME:
1339 FRRenameRequester(ld, AslBase);
1340 break;
1342 case FRMEN_SELECT:
1343 FRSelectRequester(ld, AslBase);
1344 break;
1346 case FRMEN_OK:
1347 retval = FRGetSelectedFiles(ld, ASLB(AslBase));
1348 break;
1350 case FRMEN_CANCEL:
1351 retval = FALSE;
1352 break;
1354 /* File list menu */
1356 case FRMEN_BYNAME:
1357 ifreq->ifr_SortBy = ASLFRSORTBY_Name;
1358 resort = TRUE;
1359 break;
1361 case FRMEN_BYDATE:
1362 ifreq->ifr_SortBy = ASLFRSORTBY_Date;
1363 resort = TRUE;
1364 break;
1366 case FRMEN_BYSIZE:
1367 ifreq->ifr_SortBy = ASLFRSORTBY_Size;
1368 resort = TRUE;
1369 break;
1371 case FRMEN_ASCENDING:
1372 ifreq->ifr_SortOrder = ASLFRSORTORDER_Ascend;
1373 resort = TRUE;
1374 break;
1376 case FRMEN_DESCENDING:
1377 ifreq->ifr_SortOrder = ASLFRSORTORDER_Descend;
1378 resort = TRUE;
1379 break;
1381 case FRMEN_DRAWERSFIRST:
1382 ifreq->ifr_SortDrawers = ASLFRSORTDRAWERS_First;
1383 resort = TRUE;
1384 break;
1386 case FRMEN_DRAWERSMIX:
1387 ifreq->ifr_SortDrawers = ASLFRSORTDRAWERS_Mix;
1388 resort = TRUE;
1389 break;
1391 case FRMEN_DRAWERSLAST:
1392 ifreq->ifr_SortDrawers = ASLFRSORTDRAWERS_Last;
1393 resort = TRUE;
1394 break;
1396 } /* switch id */
1398 if (resort)
1400 FRReSortListview(ld, AslBase);
1403 men = item->NextSelect;
1404 } /* if ((item = ItemAddress(ld->ld_Menu, men))) */
1405 else
1407 men = MENUNULL;
1410 } /* while(men != MENUNULL) */
1412 } /* if (ld->ld_Menu) */
1414 break; /* case IDCMP_MENUPICK: */
1416 } /* switch (imsg->Class) */
1418 ReturnInt ("FRHandleEvents", ULONG, retval);
1421 /*****************************************************************************************/
1423 STATIC VOID FRGadCleanup(struct LayoutData *ld, struct AslBase_intern *AslBase)
1425 struct FRUserData *udata;
1426 struct FileRequester *req;
1427 struct IntReq *intreq;
1429 EnterFunc(bug("FRGadCleanup(ld=%p)\n", ld));
1431 udata = (struct FRUserData *)ld->ld_UserData;
1432 req = (struct FileRequester *)ld->ld_Req;
1433 intreq = ld->ld_IntReq;
1435 if (ld->ld_Window && ld->ld_GList)
1437 RemoveGList(ld->ld_Window, ld->ld_GList, -1);
1440 FreeObjects(&FREQ_FIRST_OBJECT(udata), &FREQ_LAST_OBJECT(udata), AslBase);
1442 killscrollergadget(&udata->ScrollGad, AslBase);
1444 FRFreeListviewList(ld, AslBase);
1446 if (ld->ld_Window)
1448 req->fr_LeftEdge = intreq->ir_LeftEdge = ld->ld_Window->LeftEdge;
1449 req->fr_TopEdge = intreq->ir_TopEdge = ld->ld_Window->TopEdge;
1450 req->fr_Width = intreq->ir_Width = ld->ld_Window->Width;
1451 req->fr_Height = intreq->ir_Height = ld->ld_Window->Height;
1454 ReturnVoid("FRGadCleanup");
1457 /*****************************************************************************************/
1459 STATIC ULONG FRGetSelectedFiles(struct LayoutData *ld, struct AslBase_intern *AslBase)
1461 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
1462 struct IntReq *intreq = ld->ld_IntReq;
1463 struct IntFileReq *ifreq = (struct IntFileReq *)intreq;
1464 struct FileRequester *req = (struct FileRequester *)ld->ld_Req;
1465 char *name;
1467 ULONG retval = GHRET_OK;
1469 /* Kill possible old output variables from a previous AslRequest call
1470 on the same requester */
1472 #undef GetFR
1473 #define GetFR(r) ((struct FileRequester *)r)
1475 * must be done here and NOT in StripRequester
1477 MyFreeVecPooled(GetFR(req)->fr_Drawer, AslBase);
1478 GetFR(req)->fr_Drawer = NULL;
1480 MyFreeVecPooled(GetFR(req)->fr_File, AslBase);
1481 GetFR(req)->fr_File = NULL;
1483 MyFreeVecPooled(GetFR(req)->fr_Pattern, AslBase);
1484 GetFR(req)->fr_Pattern = NULL;
1486 StripRequester(req, ASL_FileRequest, AslBase);
1488 /* Save drawer string gadget text in fr_Drawer */
1490 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&name);
1491 if (!(req->fr_Drawer = VecPooledCloneString(name, NULL, intreq->ir_MemPool, AslBase))) goto bye;
1492 D(bug("FRGetSelectedFiles: fr_Drawer 0x%lx <%s>\n",req->fr_Drawer,req->fr_Drawer));
1493 ifreq->ifr_Drawer = req->fr_Drawer;
1495 /* Save file string gadget text in fr_File */
1497 if (!(ifreq->ifr_Flags2 & FRF_DRAWERSONLY))
1499 GetAttr(STRINGA_TextVal, udata->FileGad, (IPTR *)&name);
1501 if (!(req->fr_File = VecPooledCloneString(name, NULL, intreq->ir_MemPool, AslBase))) goto bye;
1502 D(bug("FRGetSelectedFiles: fr_File 0x%lx <%s>\n",req->fr_File,req->fr_File));
1503 ifreq->ifr_File = req->fr_File;
1506 /* Save pattern string gadget text in fr_Patterns */
1508 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS)
1510 GetAttr(STRINGA_TextVal, udata->PatternGad, (IPTR *)&name);
1512 if (!(req->fr_Pattern = VecPooledCloneString(name, NULL, intreq->ir_MemPool, AslBase))) goto bye;
1513 ifreq->ifr_Pattern = req->fr_Pattern;
1516 /* Create ArgList in case of ASLFR_DoMultiSelect requesters */
1518 req->fr_NumArgs = 0;
1520 if (ifreq->ifr_Flags1 & FRF_DOMULTISELECT)
1522 struct WBArg *wbarg;
1523 BPTR lock;
1525 if ((lock = Lock(req->fr_Drawer, ACCESS_READ)))
1527 WORD numargs, numselected = 0;
1529 if (!(udata->Flags & FRFLG_SHOWING_VOLUMES))
1531 numselected = CountNodes(&udata->ListviewList, NODEPRIF_SELECTED | NODEPRIF_MULTISEL);
1533 numargs = numselected > 0 ? numselected : 1;
1535 if ((wbarg = MyAllocVecPooled(intreq->ir_MemPool, sizeof(struct WBArg) * numargs, AslBase)))
1537 struct ASLLVFileReqNode *node;
1538 WORD i = 0;
1540 req->fr_ArgList = wbarg;
1542 ForeachNode(&udata->ListviewList, node)
1544 if (i == numselected) break;
1546 if ((node->node.ln_Pri & (NODEPRIF_SELECTED | NODEPRIF_MULTISEL)) == (NODEPRIF_SELECTED | NODEPRIF_MULTISEL))
1548 char *filename = node->text[0] ? node->text[0] : "";
1550 if ((wbarg->wa_Name = VecPooledCloneString(filename, NULL, intreq->ir_MemPool, AslBase)))
1552 wbarg->wa_Lock = lock;
1553 wbarg++;
1554 i++;
1558 } /* ForeachNode(&udata->ListviewList, node) */
1560 if (i == 0)
1562 if ((wbarg->wa_Name = VecPooledCloneString(req->fr_File, NULL, intreq->ir_MemPool, AslBase)))
1564 wbarg->wa_Lock = lock;
1565 i++;
1569 if (i == 0)
1571 MyFreeVecPooled(req->fr_ArgList, AslBase);
1572 req->fr_ArgList = NULL;
1573 } else {
1574 req->fr_NumArgs = i;
1575 lock = 0; /* clear lock to avoid that it is unlocked below */
1578 } /* if ((wbarg = MyAllocVecPooled(intreq->ir_MemPool, sizeof(struct WBArg) * numargs, AslBase))) */
1580 if (lock) UnLock(lock);
1582 } /* if ((lock = Lock(req->fr_Drawer, ACCESS_READ))) */
1584 } /* if (ifreq->ifr_Flags1 & FRF_DOMULTISELECT) */
1586 if (ifreq->ifr_GetSortBy) *ifreq->ifr_GetSortBy = ifreq->ifr_SortBy;
1587 if (ifreq->ifr_GetSortOrder) *ifreq->ifr_GetSortOrder = ifreq->ifr_SortOrder;
1588 if (ifreq->ifr_GetSortDrawers) *ifreq->ifr_GetSortDrawers = ifreq->ifr_SortDrawers;
1590 retval = GHRET_FINISHED_OK;
1592 bye:
1593 return retval;
1596 /*****************************************************************************************/