minor simplification.
[AROS.git] / workbench / libs / asl / filereqhooks.c
blobeaf23994259a6dcfe9b489836b0f798736621797
1 /*
2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
3 $Id$
5 File requester specific code.
6 */
9 #include <aros/atomic.h>
10 #include <proto/exec.h>
11 #include <proto/dos.h>
12 #include <proto/utility.h>
13 #include <proto/intuition.h>
14 #include <proto/graphics.h>
15 #include <proto/gadtools.h>
16 #include <proto/workbench.h>
17 #include <exec/memory.h>
18 #include <dos/dos.h>
19 #include <intuition/screens.h>
20 #include <intuition/icclass.h>
21 #include <intuition/gadgetclass.h>
22 #include <graphics/gfx.h>
23 #include <devices/rawkeycodes.h>
24 #include <libraries/gadtools.h>
25 #include <workbench/startup.h>
26 #include <string.h>
28 #include "asl_intern.h"
29 #include "filereqhooks.h"
30 #include "layout.h"
31 #include "filereqsupport.h"
32 #include "specialreq.h"
34 #if USE_SHARED_COOLIMAGES
35 #include <libraries/coolimages.h>
36 #include <proto/coolimages.h>
37 #else
38 #include "coolimages.h"
39 #endif
41 #define CATCOMP_NUMBERS
42 #include "strings.h"
44 #define SDEBUG 0
45 #define DEBUG 0
47 #include <aros/debug.h>
49 /*****************************************************************************************/
51 STATIC BOOL FRWindowOpened(struct LayoutData *, struct AslBase_intern *);
52 STATIC BOOL FRGadInit(struct LayoutData *, struct AslBase_intern *);
53 STATIC BOOL FRGadLayout(struct LayoutData *, struct AslBase_intern *);
54 STATIC VOID FRGadCleanup(struct LayoutData *, struct AslBase_intern *);
55 STATIC ULONG FRHandleAppWindow(struct LayoutData *, struct AslBase_intern *);
56 STATIC ULONG FRHandleEvents(struct LayoutData *, struct AslBase_intern *);
57 STATIC ULONG FRGetSelectedFiles(struct LayoutData *, struct AslBase_intern *AslBase);
59 /*****************************************************************************************/
61 #define ID_BUTOK ID_MAINBUTTON_OK
62 #define ID_BUTVOLUMES ID_MAINBUTTON_MIDDLELEFT
63 #define ID_BUTPARENT ID_MAINBUTTON_MIDDLERIGHT
64 #define ID_BUTCANCEL ID_MAINBUTTON_CANCEL
66 #define ID_LISTVIEW 1
67 #define ID_STRDRAWER 2
68 #define ID_STRPATTERN 3
69 #define ID_STRFILE 4
71 #undef NUMBUTS
72 #define NUMBUTS 4L
74 #define CLASS_ASLBASE ((struct AslBase_intern *)cl->cl_UserData)
75 #define HOOK_ASLBASE ((struct AslBase_intern *)hook->h_Data)
77 #define AslBase HOOK_ASLBASE
79 /*****************************************************************************************/
81 AROS_UFH3(IPTR, ASLFRRenderHook,
82 AROS_UFHA(struct Hook * , hook, A0),
83 AROS_UFHA(struct ASLLVFileReqNode *, node, A2),
84 AROS_UFHA(struct ASLLVDrawMsg * , msg , A1)
87 AROS_USERFUNC_INIT
89 IPTR retval;
91 if (msg->lvdm_MethodID == LV_DRAW)
93 struct DrawInfo *dri = msg->lvdm_DrawInfo;
94 struct RastPort *rp = msg->lvdm_RastPort;
95 struct LayoutData *ld = NULL;
97 WORD min_x = msg->lvdm_Bounds.MinX;
98 WORD min_y = msg->lvdm_Bounds.MinY;
99 WORD max_x = msg->lvdm_Bounds.MaxX;
100 WORD max_y = msg->lvdm_Bounds.MaxY;
101 BOOL savemode = FALSE;
103 if (node)
104 ld = ((struct LayoutData *)node->userdata);
106 if (ld && (((struct IntFileReq *)ld->ld_IntReq)->ifr_Flags1 & FRF_DOSAVEMODE))
107 savemode = TRUE;
109 UWORD erasepen = savemode ? TEXTPEN : BACKGROUNDPEN;
110 UWORD textpen = savemode ? BACKGROUNDPEN : TEXTPEN;
112 if (node) switch(node->type)
114 case ASLLV_FRNTYPE_DIRECTORY:
115 if (node->subtype > 0)
116 textpen = SHINEPEN;
117 break;
118 case ASLLV_FRNTYPE_VOLUMES:
119 switch(node->subtype)
121 case DLT_DIRECTORY:
122 case DLT_LATE:
123 case DLT_NONBINDING:
124 textpen = SHINEPEN;
125 break;
127 break;
130 SetDrMd(rp, JAM1);
132 switch (msg->lvdm_State)
134 case ASLLVR_SELECTED:
135 erasepen = FILLPEN;
136 textpen = FILLTEXTPEN;
138 /* Fall through */
140 case ASLLVR_NORMAL:
142 WORD numfit;
143 struct TextExtent te;
145 SetAPen(rp, dri->dri_Pens[erasepen]);
146 RectFill(rp, min_x, min_y, max_x, max_y);
148 if (node)
150 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
151 WORD i;
153 SetFont(rp, ld->ld_Font);
155 min_x += BORDERLVITEMSPACINGX;
156 min_y += BORDERLVITEMSPACINGY;
158 max_x -= BORDERLVITEMSPACINGX;
159 max_y -= BORDERLVITEMSPACINGY;
161 for(i = 0; i < ASLLV_MAXCOLUMNS;i++)
163 WORD x;
164 UWORD len;
166 if (node->text[i] == NULL)
167 continue;
169 len = strlen(node->text[i]);
171 switch(udata->LVColumnAlign[i])
173 case ASLLV_ALIGN_RIGHT:
174 x = min_x + udata->LVColumnWidth[i] -
175 TextLength(rp, node->text[i], len);
176 break;
178 default:
179 x = min_x;
180 break;
183 if (x > max_x)
184 break;
186 numfit = TextFit(rp,
187 node->text[i],
188 len,
189 &te,
190 NULL,
192 max_x - x + 1,
193 max_y - min_y + 1);
195 if (numfit < len)
196 numfit++;
198 if (numfit < 1)
199 break;
201 SetAPen(rp, dri->dri_Pens[textpen]);
203 /* Render text */
204 Move(rp, x, min_y + rp->Font->tf_Baseline);
205 Text(rp, node->text[i], numfit);
207 min_x += udata->LVColumnWidth[i] + rp->TxWidth * 2;
209 } /* for(i = 0; i < ASLLV_MAXCOLUMNS;i++) */
211 } /* if (node) */
213 } break;
215 } /* switch (msg->lvdm_State) */
217 retval = ASLLVCB_OK;
219 } /* if (msg->lvdm_MethodID == LV_DRAW) */
220 else
222 retval = ASLLVCB_UNKNOWN;
225 return retval;
227 AROS_USERFUNC_EXIT
230 /*****************************************************************************************/
232 #undef AslBase
234 /*****************************************************************************************/
236 AROS_UFH3(VOID, FRTagHook,
237 AROS_UFHA(struct Hook *, hook, A0),
238 AROS_UFHA(struct ParseTagArgs *, pta, A2),
239 AROS_UFHA(struct AslBase_intern *, AslBase, A1)
242 AROS_USERFUNC_INIT
244 struct TagItem *tag;
245 struct TagItem *tstate;
246 struct IntFileReq *ifreq;
247 IPTR tidata;
249 EnterFunc(bug("FRTagHook(hook=%p, pta=%p)\n", hook, pta));
251 ifreq = (struct IntFileReq *)pta->pta_IntReq;
253 tstate = pta->pta_Tags;
254 while ((tag = NextTagItem(&tstate)) != NULL)
256 tidata = tag->ti_Data;
258 switch (tag->ti_Tag)
260 /* The tags that are put "in a row" are defined as the same value,
261 and therefor we only use one of them, but the effect is for all of them
263 case ASLFR_InitialDrawer:
264 /* case ASL_Dir: Obsolete */
265 if (tidata)
266 ifreq->ifr_Drawer = (STRPTR)tidata;
267 break;
269 case ASLFR_InitialFile:
270 /* case ASL_File: Obsolete */
271 if (tidata)
272 ifreq->ifr_File = (STRPTR)tidata;
273 break;
275 case ASLFR_InitialPattern:
276 /* case ASL_Pattern: Obsolete */
277 if (tidata)
278 ifreq->ifr_Pattern = (STRPTR)tidata;
279 break;
281 case ASLFR_UserData:
282 ((struct FileRequester *)pta->pta_Req)->fr_UserData = (APTR)tidata;
283 break;
285 /* Options */
287 case ASLFR_Flags1:
288 ifreq->ifr_Flags1 = (UBYTE)tidata;
289 /* Extract some flags that are common to all requester types and
290 put them into IntReq->ir_Flags
292 if (ifreq->ifr_Flags1 & FRF_PRIVATEIDCMP)
293 GetIR(ifreq)->ir_Flags |= IF_PRIVATEIDCMP;
294 else
295 GetIR(ifreq)->ir_Flags &= ~IF_PRIVATEIDCMP;
296 break;
298 case ASLFR_Flags2:
299 ifreq->ifr_Flags2 = (UBYTE)tidata;
300 break;
302 case ASLFR_DoSaveMode:
303 if (tidata)
304 ifreq->ifr_Flags1 |= FRF_DOSAVEMODE;
305 else
306 ifreq->ifr_Flags1 &= ~FRF_DOSAVEMODE;
307 break;
309 case ASLFR_DoMultiSelect:
310 if (tidata)
311 ifreq->ifr_Flags1 |= FRF_DOMULTISELECT;
312 else
313 ifreq->ifr_Flags1 &= ~FRF_DOMULTISELECT;
314 break;
316 case ASLFR_DoPatterns:
317 if (tidata)
318 ifreq->ifr_Flags1 |= FRF_DOPATTERNS;
319 else
320 ifreq->ifr_Flags1 &= ~FRF_DOPATTERNS;
321 break;
323 case ASLFR_DrawersOnly:
324 if (tidata)
325 ifreq->ifr_Flags2 |= FRF_DRAWERSONLY;
326 else
327 ifreq->ifr_Flags2 &= ~FRF_DRAWERSONLY;
328 break;
330 case ASLFR_FilterFunc:
331 ifreq->ifr_FilterFunc = (struct Hook *)tidata;
332 ifreq->ifr_Flags1 |= FRF_FILTERFUNC;
333 break;
335 case ASLFR_RejectIcons:
336 if (tidata)
337 ifreq->ifr_Flags2 |= FRF_REJECTICONS;
338 else
339 ifreq->ifr_Flags2 &= ~FRF_REJECTICONS;
340 break;
342 case ASLFR_RejectPattern:
343 if (tidata)
344 ifreq->ifr_RejectPattern = (STRPTR)tidata;
345 break;
347 case ASLFR_AcceptPattern:
348 if (tidata)
349 ifreq->ifr_AcceptPattern = (STRPTR)tidata;
350 break;
352 case ASLFR_FilterDrawers:
353 if (tidata)
354 ifreq->ifr_Flags2 |= FRF_FILTERDRAWERS;
355 else
356 ifreq->ifr_Flags2 &= ~FRF_FILTERDRAWERS;
357 break;
359 case ASLFR_HookFunc:
360 ifreq->ifr_HookFunc = (APTR)tidata;
361 break;
363 case ASLFR_SetSortBy:
364 ifreq->ifr_SortBy = tidata;
365 break;
367 case ASLFR_GetSortBy:
368 ifreq->ifr_GetSortBy = (ULONG *)tidata;
369 break;
371 case ASLFR_SetSortOrder:
372 ifreq->ifr_SortOrder = tidata;
373 break;
375 case ASLFR_GetSortOrder:
376 ifreq->ifr_GetSortOrder = (ULONG *)tidata;
377 break;
379 case ASLFR_SetSortDrawers:
380 ifreq->ifr_SortDrawers = tidata;
381 break;
383 case ASLFR_GetSortDrawers:
384 ifreq->ifr_GetSortDrawers = (ULONG *)tidata;
385 break;
387 case ASLFR_InitialShowVolumes:
388 ifreq->ifr_InitialShowVolumes = tidata ? TRUE : FALSE;
389 break;
391 default:
392 break;
394 } /* switch (tag->ti_Tag) */
396 } /* while ((tag = NextTagItem(&tstate)) != 0) */
398 /* DrawersOnly excludes multiselect */
399 /* DoSaveMode also excludes multiselect */
401 if ((ifreq->ifr_Flags2 & FRF_DRAWERSONLY) || (ifreq->ifr_Flags1 & FRF_DOSAVEMODE))
403 ifreq->ifr_Flags1 &= ~FRF_DOMULTISELECT;
406 ReturnVoid("FRTagHook");
408 AROS_USERFUNC_EXIT
411 /*****************************************************************************************/
413 AROS_UFH3(ULONG, FRGadgetryHook,
414 AROS_UFHA(struct Hook *, hook, A0),
415 AROS_UFHA(struct LayoutData *, ld, A2),
416 AROS_UFHA(struct AslBase_intern *, AslBase, A1)
419 AROS_USERFUNC_INIT
421 ULONG retval;
423 switch (ld->ld_Command)
425 case LDCMD_WINDOWOPENED:
426 retval = (ULONG)FRWindowOpened(ld, ASLB(AslBase));
427 break;
429 case LDCMD_INIT:
430 retval = (ULONG)FRGadInit(ld, ASLB(AslBase));
431 break;
433 case LDCMD_LAYOUT:
434 retval = (ULONG)FRGadLayout(ld, ASLB(AslBase));
435 break;
437 case LDCMD_HANDLEEVENTS:
438 retval = (ULONG)FRHandleEvents(ld, ASLB(AslBase));
439 break;
441 case LDCMD_HANDLEAPPWINDOW:
442 retval = (ULONG)FRHandleAppWindow(ld, ASLB(AslBase));
443 break;
445 case LDCMD_CLEANUP:
446 FRGadCleanup(ld, ASLB(AslBase));
447 retval = GHRET_OK;
448 break;
450 default:
451 retval = GHRET_FAIL;
452 break;
455 // ReturnInt ("FRGadgetryHook(), retval", ULONG, retval);
456 return retval;
458 AROS_USERFUNC_EXIT
461 /*****************************************************************************************/
463 struct ButtonInfo
465 WORD gadid;
466 char *text;
467 #if USE_SHARED_COOLIMAGES
468 ULONG coolid;
469 Object **objvar;
470 const struct CoolImage *coolimage;
471 #else
472 const struct CoolImage *coolimage;
473 Object **objvar;
474 #endif
477 /*****************************************************************************************/
479 STATIC BOOL FRWindowOpened(struct LayoutData *ld, struct AslBase_intern *AslBase)
481 ModifyIDCMP(ld->ld_Window, ld->ld_Window->IDCMPFlags | IDCMP_INTUITICKS);
483 if ((ld->ld_AppMsgPort = CreateMsgPort()))
484 ld->ld_AppWindow = AddAppWindow(0, 0, ld->ld_Window, ld->ld_AppMsgPort, NULL);
487 * A file requester that failed to be an AppWindow is better than no file
488 * requester at all: let's not fail.
490 return TRUE;
493 /*****************************************************************************************/
495 STATIC BOOL FRGadInit(struct LayoutData *ld, struct AslBase_intern *AslBase)
497 struct FRUserData *udata = ld->ld_UserData;
498 struct IntFileReq *ifreq = (struct IntFileReq *)ld->ld_IntReq;
499 #if USE_SHARED_COOLIMAGES
500 ULONG okid = (GetIR(ifreq)->ir_Flags & IF_USER_POSTEXT) ? COOL_USEIMAGE_ID :
501 ((ifreq->ifr_Flags1 & FRF_DOSAVEMODE) ? COOL_SAVEIMAGE_ID :
502 COOL_LOADIMAGE_ID);
503 struct ButtonInfo bi[NUMBUTS] =
505 { ID_BUTOK , GetIR(ifreq)->ir_PositiveText , okid , &udata->OKBut },
506 { ID_BUTVOLUMES , NULL , COOL_DOTIMAGE_ID , &udata->VolumesBut },
507 { ID_BUTPARENT , NULL , COOL_DOTIMAGE_ID , &udata->ParentBut },
508 { ID_BUTCANCEL , GetIR(ifreq)->ir_NegativeText , COOL_CANCELIMAGE_ID , &udata->CancelBut }
510 #else
511 const struct CoolImage *okimage = (GetIR(ifreq)->ir_Flags & IF_USER_POSTEXT) ? &cool_useimage :
512 ((ifreq->ifr_Flags1 & FRF_DOSAVEMODE) ? &cool_saveimage :
513 &cool_loadimage);
514 struct ButtonInfo bi[NUMBUTS] =
516 { ID_BUTOK , GetIR(ifreq)->ir_PositiveText , okimage , &udata->OKBut },
517 { ID_BUTVOLUMES , NULL , &cool_dotimage , &udata->VolumesBut },
518 { ID_BUTPARENT , NULL , &cool_dotimage , &udata->ParentBut },
519 { ID_BUTCANCEL , GetIR(ifreq)->ir_NegativeText , &cool_cancelimage , &udata->CancelBut }
521 #endif
522 Object *gad;
523 STRPTR butstr[NUMBUTS];
524 LONG error = ERROR_NO_FREE_STORE;
525 WORD gadrows, x, y, w, h, i, y2 = 0;
527 NEWLIST(&udata->ListviewList);
529 udata->StringEditHook.h_Entry = (APTR)AROS_ASMSYMNAME(StringEditFunc);
530 udata->StringEditHook.h_SubEntry = NULL;
531 udata->StringEditHook.h_Data = AslBase;
533 udata->ListviewHook.h_Entry = (APTR)AROS_ASMSYMNAME(ASLFRRenderHook);
534 udata->ListviewHook.h_SubEntry = NULL;
535 udata->ListviewHook.h_Data = AslBase;
537 /* calc. min. size */
539 if (!bi[0].text)
540 bi[0].text = GetString(MSG_FILEREQ_POSITIVE_GAD, GetIR(ifreq)->ir_Catalog, AslBase);
541 bi[1].text = GetString(MSG_FILEREQ_VOLUMES_GAD, GetIR(ifreq)->ir_Catalog, AslBase);
542 bi[2].text = GetString(MSG_FILEREQ_PARENT_GAD, GetIR(ifreq)->ir_Catalog, AslBase);
543 if (!bi[3].text)
544 bi[3].text = GetString(MSG_FILEREQ_NEGATIVE_GAD, GetIR(ifreq)->ir_Catalog, AslBase);
547 w = 0;
548 for(i = 0; i < NUMBUTS; i++)
550 x = TextLength(&ld->ld_DummyRP, bi[i].text, strlen(bi[i].text));
552 #if FREQ_COOL_BUTTONS
553 #if USE_SHARED_COOLIMAGES
554 if (CoolImagesBase)
556 bi[i].coolimage = (const struct CoolImage *)COOL_ObtainImageA(bi[i].coolid, NULL);
559 if (CoolImagesBase)
560 #endif
561 if (ld->ld_TrueColor)
563 x += IMAGEBUTTONEXTRAWIDTH + bi[i].coolimage->width;
565 #endif
567 if (x > w) w = x;
570 udata->ButWidth = w + BUTTONEXTRAWIDTH;
572 ld->ld_ButWidth = udata->ButWidth;
573 ld->ld_NumButtons = 4;
575 #if FREQ_COOL_BUTTONS
577 #if USE_SHARED_COOLIMAGES
578 if (CoolImagesBase)
580 #endif
581 y = BUTTONEXTRAHEIGHT + ld->ld_Font->tf_YSize;
582 if (ld->ld_TrueColor)
584 y2 = IMAGEBUTTONEXTRAHEIGHT + DEF_COOLIMAGEHEIGHT;
585 } else {
586 y2 = 0;
588 udata->ButHeight = (y > y2) ? y : y2;
589 #if USE_SHARED_COOLIMAGES
591 else
593 udata->ButHeight = BUTTONEXTRAHEIGHT + ld->ld_Font->tf_YSize;
595 #endif
597 #else
598 udata->ButHeight = BUTTONEXTRAHEIGHT + ld->ld_Font->tf_YSize;
599 #endif
601 gadrows = 3; /* button row + file string + drawer string */
602 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS) gadrows++;
603 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY) gadrows--;
605 ld->ld_MinWidth = OUTERSPACINGX * 2 +
606 GADGETSPACINGX * 3 +
607 udata->ButWidth * NUMBUTS;
609 ld->ld_MinHeight = OUTERSPACINGY * 2 +
610 (GADGETSPACINGY + udata->ButHeight) * gadrows +
611 BORDERLVSPACINGY * 2 +
612 (ld->ld_Font->tf_YSize + BORDERLVITEMSPACINGY * 2) * FREQ_MIN_VISIBLELINES;
614 ld->ld_MinWidth += ld->ld_WBorLeft + ld->ld_WBorRight;
615 ld->ld_MinHeight += ld->ld_WBorTop + ld->ld_WBorBottom;
617 /* make listview gadget */
619 x = ld->ld_WBorLeft + OUTERSPACINGX;
620 y = ld->ld_WBorTop + OUTERSPACINGY;
621 w = -ld->ld_WBorRight - ld->ld_WBorLeft - OUTERSPACINGX * 2 - PROPSIZE;
622 h = -ld->ld_WBorBottom - ld->ld_WBorTop - OUTERSPACINGY * 2 -
623 udata->ButHeight * gadrows -
624 GADGETSPACINGY * gadrows;
627 struct TagItem lv_tags[] =
629 {GA_Left , x },
630 {GA_Top , y },
631 {GA_RelWidth , w },
632 {GA_RelHeight , h },
633 {GA_UserData , (IPTR)ld },
634 {GA_ID , ID_LISTVIEW },
635 {GA_RelVerify , TRUE },
636 {ASLLV_CallBack , (IPTR)&udata->ListviewHook },
637 {ASLLV_DoMultiSelect, (ifreq->ifr_Flags1 & FRF_DOMULTISELECT) },
638 {ASLLV_DoSaveMode , (ifreq->ifr_Flags1 & FRF_DOSAVEMODE) },
639 {TAG_DONE }
642 udata->Listview = gad = NewObjectA(AslBase->asllistviewclass, NULL, lv_tags);
643 if (!udata->Listview) goto failure;
647 /* make scroller gadget for listview */
649 x = -ld->ld_WBorRight - OUTERSPACINGX - PROPSIZE + 1;
650 y = ld->ld_WBorTop + OUTERSPACINGY;
651 w = PROPSIZE;
652 h = -ld->ld_WBorBottom - ld->ld_WBorTop - OUTERSPACINGY * 2 -
653 udata->ButHeight * gadrows -
654 GADGETSPACINGY * gadrows;
656 struct TagItem scroller_tags[] =
658 {GA_RelRight , x },
659 {GA_Top , y },
660 {GA_Width , w },
661 {GA_RelHeight , h },
662 {GA_ID , ID_LISTVIEW },
663 {PGA_NewLook , TRUE },
664 {PGA_Borderless , TRUE },
665 {PGA_Freedom , FREEVERT },
666 {PGA_Top , 0 },
667 {PGA_Total , 20 },
668 {PGA_Visible , 1 },
669 {GA_Previous , (IPTR)gad },
670 {TAG_DONE }
673 if (!makescrollergadget(&udata->ScrollGad, ld, scroller_tags, AslBase)) goto failure;
674 gad = udata->ScrollGad.arrow2;
677 connectscrollerandlistview(&udata->ScrollGad, udata->Listview, AslBase);
679 /* make button row */
681 y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight + 1;
684 struct TagItem button_tags[] =
686 {GA_Text , 0 },
687 {GA_Previous , 0 },
688 {GA_ID , 0 },
689 #if FREQ_COOL_BUTTONS
690 {ASLBT_CoolImage , 0 },
691 #else
692 {TAG_IGNORE , 0 },
693 #endif
694 {GA_UserData , (IPTR)ld },
695 {GA_Left , 0 },
696 {GA_RelBottom , y },
697 {GA_Width , udata->ButWidth },
698 {GA_Height , udata->ButHeight },
699 {GA_RelVerify , TRUE },
700 {GA_Image , 0 }, /* means we want a frame */
701 {TAG_DONE }
704 for(i = 0; i < NUMBUTS; i++)
706 button_tags[0].ti_Data = (IPTR)bi[i].text;
707 button_tags[1].ti_Data = (IPTR)gad;
708 button_tags[2].ti_Data = bi[i].gadid;
710 #if USE_SHARED_COOLIMAGES
711 if (CoolImagesBase == NULL) button_tags[3].ti_Tag = TAG_IGNORE;
712 #endif
713 button_tags[3].ti_Data = (IPTR)bi[i].coolimage;
715 *(bi[i].objvar) = gad = NewObjectA(AslBase->aslbuttonclass, NULL, button_tags);
716 if (!gad) goto failure;
721 /* make labels */
724 struct LabelInfo
726 BOOL doit;
727 STRPTR text;
728 Object **objvar;
729 } li [] =
731 {TRUE, (STRPTR)MSG_FILEREQ_PATTERN_LABEL, &udata->PatternLabel },
732 {TRUE, (STRPTR)MSG_FILEREQ_DRAWER_LABEL , &udata->DrawerLabel },
733 {TRUE, (STRPTR)MSG_FILEREQ_FILE_LABEL , &udata->FileLabel }
736 struct TagItem label_tags[] =
738 {GA_Left , 0 },
739 {GA_RelBottom , 0 },
740 {GA_Width , 0 },
741 {GA_Height , udata->ButHeight },
742 {GA_Text , 0 },
743 {GA_Previous , (IPTR)gad },
744 {GA_UserData , (IPTR)ld },
745 {GA_Disabled , TRUE },
746 {TAG_DONE }
749 for(i = 0; i < 3; i++)
751 li[i].text = GetString((IPTR)li[i].text, GetIR(ifreq)->ir_Catalog, AslBase);
754 /* Drawer label is always there */
756 w = TextLength(&ld->ld_DummyRP, li[1].text, strlen(li[1].text)) +
757 LABELSPACINGX +
758 ld->ld_Font->tf_XSize * 2; /* Frame symbol showing directory scan activity */
760 i = 0;
761 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS)
763 butstr[i++] = li[0].text;
765 else
767 li[0].doit = FALSE;
770 if (!(ifreq->ifr_Flags2 & FRF_DRAWERSONLY))
772 butstr[i++] = li[2].text;
774 else
776 li[2].doit = FALSE;
779 if (i)
781 x = BiggestTextLength(butstr, i, &(ld->ld_DummyRP), AslBase);
782 if (x > w) w = x;
785 x = ld->ld_WBorLeft + OUTERSPACINGX;
786 y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight -
787 (udata->ButHeight + GADGETSPACINGY) * (gadrows - 1) + 1;
789 label_tags[1].ti_Data = y;
791 for(i = 0; i < 3;i++)
793 if (!li[i].doit) continue;
795 if (i == 1) y2 = y;
797 label_tags[2].ti_Data = TextLength(&ld->ld_DummyRP, li[i].text, strlen(li[i].text));
798 label_tags[0].ti_Data = x + w - label_tags[2].ti_Data;
799 label_tags[4].ti_Data = (IPTR)li[i].text;
800 label_tags[5].ti_Data = (IPTR)gad;
802 *(li[i].objvar) = gad = NewObjectA(AslBase->aslbuttonclass, NULL, label_tags);
803 if (!gad) goto failure;
805 y += udata->ButHeight + GADGETSPACINGY;
806 label_tags[1].ti_Data = y;
810 /* Directory Scan Symbol */
813 struct TagItem sym_tags[] =
815 {GA_Left , x },
816 {GA_RelBottom , y2 + 1 },
817 {GA_Width , ld->ld_Font->tf_XSize * 2 },
818 {GA_Height , udata->ButHeight - 2 },
819 {GA_Image , 0 }, /* means we want a frame */
820 {GA_Previous , (IPTR)gad },
821 {GA_Disabled , TRUE },
822 {GA_UserData , (IPTR)ld },
823 {TAG_DONE }
826 udata->DirectoryScanSymbol = gad = NewObjectA(AslBase->aslbuttonclass, NULL, sym_tags);
827 if (!udata->DirectoryScanSymbol) goto failure;
830 /* make string gadgets */
832 y = -ld->ld_WBorBottom - OUTERSPACINGY - udata->ButHeight -
833 (udata->ButHeight + GADGETSPACINGY) * (gadrows - 1) + 1;
834 x = ld->ld_WBorLeft + OUTERSPACINGX + w + LABELSPACINGX;
836 w = -ld->ld_WBorLeft - ld->ld_WBorRight - OUTERSPACINGX * 2 -
837 w - LABELSPACINGX;
840 struct StrInfo
842 WORD gadid;
843 char *text;
844 WORD maxchars;
845 Object **objvar;
846 } si [] =
848 {ID_STRPATTERN, ifreq->ifr_Pattern, MAX_PATTERN_LEN, &udata->PatternGad },
849 {ID_STRDRAWER , ifreq->ifr_Drawer , MAX_PATH_LEN , &udata->PathGad },
850 {ID_STRFILE , ifreq->ifr_File , MAX_FILE_LEN , &udata->FileGad },
853 struct TagItem string_tags[] =
855 {GA_Left , x },
856 {GA_RelBottom , y },
857 {GA_RelWidth , w },
858 {GA_Height , udata->ButHeight },
859 {GA_Previous , (IPTR)gad },
860 {STRINGA_TextVal , (IPTR)ifreq->ifr_Pattern },
861 {STRINGA_MaxChars , MAX_PATTERN_LEN },
862 {GA_ID , ID_STRPATTERN },
863 {GA_RelVerify , TRUE },
864 {GA_UserData , (IPTR)ld },
865 {GA_TabCycle , TRUE },
866 {STRINGA_EditHook , (IPTR)&udata->StringEditHook },
867 {STRINGA_Font , (IPTR)ld->ld_Font },
868 {TAG_DONE }
871 if (!(ifreq->ifr_Flags1 & FRF_DOPATTERNS)) si[0].gadid = 0;
872 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY) si[2].gadid = 0;
874 for(i = 0;i < 3; i++)
876 if (si[i].gadid == 0) continue;
878 string_tags[4].ti_Data = (IPTR)gad;
879 string_tags[5].ti_Data = (IPTR)si[i].text;
880 string_tags[6].ti_Data = si[i].maxchars;
881 string_tags[7].ti_Data = si[i].gadid;
883 *(si[i].objvar) = gad = NewObjectA(AslBase->aslstringclass, NULL, string_tags);
884 if (!gad) goto failure;
886 y += udata->ButHeight + GADGETSPACINGY;
887 string_tags[1].ti_Data = y;
891 #if AVOID_FLICKER
893 struct TagItem eraser_tags[] =
895 {GA_Previous, (IPTR)gad},
896 {TAG_DONE}
899 udata->EraserGad = gad = NewObjectA(AslBase->asleraserclass, NULL, eraser_tags);
900 /* Doesn't matter if this failed */
902 #endif
904 if (ifreq->ifr_InitialShowVolumes)
906 FRGetVolumes(ld, AslBase);
907 } else {
908 FRNewPath((STRPTR)ifreq->ifr_Drawer, ld, AslBase);
911 SetAttrs(udata->Listview, ASLLV_Labels, (IPTR)&udata->ListviewList,
912 TAG_DONE);
914 ld->ld_GList = (struct Gadget *)udata->Listview;
916 /* Menus */
918 struct NewMenu nm[] =
920 {NM_TITLE, (STRPTR)MSG_FILEREQ_MEN_CONTROL }, /* 0 */
921 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_LASTNAME , 0, 0 , 0 , (APTR)FRMEN_LASTNAME }, /* 1 */
922 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_NEXTNAME , 0, 0 , 0 , (APTR)FRMEN_NEXTNAME }, /* 2 */
923 {NM_ITEM, NM_BARLABEL }, /* 3 */
924 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_RESTORE , 0, 0 , 0 , (APTR)FRMEN_RESTORE }, /* 4 */
925 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_PARENT , 0, 0 , 0 , (APTR)FRMEN_PARENT }, /* 5 */
926 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_VOLUMES , 0, 0 , 0 , (APTR)FRMEN_VOLUMES }, /* 6 */
927 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_UPDATE , 0, 0 , 0 , (APTR)FRMEN_UPDATE }, /* 7 */
928 {NM_ITEM, NM_BARLABEL }, /* 8 */
929 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_DELETE , 0, 0 , 0 , (APTR)FRMEN_DELETE }, /* 9 */
930 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_CREATEDRAWER , 0, 0 , 0 , (APTR)FRMEN_NEWDRAWER }, /* 10 */
931 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_RENAME , 0, 0 , 0 , (APTR)FRMEN_RENAME }, /* 11 */
932 {NM_ITEM, NM_BARLABEL }, /* 12 */
933 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_SELECT , 0, 0 , 0 , (APTR)FRMEN_SELECT }, /* 13 */
934 {NM_ITEM, NM_BARLABEL }, /* 14 */
935 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_OK , 0, 0 , 0 , (APTR)FRMEN_OK }, /* 15 */
936 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_CONTROL_CANCEL , 0, 0 , 0 , (APTR)FRMEN_CANCEL }, /* 16 */
937 {NM_TITLE, (STRPTR)MSG_FILEREQ_MEN_FILELIST }, /* 17 */
938 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTNAME , 0, CHECKIT, 2 + 4 , (APTR)FRMEN_BYNAME }, /* 18 */
939 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDATE , 0, CHECKIT, 1 + 4 , (APTR)FRMEN_BYDATE }, /* 19 */
940 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTSIZE , 0, CHECKIT, 1 + 2 , (APTR)FRMEN_BYSIZE }, /* 20 */
941 {NM_ITEM, NM_BARLABEL }, /* 21 */
942 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTUP , 0, CHECKIT, 32 , (APTR)FRMEN_ASCENDING }, /* 22 */
943 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDOWN , 0, CHECKIT, 16 , (APTR)FRMEN_DESCENDING }, /* 23 */
944 {NM_ITEM, NM_BARLABEL }, /* 24 */
945 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDRAWERFIRST, 0, CHECKIT, 256 + 512, (APTR)FRMEN_DRAWERSFIRST}, /* 25 */
946 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDRAWERSAME , 0, CHECKIT, 128 + 512, (APTR)FRMEN_DRAWERSMIX }, /* 26 */
947 {NM_ITEM, (STRPTR)MSG_FILEREQ_MEN_FILELIST_SORTDRAWERLAST , 0, CHECKIT, 128 + 256, (APTR)FRMEN_DRAWERSLAST }, /* 27 */
948 {NM_END } /* 28 */
951 struct TagItem menu_tags[] =
953 {GTMN_NewLookMenus , TRUE },
954 {GTMN_TextAttr , (IPTR)GetIR(ifreq)->ir_TextAttr },
955 {TAG_DONE }
958 if (menu_tags[1].ti_Data == 0) menu_tags[1].ti_Tag = TAG_IGNORE;
960 LocalizeMenus(nm, GetIR(ifreq)->ir_Catalog, AslBase);
962 nm[18 + ifreq->ifr_SortBy ].nm_Flags |= CHECKED;
963 nm[22 + ifreq->ifr_SortOrder ].nm_Flags |= CHECKED;
964 nm[25 + ifreq->ifr_SortDrawers].nm_Flags |= CHECKED;
966 /* Show "Select" menu item only if this is a multiselect file requester.
967 The orig Amiga asl.library disables (ghosts) the item, but why
968 show it if it cannot be used anyway. */
970 if (!(ifreq->ifr_Flags1 & FRF_DOMULTISELECT))
972 nm[13].nm_Type = NM_IGNORE;
973 nm[14].nm_Type = NM_IGNORE;
976 /* No Rename in drawersonly requesters */
978 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY)
980 nm[11].nm_Type = NM_IGNORE;
983 /* Don't fail, if menus cannot be created/layouted, because a requester
984 without menus is still better than no requester at all */
986 if ((ld->ld_Menu = CreateMenusA(nm, NULL)))
988 if (!LayoutMenusA(ld->ld_Menu, ld->ld_VisualInfo, menu_tags))
990 FreeMenus(ld->ld_Menu);ld->ld_Menu = NULL;
995 SetIoErr(0);
997 ReturnBool ("FRGadInit", TRUE);
999 failure:
1000 D(bug("failure\n"));
1002 FRGadCleanup(ld, ASLB(AslBase));
1004 SetIoErr(error);
1006 ReturnBool ("FRGadInit", FALSE);
1010 /*****************************************************************************************/
1012 STATIC BOOL FRGadLayout(struct LayoutData *ld, struct AslBase_intern *AslBase)
1014 FRActivateMainStringGadget(ld, AslBase);
1016 ReturnBool ("FRGadLayout", TRUE );
1019 /*****************************************************************************************/
1021 STATIC VOID FRClickOnVolumes(struct LayoutData *ld, struct AslBase_intern *AslBase)
1023 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
1025 if (udata->Flags & FRFLG_SHOWING_VOLUMES)
1027 union
1029 UBYTE *dir;
1030 IPTR baz;
1031 } foo;
1033 GetAttr(STRINGA_TextVal, udata->PathGad, &foo.baz);
1034 FRGetDirectory(foo.dir, ld, AslBase);
1035 } else {
1036 FRGetVolumes(ld, AslBase);
1040 /*****************************************************************************************/
1042 STATIC ULONG FRHandleAppWindow(struct LayoutData *ld, struct AslBase_intern *AslBase)
1044 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
1045 struct ASLLVFileReqNode *node;
1046 STRPTR iconname = NULL, temp;
1047 char firsticonpath[MAX_PATH_LEN], iconpath[MAX_PATH_LEN], fullpath[MAX_PATH_LEN];
1048 ULONG retval = GHRET_FAIL, i = 0;
1049 BOOL found;
1051 if (ld->ld_AppMsg && (ld->ld_AppMsg->am_Type == AMTYPE_APPWINDOW))
1053 if (ld->ld_AppMsg->am_NumArgs >= 1)
1055 if (ld->ld_AppMsg->am_ArgList->wa_Lock)
1057 NameFromLock(ld->ld_AppMsg->am_ArgList->wa_Lock, firsticonpath, MAX_PATH_LEN);
1058 FRNewPath(firsticonpath, ld, AslBase);
1062 * Try to select the files corresponding to the dropped icons
1063 * (those coming from the same drawer as the first icon)
1067 if ( (ld->ld_AppMsg->am_ArgList[i].wa_Name)
1068 && (iconname = VecPooledCloneString(ld->ld_AppMsg->am_ArgList[i].wa_Name, NULL, ld->ld_IntReq->ir_MemPool, AslBase))
1071 /* Case of a single volume icon */
1072 if ( (strcmp(iconname, "") == 0)
1073 && (ld->ld_AppMsg->am_NumArgs == 1)
1076 found = TRUE;
1078 else
1080 NameFromLock(ld->ld_AppMsg->am_ArgList[i].wa_Lock, iconpath, MAX_PATH_LEN);
1081 found = FALSE;
1082 ForeachNode(&udata->ListviewList, node)
1084 if ( (IS_MULTISEL(node) || (ld->ld_AppMsg->am_NumArgs == 1))
1085 && node->node.ln_Name
1086 && (strcmp((CONST_STRPTR)node->node.ln_Name, (CONST_STRPTR)iconname) == 0)
1089 /* Avoid to select homonyms of files dropped from other drawers */
1090 if (strcmp((CONST_STRPTR)iconpath, (CONST_STRPTR)firsticonpath) == 0)
1092 MARK_SELECTED(node);
1093 found = TRUE;
1096 break;
1098 } /* ForeachNode(&udata->ListviewList, node) */
1099 } /* if (!(single volume icon)) */
1101 if (!found)
1103 fullpath[0] = '\0';
1104 AddPart(fullpath, iconpath, MAX_PATH_LEN);
1105 AddPart(fullpath, iconname, MAX_PATH_LEN);
1106 temp = VecPooledCloneString("\n", fullpath, ld->ld_IntReq->ir_MemPool, AslBase);
1108 MyFreeVecPooled(iconname, AslBase);
1109 iconname = NULL;
1111 if (ld->ld_ForeignerFiles)
1113 iconname = temp;
1114 temp = VecPooledCloneString(ld->ld_ForeignerFiles, iconname, ld->ld_IntReq->ir_MemPool, AslBase);
1115 MyFreeVecPooled(ld->ld_ForeignerFiles, AslBase);
1118 ld->ld_ForeignerFiles = temp;
1119 } /* if (!found) */
1121 if (iconname)
1122 MyFreeVecPooled(iconname, AslBase);
1123 } /* if (iconname = ld->ld_AppMsg->am_ArgList[i].wa_Name) */
1124 } while ( (((struct IntFileReq *)ld->ld_IntReq)->ifr_Flags1 & FRF_DOMULTISELECT)
1125 && (++i < ld->ld_AppMsg->am_NumArgs)
1128 if (ld->ld_AppMsg->am_ArgList->wa_Name)
1129 FRSetFile(ld->ld_AppMsg->am_ArgList->wa_Name, ld, AslBase);
1131 retval = GHRET_OK;
1134 // ReturnInt ("FRHandleAppWindow(), retval", ULONG, retval);
1135 return retval;
1138 /*****************************************************************************************/
1140 STATIC ULONG FRHandleEvents(struct LayoutData *ld, struct AslBase_intern *AslBase)
1142 struct IntuiMessage *imsg;
1143 struct FRUserData *udata;
1144 struct IntFileReq *ifreq;
1145 ULONG retval = GHRET_OK;
1146 WORD gadid;
1147 IPTR left, top, right, bottom;
1149 // EnterFunc(bug("FRHandleEvents: Class: %d\n", imsg->Class));
1151 udata = (struct FRUserData *)ld->ld_UserData;
1152 ifreq = (struct IntFileReq *)ld->ld_IntReq;
1155 if ((imsg = ld->ld_Event))
1157 // D(bug("[ASL] FRHandleEvents() imsg->Code = '%d'\n", imsg->Code));
1158 switch (imsg->Class)
1160 case IDCMP_INTUITICKS:
1162 GT_GetGadgetAttrs((struct Gadget *)udata->Listview,
1163 ld->ld_Window,
1164 (struct Requester *)ifreq,
1165 GA_Left , &left ,
1166 GA_Top , &top ,
1167 GA_RelWidth , &right ,
1168 GA_RelHeight, &bottom);
1170 if ( (ld->ld_Window->MouseY < bottom + ld->ld_Window->Height + top)
1171 && (ld->ld_Window->MouseX < right + ld->ld_Window->Width + left)
1172 && (ld->ld_Window->MouseY >= top)
1173 && (ld->ld_Window->MouseX >= left)
1176 AROS_ATOMIC_OR(ld->ld_Window->Flags, WFLG_RMBTRAP);
1178 else
1180 AROS_ATOMIC_AND(ld->ld_Window->Flags, ~WFLG_RMBTRAP);
1182 break;
1185 case IDCMP_CLOSEWINDOW:
1186 retval = FALSE;
1187 break;
1189 case IDCMP_MOUSEBUTTONS:
1190 switch (imsg->Code)
1192 case MENUDOWN:
1193 FRClickOnVolumes(ld, AslBase);
1194 break;
1195 case MENUUP:
1196 break;
1197 default:
1198 FRActivateMainStringGadget(ld, AslBase);
1199 break;
1201 break;
1203 case IDCMP_RAWKEY:
1204 switch (imsg->Code)
1206 case CURSORUP:
1207 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, 0, AslBase);
1208 break;
1210 case RAWKEY_PAGEUP:
1211 FRChangeActiveLVItem(ld, -1, IEQUALIFIER_LSHIFT, 0, AslBase);
1212 break;
1214 case RAWKEY_HOME:
1215 FRChangeActiveLVItem(ld, -1, IEQUALIFIER_LALT, 0, AslBase);
1216 break;
1218 case RAWKEY_NM_WHEEL_UP:
1219 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, 0, AslBase);
1220 break;
1222 case CURSORDOWN:
1223 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, 0, AslBase);
1224 break;
1226 case RAWKEY_PAGEDOWN:
1227 FRChangeActiveLVItem(ld, 1, IEQUALIFIER_LSHIFT, 0, AslBase);
1228 break;
1230 case RAWKEY_END:
1231 FRChangeActiveLVItem(ld, 1, IEQUALIFIER_LALT, 0, AslBase);
1232 break;
1234 case RAWKEY_NM_WHEEL_DOWN:
1235 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, 0, AslBase);
1236 break;
1238 } /* switch (imsg->Code) */
1239 break;
1241 case IDCMP_VANILLAKEY:
1242 switch(imsg->Code)
1244 case 27: /* ESC */
1245 retval = FALSE;
1246 break;
1248 break;
1250 case IDCMP_GADGETUP:
1251 gadid = ((struct Gadget *)imsg->IAddress)->GadgetID;
1253 D(bug("GADGETUP! gadgetid=%d\n", gadid));
1255 switch (gadid)
1257 case ID_BUTCANCEL:
1258 retval = FALSE;
1259 break;
1261 case ID_BUTVOLUMES:
1262 FRClickOnVolumes(ld, AslBase);
1263 break;
1265 case ID_BUTPARENT:
1266 FRParentPath(ld, AslBase);
1267 break;
1269 case ID_STRFILE:
1270 if (imsg->Code == STRINGCODE_CURSORUP)
1272 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, (struct Gadget *)udata->FileGad, AslBase);
1273 break;
1275 else if (imsg->Code == STRINGCODE_CURSORDOWN)
1277 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, (struct Gadget *)udata->FileGad, AslBase);
1278 break;
1280 else if ((imsg->Code == 0) || (imsg->Code == 9))
1282 char filestring[MAX_FILE_LEN], checkstring[MAX_FILE_LEN], *file;
1283 BOOL fall_through = (imsg->Code == 9) ? FALSE : TRUE;
1284 BOOL has_colon = FALSE;
1285 BOOL has_slash = FALSE;
1287 GetAttr(STRINGA_TextVal, udata->FileGad, (IPTR *)&file);
1288 strcpy(filestring, file);
1290 has_colon = strchr(filestring, ':') ? TRUE : FALSE;
1291 has_slash = strchr(filestring, '/') ? TRUE : FALSE;
1293 if (has_colon || has_slash)
1295 fall_through = FALSE;
1297 if (strcmp(filestring, ":") == 0)
1299 FRNewPath(filestring, ld, AslBase);
1300 FRSetFile("", ld, AslBase);
1302 else if (stricmp(filestring, "/") == 0)
1304 FRParentPath(ld, AslBase);
1305 FRSetFile("", ld, AslBase);
1307 else
1309 BPTR lock;
1310 BOOL isfile = TRUE;
1312 if (has_colon)
1314 strcpy(checkstring, filestring);
1316 else
1318 char *dir;
1320 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&dir);
1322 strcpy(checkstring, dir);
1323 AddPart(checkstring, filestring, MAX_FILE_LEN);
1326 if ((lock = Lock(checkstring, ACCESS_READ)))
1328 struct FileInfoBlock *fib;
1330 if ((fib = AllocDosObject(DOS_FIB, NULL)))
1332 if (Examine(lock, fib))
1334 if (fib->fib_DirEntryType > 0)
1335 isfile = FALSE;
1337 FreeDosObject(DOS_FIB, fib);
1339 UnLock(lock);
1342 if (isfile)
1344 char *fp = FilePart(checkstring);
1345 char fpc = *fp;
1347 *fp = '\0';
1348 FRNewPath(checkstring, ld, AslBase);
1350 *fp = fpc;
1351 FRSetFile(fp, ld, AslBase);
1354 else
1356 FRAddPath(filestring, ld, AslBase);
1357 FRSetFile(ifreq->ifr_File, ld, AslBase);
1361 ActivateGadget((struct Gadget *)udata->FileGad, ld->ld_Window, NULL);
1363 } /* has colon or slash */
1365 if (!fall_through) break;
1367 } /* if ((imsg->Code == 0) || (imsg->Code == 9)) */
1368 else
1370 break;
1373 /* fall through */
1375 case ID_BUTOK:
1376 retval = FRGetSelectedFiles(ld, ASLB(AslBase));
1377 break;
1379 case ID_STRPATTERN:
1380 if (imsg->Code == STRINGCODE_CURSORUP)
1382 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, (struct Gadget *)udata->PatternGad, AslBase);
1383 break;
1385 else if (imsg->Code == STRINGCODE_CURSORDOWN)
1387 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, (struct Gadget *)udata->PatternGad, AslBase);
1388 break;
1390 else if ((imsg->Code == 0) || (imsg->Code == 9))
1392 if (imsg->Code == 0)
1393 ActivateGadget((struct Gadget *)udata->PathGad, ld->ld_Window, NULL);
1394 /* fall through to ID_STRDRAWER */
1396 else
1398 break;
1400 /* no break here!! */
1402 case ID_STRDRAWER:
1403 if (imsg->Code == STRINGCODE_CURSORUP)
1405 FRChangeActiveLVItem(ld, -1, imsg->Qualifier, (struct Gadget *)udata->PathGad, AslBase);
1407 else if (imsg->Code == STRINGCODE_CURSORDOWN)
1409 FRChangeActiveLVItem(ld, 1, imsg->Qualifier, (struct Gadget *)udata->PathGad, AslBase);
1411 else if ((imsg->Code == 0) || (imsg->Code == 9))
1413 UBYTE *dir;
1415 if ((imsg->Code == 0) && (gadid == ID_STRDRAWER))
1417 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY)
1419 retval = FRGetSelectedFiles(ld, ASLB(AslBase));
1420 break;
1422 else
1424 ActivateGadget((struct Gadget *)udata->FileGad, ld->ld_Window, NULL);
1427 GetAttr(STRINGA_TextVal, udata->FileGad, (IPTR *)&dir);
1428 FRAddPath(dir, ld, AslBase);
1429 FRSetFile(ifreq->ifr_File, ld, AslBase);
1431 break;
1433 case ID_LISTVIEW:
1435 struct ASLLVFileReqNode *node;
1436 IPTR active;
1438 GetAttr(ASLLV_Active, udata->Listview, &active);
1440 if ((node = (struct ASLLVFileReqNode *)FindListNode(&udata->ListviewList, (WORD)active)))
1442 switch(node->type)
1444 case ASLLV_FRNTYPE_VOLUMES:
1445 FRNewPath((STRPTR)node->text[0], ld, AslBase);
1446 break;
1448 case ASLLV_FRNTYPE_DIRECTORY:
1449 if (node->subtype > 0)
1451 FRAddPath((STRPTR)node->text[0], ld, AslBase);
1453 else
1455 FRSetFile((STRPTR)node->text[0], ld, AslBase);
1457 if ( (imsg->Code) /* TRUE if double clicked */
1458 && !(ifreq->ifr_Flags1 & FRF_DOSAVEMODE)) /* disallowed in save mode */
1460 retval = FRGetSelectedFiles(ld, AslBase);
1463 break;
1465 } /* switch(node->type) */
1467 } /* if ((node = (struct ASLLVFileReqNode *)FindNode(&udata->ListviewList, (WORD)active))) */
1469 FRActivateMainStringGadget(ld, AslBase);
1471 } /* case ID_LISTVIEW: */
1472 break;
1474 } /* switch (gadget ID) */
1476 break; /* case IDCMP_GADGETUP: */
1478 case IDCMP_MENUPICK:
1479 if (ld->ld_Menu)
1481 UWORD men = imsg->Code;
1483 while(men != MENUNULL)
1485 struct MenuItem *item;
1486 BOOL resort = FALSE;
1488 if ((item = ItemAddress(ld->ld_Menu, men)))
1490 switch((IPTR)GTMENUITEM_USERDATA(item))
1492 /* Control menu */
1494 case FRMEN_LASTNAME:
1495 FRChangeActiveLVItem(ld, -1, 0, 0, AslBase);
1496 break;
1498 case FRMEN_NEXTNAME:
1499 FRChangeActiveLVItem(ld, 1, 0, 0, AslBase);
1500 break;
1502 case FRMEN_RESTORE:
1503 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS)
1505 FRSetPattern(ifreq->ifr_Pattern, ld, AslBase);
1507 if (!(ifreq->ifr_Flags2 & FRF_DRAWERSONLY))
1509 FRSetFile(ifreq->ifr_File, ld, AslBase);
1511 FRNewPath(ifreq->ifr_Drawer, ld, AslBase);
1512 break;
1514 case FRMEN_PARENT:
1515 FRParentPath(ld, AslBase);
1516 break;
1518 case FRMEN_VOLUMES:
1519 FRClickOnVolumes(ld, AslBase);
1520 break;
1522 case FRMEN_UPDATE:
1523 /* WARNING: a bit hacky */
1524 udata->Flags ^= FRFLG_SHOWING_VOLUMES;
1525 FRClickOnVolumes(ld, AslBase);
1526 break;
1528 case FRMEN_DELETE:
1529 FRDeleteRequester(ld, AslBase);
1530 break;
1532 case FRMEN_NEWDRAWER:
1533 FRNewDrawerRequester(ld, AslBase);
1534 break;
1536 case FRMEN_RENAME:
1537 FRRenameRequester(ld, AslBase);
1538 break;
1540 case FRMEN_SELECT:
1541 FRSelectRequester(ld, AslBase);
1542 break;
1544 case FRMEN_OK:
1545 retval = FRGetSelectedFiles(ld, ASLB(AslBase));
1546 break;
1548 case FRMEN_CANCEL:
1549 retval = FALSE;
1550 break;
1552 /* File list menu */
1554 case FRMEN_BYNAME:
1555 ifreq->ifr_SortBy = ASLFRSORTBY_Name;
1556 resort = TRUE;
1557 break;
1559 case FRMEN_BYDATE:
1560 ifreq->ifr_SortBy = ASLFRSORTBY_Date;
1561 resort = TRUE;
1562 break;
1564 case FRMEN_BYSIZE:
1565 ifreq->ifr_SortBy = ASLFRSORTBY_Size;
1566 resort = TRUE;
1567 break;
1569 case FRMEN_ASCENDING:
1570 ifreq->ifr_SortOrder = ASLFRSORTORDER_Ascend;
1571 resort = TRUE;
1572 break;
1574 case FRMEN_DESCENDING:
1575 ifreq->ifr_SortOrder = ASLFRSORTORDER_Descend;
1576 resort = TRUE;
1577 break;
1579 case FRMEN_DRAWERSFIRST:
1580 ifreq->ifr_SortDrawers = ASLFRSORTDRAWERS_First;
1581 resort = TRUE;
1582 break;
1584 case FRMEN_DRAWERSMIX:
1585 ifreq->ifr_SortDrawers = ASLFRSORTDRAWERS_Mix;
1586 resort = TRUE;
1587 break;
1589 case FRMEN_DRAWERSLAST:
1590 ifreq->ifr_SortDrawers = ASLFRSORTDRAWERS_Last;
1591 resort = TRUE;
1592 break;
1594 } /* switch id */
1596 if (resort)
1598 FRReSortListview(ld, AslBase);
1601 men = item->NextSelect;
1602 } /* if ((item = ItemAddress(ld->ld_Menu, men))) */
1603 else
1605 men = MENUNULL;
1608 } /* while(men != MENUNULL) */
1610 } /* if (ld->ld_Menu) */
1612 break; /* case IDCMP_MENUPICK: */
1614 } /* switch (imsg->Class) */
1615 } /* if((imsg = ld->ld_Event)) */
1617 // ReturnInt ("FRHandleEvents", ULONG, retval);
1618 return retval;
1621 /*****************************************************************************************/
1623 STATIC VOID FRGadCleanup(struct LayoutData *ld, struct AslBase_intern *AslBase)
1625 struct FRUserData *udata;
1626 struct FileRequester *req;
1627 struct IntReq *intreq;
1629 EnterFunc(bug("FRGadCleanup(ld=%p)\n", ld));
1631 udata = (struct FRUserData *)ld->ld_UserData;
1632 req = (struct FileRequester *)ld->ld_Req;
1633 intreq = ld->ld_IntReq;
1635 if (ld->ld_Window && ld->ld_GList)
1637 RemoveGList(ld->ld_Window, ld->ld_GList, -1);
1640 FreeObjects(&FREQ_FIRST_OBJECT(udata), &FREQ_LAST_OBJECT(udata), AslBase);
1642 killscrollergadget(&udata->ScrollGad, AslBase);
1644 FRFreeListviewList(ld, AslBase);
1646 if (ld->ld_Window)
1648 req->fr_LeftEdge = intreq->ir_LeftEdge = ld->ld_Window->LeftEdge;
1649 req->fr_TopEdge = intreq->ir_TopEdge = ld->ld_Window->TopEdge;
1650 req->fr_Width = intreq->ir_Width = ld->ld_Window->Width;
1651 req->fr_Height = intreq->ir_Height = ld->ld_Window->Height;
1654 ReturnVoid("FRGadCleanup");
1657 /*****************************************************************************************/
1659 STATIC ULONG FRGetSelectedFiles(struct LayoutData *ld, struct AslBase_intern *AslBase)
1661 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
1662 struct IntReq *intreq = ld->ld_IntReq;
1663 struct IntFileReq *ifreq = (struct IntFileReq *)intreq;
1664 struct FileRequester *req = (struct FileRequester *)ld->ld_Req;
1665 char *name;
1666 ULONG retval = GHRET_OK;
1668 /* Kill possible old output variables from a previous AslRequest call
1669 on the same requester */
1671 #undef GetFR
1672 #define GetFR(r) ((struct FileRequester *)r)
1674 * must be done here and NOT in StripRequester
1676 MyFreeVecPooled(GetFR(req)->fr_Drawer, AslBase);
1677 GetFR(req)->fr_Drawer = NULL;
1679 MyFreeVecPooled(GetFR(req)->fr_File, AslBase);
1680 GetFR(req)->fr_File = NULL;
1682 MyFreeVecPooled(GetFR(req)->fr_Pattern, AslBase);
1683 GetFR(req)->fr_Pattern = NULL;
1685 StripRequester(req, ASL_FileRequest, AslBase);
1687 /* Save drawer string gadget text in fr_Drawer */
1689 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&name);
1690 if (!(req->fr_Drawer = VecPooledCloneString(name, NULL, intreq->ir_MemPool, AslBase))) goto bye;
1691 D(bug("FRGetSelectedFiles: fr_Drawer 0x%lx <%s>\n",req->fr_Drawer,req->fr_Drawer));
1692 ifreq->ifr_Drawer = req->fr_Drawer;
1694 /* Save file string gadget text in fr_File */
1696 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY)
1697 name = "";
1698 else
1699 GetAttr(STRINGA_TextVal, udata->FileGad, (IPTR *)&name);
1701 if (!(req->fr_File = VecPooledCloneString(name, NULL, intreq->ir_MemPool, AslBase)))
1702 goto bye;
1704 D(bug("FRGetSelectedFiles: fr_File 0x%lx <%s>\n",req->fr_File,req->fr_File));
1705 ifreq->ifr_File = req->fr_File;
1707 /* Save pattern string gadget text in fr_Patterns */
1709 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS)
1711 GetAttr(STRINGA_TextVal, udata->PatternGad, (IPTR *)&name);
1713 if (!(req->fr_Pattern = VecPooledCloneString(name, NULL, intreq->ir_MemPool, AslBase))) goto bye;
1714 ifreq->ifr_Pattern = req->fr_Pattern;
1717 /* Create ArgList in case of ASLFR_DoMultiSelect requesters */
1719 req->fr_NumArgs = 0;
1721 if (ifreq->ifr_Flags1 & FRF_DOMULTISELECT)
1723 struct WBArg *wbarg;
1724 BPTR lock;
1726 if ((lock = Lock(req->fr_Drawer, ACCESS_READ)))
1728 WORD numargs, numselected = 0;
1730 if (!(udata->Flags & FRFLG_SHOWING_VOLUMES))
1732 numselected = CountNodes(&udata->ListviewList, NODEPRIF_SELECTED | NODEPRIF_MULTISEL);
1734 numargs = numselected > 0 ? numselected : 1;
1736 if ((wbarg = MyAllocVecPooled(intreq->ir_MemPool, sizeof(struct WBArg) * numargs, AslBase)))
1738 struct ASLLVFileReqNode *node;
1739 WORD i = 0;
1741 req->fr_ArgList = wbarg;
1743 ForeachNode(&udata->ListviewList, node)
1745 if (i == numselected) break;
1747 if ((node->node.ln_Pri & (NODEPRIF_SELECTED | NODEPRIF_MULTISEL)) == (NODEPRIF_SELECTED | NODEPRIF_MULTISEL))
1749 char *filename = node->text[0] ? node->text[0] : "";
1751 if ((wbarg->wa_Name = VecPooledCloneString(filename, NULL, intreq->ir_MemPool, AslBase)))
1753 wbarg->wa_Lock = lock;
1754 wbarg++;
1755 i++;
1759 } /* ForeachNode(&udata->ListviewList, node) */
1761 if (i == 0)
1763 if ((wbarg->wa_Name = VecPooledCloneString(req->fr_File, NULL, intreq->ir_MemPool, AslBase)))
1765 wbarg->wa_Lock = lock;
1766 i++;
1770 if (i == 0)
1772 MyFreeVecPooled(req->fr_ArgList, AslBase);
1773 req->fr_ArgList = NULL;
1774 } else {
1775 req->fr_NumArgs = i;
1776 lock = 0; /* clear lock to avoid that it is unlocked below */
1779 } /* if ((wbarg = MyAllocVecPooled(intreq->ir_MemPool, sizeof(struct WBArg) * numargs, AslBase))) */
1781 if (lock) UnLock(lock);
1783 } /* if ((lock = Lock(req->fr_Drawer, ACCESS_READ))) */
1785 } /* if (ifreq->ifr_Flags1 & FRF_DOMULTISELECT) */
1787 if (ifreq->ifr_GetSortBy) *ifreq->ifr_GetSortBy = ifreq->ifr_SortBy;
1788 if (ifreq->ifr_GetSortOrder) *ifreq->ifr_GetSortOrder = ifreq->ifr_SortOrder;
1789 if (ifreq->ifr_GetSortDrawers) *ifreq->ifr_GetSortDrawers = ifreq->ifr_SortDrawers;
1791 retval = GHRET_FINISHED_OK;
1793 bye:
1794 return retval;
1797 /*****************************************************************************************/