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 */
52 *array
++ = entry
->fib
.fib_FileName
;
54 if (entry
->fib
.fib_DirEntryType
> 0)
56 *array
++ = "\33r\33I[6:22]";
60 snprintf(data
->size_string
, sizeof(data
->size_string
), "\33r%ld", entry
->fib
.fib_Size
);
61 *array
++ = data
->size_string
;
64 dt
.dat_Stamp
= entry
->fib
.fib_Date
;
65 dt
.dat_Format
= FORMAT_DOS
;
68 dt
.dat_StrDate
= data
->date_string
;
69 dt
.dat_StrTime
= data
->time_string
;
73 *array
++ = data
->date_string
;
74 *array
++ = data
->time_string
;
76 data
->prot_string
[0] = (entry
->fib
.fib_Protection
& FIBF_SCRIPT
) ? 's' : '-';
77 data
->prot_string
[1] = (entry
->fib
.fib_Protection
& FIBF_PURE
) ? 'p' : '-';
78 data
->prot_string
[2] = (entry
->fib
.fib_Protection
& FIBF_ARCHIVE
) ? 'a' : '-';
79 data
->prot_string
[3] = (entry
->fib
.fib_Protection
& FIBF_READ
) ? '-' : 'r';
80 data
->prot_string
[4] = (entry
->fib
.fib_Protection
& FIBF_WRITE
) ? '-' : 'w';
81 data
->prot_string
[5] = (entry
->fib
.fib_Protection
& FIBF_EXECUTE
) ? '-' : 'e';
82 data
->prot_string
[6] = (entry
->fib
.fib_Protection
& FIBF_DELETE
) ? '-' : 'd';
83 data
->prot_string
[7] = '\0';
85 *array
++ = data
->prot_string
;
86 *array
= entry
->fib
.fib_Comment
;
91 IPTR
Dirlist__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
);
93 IPTR
Dirlist__OM_NEW(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
95 obj
= (Object
*)DoSuperNewTags
98 MUIA_List_Format
, (IPTR
)",,,,,",
99 TAG_MORE
, (IPTR
) msg
->ops_AttrList
104 struct Dirlist_DATA
*data
= INST_DATA(cl
, obj
);
106 data
->status
= MUIV_Dirlist_Status_Invalid
;
108 data
->construct_hook
.h_Entry
= HookEntry
;
109 data
->construct_hook
.h_SubEntry
= (HOOKFUNC
)construct_func
;
110 data
->destruct_hook
.h_Entry
= HookEntry
;
111 data
->destruct_hook
.h_SubEntry
= (HOOKFUNC
)destruct_func
;
112 data
->display_hook
.h_Entry
= HookEntry
;
113 data
->display_hook
.h_SubEntry
= (HOOKFUNC
)display_func
;
114 data
->display_hook
.h_Data
= data
;
116 SetAttrs(obj
, MUIA_List_ConstructHook
, (IPTR
)&data
->construct_hook
,
117 MUIA_List_DestructHook
, (IPTR
)&data
->destruct_hook
,
118 MUIA_List_DisplayHook
, (IPTR
)&data
->display_hook
,
121 Dirlist__OM_SET(cl
, obj
, msg
);
127 IPTR
Dirlist__OM_DISPOSE(struct IClass
*cl
, Object
*obj
, Msg msg
)
129 struct Dirlist_DATA
*data
= INST_DATA(cl
, obj
);
133 return DoSuperMethodA(cl
, obj
, msg
);
136 static void ReadDirectory(Object
*obj
, struct Dirlist_DATA
*data
)
138 struct FileInfoBlock
*fib
;
141 if ((fib
= AllocDosObject(DOS_FIB
, NULL
)))
143 if ((lock
= Lock(data
->directory
, SHARED_LOCK
)))
147 success
= Examine(lock
, fib
);
149 if (success
&& (fib
->fib_DirEntryType
> 0))
155 success
= ExNext(lock
, fib
);
159 if (IoErr() == ERROR_NO_MORE_ENTRIES
) success
= TRUE
;
164 isdir
= (fib
->fib_DirEntryType
> 0);
166 if (data
->filterhook
)
168 struct ExAllData ead
= {0};
170 ead
.ed_Name
= fib
->fib_FileName
;
171 ead
.ed_Type
= fib
->fib_DirEntryType
;
172 ead
.ed_Size
= fib
->fib_Size
;
173 ead
.ed_Prot
= fib
->fib_Protection
;
174 ead
.ed_Days
= fib
->fib_Date
.ds_Days
;
175 ead
.ed_Mins
= fib
->fib_Date
.ds_Minute
;
176 ead
.ed_Ticks
= fib
->fib_Date
.ds_Tick
;
177 ead
.ed_Comment
= fib
->fib_Comment
;
179 if (!CallHookPkt(data
->filterhook
, obj
, &ead
)) continue;
183 if (isdir
&& data
->filesonly
) continue;
184 if (!isdir
&& data
->drawersonly
) continue;
186 if (data
->rejecticons
)
188 WORD len
= strlen(fib
->fib_FileName
);
192 if (stricmp(fib
->fib_FileName
+ len
- 5, ".info") == 0) continue;
196 if (!isdir
|| data
->filterdrawers
)
198 if (data
->acceptpattern
)
200 if (!MatchPatternNoCase(data
->acceptpattern
, fib
->fib_FileName
)) continue;
203 if (data
->rejectpattern
)
205 if (MatchPatternNoCase(data
->rejectpattern
, fib
->fib_FileName
)) continue;
211 set(obj
, MUIA_Dirlist_NumDrawers
, ++data
->numdrawers
);
215 set(obj
, MUIA_Dirlist_NumFiles
, ++data
->numfiles
);
216 set(obj
, MUIA_Dirlist_NumBytes
, data
->numbytes
+ fib
->fib_Size
);
219 DoMethod(obj
, MUIM_List_InsertSingle
, (IPTR
)fib
, MUIV_List_Insert_Bottom
);
221 } /* no filterhook */
225 set(obj
, MUIA_Dirlist_Status
, MUIV_Dirlist_Status_Valid
);
228 } /* if (success && (fib->fib_DirEntryType > 0)) */
232 } /* if ((lock = Lock(data->directory, SHARED_LOCK))) */
233 FreeDosObject(DOS_FIB
, fib
);
235 } /* if ((fib = AllocDosObject(DOS_FIB, NULL))) */
238 IPTR
Dirlist__OM_SET(struct IClass
*cl
, Object
*obj
, struct opSet
*msg
)
240 struct Dirlist_DATA
*data
= INST_DATA(cl
, obj
);
241 struct TagItem
*tag
, *tags
;
242 BOOL directory_changed
= FALSE
;
244 for (tags
= msg
->ops_AttrList
; (tag
= NextTagItem((const struct TagItem
**)&tags
)); )
246 IPTR tidata
= tag
->ti_Data
;
251 case MUIA_Dirlist_AcceptPattern
:
252 data
->acceptpattern
= (STRPTR
)tidata
;
255 case MUIA_Dirlist_Directory
:
256 data
->directory
= (STRPTR
)tidata
;
257 directory_changed
= TRUE
;
260 case MUIA_Dirlist_DrawersOnly
:
261 data
->drawersonly
= tidata
? TRUE
: FALSE
;
264 case MUIA_Dirlist_FilesOnly
:
265 data
->filesonly
= tidata
? TRUE
: FALSE
;
268 case MUIA_Dirlist_FilterDrawers
:
269 data
->filterdrawers
= tidata
? TRUE
: FALSE
;
272 case MUIA_Dirlist_FilterHook
:
273 data
->filterhook
= (struct Hook
*)tidata
;
276 case MUIA_Dirlist_MultiSelDirs
:
277 data
->multiseldirs
= tidata
? TRUE
: FALSE
;
280 case MUIA_Dirlist_RejectIcons
:
281 data
->rejecticons
= tidata
? TRUE
: FALSE
;
284 case MUIA_Dirlist_RejectPattern
:
285 data
->rejectpattern
= (STRPTR
)tidata
;
288 case MUIA_Dirlist_SortDirs
:
289 data
->sortdirs
= tidata
? TRUE
: FALSE
;
292 case MUIA_Dirlist_SortHighLow
:
293 data
->sorthighlow
= tidata
? TRUE
: FALSE
;
296 case MUIA_Dirlist_SortType
:
297 data
->sorttype
= tidata
;
300 case MUIA_Dirlist_Status
:
301 data
->status
= tidata
;
304 } /* switch (tag->ti_Tag) */
306 } /* for (tags = msg->ops_AttrList; (tag = NextTagItem(&tags)); ) */
308 if (directory_changed
)
310 if (data
->status
== MUIV_Dirlist_Status_Valid
)
312 DoMethod(obj
, MUIM_List_Clear
);
314 SetAttrs(obj
, MUIA_Dirlist_Status
, MUIV_Dirlist_Status_Invalid
,
315 MUIA_Dirlist_NumBytes
, 0 ,
316 MUIA_Dirlist_NumFiles
, 0 ,
317 MUIA_Dirlist_NumDrawers
, 0 ,
324 ReadDirectory(obj
, data
);
329 return (msg
->MethodID
== OM_SET
) ? DoSuperMethodA(cl
, obj
, (Msg
)msg
) : 0;
333 IPTR
Dirlist__OM_GET(struct IClass
*cl
, Object
*obj
, struct opGet
*msg
)
335 struct Dirlist_DATA
*data
= INST_DATA(cl
, obj
);
337 #define STORE *(msg->opg_Storage)
339 switch(msg
->opg_AttrID
)
341 case MUIA_Dirlist_AcceptPattern
:
342 STORE
= (IPTR
)data
->acceptpattern
;
345 case MUIA_Dirlist_Directory
:
346 STORE
= (IPTR
)data
->directory
;
349 case MUIA_Dirlist_DrawersOnly
:
350 STORE
= data
->drawersonly
;
353 case MUIA_Dirlist_FilesOnly
:
354 STORE
= data
->filesonly
;
357 case MUIA_Dirlist_FilterDrawers
:
358 STORE
= data
->filterdrawers
;
361 case MUIA_Dirlist_FilterHook
:
362 STORE
= (IPTR
)data
->filterhook
;
365 case MUIA_Dirlist_MultiSelDirs
:
366 STORE
= data
->multiseldirs
;
369 case MUIA_Dirlist_NumBytes
:
370 STORE
= data
->numbytes
;
373 case MUIA_Dirlist_NumFiles
:
374 STORE
= data
->numfiles
;
377 case MUIA_Dirlist_NumDrawers
:
378 STORE
= data
->numdrawers
;
381 case MUIA_Dirlist_Path
:
390 if (data
->status
== MUIV_Dirlist_Status_Valid
)
392 struct FileInfoBlock
*fib
;
394 DoMethod(obj
, MUIM_List_GetEntry
, MUIV_List_GetEntry_Active
, &fib
);
398 WORD len
= strlen(fib
->fib_FileName
) + strlen(data
->directory
) + 3;
400 data
->path
= AllocVec(len
, MEMF_ANY
);
403 strcpy(data
->path
, data
->directory
);
404 if (AddPart(data
->path
, fib
->fib_FileName
, len
))
406 STORE
= (IPTR
)data
->path
;
413 case MUIA_Dirlist_RejectIcons
:
414 STORE
= data
->rejecticons
;
417 case MUIA_Dirlist_RejectPattern
:
418 STORE
= (IPTR
)data
->rejectpattern
;
421 case MUIA_Dirlist_SortDirs
:
422 STORE
= data
->sortdirs
;
425 case MUIA_Dirlist_SortHighLow
:
426 STORE
= data
->sorthighlow
;
429 case MUIA_Dirlist_SortType
:
430 STORE
= data
->sorttype
;
433 case MUIA_Dirlist_Status
:
434 STORE
= data
->status
;
439 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
444 IPTR
Dirlist__MUIM_Dirlist_ReRead(struct IClass
*cl
, Object
*obj
, struct MUIP_Dirlist_ReRead
*msg
)
446 struct Dirlist_DATA
*data
= INST_DATA(cl
, obj
);
448 set(obj
, MUIA_List_Quiet
, TRUE
);
449 if (data
->status
== MUIV_Dirlist_Status_Valid
)
451 DoMethod(obj
, MUIM_List_Clear
);
453 SetAttrs(obj
, MUIA_Dirlist_Status
, MUIV_Dirlist_Status_Invalid
,
454 MUIA_Dirlist_NumBytes
, 0 ,
455 MUIA_Dirlist_NumFiles
, 0 ,
456 MUIA_Dirlist_NumDrawers
, 0 ,
462 ReadDirectory(obj
, data
);
464 set(obj
, MUIA_List_Quiet
, FALSE
);
470 #if ZUNE_BUILTIN_DIRLIST
471 BOOPSI_DISPATCHER(IPTR
, Dirlist_Dispatcher
, cl
, obj
, msg
)
473 switch (msg
->MethodID
)
475 case OM_NEW
: return Dirlist__OM_NEW(cl
, obj
, (struct opSet
*)msg
);
476 case OM_DISPOSE
: return Dirlist__OM_DISPOSE(cl
, obj
, msg
);
477 case OM_SET
: return Dirlist__OM_SET(cl
, obj
, (struct opSet
*)msg
);
478 case OM_GET
: return Dirlist__OM_GET(cl
, obj
, (struct opGet
*)msg
);
479 case MUIM_Dirlist_ReRead
: return Dirlist__MUIM_Dirlist_ReRead(cl
, obj
, (struct opGet
*)msg
);
480 default: return DoSuperMethodA(cl
, obj
, msg
);
483 BOOPSI_DISPATCHER_END
485 const struct __MUIBuiltinClass _MUI_Dirlist_desc
=
489 sizeof(struct Dirlist_DATA
),
490 (void*)Dirlist_Dispatcher
492 #endif /* ZUNE_BUILTIN_DIRLIST */