revert between 56095 -> 55830 in arch
[AROS.git] / workbench / system / Wanderer / panel_statusbar.c
blob97e4052245f24b74d65f6e0455841c46c47d695e
1 /*
2 Copyright 2004-2013, 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 = "IconWindow StatusBar Extension";
75 static CONST_STRPTR extension_PrefsFile = "ENV:SYS/Wanderer/statusbar.prefs";
76 static CONST_STRPTR strTrue = "True";
77 static STRPTR extension_PrefsData;
78 static struct iconWindow_Extension panelStatusBar__Extension;
79 static struct List panelStatusBar__StatusBars;
80 static struct NotifyRequest panelStatusBar__PrefsNotifyRequest;
81 static Object *panelStatusBar__PrefsNotificationObject;
83 struct panel_StatusBar_DATA
85 struct Node iwp_Node;
86 IPTR iwp_Flags;
87 Object *iwp_StatusBar_StatusBarObj;
88 Object *iwp_StatusBar_StatusTextObj;
89 #ifdef __AROS__
90 struct Hook iwp_StatusBar_updateHook;
91 #else
92 struct Hook *iwp_StatusBar_updateHook;
93 #endif
96 /// From panel_toolbar
97 STRPTR ExpandEnvName(CONST_STRPTR env_path);
98 ///
100 const UBYTE MSG_MEM_G[] = "GB";
101 const UBYTE MSG_MEM_M[] = "MB";
102 const UBYTE MSG_MEM_K[] = "KB";
103 const UBYTE MSG_MEM_B[] = "Bytes";
105 ///FmtSizeToString()
106 static void FmtSizeToString(UBYTE *buf, ULONG num)
108 UQUAD d;
109 const UBYTE *ch;
110 struct
112 ULONG val;
113 ULONG dec;
114 } array =
116 num,
120 if (num >= 1073741824)
122 //Gigabytes
123 array.val = num >> 30;
124 d = ((UQUAD)num * 10 + 536870912) / 1073741824;
125 array.dec = d % 10;
126 ch = MSG_MEM_G;
128 else if (num >= 1048576)
130 //Megabytes
131 array.val = num >> 20;
132 d = ((UQUAD)num * 10 + 524288) / 1048576;
133 array.dec = d % 10;
134 ch = MSG_MEM_M;
136 else if (num >= 1024)
138 //Kilobytes
139 array.val = num >> 10;
140 d = (num * 10 + 512) / 1024;
141 array.dec = d % 10;
142 ch = MSG_MEM_K;
144 else
146 //Bytes
147 array.val = num;
148 array.dec = 0;
149 d = 0;
150 ch = MSG_MEM_B;
153 if (!array.dec && (d > array.val * 10))
155 array.val++;
158 RawDoFmt(array.dec ? "%lu.%lu" : "%lu", (RAWARG)&array, NULL, buf);
160 while (*buf)
162 buf++;
165 sprintf(buf, " %s", ch);
169 /*** Hook functions *********************************************************/
170 static
171 ///panelStatusBar__HookFunc_UpdateStatusFunc()
172 #ifdef __AROS__
173 AROS_UFH3(
174 void, panelStatusBar__HookFunc_UpdateStatusFunc,
175 AROS_UFHA(struct Hook *, hook, A0),
176 AROS_UFHA(APTR *, obj, A2),
177 AROS_UFHA(APTR, param, A1)
180 #else
181 HOOKPROTO(panelStatusBar__HookFunc_UpdateStatusFunc, void, APTR *obj, APTR param)
183 #endif
184 AROS_USERFUNC_INIT
186 /* Get data */
187 Object *self = ( Object *)obj;
188 Class *CLASS = *( Class **)param;
189 struct panel_StatusBar_DATA *panelStatusBarPrivate = NULL;
191 SETUP_ICONWINDOW_INST_DATA;
193 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
195 /* Only change dir if it is a valid directory/volume */
196 if ((panelStatusBarPrivate = (struct panel_StatusBar_DATA *)data->iwd_BottomPanel.iwp_PanelPrivate) != NULL)
198 if (panelStatusBarPrivate->iwp_Node.ln_Name != (char *)extension_Name)
199 return;
201 struct List *iconList = NULL;
202 struct IconEntry *icon = NULL;
203 UBYTE status_str[1024];
204 UBYTE size_str[256];
206 int files = 0, dirs = 0, hidden = 0;
207 ULONG size = 0;
209 GET(data->iwd_IconListObj, MUIA_Family_List, &iconList);
210 if (iconList)
212 ForeachNode(iconList, icon)
214 if (icon->ie_Flags & ICONENTRY_FLAG_VISIBLE)
216 if (icon->ie_IconListEntry.type == ST_USERDIR)
218 dirs += 1;
220 else
222 files += 1;
223 if (icon->ie_FileInfoBlock)
225 size += icon->ie_FileInfoBlock->fib_Size;
226 D(bug("[IW.statusbar] %s: '%s' FIB Size = %d bytes\n", __PRETTY_FUNCTION__, icon->ie_IconNode.ln_Name, icon->ie_FileInfoBlock->fib_Size));
230 else
232 hidden += 1;
236 int previous = 0;
237 if (files > 0)
239 FmtSizeToString(size_str, size);
240 sprintf(status_str, " %s in %d files", size_str, files);
241 previous = strlen(status_str);
243 if (dirs > 0)
245 sprintf(status_str + previous, "%s%d drawers", (previous > 0) ? ", " : " " , dirs);
246 previous = strlen(status_str);
248 if (hidden > 0)
250 sprintf(status_str + previous, " (%d hidden)", hidden);
251 previous = strlen(status_str);
254 if (previous > 0)
256 SET(panelStatusBarPrivate->iwp_StatusBar_StatusTextObj, MUIA_Text_Contents, (IPTR)status_str);
258 else
260 SET(panelStatusBarPrivate->iwp_StatusBar_StatusTextObj, MUIA_Text_Contents, (IPTR)"");
264 AROS_USERFUNC_EXIT
266 #ifndef __AROS__
267 MakeStaticHook(StatusBar_updateHook, panelStatusBar__HookFunc_UpdateStatusFunc);
268 #endif
270 /*** Main Functions ****************************************************************/
272 #define STATUSBAR_PREFSSIZE 1024
273 static IPTR panelStatusBar__HandleFSUpdate(Object *WandererObj, struct NotifyMessage *msg)
275 if (GetVar(extension_PrefsFile, extension_PrefsData, STATUSBAR_PREFSSIZE, GVF_GLOBAL_ONLY) != -1)
277 D(bug("[IW.statusbar] %s: Prefs contain '%s'\n", __PRETTY_FUNCTION__, extension_PrefsData));
278 if ((strcasecmp(extension_PrefsData, strTrue)) == 0)
280 SET(panelStatusBar__PrefsNotificationObject, MUIA_ShowMe, TRUE);
282 else
284 SET(panelStatusBar__PrefsNotificationObject, MUIA_ShowMe, FALSE);
287 return 0;
290 ///panelStatusBar__PrefsSetup()
291 static IPTR panelStatusBar__PrefsSetup(Class *CLASS, Object *self, struct opSet *message)
293 IPTR panelStatusBarFSNotifyPort = 0;
294 struct panel_StatusBar_DATA *panelStatusBarPrivate = NULL;
295 struct List *panelStatusBarFSNotifyList = NULL;
297 SETUP_ICONWINDOW_INST_DATA;
299 panelStatusBarFSNotifyPort = GetTagData(MUIA_Wanderer_FileSysNotifyPort, (IPTR) NULL, message->ops_AttrList);
300 panelStatusBarFSNotifyList = (APTR)GetTagData(MUIA_Wanderer_FileSysNotifyList, (IPTR) NULL, message->ops_AttrList);
302 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
304 extension_PrefsData = (STRPTR)strTrue;
306 if ((panelStatusBarPrivate = (struct panel_StatusBar_DATA *)data->iwd_BottomPanel.iwp_PanelPrivate) != NULL)
308 if (panelStatusBarPrivate->iwp_Node.ln_Name != (char *)extension_Name)
309 return 0;
311 extension_PrefsData = (STRPTR)AllocVec(STATUSBAR_PREFSSIZE, MEMF_CLEAR);
312 if (extension_PrefsData == NULL)
314 extension_PrefsData = (STRPTR)strTrue;
315 return 0;
318 /* Setup notification on prefs file --------------------------------*/
319 struct Wanderer_FSHandler *_prefsNotifyHandler = NULL;
321 if ((_prefsNotifyHandler = AllocMem(sizeof(struct Wanderer_FSHandler), MEMF_CLEAR)) != NULL)
323 _prefsNotifyHandler->fshn_Node.ln_Name = ExpandEnvName(extension_PrefsFile);
324 panelStatusBar__PrefsNotifyRequest.nr_Name = _prefsNotifyHandler->fshn_Node.ln_Name;
325 panelStatusBar__PrefsNotifyRequest.nr_Flags = NRF_SEND_MESSAGE;
326 panelStatusBar__PrefsNotifyRequest.nr_stuff.nr_Msg.nr_Port = (struct MsgPort *)panelStatusBarFSNotifyPort;
327 _prefsNotifyHandler->HandleFSUpdate = panelStatusBar__HandleFSUpdate;
329 if (StartNotify(&panelStatusBar__PrefsNotifyRequest))
331 D(bug("[IW.statusbar]%s: Prefs-notification setup on '%s'\n", __PRETTY_FUNCTION__, panelStatusBar__PrefsNotifyRequest.nr_Name));
333 else
335 D(bug("[IW.statusbar] %s: FAILED to setup Prefs-notification!\n", __PRETTY_FUNCTION__));
337 AddTail(panelStatusBarFSNotifyList, &_prefsNotifyHandler->fshn_Node);
339 #ifdef __AROS__
340 panelStatusBar__PrefsNotificationObject = (Object *)NotifyObject, End;
341 #else
342 panelStatusBar__PrefsNotificationObject = MUI_NewObject(MUIC_Notify, TAG_DONE);
343 #endif
344 if (GetVar(extension_PrefsFile, extension_PrefsData, STATUSBAR_PREFSSIZE, GVF_GLOBAL_ONLY) != -1)
346 D(bug("[IW.statusbar] %s: Prefs contain '%s'\n", __PRETTY_FUNCTION__, extension_PrefsData));
349 return 0;
353 ///panelStatusBar__Setup()
354 static IPTR panelStatusBar__Setup(Class *CLASS, Object *self, struct opSet *message)
356 SETUP_ICONWINDOW_INST_DATA;
358 Object *panel_StatusBar = NULL,
359 *panelStatusBar_TextStatus = NULL;
361 struct panel_StatusBar_DATA *panelStatusBarPrivate = NULL;
363 if (!(!(data->iwd_Flags & IWDFLAG_ISROOT) && data->iwd_BottomPanel.iwp_PanelContainerObj))
364 return 0;
366 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
368 if (data->iwd_BottomPanel.iwp_PanelPrivate == 0)
370 if ((data->iwd_BottomPanel.iwp_PanelPrivate = (IPTR)AllocVec(sizeof(struct panel_StatusBar_DATA), MEMF_CLEAR)) == (IPTR)NULL)
371 return 0;
373 panelStatusBarPrivate = (struct panel_StatusBar_DATA *)data->iwd_BottomPanel.iwp_PanelPrivate;
374 panelStatusBarPrivate->iwp_Node.ln_Name = (char *)extension_Name;
376 /* Create the "StatusBar" panel object .. */
377 panel_StatusBar = MUI_NewObject(MUIC_Group,
378 MUIA_InnerLeft,(0),
379 MUIA_InnerRight,(0),
380 MUIA_InnerTop,(0),
381 MUIA_InnerBottom,(0),
382 MUIA_Frame, MUIV_Frame_None,
383 Child, (IPTR)MUI_NewObject(MUIC_Group, MUIA_Group_Horiz, TRUE ,
384 MUIA_InnerLeft,(0),
385 MUIA_InnerRight,(0),
386 MUIA_InnerTop,(0),
387 MUIA_InnerBottom,(0),
388 MUIA_Group_Spacing, 0,
389 MUIA_FixHeight, 1,
390 MUIA_Frame, MUIV_Frame_None,
391 MUIA_Background, MUII_SHADOW,
392 Child, (IPTR)MUI_NewObject(MUIC_Rectangle,
393 MUIA_Frame, MUIV_Frame_None,
394 TAG_DONE),
395 TAG_DONE),
396 Child, (IPTR)MUI_NewObject(MUIC_Group, MUIA_Group_Horiz, TRUE ,
397 MUIA_InnerLeft,(4),
398 MUIA_InnerRight,(4),
399 MUIA_InnerTop,(4),
400 MUIA_InnerBottom,(4),
401 MUIA_Frame, MUIV_Frame_None,
402 MUIA_Weight, 100,
403 Child, (IPTR)MUI_NewObject(MUIC_Group, MUIA_Group_Horiz, TRUE ,
404 MUIA_InnerLeft,(0),
405 MUIA_InnerRight,(0),
406 MUIA_InnerTop,(0),
407 MUIA_InnerBottom,(0),
408 MUIA_Weight, 100,
409 Child, (IPTR)( panelStatusBar_TextStatus = MUI_NewObject(MUIC_Text,
410 MUIA_Font, MUIV_Font_Tiny,
411 MUIA_Text_Contents, (IPTR)"",
412 TAG_DONE) ),
413 TAG_DONE),
414 TAG_DONE),
415 TAG_DONE);
417 /* Got a StatusBarPanel? setup notifies and other values are
418 copied to the data of the object */
419 if ( panel_StatusBar != NULL )
421 D(bug("[IW.statusbar] %s: StatusBar Obj @ 0x%p\n", __PRETTY_FUNCTION__, panel_StatusBar));
423 panelStatusBarPrivate->iwp_StatusBar_StatusTextObj = panelStatusBar_TextStatus;
424 panelStatusBarPrivate->iwp_StatusBar_StatusBarObj = panel_StatusBar;
426 if (DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, MUIM_Group_InitChange ))
428 DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, OM_ADDMEMBER, (IPTR)panel_StatusBar);
429 if (data->iwd_BottomPanel.iwp_PanelGroupSpacerObj)
431 DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, OM_REMMEMBER, (IPTR)data->iwd_BottomPanel.iwp_PanelGroupSpacerObj);
432 data->iwd_BottomPanel.iwp_PanelGroupSpacerObj = NULL;
435 DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, MUIM_Group_ExitChange);
438 if (panelStatusBarPrivate->iwp_StatusBar_StatusBarObj)
440 #ifdef __AROS__
441 panelStatusBarPrivate->iwp_StatusBar_updateHook.h_Entry = ( HOOKFUNC )panelStatusBar__HookFunc_UpdateStatusFunc;
442 #else
443 panelStatusBarPrivate->iwp_StatusBar_updateHook= &StatusBar_updateHook;
444 #endif
445 DoMethod (
446 data->iwd_IconListObj, MUIM_Notify, MUIA_IconList_Changed, MUIV_EveryTime,
447 (IPTR)self, 3, MUIM_CallHook, &panelStatusBarPrivate->iwp_StatusBar_updateHook, (IPTR)CLASS
450 if (!(panelStatusBar__PrefsNotificationObject))
451 panelStatusBar__PrefsSetup(CLASS, self, message);
453 DoMethod
455 panelStatusBar__PrefsNotificationObject, MUIM_Notify, MUIA_ShowMe, MUIV_EveryTime,
456 (IPTR)data->iwd_BottomPanel.iwp_PanelContainerObj, 3, MUIM_Set, MUIA_ShowMe, MUIV_TriggerValue
459 if ((strcasecmp(extension_PrefsData, strTrue)) == 0)
461 SET(data->iwd_BottomPanel.iwp_PanelContainerObj, MUIA_ShowMe, TRUE);
464 AddTail(&panelStatusBar__StatusBars, &panelStatusBarPrivate->iwp_Node);
467 else
469 panelStatusBarPrivate->iwp_StatusBar_StatusBarObj = NULL;
472 return 0;
476 ///panelStatusBar__Cleanup()
477 static IPTR panelStatusBar__Cleanup(Class *CLASS, Object *self, Msg msg)
479 SETUP_ICONWINDOW_INST_DATA;
480 struct panel_StatusBar_DATA *panelStatusBarPrivate;
482 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
484 #if (0)
485 // we cant free this here since it will be used again!
486 if (extension_PrefsData && (extension_PrefsData != strTrue))
487 FreeVec(extension_PrefsData);
488 #endif
490 if ((panelStatusBarPrivate = (struct panel_StatusBar_DATA *)data->iwd_TopPanel.iwp_PanelPrivate) != NULL)
492 if (panelStatusBarPrivate->iwp_Node.ln_Name != (char *)extension_Name)
493 return 0;
495 if (panelStatusBar__PrefsNotificationObject)
497 DoMethod
499 panelStatusBar__PrefsNotificationObject, MUIM_KillNotifyObj, MUIA_ShowMe,
500 (IPTR)data->iwd_BottomPanel.iwp_PanelContainerObj
504 return 0;
508 ///panelStatusBar__OM_GET()
509 static IPTR panelStatusBar__OM_GET(Class *CLASS, Object *self, struct opGet *message)
511 SETUP_ICONWINDOW_INST_DATA;
513 struct panel_StatusBar_DATA *panelStatusBarPrivate = NULL;
514 // IPTR *store = message->opg_Storage;
515 IPTR rv = FALSE;
517 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
519 if ((panelStatusBarPrivate = (struct panel_StatusBar_DATA *)data->iwd_BottomPanel.iwp_PanelPrivate) != NULL)
521 if (panelStatusBarPrivate->iwp_Node.ln_Name != (char *)extension_Name)
522 return rv;
524 switch (message->opg_AttrID)
528 return rv;
532 ///OM_SET()
533 static IPTR panelStatusBar__OM_SET(Class *CLASS, Object *self, struct opSet *message)
535 SETUP_ICONWINDOW_INST_DATA;
537 struct panel_StatusBar_DATA *panelStatusBarPrivate = NULL;
538 struct TagItem *tstate = message->ops_AttrList, *tag;
539 // BOOL UpdateIconlist = FALSE;
540 // IPTR focusicon = (IPTR) NULL;
541 IPTR rv = FALSE;
543 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
545 if ((panelStatusBarPrivate = (struct panel_StatusBar_DATA *)data->iwd_BottomPanel.iwp_PanelPrivate) != NULL)
547 if (panelStatusBarPrivate->iwp_Node.ln_Name != (char *)extension_Name)
548 return rv;
550 while ((tag = NextTagItem((TAGITEM)&tstate)) != NULL)
552 switch (tag->ti_Tag)
554 /*case MUIA_IconWindowExt_ToolBar_Enabled:
555 if ((!(data->iwd_Flags & IWDFLAG_ISROOT)) && (data->iwd_BottomPanel.iwp_PanelContainerObj))
557 // remove statusbar
558 if (!(( BOOL )tag->ti_Data))
560 if (panelStatusBarPrivate->iwp_StatusBar_StatusBarObj != NULL)
562 data->iwd_BottomPanel.iwp_PanelGroupSpacerObj = HSpace(0);
564 SET(data->iwd_BottomPanel.iwp_PanelContainerObj, MUIA_Frame, MUIV_Frame_None);
565 SET(data->iwd_BottomPanel.iwp_PanelContainerObj, MUIA_Group_Spacing, 0);
567 if ((data->iwd_BottomPanel.iwp_PanelGroupSpacerObj) && (DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, MUIM_Group_InitChange)))
569 DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, OM_REMMEMBER, (IPTR)panelStatusBarPrivate->iwp_StatusBar_StatusBarObj);
570 DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, OM_ADDMEMBER, (IPTR)data->iwd_BottomPanel.iwp_PanelGroupSpacerObj);
571 DoMethod(data->iwd_BottomPanel.iwp_PanelGroupObj, MUIM_Group_ExitChange);
572 panelStatusBarPrivate->iwp_StatusBar_StatusBarObj = NULL;
576 else
578 // setup statusbar
579 if (panelStatusBarPrivate->iwp_StatusBar_StatusBarObj == NULL)
581 Object *prefs = NULL;
582 GET(_app(self), MUIA_Wanderer_Prefs, &prefs);
583 panelStatusBar__Setup(CLASS, self, prefs);
587 break;*/
591 return rv;
594 #define PANELSTATUSBAR_PRIORITY 10
596 IPTR panelStatusBar__Init()
598 D(bug("[IW.statusbar]: %s()\n", __PRETTY_FUNCTION__));
600 panelStatusBar__Extension.iwe_Node.ln_Pri = PANELSTATUSBAR_PRIORITY;
601 panelStatusBar__Extension.iwe_Node.ln_Name = (char *)extension_Name;
602 panelStatusBar__Extension.iwe_Setup = panelStatusBar__Setup;
603 panelStatusBar__Extension.iwe_Cleanup = panelStatusBar__Cleanup;
604 panelStatusBar__Extension.iwe_Set = panelStatusBar__OM_SET;
605 panelStatusBar__Extension.iwe_Get = panelStatusBar__OM_GET;
607 NewList(&panelStatusBar__StatusBars);
609 Enqueue(&iconwindow_Extensions, (struct Node *)&panelStatusBar__Extension);
611 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));
613 return TRUE;
616 ADD2INIT(panelStatusBar__Init, PANELSTATUSBAR_PRIORITY);