home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / EditRecentMenu.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  9.9 KB  |  394 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. #include "EditRecentMenu.h"
  21. #include "MozillaApp.h"
  22. #include "View.h"
  23. #include "EditorFrame.h"
  24. #include "felocale.h"
  25. #include "intl_csi.h"
  26.  
  27. #include <Xm/PushBG.h>
  28. #include <Xm/SeparatoG.h>
  29. #include <Xfe/Cascade.h>
  30.  
  31. #include "edt.h"
  32. #include "xeditor.h"
  33.  
  34. #include "xpgetstr.h"            // for XP_GetString()
  35.  
  36. #define MAX_MENU_ITEM_LENGTH                40
  37. #define MAX_NUM_RECENT_MENU_ITEMS            10
  38.  
  39. extern int XFE_UNTITLED;
  40.  
  41. //////////////////////////////////////////////////////////////////////////
  42. //
  43. // Used to pass data to the callbacks
  44. //
  45. //////////////////////////////////////////////////////////////////////////
  46. typedef struct
  47. {
  48.     XFE_EditRecentMenu *    object;        // Object
  49.     char *                    pUrl;        // the URL...
  50. } _OpenCallbackStruct;
  51. //////////////////////////////////////////////////////////////////////////
  52.  
  53. //////////////////////////////////////////////////////////////////////////
  54. XFE_EditRecentMenu::XFE_EditRecentMenu(XFE_Frame *    frame,
  55.                                        Widget        cascade,
  56.                                        XP_Bool      openPage) :
  57.     _frame(frame),
  58.     _cascade(cascade),
  59.     _openPage(openPage),
  60.     _itemCount(0)
  61. {
  62.     // Obtain the submenu
  63.     XtVaGetValues(_cascade,XmNsubMenuId,&_submenu,NULL);
  64.  
  65.     XP_ASSERT( _submenu != NULL );
  66.  
  67.     XtAddCallback(_cascade,
  68.                   XmNdestroyCallback,
  69.                   &XFE_EditRecentMenu::cascadeDestroyCB,
  70.                   (XtPointer) this);
  71.     
  72.     XtAddCallback(_cascade,
  73.                   XmNcascadingCallback,
  74.                   &XFE_EditRecentMenu::cascadingCB,
  75.                   (XtPointer) this);
  76.  
  77.     // Make the delay large to get the desired "hold" effect
  78.     XtVaSetValues(_cascade,XmNmappingDelay,300,NULL);
  79. }
  80. //////////////////////////////////////////////////////////////////////////
  81. XFE_EditRecentMenu::~XFE_EditRecentMenu()
  82. {
  83. }
  84. //////////////////////////////////////////////////////////////////////////
  85. void
  86. XFE_EditRecentMenu::generate(Widget        cascade,
  87.                              XtPointer    data,
  88.                              XFE_Frame *    frame)
  89. {
  90.     XFE_EditRecentMenu * obj;
  91.  
  92.     obj = new XFE_EditRecentMenu(frame,cascade, (int) data);
  93.  
  94. #ifdef DEBUG_rhess2
  95.     fprintf(stderr, "generate::[ %p ] - [ %p ][ %p ][ %p ]\n", 
  96.             obj, cascade, data, frame);
  97. #endif
  98. }
  99. //////////////////////////////////////////////////////////////////////////
  100. //
  101. // Cascade callbacks
  102. //
  103. //////////////////////////////////////////////////////////////////////////
  104. void
  105. XFE_EditRecentMenu::cascadeDestroyCB(Widget,XtPointer clientData,XtPointer)
  106. {
  107.     XFE_EditRecentMenu * obj = (XFE_EditRecentMenu*)clientData;
  108.     
  109.     XP_ASSERT( obj != NULL );
  110.     
  111.     delete obj;
  112. }
  113. //////////////////////////////////////////////////////////////////////////
  114. void
  115. XFE_EditRecentMenu::cascadingCB(Widget,XtPointer clientData,XtPointer)
  116. {
  117.     XFE_EditRecentMenu *obj = (XFE_EditRecentMenu*)clientData;
  118.  
  119.     XP_ASSERT( obj != NULL );
  120.     
  121.     obj->cascading();
  122. }
  123. //////////////////////////////////////////////////////////////////////////
  124. void
  125. XFE_EditRecentMenu::cascading()
  126. {
  127.     destroyItems();
  128.  
  129.     fillSubmenu();
  130. }
  131. //////////////////////////////////////////////////////////////////////////
  132. void
  133. XFE_EditRecentMenu::destroyItems()
  134. {
  135.     Widget *kids = 0;
  136.     Cardinal nkids = 0;
  137.  
  138.     // XtUnrealizeWidget (_submenu);
  139.  
  140.     XtVaGetValues (_submenu, 
  141.                    XmNchildren, &kids, 
  142.                    XmNnumChildren, &nkids, 
  143.                    0);
  144.  
  145.     if (nkids) {
  146.         //        kids = &(kids[m_firstslot]);
  147.         //        nkids -= m_firstslot;
  148.         
  149.         if (nkids) { 
  150.             XtUnmanageChildren (kids, nkids);
  151.                     
  152.             fe_DestroyWidgetTree(kids, nkids);
  153. #ifdef DEBUG_rhess2
  154.             fprintf(stderr, "destroyItems::[ %d ]\n", nkids);
  155. #endif            
  156.         }
  157.     }
  158.     else {
  159. #ifdef DEBUG_rhess2
  160.         fprintf(stderr, "destroyItems::[ NULL ]\n");
  161. #endif            
  162.     }
  163.  
  164.     _itemCount = 0;
  165. }
  166. //////////////////////////////////////////////////////////////////////////
  167. void
  168. XFE_EditRecentMenu::fillSubmenu()
  169. {
  170.     char * pUrl = NULL;
  171.     int32     i = 0;
  172.  
  173.     XP_ASSERT( _frame != NULL );
  174.  
  175.     MWContext * context = _frame->getContext();
  176.  
  177.     XP_ASSERT( context != NULL );
  178.  
  179.     if (!_frame || !context)
  180.     {
  181.         return;
  182.     }
  183.     
  184.     // XtRealizeWidget (_submenu);
  185.  
  186.     if (_openPage) {
  187.         Widget separator = NULL;
  188.  
  189.         addItem(0, xfeCmdOpenPage, NULL);
  190.  
  191.         separator = XmCreateSeparatorGadget(_submenu, "separator", NULL, 0);
  192.  
  193.         XtVaSetValues(separator, 
  194.                       XmNshadowThickness, 2,
  195.                       NULL);
  196.         XtManageChild(separator);
  197.     }
  198.  
  199.     for( i = 0; i < MAX_NUM_RECENT_MENU_ITEMS; i++ )
  200.     {
  201.         if(EDT_GetEditHistory(context, i, &pUrl, NULL))
  202.         {
  203.             // Condense in case URL is too long for the menu
  204.             // Note: pUrl is static string - don't free it
  205.  
  206.             addItem(i,NULL, pUrl);
  207.             _itemCount++;
  208.         }
  209.     }
  210. #ifdef DEBUG_rhess2
  211.     fprintf(stderr, "fillSubmenu::[ %d ]\n", _itemCount);
  212. #endif            
  213. }
  214. //////////////////////////////////////////////////////////////////////////
  215.  
  216. //////////////////////////////////////////////////////////////////////////
  217. //
  218. // Menu item callbacks
  219. //
  220. //////////////////////////////////////////////////////////////////////////
  221. void
  222. XFE_EditRecentMenu::itemActivateCB(Widget,XtPointer clientData,XtPointer)
  223. {
  224.     _OpenCallbackStruct * data = (_OpenCallbackStruct *) clientData;
  225.  
  226.     XP_ASSERT( data != NULL );
  227.     XP_ASSERT( data->object != NULL );
  228.     
  229.     data->object->itemActivate(data->pUrl);
  230. }
  231. //////////////////////////////////////////////////////////////////////////
  232. void
  233. XFE_EditRecentMenu::itemArmCB(Widget,XtPointer clientData,XtPointer)
  234. {
  235.     _OpenCallbackStruct * data = (_OpenCallbackStruct *) clientData;
  236.  
  237.     XP_ASSERT( data != NULL );
  238.     XP_ASSERT( data->object != NULL );
  239.     
  240.     data->object->itemArm(data->pUrl);
  241. }
  242. //////////////////////////////////////////////////////////////////////////
  243. void
  244. XFE_EditRecentMenu::itemDisarmCB(Widget,XtPointer clientData,XtPointer)
  245. {
  246.     _OpenCallbackStruct * data = (_OpenCallbackStruct *) clientData;
  247.  
  248.     XP_ASSERT( data != NULL );
  249.     XP_ASSERT( data->object != NULL );
  250.     
  251.     data->object->itemDisarm();
  252. }
  253. //////////////////////////////////////////////////////////////////////////
  254. void
  255. XFE_EditRecentMenu::itemDestroyCB(Widget,XtPointer clientData,XtPointer)
  256. {
  257.     _OpenCallbackStruct * data = (_OpenCallbackStruct *) clientData;
  258.  
  259.     XP_ASSERT( data != NULL );
  260.  
  261.     XP_FREE(data);
  262. }
  263. //////////////////////////////////////////////////////////////////////////
  264. void
  265. XFE_EditRecentMenu::itemActivate(char * pUrl)
  266. {
  267.     XP_ASSERT( _frame != NULL );
  268.  
  269.     MWContext *        context = _frame->getContext();
  270.  
  271.     if (pUrl) {
  272.         if (_frame->handlesCommand(xfeCmdEditPage,(void *) pUrl)) {
  273.             if (EDT_IS_NEW_DOCUMENT(context) && !EDT_DirtyFlag(context)) {
  274.                 URL_Struct* url = NET_CreateURLStruct(pUrl, NET_NORMAL_RELOAD);
  275.                 XFE_EditorFrame *theFrame = (XFE_EditorFrame*) _frame;
  276.                 
  277.                 theFrame->getURL(url, FALSE);
  278.             }
  279.             else {
  280.                 fe_EditorEdit(context, _frame, /*chromespec=*/NULL, pUrl);
  281.             }
  282.         }
  283.     }
  284.     else {
  285.         fe_OpenURLDialog(context);
  286.     }
  287. }
  288. //////////////////////////////////////////////////////////////////////////
  289. void
  290. XFE_EditRecentMenu::itemArm(char* /*pUrl*/)
  291. {
  292.     XP_ASSERT( _frame != NULL );
  293.     //
  294.     // d'oh - what's supposed to happen now?...
  295.     //
  296. }
  297. //////////////////////////////////////////////////////////////////////////
  298. void
  299. XFE_EditRecentMenu::itemDisarm()
  300. {
  301.     XP_ASSERT( _frame != NULL );
  302.  
  303.     _frame->notifyInterested(XFE_View::statusNeedsUpdatingMidTruncated,
  304.                              (void*) "");
  305. }
  306. //////////////////////////////////////////////////////////////////////////
  307. void
  308. XFE_EditRecentMenu::addItem(int        position,
  309.                             char *    name,
  310.                             char *    pUrl)
  311. {
  312.     char*  xt_name = NULL;
  313.     char*    title = pUrl;
  314.  
  315.     // Make sure the title is valid
  316.     if (!name && !pUrl)
  317.     {
  318.         return;
  319.     }
  320.  
  321.     if (name) {
  322.         xt_name = name;
  323.     }
  324.     else {
  325.         xt_name = xfeCmdOpenTargetUrl;
  326.     }
  327.  
  328.     _OpenCallbackStruct * data;
  329.  
  330.     // Create a new bookmark data structure for the callbacks
  331.     data = XP_NEW_ZAP(_OpenCallbackStruct);
  332.  
  333.     data->object    = this;
  334.     data->pUrl        = pUrl;
  335.  
  336.     // Create the new item
  337.     Widget item = XtVaCreateManagedWidget(xt_name,
  338.                                           xmPushButtonGadgetClass,
  339.                                           _submenu,
  340.                                           NULL);
  341.     // Add callbacks to item
  342.     XtAddCallback(item,
  343.                   XmNactivateCallback,
  344.                   &XFE_EditRecentMenu::itemActivateCB,
  345.                   (XtPointer) data);
  346.  
  347.     XtAddCallback(item,
  348.                   XmNarmCallback,
  349.                   &XFE_EditRecentMenu::itemArmCB,
  350.                   (XtPointer) data);
  351.  
  352.     XtAddCallback(item,
  353.                   XmNdisarmCallback,
  354.                   &XFE_EditRecentMenu::itemDisarmCB,
  355.                   (XtPointer) data);
  356.  
  357.     if (title) {
  358.         // Format the title
  359.         char * buffer = PR_smprintf("%2d  %s",position + 1,title);
  360.  
  361.         XP_ASSERT( buffer != NULL );
  362.  
  363.         // Truncate the title and install it on the item
  364.         if (buffer)    {
  365.             MWContext *            context = _frame->getContext();
  366.             INTL_CharSetInfo    c = LO_GetDocumentCharacterSetInfo(context);
  367.             XmFontList            font_list;
  368.             
  369.             INTL_MidTruncateString(INTL_GetCSIWinCSID(c), 
  370.                                    buffer, 
  371.                                    buffer,
  372.                                    MAX_MENU_ITEM_LENGTH);
  373.             
  374.             
  375.             XmString label = fe_ConvertToXmString((unsigned char *) buffer,
  376.                                                   INTL_GetCSIWinCSID(c), 
  377.                                                   NULL, 
  378.                                                   XmFONT_IS_FONT,
  379.                                                   &font_list);
  380.             
  381.             if (label)
  382.                 {
  383.                     XtVaSetValues(item,XmNlabelString,label,NULL);
  384.                     
  385.                     XmStringFree(label);
  386.                 }
  387.             
  388.             // Free the allocated memory
  389.             XP_FREE(buffer);
  390.         }
  391.     }
  392. }
  393. //////////////////////////////////////////////////////////////////////////
  394.