Format status bar size display, and cleanup code a little
[AROS.git] / workbench / system / Wanderer / panel_statusbar.c
blobff44a4c1d324e995dc6d4d92eda9b111a9d6d3a3
1 /*
2 Copyright 2004-2009, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "portable_macros.h"
7 #ifdef __AROS__
8 #define MUIMASTER_YES_INLINE_STDARG
9 #endif
11 #ifdef __AROS__
12 #define DEBUG 0
13 #include <aros/debug.h>
14 #endif
16 #include <exec/types.h>
17 #include <libraries/mui.h>
19 #ifdef __AROS__
20 #include <zune/customclasses.h>
21 #else
22 #include <zune_AROS/customclasses.h>
23 #endif
25 #include <proto/utility.h>
27 #include <proto/graphics.h>
29 #include <proto/exec.h>
30 #include <proto/datatypes.h>
32 #include <dos/dos.h>
33 #include <proto/dos.h>
35 #include <proto/icon.h>
37 #include <stdio.h>
38 #include <string.h>
40 #include <intuition/screens.h>
41 #include <datatypes/pictureclass.h>
42 #include <clib/macros.h>
44 #ifdef __AROS__
45 #include <clib/alib_protos.h>
47 #include <prefs/wanderer.h>
48 #else
49 #include <prefs_AROS/wanderer.h>
50 #endif
52 #if defined(__AMIGA__) && !defined(__PPC__)
53 #define NO_INLINE_STDARG
54 #endif
55 #ifndef _PROTO_INTUITION_H
56 #include <proto/intuition.h>
57 #endif
58 #include <proto/muimaster.h>
60 #include "Classes/iconlist.h"
61 #include "Classes/iconlistview.h"
62 #include "Classes/iconlist_attributes.h"
63 #include "Classes/icon_attributes.h"
64 #include "wanderer.h"
65 #include "wandererprefs.h"
67 #include "iconwindow.h"
68 #include "iconwindow_attributes.h"
70 extern struct List iconwindow_Extensions;
72 /*** Private Data *********************************************************/
74 static CONST_STRPTR extension_Name = "StatusBar Extension";
75 static CONST_STRPTR extension_PrefsFile = "ENV:SYS/Wanderer/statusbar.prefs";
76 static STRPTR extension_PrefsData;
77 static struct iconWindow_Extension panelStatusBar__Extension;
78 static struct List panelStatusBar__StatusBars;
79 static struct NotifyRequest panelStatusBar__PrefsNotifyRequest;
80 static Object *panelStatusBar__PrefsNotificationObject;
82 struct panel_StatusBar_DATA
84 struct Node iwp_Node;
85 IPTR iwp_Flags;
86 Object *iwp_StatusBar_StatusBarObj;
87 Object *iwp_StatusBar_StatusTextObj;
88 #ifdef __AROS__
89 struct Hook iwp_StatusBar_updateHook;
90 #else
91 struct Hook *iwp_StatusBar_updateHook;
92 #endif
95 ///ExpandEnvName()
96 /* Expand a passed in env: string to its full location */
97 /* Wanderer doesnt free this mem at the moment but should
98 incase it is every closed */
99 static STRPTR ExpandEnvName(STRPTR env_path)
101 BOOL ok = FALSE;
102 char tmp_envbuff[1024];
103 STRPTR fullpath = NULL;
104 BPTR env_lock = (BPTR) NULL;
106 env_lock = Lock("ENV:", SHARED_LOCK);
107 if (env_lock)
109 if (NameFromLock(env_lock, tmp_envbuff, 256)) ok = TRUE;
110 UnLock(env_lock);
113 if (ok)
115 if ((fullpath = AllocVec(strlen(tmp_envbuff) + strlen(env_path) + 1 + 1 - 4, MEMF_CLEAR | MEMF_PUBLIC)) != NULL)
117 strcpy(fullpath, tmp_envbuff);
118 AddPart(fullpath, env_path + 4, 1019);
119 return fullpath;
123 //We couldnt expand it so just use as is ..
124 return env_path;
128 const UBYTE MSG_MEM_G[] = "GB";
129 const UBYTE MSG_MEM_M[] = "MB";
130 const UBYTE MSG_MEM_K[] = "KB";
131 const UBYTE MSG_MEM_B[] = "Bytes";
133 ///fmtlarge()
134 static void fmtlarge(UBYTE *buf, ULONG num)
136 UQUAD d;
137 UBYTE *ch;
138 struct
140 IPTR val;
141 IPTR dec;
142 } array =
144 num,
148 if (num >= 1073741824)
150 //Gigabytes
151 array.val = num >> 30;
152 d = ((UQUAD)num * 10 + 536870912) / 1073741824;
153 array.dec = d % 10;
154 ch = MSG_MEM_G;
156 else if (num >= 1048576)
158 //Megabytes
159 array.val = num >> 20;
160 d = ((UQUAD)num * 10 + 524288) / 1048576;
161 array.dec = d % 10;
162 ch = MSG_MEM_M;
164 else if (num >= 1024)
166 //Kilobytes
167 array.val = num >> 10;
168 d = (num * 10 + 512) / 1024;
169 array.dec = d % 10;
170 ch = MSG_MEM_K;
172 else
174 //Bytes
175 array.val = num;
176 array.dec = 0;
177 d = 0;
178 ch = MSG_MEM_B;
181 if (!array.dec && (d > array.val * 10))
183 array.val++;
186 RawDoFmt(array.dec ? "%lu.%lu" : "%lu", &array, NULL, buf);
188 while (*buf)
190 buf++;
193 sprintf(buf, " %s", ch);
197 /*** Hook functions *********************************************************/
198 static
199 ///panelStatusBar__HookFunc_UpdateStatusFunc()
200 #ifdef __AROS__
201 AROS_UFH3(
202 void, panelStatusBar__HookFunc_UpdateStatusFunc,
203 AROS_UFHA(struct Hook *, hook, A0),
204 AROS_UFHA(APTR *, obj, A2),
205 AROS_UFHA(APTR, param, A1)
208 #else
209 HOOKPROTO(panelStatusBar__HookFunc_UpdateStatusFunc, void, APTR *obj, APTR param)
211 #endif
212 AROS_USERFUNC_INIT
214 /* Get data */
215 Object *self = ( Object *)obj;
216 Class *CLASS = *( Class **)param;
217 STRPTR str = NULL;
218 BPTR fp = (BPTR) NULL;
219 struct FileInfoBlock *fib;
220 struct panel_StatusBar_DATA *panelStatusBarPrivate = NULL;
222 SETUP_ICONWINDOW_INST_DATA;
224 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
226 /* Only change dir if it is a valid directory/volume */
227 if ((panelStatusBarPrivate = (struct panel_StatusBar_DATA *)data->iwd_BottomPanel.iwp_PanelPrivate) != NULL)
229 if (panelStatusBarPrivate->iwp_Node.ln_Name != extension_Name)
230 return;
232 struct List *iconList = NULL;
233 struct IconEntry *icon = NULL;
234 UBYTE status_str[1024];
235 UBYTE size_str[256];
237 int files = 0, dirs = 0, hidden = 0;
238 ULONG size = 0;
240 GET(data->iwd_IconListObj, MUIA_Group_ChildList, &iconList);
241 if (iconList)
243 ForeachNode(iconList, icon)
245 if (icon->ie_Flags & ICONENTRY_FLAG_VISIBLE)
247 if (icon->ie_IconListEntry.type == ST_USERDIR)
249 dirs += 1;
251 else
253 files += 1;
254 size += icon->ie_FileInfoBlock->fib_Size;
257 else
259 hidden += 1;
263 fmtlarge(size_str, size);
264 sprintf(status_str, "%s in %d files, %d drawers (%d hidden)", size_str, files, dirs, hidden);
265 SET(panelStatusBarPrivate->iwp_StatusBar_StatusTextObj, MUIA_Text_Contents, (IPTR)status_str);
268 AROS_USERFUNC_EXIT
270 #ifndef __AROS__
271 MakeStaticHook(StatusBar_updateHook, panelStatusBar__HookFunc_UpdateStatusFunc);
272 #endif
274 /*** Main Functions ****************************************************************/
276 #define STATUSBAR_PREFSSIZE 1024
277 static IPTR panelStatusBar__HandleFSUpdate()
279 if (GetVar(extension_PrefsFile, extension_PrefsData, STATUSBAR_PREFSSIZE, GVF_GLOBAL_ONLY) != -1)
281 D(bug("[IW.statusbar] %s: Prefs contain '%s'\n", __PRETTY_FUNCTION__, extension_PrefsData));
282 if ((strcasecmp(extension_PrefsData, "True")) == 0)
284 SET(panelStatusBar__PrefsNotificationObject, MUIA_ShowMe, TRUE);
286 else
288 SET(panelStatusBar__PrefsNotificationObject, MUIA_ShowMe, FALSE);
291 return NULL;
294 ///panelStatusBar__PrefsSetup()
295 static IPTR panelStatusBar__PrefsSetup(Class *CLASS, Object *self, struct opSet *message)
297 IPTR panelStatusBarFSNotifyPort = 0;
298 struct panel_StatusBar_DATA *panelStatusBarPrivate = NULL;
299 struct List *panelStatusBarFSNotifyList = NULL;
301 SETUP_ICONWINDOW_INST_DATA;
303 panelStatusBarFSNotifyPort = GetTagData(MUIA_Wanderer_FileSysNotifyPort, (IPTR) NULL, message->ops_AttrList);
304 panelStatusBarFSNotifyList = GetTagData(MUIA_Wanderer_FileSysNotifyList, (IPTR) NULL, message->ops_AttrList);
306 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
308 if ((panelStatusBarPrivate = (struct panel_StatusBar_DATA *)data->iwd_BottomPanel.iwp_PanelPrivate) != (IPTR)NULL)
310 if (panelStatusBarPrivate->iwp_Node.ln_Name != extension_Name)
311 return NULL;
313 extension_PrefsData = AllocVec(STATUSBAR_PREFSSIZE, MEMF_CLEAR);
315 /* Setup notification on prefs file --------------------------------*/
316 struct Wanderer_FSHandler *_prefsNotifyHandler = NULL;
318 if ((_prefsNotifyHandler = AllocMem(sizeof(struct Wanderer_FSHandler), MEMF_CLEAR)) != NULL)
320 _prefsNotifyHandler->fshn_Node.ln_Name = ExpandEnvName(extension_PrefsFile);
321 panelStatusBar__PrefsNotifyRequest.nr_Name = _prefsNotifyHandler->fshn_Node.ln_Name;
322 panelStatusBar__PrefsNotifyRequest.nr_Flags = NRF_SEND_MESSAGE;
323 panelStatusBar__PrefsNotifyRequest.nr_stuff.nr_Msg.nr_Port = panelStatusBarFSNotifyPort;
324 _prefsNotifyHandler->HandleFSUpdate = panelStatusBar__HandleFSUpdate;
326 if (StartNotify(&panelStatusBar__PrefsNotifyRequest))
328 D(bug("[IW.statusbar]%s: Prefs-notification setup on '%s'\n", __PRETTY_FUNCTION__, panelStatusBar__PrefsNotifyRequest.nr_Name));
330 else
332 D(bug("[IW.statusbar] %s: FAILED to setup Prefs-notification!\n", __PRETTY_FUNCTION__));
334 AddTail(panelStatusBarFSNotifyList, &_prefsNotifyHandler->fshn_Node);
336 #ifdef __AROS__
337 panelStatusBar__PrefsNotificationObject = (Object *)NotifyObject, End;
338 #else
339 panelStatusBar__PrefsNotificationObject = MUI_NewObject(MUIC_Notify, TAG_DONE);
340 #endif
341 if (GetVar(extension_PrefsFile, extension_PrefsData, STATUSBAR_PREFSSIZE, GVF_GLOBAL_ONLY) != -1)
343 D(bug("[IW.statusbar] %s: Prefs contain '%s'\n", __PRETTY_FUNCTION__, extension_PrefsData));
349 ///panelStatusBar__Setup()
350 static IPTR panelStatusBar__Setup(Class *CLASS, Object *self, struct opSet *message)
352 SETUP_ICONWINDOW_INST_DATA;
354 Object *panel_StatusBar = NULL,
355 *panelStatusBar_TextStatus = NULL;
357 struct panel_StatusBar_DATA *panelStatusBarPrivate = NULL;
359 if (!(!(data->iwd_Flags & IWDFLAG_ISROOT) && data->iwd_BottomPanel.iwp_PanelContainerObj))
360 return NULL;
362 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
364 if (data->iwd_BottomPanel.iwp_PanelPrivate == NULL)
366 if ((data->iwd_BottomPanel.iwp_PanelPrivate = AllocVec(sizeof(struct panel_StatusBar_DATA), MEMF_CLEAR)) == NULL)
367 return;
369 panelStatusBarPrivate = (struct panel_StatusBar_DATA *)data->iwd_BottomPanel.iwp_PanelPrivate;
370 panelStatusBarPrivate->iwp_Node.ln_Name = extension_Name;
372 /* Create the "StatusBar" panel object .. */
373 panel_StatusBar = MUI_NewObject(MUIC_Group,
374 MUIA_InnerLeft,(0),
375 MUIA_InnerRight,(0),
376 MUIA_InnerTop,(0),
377 MUIA_InnerBottom,(0),
378 MUIA_Frame, MUIV_Frame_None,
379 Child, (IPTR)MUI_NewObject(MUIC_Group, MUIA_Group_Horiz, TRUE ,
380 MUIA_InnerLeft,(0),
381 MUIA_InnerRight,(0),
382 MUIA_InnerTop,(0),
383 MUIA_InnerBottom,(0),
384 MUIA_Group_Spacing, 0,
385 MUIA_FixHeight, 1,
386 MUIA_Frame, MUIV_Frame_None,
387 MUIA_Background, MUII_SHADOW,
388 Child, (IPTR)MUI_NewObject(MUIC_Rectangle,
389 MUIA_Frame, MUIV_Frame_None,
390 TAG_DONE),
391 TAG_DONE),
392 Child, (IPTR)MUI_NewObject(MUIC_Group, MUIA_Group_Horiz, TRUE ,
393 MUIA_InnerLeft,(4),
394 MUIA_InnerRight,(4),
395 MUIA_InnerTop,(4),
396 MUIA_InnerBottom,(4),
397 MUIA_Frame, MUIV_Frame_None,
398 MUIA_Weight, 100,
399 Child, (IPTR)MUI_NewObject(MUIC_Group, MUIA_Group_Horiz, TRUE ,
400 MUIA_InnerLeft,(0),
401 MUIA_InnerRight,(0),
402 MUIA_InnerTop,(0),
403 MUIA_InnerBottom,(0),
404 MUIA_Weight, 100,
405 Child, (IPTR)( panelStatusBar_TextStatus = MUI_NewObject(MUIC_Text,
406 MUIA_Font, MUIV_Font_Tiny,
407 MUIA_Text_Contents, (IPTR)"",
408 TAG_DONE) ),
409 TAG_DONE),
410 TAG_DONE),
411 TAG_DONE);
413 /* Got a StatusBarPanel? setup notifies and other values are
414 copied to the data of the object */
415 if ( panel_StatusBar != NULL )
417 D(bug("[IW.statusbar] %s: StatusBar Obj @ 0x%p\n", __PRETTY_FUNCTION__, panel_StatusBar));
419 panelStatusBarPrivate->iwp_StatusBar_StatusTextObj = panelStatusBar_TextStatus;
420 panelStatusBarPrivate->iwp_StatusBar_StatusBarObj = panel_StatusBar;
422 if (DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, MUIM_Group_InitChange ))
424 DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, OM_ADDMEMBER, (IPTR)panel_StatusBar);
425 if (data->iwd_BottomPanel.iwp_PanelGroupSpacerObj)
427 DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, OM_REMMEMBER, (IPTR)data->iwd_BottomPanel.iwp_PanelGroupSpacerObj);
428 data->iwd_BottomPanel.iwp_PanelGroupSpacerObj = NULL;
431 DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, MUIM_Group_ExitChange);
434 if (panelStatusBarPrivate->iwp_StatusBar_StatusBarObj)
436 #ifdef __AROS__
437 panelStatusBarPrivate->iwp_StatusBar_updateHook.h_Entry = ( HOOKFUNC )panelStatusBar__HookFunc_UpdateStatusFunc;
438 #else
439 panelStatusBarPrivate->iwp_StatusBar_updateHook= &StatusBar_updateHook;
440 #endif
441 DoMethod (
442 data->iwd_IconListObj, MUIM_Notify, MUIA_IconList_Changed, MUIV_EveryTime,
443 (IPTR)self, 3, MUIM_CallHook, &panelStatusBarPrivate->iwp_StatusBar_updateHook, (IPTR)CLASS
446 if (!(panelStatusBar__PrefsNotificationObject))
447 panelStatusBar__PrefsSetup(CLASS, self, message);
449 DoMethod
451 panelStatusBar__PrefsNotificationObject, MUIM_Notify, MUIA_ShowMe, MUIV_EveryTime,
452 (IPTR)data->iwd_BottomPanel.iwp_PanelContainerObj, 3, MUIM_Set, MUIA_ShowMe, MUIV_TriggerValue
455 if ((strcasecmp(extension_PrefsData, "True")) == 0)
457 SET(data->iwd_BottomPanel.iwp_PanelContainerObj, MUIA_ShowMe, TRUE);
460 AddTail(&panelStatusBar__StatusBars, &panelStatusBarPrivate->iwp_Node);
463 else
465 panelStatusBarPrivate->iwp_StatusBar_StatusBarObj = NULL;
471 ///panelStatusBar__Cleanup()
472 static IPTR panelStatusBar__Cleanup(Class *CLASS, Object *self, struct opSet *message)
474 SETUP_ICONWINDOW_INST_DATA;
475 struct panel_StatusBar_DATA *panelStatusBarPrivate;
477 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
479 if ((panelStatusBarPrivate = (struct panel_StatusBar_DATA *)data->iwd_TopPanel.iwp_PanelPrivate) != (IPTR)NULL)
481 if (panelStatusBarPrivate->iwp_Node.ln_Name != extension_Name)
482 return NULL;
484 if (panelStatusBar__PrefsNotificationObject)
486 DoMethod
488 panelStatusBar__PrefsNotificationObject, MUIM_KillNotifyObj, MUIA_ShowMe,
489 (IPTR)data->iwd_BottomPanel.iwp_PanelContainerObj
493 return NULL;
497 ///panelStatusBar__OM_GET()
498 static IPTR panelStatusBar__OM_GET(Class *CLASS, Object *self, struct opGet *message)
500 SETUP_ICONWINDOW_INST_DATA;
502 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
504 return NULL;
508 ///OM_SET()
509 static IPTR panelStatusBar__OM_SET(Class *CLASS, Object *self, struct opSet *message)
511 SETUP_ICONWINDOW_INST_DATA;
513 struct panel_StatusBar_DATA *panelStatusBarPrivate = NULL;
514 struct TagItem *tstate = message->ops_AttrList, *tag;
515 BOOL UpdateIconlist = FALSE;
516 IPTR focusicon = (IPTR) NULL;
517 IPTR rv = TRUE;
519 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
521 if ((panelStatusBarPrivate = (struct panel_StatusBar_DATA *)data->iwd_BottomPanel.iwp_PanelPrivate) != (IPTR)NULL)
523 if (panelStatusBarPrivate->iwp_Node.ln_Name != extension_Name)
524 return rv;
526 while ((tag = NextTagItem((TAGITEM)&tstate)) != NULL)
528 switch (tag->ti_Tag)
530 /*case MUIA_IconWindowExt_ToolBar_Enabled:
531 if ((!(data->iwd_Flags & IWDFLAG_ISROOT)) && (data->iwd_BottomPanel.iwp_PanelContainerObj))
533 // remove statusbar
534 if (!(( BOOL )tag->ti_Data))
536 if (panelStatusBarPrivate->iwp_StatusBar_StatusBarObj != NULL)
538 data->iwd_BottomPanel.iwp_PanelGroupSpacerObj = HSpace(0);
540 SET(data->iwd_BottomPanel.iwp_PanelContainerObj, MUIA_Frame, MUIV_Frame_None);
541 SET(data->iwd_BottomPanel.iwp_PanelContainerObj, MUIA_Group_Spacing, 0);
543 if ((data->iwd_BottomPanel.iwp_PanelGroupSpacerObj) && (DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, MUIM_Group_InitChange)))
545 DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, OM_REMMEMBER, (IPTR)panelStatusBarPrivate->iwp_StatusBar_StatusBarObj);
546 DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, OM_ADDMEMBER, (IPTR)data->iwd_BottomPanel.iwp_PanelGroupSpacerObj);
547 DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, MUIM_Group_ExitChange);
548 panelStatusBarPrivate->iwp_StatusBar_StatusBarObj = NULL;
552 else
554 // setup statusbar
555 if (panelStatusBarPrivate->iwp_StatusBar_StatusBarObj == NULL)
557 Object *prefs = NULL;
558 GET(_app(self), MUIA_Wanderer_Prefs, &prefs);
559 panelStatusBar__Setup(CLASS, self, prefs);
563 break;*/
567 return rv;
570 #define PANELSTATUSBAR_PRIORITY 10
572 IPTR panelStatusBar__Init()
574 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
576 panelStatusBar__Extension.iwe_Node.ln_Pri = PANELSTATUSBAR_PRIORITY;
577 panelStatusBar__Extension.iwe_Node.ln_Name = extension_Name;
578 panelStatusBar__Extension.iwe_Setup = panelStatusBar__Setup;
579 panelStatusBar__Extension.iwe_Cleanup = panelStatusBar__Cleanup;
580 panelStatusBar__Extension.iwe_Set = panelStatusBar__OM_SET;
581 panelStatusBar__Extension.iwe_Get = panelStatusBar__OM_GET;
583 NewList(&panelStatusBar__StatusBars);
585 Enqueue(&iconwindow_Extensions, (struct Node *)&panelStatusBar__Extension);
587 D(bug("[IconWindow] %s: Added Extension '%s' @ %p to list @ %p\n", __PRETTY_FUNCTION__, panelStatusBar__Extension.iwe_Node.ln_Name, &panelStatusBar__Extension.iwe_Node, &iconwindow_Extensions));
589 return TRUE;
592 ADD2INIT(panelStatusBar__Init, PANELSTATUSBAR_PRIORITY);