2 Copyright © 2002-2006, The AROS Development Team. All rights reserved.
6 #define MUIMASTER_YES_INLINE_STDARG
8 #include <exec/memory.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>
22 #include "muimaster_intern.h"
24 #include "support_classes.h"
25 #include "dirlist_private.h"
27 extern struct Library
*MUIMasterBase
;
29 static APTR
construct_func(struct Hook
*hook
, APTR pool
, struct Dirlist_Entry
*entry
)
31 struct Dirlist_Entry
*new;
33 if ((new = AllocPooled(pool
, sizeof(*new))))
40 static void destruct_func(struct Hook
*hook
, APTR pool
, struct Dirlist_Entry
*entry
)
42 FreePooled(pool
, entry
, sizeof(struct Dirlist_Entry
));
45 static LONG
display_func(struct Hook
*hook
, char **array
, struct Dirlist_Entry
*entry
)
47 struct Dirlist_DATA
*data
= hook
->h_Data
;
50 /* MUI: name | size | Date | Time | Protection | Comment */
53 *array
++ = entry
->fib
.fib_FileName
;
55 if (entry
->fib
.fib_DirEntryType
> 0)
57 *array
++ = "\33r\33I[6:22]";
61 snprintf(data
->size_string
, sizeof(data
->size_string
), "\33r%ld", entry
->fib
.fib_Size
);
62 *array
++ = data
->size_string
;
65 dt
.dat_Stamp
= entry
->fib
.fib_Date
;
66 dt
.dat_Format
= FORMAT_DOS
;
69 dt
.dat_StrDate
= data
->date_string
;
70 dt
.dat_StrTime
= data
->time_string
;
74 *array
++ = data
->date_string
;
75 *array
++ = data
->time_string
;
77 data
->prot_string
[0] = (entry
->fib
.fib_Protection
& FIBF_SCRIPT
) ? 's' : '-';
78 data
->prot_string
[1] = (entry
->fib
.fib_Protection
& FIBF_PURE
) ? 'p' : '-';
79 data
->prot_string
[2] = (entry
->fib
.fib_Protection
& FIBF_ARCHIVE
) ? 'a' : '-';
80 data
->prot_string
[3] = (entry
->fib
.fib_Protection
& FIBF_READ
) ? '-' : 'r';
81 data
->prot_string
[4] = (entry
->fib
.fib_Protection
& FIBF_WRITE
) ? '-' : 'w';
82 data
->prot_string
[5] = (entry
->fib
.fib_Protection
& FIBF_EXECUTE
) ? '-' : 'e';
83 data
->prot_string
[6] = (entry
->fib
.fib_Protection
& FIBF_DELETE
) ? '-' : 'd';
84 data
->prot_string
[7] = '\0';
86 *array
++ = data
->prot_string
;
87 *array
= entry
->fib
.fib_Comment
;
102 IPTR
Dirlist__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
);
104 IPTR
Dirlist__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
106 obj
= (Object
*)DoSuperNewTags
109 MUIA_List_Format
, (IPTR
)",,,,,",
110 TAG_MORE
, (IPTR
) msg
->ops_AttrList
115 struct Dirlist_DATA
*data
= INST_DATA(cl
, obj
);
117 data
->status
= MUIV_Dirlist_Status_Invalid
;
119 data
->construct_hook
.h_Entry
= HookEntry
;
120 data
->construct_hook
.h_SubEntry
= (HOOKFUNC
)construct_func
;
121 data
->destruct_hook
.h_Entry
= HookEntry
;
122 data
->destruct_hook
.h_SubEntry
= (HOOKFUNC
)destruct_func
;
123 data
->display_hook
.h_Entry
= HookEntry
;
124 data
->display_hook
.h_SubEntry
= (HOOKFUNC
)display_func
;
125 data
->display_hook
.h_Data
= data
;
127 SetAttrs(obj
, MUIA_List_ConstructHook
, (IPTR
)&data
->construct_hook
,
128 MUIA_List_DestructHook
, (IPTR
)&data
->destruct_hook
,
129 MUIA_List_DisplayHook
, (IPTR
)&data
->display_hook
,
132 Dirlist__OM_SET(cl
, obj
, msg
);
138 IPTR
Dirlist__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
140 struct Dirlist_DATA
*data
= INST_DATA(cl
, obj
);
144 return DoSuperMethodA(cl
, obj
, msg
);
147 static void ReadDirectory(Object
*obj
, struct Dirlist_DATA
*data
)
149 struct FileInfoBlock
*fib
;
152 if ((fib
= AllocDosObject(DOS_FIB
, NULL
)))
154 if ((lock
= Lock(data
->directory
, SHARED_LOCK
)))
158 success
= Examine(lock
, fib
);
160 if (success
&& (fib
->fib_DirEntryType
> 0))
166 success
= ExNext(lock
, fib
);
170 if (IoErr() == ERROR_NO_MORE_ENTRIES
) success
= TRUE
;
175 isdir
= (fib
->fib_DirEntryType
> 0);
177 if (data
->filterhook
)
179 struct ExAllData ead
= {0};
181 ead
.ed_Name
= fib
->fib_FileName
;
182 ead
.ed_Type
= fib
->fib_DirEntryType
;
183 ead
.ed_Size
= fib
->fib_Size
;
184 ead
.ed_Prot
= fib
->fib_Protection
;
185 ead
.ed_Days
= fib
->fib_Date
.ds_Days
;
186 ead
.ed_Mins
= fib
->fib_Date
.ds_Minute
;
187 ead
.ed_Ticks
= fib
->fib_Date
.ds_Tick
;
188 ead
.ed_Comment
= fib
->fib_Comment
;
190 if (!CallHookPkt(data
->filterhook
, obj
, &ead
)) continue;
194 if (isdir
&& data
->filesonly
) continue;
195 if (!isdir
&& data
->drawersonly
) continue;
197 if (data
->rejecticons
)
199 WORD len
= strlen(fib
->fib_FileName
);
203 if (stricmp(fib
->fib_FileName
+ len
- 5, ".info") == 0) continue;
207 if (!isdir
|| data
->filterdrawers
)
209 if (data
->acceptpattern
)
211 if (!MatchPatternNoCase(data
->acceptpattern
, fib
->fib_FileName
)) continue;
214 if (data
->rejectpattern
)
216 if (MatchPatternNoCase(data
->rejectpattern
, fib
->fib_FileName
)) continue;
222 set(obj
, MUIA_Dirlist_NumDrawers
, ++data
->numdrawers
);
226 set(obj
, MUIA_Dirlist_NumFiles
, ++data
->numfiles
);
227 set(obj
, MUIA_Dirlist_NumBytes
, data
->numbytes
+ fib
->fib_Size
);
230 DoMethod(obj
, MUIM_List_InsertSingle
, (IPTR
)fib
, MUIV_List_Insert_Bottom
);
232 } /* no filterhook */
236 set(obj
, MUIA_Dirlist_Status
, MUIV_Dirlist_Status_Valid
);
239 } /* if (success && (fib->fib_DirEntryType > 0)) */
243 } /* if ((lock = Lock(data->directory, SHARED_LOCK))) */
244 FreeDosObject(DOS_FIB
, fib
);
246 } /* if ((fib = AllocDosObject(DOS_FIB, NULL))) */
249 IPTR
Dirlist__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
251 struct Dirlist_DATA
*data
= INST_DATA(cl
, obj
);
252 struct TagItem
*tag
, *tags
;
253 BOOL directory_changed
= FALSE
;
255 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
)); )
257 IPTR tidata
= tag
->ti_Data
;
262 case MUIA_Dirlist_AcceptPattern
:
263 data
->acceptpattern
= (STRPTR
)tidata
;
266 case MUIA_Dirlist_Directory
:
267 data
->directory
= (STRPTR
)tidata
;
268 directory_changed
= TRUE
;
271 case MUIA_Dirlist_DrawersOnly
:
272 data
->drawersonly
= tidata
? TRUE
: FALSE
;
275 case MUIA_Dirlist_FilesOnly
:
276 data
->filesonly
= tidata
? TRUE
: FALSE
;
279 case MUIA_Dirlist_FilterDrawers
:
280 data
->filterdrawers
= tidata
? TRUE
: FALSE
;
283 case MUIA_Dirlist_FilterHook
:
284 data
->filterhook
= (struct Hook
*)tidata
;
287 case MUIA_Dirlist_MultiSelDirs
:
288 data
->multiseldirs
= tidata
? TRUE
: FALSE
;
291 case MUIA_Dirlist_RejectIcons
:
292 data
->rejecticons
= tidata
? TRUE
: FALSE
;
295 case MUIA_Dirlist_RejectPattern
:
296 data
->rejectpattern
= (STRPTR
)tidata
;
299 case MUIA_Dirlist_SortDirs
:
300 data
->sortdirs
= tidata
? TRUE
: FALSE
;
303 case MUIA_Dirlist_SortHighLow
:
304 data
->sorthighlow
= tidata
? TRUE
: FALSE
;
307 case MUIA_Dirlist_SortType
:
308 data
->sorttype
= tidata
;
311 case MUIA_Dirlist_Status
:
312 data
->status
= tidata
;
315 } /* switch (tag->ti_Tag) */
317 } /* for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); ) */
319 if (directory_changed
)
321 if (data
->status
== MUIV_Dirlist_Status_Valid
)
323 DoMethod(obj
, MUIM_List_Clear
);
325 SetAttrs(obj
, MUIA_Dirlist_Status
, MUIV_Dirlist_Status_Invalid
,
326 MUIA_Dirlist_NumBytes
, 0 ,
327 MUIA_Dirlist_NumFiles
, 0 ,
328 MUIA_Dirlist_NumDrawers
, 0 ,
335 ReadDirectory(obj
, data
);
340 return (msg
->MethodID
== OM_SET
) ? DoSuperMethodA(cl
, obj
, (Msg
)msg
) : 0;
344 IPTR
Dirlist__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
346 struct Dirlist_DATA
*data
= INST_DATA(cl
, obj
);
348 #define STORE *(msg->opg_Storage)
350 switch(msg
->opg_AttrID
)
352 case MUIA_Dirlist_AcceptPattern
:
353 STORE
= (IPTR
)data
->acceptpattern
;
356 case MUIA_Dirlist_Directory
:
357 STORE
= (IPTR
)data
->directory
;
360 case MUIA_Dirlist_DrawersOnly
:
361 STORE
= data
->drawersonly
;
364 case MUIA_Dirlist_FilesOnly
:
365 STORE
= data
->filesonly
;
368 case MUIA_Dirlist_FilterDrawers
:
369 STORE
= data
->filterdrawers
;
372 case MUIA_Dirlist_FilterHook
:
373 STORE
= (IPTR
)data
->filterhook
;
376 case MUIA_Dirlist_MultiSelDirs
:
377 STORE
= data
->multiseldirs
;
380 case MUIA_Dirlist_NumBytes
:
381 STORE
= data
->numbytes
;
384 case MUIA_Dirlist_NumFiles
:
385 STORE
= data
->numfiles
;
388 case MUIA_Dirlist_NumDrawers
:
389 STORE
= data
->numdrawers
;
392 case MUIA_Dirlist_Path
:
401 if (data
->status
== MUIV_Dirlist_Status_Valid
)
403 struct FileInfoBlock
*fib
;
405 DoMethod(obj
, MUIM_List_GetEntry
, MUIV_List_GetEntry_Active
, &fib
);
409 WORD len
= strlen(fib
->fib_FileName
) + strlen(data
->directory
) + 3;
411 data
->path
= AllocVec(len
, MEMF_ANY
);
414 strcpy(data
->path
, data
->directory
);
415 if (AddPart(data
->path
, fib
->fib_FileName
, len
))
417 STORE
= (IPTR
)data
->path
;
424 case MUIA_Dirlist_RejectIcons
:
425 STORE
= data
->rejecticons
;
428 case MUIA_Dirlist_RejectPattern
:
429 STORE
= (IPTR
)data
->rejectpattern
;
432 case MUIA_Dirlist_SortDirs
:
433 STORE
= data
->sortdirs
;
436 case MUIA_Dirlist_SortHighLow
:
437 STORE
= data
->sorthighlow
;
440 case MUIA_Dirlist_SortType
:
441 STORE
= data
->sorttype
;
444 case MUIA_Dirlist_Status
:
445 STORE
= data
->status
;
450 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
455 IPTR
Dirlist__MUIM_Dirlist_ReRead(struct IClass
*cl
, Object
*obj
, struct MUIP_Dirlist_ReRead
*msg
)
457 struct Dirlist_DATA
*data
= INST_DATA(cl
, obj
);
459 set(obj
, MUIA_List_Quiet
, TRUE
);
460 if (data
->status
== MUIV_Dirlist_Status_Valid
)
462 DoMethod(obj
, MUIM_List_Clear
);
464 SetAttrs(obj
, MUIA_Dirlist_Status
, MUIV_Dirlist_Status_Invalid
,
465 MUIA_Dirlist_NumBytes
, 0 ,
466 MUIA_Dirlist_NumFiles
, 0 ,
467 MUIA_Dirlist_NumDrawers
, 0 ,
473 ReadDirectory(obj
, data
);
475 set(obj
, MUIA_List_Quiet
, FALSE
);
481 #if ZUNE_BUILTIN_DIRLIST
482 BOOPSI_DISPATCHER(IPTR
, Dirlist_Dispatcher
, cl
, obj
, msg
)
484 switch (msg
->MethodID
)
486 case OM_NEW
: return Dirlist__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
487 case OM_DISPOSE
: return Dirlist__OM_DISPOSE(cl
, obj
, msg
);
488 case OM_SET
: return Dirlist__OM_SET(cl
, obj
, (struct opSet
*)msg
);
489 case OM_GET
: return Dirlist__OM_GET(cl
, obj
, (struct opGet
*)msg
);
490 case MUIM_Dirlist_ReRead
: return Dirlist__MUIM_Dirlist_ReRead(cl
, obj
, (struct opGet
*)msg
);
491 default: return DoSuperMethodA(cl
, obj
, msg
);
494 BOOPSI_DISPATCHER_END
496 const struct __MUIBuiltinClass _MUI_Dirlist_desc
=
500 sizeof(struct Dirlist_DATA
),
501 (void*)Dirlist_Dispatcher
503 #endif /* ZUNE_BUILTIN_DIRLIST */