home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / BackForwardMenu.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  9.8 KB  |  376 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. /*                                                                        */
  20. /* Name:        FrameListMenu.cpp                                        */
  21. /* Description:    XFE_FrameListMenu component implementation.                */
  22. /*                These are the menu items that appear at the end of the    */
  23. /*                                                                        */
  24. /* Author:        Ramiro Estrugo <ramiro@netscape.com>                    */
  25.  
  26.  
  27. /* Date:        Sun Mar  2 01:34:13 PST 1997                            */
  28. /*                                                                        */
  29. /*----------------------------------------------------------------------*/
  30.  
  31. #include "BackForwardMenu.h"
  32. #include "MozillaApp.h"
  33. #include "View.h"
  34. #include "Frame.h"
  35. #include "felocale.h"
  36. #include "intl_csi.h"
  37.  
  38. #include <Xm/PushBG.h>
  39. #include <Xfe/Cascade.h>
  40.  
  41. #include "xpgetstr.h"            // for XP_GetString()
  42.  
  43. #define MAX_MENU_ITEM_LENGTH                40
  44. #define MAX_NUM_HISTORY_MENU_ITEMS            15
  45.  
  46. extern int XFE_UNTITLED;
  47.  
  48. //////////////////////////////////////////////////////////////////////////
  49. //
  50. // Used to pass data to the callbacks
  51. //
  52. //////////////////////////////////////////////////////////////////////////
  53. typedef struct
  54. {
  55.     XFE_BackForwardMenu *    object;        // Object
  56.     History_entry *            entry;        // History entry
  57. } _HistoryCallbackStruct;
  58. //////////////////////////////////////////////////////////////////////////
  59.  
  60. //////////////////////////////////////////////////////////////////////////
  61. XFE_BackForwardMenu::XFE_BackForwardMenu(XFE_Frame *    frame,
  62.                                          Widget            cascade,
  63.                                          int            forward) :
  64.     _frame(frame),
  65.     _cascade(cascade),
  66.     _forward(forward)
  67. {
  68.     // Obtain the submenu
  69.     XtVaGetValues(_cascade,XmNsubMenuId,&_submenu,NULL);
  70.  
  71.     XP_ASSERT( _submenu != NULL );
  72.     XP_ASSERT( XfeIsCascade(_cascade) );
  73.  
  74.     XtAddCallback(_cascade,
  75.                   XmNdestroyCallback,
  76.                   &XFE_BackForwardMenu::cascadeDestroyCB,
  77.                   (XtPointer) this);
  78.     
  79.     XtAddCallback(_cascade,
  80.                   XmNcascadingCallback,
  81.                   &XFE_BackForwardMenu::cascadingCB,
  82.                   (XtPointer) this);
  83.  
  84.     // Make the delay large to get the desired "hold" effect
  85.     XtVaSetValues(_cascade,XmNmappingDelay,300,NULL);
  86. }
  87. //////////////////////////////////////////////////////////////////////////
  88. XFE_BackForwardMenu::~XFE_BackForwardMenu()
  89. {
  90. }
  91. //////////////////////////////////////////////////////////////////////////
  92. void
  93. XFE_BackForwardMenu::generate(Widget        cascade,
  94.                               XtPointer        data,
  95.                               XFE_Frame *    frame)
  96. {
  97.     XFE_BackForwardMenu * obj;
  98.     
  99.     obj = new XFE_BackForwardMenu(frame,cascade,(int) data);
  100. }
  101. //////////////////////////////////////////////////////////////////////////
  102.  
  103. //////////////////////////////////////////////////////////////////////////
  104. //
  105. // Cascade callbacks
  106. //
  107. //////////////////////////////////////////////////////////////////////////
  108. void
  109. XFE_BackForwardMenu::cascadeDestroyCB(Widget,XtPointer clientData,XtPointer)
  110. {
  111.     XFE_BackForwardMenu * obj = (XFE_BackForwardMenu*)clientData;
  112.     
  113.     XP_ASSERT( obj != NULL );
  114.     
  115.     delete obj;
  116. }
  117. //////////////////////////////////////////////////////////////////////////
  118. void
  119. XFE_BackForwardMenu::cascadingCB(Widget,XtPointer clientData,XtPointer)
  120. {
  121.     XFE_BackForwardMenu *obj = (XFE_BackForwardMenu*)clientData;
  122.  
  123.     XP_ASSERT( obj != NULL );
  124.     
  125.     obj->cascading();
  126. }
  127. //////////////////////////////////////////////////////////////////////////
  128. void
  129. XFE_BackForwardMenu::cascading()
  130. {
  131.     destroyItems();
  132.  
  133.     fillSubmenu(_forward);
  134. }
  135. //////////////////////////////////////////////////////////////////////////
  136. void
  137. XFE_BackForwardMenu::destroyItems()
  138. {
  139.     XP_ASSERT( XfeIsAlive(_cascade) );
  140.  
  141.     XfeCascadeDestroyChildren(_cascade);
  142. }
  143. //////////////////////////////////////////////////////////////////////////
  144. void
  145. XFE_BackForwardMenu::addItems(XP_List *            list,
  146.                               XP_Bool            forward)
  147. {
  148.     int num_items = 0;
  149.  
  150.     while(list)
  151.     {
  152.         History_entry *  entry = (History_entry *) list->object;
  153.  
  154.         XP_ASSERT( entry != NULL );
  155.  
  156.         if (entry && (num_items < MAX_NUM_HISTORY_MENU_ITEMS))
  157.         {
  158.             addItem(num_items++,entry);
  159.         }
  160.     
  161.         if(forward)
  162.         {
  163.             list = list->next;
  164.         }
  165.         else
  166.         {
  167.             list = list->prev;
  168.         }
  169.     }
  170. }
  171. //////////////////////////////////////////////////////////////////////////
  172. void
  173. XFE_BackForwardMenu::fillSubmenu(XP_Bool forward)
  174. {
  175.     XP_ASSERT( _frame != NULL );
  176.  
  177.     MWContext * context = _frame->getContext();
  178.  
  179.     XP_ASSERT( context != NULL );
  180.  
  181.     if (!_frame || !context)
  182.     {
  183.         return;
  184.     }
  185.     
  186.     // Get the session history list
  187.     XP_List* list = SHIST_GetList(context);
  188.  
  189.     // Get the pointer to the current history entry
  190.     History_entry * current_entry = context->hist.cur_doc_ptr;
  191.     
  192.     XP_List * current_node = XP_ListFindObject(list, current_entry);
  193.  
  194.     XP_ASSERT( list != NULL );
  195.  
  196.     // Make sure the history list is valid
  197.     if (!list)
  198.     {
  199.         return;
  200.     }
  201.     
  202.     list = list->prev;
  203.  
  204.     if (forward)
  205.     {
  206.         addItems(current_node->next,True);
  207.     }
  208.     else
  209.     {
  210.         addItems(current_node->prev,False);
  211.     }
  212. }
  213. //////////////////////////////////////////////////////////////////////////
  214.  
  215. //////////////////////////////////////////////////////////////////////////
  216. //
  217. // Menu item callbacks
  218. //
  219. //////////////////////////////////////////////////////////////////////////
  220. void
  221. XFE_BackForwardMenu::itemActivateCB(Widget,XtPointer clientData,XtPointer)
  222. {
  223.     _HistoryCallbackStruct * data = (_HistoryCallbackStruct *) clientData;
  224.  
  225.     XP_ASSERT( data != NULL );
  226.     XP_ASSERT( data->object != NULL );
  227.     
  228.     data->object->itemActivate(data->entry);
  229. }
  230. //////////////////////////////////////////////////////////////////////////
  231. void
  232. XFE_BackForwardMenu::itemArmCB(Widget,XtPointer clientData,XtPointer)
  233. {
  234.     _HistoryCallbackStruct * data = (_HistoryCallbackStruct *) clientData;
  235.  
  236.     XP_ASSERT( data != NULL );
  237.     XP_ASSERT( data->object != NULL );
  238.     
  239.     data->object->itemArm(data->entry);
  240. }
  241. //////////////////////////////////////////////////////////////////////////
  242. void
  243. XFE_BackForwardMenu::itemDisarmCB(Widget,XtPointer clientData,XtPointer)
  244. {
  245.     _HistoryCallbackStruct * data = (_HistoryCallbackStruct *) clientData;
  246.  
  247.     XP_ASSERT( data != NULL );
  248.     XP_ASSERT( data->object != NULL );
  249.     
  250.     data->object->itemDisarm();
  251. }
  252. //////////////////////////////////////////////////////////////////////////
  253. void
  254. XFE_BackForwardMenu::itemDestroyCB(Widget,XtPointer clientData,XtPointer)
  255. {
  256.     _HistoryCallbackStruct * data = (_HistoryCallbackStruct *) clientData;
  257.  
  258.     XP_ASSERT( data != NULL );
  259.  
  260.     XP_FREE(data);
  261. }
  262. //////////////////////////////////////////////////////////////////////////
  263. void
  264. XFE_BackForwardMenu::itemActivate(History_entry * entry)
  265. {
  266.     XP_ASSERT( _frame != NULL );
  267.  
  268.     MWContext *        context = _frame->getContext();
  269.     URL_Struct *    url;
  270.  
  271.     url = SHIST_CreateURLStructFromHistoryEntry(context,entry);
  272.  
  273.     if (_frame->handlesCommand(xfeCmdOpenUrl,(void *) url))
  274.     {
  275.         _frame->doCommand(xfeCmdOpenUrl,(void *) url);
  276.     }
  277. }
  278. //////////////////////////////////////////////////////////////////////////
  279. void
  280. XFE_BackForwardMenu::itemArm(History_entry * entry)
  281. {
  282.     XP_ASSERT( _frame != NULL );
  283.  
  284.     _frame->notifyInterested(XFE_View::statusNeedsUpdatingMidTruncated,
  285.                              (void*) entry->address);
  286. }
  287. //////////////////////////////////////////////////////////////////////////
  288. void
  289. XFE_BackForwardMenu::itemDisarm()
  290. {
  291.     XP_ASSERT( _frame != NULL );
  292.  
  293.     _frame->notifyInterested(XFE_View::statusNeedsUpdatingMidTruncated,
  294.                              (void*) "");
  295. }
  296. //////////////////////////////////////////////////////////////////////////
  297. void
  298. XFE_BackForwardMenu::addItem(int                position,
  299.                              History_entry *    entry)
  300. {
  301.     XP_ASSERT( entry != NULL );
  302.  
  303.     // Make sure the title is valid
  304.     if (!entry)
  305.     {
  306.         return;
  307.     }
  308.  
  309.     char * title = entry->title ? entry->title : XP_GetString(XFE_UNTITLED);
  310.  
  311.     _HistoryCallbackStruct * data;
  312.  
  313.     // Create a new bookmark data structure for the callbacks
  314.     data = XP_NEW_ZAP(_HistoryCallbackStruct);
  315.  
  316.     data->object    = this;
  317.     data->entry        = entry;
  318.  
  319.     // Create the new item
  320.     Widget item = XtVaCreateManagedWidget(xfeCmdOpenTargetUrl,
  321.                                           xmPushButtonGadgetClass,
  322.                                           _submenu,
  323.                                           NULL);
  324.     // Add callbacks to item
  325.     XtAddCallback(item,
  326.                   XmNactivateCallback,
  327.                   &XFE_BackForwardMenu::itemActivateCB,
  328.                   (XtPointer) data);
  329.  
  330.     XtAddCallback(item,
  331.                   XmNarmCallback,
  332.                   &XFE_BackForwardMenu::itemArmCB,
  333.                   (XtPointer) data);
  334.  
  335.     XtAddCallback(item,
  336.                   XmNdisarmCallback,
  337.                   &XFE_BackForwardMenu::itemDisarmCB,
  338.                   (XtPointer) data);
  339.  
  340.     // Format the title
  341.     char * buffer = PR_smprintf("%2d  %s",position + 1,title);
  342.  
  343.     XP_ASSERT( buffer != NULL );
  344.  
  345.     // Truncate the title and install it on the item
  346.     if (buffer)
  347.     {
  348.         MWContext *            context = _frame->getContext();
  349.         INTL_CharSetInfo    c = LO_GetDocumentCharacterSetInfo(context);
  350.         XmFontList            font_list;
  351.         
  352.         INTL_MidTruncateString(INTL_GetCSIWinCSID(c), 
  353.                                buffer, 
  354.                                buffer,
  355.                                MAX_MENU_ITEM_LENGTH);
  356.  
  357.         
  358.         XmString label = fe_ConvertToXmString((unsigned char *) buffer,
  359.                                               INTL_GetCSIWinCSID(c), 
  360.                                               NULL, 
  361.                                               XmFONT_IS_FONT,
  362.                                               &font_list);
  363.  
  364.         if (label)
  365.         {
  366.             XtVaSetValues(item,XmNlabelString,label,NULL);
  367.             
  368.             XmStringFree(label);
  369.         }
  370.  
  371.         // Free the allocated memory
  372.         XP_FREE(buffer);
  373.     }
  374. }
  375. //////////////////////////////////////////////////////////////////////////
  376.