Some fix for scrolling with lasso.
[tangerine.git] / workbench / libs / muimaster / classes / dirlist.c
blob34696b611977d0f60e6f8db73a338847628a4fb4
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 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))))
35 *new = *entry;
37 return 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;
48 struct DateTime dt;
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]";
58 else
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;
66 dt.dat_Flags = 0;
67 dt.dat_StrDay = NULL;
68 dt.dat_StrDate = data->date_string;
69 dt.dat_StrTime = data->time_string;
71 DateToStr(&dt);
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;
88 return 0;
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
97 cl, obj, NULL,
98 MUIA_List_Format, (IPTR)",,,,,",
99 TAG_MORE, (IPTR) msg->ops_AttrList
102 if (obj)
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,
119 TAG_DONE);
121 Dirlist__OM_SET(cl, obj, msg);
124 return (IPTR)obj;
127 IPTR Dirlist__OM_DISPOSE(struct IClass *cl, Object *obj, Msg msg)
129 struct Dirlist_DATA *data = INST_DATA(cl, obj);
131 FreeVec(data->path);
133 return DoSuperMethodA(cl, obj, msg);
136 static void ReadDirectory(Object *obj, struct Dirlist_DATA *data)
138 struct FileInfoBlock *fib;
139 BPTR lock;
141 if ((fib = AllocDosObject(DOS_FIB, NULL)))
143 if ((lock = Lock(data->directory, SHARED_LOCK)))
145 BOOL success;
147 success = Examine(lock, fib);
149 if (success && (fib->fib_DirEntryType > 0))
151 for(;;)
153 BOOL isdir;
155 success = ExNext(lock, fib);
157 if (!success)
159 if (IoErr() == ERROR_NO_MORE_ENTRIES) success = TRUE;
161 break;
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;
181 else
183 if (isdir && data->filesonly) continue;
184 if (!isdir && data->drawersonly) continue;
186 if (data->rejecticons)
188 WORD len = strlen(fib->fib_FileName);
190 if (len >= 5)
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;
209 if (isdir)
211 set(obj, MUIA_Dirlist_NumDrawers, ++data->numdrawers);
213 else
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 */
223 } /* for(;;) */
225 set(obj, MUIA_Dirlist_Status, MUIV_Dirlist_Status_Valid);
228 } /* if (success && (fib->fib_DirEntryType > 0)) */
230 UnLock(lock);
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;
248 switch (tag->ti_Tag)
251 case MUIA_Dirlist_AcceptPattern:
252 data->acceptpattern = (STRPTR)tidata;
253 break;
255 case MUIA_Dirlist_Directory:
256 data->directory = (STRPTR)tidata;
257 directory_changed = TRUE;
258 break;
260 case MUIA_Dirlist_DrawersOnly:
261 data->drawersonly = tidata ? TRUE : FALSE;
262 break;
264 case MUIA_Dirlist_FilesOnly:
265 data->filesonly = tidata ? TRUE : FALSE;
266 break;
268 case MUIA_Dirlist_FilterDrawers:
269 data->filterdrawers = tidata ? TRUE : FALSE;
270 break;
272 case MUIA_Dirlist_FilterHook:
273 data->filterhook = (struct Hook *)tidata;
274 break;
276 case MUIA_Dirlist_MultiSelDirs:
277 data->multiseldirs = tidata ? TRUE : FALSE;
278 break;
280 case MUIA_Dirlist_RejectIcons:
281 data->rejecticons = tidata ? TRUE : FALSE;
282 break;
284 case MUIA_Dirlist_RejectPattern:
285 data->rejectpattern = (STRPTR)tidata;
286 break;
288 case MUIA_Dirlist_SortDirs:
289 data->sortdirs = tidata ? TRUE : FALSE;
290 break;
292 case MUIA_Dirlist_SortHighLow:
293 data->sorthighlow = tidata ? TRUE : FALSE;
294 break;
296 case MUIA_Dirlist_SortType:
297 data->sorttype = tidata;
298 break;
300 case MUIA_Dirlist_Status:
301 data->status = tidata;
302 break;
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 ,
318 TAG_DONE );
322 if (data->directory)
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;
343 return 1;
345 case MUIA_Dirlist_Directory:
346 STORE = (IPTR)data->directory;
347 return 1;
349 case MUIA_Dirlist_DrawersOnly:
350 STORE = data->drawersonly;
351 return 1;
353 case MUIA_Dirlist_FilesOnly:
354 STORE = data->filesonly;
355 return 1;
357 case MUIA_Dirlist_FilterDrawers:
358 STORE = data->filterdrawers;
359 return 1;
361 case MUIA_Dirlist_FilterHook:
362 STORE = (IPTR)data->filterhook;
363 return 1;
365 case MUIA_Dirlist_MultiSelDirs:
366 STORE = data->multiseldirs;
367 return 1;
369 case MUIA_Dirlist_NumBytes:
370 STORE = data->numbytes;
371 return 1;
373 case MUIA_Dirlist_NumFiles:
374 STORE = data->numfiles;
375 return 1;
377 case MUIA_Dirlist_NumDrawers:
378 STORE = data->numdrawers;
379 return 1;
381 case MUIA_Dirlist_Path:
382 if (data->path)
384 FreeVec(data->path);
385 data->path = NULL;
388 STORE = 0;
390 if (data->status == MUIV_Dirlist_Status_Valid)
392 struct FileInfoBlock *fib;
394 DoMethod(obj, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &fib);
396 if (fib)
398 WORD len = strlen(fib->fib_FileName) + strlen(data->directory) + 3;
400 data->path = AllocVec(len, MEMF_ANY);
401 if (data->path)
403 strcpy(data->path, data->directory);
404 if (AddPart(data->path, fib->fib_FileName, len))
406 STORE = (IPTR)data->path;
411 return 1;
413 case MUIA_Dirlist_RejectIcons:
414 STORE = data->rejecticons;
415 return 1;
417 case MUIA_Dirlist_RejectPattern:
418 STORE = (IPTR)data->rejectpattern;
419 return 1;
421 case MUIA_Dirlist_SortDirs:
422 STORE = data->sortdirs;
423 return 1;
425 case MUIA_Dirlist_SortHighLow:
426 STORE = data->sorthighlow;
427 return 1;
429 case MUIA_Dirlist_SortType:
430 STORE = data->sorttype;
431 return 1;
433 case MUIA_Dirlist_Status:
434 STORE = data->status;
435 return 1;
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 ,
457 TAG_DONE );
460 if (data->directory)
462 ReadDirectory(obj, data);
464 set(obj, MUIA_List_Quiet, FALSE);
466 return 0;
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 =
487 MUIC_Dirlist,
488 MUIC_List,
489 sizeof(struct Dirlist_DATA),
490 (void*)Dirlist_Dispatcher
492 #endif /* ZUNE_BUILTIN_DIRLIST */