define __KERNEL_STRICT_NAMES to avoid inclusion of kernel types on systems that carry...
[cake.git] / workbench / libs / muimaster / classes / dirlist.c
blob3ae0207495e4f063f24b442cdc4e2692c1b57c5d
1 /*
2 Copyright © 2002-2006, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/memory.h>
9 #include <dos/exall.h>
10 #include <dos/datetime.h>
11 #include <clib/alib_protos.h>
12 #include <proto/exec.h>
13 #include <proto/dos.h>
14 #include <proto/intuition.h>
15 #include <proto/utility.h>
16 #include <proto/muimaster.h>
18 #include <string.h>
19 #include <stdio.h>
21 #include "mui.h"
22 #include "muimaster_intern.h"
23 #include "support.h"
24 #include "support_classes.h"
25 #include "dirlist_private.h"
27 extern struct Library *MUIMasterBase;
29 AROS_UFH3S(APTR, construct_func,
30 AROS_UFHA(struct Hook *, hook, A0),
31 AROS_UFHA(APTR, pool, A2),
32 AROS_UFHA(struct Dirlist_Entry *, entry, A1))
34 AROS_USERFUNC_INIT
36 struct Dirlist_Entry *new;
38 if ((new = AllocPooled(pool, sizeof(*new))))
40 *new = *entry;
42 return new;
44 AROS_USERFUNC_EXIT
47 AROS_UFH3S(void, destruct_func,
48 AROS_UFHA(struct Hook *, hook, A0),
49 AROS_UFHA(APTR, pool, A2),
50 AROS_UFHA(struct Dirlist_Entry *, entry, A1))
52 AROS_USERFUNC_INIT
54 FreePooled(pool, entry, sizeof(struct Dirlist_Entry));
56 AROS_USERFUNC_EXIT
59 AROS_UFH3S(LONG, display_func,
60 AROS_UFHA(struct Hook *, hook, A0),
61 AROS_UFHA(char **, array, A2),
62 AROS_UFHA(struct Dirlist_Entry *, entry, A1))
64 AROS_USERFUNC_INIT
66 struct Dirlist_DATA *data = hook->h_Data;
67 struct DateTime dt;
69 /* MUI: name | size | Date | Time | Protection | Comment */
70 if (entry)
72 *array++ = entry->fib.fib_FileName;
74 if (entry->fib.fib_DirEntryType > 0)
76 *array++ = "\33I[6:22]";
78 else
80 snprintf(data->size_string, sizeof(data->size_string), "%d", entry->fib.fib_Size);
81 *array++ = data->size_string;
84 dt.dat_Stamp = entry->fib.fib_Date;
85 dt.dat_Format = FORMAT_DOS;
86 dt.dat_Flags = 0;
87 dt.dat_StrDay = NULL;
88 dt.dat_StrDate = data->date_string;
89 dt.dat_StrTime = data->time_string;
91 DateToStr(&dt);
93 *array++ = data->date_string;
94 *array++ = data->time_string;
96 data->prot_string[0] = (entry->fib.fib_Protection & FIBF_SCRIPT) ? 's' : '-';
97 data->prot_string[1] = (entry->fib.fib_Protection & FIBF_PURE) ? 'p' : '-';
98 data->prot_string[2] = (entry->fib.fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
99 data->prot_string[3] = (entry->fib.fib_Protection & FIBF_READ) ? '-' : 'r';
100 data->prot_string[4] = (entry->fib.fib_Protection & FIBF_WRITE) ? '-' : 'w';
101 data->prot_string[5] = (entry->fib.fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
102 data->prot_string[6] = (entry->fib.fib_Protection & FIBF_DELETE ) ? '-' : 'd';
103 data->prot_string[7] = '\0';
105 *array++ = data->prot_string;
106 *array = entry->fib.fib_Comment;
108 else
110 *array++ = "Name";
111 *array++ = "Size";
112 *array++ = "Date";
113 *array++ = "Time";
114 *array++ = "Flags";
115 *array = "Comment";
118 return 0;
120 AROS_USERFUNC_EXIT
123 IPTR Dirlist__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg);
125 IPTR Dirlist__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
127 STRPTR format = (STRPTR)GetTagData(MUIA_List_Format, 0, msg->ops_AttrList);
129 obj = (Object *)DoSuperNewTags
131 cl, obj, NULL,
132 MUIA_List_Format, format
133 ? TAG_IGNORE
134 : (IPTR)",P=\33r,,,,",
135 TAG_MORE, (IPTR) msg->ops_AttrList
138 if (obj)
140 struct Dirlist_DATA *data = INST_DATA(cl, obj);
142 data->status = MUIV_Dirlist_Status_Invalid;
144 data->construct_hook.h_Entry = (HOOKFUNC)construct_func;
145 data->destruct_hook.h_Entry = (HOOKFUNC)destruct_func;
146 data->display_hook.h_Entry = (HOOKFUNC)display_func;
147 data->display_hook.h_Data = data;
149 SetAttrs(obj, MUIA_List_ConstructHook, (IPTR)&data->construct_hook,
150 MUIA_List_DestructHook, (IPTR)&data->destruct_hook,
151 MUIA_List_DisplayHook, (IPTR)&data->display_hook,
152 TAG_DONE);
154 Dirlist__OM_SET(cl, obj, msg);
157 return (IPTR)obj;
160 IPTR Dirlist__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
162 struct Dirlist_DATA *data = INST_DATA(cl, obj);
164 FreeVec(data->path);
166 return DoSuperMethodA(cl, obj, msg);
169 static void ReadDirectory(Object *obj, struct Dirlist_DATA *data)
171 struct FileInfoBlock *fib;
172 BPTR lock;
174 if ((fib = AllocDosObject(DOS_FIB, NULL)))
176 if ((lock = Lock(data->directory, SHARED_LOCK)))
178 BOOL success;
180 success = Examine(lock, fib);
182 if (success && (fib->fib_DirEntryType > 0))
184 for(;;)
186 BOOL isdir;
188 success = ExNext(lock, fib);
190 if (!success)
192 if (IoErr() == ERROR_NO_MORE_ENTRIES) success = TRUE;
194 break;
197 isdir = (fib->fib_DirEntryType > 0);
199 if (data->filterhook)
201 struct ExAllData ead = {0};
203 ead.ed_Name = fib->fib_FileName;
204 ead.ed_Type = fib->fib_DirEntryType;
205 ead.ed_Size = fib->fib_Size;
206 ead.ed_Prot = fib->fib_Protection;
207 ead.ed_Days = fib->fib_Date.ds_Days;
208 ead.ed_Mins = fib->fib_Date.ds_Minute;
209 ead.ed_Ticks = fib->fib_Date.ds_Tick;
210 ead.ed_Comment = fib->fib_Comment;
212 if (!CallHookPkt(data->filterhook, obj, &ead)) continue;
214 else
216 if (isdir && data->filesonly) continue;
217 if (!isdir && data->drawersonly) continue;
219 if (data->rejecticons)
221 WORD len = strlen(fib->fib_FileName);
223 if (len >= 5)
225 if (stricmp(fib->fib_FileName + len - 5, ".info") == 0) continue;
229 if (!isdir || data->filterdrawers)
231 if (data->acceptpattern)
233 if (!MatchPatternNoCase(data->acceptpattern, fib->fib_FileName)) continue;
236 if (data->rejectpattern)
238 if (MatchPatternNoCase(data->rejectpattern, fib->fib_FileName)) continue;
242 if (isdir)
244 set(obj, MUIA_Dirlist_NumDrawers, ++data->numdrawers);
246 else
248 set(obj, MUIA_Dirlist_NumFiles, ++data->numfiles);
249 set(obj, MUIA_Dirlist_NumBytes, data->numbytes + fib->fib_Size);
252 DoMethod(obj, MUIM_List_InsertSingle, (IPTR)fib, MUIV_List_Insert_Bottom);
254 } /* no filterhook */
256 } /* for(;;) */
258 set(obj, MUIA_Dirlist_Status, MUIV_Dirlist_Status_Valid);
261 } /* if (success && (fib->fib_DirEntryType > 0)) */
263 UnLock(lock);
265 } /* if ((lock = Lock(data->directory, SHARED_LOCK))) */
266 FreeDosObject(DOS_FIB, fib);
268 } /* if ((fib = AllocDosObject(DOS_FIB, NULL))) */
271 IPTR Dirlist__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
273 struct Dirlist_DATA *data = INST_DATA(cl, obj);
274 struct TagItem *tag, *tags;
275 BOOL directory_changed = FALSE;
277 for (tags = msg->ops_AttrList; (tag = NextTagItem((const struct TagItem **)&tags)); )
279 IPTR tidata = tag->ti_Data;
281 switch (tag->ti_Tag)
284 case MUIA_Dirlist_AcceptPattern:
285 data->acceptpattern = (STRPTR)tidata;
286 break;
288 case MUIA_Dirlist_Directory:
289 data->directory = (STRPTR)tidata;
290 directory_changed = TRUE;
291 break;
293 case MUIA_Dirlist_DrawersOnly:
294 data->drawersonly = tidata ? TRUE : FALSE;
295 break;
297 case MUIA_Dirlist_FilesOnly:
298 data->filesonly = tidata ? TRUE : FALSE;
299 break;
301 case MUIA_Dirlist_FilterDrawers:
302 data->filterdrawers = tidata ? TRUE : FALSE;
303 break;
305 case MUIA_Dirlist_FilterHook:
306 data->filterhook = (struct Hook *)tidata;
307 break;
309 case MUIA_Dirlist_MultiSelDirs:
310 data->multiseldirs = tidata ? TRUE : FALSE;
311 break;
313 case MUIA_Dirlist_RejectIcons:
314 data->rejecticons = tidata ? TRUE : FALSE;
315 break;
317 case MUIA_Dirlist_RejectPattern:
318 data->rejectpattern = (STRPTR)tidata;
319 break;
321 case MUIA_Dirlist_SortDirs:
322 data->sortdirs = tidata ? TRUE : FALSE;
323 break;
325 case MUIA_Dirlist_SortHighLow:
326 data->sorthighlow = tidata ? TRUE : FALSE;
327 break;
329 case MUIA_Dirlist_SortType:
330 data->sorttype = tidata;
331 break;
333 case MUIA_Dirlist_Status:
334 data->status = tidata;
335 break;
337 } /* switch (tag->ti_Tag) */
339 } /* for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); ) */
341 if (directory_changed)
343 if (data->status == MUIV_Dirlist_Status_Valid)
345 DoMethod(obj, MUIM_List_Clear);
347 SetAttrs(obj, MUIA_Dirlist_Status , MUIV_Dirlist_Status_Invalid,
348 MUIA_Dirlist_NumBytes , 0 ,
349 MUIA_Dirlist_NumFiles , 0 ,
350 MUIA_Dirlist_NumDrawers, 0 ,
351 TAG_DONE );
355 if (data->directory)
357 ReadDirectory(obj, data);
362 return (msg->MethodID == OM_SET) ? DoSuperMethodA(cl, obj, (Msg)msg) : 0;
366 IPTR Dirlist__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
368 struct Dirlist_DATA *data = INST_DATA(cl, obj);
370 #define STORE *(msg->opg_Storage)
372 switch(msg->opg_AttrID)
374 case MUIA_Dirlist_AcceptPattern:
375 STORE = (IPTR)data->acceptpattern;
376 return 1;
378 case MUIA_Dirlist_Directory:
379 STORE = (IPTR)data->directory;
380 return 1;
382 case MUIA_Dirlist_DrawersOnly:
383 STORE = data->drawersonly;
384 return 1;
386 case MUIA_Dirlist_FilesOnly:
387 STORE = data->filesonly;
388 return 1;
390 case MUIA_Dirlist_FilterDrawers:
391 STORE = data->filterdrawers;
392 return 1;
394 case MUIA_Dirlist_FilterHook:
395 STORE = (IPTR)data->filterhook;
396 return 1;
398 case MUIA_Dirlist_MultiSelDirs:
399 STORE = data->multiseldirs;
400 return 1;
402 case MUIA_Dirlist_NumBytes:
403 STORE = data->numbytes;
404 return 1;
406 case MUIA_Dirlist_NumFiles:
407 STORE = data->numfiles;
408 return 1;
410 case MUIA_Dirlist_NumDrawers:
411 STORE = data->numdrawers;
412 return 1;
414 case MUIA_Dirlist_Path:
415 if (data->path)
417 FreeVec(data->path);
418 data->path = NULL;
421 STORE = 0;
423 if (data->status == MUIV_Dirlist_Status_Valid)
425 struct FileInfoBlock *fib;
427 DoMethod(obj, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &fib);
429 if (fib)
431 WORD len = strlen(fib->fib_FileName) + strlen(data->directory) + 3;
433 data->path = AllocVec(len, MEMF_ANY);
434 if (data->path)
436 strcpy(data->path, data->directory);
437 if (AddPart(data->path, fib->fib_FileName, len))
439 STORE = (IPTR)data->path;
444 return 1;
446 case MUIA_Dirlist_RejectIcons:
447 STORE = data->rejecticons;
448 return 1;
450 case MUIA_Dirlist_RejectPattern:
451 STORE = (IPTR)data->rejectpattern;
452 return 1;
454 case MUIA_Dirlist_SortDirs:
455 STORE = data->sortdirs;
456 return 1;
458 case MUIA_Dirlist_SortHighLow:
459 STORE = data->sorthighlow;
460 return 1;
462 case MUIA_Dirlist_SortType:
463 STORE = data->sorttype;
464 return 1;
466 case MUIA_Dirlist_Status:
467 STORE = data->status;
468 return 1;
472 return DoSuperMethodA(cl, obj, (Msg)msg);
477 IPTR Dirlist__MUIM_Dirlist_ReRead(struct IClass *cl, Object *obj, struct MUIP_Dirlist_ReRead *msg)
479 struct Dirlist_DATA *data = INST_DATA(cl, obj);
481 set(obj, MUIA_List_Quiet, TRUE);
482 if (data->status == MUIV_Dirlist_Status_Valid)
484 DoMethod(obj, MUIM_List_Clear);
486 SetAttrs(obj, MUIA_Dirlist_Status , MUIV_Dirlist_Status_Invalid,
487 MUIA_Dirlist_NumBytes , 0 ,
488 MUIA_Dirlist_NumFiles , 0 ,
489 MUIA_Dirlist_NumDrawers, 0 ,
490 TAG_DONE );
493 if (data->directory)
495 ReadDirectory(obj, data);
497 set(obj, MUIA_List_Quiet, FALSE);
499 return 0;
503 #if ZUNE_BUILTIN_DIRLIST
504 BOOPSI_DISPATCHER(IPTR, Dirlist_Dispatcher, cl, obj, msg)
506 switch (msg->MethodID)
508 case OM_NEW: return Dirlist__OM_NEW(cl, obj, (struct opSet *)msg);
509 case OM_DISPOSE: return Dirlist__OM_DISPOSE(cl, obj, msg);
510 case OM_SET: return Dirlist__OM_SET(cl, obj, (struct opSet *)msg);
511 case OM_GET: return Dirlist__OM_GET(cl, obj, (struct opGet *)msg);
512 case MUIM_Dirlist_ReRead: return Dirlist__MUIM_Dirlist_ReRead(cl, obj, (struct opGet *)msg);
513 default: return DoSuperMethodA(cl, obj, msg);
516 BOOPSI_DISPATCHER_END
518 const struct __MUIBuiltinClass _MUI_Dirlist_desc =
520 MUIC_Dirlist,
521 MUIC_List,
522 sizeof(struct Dirlist_DATA),
523 (void*)Dirlist_Dispatcher
525 #endif /* ZUNE_BUILTIN_DIRLIST */