home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / TreeView.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  11.0 KB  |  513 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.    TreeView.cpp -- class definition for TreeView
  20.    Created: spence murray <spence@netscape.com>, 3-Nov-97.
  21.  */
  22.  
  23.  
  24.  
  25. #include "TreeView.h"
  26. #include "Outlinable.h"
  27. #include "BookmarkView.h"
  28. #include "AddrBookView.h"
  29. #include "HistoryView.h"
  30. #include "ViewGlue.h"
  31. #include "Frame.h"
  32. #include "mozilla.h"
  33.  
  34. #define TREE_OUTLINER_GEOMETRY_PREF "tree.outliner_geometry"
  35.  
  36. extern "C" MWContext *fe_WidgetToMWContext (Widget);
  37.  
  38. // Sanity check on the context.  Throughout the progress stuff below,
  39. // the context (and fe_data) needs to be checked for validity before
  40. // dereferencing the members.
  41. #define CHECK_CONTEXT_AND_DATA(c) \
  42. ((c) && CONTEXT_DATA(c) && !CONTEXT_DATA(context)->being_destroyed)
  43.  
  44. static XFE_Frame * 
  45. fe_frameFromMWContext(MWContext *context)
  46. {
  47.     XFE_Frame * frame = NULL;
  48.  
  49.     // Sanity check for possible invocation of this function from a frame
  50.     // that was just destroyed (or is being destroyed)
  51.     if (!CHECK_CONTEXT_AND_DATA(context))
  52.     {
  53.         return NULL;
  54.     }
  55.  
  56.     // Try to use context's frame
  57.     frame = ViewGlue_getFrame(XP_GetNonGridContext(context));
  58.     
  59.     // Try to use the active frame
  60. //     if (!frame)
  61. //     {
  62. //          frame = XFE_Frame::getActiveFrame();
  63. //     }
  64.  
  65.     // Make sure the frame is alive
  66.     if (frame && !frame->isAlive())
  67.     {
  68.         frame = NULL;
  69.     }
  70.  
  71.     return frame;
  72. }
  73.  
  74. XFE_TreeView::XFE_TreeView (const char *name,
  75.                             Widget parent, 
  76.                             int tree_type,
  77.                             int width,
  78.                             int height)
  79. {
  80. #ifdef DEBUG_spence
  81.     printf ("XFE_TreeView: %s\n", name);
  82. #endif
  83.  
  84.     // get the toplevel
  85.     MWContext *context = fe_WidgetToMWContext (parent);
  86.     XFE_Component *toplevel = fe_frameFromMWContext (context);
  87.         
  88.     /* empty tree */
  89.     if (tree_type == 0)
  90.     {
  91.         int i, n, size;
  92.         XmLTreeRowDefinition *rows;
  93.         static struct
  94.         {
  95.             Boolean expands;
  96.             int level;
  97.             char *string;
  98.         } data[] =
  99.           {
  100.               { True,  0, "Root" },
  101.               { True,  1, "Level 1 Parent" },
  102.               { False, 2, "1st Child of Level 1 Parent" },
  103.               { False, 2, "2nd Child of Level 1 Parent" },
  104.               { True,  2, "Level 2 Parent" },
  105.               { False, 3, "Child of Level 2 Parent" },
  106.               { True,  1, "Level 1 Parent" },
  107.               { False, 2, "Child of Level 1 Parent" },
  108.     };
  109.  
  110. #ifdef DEBUG_spence
  111.         printf ("empty tree\n");
  112. #endif
  113.  
  114.         // create the tree
  115.     m_tree = XtVaCreateManagedWidget("tree",
  116.         xmlTreeWidgetClass, parent,
  117.         XmNvisibleRows, 10,
  118.         NULL);
  119.     XtVaSetValues(m_tree,
  120.         XmNcellDefaults, True,
  121.         NULL);
  122.  
  123.     /* Create a TreeRowDefinition array from the data array */
  124.     /* and add rows to the Tree */
  125.     n = 8;
  126.     size = sizeof(XmLTreeRowDefinition) * n;
  127.     rows = (XmLTreeRowDefinition *)malloc(size);
  128.     for (i = 0; i < n; i++)
  129.     {
  130.         rows[i].level = data[i].level;
  131.         rows[i].expands = data[i].expands;
  132.         rows[i].isExpanded = True;
  133.         rows[i].pixmap = XmUNSPECIFIED_PIXMAP;
  134.         rows[i].pixmask = XmUNSPECIFIED_PIXMAP;
  135.         rows[i].string = XmStringCreateSimple(data[i].string);
  136.     }
  137.     XmLTreeAddRows(m_tree, rows, n, -1);
  138.  
  139.     /* Free the TreeRowDefintion array (and XmStrings) we created above */
  140.     for (i = 0; i < n; i++)
  141.         XmStringFree(rows[i].string);
  142.     free((char *)rows);
  143.  
  144. #if 0
  145.     // Save vertical scroller for keyboard accelerators
  146.     CONTEXT_DATA(context)->vscroll = m_outliner->getScroller();
  147.     m_outliner->show();
  148. #endif
  149.  
  150. #ifdef DEBUG_spence
  151.     printf ("width = %d, height = %d\n", width, height);
  152. #endif
  153.  
  154.     XtVaSetValues (m_tree, XmNwidth, width, XmNheight, height, NULL);
  155.  
  156.     // load rdf database
  157.     getRDFDB();
  158.  
  159.     } else if (tree_type == 1) {
  160. #ifdef DEBUG_spence
  161.         printf ("bookmark tree\n");
  162. #endif
  163.         // bookmark tree
  164.         // create the bookmark view
  165.         XFE_BookmarkView *view = new XFE_BookmarkView(toplevel, 
  166.                                                       parent, 
  167.                                                       NULL, 
  168.                                                       context);
  169.  
  170.         XtVaSetValues(view->getBaseWidget(),
  171.           XmNleftAttachment, XmATTACH_FORM,
  172.         XmNtopAttachment, XmATTACH_FORM,
  173.         XmNrightAttachment, XmATTACH_FORM,
  174.         XmNbottomAttachment, XmATTACH_FORM,
  175.         NULL);
  176.  
  177.         view->show ();
  178.         m_outliner = view->getOutliner ();
  179.     } else if (tree_type == 2) {
  180. #ifdef DEBUG_spence
  181.         printf ("addressbook tree\n");
  182. #endif
  183.         // create the addressbook view; 
  184.         // import from XFE_BookmarkFrame::XFE_BookmarkFrame
  185.         XFE_AddrBookView *view = new XFE_AddrBookView(toplevel, 
  186.                                                       parent,
  187.                                                       NULL,
  188.                                                       context);
  189.     } else if (tree_type == 3) {
  190. #ifdef DEBUG_spence
  191.         printf ("history tree\n");
  192. #endif
  193.         // create the History view
  194.         XFE_HistoryView *view = new XFE_HistoryView(toplevel, parent, NULL, context);
  195.     }
  196.  
  197.     if (m_tree == NULL && m_outliner == NULL)
  198.     {
  199. #ifdef DEBUG_spence
  200.         printf ("XFE_TreeView: outliner create failed!\n");
  201. #endif
  202.         return;
  203.     }
  204. }
  205.  
  206. XFE_TreeView::~XFE_TreeView()
  207. {
  208.     /* nothing to do here */
  209. }
  210.  
  211. void
  212. XFE_TreeView::getRDFDB()
  213. {
  214.     HT_Notification ns;
  215.     RDF_Resources std;
  216.  
  217. #ifdef DEBUG_spence
  218.     printf ("getRDFDB:\n");
  219. #endif
  220.  
  221. #if 0
  222.     ns = (HT_Notification) XP_ALLOC (sizeof (HT_NotificationStruct));
  223.     if (ns == NULL)
  224.     {
  225.         printf ("couldn't allocate NotificationStruct\n");
  226.         return;
  227.     }
  228. #endif
  229.  
  230.     ns = new HT_NotificationStruct;
  231.     ns->notifyProc = (HT_NotificationProc) xfe_handleRDFNotify;
  232.     ns->data = this;
  233.  
  234. #if 0
  235.     std = RDF_StdVocab();
  236. #endif
  237.  
  238.     // now create the HT_View - the backend representation of our tree
  239.     m_htPane = HT_NewPane (ns);
  240.     m_htView = HT_GetNthView (m_htPane, 0);
  241.     // m_htView = HT_NewView (std->RDF_Top, m_htPane);
  242.  
  243.     // now populate the tree
  244.     drawTree ();
  245. }
  246.  
  247. void 
  248. XFE_TreeView::handleRDFNotify (HT_Notification ns, 
  249.                                HT_Resource node,
  250.                                HT_Event event)
  251. {
  252. #ifdef DEBUG_spence
  253.     printf ("handleRDFNotify\n");
  254. #endif
  255. }
  256.  
  257.  
  258. void
  259. XFE_TreeView::drawTree ()
  260. {
  261.     HT_Pane      pane;
  262.     // fe_Data      *feData = (fe_Data *) HT_GetViewFEData (m_htView);
  263.     int          count = HT_GetItemListCount (m_htView);
  264.     int          n = 0;
  265.  
  266. #ifdef DEBUG_spence
  267.     printf ("drawTree\n");
  268. #endif
  269.  
  270.     while (n < count) {
  271.         HT_Resource node = HT_GetNthItem (m_htView, n);
  272.         // add element to tree widget
  273.         drawNode (node);
  274.         ++n;
  275.     }
  276. }
  277.  
  278. void
  279. XFE_TreeView::drawNode (HT_Resource node)
  280. {
  281.     HT_Cursor cursor;
  282.     PRBool isContainer, isOpen, isSelected;
  283.     uint16            colNum, depth;
  284.     uint32            colWidth, colTokenType;
  285.     void *data, *colToken;
  286.     struct tm *time;
  287.     time_t dateVal;
  288.     char buffer [128];
  289.  
  290.     if (isContainer = HT_IsContainer(node))
  291.     {
  292.         isOpen = HT_IsContainerOpen(node);
  293.         // draw the node
  294. #ifdef DEBUG_spence
  295.         printf ("node draw\n");
  296. #endif
  297.     }
  298.  
  299.     if ((cursor = HT_NewColumnCursor(HT_GetView(node))) == NULL) {
  300.         return;
  301.     }
  302.  
  303.     isSelected = HT_IsSelected(node);
  304.  
  305.     colNum = 0;
  306.     while (HT_GetNextColumn(cursor, NULL, &colWidth, &colToken, &colTokenType) == TRUE)
  307.     {
  308.         if (HT_GetNodeData(node, colToken, colTokenType, &data) == TRUE)
  309.         {
  310.             switch(colTokenType)
  311.             {
  312.             case    HT_COLUMN_DATE_STRING:
  313.                 if (data == NULL)    break;
  314.                 if ((dateVal = (time_t)atol((char *)data)) == 0)    break;
  315.                 if ((time = localtime(&dateVal)) == NULL)    break;
  316.  
  317.                 strftime(buffer,sizeof(buffer),"%#m/%#d/%Y %#I:%M %p",time);
  318. #ifdef DEBUG_spence
  319.                 printf ("node: %s\n", buffer);
  320. #endif
  321.             break;
  322.  
  323.             case    HT_COLUMN_DATE_INT:
  324.                 if (data == 0L)    break;
  325.                 if ((time = localtime((time_t *) &data)) == NULL)    break;
  326.  
  327.                 strftime(buffer,sizeof(buffer),"%#m/%#d/%Y %#I:%M %p",time);
  328. #ifdef DEBUG_spence
  329.                 printf ("node: %s\n", buffer);
  330. #endif
  331.             break;
  332.  
  333.             case    HT_COLUMN_INT:
  334.                 sprintf(buffer,"%d",(int)data);
  335. #ifdef DEBUG_spence
  336.                 printf ("node: %s\n", buffer);
  337. #endif
  338.             break;
  339.  
  340.             case    HT_COLUMN_STRING:
  341.                 if (data == NULL)    break;
  342.                 if (colNum==0)
  343.                 {
  344.                     depth = HT_GetItemIndentation(node) - 1;
  345. #ifdef DEBUG_spence
  346.                     printf ("node: %s\n", (char *)data);
  347. #endif
  348.                 }
  349.                 else
  350.                 {
  351. #ifdef DEBUG_spence
  352.                     printf ("node: %s\n", (char *)data);
  353. #endif
  354.                 }
  355.             break;
  356.             }
  357.         }
  358.         if (isContainer)    break;
  359.     }
  360.     HT_DeleteColumnCursor(cursor);
  361. }
  362.  
  363.  
  364. // Outlinable interface methods
  365. void *
  366. XFE_TreeView::ConvFromIndex (int /* index */)
  367. {
  368.     return NULL;
  369. }
  370.  
  371. int
  372. XFE_TreeView::ConvToIndex (void * /* item */)
  373. {
  374.     return 0;
  375. }
  376.  
  377. char *
  378. XFE_TreeView::getColumnName (int /* column */)
  379. {
  380.     return NULL;
  381. }
  382.  
  383. char *
  384. XFE_TreeView::getColumnHeaderText (int /* column */)
  385. {
  386.     return NULL;
  387. }
  388.  
  389. fe_icon *
  390. XFE_TreeView::getColumnHeaderIcon (int /* column */)
  391. {
  392.     return NULL;
  393. }
  394.  
  395. EOutlinerTextStyle
  396. XFE_TreeView::getColumnHeaderStyle (int /* column */)
  397. {
  398.     return (EOutlinerTextStyle) NULL;
  399. }
  400.  
  401. void *
  402. XFE_TreeView::acquireLineData (int /* line */)
  403. {
  404.     return NULL;
  405. }
  406.  
  407. void
  408. XFE_TreeView::getTreeInfo (XP_Bool * /* expandable */, XP_Bool * /* is_expanded */,
  409.              int * /* depth */, OutlinerAncestorInfo ** /* ancestor */)
  410. {
  411. }
  412.  
  413. EOutlinerTextStyle
  414. XFE_TreeView::getColumnStyle (int /* column */)
  415. {
  416.     return (EOutlinerTextStyle) NULL;
  417. }
  418.  
  419. char *
  420. XFE_TreeView::getColumnText (int /* column */)
  421. {
  422.     return NULL;
  423. }
  424.  
  425. fe_icon *
  426. XFE_TreeView::getColumnIcon (int /* column */)
  427. {
  428.     return NULL;
  429. }
  430.  
  431. void
  432. XFE_TreeView::releaseLineData()
  433. {
  434. }
  435.  
  436. void
  437. XFE_TreeView::Buttonfunc (const OutlineButtonFuncData * /* data */)
  438. {
  439. }
  440.  
  441. void
  442. XFE_TreeView::Flippyfunc (const OutlineFlippyFuncData * /* data */)
  443. {
  444. }
  445.  
  446. XFE_Outliner *
  447. XFE_TreeView::getOutliner()
  448. {
  449.     return m_outliner;
  450. }
  451.  
  452. char *
  453. XFE_TreeView::getCellTipString (int /* row */, int /* column */)
  454. {
  455.     return NULL;
  456. }
  457.  
  458. char *
  459. XFE_TreeView::getCellDocString (int /* row */, int /* column */)
  460. {
  461.     return NULL;
  462. }
  463.  
  464.  
  465. extern "C" void
  466. fe_showTreeView (Widget parent, int tree_type, int width, int height)
  467. {
  468.     static XP_Bool been_here = FALSE;
  469.  
  470. #ifdef DEBUG_spence
  471.     printf ("XFE_TreeView: showTreeView()\n");
  472. #endif
  473.  
  474.     if (!been_here) {
  475. #ifdef DEBUG_spence
  476.         printf ("RDF_Init()\n");
  477. #endif
  478.         RDF_Init("file://./"); // assume it hasn't been initialized yet
  479.         been_here = TRUE;
  480.     }
  481.  
  482.     XFE_TreeView *tree = new XFE_TreeView ("tree", 
  483.                                            parent,
  484.                                            tree_type,
  485.                                            width,
  486.                                            height);
  487.  
  488.     XtRealizeWidget (parent);
  489.  
  490. #ifdef DEBUG_spence
  491.     if (tree == NULL)
  492.     {
  493.         printf ("fe_showTreeView: create failed!\n");
  494.         return;
  495.     }
  496. #endif
  497.  
  498. }
  499.  
  500. extern "C" void 
  501. xfe_handleRDFNotify (HT_Notification ns, 
  502.                      HT_Resource node,
  503.                      HT_Event event)
  504. {
  505. #ifdef DEBUG_spence
  506.     printf ("handleRDFNotify\n");
  507. #endif
  508.  
  509.     XFE_TreeView *tree = (XFE_TreeView *) ns->data;
  510.     tree->handleRDFNotify (ns, node, event);
  511. }
  512.  
  513.