Properly navigate in drawers.
[AROS.git] / workbench / libs / asl / filereqhooks.c
blob7fa0afc6d6af25801957f34e751eee5bec9d1288
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 <proto/workbench.h>
16 #include <exec/memory.h>
17 #include <dos/dos.h>
18 #include <intuition/screens.h>
19 #include <intuition/icclass.h>
20 #include <intuition/gadgetclass.h>
21 #include <graphics/gfx.h>
22 #include <devices/rawkeycodes.h>
23 #include <libraries/gadtools.h>
24 #include <workbench/startup.h>
25 #include <string.h>
27 #include "asl_intern.h"
28 #include "filereqhooks.h"
29 #include "layout.h"
30 #include "filereqsupport.h"
31 #include "specialreq.h"
33 #if USE_SHARED_COOLIMAGES
34 #include <libraries/coolimages.h>
35 #include <proto/coolimages.h>
36 #else
37 #include "coolimages.h"
38 #endif
40 #define CATCOMP_NUMBERS
41 #include "strings.h"
43 #define SDEBUG 0
44 #define DEBUG 0
46 #include <aros/debug.h>
48 /*****************************************************************************************/
50 STATIC BOOL FRGadInit(struct LayoutData *, struct AslBase_intern *);
51 STATIC BOOL FRGadLayout(struct LayoutData *, struct AslBase_intern *);
52 STATIC VOID FRGadCleanup(struct LayoutData *, struct AslBase_intern *);
53 STATIC ULONG FRHandleAppWindow(struct LayoutData *, struct AslBase_intern *);
54 STATIC ULONG FRHandleEvents(struct LayoutData *, struct AslBase_intern *);
55 STATIC ULONG FRGetSelectedFiles(struct LayoutData *, struct AslBase_intern *AslBase);
57 /*****************************************************************************************/
59 #define ID_BUTOK ID_MAINBUTTON_OK
60 #define ID_BUTVOLUMES ID_MAINBUTTON_MIDDLELEFT
61 #define ID_BUTPARENT ID_MAINBUTTON_MIDDLERIGHT
62 #define ID_BUTCANCEL ID_MAINBUTTON_CANCEL
64 #define ID_LISTVIEW 1
65 #define ID_STRDRAWER 2
66 #define ID_STRPATTERN 3
67 #define ID_STRFILE 4
69 #undef NUMBUTS
70 #define NUMBUTS 4L
72 #define CLASS_ASLBASE ((struct AslBase_intern *)cl->cl_UserData)
73 #define HOOK_ASLBASE ((struct AslBase_intern *)hook->h_Data)
75 #define AslBase HOOK_ASLBASE
77 /*****************************************************************************************/
79 AROS_UFH3(IPTR, ASLFRRenderHook,
80 AROS_UFHA(struct Hook *, hook, A0),
81 AROS_UFHA(struct ASLLVFileReqNode *,node, A2),
82 AROS_UFHA(struct ASLLVDrawMsg *, msg, A1)
85 AROS_USERFUNC_INIT
87 IPTR retval;
89 if (msg->lvdm_MethodID == LV_DRAW)
91 struct DrawInfo *dri = msg->lvdm_DrawInfo;
92 struct RastPort *rp = msg->lvdm_RastPort;
94 WORD min_x = msg->lvdm_Bounds.MinX;
95 WORD min_y = msg->lvdm_Bounds.MinY;
96 WORD max_x = msg->lvdm_Bounds.MaxX;
97 WORD max_y = msg->lvdm_Bounds.MaxY;
99 UWORD erasepen = BACKGROUNDPEN;
100 UWORD textpen = TEXTPEN;
102 if (node) switch(node->type)
104 case ASLLV_FRNTYPE_DIRECTORY:
105 if (node->subtype > 0) textpen = SHINEPEN;
106 break;
107 case ASLLV_FRNTYPE_VOLUMES:
108 switch(node->subtype)
110 case DLT_DIRECTORY:
111 case DLT_LATE:
112 case DLT_NONBINDING:
113 textpen = SHINEPEN;
114 break;
116 break;
119 SetDrMd(rp, JAM1);
121 switch (msg->lvdm_State)
123 case ASLLVR_SELECTED:
124 erasepen = FILLPEN;
125 textpen = FILLTEXTPEN;
127 /* Fall through */
129 case ASLLVR_NORMAL:
131 WORD numfit;
132 struct TextExtent te;
134 SetAPen(rp, dri->dri_Pens[erasepen]);
135 RectFill(rp, min_x, min_y, max_x, max_y);
137 if (node)
139 struct LayoutData *ld = ((struct LayoutData *)node->userdata);
140 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
141 WORD i;
143 SetFont(rp, ld->ld_Font);
145 min_x += BORDERLVITEMSPACINGX;
146 min_y += BORDERLVITEMSPACINGY;
148 max_x -= BORDERLVITEMSPACINGX;
149 max_y -= BORDERLVITEMSPACINGY;
151 for(i = 0; i < ASLLV_MAXCOLUMNS;i++)
153 WORD x;
154 UWORD len;
156 if (node->text[i] == NULL) continue;
158 len = strlen(node->text[i]);
160 switch(udata->LVColumnAlign[i])
162 case ASLLV_ALIGN_RIGHT:
163 x = min_x + udata->LVColumnWidth[i] -
164 TextLength(rp, node->text[i], len);
165 break;
167 default:
168 x = min_x;
169 break;
172 if (x > max_x) break;
174 numfit = TextFit(rp,
175 node->text[i],
176 len,
177 &te,
178 NULL,
180 max_x - x + 1,
181 max_y - min_y + 1);
183 if (numfit < len) numfit++;
185 if (numfit < 1) break;
187 SetAPen(rp, dri->dri_Pens[textpen]);
189 /* Render text */
190 Move(rp, x, min_y + rp->Font->tf_Baseline);
191 Text(rp, node->text[i], numfit);
193 min_x += udata->LVColumnWidth[i] + rp->TxWidth * 2;
195 } /* for(i = 0; i < ASLLV_MAXCOLUMNS;i++) */
197 } /* if (node) */
199 } break;
201 } /* switch (msg->lvdm_State) */
203 retval = ASLLVCB_OK;
205 } /* if (msg->lvdm_MethodID == LV_DRAW) */
206 else
208 retval = ASLLVCB_UNKNOWN;
211 return retval;
213 AROS_USERFUNC_EXIT
216 /*****************************************************************************************/
218 #undef AslBase
220 /*****************************************************************************************/
222 AROS_UFH3(VOID, FRTagHook,
223 AROS_UFHA(struct Hook *, hook, A0),
224 AROS_UFHA(struct ParseTagArgs *, pta, A2),
225 AROS_UFHA(struct AslBase_intern *, AslBase, A1)
228 AROS_USERFUNC_INIT
230 struct TagItem *tag;
231 const struct TagItem *tstate;
232 struct IntFileReq *ifreq;
233 IPTR tidata;
235 EnterFunc(bug("FRTagHook(hook=%p, pta=%p)\n", hook, pta));
237 ifreq = (struct IntFileReq *)pta->pta_IntReq;
239 tstate = pta->pta_Tags;
240 while ((tag = NextTagItem(&tstate)) != NULL)
242 tidata = tag->ti_Data;
244 switch (tag->ti_Tag)
246 /* The tags that are put "in a row" are defined as the same value,
247 and therefor we only use one of them, but the effect is for all of them
249 case ASLFR_InitialDrawer:
250 /* case ASL_Dir: Obsolete */
251 if (tidata)
252 ifreq->ifr_Drawer = (STRPTR)tidata;
253 break;
255 case ASLFR_InitialFile:
256 /* case ASL_File: Obsolete */
257 if (tidata)
258 ifreq->ifr_File = (STRPTR)tidata;
259 break;
261 case ASLFR_InitialPattern:
262 /* case ASL_Pattern: Obsolete */
263 if (tidata)
264 ifreq->ifr_Pattern = (STRPTR)tidata;
265 break;
267 case ASLFR_UserData:
268 ((struct FileRequester *)pta->pta_Req)->fr_UserData = (APTR)tidata;
269 break;
271 /* Options */
273 case ASLFR_Flags1:
274 ifreq->ifr_Flags1 = (UBYTE)tidata;
275 /* Extract some flags that are common to all requester types and
276 put them into IntReq->ir_Flags
278 if (ifreq->ifr_Flags1 & FRF_PRIVATEIDCMP)
279 GetIR(ifreq)->ir_Flags |= IF_PRIVATEIDCMP;
280 else
281 GetIR(ifreq)->ir_Flags &= ~IF_PRIVATEIDCMP;
282 break;
284 case ASLFR_Flags2:
285 ifreq->ifr_Flags2 = (UBYTE)tidata;
286 break;
288 case ASLFR_DoSaveMode:
289 if (tidata)
290 ifreq->ifr_Flags1 |= FRF_DOSAVEMODE;
291 else
292 ifreq->ifr_Flags1 &= ~FRF_DOSAVEMODE;
293 break;
295 case ASLFR_DoMultiSelect:
296 if (tidata)
297 ifreq->ifr_Flags1 |= FRF_DOMULTISELECT;
298 else
299 ifreq->ifr_Flags1 &= ~FRF_DOMULTISELECT;
300 break;
302 case ASLFR_DoPatterns:
303 if (tidata)
304 ifreq->ifr_Flags1 |= FRF_DOPATTERNS;
305 else
306 ifreq->ifr_Flags1 &= ~FRF_DOPATTERNS;
307 break;
309 case ASLFR_DrawersOnly:
310 if (tidata)
311 ifreq->ifr_Flags2 |= FRF_DRAWERSONLY;
312 else
313 ifreq->ifr_Flags2 &= ~FRF_DRAWERSONLY;
314 break;
316 case ASLFR_FilterFunc:
317 ifreq->ifr_FilterFunc = (struct Hook *)tidata;
318 ifreq->ifr_Flags1 |= FRF_FILTERFUNC;
319 break;
321 case ASLFR_RejectIcons:
322 if (tidata)
323 ifreq->ifr_Flags2 |= FRF_REJECTICONS;
324 else
325 ifreq->ifr_Flags2 &= ~FRF_REJECTICONS;
326 break;
328 case ASLFR_RejectPattern:
329 if (tidata)
330 ifreq->ifr_RejectPattern = (STRPTR)tidata;
331 break;
333 case ASLFR_AcceptPattern:
334 if (tidata)
335 ifreq->ifr_AcceptPattern = (STRPTR)tidata;
336 break;
338 case ASLFR_FilterDrawers:
339 if (tidata)
340 ifreq->ifr_Flags2 |= FRF_FILTERDRAWERS;
341 else
342 ifreq->ifr_Flags2 &= ~FRF_FILTERDRAWERS;
343 break;
345 case ASLFR_HookFunc:
346 ifreq->ifr_HookFunc = (APTR)tidata;
347 break;
349 case ASLFR_SetSortBy:
350 ifreq->ifr_SortBy = tidata;
351 break;
353 case ASLFR_GetSortBy:
354 ifreq->ifr_GetSortBy = (ULONG *)tidata;
355 break;
357 case ASLFR_SetSortOrder:
358 ifreq->ifr_SortOrder = tidata;
359 break;
361 case ASLFR_GetSortOrder:
362 ifreq->ifr_GetSortOrder = (ULONG *)tidata;
363 break;
365 case ASLFR_SetSortDrawers:
366 ifreq->ifr_SortDrawers = tidata;
367 break;
369 case ASLFR_GetSortDrawers:
370 ifreq->ifr_GetSortDrawers = (ULONG *)tidata;
371 break;
373 case ASLFR_InitialShowVolumes:
374 ifreq->ifr_InitialShowVolumes = tidata ? TRUE : FALSE;
375 break;
377 default:
378 break;
380 } /* switch (tag->ti_Tag) */
382 } /* while ((tag = NextTagItem(&tstate)) != 0) */
384 /* DrawersOnly excludes multiselect */
386 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY)
388 ifreq->ifr_Flags1 &= ~FRF_DOMULTISELECT;
391 ReturnVoid("FRTagHook");
393 AROS_USERFUNC_EXIT
396 /*****************************************************************************************/
398 AROS_UFH3(ULONG, FRGadgetryHook,
399 AROS_UFHA(struct Hook *, hook, A0),
400 AROS_UFHA(struct LayoutData *, ld, A2),
401 AROS_UFHA(struct AslBase_intern *, AslBase, A1)
404 AROS_USERFUNC_INIT
406 ULONG retval;
408 switch (ld->ld_Command)
410 case LDCMD_INIT:
411 retval = (ULONG)FRGadInit(ld, ASLB(AslBase));
412 break;
414 case LDCMD_LAYOUT:
415 retval = (ULONG)FRGadLayout(ld, ASLB(AslBase));
416 break;
418 case LDCMD_HANDLEEVENTS:
419 retval = (ULONG)FRHandleEvents(ld, ASLB(AslBase));
420 break;
422 case LDCMD_HANDLEAPPWINDOW:
423 retval = (ULONG)FRHandleAppWindow(ld, ASLB(AslBase));
424 break;
426 case LDCMD_CLEANUP:
427 FRGadCleanup(ld, ASLB(AslBase));
428 retval = GHRET_OK;
429 break;
431 default:
432 retval = GHRET_FAIL;
433 break;
436 ReturnInt ("FRGadgetryHook(), retval", ULONG, retval);
438 AROS_USERFUNC_EXIT
441 /*****************************************************************************************/
443 struct ButtonInfo
445 WORD gadid;
446 char *text;
447 #if USE_SHARED_COOLIMAGES
448 ULONG coolid;
449 Object **objvar;
450 const struct CoolImage *coolimage;
451 #else
452 const struct CoolImage *coolimage;
453 Object **objvar;
454 #endif
457 /*****************************************************************************************/
459 STATIC BOOL FRGadInit(struct LayoutData *ld, struct AslBase_intern *AslBase)
461 struct FRUserData *udata = ld->ld_UserData;
462 struct IntFileReq *ifreq = (struct IntFileReq *)ld->ld_IntReq;
463 #if USE_SHARED_COOLIMAGES
464 ULONG okid = (GetIR(ifreq)->ir_Flags & IF_USER_POSTEXT) ? COOL_USEIMAGE_ID :
465 ((ifreq->ifr_Flags1 & FRF_DOSAVEMODE) ? COOL_SAVEIMAGE_ID :
466 COOL_LOADIMAGE_ID);
467 struct ButtonInfo bi[NUMBUTS] =
469 { ID_BUTOK , GetIR(ifreq)->ir_PositiveText , okid , &udata->OKBut },
470 { ID_BUTVOLUMES , NULL , COOL_DOTIMAGE_ID , &udata->VolumesBut },
471 { ID_BUTPARENT , NULL , COOL_DOTIMAGE_ID , &udata->ParentBut },
472 { ID_BUTCANCEL , GetIR(ifreq)->ir_NegativeText , COOL_CANCELIMAGE_ID , &udata->CancelBut }
474 #else
475 const struct CoolImage *okimage = (GetIR(ifreq)->ir_Flags & IF_USER_POSTEXT) ? &cool_useimage :
476 ((ifreq->ifr_Flags1 & FRF_DOSAVEMODE) ? &cool_saveimage :
477 &cool_loadimage);
478 struct ButtonInfo bi[NUMBUTS] =
480 { ID_BUTOK , GetIR(ifreq)->ir_PositiveText , okimage , &udata->OKBut },
481 { ID_BUTVOLUMES , NULL , &cool_dotimage , &udata->VolumesBut },
482 { ID_BUTPARENT , NULL , &cool_dotimage , &udata->ParentBut },
483 { ID_BUTCANCEL , GetIR(ifreq)->ir_NegativeText , &cool_cancelimage , &udata->CancelBut }
485 #endif
486 Object *gad;
487 STRPTR butstr[NUMBUTS];
488 LONG error = ERROR_NO_FREE_STORE;
489 WORD gadrows, x, y, w, h, i, y2 = 0;
491 NEWLIST(&udata->ListviewList);
493 udata->StringEditHook.h_Entry = (APTR)AROS_ASMSYMNAME(StringEditFunc);
494 udata->StringEditHook.h_SubEntry = NULL;
495 udata->StringEditHook.h_Data = AslBase;
497 udata->ListviewHook.h_Entry = (APTR)AROS_ASMSYMNAME(ASLFRRenderHook);
498 udata->ListviewHook.h_SubEntry = NULL;
499 udata->ListviewHook.h_Data = AslBase;
501 /* calc. min. size */
503 if (!bi[0].text) bi[0].text = GetString(MSG_FILEREQ_POSITIVE_GAD, GetIR(ifreq)->ir_Catalog, AslBase);
504 bi[1].text = GetString(MSG_FILEREQ_VOLUMES_GAD, GetIR(ifreq)->ir_Catalog, AslBase);
505 bi[2].text = GetString(MSG_FILEREQ_PARENT_GAD, GetIR(ifreq)->ir_Catalog, AslBase);
506 if (!bi[3].text) bi[3].text = GetString(MSG_FILEREQ_NEGATIVE_GAD, GetIR(ifreq)->ir_Catalog, AslBase);
509 w = 0;
510 for(i = 0; i < NUMBUTS; i++)
512 x = TextLength(&ld->ld_DummyRP, bi[i].text, strlen(bi[i].text));
514 #if FREQ_COOL_BUTTONS
515 #if USE_SHARED_COOLIMAGES
516 if (CoolImagesBase)
518 bi[i].coolimage = (const struct CoolImage *)COOL_ObtainImageA(bi[i].coolid, NULL);
521 if (CoolImagesBase)
522 #endif
523 if (ld->ld_TrueColor)
525 x += IMAGEBUTTONEXTRAWIDTH + bi[i].coolimage->width;
527 #endif
529 if (x > w) w = x;
532 udata->ButWidth = w + BUTTONEXTRAWIDTH;
534 ld->ld_ButWidth = udata->ButWidth;
535 ld->ld_NumButtons = 4;
537 #if FREQ_COOL_BUTTONS
539 #if USE_SHARED_COOLIMAGES
540 if (CoolImagesBase)
542 #endif
543 y = BUTTONEXTRAHEIGHT + ld->ld_Font->tf_YSize;
544 if (ld->ld_TrueColor)
546 y2 = IMAGEBUTTONEXTRAHEIGHT + DEF_COOLIMAGEHEIGHT;
547 } else {
548 y2 = 0;
550 udata->ButHeight = (y > y2) ? y : y2;
551 #if USE_SHARED_COOLIMAGES
553 else
555 udata->ButHeight = BUTTONEXTRAHEIGHT + ld->ld_Font->tf_YSize;
557 #endif
559 #else
560 udata->ButHeight = BUTTONEXTRAHEIGHT + ld->ld_Font->tf_YSize;
561 #endif
563 gadrows = 3; /* button row + file string + drawer string */
564 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS) gadrows++;
565 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY) gadrows--;
567 ld->ld_MinWidth = OUTERSPACINGX * 2 +
568 GADGETSPACINGX * 3 +
569 udata->ButWidth * NUMBUTS;
571 ld->ld_MinHeight = OUTERSPACINGY * 2 +
572 (GADGETSPACINGY + udata->ButHeight) * gadrows +
573 BORDERLVSPACINGY * 2 +
574 (ld->ld_Font->tf_YSize + BORDERLVITEMSPACINGY * 2) * FREQ_MIN_VISIBLELINES;
576 /* make listview gadget */
578 x = ld->ld_WBorLeft + OUTERSPACINGX;
579 y = ld->ld_WBorTop + OUTERSPACINGY;
580 w = -ld->ld_WBorRight - ld->ld_WBorLeft - OUTERSPACINGX * 2 - PROPSIZE;
581 h = -ld->ld_WBorBottom - ld->ld_WBorTop - OUTERSPACINGY * 2 -
582 udata->ButHeight * gadrows -
583 GADGETSPACINGY * gadrows;
586 struct TagItem lv_tags[] =
588 {GA_Left , x },
589 {GA_Top , y },
590 {GA_RelWidth , w },
591 {GA_RelHeight , h },
592 {GA_UserData , (IPTR)ld },
593 {GA_ID , ID_LISTVIEW },
594 {GA_RelVerify , TRUE },
595 {ASLLV_CallBack , (IPTR)&udata->ListviewHook },
596 {ASLLV_DoMultiSelect, (ifreq->ifr_Flags1 & FRF_DOMULTISELECT) },
597 {TAG_DONE }
600 udata->Listview = gad = NewObjectA(AslBase->asllistviewclass, NULL, lv_tags);
601 if (!udata->Listview) goto failure;
605 /* make scroller gadget for listview */
607 x = -ld->ld_WBorRight - OUTERSPACINGX - PROPSIZE + 1;
608 y = ld->ld_WBorTop + OUTERSPACINGY;
609 w = PROPSIZE;
610 h = -ld->ld_WBorBottom - ld->ld_WBorTop - OUTERSPACINGY * 2 -
611 udata->ButHeight * gadrows -
612 GADGETSPACINGY * gadrows;
614 struct TagItem scroller_tags[] =
616 {GA_RelRight , x },
617 {GA_Top , y },
618 {GA_Width , w },
619 {GA_RelHeight , h },
620 {GA_ID , ID_LISTVIEW },
621 {PGA_NewLook , TRUE },
622 {PGA_Borderless , TRUE },
623 {PGA_Freedom , FREEVERT },
624 {PGA_Top , 0 },
625 {PGA_Total , 20 },
626 {PGA_Visible , 1 },
627 {GA_Previous , (IPTR)gad },
628 {TAG_DONE }
631 if (!makescrollergadget(&udata->ScrollGad, ld, scroller_tags, AslBase)) goto failure;
632 gad = udata->ScrollGad.arrow2;
635 connectscrollerandlistview(&udata->ScrollGad, udata->Listview, AslBase);
637 /* make button row */
639 y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight + 1;
642 struct TagItem button_tags[] =
644 {GA_Text , 0 },
645 {GA_Previous , 0 },
646 {GA_ID , 0 },
647 #if FREQ_COOL_BUTTONS
648 {ASLBT_CoolImage , 0 },
649 #else
650 {TAG_IGNORE , 0 },
651 #endif
652 {GA_UserData , (IPTR)ld },
653 {GA_Left , 0 },
654 {GA_RelBottom , y },
655 {GA_Width , udata->ButWidth },
656 {GA_Height , udata->ButHeight },
657 {GA_RelVerify , TRUE },
658 {GA_Image , 0 }, /* means we want a frame */
659 {TAG_DONE }
662 for(i = 0; i < NUMBUTS; i++)
664 button_tags[0].ti_Data = (IPTR)bi[i].text;
665 button_tags[1].ti_Data = (IPTR)gad;
666 button_tags[2].ti_Data = bi[i].gadid;
668 #if USE_SHARED_COOLIMAGES
669 if (CoolImagesBase == NULL) button_tags[3].ti_Tag = TAG_IGNORE;
670 #endif
671 button_tags[3].ti_Data = (IPTR)bi[i].coolimage;
673 *(bi[i].objvar) = gad = NewObjectA(AslBase->aslbuttonclass, NULL, button_tags);
674 if (!gad) goto failure;
679 /* make labels */
682 struct LabelInfo
684 BOOL doit;
685 STRPTR text;
686 Object **objvar;
687 } li [] =
689 {TRUE, (STRPTR)MSG_FILEREQ_PATTERN_LABEL, &udata->PatternLabel },
690 {TRUE, (STRPTR)MSG_FILEREQ_DRAWER_LABEL , &udata->DrawerLabel },
691 {TRUE, (STRPTR)MSG_FILEREQ_FILE_LABEL , &udata->FileLabel }
694 struct TagItem label_tags[] =
696 {GA_Left , 0 },
697 {GA_RelBottom , 0 },
698 {GA_Width , 0 },
699 {GA_Height , udata->ButHeight },
700 {GA_Text , 0 },
701 {GA_Previous , (IPTR)gad },
702 {GA_UserData , (IPTR)ld },
703 {GA_Disabled , TRUE },
704 {TAG_DONE }
707 for(i = 0; i < 3; i++)
709 li[i].text = GetString((IPTR)li[i].text, GetIR(ifreq)->ir_Catalog, AslBase);
712 /* Drawer label is always there */
714 w = TextLength(&ld->ld_DummyRP, li[1].text, strlen(li[1].text)) +
715 LABELSPACINGX +
716 ld->ld_Font->tf_XSize * 2; /* Frame symbol showing directory scan activity */
718 i = 0;
719 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS)
721 butstr[i++] = li[0].text;
723 else
725 li[0].doit = FALSE;
728 if (!(ifreq->ifr_Flags2 & FRF_DRAWERSONLY))
730 butstr[i++] = li[2].text;
732 else
734 li[2].doit = FALSE;
737 if (i)
739 x = BiggestTextLength(butstr, i, &(ld->ld_DummyRP), AslBase);
740 if (x > w) w = x;
743 x = ld->ld_WBorLeft + OUTERSPACINGX;
744 y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight -
745 (udata->ButHeight + GADGETSPACINGY) * (gadrows - 1) + 1;
747 label_tags[1].ti_Data = y;
749 for(i = 0; i < 3;i++)
751 if (!li[i].doit) continue;
753 if (i == 1) y2 = y;
755 label_tags[2].ti_Data = TextLength(&ld->ld_DummyRP, li[i].text, strlen(li[i].text));
756 label_tags[0].ti_Data = x + w - label_tags[2].ti_Data;
757 label_tags[4].ti_Data = (IPTR)li[i].text;
758 label_tags[5].ti_Data = (IPTR)gad;
760 *(li[i].objvar) = gad = NewObjectA(AslBase->aslbuttonclass, NULL, label_tags);
761 if (!gad) goto failure;
763 y += udata->ButHeight + GADGETSPACINGY;
764 label_tags[1].ti_Data = y;
768 /* Directory Scan Symbol */
771 struct TagItem sym_tags[] =
773 {GA_Left , x },
774 {GA_RelBottom , y2 + 1 },
775 {GA_Width , ld->ld_Font->tf_XSize * 2 },
776 {GA_Height , udata->ButHeight - 2 },
777 {GA_Image , 0 }, /* means we want a frame */
778 {GA_Previous , (IPTR)gad },
779 {GA_Disabled , TRUE },
780 {GA_UserData , (IPTR)ld },
781 {TAG_DONE }
784 udata->DirectoryScanSymbol = gad = NewObjectA(AslBase->aslbuttonclass, NULL, sym_tags);
785 if (!udata->DirectoryScanSymbol) goto failure;
788 /* make string gadgets */
790 y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight -
791 (udata->ButHeight + GADGETSPACINGY) * (gadrows - 1) + 1;
792 x = ld->ld_WBorLeft + OUTERSPACINGX + w + LABELSPACINGX;
794 w = -ld->ld_WBorLeft - ld->ld_WBorRight - OUTERSPACINGX * 2 -
795 w - LABELSPACINGX;
798 struct StrInfo
800 WORD gadid;
801 char *text;
802 WORD maxchars;
803 Object **objvar;
804 } si [] =
806 {ID_STRPATTERN, ifreq->ifr_Pattern, MAX_PATTERN_LEN, &udata->PatternGad },
807 {ID_STRDRAWER , ifreq->ifr_Drawer , MAX_PATH_LEN , &udata->PathGad },
808 {ID_STRFILE , ifreq->ifr_File , MAX_FILE_LEN , &udata->FileGad },
811 struct TagItem string_tags[] =
813 {GA_Left , x },
814 {GA_RelBottom , y },
815 {GA_RelWidth , w },
816 {GA_Height , udata->ButHeight },
817 {GA_Previous , (IPTR)gad },
818 {STRINGA_TextVal , (IPTR)ifreq->ifr_Pattern },
819 {STRINGA_MaxChars , MAX_PATTERN_LEN },
820 {GA_ID , ID_STRPATTERN },
821 {GA_RelVerify , TRUE },
822 {GA_UserData , (IPTR)ld },
823 {GA_TabCycle , TRUE },
824 {STRINGA_EditHook , (IPTR)&udata->StringEditHook },
825 {STRINGA_Font , (IPTR)ld->ld_Font },
826 {TAG_DONE }
829 if (!(ifreq->ifr_Flags1 & FRF_DOPATTERNS)) si[0].gadid = 0;
830 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY) si[2].gadid = 0;
832 for(i = 0;i < 3; i++)
834 if (si[i].gadid == 0) continue;
836 string_tags[4].ti_Data = (IPTR)gad;
837 string_tags[5].ti_Data = (IPTR)si[i].text;
838 string_tags[6].ti_Data = si[i].maxchars;
839 string_tags[7].ti_Data = si[i].gadid;
841 *(si[i].objvar) = gad = NewObjectA(AslBase->aslstringclass, NULL, string_tags);
842 if (!gad) goto failure;
844 y += udata->ButHeight + GADGETSPACINGY;
845 string_tags[1].ti_Data = y;
849 #if AVOID_FLICKER
851 struct TagItem eraser_tags[] =
853 {GA_Previous, (IPTR)gad},
854 {TAG_DONE}
857 udata->EraserGad = gad = NewObjectA(AslBase->asleraserclass, NULL, eraser_tags);
858 /* Doesn't matter if this failed */
860 #endif
862 if (ifreq->ifr_InitialShowVolumes)
864 FRGetVolumes(ld, AslBase);
865 } else {
866 FRNewPath((STRPTR)ifreq->ifr_Drawer, ld, AslBase);
869 SetAttrs(udata->Listview, ASLLV_Labels, (IPTR)&udata->ListviewList,
870 TAG_DONE);
872 ld->ld_GList = (struct Gadget *)udata->Listview;
874 /* Menus */
876 struct NewMenu nm[] =
878 {NM_TITLE, (STRPTR)MSG_FILEREQ_MEN_CONTROL }, /* 0 */
879 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_LASTNAME , 0 , 0 , 0 , (APTR)FRMEN_LASTNAME }, /* 1 */
880 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_NEXTNAME , 0, 0 , 0 , (APTR)FRMEN_NEXTNAME }, /* 2 */
881 {NM_ITEM, NM_BARLABEL }, /* 3 */
882 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_RESTORE , 0, 0 , 0 , (APTR)FRMEN_RESTORE }, /* 4 */
883 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_PARENT , 0, 0 , 0 , (APTR)FRMEN_PARENT }, /* 5 */
884 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_VOLUMES , 0, 0 , 0 , (APTR)FRMEN_VOLUMES }, /* 6 */
885 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_UPDATE , 0, 0 , 0 , (APTR)FRMEN_UPDATE }, /* 7 */
886 {NM_ITEM, NM_BARLABEL }, /* 8 */
887 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_DELETE , 0, 0 , 0 , (APTR)FRMEN_DELETE }, /* 9 */
888 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_CREATEDRAWER , 0, 0 , 0 , (APTR)FRMEN_NEWDRAWER }, /* 10 */
889 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_RENAME , 0, 0 , 0 , (APTR)FRMEN_RENAME }, /* 11 */
890 {NM_ITEM, NM_BARLABEL }, /* 12 */
891 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_SELECT , 0, 0 , 0 , (APTR)FRMEN_SELECT }, /* 13 */
892 {NM_ITEM, NM_BARLABEL }, /* 14 */
893 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_OK , 0, 0 , 0 , (APTR)FRMEN_OK }, /* 15 */
894 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_CANCEL , 0, 0 , 0 , (APTR)FRMEN_CANCEL }, /* 16 */
895 {NM_TITLE, (STRPTR)MSG_FILEREQ_MEN_FILELIST }, /* 17 */
896 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTNAME , 0, CHECKIT , 2 + 4 , (APTR)FRMEN_BYNAME }, /* 18 */
897 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDATE , 0, CHECKIT , 1 + 4 , (APTR)FRMEN_BYDATE }, /* 19 */
898 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTSIZE , 0, CHECKIT , 1 + 2 , (APTR)FRMEN_BYSIZE }, /* 20 */
899 {NM_ITEM, NM_BARLABEL }, /* 21 */
900 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTUP , 0, CHECKIT , 32 , (APTR)FRMEN_ASCENDING }, /* 22 */
901 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDOWN , 0, CHECKIT , 16 , (APTR)FRMEN_DESCENDING }, /* 23 */
902 {NM_ITEM, NM_BARLABEL }, /* 24 */
903 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDRAWERFIRST , 0, CHECKIT , 256 + 512 , (APTR)FRMEN_DRAWERSFIRST }, /* 25 */
904 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDRAWERSAME , 0, CHECKIT , 128 + 512 , (APTR)FRMEN_DRAWERSMIX }, /* 26 */
905 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDRAWERLAST , 0, CHECKIT , 128 + 256 , (APTR)FRMEN_DRAWERSLAST }, /* 27 */
906 {NM_END } /* 28 */
909 struct TagItem menu_tags[] =
911 {GTMN_NewLookMenus , TRUE },
912 {GTMN_TextAttr , (IPTR)GetIR(ifreq)->ir_TextAttr },
913 {TAG_DONE }
916 if (menu_tags[1].ti_Data == 0) menu_tags[1].ti_Tag = TAG_IGNORE;
918 LocalizeMenus(nm, GetIR(ifreq)->ir_Catalog, AslBase);
920 nm[18 + ifreq->ifr_SortBy ].nm_Flags |= CHECKED;
921 nm[22 + ifreq->ifr_SortOrder ].nm_Flags |= CHECKED;
922 nm[25 + ifreq->ifr_SortDrawers].nm_Flags |= CHECKED;
924 /* Show "Select" menu item only if this is a multiselect file requester.
925 The orig Amiga asl.library disables (ghosts) the item, but why
926 show it if it cannot be used anyway. */
928 if (!(ifreq->ifr_Flags1 & FRF_DOMULTISELECT))
930 nm[13].nm_Type = NM_IGNORE;
931 nm[14].nm_Type = NM_IGNORE;
934 /* No Rename in drawersonly requesters */
936 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY)
938 nm[11].nm_Type = NM_IGNORE;
941 /* Don't fail, if menus cannot be created/layouted, because a requester
942 without menus is still better than no requester at all */
944 if ((ld->ld_Menu = CreateMenusA(nm, NULL)))
946 if (!LayoutMenusA(ld->ld_Menu, ld->ld_VisualInfo, menu_tags))
948 FreeMenus(ld->ld_Menu);ld->ld_Menu = NULL;
953 SetIoErr(0);
955 ReturnBool ("FRGadInit", TRUE);
957 failure:
958 D(bug("failure\n"));
960 FRGadCleanup(ld, ASLB(AslBase));
962 SetIoErr(error);
964 ReturnBool ("FRGadInit", FALSE);
968 /*****************************************************************************************/
970 STATIC BOOL FRGadLayout(struct LayoutData *ld, struct AslBase_intern *AslBase)
972 FRActivateMainStringGadget(ld, AslBase);
974 ReturnBool ("FRGadLayout", TRUE );
977 /*****************************************************************************************/
979 STATIC VOID FRClickOnVolumes(struct LayoutData *ld, struct AslBase_intern *AslBase)
981 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
983 if (udata->Flags & FRFLG_SHOWING_VOLUMES)
985 union
987 UBYTE *dir;
988 IPTR baz;
989 } foo;
991 GetAttr(STRINGA_TextVal, udata->PathGad, &foo.baz);
992 FRGetDirectory(foo.dir, ld, AslBase);
993 } else {
994 FRGetVolumes(ld, AslBase);
998 /*****************************************************************************************/
1000 STATIC ULONG FRHandleAppWindow(struct LayoutData *ld, struct AslBase_intern *AslBase)
1002 ULONG retval = GHRET_FAIL;
1003 char pathbuffer[MAX_PATH_LEN];
1005 if (ld->ld_AppMsg && (ld->ld_AppMsg->am_Type == AMTYPE_APPWINDOW))
1007 /* FIXME: Should we handle multiple droped icons in case of multiselect requester? */
1008 if (ld->ld_AppMsg->am_NumArgs >= 1)
1010 if (ld->ld_AppMsg->am_ArgList->wa_Lock)
1012 NameFromLock(ld->ld_AppMsg->am_ArgList->wa_Lock, pathbuffer, MAX_PATH_LEN);
1013 FRNewPath(pathbuffer, ld, AslBase);
1015 if (ld->ld_AppMsg->am_ArgList->wa_Name)
1017 FRSetFile(ld->ld_AppMsg->am_ArgList->wa_Name, ld, AslBase);
1019 retval = GHRET_OK;
1022 ReturnInt ("FRHandleEvents(), retval", ULONG, retval);
1025 /*****************************************************************************************/
1027 STATIC ULONG FRHandleEvents(struct LayoutData *ld, struct AslBase_intern *AslBase)
1029 struct IntuiMessage *imsg;
1030 ULONG retval = GHRET_OK;
1031 struct FRUserData *udata;
1032 struct IntFileReq *ifreq;
1033 WORD gadid;
1035 // EnterFunc(bug("FRHandleEvents: Class: %d\n", imsg->Class));
1037 udata = (struct FRUserData *)ld->ld_UserData;
1038 ifreq = (struct IntFileReq *)ld->ld_IntReq;
1041 if ((imsg = ld->ld_Event))
1043 D(bug("[ASL] FRHandleEvents() imsg->Code = '%d'\n", imsg->Code));
1044 switch (imsg->Class)
1046 case IDCMP_CLOSEWINDOW:
1047 retval = FALSE;
1048 break;
1050 case IDCMP_MOUSEBUTTONS:
1051 FRActivateMainStringGadget(ld, AslBase);
1052 break;
1054 case IDCMP_RAWKEY:
1055 switch (imsg->Code)
1057 case CURSORUP:
1058 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, 0, AslBase);
1059 break;
1061 case RAWKEY_PAGEUP:
1062 FRChangeActiveLVItem(ld, -1, IEQUALIFIER_LSHIFT, 0, AslBase);
1063 break;
1065 case RAWKEY_HOME:
1066 FRChangeActiveLVItem(ld, -1, IEQUALIFIER_LALT, 0, AslBase);
1067 break;
1069 case RAWKEY_NM_WHEEL_UP:
1070 FRChangeActiveLVItem(ld, -3, imsg->Qualifier, 0, AslBase);
1071 break;
1073 case CURSORDOWN:
1074 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, 0, AslBase);
1075 break;
1077 case RAWKEY_PAGEDOWN:
1078 FRChangeActiveLVItem(ld, 1, IEQUALIFIER_LSHIFT, 0, AslBase);
1079 break;
1081 case RAWKEY_END:
1082 FRChangeActiveLVItem(ld, 1, IEQUALIFIER_LALT, 0, AslBase);
1083 break;
1085 case RAWKEY_NM_WHEEL_DOWN:
1086 FRChangeActiveLVItem(ld, 3, imsg->Qualifier, 0, AslBase);
1087 break;
1090 break;
1092 case IDCMP_VANILLAKEY:
1093 switch(imsg->Code)
1095 case 27: /* ESC */
1096 retval = FALSE;
1097 break;
1099 break;
1101 case IDCMP_GADGETUP:
1102 gadid = ((struct Gadget *)imsg->IAddress)->GadgetID;
1104 D(bug("GADGETUP! gadgetid=%d\n", gadid));
1106 switch (gadid)
1108 case ID_BUTCANCEL:
1109 retval = FALSE;
1110 break;
1112 case ID_BUTVOLUMES:
1113 FRClickOnVolumes(ld, AslBase);
1114 break;
1116 case ID_BUTPARENT:
1117 FRParentPath(ld, AslBase);
1118 break;
1120 case ID_STRFILE:
1121 if (imsg->Code == STRINGCODE_CURSORUP)
1123 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, (struct Gadget *)udata->FileGad, AslBase);
1124 break;
1126 else if (imsg->Code == STRINGCODE_CURSORDOWN)
1128 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, (struct Gadget *)udata->FileGad, AslBase);
1129 break;
1131 else if ((imsg->Code == 0) || (imsg->Code == 9))
1133 char filestring[MAX_FILE_LEN], checkstring[MAX_FILE_LEN], *file;
1134 BOOL fall_through = (imsg->Code == 9) ? FALSE : TRUE;
1135 BOOL has_colon = FALSE;
1136 BOOL has_slash = FALSE;
1138 GetAttr(STRINGA_TextVal, udata->FileGad, (IPTR *)&file);
1139 strcpy(filestring, file);
1141 has_colon = strchr(filestring, ':') ? TRUE : FALSE;
1142 has_slash = strchr(filestring, '/') ? TRUE : FALSE;
1144 if (has_colon || has_slash)
1146 fall_through = FALSE;
1148 if (strcmp(filestring, ":") == 0)
1150 FRNewPath(filestring, ld, AslBase);
1151 FRSetFile("", ld, AslBase);
1152 } else if (stricmp(filestring, "/") == 0)
1154 FRParentPath(ld, AslBase);
1155 FRSetFile("", ld, AslBase);
1156 } else {
1157 BPTR lock;
1158 BOOL isfile = TRUE;
1160 if (has_colon)
1162 strcpy(checkstring, filestring);
1163 } else {
1164 char *dir;
1166 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&dir);
1168 strcpy(checkstring, dir);
1169 AddPart(checkstring, filestring, MAX_FILE_LEN);
1172 if ((lock = Lock(checkstring, ACCESS_READ)))
1174 struct FileInfoBlock *fib;
1176 if ((fib = AllocDosObject(DOS_FIB, NULL)))
1178 if (Examine(lock, fib))
1180 if (fib->fib_DirEntryType > 0) isfile = FALSE;
1182 FreeDosObject(DOS_FIB, fib);
1184 UnLock(lock);
1187 if (isfile)
1189 char *fp = FilePart(checkstring);
1190 char fpc = *fp;
1192 *fp = '\0';
1193 FRNewPath(checkstring, ld, AslBase);
1195 *fp = fpc;
1196 FRSetFile(fp, ld, AslBase);
1198 } else {
1199 FRAddPath(filestring, ld, AslBase);
1200 FRSetFile("", ld, AslBase);
1204 ActivateGadget((struct Gadget *)udata->FileGad, ld->ld_Window, NULL);
1206 } /* has colon or slash */
1208 if (!fall_through) break;
1210 } /* if ((imsg->Code == 0) || (imsg->Code == 9)) */
1211 else
1213 break;
1216 /* fall through */
1218 case ID_BUTOK:
1219 retval = FRGetSelectedFiles(ld, ASLB(AslBase));
1220 break;
1222 case ID_STRPATTERN:
1223 if (imsg->Code == STRINGCODE_CURSORUP)
1225 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, (struct Gadget *)udata->PatternGad, AslBase);
1226 break;
1228 else if (imsg->Code == STRINGCODE_CURSORDOWN)
1230 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, (struct Gadget *)udata->PatternGad, AslBase);
1231 break;
1233 else if ((imsg->Code == 0) || (imsg->Code == 9))
1235 if (imsg->Code == 0) ActivateGadget((struct Gadget *)udata->PathGad, ld->ld_Window, NULL);
1236 /* fall through to ID_STRDRAWER */
1238 else
1240 break;
1242 /* no break here!! */
1244 case ID_STRDRAWER:
1245 if (imsg->Code == STRINGCODE_CURSORUP)
1247 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, (struct Gadget *)udata->PathGad, AslBase);
1249 else if (imsg->Code == STRINGCODE_CURSORDOWN)
1251 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, (struct Gadget *)udata->PathGad, AslBase);
1253 else if ((imsg->Code == 0) || (imsg->Code == 9))
1255 UBYTE *dir;
1257 if ((imsg->Code == 0) && (gadid == ID_STRDRAWER))
1259 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY)
1261 retval = FRGetSelectedFiles(ld, ASLB(AslBase));
1262 break;
1263 } else {
1264 ActivateGadget((struct Gadget *)udata->FileGad, ld->ld_Window, NULL);
1267 GetAttr(STRINGA_TextVal, udata->FileGad, (IPTR *)&dir);
1268 FRAddPath(dir, ld, AslBase);
1269 FRSetFile("", ld, AslBase);
1271 break;
1273 case ID_LISTVIEW:
1275 struct ASLLVFileReqNode *node;
1276 IPTR active;
1278 GetAttr(ASLLV_Active, udata->Listview, &active);
1280 if ((node = (struct ASLLVFileReqNode *)FindListNode(&udata->ListviewList, (WORD)active)))
1282 switch(node->type)
1284 case ASLLV_FRNTYPE_VOLUMES:
1285 FRNewPath((STRPTR)node->text[0], ld, AslBase);
1286 break;
1288 case ASLLV_FRNTYPE_DIRECTORY:
1289 if (node->subtype > 0)
1291 FRAddPath((STRPTR)node->text[0], ld, AslBase);
1292 } else {
1293 FRSetFile((STRPTR)node->text[0], ld, AslBase);
1295 if (imsg->Code) /* TRUE if double clicked */
1297 retval = FRGetSelectedFiles(ld, AslBase);
1300 break;
1302 } /* switch(node->type) */
1304 } /* if ((node = (struct ASLLVFileReqNode *)FindNode(&udata->ListviewList, (WORD)active))) */
1306 FRActivateMainStringGadget(ld, AslBase);
1309 break;
1311 } /* switch (gadget ID) */
1313 break; /* case IDCMP_GADGETUP: */
1315 case IDCMP_MENUPICK:
1316 if (ld->ld_Menu)
1318 UWORD men = imsg->Code;
1320 while(men != MENUNULL)
1322 struct MenuItem *item;
1323 BOOL resort = FALSE;
1325 if ((item = ItemAddress(ld->ld_Menu, men)))
1327 switch((IPTR)GTMENUITEM_USERDATA(item))
1329 /* Control menu */
1331 case FRMEN_LASTNAME:
1332 FRChangeActiveLVItem(ld, -1, 0, 0, AslBase);
1333 break;
1335 case FRMEN_NEXTNAME:
1336 FRChangeActiveLVItem(ld, 1, 0, 0, AslBase);
1337 break;
1339 case FRMEN_RESTORE:
1340 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS)
1342 FRSetPattern(ifreq->ifr_Pattern, ld, AslBase);
1344 if (!(ifreq->ifr_Flags2 & FRF_DRAWERSONLY))
1346 FRSetFile(ifreq->ifr_File, ld, AslBase);
1348 FRNewPath(ifreq->ifr_Drawer, ld, AslBase);
1349 break;
1351 case FRMEN_PARENT:
1352 FRParentPath(ld, AslBase);
1353 break;
1355 case FRMEN_VOLUMES:
1356 FRClickOnVolumes(ld, AslBase);
1357 break;
1359 case FRMEN_UPDATE:
1360 /* WARNING: a bit hacky */
1361 udata->Flags ^= FRFLG_SHOWING_VOLUMES;
1362 FRClickOnVolumes(ld, AslBase);
1363 break;
1365 case FRMEN_DELETE:
1366 FRDeleteRequester(ld, AslBase);
1367 break;
1369 case FRMEN_NEWDRAWER:
1370 FRNewDrawerRequester(ld, AslBase);
1371 break;
1373 case FRMEN_RENAME:
1374 FRRenameRequester(ld, AslBase);
1375 break;
1377 case FRMEN_SELECT:
1378 FRSelectRequester(ld, AslBase);
1379 break;
1381 case FRMEN_OK:
1382 retval = FRGetSelectedFiles(ld, ASLB(AslBase));
1383 break;
1385 case FRMEN_CANCEL:
1386 retval = FALSE;
1387 break;
1389 /* File list menu */
1391 case FRMEN_BYNAME:
1392 ifreq->ifr_SortBy = ASLFRSORTBY_Name;
1393 resort = TRUE;
1394 break;
1396 case FRMEN_BYDATE:
1397 ifreq->ifr_SortBy = ASLFRSORTBY_Date;
1398 resort = TRUE;
1399 break;
1401 case FRMEN_BYSIZE:
1402 ifreq->ifr_SortBy = ASLFRSORTBY_Size;
1403 resort = TRUE;
1404 break;
1406 case FRMEN_ASCENDING:
1407 ifreq->ifr_SortOrder = ASLFRSORTORDER_Ascend;
1408 resort = TRUE;
1409 break;
1411 case FRMEN_DESCENDING:
1412 ifreq->ifr_SortOrder = ASLFRSORTORDER_Descend;
1413 resort = TRUE;
1414 break;
1416 case FRMEN_DRAWERSFIRST:
1417 ifreq->ifr_SortDrawers = ASLFRSORTDRAWERS_First;
1418 resort = TRUE;
1419 break;
1421 case FRMEN_DRAWERSMIX:
1422 ifreq->ifr_SortDrawers = ASLFRSORTDRAWERS_Mix;
1423 resort = TRUE;
1424 break;
1426 case FRMEN_DRAWERSLAST:
1427 ifreq->ifr_SortDrawers = ASLFRSORTDRAWERS_Last;
1428 resort = TRUE;
1429 break;
1431 } /* switch id */
1433 if (resort)
1435 FRReSortListview(ld, AslBase);
1438 men = item->NextSelect;
1439 } /* if ((item = ItemAddress(ld->ld_Menu, men))) */
1440 else
1442 men = MENUNULL;
1445 } /* while(men != MENUNULL) */
1447 } /* if (ld->ld_Menu) */
1449 break; /* case IDCMP_MENUPICK: */
1451 } /* switch (imsg->Class) */
1452 } /* if((imsg = ld->ld_Event)) */
1454 ReturnInt ("FRHandleEvents", ULONG, retval);
1457 /*****************************************************************************************/
1459 STATIC VOID FRGadCleanup(struct LayoutData *ld, struct AslBase_intern *AslBase)
1461 struct FRUserData *udata;
1462 struct FileRequester *req;
1463 struct IntReq *intreq;
1465 EnterFunc(bug("FRGadCleanup(ld=%p)\n", ld));
1467 udata = (struct FRUserData *)ld->ld_UserData;
1468 req = (struct FileRequester *)ld->ld_Req;
1469 intreq = ld->ld_IntReq;
1471 if (ld->ld_Window && ld->ld_GList)
1473 RemoveGList(ld->ld_Window, ld->ld_GList, -1);
1476 FreeObjects(&FREQ_FIRST_OBJECT(udata), &FREQ_LAST_OBJECT(udata), AslBase);
1478 killscrollergadget(&udata->ScrollGad, AslBase);
1480 FRFreeListviewList(ld, AslBase);
1482 if (ld->ld_Window)
1484 req->fr_LeftEdge = intreq->ir_LeftEdge = ld->ld_Window->LeftEdge;
1485 req->fr_TopEdge = intreq->ir_TopEdge = ld->ld_Window->TopEdge;
1486 req->fr_Width = intreq->ir_Width = ld->ld_Window->Width;
1487 req->fr_Height = intreq->ir_Height = ld->ld_Window->Height;
1490 ReturnVoid("FRGadCleanup");
1493 /*****************************************************************************************/
1495 STATIC ULONG FRGetSelectedFiles(struct LayoutData *ld, struct AslBase_intern *AslBase)
1497 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
1498 struct IntReq *intreq = ld->ld_IntReq;
1499 struct IntFileReq *ifreq = (struct IntFileReq *)intreq;
1500 struct FileRequester *req = (struct FileRequester *)ld->ld_Req;
1501 char *name;
1503 ULONG retval = GHRET_OK;
1505 /* Kill possible old output variables from a previous AslRequest call
1506 on the same requester */
1508 #undef GetFR
1509 #define GetFR(r) ((struct FileRequester *)r)
1511 * must be done here and NOT in StripRequester
1513 MyFreeVecPooled(GetFR(req)->fr_Drawer, AslBase);
1514 GetFR(req)->fr_Drawer = NULL;
1516 MyFreeVecPooled(GetFR(req)->fr_File, AslBase);
1517 GetFR(req)->fr_File = NULL;
1519 MyFreeVecPooled(GetFR(req)->fr_Pattern, AslBase);
1520 GetFR(req)->fr_Pattern = NULL;
1522 StripRequester(req, ASL_FileRequest, AslBase);
1524 /* Save drawer string gadget text in fr_Drawer */
1526 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&name);
1527 if (!(req->fr_Drawer = VecPooledCloneString(name, NULL, intreq->ir_MemPool, AslBase))) goto bye;
1528 D(bug("FRGetSelectedFiles: fr_Drawer 0x%lx <%s>\n",req->fr_Drawer,req->fr_Drawer));
1529 ifreq->ifr_Drawer = req->fr_Drawer;
1531 /* Save file string gadget text in fr_File */
1533 if (!(ifreq->ifr_Flags2 & FRF_DRAWERSONLY))
1535 GetAttr(STRINGA_TextVal, udata->FileGad, (IPTR *)&name);
1537 if (!(req->fr_File = VecPooledCloneString(name, NULL, intreq->ir_MemPool, AslBase))) goto bye;
1538 D(bug("FRGetSelectedFiles: fr_File 0x%lx <%s>\n",req->fr_File,req->fr_File));
1539 ifreq->ifr_File = req->fr_File;
1542 /* Save pattern string gadget text in fr_Patterns */
1544 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS)
1546 GetAttr(STRINGA_TextVal, udata->PatternGad, (IPTR *)&name);
1548 if (!(req->fr_Pattern = VecPooledCloneString(name, NULL, intreq->ir_MemPool, AslBase))) goto bye;
1549 ifreq->ifr_Pattern = req->fr_Pattern;
1552 /* Create ArgList in case of ASLFR_DoMultiSelect requesters */
1554 req->fr_NumArgs = 0;
1556 if (ifreq->ifr_Flags1 & FRF_DOMULTISELECT)
1558 struct WBArg *wbarg;
1559 BPTR lock;
1561 if ((lock = Lock(req->fr_Drawer, ACCESS_READ)))
1563 WORD numargs, numselected = 0;
1565 if (!(udata->Flags & FRFLG_SHOWING_VOLUMES))
1567 numselected = CountNodes(&udata->ListviewList, NODEPRIF_SELECTED | NODEPRIF_MULTISEL);
1569 numargs = numselected > 0 ? numselected : 1;
1571 if ((wbarg = MyAllocVecPooled(intreq->ir_MemPool, sizeof(struct WBArg) * numargs, AslBase)))
1573 struct ASLLVFileReqNode *node;
1574 WORD i = 0;
1576 req->fr_ArgList = wbarg;
1578 ForeachNode(&udata->ListviewList, node)
1580 if (i == numselected) break;
1582 if ((node->node.ln_Pri & (NODEPRIF_SELECTED | NODEPRIF_MULTISEL)) == (NODEPRIF_SELECTED | NODEPRIF_MULTISEL))
1584 char *filename = node->text[0] ? node->text[0] : "";
1586 if ((wbarg->wa_Name = VecPooledCloneString(filename, NULL, intreq->ir_MemPool, AslBase)))
1588 wbarg->wa_Lock = lock;
1589 wbarg++;
1590 i++;
1594 } /* ForeachNode(&udata->ListviewList, node) */
1596 if (i == 0)
1598 if ((wbarg->wa_Name = VecPooledCloneString(req->fr_File, NULL, intreq->ir_MemPool, AslBase)))
1600 wbarg->wa_Lock = lock;
1601 i++;
1605 if (i == 0)
1607 MyFreeVecPooled(req->fr_ArgList, AslBase);
1608 req->fr_ArgList = NULL;
1609 } else {
1610 req->fr_NumArgs = i;
1611 lock = 0; /* clear lock to avoid that it is unlocked below */
1614 } /* if ((wbarg = MyAllocVecPooled(intreq->ir_MemPool, sizeof(struct WBArg) * numargs, AslBase))) */
1616 if (lock) UnLock(lock);
1618 } /* if ((lock = Lock(req->fr_Drawer, ACCESS_READ))) */
1620 } /* if (ifreq->ifr_Flags1 & FRF_DOMULTISELECT) */
1622 if (ifreq->ifr_GetSortBy) *ifreq->ifr_GetSortBy = ifreq->ifr_SortBy;
1623 if (ifreq->ifr_GetSortOrder) *ifreq->ifr_GetSortOrder = ifreq->ifr_SortOrder;
1624 if (ifreq->ifr_GetSortDrawers) *ifreq->ifr_GetSortDrawers = ifreq->ifr_SortDrawers;
1626 retval = GHRET_FINISHED_OK;
1628 bye:
1629 return retval;
1632 /*****************************************************************************************/