home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / Toolbar.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  28.8 KB  |  1,197 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.    Toolbar.cpp -- implementation file for toolbars
  20.    Created: Chris Toshok <toshok@netscape.com>, 13-Aug-96.
  21.  */
  22.  
  23.  
  24.  
  25. #include "Frame.h"
  26. #include "HTMLView.h"
  27. #include "MozillaApp.h"
  28. #include "Toolbar.h"
  29. #include "Command.h"
  30. #include "Button.h"
  31. #include "Logo.h"
  32. #include "Toolbox.h"
  33. #include "BackForwardMenu.h"
  34. #include "prefapi.h"
  35.  
  36. #include <Xfe/ToolBar.h>
  37. #include <Xfe/ToolBox.h>
  38. #include <Xfe/ToolItem.h>
  39. #include <Xfe/Cascade.h>
  40.  
  41. #if 0
  42. #define D(x) x
  43. #else
  44. #define D(x)
  45. #endif
  46.  
  47. #define MAX_DELAY 5000
  48. #define MIN_DELAY 0
  49.  
  50. #define LOGO_NAME                "logo"
  51. #define TOOL_BAR_ITEM_NAME        "toolBarItem"
  52. #define TOOL_BAR_NAME            "toolBar"
  53.  
  54. //////////////////////////////////////////////////////////////////////////
  55. //
  56. // User command resources
  57. //
  58. //////////////////////////////////////////////////////////////////////////
  59. /* static */ XtResource
  60. XFE_Toolbar::m_user_commandResources[] = 
  61. {
  62.     {
  63.         "commandName",
  64.         "CommandName",
  65.         XmRString,
  66.         sizeof(String),
  67.         XtOffset(XFE_Toolbar *, m_user_commandName),
  68.         XmRString,
  69.         "Error"
  70.     },
  71.     {
  72.         "commandData",
  73.         "CommandData",
  74.         XmRString,
  75.         sizeof(String),
  76.         XtOffset(XFE_Toolbar *, m_user_commandData),
  77.         XmRImmediate,
  78.         (XtPointer) NULL
  79.     },
  80.     {
  81.         "commandIcon",
  82.         "CommandIcon",
  83.         XmRString,
  84.         sizeof(String),
  85.         XtOffset(XFE_Toolbar *, m_user_commandIcon),
  86.         XmRImmediate,
  87.         (XtPointer) NULL
  88.     },
  89.     {
  90.         "commandSubMenu",
  91.         "CommandSubMenu",
  92.         XmRString,
  93.         sizeof(String),
  94.         XtOffset(XFE_Toolbar *, m_user_commandSubMenu),
  95.         XmRImmediate,
  96.         (XtPointer) NULL
  97.     },
  98. };
  99. //////////////////////////////////////////////////////////////////////////
  100.  
  101. //
  102. // XFE_Toolbar class
  103. //
  104. //////////////////////////////////////////////////////////////////////////
  105. XFE_Toolbar::XFE_Toolbar(XFE_Frame *        parent_frame,
  106.                          XFE_Toolbox *        parent_toolbox,
  107.                          ToolbarSpec *        spec) :
  108.     XFE_ToolboxItem(parent_frame,parent_toolbox)
  109. {
  110.     m_parentFrame = parent_frame;
  111.  
  112.     m_spec = spec;
  113.  
  114.     m_security = NULL;
  115.  
  116.     createMain(m_parentToolbox->getBaseWidget());
  117.  
  118.     createItems();
  119.  
  120.     // add drag widgets for toolbar
  121.     addDragWidget(getBaseWidget());
  122.     addDragWidget(getToolBar());
  123.     addDragWidget(getToolBarForm());
  124.  
  125.     m_parentFrame->registerInterest(XFE_View::chromeNeedsUpdating,
  126.                                     this,
  127.                                     (XFE_FunctionNotification)update_cb);
  128.  
  129.     m_parentFrame->registerInterest(XFE_View::commandNeedsUpdating,
  130.                                     this,
  131.                                     (XFE_FunctionNotification)updateCommand_cb);
  132.  
  133.     XFE_MozillaApp::theApp()->registerInterest(XFE_View::commandNeedsUpdating,
  134.                                                this,
  135.                                                (XFE_FunctionNotification)updateCommand_cb);
  136.  
  137.     XFE_MozillaApp::theApp()->registerInterest(XFE_MozillaApp::updateToolbarAppearance,
  138.                                                this,
  139.                                                (XFE_FunctionNotification)updateToolbarAppearance_cb);
  140. }
  141. //////////////////////////////////////////////////////////////////////////
  142. XFE_Toolbar::~XFE_Toolbar()
  143. {
  144.     m_parentFrame->unregisterInterest(XFE_View::chromeNeedsUpdating,
  145.                                       this,
  146.                                       (XFE_FunctionNotification)update_cb);
  147.  
  148.     m_parentFrame->unregisterInterest(XFE_View::commandNeedsUpdating,
  149.                                       this,
  150.                                       (XFE_FunctionNotification)updateCommand_cb);
  151.  
  152.     XFE_MozillaApp::theApp()->unregisterInterest(XFE_View::commandNeedsUpdating,
  153.                                                  this,
  154.                                                  (XFE_FunctionNotification)updateCommand_cb);
  155.  
  156.     XFE_MozillaApp::theApp()->unregisterInterest(XFE_MozillaApp::updateToolbarAppearance,
  157.                                                  this,
  158.                                                  (XFE_FunctionNotification)updateToolbarAppearance_cb);
  159. }
  160. //////////////////////////////////////////////////////////////////////////
  161. void
  162. XFE_Toolbar::updateButton(Widget w)
  163. {
  164.     XP_ASSERT( XfeIsAlive(w) );
  165.     XP_ASSERT( XfeIsButton(w) );
  166.  
  167.     // Make very sure we deal with a valid button/cascade
  168.     if (!w || !XfeIsButton(w) || !XfeIsAlive(w))
  169.     {
  170.         return;
  171.     }
  172.  
  173.     XFE_Button * button = (XFE_Button *) XfeInstancePointer(w);
  174.  
  175.     XP_ASSERT(button);
  176.  
  177.     if (!button)
  178.     {
  179.         return;
  180.     }
  181.  
  182.     // Ontain the button's command
  183.     CommandType cmd = button->getCmd();
  184.  
  185.     button->setPretendSensitive(m_parentFrame->isCommandEnabled(cmd));
  186.  
  187.     // The submenu items of the back/forward buttons are dynamic and
  188.     // always active, so leave them alone.
  189.     if ((cmd == xfeCmdBack) || (cmd == xfeCmdForward))
  190.     {
  191.         return;
  192.     }        
  193.  
  194.     // check for Cascade button with pulldown attached
  195.     if (XfeIsCascade(w)) 
  196.     {
  197.         Widget *    children;
  198.         Cardinal    num_children;
  199.         Cardinal    j;
  200.  
  201.         // Obtain the children
  202.         XfeCascadeGetChildren(w,&children,&num_children);
  203.  
  204.         for (j = 0; j < num_children; j++)
  205.         {
  206.             Widget child = children[j];
  207.  
  208.             if (XfeIsAlive(child) && XtName(child))
  209.             {
  210.                 // Only gadgets are used by XFE_Button for submenus
  211.  
  212.                 if (XmIsPushButtonGadget(child))
  213.                 {
  214.                     CommandType cmd = Command::intern(XtName(child));
  215.                     Boolean enabled = m_parentFrame->isCommandEnabled(cmd);
  216.  
  217.                     XtSetSensitive(child,enabled);
  218.  
  219.                     // toolbar button must be enabled if any of the 
  220.                     // subcommands are.
  221.                     if (enabled)
  222.                         button->setPretendSensitive(True);
  223.  
  224.                     char *command_string;
  225.  
  226.                     command_string = m_parentFrame->commandToString(cmd);
  227.                     
  228.                     if ( command_string )
  229.                     {
  230.                         XmString str;
  231.                                 
  232.                         str = XmStringCreate(command_string, 
  233.                                              XmFONTLIST_DEFAULT_TAG);
  234.                                 
  235.                         XtVaSetValues(child, XmNlabelString, str, NULL);
  236.                                 
  237.                         XmStringFree(str);
  238.                     }
  239.                 }
  240.                 else if (XmIsToggleButtonGadget(child))
  241.                 {
  242.                     CommandType cmd = Command::intern(XtName(child));
  243.                     Boolean turnOn = m_parentFrame->isCommandSelected(cmd);
  244.  
  245.                     XmToggleButtonGadgetSetState(child,turnOn,False);
  246.  
  247.                     char *command_string;
  248.  
  249.                     command_string = m_parentFrame->commandToString(cmd);
  250.                     
  251.                     if ( command_string )
  252.                     {
  253.                         XmString str;
  254.                                 
  255.                         str = XmStringCreate(command_string, 
  256.                                              XmFONTLIST_DEFAULT_TAG);
  257.                                 
  258.                         XtVaSetValues(child, XmNlabelString, str, NULL);
  259.                                 
  260.                         XmStringFree(str);
  261.                     }
  262.                 }
  263.             }
  264.         }
  265.     }
  266. }
  267. //////////////////////////////////////////////////////////////////////////
  268. XFE_CALLBACK_DEFN(XFE_Toolbar, updateCommand)(XFE_NotificationCenter */*obj*/, 
  269.                           void */*clientData*/, 
  270.                           void *callData)
  271. {
  272.     D(printf("In XFE_Toolbar::updateCommand(%s)\n",Command::getString(cmd));)  
  273.  
  274.     // Make sure the toolbar is alive
  275.     if (!XfeIsAlive(m_toolBar))
  276.     {
  277.         return;
  278.     }
  279.     
  280.     Widget *        children;
  281.     Cardinal        num_children;
  282.     Cardinal        i;
  283.     CommandType        cmd = (CommandType) callData;
  284.  
  285.     XfeChildrenGet(m_toolBar,&children,&num_children);    
  286.     
  287.     for (i = 0; i < num_children; i ++)
  288.     {
  289.         if (XfeIsButton(children[i]))
  290.         {
  291.             XFE_Button * button = 
  292.                 (XFE_Button *) XfeInstancePointer(children[i]);
  293.             
  294.             if (button)
  295.             {
  296.                 if (cmd == button->getCmd())
  297.                     button->setPretendSensitive(m_parentFrame->isCommandEnabled(cmd));
  298.             }
  299.         }
  300.     }
  301. }
  302. //////////////////////////////////////////////////////////////////////////
  303. XFE_CALLBACK_DEFN(XFE_Toolbar, update)(XFE_NotificationCenter */*obj*/, 
  304.                                        void */*clientData*/, 
  305.                                        void */*callData*/)
  306. {
  307.   update();
  308. }
  309. //////////////////////////////////////////////////////////////////////////
  310. void
  311. XFE_Toolbar::update()
  312. {
  313.     D(    printf ("In XFE_Toolbar::update()\n");)
  314.  
  315.     // Make sure the toolbar is alive
  316.     if (!XfeIsAlive(m_toolBar))
  317.     {
  318.         return;
  319.     }
  320.   
  321.     Widget *        children;
  322.     Cardinal        num_children;
  323.     Cardinal        i;
  324.  
  325.     XfeChildrenGet(m_toolBar,&children,&num_children);
  326.  
  327.     for (i = 0; i < num_children; i ++)
  328.     {
  329.         if (XfeIsButton(children[i]))
  330.         {
  331.             if (m_security && children[i] == m_security->getBaseWidget())
  332.             {
  333.                 m_security->useIconGroup(m_parentFrame->getSecurityStatus());
  334.             }
  335.             updateButton(children[i]);
  336.         }
  337.     }
  338.     
  339.     D(    printf ("Leaving XFE_Toolbar::update()\n");)
  340. }
  341. //////////////////////////////////////////////////////////////////////////
  342. XFE_CALLBACK_DEFN(XFE_Toolbar, updateToolbarAppearance)(XFE_NotificationCenter */*obj*/, 
  343.                                        void */*clientData*/, 
  344.                                        void */*callData*/)
  345. {
  346.     updateAppearance();
  347. }
  348. //////////////////////////////////////////////////////////////////////////
  349. void
  350. XFE_Toolbar::updateAppearance() 
  351. {
  352.     unsigned char    button_layout;
  353.  
  354.     button_layout = XFE_Toolbar::styleToLayout(fe_globalPrefs.toolbar_style);
  355.  
  356.     XtVaSetValues(m_toolBar,XmNbuttonLayout,button_layout,NULL);
  357.  
  358.     if (button_layout == XmBUTTON_LABEL_ON_BOTTOM)
  359.     {
  360.         m_logo->setSize(XFE_ANIMATION_LARGE);
  361.     }
  362.     else
  363.     {
  364.         m_logo->setSize(XFE_ANIMATION_SMALL);
  365.     }
  366. }
  367. //////////////////////////////////////////////////////////////////////////
  368. void
  369. XFE_Toolbar::setToolbarSpec(ToolbarSpec *spec)
  370. {
  371.     XP_ASSERT( spec != NULL );
  372.     XP_ASSERT( m_spec == NULL );
  373.  
  374.     m_spec = spec;
  375.  
  376.     m_security = NULL;
  377.  
  378.     createItems();
  379. }
  380. //////////////////////////////////////////////////////////////////////////
  381. XFE_Frame *
  382. XFE_Toolbar::getFrame()
  383. {
  384.     return m_parentFrame;
  385. }
  386. //////////////////////////////////////////////////////////////////////////
  387. void
  388. XFE_Toolbar::addButton(const char */*name*/,
  389.                        EChromeTag /*tag*/,
  390.                        CommandType /*command*/,
  391.                        fe_icon */*icon*/)
  392. {
  393. }
  394. //////////////////////////////////////////////////////////////////////////
  395. Widget
  396. XFE_Toolbar::findButton(const char *name,
  397.                         EChromeTag /*tag*/)
  398. {
  399.     WidgetList    children;
  400.     Cardinal    num_children;
  401.     Cardinal    i;
  402.     CommandType cmd = Command::intern((char *) name);
  403.     
  404.     XfeChildrenGet(m_toolBar,&children,&num_children);
  405.  
  406.     for (i = 0; i < num_children; i ++)
  407.     {
  408.         if (XfeIsButton(children[i]))
  409.         {
  410.             XFE_Button * button = 
  411.                 (XFE_Button *) XfeInstancePointer(children[i]);
  412.  
  413.             // First try to match command
  414.             if (button->getCmd() == cmd)
  415.             {
  416.                 return children[i];
  417.             }
  418.             // Then, try to match name
  419.             else if (XP_STRCMP(button->getName(),name) == 0)
  420.             {
  421.                 return children[i];
  422.             }
  423.         }
  424.     }
  425.  
  426.     return NULL;
  427. }
  428. //////////////////////////////////////////////////////////////////////////
  429. void
  430. XFE_Toolbar::hideButton(const char *name,
  431.                         EChromeTag tag)
  432. {
  433.     Widget kid = findButton(name, tag);
  434.  
  435.     if (kid)
  436.         XtUnmanageChild(kid);
  437. }
  438. //////////////////////////////////////////////////////////////////////////
  439. void
  440. XFE_Toolbar::showButton(const char *name,
  441.                         EChromeTag tag)
  442. {
  443.     Widget kid = findButton(name, tag);
  444.  
  445.     if (kid)
  446.         XtManageChild(kid);
  447. }
  448. //////////////////////////////////////////////////////////////////////////
  449. XFE_CALLBACK_DEFN(XFE_Toolbar, doCommand)
  450.     (XFE_NotificationCenter *    /* obj */,
  451.      void *                        /* clientData */,
  452.      void *                        callData)
  453. {
  454.     XFE_DoCommandArgs * cmdArgs = (XFE_DoCommandArgs *) callData;
  455.  
  456.     if (m_parentFrame->handlesCommand(cmdArgs->cmd,
  457.                                       cmdArgs->callData,
  458.                                       cmdArgs->info)
  459.         && m_parentFrame->isCommandEnabled(cmdArgs->cmd,
  460.                                            cmdArgs->callData,
  461.                                            cmdArgs->info))
  462.     {
  463.         xfe_ExecuteCommand(m_parentFrame, cmdArgs->cmd, cmdArgs->callData,
  464.                            cmdArgs->info );
  465.         
  466.         m_parentFrame->notifyInterested(Command::commandDispatchedCallback, 
  467.                                         callData);
  468.       }
  469. }
  470. //////////////////////////////////////////////////////////////////////////
  471. Widget
  472. XFE_Toolbar::getToolBar()
  473. {
  474.     return m_toolBar;
  475. }
  476. //////////////////////////////////////////////////////////////////////////
  477. Widget
  478. XFE_Toolbar::getToolBarForm()
  479. {
  480.     XP_ASSERT( XfeIsAlive(m_toolBar) );
  481.  
  482.     return XtParent(m_toolBar);
  483. }
  484. //////////////////////////////////////////////////////////////////////////
  485. void
  486. XFE_Toolbar::createMain(Widget parent)
  487. {
  488.     XP_ASSERT( XfeIsAlive(parent) );
  489.  
  490.     // Create the base widget - a tool item
  491.     m_widget = XtVaCreateWidget(TOOL_BAR_ITEM_NAME,
  492.                                 xfeToolItemWidgetClass,
  493.                                 parent,
  494.                                 XmNuserData,            this,
  495.                                 NULL);
  496.  
  497.     // Create the tool bar
  498.     m_toolBar = 
  499.         XtVaCreateManagedWidget(TOOL_BAR_NAME,
  500.                                 xfeToolBarWidgetClass,
  501.                                 m_widget,
  502.                                 XmNorientation,            XmHORIZONTAL,
  503.                                 XmNusePreferredHeight,    True,
  504.                                 XmNusePreferredWidth,    False,
  505.                                 NULL);
  506.  
  507.     // Create the logo
  508.     m_logo = new XFE_Logo(m_parentFrame,m_widget,LOGO_NAME);
  509.  
  510.     m_logo->show();
  511.  
  512.     // Update the appearance for the first time
  513.     updateAppearance();
  514.  
  515.     // Configure the logo for the first time
  516.     configureLogo();
  517.  
  518.     installDestroyHandler();
  519. }
  520. //////////////////////////////////////////////////////////////////////////
  521. Widget
  522. XFE_Toolbar::createItem(ToolbarSpec *    spec)
  523. {
  524.     XP_ASSERT( spec != NULL );
  525.     
  526.     switch(spec->tag)
  527.     {
  528.     case PUSHBUTTON:
  529.  
  530.         return createPush(spec);
  531.  
  532.         break;
  533.         
  534.     case DYNA_CASCADEBUTTON:
  535.  
  536.         return createDynamicCascade(spec);
  537.  
  538.         break;
  539.         
  540.     case CASCADEBUTTON:
  541.  
  542.         return createCascade(spec);
  543.  
  544.         break;
  545.         
  546.     case SEPARATOR:
  547.  
  548.         return createSeparator(spec);
  549.  
  550.         break;
  551.         
  552.     default:
  553.         
  554.         XP_ASSERT(0);
  555.     }
  556.  
  557.     return NULL;
  558. }
  559. //////////////////////////////////////////////////////////////////////////
  560. void
  561. XFE_Toolbar::createItems()
  562. {
  563.     ToolbarSpec *    cur_spec;
  564.  
  565.     XP_ASSERT( XfeIsAlive(m_toolBar) );
  566.  
  567.     if (!m_spec)
  568.     {
  569.         return;
  570.     }
  571.  
  572.     cur_spec = m_spec;
  573.  
  574.     // Create toolbar buttons
  575.     while (cur_spec->toolbarButtonName)
  576.     {
  577.         // Create the item only if it is not disabled through resources.
  578.         if (XfeChildIsEnabled(m_toolBar,
  579.                               (String) cur_spec->toolbarButtonName,
  580.                               "UserCommand",
  581.                               True))
  582.         {
  583.             createItem(cur_spec);
  584.         }
  585.  
  586.         cur_spec ++;
  587.     }
  588.  
  589.     // Create user buttons
  590.     user_createItems();
  591. }
  592. //////////////////////////////////////////////////////////////////////////
  593. Widget
  594. XFE_Toolbar::createPush(ToolbarSpec * spec)
  595. {
  596.     XP_ASSERT( spec != NULL );
  597.     XP_ASSERT( spec->tag == PUSHBUTTON );
  598.     XP_ASSERT( XfeIsAlive(m_toolBar) );
  599.  
  600.     // Create a XFE_Button.
  601.     XFE_Button * button = new XFE_Button(m_parentFrame,
  602.                                          m_toolBar,
  603.                                          spec->toolbarButtonName, 
  604.                                          spec->iconGroup,
  605.                                          spec->iconGroup2,
  606.                                          spec->iconGroup3,
  607.                                          spec->iconGroup4);
  608.     // 
  609.     button->setToplevel(m_parentFrame);
  610.  
  611.     Widget result = button->getBaseWidget();
  612.  
  613.     // Show the new push
  614.     button->show();
  615.         
  616.     // [button] --DoCommandCallback--> [toolbar]
  617.     button->registerInterest(XFE_Button::doCommandCallback,
  618.                              this,
  619.                              (XFE_FunctionNotification)doCommand_cb);
  620.     
  621.     if (XP_STRCMP(spec->toolbarButtonName, xfeCmdViewSecurity) == 0) 
  622.     {
  623.         m_security = button;
  624.     }
  625.     
  626.     return result;
  627. }
  628. //////////////////////////////////////////////////////////////////////////
  629. Widget
  630. XFE_Toolbar::createDynamicCascade(ToolbarSpec * spec)
  631. {
  632.     XP_ASSERT( spec != NULL );
  633.     XP_ASSERT( spec->tag == DYNA_CASCADEBUTTON );
  634.     XP_ASSERT( XfeIsAlive(m_toolBar) );
  635.  
  636.     // Create a XFE_Button. (with popups)
  637.     XFE_Button * button = new XFE_Button(m_parentFrame,
  638.                                          m_toolBar,
  639.                                          spec->toolbarButtonName, 
  640.                                          spec->generateProc,
  641.                                          spec->generateArg,
  642.                                          spec->iconGroup);
  643.     
  644.     // Show the new cascade
  645.     button->show();
  646.         
  647.     // [button] --DoCommandCallback--> [toolbar]
  648.     button->registerInterest(XFE_Button::doCommandCallback,
  649.                              this,
  650.                              (XFE_FunctionNotification)doCommand_cb);
  651.  
  652.     // Set the popup delay
  653.     button->setPopupDelay(verifyPopupDelay(spec->popupDelay));
  654.     
  655.     return button->getBaseWidget();
  656. }
  657. //////////////////////////////////////////////////////////////////////////
  658. Widget
  659. XFE_Toolbar::createCascade(ToolbarSpec * spec)
  660. {
  661.     XP_ASSERT( spec != NULL );
  662.     XP_ASSERT( spec->tag == CASCADEBUTTON );
  663.     XP_ASSERT( XfeIsAlive(m_toolBar) );
  664.  
  665.     // Create a XFE_Button. (with popups)
  666.     XFE_Button * button = new XFE_Button(m_parentFrame,
  667.                                          m_toolBar,
  668.                                          spec->toolbarButtonName, 
  669.                                          spec->submenu,
  670.                                          spec->iconGroup);
  671.     
  672.     // Show the new cascade
  673.     button->show();
  674.         
  675.     // [button] --DoCommandCallback--> [toolbar]
  676.     button->registerInterest(XFE_Button::doCommandCallback,
  677.                              this,
  678.                              (XFE_FunctionNotification)doCommand_cb);
  679.  
  680.     // Set the popup delay
  681.     button->setPopupDelay(verifyPopupDelay(spec->popupDelay));
  682.     
  683.     return button->getBaseWidget();
  684. }
  685. //////////////////////////////////////////////////////////////////////////
  686. Widget
  687. XFE_Toolbar::createSeparator(ToolbarSpec * spec)
  688. {
  689.     XP_ASSERT( spec != NULL );
  690.     XP_ASSERT( spec->tag == SEPARATOR );
  691.     XP_ASSERT( XfeIsAlive(m_toolBar) );
  692.  
  693.     Widget separator = XmCreateSeparator(m_toolBar,
  694.                                          (char *) spec->toolbarButtonName,
  695.                                          NULL,0);
  696.  
  697.     XtManageChild(separator);
  698.     
  699.     return separator;
  700. }
  701. //////////////////////////////////////////////////////////////////////////
  702. int
  703. XFE_Toolbar::verifyPopupDelay(int delay)
  704. {
  705.     int result = delay;
  706.  
  707.      if (result < MIN_DELAY)
  708.      {
  709.         result = MIN_DELAY;
  710.      }
  711.      else if (result > MAX_DELAY)
  712.      {
  713.          result = MAX_DELAY;
  714.      }
  715.  
  716.     return result;
  717. }
  718. //////////////////////////////////////////////////////////////////////////
  719. /* static */ unsigned char
  720. XFE_Toolbar::styleToLayout(int32 style)
  721. {
  722.     unsigned char button_layout = XmBUTTON_LABEL_ON_BOTTOM;
  723.  
  724.     switch(style)
  725.     {
  726.     case BROWSER_TOOLBAR_ICONS_AND_TEXT:
  727.  
  728.         button_layout = XmBUTTON_LABEL_ON_BOTTOM;
  729.  
  730.         break;
  731.  
  732.     case BROWSER_TOOLBAR_ICONS_ONLY:
  733.  
  734.         button_layout = XmBUTTON_PIXMAP_ONLY;
  735.  
  736.         break;
  737.  
  738.     case BROWSER_TOOLBAR_TEXT_ONLY:
  739.  
  740.         button_layout = XmBUTTON_LABEL_ONLY;
  741.  
  742.         break;
  743.  
  744.     default:
  745.         
  746.         XP_ASSERT( 0 );
  747.  
  748.         break;
  749.     }
  750.     
  751.     return button_layout;
  752. }
  753. //////////////////////////////////////////////////////////////////////////
  754.  
  755. //////////////////////////////////////////////////////////////////////////
  756. //
  757. // User commands support
  758. //
  759. //////////////////////////////////////////////////////////////////////////
  760. void
  761. XFE_Toolbar::user_createItems()
  762. {
  763.     XP_ASSERT( XfeIsAlive(m_toolBar) );
  764.  
  765.     Cardinal    i = 1;
  766.     XP_Bool        done = False;
  767.  
  768.     // Iterate
  769.     while(!done)
  770.     {
  771.         char userCommandName[32];
  772.  
  773.         // Commands are name userCommand1, userCommand2, userCommand3, etc
  774.         XP_SPRINTF(userCommandName,"userCommand%d",i);
  775.  
  776.         // Attempt to get sub resources for the next user command
  777.         XtGetSubresources(m_toolBar,
  778.                           (XtPointer) this,
  779.                           userCommandName,
  780.                           "UserCommand",
  781.                           m_user_commandResources,
  782.                           XtNumber(m_user_commandResources),
  783.                           NULL,
  784.                           0);
  785.  
  786.         // If no sub resource are found, then we are done adding commands
  787.         done = (!m_user_commandName || 
  788.                 (XP_STRCMP(m_user_commandName,"Error") == 0));
  789.  
  790.         // Verify that the command is valid
  791.         if (!done)
  792.         {
  793.             // Separator
  794.             if ((XP_STRNCASECMP(m_user_commandName,"sep",3) == 0) ||
  795.                 (m_user_commandName[0] == '-') )
  796.             {
  797.                 user_addItem("--",                        // widgetName
  798.                              NULL,                        // cmd
  799.                              SEPARATOR,                    // tag
  800.                              NULL,                        // data
  801.                              False,                        // needToFreeData
  802.                              NULL,                        // ig
  803.                              NULL,                        // subMenuSpec
  804.                              False,                        // needToFreeSpec
  805.                              NULL,                        // generateProc
  806.                              NULL,                        // generateArg
  807.                              XFE_TOOLBAR_DELAY_SHORT);    // popupDelay
  808.             }
  809.             else 
  810.             {
  811.                 MenuSpec *            subMenuSpec = NULL;
  812.                 dynamenuCreateProc    generateProc = NULL;
  813.                 void *                generateArg = NULL;
  814.                 CommandType            cmd;
  815.  
  816.                 // Verify the sub menu spec
  817.                 subMenuSpec = user_verifySubMenu(m_user_commandSubMenu);
  818.  
  819.                 // Verify the command
  820.                 cmd = user_verifyCommand(m_user_commandName,
  821.                                          generateProc,
  822.                                          generateArg);
  823.                 
  824.                 // Add the command if needed
  825.                 if (cmd || subMenuSpec)
  826.                 {
  827.                     XP_Bool                needToFreeData = False;
  828.                     XP_Bool                needToFreeSpec = (subMenuSpec != NULL);
  829.                     void *                data = NULL;
  830.                     IconGroup *            ig = NULL;
  831.                     EChromeTag            tag;
  832.                     EToolbarPopupDelay    popupDelay = XFE_TOOLBAR_DELAY_SHORT;
  833.                     
  834.                     // Adjust the popup delay if the command is valid
  835.                     if (cmd)
  836.                     {
  837.                         popupDelay = XFE_TOOLBAR_DELAY_LONG;
  838.                     }
  839.                     
  840.                     // Verify the command data if needed
  841.                     if (cmd)
  842.                     {
  843.                         data = user_verifyCommandData(cmd,
  844.                                                       m_user_commandData,
  845.                                                       needToFreeData);
  846.                     }
  847.                     
  848.                     // Verify the icon group
  849.                     ig = user_verifyCommandIcon(cmd,m_user_commandIcon);
  850.  
  851.                     // Determine what chrome tag to use
  852.                     if (subMenuSpec != NULL)
  853.                     {
  854.                         tag = CASCADEBUTTON;
  855.                     }
  856.                     else if (generateProc)
  857.                     {
  858.                         tag = DYNA_CASCADEBUTTON;
  859.                     }
  860.                     else
  861.                     {
  862.                         tag = PUSHBUTTON;
  863.                     }
  864.                     
  865. #ifdef DEBUG_ramiro
  866.                     printf("Adding UserCommand(%d,%s,%s,%s,submenu = %s)\n",
  867.                            i,
  868.                            cmd,
  869.                            data ? m_user_commandData : "NULL",
  870.                            m_user_commandIcon ? m_user_commandIcon : cmd,
  871.                            m_user_commandSubMenu ? m_user_commandSubMenu : "NULL");
  872. #endif
  873.                     
  874.                     // Add the command
  875.                     user_addItem(userCommandName,        // widgetName
  876.                                  cmd,                    // cmd
  877.                                  tag,                    // tag
  878.                                  data,                    // data
  879.                                  needToFreeData,        // needToFreeData
  880.                                  ig,                    // ig
  881.                                  subMenuSpec,            // subMenuSpec
  882.                                  needToFreeSpec,        // needToFreeSpec
  883.                                  generateProc,            // generateProc
  884.                                  generateArg,            // generateArg
  885.                                  popupDelay);            // popupDelay
  886.  
  887.                 } // if (cmd || submenu)
  888.             } // else
  889.         } // if (!done)
  890.         
  891.         i++;
  892.         
  893.     } // while(!done)
  894. }
  895. //////////////////////////////////////////////////////////////////////////
  896. CommandType
  897. XFE_Toolbar::user_verifyCommand(String                    commandName,
  898.                                 dynamenuCreateProc &    generateProcOut,
  899.                                 void * &                generateArgOut)
  900. {
  901.     generateProcOut = NULL;
  902.     generateArgOut = NULL;
  903.  
  904.     // Make sure a command name string is given
  905.     if (commandName == NULL)
  906.     {
  907.         return NULL;
  908.     }
  909.  
  910.     // Try to find the command
  911.     CommandType cmd = Command::intern(commandName);
  912.  
  913.     // Replace, swap or massage commands that need extra care
  914.     if (cmd == xfeCmdOpenUrl)
  915.     {
  916.         cmd = xfeCmdOpenTargetUrl;
  917.     }
  918.  
  919.     // Determine if the parent frame handles the command
  920.     if (!m_parentFrame->handlesCommand(cmd))
  921.     {
  922.         return NULL;
  923.     }
  924.  
  925.     // Assign the generation proc and arg for commands that have them
  926.     if (cmd == xfeCmdBack)
  927.     {
  928.         generateProcOut = &XFE_BackForwardMenu::generate;
  929.         generateArgOut = (void *) False;
  930.     }
  931.     else if (cmd == xfeCmdForward)
  932.     {
  933.         generateProcOut = &XFE_BackForwardMenu::generate;
  934.         generateArgOut = (void *) True;
  935.     }
  936.  
  937.     return cmd;
  938. }
  939. //////////////////////////////////////////////////////////////////////////
  940. void *        
  941. XFE_Toolbar::user_verifyCommandData(CommandType     cmd,
  942.                                     String            commandData,
  943.                                     XP_Bool &        needToFreeOut)
  944. {
  945.     // Initialize the return value
  946.     needToFreeOut = False;
  947.  
  948.     // Make sure a command data string is given
  949.     if (commandData == NULL)
  950.     {
  951.         return False;
  952.     }
  953.     
  954.     // xfeCmdOpenTargetUrl
  955.     if (cmd == xfeCmdOpenTargetUrl)
  956.     {
  957.         LO_AnchorData * anchorData = 
  958.             (LO_AnchorData *) XtMalloc(sizeof(LO_AnchorData));
  959.         
  960.         anchorData->anchor = (PA_Block) commandData;
  961.         anchorData->target = (PA_Block) NULL;
  962.  
  963.         // Assign the return values
  964.         needToFreeOut = True;
  965.  
  966.         return (void *) anchorData;
  967.     }
  968.     
  969.     return NULL;
  970. }
  971. //////////////////////////////////////////////////////////////////////////
  972. IconGroup *
  973. XFE_Toolbar::user_verifyCommandIcon(CommandType cmd,String commandIcon)
  974. {
  975.     String iconName = commandIcon;
  976.  
  977.     // Use the command if no icon name is given
  978.     if (iconName == NULL)
  979.     {
  980.         iconName = cmd;
  981.     }
  982.  
  983.     if (iconName == NULL)
  984.     {
  985.         return &TB_Home_group;
  986.     }
  987.  
  988.     return IconGroup_findGroupForName(iconName);
  989. }
  990. //////////////////////////////////////////////////////////////////////////
  991. MenuSpec *    
  992. XFE_Toolbar::user_verifySubMenu(String commandSubMenu)
  993. {
  994.     if (commandSubMenu == NULL)
  995.     {
  996.         return NULL;
  997.     }
  998.  
  999.     // Make a local copy of the submenu string for strtok
  1000.     String        sub_menu_copy = (String) XtNewString(commandSubMenu);
  1001.     String        strptr;
  1002.     String        tokptr;
  1003.     Cardinal    numItems = 0;
  1004.  
  1005.     // First, count the number of valid submenu commands
  1006.     strptr = sub_menu_copy;
  1007.  
  1008.     // Tokenize
  1009.     while( (tokptr = XP_STRTOK(strptr,",")) != NULL )
  1010.     {
  1011.         // Check for separators
  1012.         if ( (XP_STRNCASECMP(tokptr,"sep",3) == 0) || 
  1013.              (tokptr[0] == '-') )
  1014.         {
  1015.             numItems++;
  1016.         }
  1017.         else
  1018.         {
  1019.             CommandType subcmd = Command::intern(tokptr);
  1020.             
  1021.             // Check whether the parent frame handles the command
  1022.             if (m_parentFrame->handlesCommand(subcmd))
  1023.             {
  1024.                 numItems++;
  1025.             }
  1026.         }
  1027.  
  1028.         // Advance to next token
  1029.         strptr = NULL;
  1030.     } // while
  1031.  
  1032.     // Make sure at least 1 valid command is given
  1033.     if (numItems == 0)
  1034.     {
  1035.         XtFree(sub_menu_copy);
  1036.  
  1037.         return NULL;
  1038.     }
  1039.  
  1040.     // Allocate enough space for n MenuSpecs plus 1 NULL terminator
  1041.     MenuSpec *    spec = (MenuSpec *) XtMalloc(sizeof(MenuSpec) * (numItems+1));
  1042.     Cardinal    i = 0;
  1043.  
  1044.     // Replace the local copy since strtok screws it up
  1045.     XP_STRCPY(sub_menu_copy,commandSubMenu);
  1046.     
  1047.     // Add the commands
  1048.     strptr = sub_menu_copy;
  1049.     
  1050.     // Tokenize
  1051.     while( (tokptr = XP_STRTOK(strptr,",")) != NULL )
  1052.     {
  1053.         // Check for separators
  1054.         if ( (XP_STRNCASECMP(tokptr,"sep",3) == 0) ||
  1055.              (tokptr[0] == '-') )
  1056.         {
  1057.             static String static_sep_name = "--";
  1058.  
  1059.             spec[i].menuItemName    = static_sep_name;
  1060.             spec[i].tag                = SEPARATOR;
  1061.  
  1062.             i++;
  1063.         }
  1064.         else
  1065.         {
  1066.             CommandType subcmd = Command::intern(tokptr);
  1067.             
  1068.             // Check whether the parent frame handles the command
  1069.             if (m_parentFrame->handlesCommand(subcmd))
  1070.             {
  1071.                 spec[i].menuItemName    = subcmd;
  1072.                 spec[i].tag                = PUSHBUTTON;
  1073.                 
  1074.                 i++;
  1075.             }
  1076.         }
  1077.  
  1078.         // Advance to next token
  1079.         strptr = NULL;
  1080.     }    
  1081.  
  1082.     // Assign the terminating spec
  1083.     spec[i].menuItemName = NULL;
  1084.  
  1085.     // Free the local copy
  1086.     XtFree(sub_menu_copy);
  1087.  
  1088.     return spec;
  1089. }
  1090. //////////////////////////////////////////////////////////////////////////
  1091. void
  1092. XFE_Toolbar::user_addItem(String                widgetName,
  1093.                           CommandType            cmd,
  1094.                           EChromeTag            tag,
  1095.                           void *                data,
  1096.                           XP_Bool                needToFreeData,
  1097.                           IconGroup *            ig,
  1098.                           MenuSpec *            subMenuSpec,
  1099.                           XP_Bool                needToFreeSpec,
  1100.                           dynamenuCreateProc    generateProc,
  1101.                           void *                generateArg,
  1102.                           EToolbarPopupDelay    popupDelay)
  1103. {
  1104.     XP_ASSERT( XfeIsAlive(m_toolBar) );
  1105.     XP_ASSERT( widgetName != NULL );
  1106.  
  1107.     XFE_Button *    button = NULL;
  1108.     Widget            item = NULL;
  1109.     ToolbarSpec *    spec = (ToolbarSpec *)XtMalloc(sizeof(ToolbarSpec));
  1110.  
  1111.     // Initialize the toolbar spec
  1112.     spec->toolbarButtonName = (char *) XtNewString(widgetName);
  1113.     spec->tag                = tag;
  1114.     spec->iconGroup            = ig;
  1115.     spec->iconGroup2        = NULL;
  1116.     spec->iconGroup3        = NULL;
  1117.     spec->iconGroup4        = NULL;
  1118.     spec->submenu            = subMenuSpec;
  1119.     spec->generateProc        = generateProc;
  1120.     spec->generateArg        = generateArg;
  1121.     spec->popupDelay        = popupDelay;
  1122.             
  1123.     // Create the new user command item
  1124.     item = createItem(spec);
  1125.  
  1126.     // Configure items that are not separators
  1127.     if (tag != SEPARATOR)
  1128.     {
  1129.         // Acces the instance pointer
  1130.         button = (XFE_Button *) XfeInstancePointer(item);
  1131.         
  1132.         // Install the new cmd on the button if needed
  1133.         if (cmd)
  1134.         {
  1135.             button->setCmd(cmd);
  1136.             
  1137.             // Add the command data if needed
  1138.             if (data != NULL)
  1139.             {
  1140.                 button->setCallData(data);
  1141.                 
  1142.                 // Add destroy callback to free data if needed
  1143.                 if (needToFreeData)
  1144.                 {
  1145.                     XtAddCallback(item,
  1146.                                   XmNdestroyCallback,
  1147.                                   user_freeCallDataCB,
  1148.                                   (XtPointer) data);
  1149.                 }
  1150.             }
  1151.         }
  1152.  
  1153.         // Add destroy callback to free menu spec if needed
  1154.         if (needToFreeSpec)
  1155.         {
  1156.             XtAddCallback(item,
  1157.                           XmNdestroyCallback,
  1158.                           user_freeCallDataCB,
  1159.                           (XtPointer) subMenuSpec);
  1160.         }
  1161.     }
  1162.     
  1163.     // Add destroy callback to free all the ToolbarSpec we allocated
  1164.     XtAddCallback(item,
  1165.                   XmNdestroyCallback,
  1166.                   user_commandDestroyCB,
  1167.                   (XtPointer) spec);
  1168. }
  1169. //////////////////////////////////////////////////////////////////////////
  1170. /* static */ void 
  1171. XFE_Toolbar::user_commandDestroyCB(Widget        /* w */,
  1172.                                    XtPointer    clientData,
  1173.                                    XtPointer    /* callData */)
  1174. {
  1175.     ToolbarSpec * spec = (ToolbarSpec *) clientData;
  1176.  
  1177.     XP_ASSERT( spec != NULL );
  1178.  
  1179.     XP_ASSERT( spec->toolbarButtonName != NULL );
  1180.  
  1181.     XtFree((char *) spec->toolbarButtonName);
  1182.  
  1183.     XtFree((char *) spec);
  1184. }
  1185. //////////////////////////////////////////////////////////////////////////
  1186. /* static */ void 
  1187. XFE_Toolbar::user_freeCallDataCB(Widget            /* w */,
  1188.                                  XtPointer        clientData,
  1189.                                  XtPointer        /* callData */)
  1190. {
  1191.     if (clientData)
  1192.     {
  1193.         XtFree((char *) clientData);
  1194.     }
  1195. }
  1196. //////////////////////////////////////////////////////////////////////////
  1197.