Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / asl / filereqsupport.c
blob16965809e1aed53b2fcc7f65c08440a9d02a3e77
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
4 */
7 #include <proto/exec.h>
8 #include <proto/dos.h>
9 #include <proto/intuition.h>
10 #include <proto/graphics.h>
11 #include <proto/utility.h>
12 #include <exec/memory.h>
13 #include <dos/dos.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>
19 #include <stdio.h>
20 #include <string.h>
21 #include <clib/macros.h>
23 #include "asl_intern.h"
24 #include "filereqsupport.h"
25 #include "filereqhooks.h"
26 #include "specialreq.h"
27 #include "layout.h"
29 #define CATCOMP_NUMBERS
30 #include "strings.h"
32 #define SDEBUG 0
33 #define DEBUG 0
34 //#define ADEBUG 0
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)
48 char *start;
49 WORD i, len;
51 /* tricky slash stuff:
53 work:pictures/ --> work:pictures
54 work:pictures// --> work:
55 work:pictures/// --> work:/
56 work:pictures//// --> work://
57 /pics/ --> /pics
58 /pics// --> /
59 /pics/// --> //
60 /pics//pics --> /pics
61 /pics//pics/ --> /pics
62 /pics/scans//// --> //
66 start = strrchr(pathstring,':');
67 if (start)
69 start++;
70 } else {
71 start = pathstring;
74 for(; (i = len = strlen(start)); )
76 char *sp = start;
78 /* skip leading slashes */
80 while(i && (*sp == '/'))
82 i--;
83 sp++;
86 if (i)
88 char *sp2;
90 if((sp2 = strstr(sp, "//")))
92 char *sp3 = sp2;
94 while(sp3 > sp)
96 char c = sp3[-1];
98 if (c == '/') break;
99 sp3--;
102 memmove(sp3, sp2 + 2, strlen(sp2 + 2) + 1);
104 continue;
107 } /* if path is something more than just leading slashes */
109 break;
111 } /* for(; (i = len = strlen(start)); ) */
113 /* kill trailing slash */
115 i = strlen(start);
116 if (i >= 2)
118 if ((start[i - 1] == '/') &&
119 (start[i - 2] != '/'))
121 start[--i] = '\0';
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 },
134 {TAG_DONE }
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)
144 WORD i;
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);
154 if (node->type == ASLLV_FRNTYPE_VOLUMES)
155 FreePooled(ld->ld_IntReq->ir_MemPool, node->node.ln_Name, strlen(node->node.ln_Name) + 1);
157 FreePooled(ld->ld_IntReq->ir_MemPool, node, sizeof(struct ASLLVFileReqNode));
160 /*****************************************************************************************/
162 void FRFreeListviewList(struct LayoutData *ld, struct AslBase_intern *AslBase)
164 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
165 struct ASLLVFileReqNode *node, *succ;
166 struct TagItem set_tags [] =
168 {ASLLV_Labels , 0 },
169 {TAG_DONE }
172 if (udata->Listview)
174 SetGadgetAttrsA((struct Gadget *)udata->Listview, ld->ld_Window, NULL, set_tags);
177 ForeachNodeSafe(&udata->ListviewList, node, succ)
179 FRFreeListviewNode(node, ld, AslBase);
182 NEWLIST(&udata->ListviewList);
186 /*****************************************************************************************/
188 void FRReSortListview(struct LayoutData *ld, struct AslBase_intern *AslBase)
190 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
191 struct IntFileReq *ifreq = (struct IntFileReq *)ld->ld_IntReq;
192 struct Node *node, *succ;
193 struct List templist;
194 struct TagItem set_tags [] =
196 {ASLLV_Labels , 0 },
197 {ASLLV_Top , 0 },
198 {TAG_DONE }
200 IPTR old_top;
202 if (udata->Flags & FRFLG_SHOWING_VOLUMES) return;
204 GetAttr(ASLLV_Top, udata->Listview, &old_top);
206 SetGadgetAttrsA((struct Gadget *)udata->Listview, ld->ld_Window, NULL, set_tags);
208 NEWLIST(&templist);
210 ForeachNodeSafe(&udata->ListviewList, node, succ)
212 Remove(node);
213 MARK_UNSELECTED(node);
214 AddTail(&templist, node);
217 ForeachNodeSafe(&templist, node, succ)
219 SortInNode(ifreq, &udata->ListviewList, node, (APTR)FRCompareDirectoryNodes, AslBase);
222 set_tags[0].ti_Data = (IPTR)&udata->ListviewList;
223 set_tags[1].ti_Data = old_top;
225 SetGadgetAttrsA((struct Gadget *)udata->Listview, ld->ld_Window, NULL, set_tags);
228 /*****************************************************************************************/
230 void FRDirectoryScanSymbolState(struct LayoutData *ld, BOOL on, struct AslBase_intern *AslBase)
233 if (ld->ld_Window)
235 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
236 struct TagItem set_tags[] =
238 {GA_Selected , on },
239 {TAG_DONE }
242 SetAttrsA(udata->DirectoryScanSymbol, set_tags);
243 RefreshGList((struct Gadget *)udata->DirectoryScanSymbol, ld->ld_Window, NULL, 1);
247 /*****************************************************************************************/
249 static void FRCalcColumnWidths(struct LayoutData *ld, struct AslBase_intern *AslBase)
251 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
252 struct ASLLVFileReqNode *node;
253 WORD i;
255 for(i = 0; i < ASLLV_MAXCOLUMNS; i++)
257 udata->LVColumnWidth[i] = 0;
260 ForeachNode(&udata->ListviewList, node)
262 for(i = 0; i < ASLLV_MAXCOLUMNS; i++)
264 WORD w;
266 if (node->text[i])
268 w = TextLength(&ld->ld_DummyRP, node->text[i], strlen(node->text[i]));
269 if (w > udata->LVColumnWidth[i]) udata->LVColumnWidth[i] = w;
274 if (udata->LVColumnWidth[0] < FREQ_MIN_FILECOLUMNWIDTH)
276 udata->LVColumnWidth[0] = FREQ_MIN_FILECOLUMNWIDTH;
281 /*****************************************************************************************/
283 static WORD FRCompareDirectoryNodes(struct IntFileReq *ifreq, struct ASLLVFileReqNode *node1,
284 struct ASLLVFileReqNode *node2, struct AslBase_intern *AslBase)
286 WORD pri1 = (node1->subtype > 0) ? 1 : 0;
287 WORD pri2 = (node2->subtype > 0) ? 1 : 0;
288 WORD diff = (pri2 - pri1) * -(ifreq->ifr_SortDrawers - 1);
289 LONG bigdiff;
291 if (!diff)
293 switch(ifreq->ifr_SortBy)
295 case ASLFRSORTBY_Name:
296 diff = Stricmp(node1->node.ln_Name, node2->node.ln_Name);
297 break;
299 case ASLFRSORTBY_Date:
300 bigdiff = CompareDates((const struct DateStamp *)&node2->date, (const struct DateStamp *)&node1->date);
301 if (bigdiff < 0)
303 diff = -1;
304 } else if (bigdiff > 0)
306 diff = 1;
308 break;
310 case ASLFRSORTBY_Size:
311 if (node1->filesize < node2->filesize)
313 diff = -1;
315 else if (node1->filesize > node2->filesize)
317 diff = 1;
319 break;
322 if (ifreq->ifr_SortOrder == ASLFRSORTORDER_Descend) diff = -diff;
325 return diff;
328 BOOL FRGetDirectory(STRPTR path, struct LayoutData *ld, struct AslBase_intern *AslBase)
330 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
331 struct IntFileReq *ifreq = (struct IntFileReq *)ld->ld_IntReq;
332 struct FileRequester *freq = (struct FileRequester *)ld->ld_Req;
333 struct FileInfoBlock *fib;
334 UBYTE parsedpattern[MAX_PATTERN_LEN * 2 + 3];
335 BPTR lock;
336 BOOL dopatternstring = FALSE, success = FALSE;
338 FRDirectoryScanSymbolState(ld, TRUE, AslBase);
340 FRFreeListviewList(ld, AslBase);
341 FRMultiSelectOnOff(ld, (ifreq->ifr_Flags1 & FRF_DOMULTISELECT) ? TRUE : FALSE, AslBase);
343 if (ifreq->ifr_Flags1 & FRF_DOPATTERNS)
345 char *pat;
347 GetAttr(STRINGA_TextVal, udata->PatternGad, (IPTR *)&pat);
348 if (pat[0])
350 if (ParsePatternNoCase(pat, parsedpattern, MAX_PATTERN_LEN * 2 + 3) != -1)
352 dopatternstring = TRUE;
357 lock = Lock(path, ACCESS_READ);
358 if (!lock)
360 D(bug("Could not lock directory \"%s\"\n", path));
362 else
364 fib = AllocDosObject(DOS_FIB, NULL);
365 if (fib)
367 success = Examine(lock, fib);
369 if (success && fib->fib_DirEntryType > 0) for(;;)
371 struct ASLLVFileReqNode *node;
372 BOOL ok, addentry = TRUE;
374 ok = ExNext(lock, fib);
376 if (!ok)
378 if (IoErr() == ERROR_NO_MORE_ENTRIES) break;
379 success = FALSE;
380 continue;
383 /* add to list checks which affect only files */
385 if (fib->fib_DirEntryType < 0)
387 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY) addentry = FALSE;
389 if (addentry && (ifreq->ifr_Flags2 & FRF_REJECTICONS))
391 WORD len = strlen(fib->fib_FileName);
392 if (len >= 5)
394 if (Stricmp(fib->fib_FileName + len - 5, ".info") == 0) addentry = FALSE;
398 if (addentry && dopatternstring)
400 if (!MatchPatternNoCase(parsedpattern, fib->fib_FileName)) addentry = FALSE;
403 if (addentry && ifreq->ifr_AcceptPattern)
405 if (!MatchPatternNoCase(ifreq->ifr_AcceptPattern, fib->fib_FileName)) addentry = FALSE;
408 if (addentry && ifreq->ifr_RejectPattern)
410 if (MatchPatternNoCase(ifreq->ifr_RejectPattern, fib->fib_FileName)) addentry = FALSE;
413 } /* if (fib->fib_DirEntryType < 0) */
415 /* add to list checks which affect both files and drawers */
417 if (addentry && ifreq->ifr_HookFunc && (ifreq->ifr_Flags1 & FRF_FILTERFUNC))
419 struct AnchorPath ap;
420 STRPTR old_frdrawer;
422 /* FIXME: is ap.ap_Info enough for the hookfunc */
424 memset(&ap, 0, sizeof(ap));
425 ap.ap_Info = *fib;
427 /* Some user filter functions access freq->fr_Drawer :-( */
429 old_frdrawer = freq->fr_Drawer;
430 freq->fr_Drawer = path;
432 D(bug("FRGetDirectory: 1 fr_Drawer 0x%lx <%s>\n",path,path));
434 /* return code 0 means, add to list */
436 #ifdef __MORPHOS__
438 ULONG ret;
439 UWORD *funcptr = ifreq->ifr_HookFunc;
440 ULONG *p = (ULONG *)REG_A7 - 3;
442 p[0] = (ULONG)FRF_FILTERFUNC;
443 p[1] = (ULONG)&ap;
444 p[2] = (ULONG)freq;
445 REG_A7 = (ULONG)p;
447 if (*funcptr >= (UWORD)0xFF00)
448 REG_A7 -= 4;
450 REG_A4 = (ULONG)ifreq->ifr_IntReq.ir_BasePtr; /* Compatability */
452 ret = (ULONG)(*MyEmulHandle->EmulCallDirect68k)(funcptr);
454 if (*funcptr >= (UWORD)0xFF00)
455 REG_A7 += 4;
457 REG_A7 += (3*4);
459 if (ret != 0)
460 addentry = FALSE;
462 #else
463 if (ifreq->ifr_HookFunc(FRF_FILTERFUNC, &ap, freq) != 0)
464 addentry = FALSE;
465 #endif
467 freq->fr_Drawer = old_frdrawer;
470 if (addentry && ifreq->ifr_FilterFunc)
472 struct AnchorPath ap;
473 STRPTR old_frdrawer;
475 /* FIXME: is ap.ap_Info enough for the filterfunc */
477 memset(&ap, 0, sizeof(ap));
478 ap.ap_Info = *fib;
480 /* Some user filter functions access freq->fr_Drawer :-( */
482 old_frdrawer = freq->fr_Drawer;
483 freq->fr_Drawer = path;
485 D(bug("FRGetDirectory: 2 fr_Drawer 0x%lx <%s>\n",path,path));
487 /* return code TRUE (!= 0) means, add to list */
489 #ifdef __MORPHOS__
491 ULONG ret;
493 REG_A4 = (ULONG)ifreq->ifr_IntReq.ir_BasePtr; /* Compatability */
494 REG_A0 = (ULONG)ifreq->ifr_FilterFunc;
495 REG_A2 = (ULONG)freq;
496 REG_A1 = (ULONG)&ap;
497 ret = (*MyEmulHandle->EmulCallDirect68k)(ifreq->ifr_FilterFunc->h_Entry);
499 if (ret == 0)
500 addentry = FALSE;
502 #else
503 if (CallHookPkt(ifreq->ifr_FilterFunc, freq, &ap) == 0)
504 addentry = FALSE;
505 #endif
507 freq->fr_Drawer = old_frdrawer;
509 D(bug("FRGetDirectory: 3 fr_Drawer 0x%lx <%s>\n",old_frdrawer,old_frdrawer));
513 if (addentry)
515 if ((node = AllocPooled(ld->ld_IntReq->ir_MemPool, sizeof(struct ASLLVFileReqNode))))
517 struct DateTime dt;
518 char datebuffer[LEN_DATSTRING];
519 char timebuffer[LEN_DATSTRING];
521 if (fib->fib_FileName[0])
523 node->text[0] = node->node.ln_Name = PooledCloneString(fib->fib_FileName,
524 NULL,
525 ld->ld_IntReq->ir_MemPool,
526 AslBase);
529 if (fib->fib_DirEntryType > 0)
531 node->text[1] = GetString(MSG_FILEREQ_LV_DRAWER, GetIR(ifreq)->ir_Catalog, AslBase);
532 node->dontfreetext |= (1 << 1);
533 } else {
534 node->text[1] = PooledUIntegerToString(fib->fib_Size,
535 ld->ld_IntReq->ir_MemPool,
536 AslBase);
538 MARK_DO_MULTISEL(node);
541 dt.dat_Stamp = fib->fib_Date;
542 dt.dat_Format = FORMAT_DOS;
543 dt.dat_Flags = 0;
544 dt.dat_StrDay = NULL;
545 dt.dat_StrDate = datebuffer;
546 dt.dat_StrTime = timebuffer;
548 if (DateToStr(&dt))
550 //sprintf(datebuffer, "%x8", fib->fib_Date.ds_Days);
551 //sprintf(timebuffer, "%x8", fib->fib_Date.ds_Minute);
553 node->text[2] = PooledCloneString(datebuffer, NULL, ld->ld_IntReq->ir_MemPool, AslBase);
554 node->text[3] = PooledCloneString(timebuffer, NULL, ld->ld_IntReq->ir_MemPool, AslBase);
557 if (fib->fib_Comment[0])
559 node->text[4] = PooledCloneString(fib->fib_Comment, NULL, ld->ld_IntReq->ir_MemPool, AslBase);
562 node->userdata = ld;
563 node->date = fib->fib_Date;
564 node->filesize = fib->fib_Size;
565 node->type = ASLLV_FRNTYPE_DIRECTORY;
566 node->subtype = fib->fib_DirEntryType;
568 SortInNode(ifreq, &udata->ListviewList, &node->node, (APTR)FRCompareDirectoryNodes, AslBase);
571 } /* if (addentry) */
573 } /* foreach file in directory */
575 FreeDosObject(DOS_FIB, fib);
577 } /* if (DosObject allocated) */
579 UnLock(lock);
581 } /* if (directory locked) */
583 udata->LVColumnAlign[0] = ASLLV_ALIGN_LEFT; /* File/Dir name */
584 udata->LVColumnAlign[1] = ASLLV_ALIGN_RIGHT; /* Size/"Drawer" */
585 udata->LVColumnAlign[2] = ASLLV_ALIGN_LEFT; /* Date */
586 udata->LVColumnAlign[3] = ASLLV_ALIGN_LEFT; /* Time */
587 udata->LVColumnAlign[4] = ASLLV_ALIGN_LEFT; /* Comment */
589 FRCalcColumnWidths(ld, AslBase);
590 FRRefreshListview(ld, AslBase);
592 udata->Flags &= ~FRFLG_SHOWING_VOLUMES;
594 FRDirectoryScanSymbolState(ld, FALSE, AslBase);
596 return success;
599 /*****************************************************************************************/
601 static WORD FRCompareVolumeNodes(struct IntFileReq *ifreq, struct ASLLVFileReqNode *node1,
602 struct ASLLVFileReqNode *node2, struct AslBase_intern *AslBase)
604 WORD pri1, pri2, diff;
606 switch(node1->subtype)
608 case DLT_DIRECTORY:
609 case DLT_LATE:
610 case DLT_NONBINDING:
611 pri1 = 0;
612 break;
614 default:
615 pri1 = 1;
616 break;
619 switch(node2->subtype)
621 case DLT_DIRECTORY:
622 case DLT_LATE:
623 case DLT_NONBINDING:
624 pri2 = 0;
625 break;
627 default:
628 pri2 = 1;
629 break;
632 diff = pri2 - pri1;
633 if (!diff) diff = Stricmp(node1->node.ln_Name, node2->node.ln_Name);
635 return diff;
638 /*****************************************************************************************/
640 BOOL FRGetVolumes(struct LayoutData *ld, struct AslBase_intern *AslBase)
642 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
643 struct IntFileReq *ifreq = (struct IntFileReq *)ld->ld_IntReq;
644 struct DosList *dlist;
645 BOOL success = TRUE;
647 FRDirectoryScanSymbolState(ld, TRUE, AslBase);
649 FRFreeListviewList(ld, AslBase);
650 FRMultiSelectOnOff(ld, FALSE, AslBase);
652 dlist = LockDosList(LDF_READ | LDF_VOLUMES | LDF_ASSIGNS);
654 while ((dlist = NextDosEntry(dlist, LDF_VOLUMES | LDF_ASSIGNS)) != NULL)
656 struct ASLLVFileReqNode *node;
658 if ((node = AllocPooled(ld->ld_IntReq->ir_MemPool, sizeof(struct ASLLVFileReqNode))))
660 if (dlist->dol_Name)
662 char *name = AROS_BSTR_ADDR(dlist->dol_Name);
663 ULONG len = AROS_BSTR_strlen(dlist->dol_Name);
665 node->text[0] = PooledCloneStringLen(name, len, ":", 1, ld->ld_IntReq->ir_MemPool, AslBase);
666 node->node.ln_Name = PooledCloneStringLen(name, len, NULL, 0, ld->ld_IntReq->ir_MemPool, AslBase);
669 switch(dlist->dol_Type)
671 case DLT_DIRECTORY:
672 case DLT_LATE:
673 case DLT_NONBINDING:
674 node->text[1] = GetString(MSG_FILEREQ_LV_ASSIGN, GetIR(ifreq)->ir_Catalog, AslBase);
675 node->dontfreetext |= (1 << 1);
676 break;
678 case DLT_VOLUME:
680 struct DosList *dl = LockDosList(LDF_DEVICES | LDF_READ);
682 while ((dl = NextDosEntry(dl, LDF_DEVICES)))
684 /* This works for most filesystems */
685 if (dl->dol_Task == dlist->dol_Task)
687 STRPTR devname = AROS_BSTR_ADDR(dl->dol_Name);
688 ULONG devlen = AROS_BSTR_strlen(dl->dol_Name);
690 if (devname[devlen-1] == 0) devlen--;
692 node->text[1] = AllocPooled(ld->ld_IntReq->ir_MemPool, devlen + 3);
693 node->text[1][0] = '(';
694 strncpy(&node->text[1][1], devname, devlen);
695 node->text[1][devlen+1] = ')';
696 node->text[1][devlen+2] = 0;
698 break;
702 UnLockDosList(LDF_DEVICES | LDF_READ);
704 break;
707 node->userdata = ld;
709 node->filesize = 0;
710 node->type = ASLLV_FRNTYPE_VOLUMES;
711 node->subtype = dlist->dol_Type;
713 SortInNode(ifreq, &udata->ListviewList, &node->node, (APTR)FRCompareVolumeNodes, AslBase);
719 UnLockDosList(LDF_READ | LDF_VOLUMES | LDF_ASSIGNS);
721 udata->LVColumnAlign[0] = ASLLV_ALIGN_LEFT;
722 udata->LVColumnAlign[1] = ASLLV_ALIGN_RIGHT;
724 FRCalcColumnWidths(ld, AslBase);
725 FRRefreshListview(ld, AslBase);
727 udata->Flags |= FRFLG_SHOWING_VOLUMES;
729 FRDirectoryScanSymbolState(ld, FALSE, AslBase);
731 return success;
734 /*****************************************************************************************/
736 void FRSetPath(STRPTR path, struct LayoutData *ld, struct AslBase_intern *AslBase)
738 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
739 struct TagItem set_tags[] =
741 {STRINGA_TextVal , path ? (IPTR)path : (IPTR)"" },
742 {TAG_DONE }
745 SetGadgetAttrsA((struct Gadget *)udata->PathGad, ld->ld_Window, NULL, set_tags);
748 /*****************************************************************************************/
750 BOOL FRNewPath(STRPTR path, struct LayoutData *ld, struct AslBase_intern *AslBase)
752 char pathstring[MAX_PATH_LEN];
753 BOOL result = FALSE;
755 strcpy(pathstring, path);
756 fixpath(pathstring);
758 FRSetPath(pathstring, ld, AslBase);
760 result = FRGetDirectory(pathstring, ld, AslBase);
762 return result;
765 /*****************************************************************************************/
767 BOOL FRAddPath(STRPTR path, struct LayoutData *ld, struct AslBase_intern *AslBase)
769 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
770 char pathstring[MAX_PATH_LEN], *gadpath;
771 BOOL result;
773 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&gadpath);
775 strcpy(pathstring, gadpath);
776 AddPart(pathstring, path, MAX_PATH_LEN);
778 result = FRNewPath(pathstring, ld, AslBase);
780 return result;
784 /*****************************************************************************************/
786 BOOL FRParentPath(struct LayoutData *ld, struct AslBase_intern *AslBase)
788 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
789 char pathstring[MAX_PATH_LEN], *gadpath;
790 WORD len;
791 BOOL result;
793 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&gadpath);
795 strcpy(pathstring, gadpath);
796 fixpath(pathstring);
798 len = strlen(pathstring);
799 if (len == 0)
801 strcpy(pathstring, "/");
803 else if (len < MAX_PATH_LEN - 3)
805 switch(pathstring[len - 1])
807 case '/':
808 case ':':
809 strcat(pathstring, "/");
810 break;
812 default:
813 strcat(pathstring, "//");
814 fixpath(pathstring);
815 break;
819 BPTR lock = Lock(pathstring, ACCESS_READ);
820 if (!lock)
822 D(bug("Could not lock parent directory (\"%s\"), let's reach volumes list\n", pathstring));
823 result = FRGetVolumes(ld, AslBase);
825 else
827 UnLock(lock);
828 result = FRNewPath(pathstring, ld, AslBase);
832 return result;
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)"" },
843 {TAG_DONE }
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[] =
860 {ASLLV_Active , 0 },
861 {ASLLV_MakeVisible , 0 },
862 {TAG_DONE }
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))
879 delta *= total;
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];
888 char *val;
889 WORD i, len;
890 BOOL dojump = TRUE;
892 GetAttr(STRINGA_TextVal, (Object *)gad, (IPTR *)&val);
893 strcpy(buffer, val);
895 len = strlen(buffer);
896 if (len > 0) if (buffer[len - 1] == '/') buffer[--len] = '\0';
898 if (len)
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;
908 if (dojump)
910 i = 0;
911 ForeachNode(&udata->ListviewList, node)
913 if (Strnicmp((CONST_STRPTR)node->node.ln_Name, (CONST_STRPTR)buffer, len) == 0)
915 active = i;
916 delta = 0;
917 break;
919 i++;
923 } /* if (dojump) */
925 } /* if (len) */
929 active += delta;
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);
943 } else {
944 char pathstring[MAX_FILE_LEN];
946 strcpy(pathstring, node->node.ln_Name);
947 if (node->subtype > 0)
949 if (udata->Flags & FRFLG_SHOWING_VOLUMES)
950 strcat(pathstring, ":");
951 else
952 strcat(pathstring, "/");
955 FRSetFile(pathstring, ld, AslBase);
959 if (gad)
961 ActivateGadget(gad, ld->ld_Window, NULL);
962 } else {
963 FRActivateMainStringGadget(ld, AslBase);
967 /*****************************************************************************************/
969 void FRActivateMainStringGadget(struct LayoutData *ld, struct AslBase_intern *AslBase)
971 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
972 struct IntFileReq *ifreq = (struct IntFileReq *)ld->ld_IntReq;
974 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY)
976 ActivateGadget((struct Gadget *)udata->PathGad, ld->ld_Window, NULL);
977 } else {
978 ActivateGadget((struct Gadget *)udata->FileGad, ld->ld_Window, NULL);
982 /*****************************************************************************************/
984 void FRMultiSelectOnOff(struct LayoutData *ld, BOOL onoff, struct AslBase_intern *AslBase)
986 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
987 struct TagItem set_tags[] =
989 {ASLLV_DoMultiSelect , onoff },
990 {TAG_DONE }
993 SetGadgetAttrsA((struct Gadget *)udata->Listview, ld->ld_Window, NULL, set_tags);
996 /*****************************************************************************************/
998 void FRSetPattern(STRPTR pattern, struct LayoutData *ld, struct AslBase_intern *AslBase)
1000 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
1001 struct TagItem set_tags[] =
1003 {STRINGA_TextVal , pattern ? (IPTR)pattern : (IPTR)"" },
1004 {TAG_DONE }
1007 SetGadgetAttrsA((struct Gadget *)udata->PatternGad, ld->ld_Window, NULL, set_tags);
1010 /*****************************************************************************************/
1012 void FRSelectRequester(struct LayoutData *ld, struct AslBase_intern *AslBase)
1014 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
1015 struct IntFileReq *ifreq = (struct IntFileReq *)ld->ld_IntReq;
1016 STRPTR oldpattern = udata->SelectPattern;
1018 udata->SelectPattern = REQ_String(GetString(MSG_FILEREQ_SELECT_TITLE, GetIR(ifreq)->ir_Catalog, AslBase),
1019 oldpattern ? oldpattern : (STRPTR)"#?",
1020 GetString(MSG_FILEREQ_SELECT_OK, GetIR(ifreq)->ir_Catalog, AslBase),
1021 GetString(MSG_FILEREQ_SELECT_CANCEL, GetIR(ifreq)->ir_Catalog, AslBase),
1023 AslBase);
1025 if (oldpattern) MyFreeVecPooled(oldpattern, AslBase);
1027 if (udata->SelectPattern)
1029 LONG patternlen = strlen(udata->SelectPattern);
1031 if (patternlen > 0)
1033 STRPTR parsedpattern;
1035 parsedpattern = MyAllocVecPooled(ld->ld_IntReq->ir_MemPool, patternlen * 2 + 3, AslBase);
1036 if (parsedpattern)
1038 if (ParsePatternNoCase(udata->SelectPattern, parsedpattern, patternlen * 2 + 3) != -1)
1040 struct ASLLVFileReqNode *node;
1042 if (udata->Flags & FRFLG_SHOWING_VOLUMES)
1044 UBYTE *dir;
1046 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&dir);
1047 FRGetDirectory(dir, ld, AslBase);
1050 SetGadgetAttrs((struct Gadget *)udata->Listview, ld->ld_Window, NULL, ASLLV_Active, -1,
1051 TAG_DONE);
1053 ForeachNode(&udata->ListviewList, node)
1055 if (IS_MULTISEL(node) && node->node.ln_Name)
1057 if (MatchPatternNoCase(parsedpattern, node->node.ln_Name))
1059 MARK_SELECTED(node);
1060 } else {
1061 MARK_UNSELECTED(node);
1066 RefreshGList((struct Gadget *)udata->Listview, ld->ld_Window, NULL, 1);
1069 MyFreeVecPooled(parsedpattern, AslBase);
1071 } /* if (parsedpattern) */
1073 } /* if (udata->SelectPattern[0]) */
1075 } /* if (udata->SelectPattern) */
1077 } /**/
1079 /*****************************************************************************************/
1081 void FRDeleteRequester(struct LayoutData *ld, struct AslBase_intern *AslBase)
1083 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
1084 struct IntFileReq *ifreq = (struct IntFileReq *)ld->ld_IntReq;
1085 STRPTR name = NULL, name2, s;
1087 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&name);
1089 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY)
1091 name = name2 = VecPooledCloneString(name, NULL, ld->ld_IntReq->ir_MemPool, AslBase);
1092 } else {
1093 GetAttr(STRINGA_TextVal, udata->FileGad, (IPTR *)&name2);
1095 if ((s = MyAllocVecPooled(ld->ld_IntReq->ir_MemPool, strlen(name) + strlen(name2) + 4, AslBase)))
1097 strcpy(s, name);
1098 AddPart(s, name2, 10000);
1099 name = s;
1103 if (name) if (name[0])
1105 D(bug("[ASL] delete() name = '%s'\n", name));
1106 struct EasyStruct es;
1108 es.es_StructSize = sizeof(es);
1109 es.es_Flags = 0;
1110 es.es_Title = GetString(MSG_FILEREQ_DELETE_TITLE , GetIR(ifreq)->ir_Catalog, AslBase);
1111 es.es_TextFormat = GetString(MSG_FILEREQ_DELETE_MSG , GetIR(ifreq)->ir_Catalog, AslBase);
1112 es.es_GadgetFormat = GetString(MSG_FILEREQ_DELETE_OKCANCEL, GetIR(ifreq)->ir_Catalog, AslBase);
1114 if (EasyRequestArgs(ld->ld_Window, &es, NULL, (RAWARG)&name) == 1)
1116 if (DeleteFile(name) && !(udata->Flags & FRFLG_SHOWING_VOLUMES))
1118 struct ASLLVFileReqNode *node;
1119 struct TagItem set_tags[] =
1121 {ASLLV_Labels , 0 },
1122 {ASLLV_Top , 0 },
1123 {TAG_DONE }
1125 IPTR top;
1127 GetAttr(ASLLV_Top, udata->Listview, &top);
1128 SetGadgetAttrsA((struct Gadget *)udata->Listview, ld->ld_Window, NULL, set_tags);
1130 ForeachNode(&udata->ListviewList, node)
1132 if (node->node.ln_Name)
1134 if (stricmp(node->node.ln_Name, name2) == 0)
1136 Remove(&node->node);
1137 FRFreeListviewNode(node, ld, AslBase);
1138 break;
1143 set_tags[0].ti_Data = (IPTR)&udata->ListviewList;
1144 set_tags[1].ti_Data = top;
1145 SetGadgetAttrsA((struct Gadget *)udata->Listview, ld->ld_Window, NULL, set_tags);
1148 } /* if (DeleteFile(name) && !(udata->Flags & FRFLG_SHOWING_VOLUMES)) */
1150 } /* if (EasyRequestArgs(ld->ld_Window, &es, NULL, &name) == 1) */
1152 } /* if (name) if (name[0]) */
1154 if (name) MyFreeVecPooled(name, AslBase);
1157 /*****************************************************************************************/
1159 void FRNewDrawerRequester(struct LayoutData *ld, struct AslBase_intern *AslBase)
1161 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
1162 struct IntFileReq *ifreq = (struct IntFileReq *)ld->ld_IntReq;
1163 STRPTR path, dirname;
1164 BPTR lock, lock2, olddir;
1166 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&path);
1168 lock = Lock(path, SHARED_LOCK);
1169 if (lock)
1171 olddir = CurrentDir(lock);
1173 if ((dirname = REQ_String(GetString(MSG_FILEREQ_CREATEDRAWER_TITLE, GetIR(ifreq)->ir_Catalog, AslBase),
1174 GetString(MSG_FILEREQ_CREATEDRAWER_DEFNAME, GetIR(ifreq)->ir_Catalog, AslBase),
1175 GetString(MSG_FILEREQ_CREATEDRAWER_OK, GetIR(ifreq)->ir_Catalog, AslBase),
1176 GetString(MSG_FILEREQ_CREATEDRAWER_CANCEL, GetIR(ifreq)->ir_Catalog, AslBase),
1178 AslBase)))
1180 if ((lock2 = CreateDir(dirname)))
1182 if (!(udata->Flags & FRFLG_SHOWING_VOLUMES))
1184 struct TagItem set_tags[] =
1186 {ASLLV_Top , 0 },
1187 {TAG_DONE }
1189 IPTR top;
1191 GetAttr(ASLLV_Top, udata->Listview, &top);
1193 FRGetDirectory(path, ld, AslBase);
1195 set_tags[0].ti_Data = top;
1196 SetGadgetAttrsA((struct Gadget *)udata->Listview, ld->ld_Window, NULL, set_tags);
1199 UnLock(lock2);
1201 } /* if ((lock2 = CreateDir(dirname))) */
1203 MyFreeVecPooled(dirname, AslBase);
1205 }; /* if ((dirname = REQ_String(... */
1207 CurrentDir(olddir);
1208 UnLock(lock);
1210 } /* if (lock) */
1214 /*****************************************************************************************/
1216 void FRRenameRequester(struct LayoutData *ld, struct AslBase_intern *AslBase)
1218 struct FRUserData *udata = (struct FRUserData *)ld->ld_UserData;
1219 struct IntFileReq *ifreq = (struct IntFileReq *)ld->ld_IntReq;
1220 STRPTR path, file, newname;
1221 BPTR lock, lock2, olddir;
1223 if (ifreq->ifr_Flags2 & FRF_DRAWERSONLY) return;
1225 GetAttr(STRINGA_TextVal, udata->FileGad, (IPTR *)&file);
1226 if (!file[0]) return;
1228 GetAttr(STRINGA_TextVal, udata->PathGad, (IPTR *)&path);
1230 lock = Lock(path, SHARED_LOCK);
1231 if (lock)
1233 olddir = CurrentDir(lock);
1235 lock2 = Lock(file, SHARED_LOCK);
1236 if (lock2)
1238 UnLock(lock2);
1240 if ((newname = REQ_String(GetString(MSG_FILEREQ_RENAME_TITLE, GetIR(ifreq)->ir_Catalog, AslBase),
1241 file,
1242 GetString(MSG_FILEREQ_RENAME_OK, GetIR(ifreq)->ir_Catalog, AslBase),
1243 GetString(MSG_FILEREQ_RENAME_CANCEL, GetIR(ifreq)->ir_Catalog, AslBase),
1245 AslBase)))
1247 if (Rename(file, newname))
1249 FRSetFile(newname, ld, AslBase);
1251 if (!(udata->Flags & FRFLG_SHOWING_VOLUMES))
1253 struct TagItem set_tags[] =
1255 {ASLLV_Top , 0 },
1256 {TAG_DONE }
1258 IPTR top;
1260 GetAttr(ASLLV_Top, udata->Listview, &top);
1262 FRGetDirectory(path, ld, AslBase);
1264 set_tags[0].ti_Data = top;
1265 SetGadgetAttrsA((struct Gadget *)udata->Listview, ld->ld_Window, NULL, set_tags);
1268 } /* if (Rename(file, newname)) */
1270 MyFreeVecPooled(newname, AslBase);
1272 }; /* if ((newname = REQ_String(... */
1274 } /* if (lock2) */
1276 CurrentDir(olddir);
1277 UnLock(lock);
1279 } /* if (lock) */
1283 /*****************************************************************************************/
1285 void FRDropFromDifferentDrawersRequester(struct LayoutData *ld, struct AslBase_intern *AslBase)
1287 struct IntFileReq *ifreq = (struct IntFileReq *)ld->ld_IntReq;
1288 struct EasyStruct es;
1290 es.es_StructSize = sizeof(es);
1291 es.es_Flags = 0;
1292 es.es_Title = GetString(MSG_FILEREQ_FOREIGNER_TITLE, GetIR(ifreq)->ir_Catalog, AslBase);
1293 es.es_TextFormat = GetString(MSG_FILEREQ_FOREIGNER_MSG , GetIR(ifreq)->ir_Catalog, AslBase);
1294 es.es_GadgetFormat = GetString(MSG_FILEREQ_FOREIGNER_OK , GetIR(ifreq)->ir_Catalog, AslBase);
1296 EasyRequestArgs(ld->ld_Window, &es, NULL, (RAWARG)&ld->ld_ForeignerFiles);
1299 /*****************************************************************************************/