home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / TaskBar.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  14.5 KB  |  556 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /* 
  19.    TaskBar.cpp -- implementation file for TaskBar
  20.    Created: Stephen Lamm <slamm@netscape.com>, 19-Nov-96.
  21.  */
  22.  
  23.  
  24. #include "TaskBar.h"
  25. #include "TaskBarDrop.h"
  26.  
  27. #include "Button.h"
  28. #include "Command.h"
  29. #include "Frame.h"
  30.  
  31. #ifdef MOZ_MAIL_NEWS
  32. #include "MNView.h"
  33. #endif
  34.  
  35. #include "MozillaApp.h"
  36. #include "BrowserFrame.h"
  37. #include "Dashboard.h"
  38. #include "BookmarkFrame.h"
  39. #include "Toolbar.h"
  40. #include "xfe2_extern.h"
  41. #include "prefapi.h"
  42.  
  43. #include <Xfe/TaskBar.h>
  44. #include <Xfe/Button.h>
  45.  
  46. #ifdef MOZ_MAIL_NEWS
  47. #define SM_BIFF_UNKNOWN_ICONS TaskSm_MailU_group
  48. #define SM_BIFF_NEWMAIL_ICONS TaskSm_MailY_group
  49. #define SM_BIFF_NOMAIL_ICONS  TaskSm_MailN_group
  50.  
  51. #define LG_BIFF_UNKNOWN_ICONS Task_MailU_group
  52. #define LG_BIFF_NEWMAIL_ICONS Task_MailY_group
  53. #define LG_BIFF_NOMAIL_ICONS  Task_MailN_group
  54. #endif
  55.  
  56. #define FLOATING_TASK_BAR_NAME        "floatingTaskBar"
  57. #define DOCKED_TASK_BAR_NAME        "dockedTaskBar"
  58.  
  59. //////////////////////////////////////////////////////////////////////////
  60. //
  61. // Small icons.
  62. //
  63. //////////////////////////////////////////////////////////////////////////
  64. /*static */ TaskBarSpec 
  65. XFE_TaskBar::m_dockedSpec[] = 
  66. {
  67.     { xfeCmdOpenOrBringUpBrowser,    PUSHBUTTON,  &TaskSm_Browser_group },
  68. #ifdef MOZ_MAIL_NEWS
  69.     { xfeCmdOpenInboxAndGetNewMessages,    PUSHBUTTON,  &SM_BIFF_UNKNOWN_ICONS },
  70.     { xfeCmdOpenNewsgroups, PUSHBUTTON,  &TaskSm_Discussions_group },
  71. #endif
  72.     { xfeCmdOpenEditor,     PUSHBUTTON,  &TaskSm_Composer_group },
  73.     { NULL }
  74. };
  75.  
  76. //////////////////////////////////////////////////////////////////////////
  77. //
  78. // Large icons.
  79. //
  80. //////////////////////////////////////////////////////////////////////////
  81. /*static */ TaskBarSpec 
  82. XFE_TaskBar::m_floatingSpec[] = 
  83. {
  84.     { xfeCmdOpenOrBringUpBrowser,    PUSHBUTTON,  &Task_Browser_group },
  85. #ifdef MOZ_MAIL_NEWS
  86.     { xfeCmdOpenInboxAndGetNewMessages,    PUSHBUTTON,  &LG_BIFF_UNKNOWN_ICONS },
  87.     { xfeCmdOpenNewsgroups, PUSHBUTTON,  &Task_Discussions_group },
  88. #endif
  89.     { xfeCmdOpenEditor,     PUSHBUTTON,  &Task_Composer_group },
  90.     { NULL }
  91. };
  92.  
  93. //////////////////////////////////////////////////////////////////////////
  94. //
  95. // XFE_TaskBar Public Methods
  96. //
  97. //////////////////////////////////////////////////////////////////////////
  98. XFE_TaskBar::XFE_TaskBar(Widget            parent,
  99.                          XFE_Frame *    parent_frame,
  100.                          XP_Bool        is_floating) :
  101.     XFE_Component(parent_frame),
  102.     m_isFloating(is_floating),
  103.     m_parentFrame(parent_frame)
  104. #ifdef MOZ_MAIL_NEWS
  105.     ,m_biffNoticeInstalled(False)
  106. #endif
  107. {
  108.     XP_ASSERT( parent_frame != NULL );
  109.  
  110.     // Create widgets according to docking state
  111.     if (!m_isFloating)
  112.     {
  113.         createDockedWidgets(parent);
  114.     }
  115.     else
  116.     {
  117.         createFloatingWidgets(parent);
  118.  
  119.         XFE_MozillaApp::theApp()->registerInterest(
  120.             XFE_MozillaApp::appBusyCallback,
  121.             this,
  122.             updateFloatingBusyState_cb,
  123.             (void*)True);
  124.  
  125.         XFE_MozillaApp::theApp()->registerInterest(
  126.             XFE_MozillaApp::appNotBusyCallback,
  127.             this,
  128.             updateFloatingBusyState_cb,
  129.             (void*)False);
  130.     }
  131.     
  132.     installDestroyHandler();
  133. }
  134. //////////////////////////////////////////////////////////////////////////
  135. XFE_TaskBar::~XFE_TaskBar()
  136. {
  137. #ifdef MOZ_MAIL_NEWS
  138.     // Unregister the biff notice if needed
  139.     if (m_biffNoticeInstalled)
  140.     {
  141.         XFE_MozillaApp::theApp()->unregisterInterest(
  142.             XFE_MozillaApp::biffStateChanged,
  143.             this,
  144.             (XFE_FunctionNotification)updateBiffStateNotice_cb);
  145.     }
  146. #endif
  147.  
  148.     if (m_isFloating)
  149.     {
  150.         XFE_MozillaApp::theApp()->unregisterInterest(
  151.             XFE_MozillaApp::appBusyCallback,
  152.             this,
  153.             updateFloatingBusyState_cb,
  154.             (void*)True);
  155.  
  156.         XFE_MozillaApp::theApp()->unregisterInterest(
  157.             XFE_MozillaApp::appNotBusyCallback,
  158.             this,
  159.             updateFloatingBusyState_cb,
  160.             (void*)False);
  161.     }
  162. }
  163. //////////////////////////////////////////////////////////////////////////
  164. #ifdef MOZ_MAIL_NEWS
  165. XFE_CALLBACK_DEFN(XFE_TaskBar, updateBiffStateNotice)
  166.     (XFE_NotificationCenter*    /* obj */,
  167.      void *                        /* callData */, 
  168.      void *                        clientData)
  169. {
  170.     MSG_BIFF_STATE state = (MSG_BIFF_STATE) clientData;
  171.     IconGroup *icons = 0;
  172.     
  173.     switch (state)
  174.     {
  175.     case MSG_BIFF_NewMail:
  176.         
  177.         if (m_isFloating)
  178.             icons = &LG_BIFF_NEWMAIL_ICONS;
  179.         else
  180.             icons = &SM_BIFF_NEWMAIL_ICONS;
  181.         break;
  182.         
  183.     case MSG_BIFF_NoMail:
  184.         
  185.         if (m_isFloating)
  186.             icons = &LG_BIFF_NOMAIL_ICONS;
  187.         else
  188.             icons = &SM_BIFF_NOMAIL_ICONS;
  189.         break;
  190.         
  191.     case MSG_BIFF_Unknown:
  192.         
  193.         if (m_isFloating)
  194.             icons = &LG_BIFF_UNKNOWN_ICONS;
  195.         else
  196.             icons = &SM_BIFF_UNKNOWN_ICONS;
  197.         break;
  198.         
  199.     default:
  200.         XP_ASSERT(0);
  201.     }
  202.     
  203.     setIconGroupForCommand(xfeCmdOpenInboxAndGetNewMessages, 
  204.                            icons);
  205. }
  206. //////////////////////////////////////////////////////////////////////////
  207. #endif
  208.  
  209.  
  210. //////////////////////////////////////////////////////////////////////////
  211. //
  212. // XFE_TaskBar Private Methods
  213. //
  214. //////////////////////////////////////////////////////////////////////////
  215. void
  216. XFE_TaskBar::setIconGroupForCommand(CommandType cmd, IconGroup *icons)
  217. {
  218.     Widget *    children;
  219.     Cardinal    num_children;
  220.     Cardinal    i;
  221.   
  222.     XfeChildrenGet(m_widget,&children,&num_children);
  223.  
  224.     for (i = 0; i < num_children; i ++)
  225.     {
  226.         if (XfeIsButton(children[i]))
  227.         {
  228.             if (Command::intern(XtName(children[i])) == cmd)
  229.             {
  230.                 XFE_Button * button = 
  231.                     (XFE_Button *) XfeInstancePointer(children[i]);
  232.                 
  233.                 XP_ASSERT(button);
  234.  
  235.                 if (!button) return;
  236.                 
  237.                 button->setPixmap(icons);
  238.                 
  239.                 return;
  240.             }
  241.         }
  242.     }
  243.  
  244.     XP_ASSERT(0); // command not found in the taskbar...
  245. }
  246. //////////////////////////////////////////////////////////////////////////
  247. static void DropSiteDestroyCb(Widget,XtPointer cd,XtPointer)
  248. {
  249.     if (cd)
  250.         delete (XFE_TaskBarDrop*)cd;
  251. }
  252.  
  253.  
  254.  
  255. Widget
  256. XFE_TaskBar::createTaskBarButton(TaskBarSpec *spec)
  257. {
  258.     Widget result = NULL;
  259.     
  260.     XP_ASSERT( XfeIsAlive(m_widget) );
  261.     
  262.     if ( (spec->taskBarButtonName == xfeCmdOpenEditor) &&
  263.          fe_IsEditorDisabled() )
  264.     {
  265.         return NULL;
  266.     }
  267.  
  268.     // Create a XFE_Button.
  269.     XFE_Button *newButton = new XFE_Button(m_parentFrame,
  270.                                            m_widget,
  271.                                            spec->taskBarButtonName, 
  272.                                            spec->icons);
  273.     
  274.     newButton->registerInterest(XFE_Button::doCommandCallback,
  275.                                 this,
  276.                                 (XFE_FunctionNotification)doCommandNotice_cb);
  277.  
  278.     XtVaSetValues(newButton->getBaseWidget(),
  279.                   XmNtraversalOn,            False,
  280.                   XmNhighlightThickness,    0,
  281.                   NULL);
  282.     
  283.     // Show the new button
  284.     newButton->show();
  285.     
  286.     result = newButton->getBaseWidget();
  287.     
  288.     // register drop site and associated destroy callback
  289.     // for interesting commands
  290.     
  291.     if (spec->taskBarButtonName == xfeCmdOpenOrBringUpBrowser
  292.         || spec->taskBarButtonName == xfeCmdOpenEditor 
  293. #ifdef MOZ_MAIL_NEWS
  294.         || spec->taskBarButtonName == xfeCmdOpenInboxAndGetNewMessages 
  295.         || spec->taskBarButtonName == xfeCmdOpenNewsgroups
  296. #endif
  297.         ) 
  298.     {
  299.         XFE_TaskBarDrop * dropSite = 
  300.             new XFE_TaskBarDrop(result,spec->taskBarButtonName);
  301.  
  302.         dropSite->enable();
  303.  
  304.         XtAddCallback(result,
  305.                       XmNdestroyCallback,
  306.                       DropSiteDestroyCb,
  307.                       (XtPointer)dropSite);
  308.     }
  309.  
  310. #ifdef MOZ_MAIL_NEWS
  311.     if (spec->taskBarButtonName == xfeCmdOpenInboxAndGetNewMessages)
  312.     {
  313.         XFE_MozillaApp::theApp()->registerInterest(
  314.             XFE_MozillaApp::biffStateChanged,
  315.             this,
  316.             (XFE_FunctionNotification) updateBiffStateNotice_cb);
  317.         
  318.         // make sure we have the correct biff icon when we start.
  319.         updateBiffStateNotice(NULL, 
  320.                               NULL,
  321.                               (void*) XFE_MNView::getBiffState());
  322.  
  323.         m_biffNoticeInstalled = True;
  324.     }
  325. #endif
  326.         
  327.     return result;
  328. }
  329. //////////////////////////////////////////////////////////////////////////
  330. void
  331. XFE_TaskBar::createDockedWidgets(Widget parent)
  332. {
  333.     XP_ASSERT( XfeIsAlive(parent) );
  334.  
  335.     // Create a horizontal task bar
  336.     m_widget = XtVaCreateWidget(DOCKED_TASK_BAR_NAME,
  337.                                 xfeTaskBarWidgetClass,
  338.                                 parent,
  339.                                 XmNorientation,            XmHORIZONTAL,
  340.                                 XmNusePreferredWidth,    True,
  341.                                 XmNusePreferredHeight,    True,
  342.                                 NULL);
  343.  
  344.     // Floating undock image
  345.     IconGroup_createAllIcons(&TaskSm_Handle_group,
  346.  
  347.                              XfeAncestorFindByClass(m_widget,
  348.                                                     shellWidgetClass,
  349.                                                     XfeFIND_ANY),
  350.  
  351.                              XfeForeground(m_widget),
  352.  
  353.                              XfeBackground(m_widget));
  354.  
  355.     // Create floating buttons
  356.     createButtons(m_dockedSpec);
  357.     
  358.     if (XfePixmapGood(TaskSm_Handle_group.pixmap_icon.pixmap))
  359.     {
  360.         XtVaSetValues(m_widget,
  361.                       XmNactionPixmap, TaskSm_Handle_group.pixmap_icon.pixmap,
  362.                       NULL);
  363.     }
  364.  
  365.     // If the floating taskbar does not have any enabled buttons, then 
  366.     // we dont need to show the action button.
  367.     XFE_TaskBar * ftb = XFE_Dashboard::getFloatingTaskBar();
  368.  
  369.     if (!ftb || !ftb->numEnabledButtons())
  370.     {
  371.         XtVaSetValues(m_widget,XmNshowActionButton,False,NULL);
  372.     }
  373. }
  374. //////////////////////////////////////////////////////////////////////////
  375. void
  376. XFE_TaskBar::createFloatingWidgets(Widget parent)
  377. {
  378.     XP_ASSERT( XfeIsAlive(parent) );
  379.  
  380.     unsigned char    orientation = 
  381.         fe_globalPrefs.task_bar_horizontal ? XmHORIZONTAL : XmVERTICAL;
  382.     
  383.     // Create the floating task bar
  384.     m_widget = XtVaCreateWidget(FLOATING_TASK_BAR_NAME,
  385.                                 xfeTaskBarWidgetClass,
  386.                                 parent,
  387.                                 XmNorientation,            orientation,
  388.                                 XmNusePreferredWidth,    True,
  389.                                 XmNusePreferredHeight,    True,
  390.                                 NULL);
  391.  
  392.     // Create floating buttons
  393.     createButtons(m_floatingSpec);
  394.  
  395.     // Show both label and pixmap for floating tools
  396.     XtVaSetValues(m_widget,XmNbuttonLayout,XmBUTTON_LABEL_ON_BOTTOM,NULL);
  397.  
  398.     // Update the floating appearance for the first time
  399.     updateFloatingAppearance();
  400.  
  401.     // Update the icons layout when needed
  402.     XFE_MozillaApp::theApp()->registerInterest(
  403.         XFE_MozillaApp::updateToolbarAppearance,
  404.         this,
  405.         (XFE_FunctionNotification)updateIconAppearance_cb);
  406. }
  407. //////////////////////////////////////////////////////////////////////////
  408. void 
  409. XFE_TaskBar::createButtons(TaskBarSpec * spec)
  410. {
  411.     XP_ASSERT( XfeIsAlive(m_widget) );
  412.     
  413.     if (!spec)
  414.     {
  415.         return;
  416.     }
  417.  
  418.     TaskBarSpec *cur_spec = spec;
  419.     
  420.     while (cur_spec->taskBarButtonName)
  421.     {
  422.         // Create the button only if it is not disabled through resources.
  423.           if (XfeChildIsEnabled(m_widget,
  424.                               (String) cur_spec->taskBarButtonName,
  425.                               "TaskBarButton",
  426.                               True))
  427.           {
  428.             createTaskBarButton(cur_spec);
  429.           }
  430.  
  431.         cur_spec++;
  432.     }
  433. }
  434. //////////////////////////////////////////////////////////////////////////
  435. XFE_CALLBACK_DEFN(XFE_TaskBar,doCommandNotice)
  436.     (XFE_NotificationCenter *        /*obj*/,
  437.      void *                            /*clientData*/,
  438.      void *                            callData)
  439. {
  440.     XP_ASSERT( m_parentFrame != NULL );
  441.  
  442.     // This code is identical to that in XFE_Toolbar::doCommand_cb()
  443.     XFE_DoCommandArgs *    cmdArgs = (XFE_DoCommandArgs *)callData;
  444.  
  445.     if (m_parentFrame->handlesCommand(cmdArgs->cmd,
  446.                                       cmdArgs->callData,
  447.                                       cmdArgs->info)
  448.         && m_parentFrame->isCommandEnabled(cmdArgs->cmd,
  449.                                            cmdArgs->callData,
  450.                                            cmdArgs->info))
  451.     {
  452.         // Busy 
  453.         XFE_MozillaApp::theApp()->notifyInterested(XFE_MozillaApp::appBusyCallback);
  454.  
  455.         xfe_ExecuteCommand(m_parentFrame, cmdArgs->cmd, cmdArgs->callData,
  456.                            cmdArgs->info );
  457.         
  458.  
  459.         // Not busy
  460.         XFE_MozillaApp::theApp()->notifyInterested(XFE_MozillaApp::appNotBusyCallback);
  461.  
  462.         m_parentFrame->notifyInterested(Command::commandDispatchedCallback, 
  463.                                         callData);
  464.     }
  465. }
  466. //////////////////////////////////////////////////////////////////////////
  467. void
  468. XFE_TaskBar::updateFloatingAppearance() 
  469. {
  470.     XP_ASSERT( XfeIsAlive(m_widget) );
  471.     XP_ASSERT( m_isFloating == True );
  472.  
  473.     unsigned char    button_layout;
  474.  
  475.     button_layout = XFE_Toolbar::styleToLayout(fe_globalPrefs.toolbar_style);
  476.  
  477.     XtVaSetValues(m_widget,XmNbuttonLayout,button_layout,NULL);
  478. }
  479. //////////////////////////////////////////////////////////////////////////
  480. void
  481. XFE_TaskBar::setFloatingTitle(const char * title)
  482. {
  483.     XP_ASSERT( XfeIsAlive(m_widget) );
  484.     XP_ASSERT( m_isFloating == True );
  485.     XP_ASSERT( m_isFloating == True );
  486.  
  487.     Widget shell_widget = XfeAncestorFindByClass(m_widget,
  488.                                                  shellWidgetClass,
  489.                                                  XfeFIND_ANY);
  490.  
  491.     XtVaSetValues(shell_widget,XmNtitle,title,NULL);
  492. }
  493. //////////////////////////////////////////////////////////////////////////
  494. Cardinal
  495. XFE_TaskBar::numEnabledButtons()
  496. {
  497.     if (!XfeIsAlive(m_widget))
  498.     {
  499.         return 0;
  500.     }
  501.  
  502.     Cardinal num_managed = XfeChildrenGetNumManaged(m_widget);
  503.  
  504.     // Ignore the action button
  505.     if (!m_isFloating && (num_managed > 0))
  506.     {
  507.         num_managed--;
  508.     }
  509.  
  510.     return num_managed;
  511. }
  512. //////////////////////////////////////////////////////////////////////////
  513.  
  514. XFE_CALLBACK_DEFN(XFE_TaskBar,updateIconAppearance)
  515.     (XFE_NotificationCenter *    /*obj*/, 
  516.      void *                        /*clientData*/, 
  517.      void *                        /*callData*/)
  518. {
  519.     updateFloatingAppearance();
  520. }
  521. //////////////////////////////////////////////////////////////////////////
  522. XFE_CALLBACK_DEFN(XFE_TaskBar, updateFloatingBusyState)
  523.     (XFE_NotificationCenter *    /* obj */,
  524.      void *                        clientData,
  525.      void *                        /* callData */)
  526. {
  527.     XP_Bool busy = (XP_Bool) (int) clientData;
  528.  
  529.     Widget floatingShell = XfeAncestorFindByClass(m_widget,
  530.                                                   shellWidgetClass,
  531.                                                   XfeFIND_ANY);
  532.  
  533.     // Dont update busy state if not realized/alive or undocked
  534.     if (!XfeIsAlive(floatingShell) || 
  535.         !XtIsRealized(floatingShell) ||
  536.         XFE_Dashboard::isTaskBarDocked())
  537.     {
  538.         return;
  539.     }
  540.  
  541.     if (busy)
  542.     {
  543.         MWContext *    context = m_parentFrame->getContext();
  544.         Cursor        cursor = CONTEXT_DATA(context)->busy_cursor;
  545.  
  546.         XDefineCursor(XtDisplay(floatingShell),
  547.                       XtWindow(floatingShell),
  548.                       cursor);
  549.     }
  550.     else
  551.     {
  552.         XUndefineCursor(XtDisplay(floatingShell),XtWindow(floatingShell));
  553.     }
  554. }
  555. //////////////////////////////////////////////////////////////////////////
  556.