2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
7 #include <proto/exec.h>
9 #include <proto/intuition.h>
10 #include <proto/graphics.h>
11 #include <proto/utility.h>
12 #include <exec/memory.h>
14 #include <dos/exall.h>
15 #include <dos/dosasl.h>
16 #include <dos/datetime.h>
17 #include <dos/filehandler.h>
18 #include <intuition/gadgetclass.h>
21 #include <clib/macros.h>
23 #include "asl_intern.h"
24 #include "filereqsupport.h"
25 #include "filereqhooks.h"
26 #include "specialreq.h"
29 #define CATCOMP_NUMBERS
36 #include <aros/debug.h>
38 /*****************************************************************************************/
40 static WORD
FRCompareDirectoryNodes(struct IntFileReq
*ifreq
, struct ASLLVFileReqNode
*node1
,
41 struct ASLLVFileReqNode
*node2
, struct AslBase_intern
*AslBase
);
44 /*****************************************************************************************/
46 static void fixpath(char *pathstring
)
51 /* tricky slash stuff:
53 work:pictures/ --> work:pictures
54 work:pictures// --> work:
55 work:pictures/// --> work:/
56 work:pictures//// --> work://
61 /pics//pics/ --> /pics
62 /pics/scans//// --> //
66 start
= strrchr(pathstring
,':');
74 for(; (i
= len
= strlen(start
)); )
78 /* skip leading slashes */
80 while(i
&& (*sp
== '/'))
90 if((sp2
= strstr(sp
, "//")))
102 memmove(sp3
, sp2
+ 2, strlen(sp2
+ 2) + 1);
107 } /* if path is something more than just leading slashes */
111 } /* for(; (i = len = strlen(start)); ) */
113 /* kill trailing slash */
118 if ((start
[i
- 1] == '/') &&
119 (start
[i
- 2] != '/'))
126 /*****************************************************************************************/
128 void FRRefreshListview(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
130 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
131 struct TagItem set_tags
[] =
133 {ASLLV_Labels
, (IPTR
)&udata
->ListviewList
},
137 SetGadgetAttrsA((struct Gadget
*)udata
->Listview
, ld
->ld_Window
, NULL
, set_tags
);
140 /*****************************************************************************************/
142 void FRFreeListviewNode(struct ASLLVFileReqNode
*node
, struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
146 for(i
= 0; i
< ASLLV_MAXCOLUMNS
; i
++)
148 if (node
->text
[i
] && !(node
->dontfreetext
& (1 << i
)))
150 FreePooled(ld
->ld_IntReq
->ir_MemPool
, node
->text
[i
], strlen(node
->text
[i
]) + 1);
155 if (node
->type
== ASLLV_FRNTYPE_VOLUMES
)
156 FreePooled(ld
->ld_IntReq
->ir_MemPool
, node
->node
.ln_Name
, strlen(node
->node
.ln_Name
) + 1);
159 FreePooled(ld
->ld_IntReq
->ir_MemPool
, node
, sizeof(struct ASLLVFileReqNode
));
162 /*****************************************************************************************/
164 void FRFreeListviewList(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
166 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
167 struct ASLLVFileReqNode
*node
, *succ
;
168 struct TagItem set_tags
[] =
176 SetGadgetAttrsA((struct Gadget
*)udata
->Listview
, ld
->ld_Window
, NULL
, set_tags
);
179 ForeachNodeSafe(&udata
->ListviewList
, node
, succ
)
181 FRFreeListviewNode(node
, ld
, AslBase
);
184 NEWLIST(&udata
->ListviewList
);
188 /*****************************************************************************************/
190 void FRReSortListview(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
192 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
193 struct IntFileReq
*ifreq
= (struct IntFileReq
*)ld
->ld_IntReq
;
194 struct Node
*node
, *succ
;
195 struct List templist
;
196 struct TagItem set_tags
[] =
204 if (udata
->Flags
& FRFLG_SHOWING_VOLUMES
) return;
206 GetAttr(ASLLV_Top
, udata
->Listview
, &old_top
);
208 SetGadgetAttrsA((struct Gadget
*)udata
->Listview
, ld
->ld_Window
, NULL
, set_tags
);
212 ForeachNodeSafe(&udata
->ListviewList
, node
, succ
)
215 MARK_UNSELECTED(node
);
216 AddTail(&templist
, node
);
219 ForeachNodeSafe(&templist
, node
, succ
)
221 SortInNode(ifreq
, &udata
->ListviewList
, node
, (APTR
)FRCompareDirectoryNodes
, AslBase
);
224 set_tags
[0].ti_Data
= (IPTR
)&udata
->ListviewList
;
225 set_tags
[1].ti_Data
= old_top
;
227 SetGadgetAttrsA((struct Gadget
*)udata
->Listview
, ld
->ld_Window
, NULL
, set_tags
);
230 /*****************************************************************************************/
232 void FRDirectoryScanSymbolState(struct LayoutData
*ld
, BOOL on
, struct AslBase_intern
*AslBase
)
237 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
238 struct TagItem set_tags
[] =
244 SetAttrsA(udata
->DirectoryScanSymbol
, set_tags
);
245 RefreshGList((struct Gadget
*)udata
->DirectoryScanSymbol
, ld
->ld_Window
, NULL
, 1);
249 /*****************************************************************************************/
251 static void FRCalcColumnWidths(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
253 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
254 struct ASLLVFileReqNode
*node
;
257 for(i
= 0; i
< ASLLV_MAXCOLUMNS
; i
++)
259 udata
->LVColumnWidth
[i
] = 0;
262 ForeachNode(&udata
->ListviewList
, node
)
264 for(i
= 0; i
< ASLLV_MAXCOLUMNS
; i
++)
270 w
= TextLength(&ld
->ld_DummyRP
, node
->text
[i
], strlen(node
->text
[i
]));
271 if (w
> udata
->LVColumnWidth
[i
]) udata
->LVColumnWidth
[i
] = w
;
276 if (udata
->LVColumnWidth
[0] < FREQ_MIN_FILECOLUMNWIDTH
)
278 udata
->LVColumnWidth
[0] = FREQ_MIN_FILECOLUMNWIDTH
;
283 /*****************************************************************************************/
285 static WORD
FRCompareDirectoryNodes(struct IntFileReq
*ifreq
, struct ASLLVFileReqNode
*node1
,
286 struct ASLLVFileReqNode
*node2
, struct AslBase_intern
*AslBase
)
288 WORD pri1
= (node1
->subtype
> 0) ? 1 : 0;
289 WORD pri2
= (node2
->subtype
> 0) ? 1 : 0;
290 WORD diff
= (pri2
- pri1
) * -(ifreq
->ifr_SortDrawers
- 1);
295 switch(ifreq
->ifr_SortBy
)
297 case ASLFRSORTBY_Name
:
298 diff
= Stricmp(node1
->node
.ln_Name
, node2
->node
.ln_Name
);
301 case ASLFRSORTBY_Date
:
302 bigdiff
= CompareDates((const struct DateStamp
*)&node2
->date
, (const struct DateStamp
*)&node1
->date
);
306 } else if (bigdiff
> 0)
312 case ASLFRSORTBY_Size
:
313 if (node1
->filesize
< node2
->filesize
)
317 else if (node1
->filesize
> node2
->filesize
)
324 if (ifreq
->ifr_SortOrder
== ASLFRSORTORDER_Descend
) diff
= -diff
;
330 BOOL
FRGetDirectory(STRPTR path
, struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
332 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
333 struct IntFileReq
*ifreq
= (struct IntFileReq
*)ld
->ld_IntReq
;
334 struct FileRequester
*freq
= (struct FileRequester
*)ld
->ld_Req
;
335 struct FileInfoBlock
*fib
;
336 UBYTE parsedpattern
[MAX_PATTERN_LEN
* 2 + 3];
338 BOOL dopatternstring
= FALSE
, success
= FALSE
;
340 FRDirectoryScanSymbolState(ld
, TRUE
, AslBase
);
342 FRFreeListviewList(ld
, AslBase
);
343 FRMultiSelectOnOff(ld
, (ifreq
->ifr_Flags1
& FRF_DOMULTISELECT
) ? TRUE
: FALSE
, AslBase
);
345 if (ifreq
->ifr_Flags1
& FRF_DOPATTERNS
)
349 GetAttr(STRINGA_TextVal
, udata
->PatternGad
, (IPTR
*)&pat
);
352 if (ParsePatternNoCase(pat
, parsedpattern
, MAX_PATTERN_LEN
* 2 + 3) != -1)
354 dopatternstring
= TRUE
;
359 lock
= Lock(path
, ACCESS_READ
);
362 D(bug("Could not lock directory \"%s\"\n", path
));
366 fib
= AllocDosObject(DOS_FIB
, NULL
);
369 success
= Examine(lock
, fib
);
371 if (success
&& fib
->fib_DirEntryType
> 0) for(;;)
373 struct ASLLVFileReqNode
*node
;
374 BOOL ok
, addentry
= TRUE
;
376 ok
= ExNext(lock
, fib
);
380 if (IoErr() == ERROR_NO_MORE_ENTRIES
) break;
385 /* add to list checks which affect only files */
387 if (fib
->fib_DirEntryType
< 0)
389 if (ifreq
->ifr_Flags2
& FRF_DRAWERSONLY
) addentry
= FALSE
;
391 if (addentry
&& (ifreq
->ifr_Flags2
& FRF_REJECTICONS
))
393 WORD len
= strlen(fib
->fib_FileName
);
396 if (Stricmp(fib
->fib_FileName
+ len
- 5, ".info") == 0) addentry
= FALSE
;
400 if (addentry
&& dopatternstring
)
402 if (!MatchPatternNoCase(parsedpattern
, fib
->fib_FileName
)) addentry
= FALSE
;
405 if (addentry
&& ifreq
->ifr_AcceptPattern
)
407 if (!MatchPatternNoCase(ifreq
->ifr_AcceptPattern
, fib
->fib_FileName
)) addentry
= FALSE
;
410 if (addentry
&& ifreq
->ifr_RejectPattern
)
412 if (MatchPatternNoCase(ifreq
->ifr_RejectPattern
, fib
->fib_FileName
)) addentry
= FALSE
;
415 } /* if (fib->fib_DirEntryType < 0) */
417 /* add to list checks which affect both files and drawers */
419 if (addentry
&& ifreq
->ifr_HookFunc
&& (ifreq
->ifr_Flags1
& FRF_FILTERFUNC
))
421 struct AnchorPath ap
;
424 /* FIXME: is ap.ap_Info enough for the hookfunc */
426 memset(&ap
, 0, sizeof(ap
));
429 /* Some user filter functions access freq->fr_Drawer :-( */
431 old_frdrawer
= freq
->fr_Drawer
;
432 freq
->fr_Drawer
= path
;
434 D(bug("FRGetDirectory: 1 fr_Drawer 0x%lx <%s>\n",path
,path
));
436 /* return code 0 means, add to list */
441 UWORD
*funcptr
= ifreq
->ifr_HookFunc
;
442 ULONG
*p
= (ULONG
*)REG_A7
- 3;
444 p
[0] = (ULONG
)FRF_FILTERFUNC
;
449 if (*funcptr
>= (UWORD
)0xFF00)
452 REG_A4
= (ULONG
)ifreq
->ifr_IntReq
.ir_BasePtr
; /* Compatability */
454 ret
= (ULONG
)(*MyEmulHandle
->EmulCallDirect68k
)(funcptr
);
456 if (*funcptr
>= (UWORD
)0xFF00)
465 if (ifreq
->ifr_HookFunc(FRF_FILTERFUNC
, &ap
, freq
) != 0)
469 freq
->fr_Drawer
= old_frdrawer
;
472 if (addentry
&& ifreq
->ifr_FilterFunc
)
474 struct AnchorPath ap
;
477 /* FIXME: is ap.ap_Info enough for the filterfunc */
479 memset(&ap
, 0, sizeof(ap
));
482 /* Some user filter functions access freq->fr_Drawer :-( */
484 old_frdrawer
= freq
->fr_Drawer
;
485 freq
->fr_Drawer
= path
;
487 D(bug("FRGetDirectory: 2 fr_Drawer 0x%lx <%s>\n",path
,path
));
489 /* return code TRUE (!= 0) means, add to list */
495 REG_A4
= (ULONG
)ifreq
->ifr_IntReq
.ir_BasePtr
; /* Compatability */
496 REG_A0
= (ULONG
)ifreq
->ifr_FilterFunc
;
497 REG_A2
= (ULONG
)freq
;
499 ret
= (*MyEmulHandle
->EmulCallDirect68k
)(ifreq
->ifr_FilterFunc
->h_Entry
);
505 if (CallHookPkt(ifreq
->ifr_FilterFunc
, freq
, &ap
) == 0)
509 freq
->fr_Drawer
= old_frdrawer
;
511 D(bug("FRGetDirectory: 3 fr_Drawer 0x%lx <%s>\n",old_frdrawer
,old_frdrawer
));
517 if ((node
= AllocPooled(ld
->ld_IntReq
->ir_MemPool
, sizeof(struct ASLLVFileReqNode
))))
520 char datebuffer
[LEN_DATSTRING
];
521 char timebuffer
[LEN_DATSTRING
];
523 if (fib
->fib_FileName
[0])
525 node
->text
[0] = node
->node
.ln_Name
= PooledCloneString(fib
->fib_FileName
,
527 ld
->ld_IntReq
->ir_MemPool
,
531 if (fib
->fib_DirEntryType
> 0)
533 node
->text
[1] = GetString(MSG_FILEREQ_LV_DRAWER
, GetIR(ifreq
)->ir_Catalog
, AslBase
);
534 node
->dontfreetext
|= (1 << 1);
536 node
->text
[1] = PooledUIntegerToString(fib
->fib_Size
,
537 ld
->ld_IntReq
->ir_MemPool
,
540 MARK_DO_MULTISEL(node
);
543 dt
.dat_Stamp
= fib
->fib_Date
;
544 dt
.dat_Format
= FORMAT_DOS
;
546 dt
.dat_StrDay
= NULL
;
547 dt
.dat_StrDate
= datebuffer
;
548 dt
.dat_StrTime
= timebuffer
;
552 //sprintf(datebuffer, "%x8", fib->fib_Date.ds_Days);
553 //sprintf(timebuffer, "%x8", fib->fib_Date.ds_Minute);
555 node
->text
[2] = PooledCloneString(datebuffer
, NULL
, ld
->ld_IntReq
->ir_MemPool
, AslBase
);
556 node
->text
[3] = PooledCloneString(timebuffer
, NULL
, ld
->ld_IntReq
->ir_MemPool
, AslBase
);
559 if (fib
->fib_Comment
[0])
561 node
->text
[4] = PooledCloneString(fib
->fib_Comment
, NULL
, ld
->ld_IntReq
->ir_MemPool
, AslBase
);
565 node
->date
= fib
->fib_Date
;
566 node
->filesize
= fib
->fib_Size
;
567 node
->type
= ASLLV_FRNTYPE_DIRECTORY
;
568 node
->subtype
= fib
->fib_DirEntryType
;
570 SortInNode(ifreq
, &udata
->ListviewList
, &node
->node
, (APTR
)FRCompareDirectoryNodes
, AslBase
);
573 } /* if (addentry) */
575 } /* foreach file in directory */
577 FreeDosObject(DOS_FIB
, fib
);
579 } /* if (DosObject allocated) */
583 } /* if (directory locked) */
585 udata
->LVColumnAlign
[0] = ASLLV_ALIGN_LEFT
; /* File/Dir name */
586 udata
->LVColumnAlign
[1] = ASLLV_ALIGN_RIGHT
; /* Size/"Drawer" */
587 udata
->LVColumnAlign
[2] = ASLLV_ALIGN_LEFT
; /* Date */
588 udata
->LVColumnAlign
[3] = ASLLV_ALIGN_LEFT
; /* Time */
589 udata
->LVColumnAlign
[4] = ASLLV_ALIGN_LEFT
; /* Comment */
591 FRCalcColumnWidths(ld
, AslBase
);
592 FRRefreshListview(ld
, AslBase
);
594 udata
->Flags
&= ~FRFLG_SHOWING_VOLUMES
;
596 FRDirectoryScanSymbolState(ld
, FALSE
, AslBase
);
601 /*****************************************************************************************/
603 static WORD
FRCompareVolumeNodes(struct IntFileReq
*ifreq
, struct ASLLVFileReqNode
*node1
,
604 struct ASLLVFileReqNode
*node2
, struct AslBase_intern
*AslBase
)
606 WORD pri1
, pri2
, diff
;
608 switch(node1
->subtype
)
621 switch(node2
->subtype
)
635 if (!diff
) diff
= Stricmp(node1
->node
.ln_Name
, node2
->node
.ln_Name
);
640 /*****************************************************************************************/
642 BOOL
FRGetVolumes(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
644 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
645 struct IntFileReq
*ifreq
= (struct IntFileReq
*)ld
->ld_IntReq
;
646 struct DosList
*dlist
;
649 FRDirectoryScanSymbolState(ld
, TRUE
, AslBase
);
651 FRFreeListviewList(ld
, AslBase
);
652 FRMultiSelectOnOff(ld
, FALSE
, AslBase
);
654 dlist
= LockDosList(LDF_READ
| LDF_VOLUMES
| LDF_ASSIGNS
);
656 while ((dlist
= NextDosEntry(dlist
, LDF_VOLUMES
| LDF_ASSIGNS
)) != NULL
)
658 struct ASLLVFileReqNode
*node
;
660 if ((node
= AllocPooled(ld
->ld_IntReq
->ir_MemPool
, sizeof(struct ASLLVFileReqNode
))))
663 char *name
= BADDR(dlist
->dol_Name
);
666 node
->text
[0] = PooledCloneStringLen(&name
[1], name
[0], ":", sizeof(":"), ld
->ld_IntReq
->ir_MemPool
, AslBase
);
667 node
->node
.ln_Name
= PooledCloneStringLen(&name
[1], name
[0], NULL
, 0, ld
->ld_IntReq
->ir_MemPool
, AslBase
);
670 char *name
= dlist
->dol_Ext
.dol_AROS
.dol_DevName
;
673 node
->text
[0] = node
->node
.ln_Name
= PooledCloneString(name
, ":", ld
->ld_IntReq
->ir_MemPool
, AslBase
);
677 switch(dlist
->dol_Type
)
682 node
->text
[1] = GetString(MSG_FILEREQ_LV_ASSIGN
, GetIR(ifreq
)->ir_Catalog
, AslBase
);
683 node
->dontfreetext
|= (1 << 1);
689 struct DosList
*dl
= LockDosList(LDF_DEVICES
| LDF_READ
);
691 while ((dl
= NextDosEntry(dl
, LDF_DEVICES
)))
693 /* This works for most filesystems */
694 if (dl
->dol_Task
== dlist
->dol_Task
)
696 STRPTR devname
= (STRPTR
)BADDR(dl
->dol_Name
);
697 ULONG devlen
= *devname
++;
699 if (devname
[devlen
-1] == 0) devlen
--;
701 node
->text
[1] = AllocPooled(ld
->ld_IntReq
->ir_MemPool
, devlen
+ 3);
702 node
->text
[1][0] = '(';
703 strncpy(&node
->text
[1][1], devname
, devlen
);
704 node
->text
[1][devlen
+1] = ')';
705 node
->text
[1][devlen
+2] = 0;
711 UnLockDosList(LDF_DEVICES
| LDF_READ
);
720 node
->type
= ASLLV_FRNTYPE_VOLUMES
;
721 node
->subtype
= dlist
->dol_Type
;
723 SortInNode(ifreq
, &udata
->ListviewList
, &node
->node
, (APTR
)FRCompareVolumeNodes
, AslBase
);
729 UnLockDosList(LDF_READ
| LDF_VOLUMES
| LDF_ASSIGNS
);
731 udata
->LVColumnAlign
[0] = ASLLV_ALIGN_LEFT
;
732 udata
->LVColumnAlign
[1] = ASLLV_ALIGN_RIGHT
;
734 FRCalcColumnWidths(ld
, AslBase
);
735 FRRefreshListview(ld
, AslBase
);
737 udata
->Flags
|= FRFLG_SHOWING_VOLUMES
;
739 FRDirectoryScanSymbolState(ld
, FALSE
, AslBase
);
744 /*****************************************************************************************/
746 void FRSetPath(STRPTR path
, struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
748 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
749 struct TagItem set_tags
[] =
751 {STRINGA_TextVal
, path
? (IPTR
)path
: (IPTR
)"" },
755 SetGadgetAttrsA((struct Gadget
*)udata
->PathGad
, ld
->ld_Window
, NULL
, set_tags
);
758 /*****************************************************************************************/
760 BOOL
FRNewPath(STRPTR path
, struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
762 char pathstring
[MAX_PATH_LEN
];
765 strcpy(pathstring
, path
);
768 FRSetPath(pathstring
, ld
, AslBase
);
770 result
= FRGetDirectory(pathstring
, ld
, AslBase
);
775 /*****************************************************************************************/
777 BOOL
FRAddPath(STRPTR path
, struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
779 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
780 char pathstring
[MAX_PATH_LEN
], *gadpath
;
783 GetAttr(STRINGA_TextVal
, udata
->PathGad
, (IPTR
*)&gadpath
);
785 strcpy(pathstring
, gadpath
);
786 AddPart(pathstring
, path
, MAX_PATH_LEN
);
788 result
= FRNewPath(pathstring
, ld
, AslBase
);
794 /*****************************************************************************************/
796 BOOL
FRParentPath(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
798 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
799 char pathstring
[MAX_PATH_LEN
], *gadpath
;
803 GetAttr(STRINGA_TextVal
, udata
->PathGad
, (IPTR
*)&gadpath
);
805 strcpy(pathstring
, gadpath
);
808 len
= strlen(pathstring
);
811 strcpy(pathstring
, "/");
813 else if (len
< MAX_PATH_LEN
- 3)
815 switch(pathstring
[len
- 1])
819 strcat(pathstring
, "/");
823 strcat(pathstring
, "//");
829 result
= FRNewPath(pathstring
, ld
, AslBase
);
835 /*****************************************************************************************/
837 void FRSetFile(STRPTR file
, struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
839 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
840 struct TagItem set_tags
[] =
842 {STRINGA_TextVal
, file
? (IPTR
)file
: (IPTR
)"" },
846 SetGadgetAttrsA((struct Gadget
*)udata
->FileGad
, ld
->ld_Window
, NULL
, set_tags
);
849 /*****************************************************************************************/
851 void FRChangeActiveLVItem(struct LayoutData
*ld
, WORD delta
, UWORD quali
, struct Gadget
*gad
, struct AslBase_intern
*AslBase
)
853 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
854 struct IntFileReq
*ifreq
= (struct IntFileReq
*)ld
->ld_IntReq
;
855 struct ASLLVFileReqNode
*node
;
856 IPTR active
, total
, visible
;
857 struct Gadget
*mainstrgad
;
858 struct TagItem set_tags
[] =
861 {ASLLV_MakeVisible
, 0 },
865 GetAttr(ASLLV_Active
, udata
->Listview
, &active
);
866 GetAttr(ASLLV_Total
, udata
->Listview
, &total
);
867 GetAttr(ASLLV_Visible
, udata
->Listview
, &visible
);
869 mainstrgad
= (struct Gadget
*)((ifreq
->ifr_Flags2
& FRF_DRAWERSONLY
) ? udata
->PathGad
: udata
->FileGad
);
871 if (total
< 1) return;
873 if (quali
& (IEQUALIFIER_LSHIFT
| IEQUALIFIER_RSHIFT
))
875 delta
*= (visible
- 1);
877 else if (quali
& (IEQUALIFIER_LALT
| IEQUALIFIER_RALT
| IEQUALIFIER_CONTROL
))
881 else if (gad
&& (gad
== mainstrgad
))
883 /* try to jump to first item which matches text in string gadget,
884 but only if text in string gadget mismatches actual active
885 item's text (in this case move normally = one step)) */
887 char buffer
[MAX_FILE_LEN
];
892 GetAttr(STRINGA_TextVal
, (Object
*)gad
, (IPTR
*)&val
);
895 len
= strlen(buffer
);
896 if (len
> 0) if (buffer
[len
- 1] == '/') buffer
[--len
] = '\0';
900 if (((LONG
)active
) >= 0)
902 if ((node
= (struct ASLLVFileReqNode
*)FindListNode(&udata
->ListviewList
, (WORD
)active
)))
904 if (stricmp(node
->node
.ln_Name
, buffer
) == 0) dojump
= FALSE
;
911 ForeachNode(&udata
->ListviewList
, node
)
913 if (Strnicmp((CONST_STRPTR
)node
->node
.ln_Name
, (CONST_STRPTR
)buffer
, len
) == 0)
931 if (((LONG
)active
) < 0) active
= 0;
932 if (active
>= total
) active
= total
- 1;
934 set_tags
[0].ti_Data
= set_tags
[1].ti_Data
= active
;
936 SetGadgetAttrsA((struct Gadget
*)udata
->Listview
, ld
->ld_Window
, NULL
, set_tags
);
938 if ((node
= (struct ASLLVFileReqNode
*)FindListNode(&udata
->ListviewList
, (WORD
)active
)))
940 if (ifreq
->ifr_Flags2
& FRF_DRAWERSONLY
)
942 FRSetPath(node
->node
.ln_Name
, ld
, AslBase
);
944 char pathstring
[MAX_FILE_LEN
];
946 strcpy(pathstring
, node
->node
.ln_Name
);
947 if ((node
->subtype
> 0) && (!(udata
->Flags
& FRFLG_SHOWING_VOLUMES
)))
949 strcat(pathstring
, "/");
952 FRSetFile(pathstring
, ld
, AslBase
);
958 ActivateGadget(gad
, ld
->ld_Window
, NULL
);
960 FRActivateMainStringGadget(ld
, AslBase
);
964 /*****************************************************************************************/
966 void FRActivateMainStringGadget(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
968 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
969 struct IntFileReq
*ifreq
= (struct IntFileReq
*)ld
->ld_IntReq
;
971 if (ifreq
->ifr_Flags2
& FRF_DRAWERSONLY
)
973 ActivateGadget((struct Gadget
*)udata
->PathGad
, ld
->ld_Window
, NULL
);
975 ActivateGadget((struct Gadget
*)udata
->FileGad
, ld
->ld_Window
, NULL
);
979 /*****************************************************************************************/
981 void FRMultiSelectOnOff(struct LayoutData
*ld
, BOOL onoff
, struct AslBase_intern
*AslBase
)
983 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
984 struct TagItem set_tags
[] =
986 {ASLLV_DoMultiSelect
, onoff
},
990 SetGadgetAttrsA((struct Gadget
*)udata
->Listview
, ld
->ld_Window
, NULL
, set_tags
);
993 /*****************************************************************************************/
995 void FRSetPattern(STRPTR pattern
, struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
997 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
998 struct TagItem set_tags
[] =
1000 {STRINGA_TextVal
, pattern
? (IPTR
)pattern
: (IPTR
)"" },
1004 SetGadgetAttrsA((struct Gadget
*)udata
->PatternGad
, ld
->ld_Window
, NULL
, set_tags
);
1007 /*****************************************************************************************/
1009 void FRSelectRequester(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
1011 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
1012 struct IntFileReq
*ifreq
= (struct IntFileReq
*)ld
->ld_IntReq
;
1013 STRPTR oldpattern
= udata
->SelectPattern
;
1015 udata
->SelectPattern
= REQ_String(GetString(MSG_FILEREQ_SELECT_TITLE
, GetIR(ifreq
)->ir_Catalog
, AslBase
),
1016 oldpattern
? oldpattern
: (STRPTR
)"#?",
1017 GetString(MSG_FILEREQ_SELECT_OK
, GetIR(ifreq
)->ir_Catalog
, AslBase
),
1018 GetString(MSG_FILEREQ_SELECT_CANCEL
, GetIR(ifreq
)->ir_Catalog
, AslBase
),
1022 if (oldpattern
) MyFreeVecPooled(oldpattern
, AslBase
);
1024 if (udata
->SelectPattern
)
1026 LONG patternlen
= strlen(udata
->SelectPattern
);
1030 STRPTR parsedpattern
;
1032 parsedpattern
= MyAllocVecPooled(ld
->ld_IntReq
->ir_MemPool
, patternlen
* 2 + 3, AslBase
);
1035 if (ParsePatternNoCase(udata
->SelectPattern
, parsedpattern
, patternlen
* 2 + 3) != -1)
1037 struct ASLLVFileReqNode
*node
;
1039 if (udata
->Flags
& FRFLG_SHOWING_VOLUMES
)
1043 GetAttr(STRINGA_TextVal
, udata
->PathGad
, (IPTR
*)&dir
);
1044 FRGetDirectory(dir
, ld
, AslBase
);
1047 SetGadgetAttrs((struct Gadget
*)udata
->Listview
, ld
->ld_Window
, NULL
, ASLLV_Active
, -1,
1050 ForeachNode(&udata
->ListviewList
, node
)
1052 if (IS_MULTISEL(node
) && node
->node
.ln_Name
)
1054 if (MatchPatternNoCase(parsedpattern
, node
->node
.ln_Name
))
1056 MARK_SELECTED(node
);
1058 MARK_UNSELECTED(node
);
1063 RefreshGList((struct Gadget
*)udata
->Listview
, ld
->ld_Window
, NULL
, 1);
1066 MyFreeVecPooled(parsedpattern
, AslBase
);
1068 } /* if (parsedpattern) */
1070 } /* if (udata->SelectPattern[0]) */
1072 } /* if (udata->SelectPattern) */
1076 /*****************************************************************************************/
1078 void FRDeleteRequester(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
1080 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
1081 struct IntFileReq
*ifreq
= (struct IntFileReq
*)ld
->ld_IntReq
;
1082 STRPTR name
= NULL
, name2
, s
;
1084 GetAttr(STRINGA_TextVal
, udata
->PathGad
, (IPTR
*)&name
);
1086 if (ifreq
->ifr_Flags2
& FRF_DRAWERSONLY
)
1088 name
= name2
= VecPooledCloneString(name
, NULL
, ld
->ld_IntReq
->ir_MemPool
, AslBase
);
1090 GetAttr(STRINGA_TextVal
, udata
->FileGad
, (IPTR
*)&name2
);
1092 if ((s
= MyAllocVecPooled(ld
->ld_IntReq
->ir_MemPool
, strlen(name
) + strlen(name2
) + 4, AslBase
)))
1095 AddPart(s
, name2
, 10000);
1100 if (name
) if (name
[0])
1102 struct EasyStruct es
;
1104 es
.es_StructSize
= sizeof(es
);
1106 es
.es_Title
= GetString(MSG_FILEREQ_DELETE_TITLE
, GetIR(ifreq
)->ir_Catalog
, AslBase
);
1107 es
.es_TextFormat
= GetString(MSG_FILEREQ_DELETE_MSG
, GetIR(ifreq
)->ir_Catalog
, AslBase
);
1108 es
.es_GadgetFormat
= GetString(MSG_FILEREQ_DELETE_OKCANCEL
, GetIR(ifreq
)->ir_Catalog
, AslBase
);
1110 if (EasyRequestArgs(ld
->ld_Window
, &es
, NULL
, &name
) == 1)
1112 if (DeleteFile(name
) && !(udata
->Flags
& FRFLG_SHOWING_VOLUMES
))
1114 struct ASLLVFileReqNode
*node
;
1115 struct TagItem set_tags
[] =
1117 {ASLLV_Labels
, 0 },
1123 GetAttr(ASLLV_Top
, udata
->Listview
, &top
);
1124 SetGadgetAttrsA((struct Gadget
*)udata
->Listview
, ld
->ld_Window
, NULL
, set_tags
);
1126 ForeachNode(&udata
->ListviewList
, node
)
1128 if (node
->node
.ln_Name
)
1130 if (stricmp(node
->node
.ln_Name
, name2
) == 0)
1132 Remove(&node
->node
);
1133 FRFreeListviewNode(node
, ld
, AslBase
);
1139 set_tags
[0].ti_Data
= (IPTR
)&udata
->ListviewList
;
1140 set_tags
[1].ti_Data
= top
;
1141 SetGadgetAttrsA((struct Gadget
*)udata
->Listview
, ld
->ld_Window
, NULL
, set_tags
);
1144 } /* if (DeleteFile(name) && !(udata->Flags & FRFLG_SHOWING_VOLUMES)) */
1146 } /* if (EasyRequestArgs(ld->ld_Window, &es, NULL, &name) == 1) */
1148 } /* if (name) if (name[0]) */
1150 if (name
) MyFreeVecPooled(name
, AslBase
);
1153 /*****************************************************************************************/
1155 void FRNewDrawerRequester(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
1157 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
1158 struct IntFileReq
*ifreq
= (struct IntFileReq
*)ld
->ld_IntReq
;
1159 STRPTR path
, dirname
;
1160 BPTR lock
, lock2
, olddir
;
1162 GetAttr(STRINGA_TextVal
, udata
->PathGad
, (IPTR
*)&path
);
1164 lock
= Lock(path
, SHARED_LOCK
);
1167 olddir
= CurrentDir(lock
);
1169 if ((dirname
= REQ_String(GetString(MSG_FILEREQ_CREATEDRAWER_TITLE
, GetIR(ifreq
)->ir_Catalog
, AslBase
),
1170 GetString(MSG_FILEREQ_CREATEDRAWER_DEFNAME
, GetIR(ifreq
)->ir_Catalog
, AslBase
),
1171 GetString(MSG_FILEREQ_CREATEDRAWER_OK
, GetIR(ifreq
)->ir_Catalog
, AslBase
),
1172 GetString(MSG_FILEREQ_CREATEDRAWER_CANCEL
, GetIR(ifreq
)->ir_Catalog
, AslBase
),
1176 if ((lock2
= CreateDir(dirname
)))
1178 if (!(udata
->Flags
& FRFLG_SHOWING_VOLUMES
))
1180 struct TagItem set_tags
[] =
1187 GetAttr(ASLLV_Top
, udata
->Listview
, &top
);
1189 FRGetDirectory(path
, ld
, AslBase
);
1191 set_tags
[0].ti_Data
= top
;
1192 SetGadgetAttrsA((struct Gadget
*)udata
->Listview
, ld
->ld_Window
, NULL
, set_tags
);
1197 } /* if ((lock2 = CreateDir(dirname))) */
1199 MyFreeVecPooled(dirname
, AslBase
);
1201 }; /* if ((dirname = REQ_String(... */
1210 /*****************************************************************************************/
1212 void FRRenameRequester(struct LayoutData
*ld
, struct AslBase_intern
*AslBase
)
1214 struct FRUserData
*udata
= (struct FRUserData
*)ld
->ld_UserData
;
1215 struct IntFileReq
*ifreq
= (struct IntFileReq
*)ld
->ld_IntReq
;
1216 STRPTR path
, file
, newname
;
1217 BPTR lock
, lock2
, olddir
;
1219 if (ifreq
->ifr_Flags2
& FRF_DRAWERSONLY
) return;
1221 GetAttr(STRINGA_TextVal
, udata
->FileGad
, (IPTR
*)&file
);
1222 if (!file
[0]) return;
1224 GetAttr(STRINGA_TextVal
, udata
->PathGad
, (IPTR
*)&path
);
1226 lock
= Lock(path
, SHARED_LOCK
);
1229 olddir
= CurrentDir(lock
);
1231 lock2
= Lock(file
, SHARED_LOCK
);
1236 if ((newname
= REQ_String(GetString(MSG_FILEREQ_RENAME_TITLE
, GetIR(ifreq
)->ir_Catalog
, AslBase
),
1238 GetString(MSG_FILEREQ_RENAME_OK
, GetIR(ifreq
)->ir_Catalog
, AslBase
),
1239 GetString(MSG_FILEREQ_RENAME_CANCEL
, GetIR(ifreq
)->ir_Catalog
, AslBase
),
1243 if (Rename(file
, newname
))
1245 FRSetFile(newname
, ld
, AslBase
);
1247 if (!(udata
->Flags
& FRFLG_SHOWING_VOLUMES
))
1249 struct TagItem set_tags
[] =
1256 GetAttr(ASLLV_Top
, udata
->Listview
, &top
);
1258 FRGetDirectory(path
, ld
, AslBase
);
1260 set_tags
[0].ti_Data
= top
;
1261 SetGadgetAttrsA((struct Gadget
*)udata
->Listview
, ld
->ld_Window
, NULL
, set_tags
);
1264 } /* if (Rename(file, newname)) */
1266 MyFreeVecPooled(newname
, AslBase
);
1268 }; /* if ((newname = REQ_String(... */
1279 /*****************************************************************************************/