Tabs to spaces, more consistent formatting.
[AROS.git] / workbench / libs / muimaster / classes / dirlist.c
blob3ab04e5052a431f2905827a0b9239674fdd9a762
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;
43 return new;
45 AROS_USERFUNC_EXIT
48 AROS_UFH3S(void, destruct_func,
49 AROS_UFHA(struct Hook *, hook, A0),
50 AROS_UFHA(APTR, pool, A2),
51 AROS_UFHA(struct Dirlist_Entry *, entry, A1))
53 AROS_USERFUNC_INIT
55 FreePooled(pool, entry, sizeof(struct Dirlist_Entry));
57 AROS_USERFUNC_EXIT
60 AROS_UFH3S(LONG, display_func,
61 AROS_UFHA(struct Hook *, hook, A0),
62 AROS_UFHA(char **, array, A2),
63 AROS_UFHA(struct Dirlist_Entry *, entry, A1))
65 AROS_USERFUNC_INIT
67 struct Dirlist_DATA *data = hook->h_Data;
68 struct DateTime dt;
70 /* MUI: name | size | Date | Time | Protection | Comment */
71 if (entry)
73 *array++ = entry->fib.fib_FileName;
75 if (entry->fib.fib_DirEntryType > 0)
77 *array++ = "\33I[6:22]";
79 else
81 snprintf(data->size_string, sizeof(data->size_string), "%ld",
82 (long)entry->fib.fib_Size);
83 *array++ = data->size_string;
86 dt.dat_Stamp = entry->fib.fib_Date;
87 dt.dat_Format = FORMAT_DOS;
88 dt.dat_Flags = 0;
89 dt.dat_StrDay = NULL;
90 dt.dat_StrDate = data->date_string;
91 dt.dat_StrTime = data->time_string;
93 DateToStr(&dt);
95 *array++ = data->date_string;
96 *array++ = data->time_string;
98 data->prot_string[0] =
99 (entry->fib.fib_Protection & FIBF_SCRIPT) ? 's' : '-';
100 data->prot_string[1] =
101 (entry->fib.fib_Protection & FIBF_PURE) ? 'p' : '-';
102 data->prot_string[2] =
103 (entry->fib.fib_Protection & FIBF_ARCHIVE) ? 'a' : '-';
104 data->prot_string[3] =
105 (entry->fib.fib_Protection & FIBF_READ) ? '-' : 'r';
106 data->prot_string[4] =
107 (entry->fib.fib_Protection & FIBF_WRITE) ? '-' : 'w';
108 data->prot_string[5] =
109 (entry->fib.fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
110 data->prot_string[6] =
111 (entry->fib.fib_Protection & FIBF_DELETE) ? '-' : 'd';
112 data->prot_string[7] = '\0';
114 *array++ = data->prot_string;
115 *array = entry->fib.fib_Comment;
117 else
119 *array++ = "Name";
120 *array++ = "Size";
121 *array++ = "Date";
122 *array++ = "Time";
123 *array++ = "Flags";
124 *array = "Comment";
127 return 0;
129 AROS_USERFUNC_EXIT
132 IPTR Dirlist__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg);
134 IPTR Dirlist__OM_NEW(struct IClass *cl, Object *obj, struct opSet *msg)
136 STRPTR format =
137 (STRPTR) GetTagData(MUIA_List_Format, 0, msg->ops_AttrList);
139 obj = (Object *) DoSuperNewTags
140 (cl, obj, NULL,
141 format ? TAG_IGNORE : MUIA_List_Format, (IPTR) ",P=\33r,,,,",
142 TAG_MORE, (IPTR) msg->ops_AttrList);
144 if (obj)
146 struct Dirlist_DATA *data = INST_DATA(cl, obj);
148 data->status = MUIV_Dirlist_Status_Invalid;
150 data->construct_hook.h_Entry = (HOOKFUNC) construct_func;
151 data->destruct_hook.h_Entry = (HOOKFUNC) destruct_func;
152 data->display_hook.h_Entry = (HOOKFUNC) display_func;
153 data->display_hook.h_Data = data;
155 SetAttrs(obj, MUIA_List_ConstructHook,
156 (IPTR) & data->construct_hook, MUIA_List_DestructHook,
157 (IPTR) & data->destruct_hook, MUIA_List_DisplayHook,
158 (IPTR) & data->display_hook, TAG_DONE);
160 Dirlist__OM_SET(cl, obj, msg);
163 return (IPTR) obj;
166 IPTR Dirlist__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
168 struct Dirlist_DATA *data = INST_DATA(cl, obj);
170 FreeVec(data->path);
172 return DoSuperMethodA(cl, obj, msg);
175 static void ReadDirectory(Object *obj, struct Dirlist_DATA *data)
177 struct FileInfoBlock *fib;
178 BPTR lock;
180 if ((fib = AllocDosObject(DOS_FIB, NULL)))
182 if ((lock = Lock(data->directory, SHARED_LOCK)))
184 BOOL success;
186 success = Examine(lock, fib);
188 if (success && (fib->fib_DirEntryType > 0))
190 for (;;)
192 BOOL isdir;
194 success = ExNext(lock, fib);
196 if (!success)
198 if (IoErr() == ERROR_NO_MORE_ENTRIES)
199 success = TRUE;
201 break;
204 isdir = (fib->fib_DirEntryType > 0);
206 if (data->filterhook)
208 struct ExAllData ead = { 0 };
210 ead.ed_Name = fib->fib_FileName;
211 ead.ed_Type = fib->fib_DirEntryType;
212 ead.ed_Size = fib->fib_Size;
213 ead.ed_Prot = fib->fib_Protection;
214 ead.ed_Days = fib->fib_Date.ds_Days;
215 ead.ed_Mins = fib->fib_Date.ds_Minute;
216 ead.ed_Ticks = fib->fib_Date.ds_Tick;
217 ead.ed_Comment = fib->fib_Comment;
219 if (!CallHookPkt(data->filterhook, obj, &ead))
220 continue;
222 else
224 if (isdir && data->filesonly)
225 continue;
226 if (!isdir && data->drawersonly)
227 continue;
229 if (data->rejecticons)
231 WORD len = strlen(fib->fib_FileName);
233 if (len >= 5)
235 if (stricmp(fib->fib_FileName + len - 5,
236 ".info") == 0)
237 continue;
241 if (!isdir || data->filterdrawers)
243 if (data->acceptpattern)
245 if (!MatchPatternNoCase(data->acceptpattern,
246 fib->fib_FileName))
247 continue;
250 if (data->rejectpattern)
252 if (MatchPatternNoCase(data->rejectpattern,
253 fib->fib_FileName))
254 continue;
258 if (isdir)
260 set(obj, MUIA_Dirlist_NumDrawers,
261 ++data->numdrawers);
263 else
265 set(obj, MUIA_Dirlist_NumFiles,
266 ++data->numfiles);
267 set(obj, MUIA_Dirlist_NumBytes,
268 data->numbytes + fib->fib_Size);
271 DoMethod(obj, MUIM_List_InsertSingle, (IPTR) fib,
272 MUIV_List_Insert_Bottom);
274 } /* no filterhook */
276 } /* for(;;) */
278 set(obj, MUIA_Dirlist_Status, MUIV_Dirlist_Status_Valid);
282 UnLock(lock);
285 FreeDosObject(DOS_FIB, fib);
289 IPTR Dirlist__OM_SET(struct IClass *cl, Object *obj, struct opSet *msg)
291 struct Dirlist_DATA *data = INST_DATA(cl, obj);
292 struct TagItem *tag, *tags;
293 BOOL directory_changed = FALSE;
295 for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags));)
297 IPTR tidata = tag->ti_Data;
299 switch (tag->ti_Tag)
302 case MUIA_Dirlist_AcceptPattern:
303 data->acceptpattern = (STRPTR) tidata;
304 break;
306 case MUIA_Dirlist_Directory:
307 data->directory = (STRPTR) tidata;
308 directory_changed = TRUE;
309 break;
311 case MUIA_Dirlist_DrawersOnly:
312 data->drawersonly = tidata ? TRUE : FALSE;
313 break;
315 case MUIA_Dirlist_FilesOnly:
316 data->filesonly = tidata ? TRUE : FALSE;
317 break;
319 case MUIA_Dirlist_FilterDrawers:
320 data->filterdrawers = tidata ? TRUE : FALSE;
321 break;
323 case MUIA_Dirlist_FilterHook:
324 data->filterhook = (struct Hook *)tidata;
325 break;
327 case MUIA_Dirlist_MultiSelDirs:
328 data->multiseldirs = tidata ? TRUE : FALSE;
329 break;
331 case MUIA_Dirlist_RejectIcons:
332 data->rejecticons = tidata ? TRUE : FALSE;
333 break;
335 case MUIA_Dirlist_RejectPattern:
336 data->rejectpattern = (STRPTR) tidata;
337 break;
339 case MUIA_Dirlist_SortDirs:
340 data->sortdirs = tidata ? TRUE : FALSE;
341 break;
343 case MUIA_Dirlist_SortHighLow:
344 data->sorthighlow = tidata ? TRUE : FALSE;
345 break;
347 case MUIA_Dirlist_SortType:
348 data->sorttype = tidata;
349 break;
351 case MUIA_Dirlist_Status:
352 data->status = tidata;
353 break;
358 if (directory_changed)
360 if (data->status == MUIV_Dirlist_Status_Valid)
362 DoMethod(obj, MUIM_List_Clear);
364 SetAttrs(obj, MUIA_Dirlist_Status, MUIV_Dirlist_Status_Invalid,
365 MUIA_Dirlist_NumBytes, 0,
366 MUIA_Dirlist_NumFiles, 0,
367 MUIA_Dirlist_NumDrawers, 0, TAG_DONE);
371 if (data->directory)
373 ReadDirectory(obj, data);
378 return (msg->MethodID == OM_SET) ? DoSuperMethodA(cl, obj,
379 (Msg) msg) : 0;
383 IPTR Dirlist__OM_GET(struct IClass *cl, Object *obj, struct opGet *msg)
385 struct Dirlist_DATA *data = INST_DATA(cl, obj);
387 #define STORE *(msg->opg_Storage)
389 switch (msg->opg_AttrID)
391 case MUIA_Dirlist_AcceptPattern:
392 STORE = (IPTR) data->acceptpattern;
393 return 1;
395 case MUIA_Dirlist_Directory:
396 STORE = (IPTR) data->directory;
397 return 1;
399 case MUIA_Dirlist_DrawersOnly:
400 STORE = data->drawersonly;
401 return 1;
403 case MUIA_Dirlist_FilesOnly:
404 STORE = data->filesonly;
405 return 1;
407 case MUIA_Dirlist_FilterDrawers:
408 STORE = data->filterdrawers;
409 return 1;
411 case MUIA_Dirlist_FilterHook:
412 STORE = (IPTR) data->filterhook;
413 return 1;
415 case MUIA_Dirlist_MultiSelDirs:
416 STORE = data->multiseldirs;
417 return 1;
419 case MUIA_Dirlist_NumBytes:
420 STORE = data->numbytes;
421 return 1;
423 case MUIA_Dirlist_NumFiles:
424 STORE = data->numfiles;
425 return 1;
427 case MUIA_Dirlist_NumDrawers:
428 STORE = data->numdrawers;
429 return 1;
431 case MUIA_Dirlist_Path:
432 if (data->path)
434 FreeVec(data->path);
435 data->path = NULL;
438 STORE = 0;
440 if (data->status == MUIV_Dirlist_Status_Valid)
442 struct FileInfoBlock *fib;
444 DoMethod(obj, MUIM_List_GetEntry, MUIV_List_GetEntry_Active,
445 &fib);
447 if (fib)
449 WORD len =
450 strlen(fib->fib_FileName) + strlen(data->directory) + 3;
452 data->path = AllocVec(len, MEMF_ANY);
453 if (data->path)
455 strcpy(data->path, data->directory);
456 if (AddPart(data->path, fib->fib_FileName, len))
458 STORE = (IPTR) data->path;
463 return 1;
465 case MUIA_Dirlist_RejectIcons:
466 STORE = data->rejecticons;
467 return 1;
469 case MUIA_Dirlist_RejectPattern:
470 STORE = (IPTR) data->rejectpattern;
471 return 1;
473 case MUIA_Dirlist_SortDirs:
474 STORE = data->sortdirs;
475 return 1;
477 case MUIA_Dirlist_SortHighLow:
478 STORE = data->sorthighlow;
479 return 1;
481 case MUIA_Dirlist_SortType:
482 STORE = data->sorttype;
483 return 1;
485 case MUIA_Dirlist_Status:
486 STORE = data->status;
487 return 1;
490 return DoSuperMethodA(cl, obj, (Msg) msg);
494 IPTR Dirlist__MUIM_Dirlist_ReRead(struct IClass *cl, Object *obj,
495 struct MUIP_Dirlist_ReRead *msg)
497 struct Dirlist_DATA *data = INST_DATA(cl, obj);
499 set(obj, MUIA_List_Quiet, TRUE);
500 if (data->status == MUIV_Dirlist_Status_Valid)
502 DoMethod(obj, MUIM_List_Clear);
504 SetAttrs(obj, MUIA_Dirlist_Status, MUIV_Dirlist_Status_Invalid,
505 MUIA_Dirlist_NumBytes, 0,
506 MUIA_Dirlist_NumFiles, 0,
507 MUIA_Dirlist_NumDrawers, 0, TAG_DONE);
510 if (data->directory)
512 ReadDirectory(obj, data);
514 set(obj, MUIA_List_Quiet, FALSE);
516 return 0;
520 #if ZUNE_BUILTIN_DIRLIST
521 BOOPSI_DISPATCHER(IPTR, Dirlist_Dispatcher, cl, obj, msg)
523 switch (msg->MethodID)
525 case OM_NEW:
526 return Dirlist__OM_NEW(cl, obj, (struct opSet *)msg);
527 case OM_DISPOSE:
528 return Dirlist__OM_DISPOSE(cl, obj, msg);
529 case OM_SET:
530 return Dirlist__OM_SET(cl, obj, (struct opSet *)msg);
531 case OM_GET:
532 return Dirlist__OM_GET(cl, obj, (struct opGet *)msg);
533 case MUIM_Dirlist_ReRead:
534 return Dirlist__MUIM_Dirlist_ReRead(cl, obj, (struct opGet *)msg);
535 default:
536 return DoSuperMethodA(cl, obj, msg);
539 BOOPSI_DISPATCHER_END
541 const struct __MUIBuiltinClass _MUI_Dirlist_desc =
543 MUIC_Dirlist,
544 MUIC_List,
545 sizeof(struct Dirlist_DATA),
546 (void *) Dirlist_Dispatcher
548 #endif /* ZUNE_BUILTIN_DIRLIST */