home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / modules / rdf / src / ht.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  147.6 KB  |  7,021 lines

  1. /* -*- Mode: C; tab-width: 8; 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.    This file implements the Hypertree model on top of the RDF graph model.
  21.    For more information on this file, contact rjc or guha 
  22.    For more information on RDF, look at the RDF section of www.mozilla.org
  23. */
  24.  
  25. #include "fs2rdf.h"
  26. #include "glue.h"
  27. #include "hist2rdf.h"
  28. #include "ht.h"
  29. #include "scook.h"
  30. #include "rdfparse.h"
  31.  
  32.  
  33.     /* globals */
  34. HT_Icon            urlList = NULL;
  35. HT_PaneStruct        *gHTTop = NULL;
  36. RDF            gNCDB = NULL;
  37. PRBool            gInited = PR_FALSE;
  38. PRBool            gBatchUpdate = false, gAutoEditNewNode = false, gPaneDeletionMode = false;
  39. XP_Bool            gMissionControlEnabled = false;
  40. HT_MenuCommand        menuCommandsList = NULL;
  41. _htmlElementPtr         htmlElementList = NULL;
  42.  
  43.  
  44.     /* extern declarations */
  45. extern RDFT        gRemoteStore;
  46. extern char        *gRLForbiddenDomains;
  47.  
  48. void            FE_Print(const char *pUrl);    /* XXX this should be added to fe_proto.h */
  49.  
  50.  
  51.  
  52. void
  53. HT_Startup()
  54. {
  55.     if (gInited == PR_FALSE)
  56.     {
  57.         gInited = PR_TRUE;
  58.         gMissionControlEnabled = false;
  59.         PREF_GetBoolPref(MISSION_CONTROL_RDF_PREF, &gMissionControlEnabled);
  60.     }
  61. }
  62.  
  63.  
  64.  
  65. void
  66. HT_Shutdown()
  67. {
  68.     freeMenuCommandList();
  69.     gInited = PR_FALSE;
  70.     gMissionControlEnabled = false;
  71. }
  72.  
  73.  
  74.  
  75. PR_PUBLIC_API(PRBool)
  76. HT_IsLocalData (HT_Resource node)
  77. {
  78.     PRBool        isLocal = PR_FALSE;
  79.     char        *origin;
  80.  
  81.     XP_ASSERT(node != NULL);
  82.  
  83.     if (node != NULL)
  84.     {
  85.         if ((origin = node->dataSource) != NULL)
  86.         {
  87.             if (startsWith("rdf:lfs", origin) ||
  88.                 startsWith("rdf:localStore", origin))
  89.             {
  90.                 isLocal = PR_TRUE;
  91.             }
  92.         }
  93.     }
  94.     return (isLocal);
  95. }
  96.  
  97.  
  98.  
  99. PR_PUBLIC_API(char *)
  100. HT_DataSource (HT_Resource node)
  101. {
  102.     char        *dataSource = NULL;
  103.  
  104.     XP_ASSERT(node != NULL);
  105.  
  106.     if (node != NULL)
  107.     {
  108.         dataSource = node->dataSource;
  109.     }
  110.     return(dataSource);
  111. }
  112.  
  113.  
  114.  
  115. HT_Resource
  116. newHTEntry (HT_View view, RDF_Resource node)
  117. {
  118.     HT_Resource        existing, nr;
  119.  
  120.     XP_ASSERT(view != NULL);
  121.     XP_ASSERT(node != NULL);
  122.  
  123.     if ((nr = (HT_Resource)getMem(sizeof(HT_ResourceStruct))) != NULL)
  124.     {
  125.         existing = PL_HashTableLookup(view->pane->hash, node);
  126.         nr->view = view;
  127.         if (existing != NULL)
  128.         {
  129.             existing->nextItem = nr;
  130.         }
  131.         else
  132.         {
  133.             PL_HashTableAdd(view->pane->hash, node, nr);
  134.         }
  135.         nr->node = node;
  136.         if (containerp(node))
  137.         {
  138.             nr->flags |= HT_CONTAINER_FLAG;
  139.         }
  140.         else
  141.         {
  142.             nr->flags &= (~HT_CONTAINER_FLAG);
  143.         }
  144.     }
  145.     return(nr);
  146. }
  147.  
  148.  
  149.  
  150. void
  151. addWorkspace(HT_Pane pane, RDF_Resource r, void *feData)
  152. {
  153.     HT_View            view;
  154.  
  155.     XP_ASSERT(pane != NULL);
  156.     XP_ASSERT(r != NULL);
  157.  
  158.     /* if view has been deleted (false assertion), don't reassert it */
  159.  
  160.     if (!RDF_HasAssertion(gNCDB, r, gCoreVocab->RDF_parent, gNavCenter->RDF_Top, RDF_RESOURCE_TYPE, 0))
  161.     {
  162.         view = HT_NewView(r, pane, PR_TRUE, feData, PR_FALSE);
  163.     }
  164. }
  165.  
  166.  
  167.  
  168. void
  169. deleteWorkspace(HT_Pane pane, RDF_Resource r)
  170. {
  171.     HT_Pane            paneList;
  172.     HT_Resource        parent;
  173.     HT_View            view, nextView;
  174.  
  175.     XP_ASSERT(pane != NULL);
  176.     XP_ASSERT(r != NULL);
  177.  
  178.     /* find appropriate view(s) and delete them */
  179.  
  180.     paneList = gHTTop;
  181.     while (paneList != NULL)
  182.     {
  183.         view = paneList->viewList;
  184.         while (view != NULL)
  185.         {
  186.             nextView = view->next;
  187.             if ((parent = HT_TopNode(view)) != NULL)
  188.             {
  189.                 if (parent->node == r)
  190.                 {
  191.                     HT_DeleteView(view);
  192.                 }
  193.             }
  194.             view = nextView;
  195.         }
  196.         paneList = paneList->next;
  197.     }
  198. }
  199.  
  200.  
  201.  
  202. /*
  203.     HyperTree pane notification function
  204. */
  205.  
  206. void
  207. htrdfNotifFunc (RDF_Event ns, void* pdata)
  208. {
  209.     HT_Pane            pane;
  210.     HT_Resource        htr;
  211.     PRHashTable        *hash;
  212.     RDF_AssertEvent        aev;
  213.     RDF_UnassertEvent    uev;
  214.     RDF_Resource        vu;
  215.  
  216.     pane = (HT_Pane)pdata;
  217.     XP_ASSERT(pane != NULL);
  218.     hash = pane->hash;
  219.     XP_ASSERT(hash != NULL);
  220.  
  221.     switch (ns->eventType) 
  222.     {     
  223.         case RDF_INSERT_NOTIFY:
  224.         case RDF_ASSERT_NOTIFY:
  225.         aev = &(ns->event.assert);
  226.         if (aev->s == gCoreVocab->RDF_parent)
  227.         {
  228.             vu = (RDF_Resource)aev->v;
  229.             if (vu == gNavCenter->RDF_Top)
  230.             {
  231.                 if (aev->tv)
  232.                 {
  233.                     addWorkspace(pane, aev->u, NULL);
  234.                 }
  235.                 else
  236.                 {
  237.                     deleteWorkspace(pane, aev->u);
  238.                 }
  239.             }
  240.             else
  241.             {
  242.                 htr = PR_HashTableLookup(hash, vu);
  243.                 while (htr != NULL)
  244.                 {
  245.                     if (HT_IsContainerOpen(htr))
  246.                     {
  247.                         if (aev->tv)
  248.                         { 
  249.                             if (ns->eventType == RDF_INSERT_NOTIFY)
  250.                             {
  251.                                 resynchContainer(htr);
  252.                             }
  253.                             else
  254.                             {
  255.                                 addContainerItem(htr, aev->u);
  256.                             }
  257.                         }
  258.                         else
  259.                         {
  260.                             deleteContainerItem(htr, aev->u);
  261.                         }
  262.                     }
  263.                     htr = htr->nextItem;
  264.                 }
  265.             }
  266.         }
  267.         else
  268.         {
  269.             htr = PR_HashTableLookup(hash, aev->u);
  270.             while (htr != NULL)
  271.             {
  272.                 resynchItem(htr, aev->s, aev->v, TRUE);
  273.                 sendNotification(htr, HT_EVENT_NODE_VPROP_CHANGED);
  274.                 htr = htr->nextItem;
  275.             }
  276.         }
  277.         break;
  278.  
  279.         case RDF_DELETE_NOTIFY:
  280.         uev = &(ns->event.unassert);
  281.         if ((uev->s == gCoreVocab->RDF_parent))
  282.         {
  283.             if ((RDF_Resource)uev->v == gNavCenter->RDF_Top)
  284.             {
  285.                 deleteWorkspace(pane, uev->u);
  286.             }
  287.             else
  288.             {
  289.                 htr = PR_HashTableLookup(hash, (RDF_Resource)uev->v);
  290.                 while (htr != NULL)
  291.                 {
  292.                     if ((uev->s == gCoreVocab->RDF_parent) && (htr->child))
  293.                     {
  294.                         deleteContainerItem(htr, uev->u);
  295.                     }
  296.                     htr = htr->nextItem;
  297.                 }
  298.             }
  299.         }
  300.         else
  301.         {
  302.             htr = PR_HashTableLookup(hash, (RDF_Resource)uev->u);
  303.             while (htr != NULL)
  304.             {
  305.                 resynchItem(htr, uev->s, uev->v, FALSE);
  306.                 sendNotification(htr, HT_EVENT_NODE_VPROP_CHANGED);
  307.                 htr = htr->nextItem;
  308.             }      
  309.         }
  310.         break;
  311.     }
  312. }
  313.  
  314.  
  315.  
  316. /*
  317.     Bookmark / Personal Toolbar pane notification function
  318.     
  319.     Note: only pass RDF_name property changes
  320. */
  321.  
  322. void
  323. bmkNotifFunc (RDF_Event ns, void* pdata)
  324. {
  325.     HT_Pane            pane;
  326.     HT_Resource        htr;
  327.     PLHashTable        *hash;
  328.     RDF_AssertEvent        aev = NULL;
  329.     RDF_UnassertEvent    uev = NULL;
  330.  
  331.     pane = (HT_Pane)pdata;
  332.     XP_ASSERT(pane != NULL);
  333.     hash = pane->hash;
  334.     XP_ASSERT(hash != NULL);
  335.  
  336.     switch (ns->eventType) 
  337.     {
  338.         case RDF_INSERT_NOTIFY :
  339.         case RDF_ASSERT_NOTIFY :
  340.         aev = &(ns->event.assert);
  341.         if (aev->s == gCoreVocab->RDF_parent)
  342.         {
  343.             htr = PL_HashTableLookup(hash, (RDF_Resource)aev->v);
  344.             while (htr != NULL)
  345.             {
  346.                 /* Note: don't check if open... remove item even if closed */
  347.                 if (aev->tv)
  348.                 {
  349.                     if (ns->eventType == RDF_INSERT_NOTIFY)
  350.                     {
  351.                         resynchContainer(htr);
  352.                     }
  353.                     else
  354.                     {
  355.                         addContainerItem(htr, aev->u);
  356.                     }
  357.                 }
  358.                 else
  359.                 {
  360.                     deleteContainerItem(htr, aev->u);
  361.                 }
  362.                 htr = htr->nextItem;
  363.             }
  364.         }
  365.         else if ((aev->s == gCoreVocab->RDF_name) || (aev->s == gNavCenter->RDF_smallIcon) ||
  366.                  (aev->s == gNavCenter->RDF_largeIcon))
  367.         {
  368.             htr = PL_HashTableLookup(hash, aev->u);
  369.             while (htr != NULL)
  370.             {
  371.                 resynchItem(htr, aev->s, aev->v, TRUE);
  372.                 sendNotification(htr, HT_EVENT_NODE_VPROP_CHANGED);
  373.                 htr = htr->nextItem;
  374.             }
  375.         }
  376.         break;
  377.           
  378.         case RDF_DELETE_NOTIFY:
  379.         uev = &(ns->event.unassert);
  380.         if (uev->s == gCoreVocab->RDF_parent)
  381.         {
  382.             htr = PL_HashTableLookup(hash, (RDF_Resource)uev->v);
  383.             while (htr != NULL)
  384.             {
  385.                 if (htr->child)
  386.                 {
  387.                     deleteContainerItem(htr, uev->u);
  388.                 }
  389.                 htr = htr->nextItem;
  390.             }
  391.         }
  392.         else if ((uev->s == gCoreVocab->RDF_name) || (uev->s == gNavCenter->RDF_smallIcon) ||
  393.                  (uev->s == gNavCenter->RDF_largeIcon))
  394.         {
  395.             htr = PL_HashTableLookup(hash, (RDF_Resource)uev->u);
  396.             while (htr != NULL)
  397.             {
  398.                 resynchItem(htr, uev->s, uev->v, FALSE);
  399.                 sendNotification(htr, HT_EVENT_NODE_VPROP_CHANGED);
  400.                 htr = htr->nextItem;
  401.             }
  402.         }
  403.         break;
  404.     }
  405. }
  406.  
  407.  
  408.  
  409. void
  410. refreshItemListInt (HT_View view, HT_Resource node)
  411. {
  412.     uint32            bucketNum,count,offset;
  413.     ldiv_t            cdiv;
  414.  
  415.     if (node != NULL)
  416.     {
  417.         node->view = view;
  418.     }
  419.     count = view->itemListCount;
  420.     cdiv  = ldiv(count , ITEM_LIST_ELEMENT_SIZE);
  421.     bucketNum = (uint32)cdiv.quot;
  422.     offset = (uint32)cdiv.rem;
  423.     if (*(view->itemList + bucketNum) == NULL) 
  424.     {
  425.         *(view->itemList + bucketNum) = (HT_Resource*)getMem(ITEM_LIST_ELEMENT_SIZE*4);
  426.         if (*(view->itemList + bucketNum) == NULL)
  427.         {
  428.             return;
  429.         }
  430.     }
  431.     *((*(view->itemList + bucketNum)) + offset) = node;
  432.     node->itemListIndex = (uint32)count;
  433.     view->itemListCount++;
  434. }
  435.  
  436.  
  437.  
  438. int
  439. compareStrings(char *s1, char *s2)
  440. {
  441. #ifdef    XP_WIN
  442.     return(stricmp(s1,s2));        /* case insignificant string compare */
  443. #endif
  444.  
  445. #ifdef    XP_MAC
  446.     return(strcasecmp(s1,s2));
  447. #endif
  448.  
  449.     return(strcmp(s1,s2));
  450. }
  451.  
  452.  
  453.  
  454. int
  455. nodeCompareRtn(HT_Resource *node1, HT_Resource *node2)
  456. {
  457.     PRBool        sortOnName = true, isSep1, isSep2;
  458.     uint32        node1Index, node2Index;
  459.     int         retVal=0;
  460.     void        *data1, *data2;
  461.     void        *sortToken;
  462.     uint32        sortTokenType;
  463.     PRBool        descendingFlag;
  464.     char        *node1Name = NULL, *node2Name = NULL;
  465.  
  466.     XP_ASSERT(node1 != NULL);
  467.     XP_ASSERT(node2 != NULL);
  468.  
  469.     if (((*node1) == NULL) || ((*node2) == NULL))
  470.     {
  471.         if (((*node1) == NULL) && ((*node2) != NULL))        return(1);
  472.         else if (((*node1) != NULL) && ((*node2) == NULL))    return(-1);
  473.         return(0);
  474.     }
  475.  
  476.     sortToken = (*node1)->view->sortToken;
  477.     sortTokenType = (*node1)->view->sortTokenType;
  478.     descendingFlag = (*node1)->view->descendingFlag;
  479.  
  480.     if (sortToken != NULL)
  481.     {
  482.         isSep1 = HT_IsSeparator(*node1);
  483.         isSep2 = HT_IsSeparator(*node2);
  484.         if (isSep1 && isSep2)    return(0);
  485.         else if (isSep1)    return(1);
  486.         else if (isSep2)    return(-1);
  487.  
  488.         HT_GetNodeData (*node1, sortToken, sortTokenType, &data1);
  489.         HT_GetNodeData (*node2, sortToken, sortTokenType, &data2);
  490.  
  491.         switch(sortTokenType)
  492.         {
  493.         case    HT_COLUMN_STRING:
  494.         case    HT_COLUMN_DATE_STRING:
  495.             sortOnName = false;
  496.             if (data1 && data2)
  497.             {
  498.                 retVal = compareStrings(data1, data2);
  499.                 sortOnName = false;
  500.             }
  501.             else
  502.             {
  503.                 descendingFlag = false;
  504.                 if (data1)        retVal=-1;
  505.                 else if (data2)     retVal=1;
  506.                 else
  507.                 {
  508.                     descendingFlag = true;
  509.                     sortOnName = true;
  510.                     retVal=0;
  511.                 }
  512.             }
  513.             break;
  514.  
  515.         case    HT_COLUMN_INT:
  516.         case    HT_COLUMN_DATE_INT:
  517.             if ((long)data1 == (long)data2)
  518.                 retVal = 0;
  519.             else if((long)data1 < (long)data2)
  520.                 retVal = -1;
  521.             else    retVal = 1;
  522.             sortOnName = false;
  523.             break;
  524.         }
  525.         if (sortOnName == true)
  526.         {
  527.             node1Name = HT_GetNodeName(*node1);
  528.             node2Name = HT_GetNodeName(*node2);
  529.             if ((node1Name != NULL) && (node2Name != NULL))
  530.             {
  531.                 retVal = compareStrings(node1Name, node2Name);
  532.             }
  533.             else
  534.             {
  535.                 if (node1Name != NULL)        retVal=-1;
  536.                 else if (node2Name != NULL)    retVal=1;
  537.                 else                retVal=0;
  538.             }
  539.         }
  540.         if ((descendingFlag == true) && (retVal != 0))
  541.         {
  542.             retVal = -retVal;
  543.         }
  544.     }
  545.     else    /* natural order */
  546.     {
  547.         node1Index = (*node1)->unsortedIndex;
  548.         node2Index = (*node2)->unsortedIndex;
  549.         if (node1Index < node2Index)        retVal=-1;
  550.         else if (node1Index > node2Index)    retVal=1;
  551.         else                    retVal=0;
  552.     }
  553.     return(retVal);
  554. }
  555.  
  556.  
  557.  
  558. void
  559. sortNodes(HT_View view, HT_Resource parent, HT_Resource *children, uint32 numChildren)
  560. {
  561.     RDF_BT            containerType;
  562.     PRBool            descendingFlag, sortChanged = false;
  563.     void            *sortToken;
  564.     uint32            sortTokenType;
  565.  
  566.     XP_ASSERT(view != NULL);
  567.     XP_ASSERT(parent != NULL);
  568.  
  569.     containerType = resourceType(parent->node);
  570.     if ((view->sortToken == NULL) && (containerType != RDF_RT))
  571.     {
  572.         /* default: sort on name column */
  573.  
  574.         sortChanged = true;
  575.  
  576.         sortToken = view->sortToken;
  577.         view->sortToken = gCoreVocab->RDF_name;
  578.  
  579.         sortTokenType = view->sortTokenType;
  580.         view->sortTokenType = HT_COLUMN_STRING;
  581.  
  582.         descendingFlag = view->descendingFlag;
  583.         view->descendingFlag = false;
  584.     }
  585.     if (numChildren>1)
  586.     {
  587.         XP_QSORT((void *)children, (size_t)numChildren,
  588.         (size_t)sizeof(HT_Resource *), (void *)nodeCompareRtn);
  589.     }
  590.     if (sortChanged == true)
  591.     {
  592.         view->sortToken = sortToken;
  593.         view->sortTokenType = sortTokenType;
  594.         view->descendingFlag = descendingFlag;
  595.     }
  596. }
  597.  
  598.  
  599.  
  600. uint32
  601. refreshItemList1(HT_View view, HT_Resource node)
  602. {
  603.     HT_Cursor        c;
  604.     HT_Resource        *r;
  605.     uint32            loop, numElements=0, numGrandChildren=0;
  606.  
  607.     XP_ASSERT(view != NULL);
  608.     XP_ASSERT(node != NULL);
  609.  
  610.     if (node == NULL)    return(0);
  611.     node->view = view;
  612.  
  613.     if ((c = HT_NewCursor(node)) != NULL)
  614.     {
  615.         if ((numElements = c->numElements) > 0)
  616.         {
  617.             if (node->children = (HT_Resource *)getMem(
  618.                         (numElements+1) * sizeof (HT_Resource *)))
  619.             {
  620.                 loop=0;
  621.                 while (((node->children[loop]) = HT_GetNextItem(c)) != NULL)
  622.                 {
  623.                     ++loop;
  624.                     if (loop >= numElements)    break;
  625.                 }
  626.                 numElements = loop;
  627.  
  628.                 sortNodes(view, node, node->children, numElements);
  629.  
  630.                 /* after a sort, update container's child list */
  631.  
  632.                 r = &(node->child);
  633.                 for (loop=0; loop<numElements; loop++)
  634.                 {
  635.                     *r = node->children[loop];
  636.                     r = &((*r)->next);
  637.                 }
  638.                 *r = NULL;
  639.  
  640.                 for (loop=0; loop<numElements; loop++)
  641.                 {
  642.                     refreshItemListInt(view, node->children[loop]);
  643.                     if (HT_IsContainer(node->children[loop]))
  644.                     {
  645.                         numGrandChildren = refreshItemList1(view,
  646.                                     node->children[loop]);
  647.                     }
  648.                 }
  649.                 freeMem(node->children);
  650.                 node->children = NULL;
  651.             }
  652.         }
  653.         HT_DeleteCursor(c);
  654.         node->numChildren = numElements;
  655.         node->numChildrenTotal = numElements + numGrandChildren;
  656.         return(node->numChildrenTotal);
  657.     }
  658.     else
  659.     {
  660.         node->child = NULL;
  661.         node->numChildren = 0;
  662.         node->numChildrenTotal = 0;
  663.         return(0);
  664.     }
  665. }
  666.  
  667.  
  668.  
  669. void
  670. refreshItemList (HT_Resource node, HT_Event whatHappened)
  671. {
  672.     XP_ASSERT(node != NULL);
  673.     XP_ASSERT(node->view != NULL);
  674.     XP_ASSERT(node->view->top != NULL);
  675.  
  676.     if ((node == NULL) || (node->view == NULL) || (node->view->top == NULL))
  677.     {
  678.         return;
  679.     }
  680.  
  681.     if (!node->view->refreshingItemListp)
  682.     {
  683.         node->view->refreshingItemListp = 1;
  684.         node->view->itemListCount = 0;
  685.         refreshItemList1(node->view,node->view->top);
  686.         node->view->refreshingItemListp = 0;
  687.         node->view->inited = PR_TRUE;
  688.         if (whatHappened) sendNotification(node,  whatHappened);
  689.     }
  690. }
  691.  
  692.  
  693.  
  694. void
  695. refreshPanes(PRBool onlyUpdateBookmarks, PRBool onlyUpdatePersonalToolbar, RDF_Resource newTopNode)
  696. {
  697.     HT_Pane        *paneList;
  698.  
  699.     paneList = &gHTTop;
  700.     while ((*paneList) != NULL)
  701.     {
  702.         if (((onlyUpdateBookmarks == true) && ((*paneList)->bookmarkmenu == true)) ||
  703.         ((onlyUpdatePersonalToolbar == true) && ((*paneList)->personaltoolbar == true)))
  704.         {
  705.             if ((*paneList)->selectedView != NULL)
  706.             {
  707.                 destroyViewInt((*paneList)->selectedView->top, FALSE);
  708.                 (*paneList)->selectedView->top->node = newTopNode;
  709.                 (*paneList)->selectedView->top->flags |= HT_OPEN_FLAG;
  710.                 (*paneList)->dirty = true;
  711.             }
  712.         }
  713.  
  714.         if ((*paneList)->dirty == true)
  715.         {
  716.             if ((*paneList)->selectedView != NULL)
  717.             {
  718.                 refreshItemList (((*paneList)->selectedView)->top,
  719.                         HT_EVENT_VIEW_REFRESH);
  720.             }
  721.             (*paneList)->dirty = false;
  722.         }
  723.         paneList = &(*paneList)->next;
  724.     }
  725. }
  726.  
  727.  
  728.  
  729. PR_PUBLIC_API(uint32)
  730. HT_GetCountVisibleChildren(HT_Resource node)
  731. {
  732.     uint32        count=0;
  733.  
  734.     XP_ASSERT(node != NULL);
  735.  
  736.     if (HT_IsContainer(node) && HT_IsContainerOpen(node))
  737.     {
  738.         count = node->numChildrenTotal;
  739.     }
  740.     return(count);
  741. }
  742.  
  743.  
  744.  
  745. HT_Pane
  746. paneFromResource(RDF_Resource resource, HT_Notification notify, PRBool autoFlushFlag, PRBool autoOpenFlag)
  747. {
  748.     HT_Pane            pane;
  749.     HT_View            view;
  750.         RDF_Event               ev;
  751.     PRBool            err = false;
  752.  
  753.     do
  754.     {
  755.         if ((pane = (HT_Pane)getMem(sizeof(HT_PaneStruct))) == NULL)
  756.         {
  757.             err = true;
  758.             break;
  759.         }
  760.         pane->special = true;
  761.         pane->ns = notify;
  762.         pane->mask = HT_EVENT_DEFAULT_NOTIFICATION_MASK ;
  763.                 if ((ev = (RDF_Event)getMem(sizeof(struct RDF_EventStruct))) == NULL) 
  764.         {
  765.             err = true; 
  766.             break;
  767.         }
  768.  
  769.         ev->eventType = HT_EVENT_DEFAULT_NOTIFICATION_MASK;
  770.  
  771.         pane->rns = RDF_AddNotifiable(gNCDB, bmkNotifFunc, ev, pane);
  772.         freeMem(ev);
  773.  
  774.         if ((pane->hash = PL_NewHashTable(500, idenHash, PL_CompareValues,
  775.                         PL_CompareValues,  NULL, NULL)) == NULL)
  776.         {
  777.             err = true;
  778.             break;
  779.         }
  780.         pane->db =  newNavCenterDB();
  781.         pane->autoFlushFlag = autoFlushFlag;
  782.  
  783.         if ((view = HT_NewView(resource, pane, PR_FALSE, NULL, autoOpenFlag)) == NULL)
  784.         {
  785.             err = true;
  786.             break;
  787.         }
  788.         pane->selectedView = view;
  789.  
  790.         pane->next = gHTTop;
  791.         gHTTop = pane;
  792.  
  793.     } while (false);
  794.  
  795.     if (err == true)
  796.     {
  797.         if (pane != NULL)
  798.         {
  799.             htDeletePane(pane,PR_FALSE);
  800.             pane = NULL;
  801.         }
  802.     }
  803.     return(pane);
  804. }
  805.  
  806.  
  807.  
  808. PR_PUBLIC_API(HT_Pane)
  809. HT_PaneFromResource(RDF_Resource r, HT_Notification n, PRBool autoFlush)
  810. {
  811.     return paneFromResource(r, n, autoFlush, false);
  812. }
  813.  
  814.  
  815.  
  816. PR_PUBLIC_API(HT_Pane)
  817. HT_NewQuickFilePane(HT_Notification notify)
  818. {
  819.     HT_Pane            pane = NULL;
  820.     RDF_Resource        qf;
  821.  
  822.     if ((qf = RDFUtil_GetQuickFileFolder()) != NULL)
  823.     {
  824.         if ((pane = paneFromResource( qf, notify, true, true)) != NULL)
  825.         {
  826.             pane->bookmarkmenu = true;
  827.             RDFUtil_SetQuickFileFolder(pane->selectedView->top->node);
  828.         }
  829.     }
  830.     return(pane);
  831. }
  832.  
  833.  
  834.  
  835. PR_PUBLIC_API(HT_Pane)
  836. HT_NewPersonalToolbarPane(HT_Notification notify)
  837. {
  838.     HT_Pane            pane = NULL;
  839.     RDF_Resource        pt;
  840.  
  841.  
  842.     if ((pt  = RDFUtil_GetPTFolder()) != NULL)
  843.     {
  844.         if ((pane = paneFromResource(pt, notify, true, true)) != NULL)
  845.         {
  846.             pane->personaltoolbar = true;
  847.             RDFUtil_SetPTFolder(pane->selectedView->top->node);
  848.         }
  849.     }
  850.     return(pane);
  851. }
  852.  
  853.  
  854.  
  855. PR_PUBLIC_API(void)
  856. HT_AddToContainer (HT_Resource container, char *url, char *optionalTitle)
  857. {
  858.     RDF_Resource            r;
  859.     RDF                 db;
  860.  
  861.     XP_ASSERT(container != NULL);
  862.     XP_ASSERT(container->view != NULL);
  863.     XP_ASSERT(container->view->pane != NULL);
  864.     XP_ASSERT(container->view->pane->db != NULL);
  865.     XP_ASSERT(url != NULL);
  866.  
  867.     db = container->view->pane->db;
  868.  
  869.     if ((r = RDF_GetResource(db, url, 1)) != NULL)
  870.     {
  871.         if ((optionalTitle != NULL) && (optionalTitle[0] != '\0'))
  872.         {
  873.             RDF_Assert(db, r, gCoreVocab->RDF_name, 
  874.                    optionalTitle, RDF_STRING_TYPE);
  875.         }
  876.         RDF_Assert(db, r, gCoreVocab->RDF_parent, container->node, RDF_RESOURCE_TYPE);
  877.     }
  878. }
  879.  
  880.  
  881.  
  882. PR_PUBLIC_API(void)
  883. HT_AddBookmark (char *url, char *optionalTitle)
  884. {
  885.     RDF_Resource        nbFolder, r;
  886.  
  887.     XP_ASSERT(url != NULL);
  888.  
  889.     if ((nbFolder = RDFUtil_GetNewBookmarkFolder()) != NULL)
  890.     {
  891.         if ((r = RDF_GetResource(gNCDB, url, 1)) != NULL)
  892.         {
  893.             if ((optionalTitle != NULL) && (optionalTitle[0] != '\0'))
  894.             {
  895.                 RDF_Assert(gNCDB, r, gCoreVocab->RDF_name, 
  896.                        optionalTitle, RDF_STRING_TYPE);
  897.             }
  898.             RDF_Assert(gNCDB, r, gCoreVocab->RDF_parent, nbFolder, RDF_RESOURCE_TYPE);
  899.         }
  900.     }
  901. }
  902.  
  903.  
  904.  
  905. RDF
  906. newHTPaneDB()
  907. {
  908.     return gNCDB;
  909. }
  910.  
  911.  
  912.  
  913. char *
  914. gNavCenterDataSources1[15] = 
  915. {
  916.     "rdf:localStore", "rdf:remoteStore", "rdf:history",
  917.      /* "rdf:ldap", */
  918.     "rdf:esftp", "rdf:mail",
  919.     "rdf:lfs",  "rdf:ht",
  920.     "rdf:columns",  NULL
  921. };
  922.  
  923.  
  924.  
  925. PR_PUBLIC_API(HT_Pane)
  926. HT_NewPane (HT_Notification notify)
  927. {
  928.     HT_Pane            pane;
  929.     PRBool            err = false;
  930.     RDF_Event               ev;
  931.  
  932.  
  933.     do
  934.     {
  935.         if ((pane = (HT_Pane)getMem(sizeof(HT_PaneStruct))) == NULL)
  936.         {
  937.             err = true;
  938.             break;
  939.         }
  940.         pane->ns = notify;
  941.         pane->mask = HT_EVENT_DEFAULT_NOTIFICATION_MASK ;
  942.         
  943.         if ((ev = (RDF_Event)getMem(sizeof(struct RDF_EventStruct))) == NULL) 
  944.         {
  945.             err = true;
  946.             break;
  947.         }
  948.         ev->eventType = HT_EVENT_DEFAULT_NOTIFICATION_MASK;
  949.         pane->db = RDF_GetDB((char**)gNavCenterDataSources1);
  950.         pane->rns = RDF_AddNotifiable(pane->db, htrdfNotifFunc, ev, pane);
  951.         freeMem(ev);
  952.  
  953.         if ((pane->hash = PL_NewHashTable(500, idenHash, PL_CompareValues,
  954.                         PL_CompareValues,  null, null)) == NULL)
  955.         {
  956.             err = true;
  957.             break;
  958.         }
  959.  
  960.         pane->next = gHTTop;
  961.         gHTTop = pane;
  962.  
  963.         if ((err = initViews(pane)) == true)
  964.         {
  965.             break;
  966.         }
  967.  
  968. /*
  969.         pane->selectedView = pane->viewList;
  970. */
  971.     } while (false);
  972.  
  973.     if (err == true)
  974.     {
  975.         if (pane != NULL)
  976.         {
  977.             htDeletePane(pane, PR_FALSE);
  978.             pane = NULL;
  979.         }
  980.     }
  981.     return(pane);
  982. }
  983.  
  984.  
  985.  
  986. PRBool
  987. initViews (HT_Pane pane)
  988. {
  989.     HT_View            view;
  990.     RDF_Cursor        c;
  991.     RDF_Resource        n;
  992.     PRBool            err = false;
  993.  
  994.     XP_ASSERT(pane != NULL);
  995.  
  996.     if ((c = RDF_GetSources(pane->db, gNavCenter->RDF_Top, gCoreVocab->RDF_parent,
  997.                 RDF_RESOURCE_TYPE, 1)) != NULL)
  998.     {
  999.         while ((n = RDF_NextValue(c)) != NULL)
  1000.         {
  1001.             if ((view = HT_NewView(n, pane, PR_TRUE, NULL, PR_FALSE)) == NULL)
  1002.             {
  1003.                 err = true;
  1004.                 break;
  1005.             }
  1006.         }
  1007.         RDF_DisposeCursor(c);
  1008.     }
  1009.     return(err);
  1010. }
  1011.  
  1012.  
  1013.  
  1014. PR_PUBLIC_API(void)
  1015. HT_NewWorkspace(HT_Pane pane, char *id, char *optionalTitle)
  1016. {
  1017.     RDF_Resource        r;
  1018.  
  1019.     XP_ASSERT(id != NULL);
  1020.     XP_ASSERT(pane != NULL);
  1021.  
  1022.     if ((r = RDF_GetResource(pane->db, id, 0)) == NULL)
  1023.     {
  1024.         if ((r = RDF_GetResource(pane->db, id, 1)) != NULL)
  1025.         {
  1026.             setContainerp (r, true);
  1027.             setResourceType (r, RDF_RT);
  1028.         }
  1029.     }
  1030.     if (r != NULL)
  1031.     {
  1032.         if ((optionalTitle != NULL) && (optionalTitle[0] != '\0'))
  1033.         {
  1034.             RDF_Assert(pane->db, r, gCoreVocab->RDF_name, 
  1035.                    optionalTitle, RDF_STRING_TYPE);
  1036.         }
  1037.         RDFUtil_SetDefaultSelectedView(r);
  1038.         RDF_Assert(pane->db, r, gCoreVocab->RDF_parent,
  1039.             gNavCenter->RDF_Top, RDF_RESOURCE_TYPE);
  1040.     }
  1041. }
  1042.  
  1043.  
  1044.  
  1045. HT_PaneStruct *
  1046. HT_GetHTPaneList ()
  1047. {
  1048.     return(gHTTop);
  1049. }
  1050.  
  1051.  
  1052.  
  1053. HT_PaneStruct *
  1054. HT_GetNextHTPane (HT_PaneStruct* pane)
  1055. {
  1056.     if (pane == NULL)
  1057.     {
  1058.         return(NULL);
  1059.     }
  1060.     return(pane->next);
  1061. }
  1062.  
  1063.  
  1064.  
  1065. void
  1066. htSetWorkspaceOrder(RDF_Resource src, RDF_Resource dest, PRBool afterDestFlag)
  1067. {
  1068.     HT_Pane            paneList;
  1069.     HT_View            *viewList, *prevViewList, srcView, *srcViewList;
  1070.     PRBool            foundSrc, foundDest;
  1071.  
  1072.     XP_ASSERT(src != NULL);
  1073.     XP_ASSERT(dest != NULL);
  1074.     if ((src == NULL) || (dest == NULL))    return;
  1075.  
  1076.     paneList = gHTTop;
  1077.     while (paneList != NULL)
  1078.     {
  1079.         foundSrc = foundDest = FALSE;
  1080.         srcView = NULL;
  1081.         prevViewList = srcViewList = NULL;
  1082.         viewList = &(paneList->viewList);
  1083.         while(*viewList)
  1084.         {
  1085.             if ((*viewList)->top->node == src)
  1086.             {
  1087.                 srcView = (*viewList);
  1088.                 srcViewList = viewList;
  1089.                 foundSrc = TRUE;
  1090.             }
  1091.             if ((*viewList)->top->node == dest)
  1092.             {
  1093.                 foundDest = TRUE;
  1094.             }
  1095.             if (foundDest == FALSE)
  1096.             {
  1097.                 prevViewList = viewList;
  1098.             }
  1099.             if (foundSrc == TRUE && foundDest == TRUE)
  1100.             {
  1101.                 break;
  1102.             }
  1103.             viewList = &(*viewList)->next;
  1104.         }
  1105.         if (foundSrc == TRUE && foundDest == TRUE)
  1106.         {
  1107.             if (htIsOpLocked(srcView->top,
  1108.                 gNavCenter->RDF_WorkspacePosLock))
  1109.             {
  1110.                 return;
  1111.             }
  1112.             if (afterDestFlag == TRUE)
  1113.             {
  1114.                 /* move src workspace after dest workspace */
  1115.                 
  1116.                 if ((*prevViewList)->next != NULL)
  1117.                 {
  1118.                     if (htIsOpLocked(((*prevViewList)->next)->top,
  1119.                         gNavCenter->RDF_WorkspacePosLock))
  1120.                     {
  1121.                         return;
  1122.                     }
  1123.                 }
  1124.  
  1125.                 *srcViewList = (*srcViewList)->next;
  1126.                 srcView->next = (*prevViewList)->next;
  1127.                 (*prevViewList)->next = srcView;
  1128.             }
  1129.             else
  1130.             {
  1131.                 /* move src workspace before dest workspace */
  1132.  
  1133.                 if (prevViewList == NULL)
  1134.                 {
  1135.                     prevViewList = &(paneList->viewList);
  1136.                 }
  1137.                 else
  1138.                 {
  1139.                     prevViewList = &((*prevViewList)->next);
  1140.                 }
  1141.  
  1142.                 if ((*prevViewList) != NULL)
  1143.                 {
  1144.                     if (htIsOpLocked((*prevViewList)->top,
  1145.                         gNavCenter->RDF_WorkspacePosLock))
  1146.                     {
  1147.                         return;
  1148.                     }
  1149.                 }
  1150.                 *srcViewList = (*srcViewList)->next;
  1151.                 srcView->next = *prevViewList;
  1152.                 *prevViewList = srcView;
  1153.             }
  1154.  
  1155.             saveWorkspaceOrder(paneList);
  1156.             sendNotification(srcView->top, HT_EVENT_VIEW_WORKSPACE_REFRESH);
  1157.         }
  1158.         paneList = paneList->next;
  1159.     }
  1160. }
  1161.  
  1162.  
  1163.  
  1164. PR_PUBLIC_API(void)
  1165. HT_SetWorkspaceOrder(HT_View src, HT_View dest, PRBool afterDestFlag)
  1166. {
  1167.     XP_ASSERT(src != NULL);
  1168.     XP_ASSERT(src->pane != NULL);
  1169.     XP_ASSERT(dest != NULL);
  1170.     XP_ASSERT(dest->pane != NULL);
  1171.     XP_ASSERT(src->pane == dest->pane);
  1172.  
  1173.     if ((src == NULL) || (dest == NULL))    return;
  1174.  
  1175.     htSetWorkspaceOrder(src->top->node, dest->top->node, afterDestFlag);
  1176. }
  1177.  
  1178.  
  1179.  
  1180. HT_View
  1181. HT_NewView (RDF_Resource topNode, HT_Pane pane, PRBool useColumns, void *feData, PRBool autoOpen)
  1182. {
  1183.     HT_Column        *columnList, column, nextColumn;
  1184.     HT_View            view, *viewList;
  1185.     RDF_Cursor        cursor;
  1186.     RDF_Resource        r, selectedView;
  1187.     PRBool            err = false, workspaceAdded;
  1188.     uint32            workspacePos;
  1189.  
  1190.     do
  1191.     {
  1192.         if ((view = (HT_View)getMem(sizeof(HT_ViewStruct))) == NULL)
  1193.         {
  1194.             err = true;
  1195.             break;
  1196.         }
  1197.         view->pane = pane;
  1198.         if ((view->top = newHTEntry(view, topNode)) == NULL)
  1199.         {
  1200.             err = true;
  1201.             break;
  1202.         }
  1203.  
  1204.         HT_SetViewFEData(view, feData);
  1205.  
  1206.         if (autoOpen)    view->top->flags |= HT_OPEN_FLAG;
  1207.         view->top->depth = 0;
  1208.  
  1209.         view->itemListSize = ITEM_LIST_SIZE;
  1210.         if ((view->itemList = (HT_Resource **)getMem(ITEM_LIST_SIZE * 4)) == NULL)
  1211.         {
  1212.             err = true;
  1213.             break;
  1214.         }
  1215.  
  1216.         view->itemListCount = 0;
  1217.         if (autoOpen)
  1218.         {
  1219.             refreshItemList(view->top, 0);
  1220.         }
  1221.  
  1222.         if (useColumns)    {
  1223.         columnList = &view->columns;
  1224.         if ((cursor = RDF_GetTargets(pane->db, view->top->node, gNavCenter->RDF_Column, 
  1225.                         RDF_RESOURCE_TYPE,  true)) != NULL)
  1226.         {
  1227.             while ((r = RDF_NextValue(cursor)) != NULL)
  1228.             {
  1229.                 if (resourceID(r) == NULL)    break;
  1230.  
  1231.                 column = (HT_Column)getMem(sizeof(HT_ColumnStruct));
  1232.                 if (column == NULL)    {
  1233.                     err = true;
  1234.                     break;
  1235.                     }
  1236.  
  1237.                 column->token = r;
  1238.                 column->tokenType = (uint32) RDF_GetSlotValue(pane->db, r,
  1239.                                 gNavCenter->RDF_ColumnDataType,
  1240.                                 RDF_INT_TYPE, false, true);
  1241.                 column->width = (uint32) RDF_GetSlotValue(pane->db, r,
  1242.                                 gNavCenter->RDF_ColumnWidth,
  1243.                                 RDF_INT_TYPE, false, true);
  1244.                 column->name = (char *) RDF_GetSlotValue(pane->db, r,
  1245.                                 gCoreVocab->RDF_name,
  1246.                                 RDF_STRING_TYPE, false, true);
  1247. #ifndef    DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  1248.  
  1249.                 if (column->name != NULL)
  1250.                 {
  1251.                     column->name = copyString(column->name);
  1252.                 }
  1253. #endif
  1254.  
  1255.                 *columnList = column;
  1256.                 columnList = &(column->next);
  1257.             }    
  1258.             RDF_DisposeCursor(cursor);
  1259.         }
  1260.  
  1261.         /* if no columns defined, force one (name) to exist */
  1262.  
  1263.         if (view->columns == NULL)
  1264.         {
  1265.             column = (HT_Column)getMem(sizeof(HT_ColumnStruct));
  1266.             if (column == NULL)    {
  1267.                 err = true;
  1268.                 break;
  1269.                 }
  1270.             column->token = gCoreVocab->RDF_name;
  1271.             column->tokenType = HT_COLUMN_STRING;
  1272.             column->width = 10000;
  1273.             column->name = copyString(XP_GetString(RDF_DEFAULTCOLUMNNAME));
  1274.  
  1275.             view->columns = column;
  1276.         }
  1277.         }
  1278.  
  1279.         /*
  1280.             add into view list, taking into account any defined
  1281.             workspace positions, workspace lock status, etc...
  1282.         */
  1283.  
  1284.         workspacePos = (uint32) RDF_GetSlotValue(gNCDB,
  1285.                         view->top->node,
  1286.                         gNavCenter->RDF_WorkspacePos,
  1287.                         RDF_INT_TYPE, false, true);
  1288.  
  1289.         view->workspacePos = workspacePos;
  1290.         viewList = &(pane->viewList);
  1291.         if (htIsOpLocked(view->top, gNavCenter->RDF_WorkspacePosLock))
  1292.         {
  1293.             /* always insert locked workspaces BEFORE unlocked workspaces */
  1294.             workspaceAdded = false;
  1295.             while ((*viewList) != NULL)
  1296.             {
  1297.                 if ((!htIsOpLocked((*viewList)->top, gNavCenter->RDF_WorkspacePosLock)) ||
  1298.                     ((*viewList)->workspacePos > workspacePos))
  1299.                 {
  1300.                     view->next = (*viewList);
  1301.                     (*viewList) = view;
  1302.                     workspaceAdded = true;
  1303.                     break;
  1304.                 }
  1305.                 viewList = &((*viewList)->next);
  1306.             }
  1307.             if (workspaceAdded == false)
  1308.             {
  1309.                 view->next = (*viewList);
  1310.                 (*viewList) = view;
  1311.             }
  1312.         }
  1313.         else
  1314.         {
  1315.             /* always insert unlocked workspaces AFTER locked workspaces */
  1316.             if (workspacePos == 0)
  1317.             {
  1318.                 /*
  1319.                     if unlocked and position not specified,
  1320.                     add onto end of view list
  1321.                 */
  1322.                 while ((*viewList) != NULL)
  1323.                 {
  1324.                     viewList = &((*viewList)->next);
  1325.                 }
  1326.                 *viewList = view;
  1327.             }
  1328.             else
  1329.             {
  1330.                 /*
  1331.                     if unlocked and position specified,
  1332.                     move past locked workspaces, and then
  1333.                     add into list
  1334.                 */
  1335.                 while (((*viewList) != NULL) && 
  1336.                     (htIsOpLocked((*viewList)->top,
  1337.                         gNavCenter->RDF_WorkspacePosLock)))
  1338.                 {
  1339.                     viewList = &((*viewList)->next);
  1340.                 }
  1341.                 while ((*viewList) != NULL)
  1342.                 {
  1343.                     if ((*viewList)->workspacePos > workspacePos)    break;
  1344.                     viewList = &((*viewList)->next);
  1345.                 }
  1346.                 view->next = (*viewList);
  1347.                 (*viewList) = view;
  1348.             }
  1349.         }
  1350.         ++(pane->viewListCount);
  1351.  
  1352.         sendNotification(view->top, HT_EVENT_VIEW_ADDED);
  1353.  
  1354.         if (pane->special == false)
  1355.         {
  1356.             selectedView = RDFUtil_GetDefaultSelectedView();
  1357.             if ((selectedView == topNode) || (selectedView == NULL))
  1358.             {
  1359.                 HT_SetSelectedView(pane, view);
  1360.             }
  1361.         }
  1362.  
  1363.     } while (false);
  1364.  
  1365.     if (err == true)
  1366.     {
  1367.         if (view != NULL)
  1368.         {
  1369.             if (view->top != NULL)
  1370.             {
  1371.                 freeMem(view->top);
  1372.             }
  1373.             if (view->itemList != NULL)
  1374.             {
  1375.                 freeMem(view->itemList);
  1376.                 view->itemList = NULL;
  1377.             }
  1378.             column = view->columns;
  1379.             while (column != NULL)
  1380.             {
  1381.                 nextColumn = column->next;
  1382.                 freeMem(column);
  1383.                 column = nextColumn;
  1384.             }
  1385.             freeMem(view);
  1386.             view = NULL;
  1387.         }
  1388.     }
  1389.     return(view);
  1390. }
  1391.  
  1392.  
  1393.  
  1394. void
  1395. sendNotification (HT_Resource node, HT_Event whatHappened)
  1396. {
  1397.     HT_Pane            pane;
  1398.     HT_Notification        ns;
  1399.  
  1400.     XP_ASSERT(node != NULL);
  1401.     XP_ASSERT(node->view != NULL);
  1402.     XP_ASSERT(node->view->pane != NULL);
  1403.  
  1404.     if (node->view == NULL)            return;
  1405.     if ((pane = node->view->pane) == NULL)    return;
  1406.     if ((ns = pane->ns) == NULL)        return;
  1407.     if (ns->notifyProc == NULL)        return;
  1408.   
  1409.     if (pane->mask & whatHappened) 
  1410.     {
  1411.         (*ns->notifyProc)(ns, node, whatHappened);
  1412.     }
  1413.     pane->dirty = TRUE;
  1414. }
  1415.  
  1416.  
  1417.  
  1418. void
  1419. deleteHTNode(HT_Resource node)
  1420. {
  1421.     HT_Value        value,nextValue;
  1422.     HT_View            view;
  1423.     ldiv_t            cdiv;
  1424.     uint32            bucketNum, itemListIndex, offset;
  1425.  
  1426.     XP_ASSERT(node != NULL);
  1427.     XP_ASSERT(node->view != NULL);
  1428.  
  1429.     /* HT_SetSelectedState(node, false); */
  1430.     sendNotification(node, (node->feData != NULL) ?
  1431.         HT_EVENT_NODE_DELETED_DATA : HT_EVENT_NODE_DELETED_NODATA);
  1432.  
  1433.     itemListIndex = node->itemListIndex;
  1434.  
  1435.     value = node->values;
  1436.     while (value != NULL)
  1437.     {
  1438.         nextValue = value->next;
  1439.         if (value->tokenType == HT_COLUMN_STRING ||
  1440.             value->tokenType == HT_COLUMN_DATE_STRING)
  1441.         {
  1442.             if (value->data != NULL)
  1443.             {
  1444.                 freeMem(value->data);
  1445.                 value->data = NULL;
  1446.             }
  1447.         }
  1448.         freeMem(value);
  1449.         value = nextValue;
  1450.     }
  1451.     node->values = NULL;
  1452.  
  1453. #ifdef DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  1454.     if (node->flags & HT_FREEICON_URL_FLAG)
  1455.     {
  1456.         if (node->url[0] != NULL)
  1457.         {
  1458.             freeMem(node->url[0]);
  1459.             node->url[0] = NULL;
  1460.         }
  1461.         if (node->url[1] != NULL)
  1462.         {
  1463.             freeMem(node->url[1]);
  1464.             node->url[1] = NULL;
  1465.         }
  1466.     }
  1467. #endif
  1468.  
  1469.     if ((!node->view->refreshingItemListp) && (node->view->itemList != NULL))
  1470.     {
  1471.         /* set node's associated entry in itemList to NULL */
  1472.  
  1473.         if (itemListIndex < node->view->itemListCount)
  1474.         {
  1475.             cdiv  = ldiv(itemListIndex , ITEM_LIST_ELEMENT_SIZE);
  1476.             bucketNum = (uint32)cdiv.quot;
  1477.             offset = (uint32)cdiv.rem;
  1478.             view = node->view;
  1479.             if (*(view->itemList + bucketNum) != NULL) 
  1480.             {
  1481.                 *((*(view->itemList + bucketNum)) + offset) = NULL;
  1482.             }
  1483.         }
  1484.  
  1485.         /* update list count if list isn't busy */
  1486.  
  1487.         if ((gBatchUpdate != true) && (node->view->itemListCount > 0))
  1488.         {
  1489.             --(node->view->itemListCount);
  1490.         }
  1491.     }
  1492.  
  1493.     removeHTFromHash(node->view->pane, node);
  1494.     node->node = NULL;
  1495.     node->view = NULL;
  1496.     node->parent = NULL;
  1497.     node->child = NULL;
  1498.     node->children = NULL;     
  1499.     freeMem(node);
  1500. }
  1501.  
  1502.  
  1503.  
  1504. void
  1505. destroyViewInt (HT_Resource r, PRBool saveOpenState)
  1506. {
  1507.     HT_Resource        child, tmp;
  1508.     PRBool            openState;
  1509.  
  1510.     child = r->child;
  1511.     while (child != NULL)
  1512.     {
  1513.         /* save container's open/closed state */
  1514.         if (HT_IsContainer(child) && (child->view->pane->special == PR_FALSE))
  1515.         {
  1516.             openState = nlocalStoreHasAssertion(gLocalStore, child->node,
  1517.                 gCoreVocab->RDF_instanceOf, gNavCenter->RDF_AutoOpen,
  1518.                 RDF_RESOURCE_TYPE, 1);
  1519.             if ((!openState) && (HT_IsContainerOpen(child)) &&
  1520.                 (!startsWith("ftp:", resourceID(child->node))) &&
  1521.                 (!startsWith("es:", resourceID(child->node))) &&
  1522.                 (!startsWith("ldap:", resourceID(child->node))))
  1523.             {
  1524.                 /* make assertion */
  1525.                 nlocalStoreAssert(gLocalStore, child->node,
  1526.                 gCoreVocab->RDF_instanceOf, gNavCenter->RDF_AutoOpen,
  1527.                 RDF_RESOURCE_TYPE, 1);
  1528.             }
  1529.             else if (openState && (!HT_IsContainerOpen(child)))
  1530.             {
  1531.                 /* remove assertion */
  1532.                 nlocalStoreUnassert(gLocalStore, child->node,
  1533.                 gCoreVocab->RDF_instanceOf, gNavCenter->RDF_AutoOpen,
  1534.                 RDF_RESOURCE_TYPE);
  1535.             }
  1536.         }
  1537.         if (child->child)
  1538.         {
  1539.             tmp=child->next;
  1540.             destroyViewInt(child, saveOpenState);
  1541.             if(child != NULL)
  1542.             {
  1543.                 deleteHTNode(child);
  1544.             }
  1545.             child = tmp;
  1546.         }
  1547.         else
  1548.         {
  1549.             tmp = child;
  1550.             child = child->next;
  1551.             deleteHTNode(tmp);
  1552.         }
  1553.     }
  1554.     r->child = NULL;
  1555.     r->numChildren = 0;
  1556.     r->numChildrenTotal = 0;
  1557. }
  1558.  
  1559.  
  1560.  
  1561. PR_PUBLIC_API(HT_Error)
  1562. HT_DeleteView (HT_View view)
  1563. {
  1564.     HT_Column        column, nextColumn;
  1565.     HT_View            *viewList;
  1566.     HT_Pane            pane;
  1567.     HT_Resource        **r;
  1568.     uint32            loop, viewIndex;
  1569.  
  1570.     XP_ASSERT(view != NULL);
  1571.  
  1572.     if (view->top != NULL)                    /* delete nodes */
  1573.     {
  1574.         destroyViewInt(view->top, PR_TRUE);
  1575.     }
  1576.     if (view->itemList != NULL)                /* delete itemList */
  1577.     {
  1578.         for (loop=0; loop<view->itemListSize; loop++)
  1579.         {
  1580.             if ((r = (HT_Resource **)view->itemList[loop]) != NULL)
  1581.             {
  1582.                 freeMem(r);
  1583.             }
  1584.         }
  1585.         freeMem(view->itemList);
  1586.         view->itemList = NULL;
  1587.     }
  1588.  
  1589.     column = view->columns;                    /* delete columns */
  1590.     while (column != NULL)
  1591.     {
  1592.         nextColumn = column->next;
  1593.         if (column->name != NULL)
  1594.         {
  1595.             freeMem(column->name);
  1596.             column->name = NULL;
  1597.         }
  1598.         freeMem(column);
  1599.         column = nextColumn;
  1600.     }
  1601.     view->columns = NULL;
  1602.  
  1603.     pane = HT_GetPane(view);
  1604.     viewList = &(pane->viewList);
  1605.     while (*viewList)
  1606.     {
  1607.         if (*viewList == view)
  1608.         {
  1609.             viewIndex = HT_GetViewIndex(view);
  1610.             if (viewIndex > 0)    --viewIndex;
  1611.  
  1612.             *viewList = view->next;
  1613.             --(pane->viewListCount);
  1614.  
  1615.             /*
  1616.                 if deleting the selected view,
  1617.                 try and select another view
  1618.             */
  1619.  
  1620.             if ((gPaneDeletionMode != true) && (pane->selectedView == view))
  1621.             {
  1622.                 HT_SetSelectedView(pane, HT_GetNthView(pane, viewIndex));
  1623.             }
  1624.             break;
  1625.         }
  1626.         viewList = &((*viewList)->next);
  1627.     }
  1628.  
  1629.     sendNotification(view->top, HT_EVENT_VIEW_DELETED);
  1630.     if (gPaneDeletionMode != true)
  1631.     {
  1632.         sendNotification(view->top, HT_EVENT_VIEW_WORKSPACE_REFRESH);
  1633.     }
  1634.     
  1635.     if (view->top != NULL)
  1636.     {
  1637.         deleteHTNode(view->top);
  1638.         view->top = NULL;
  1639.     }
  1640.  
  1641.     freeMem(view);
  1642.     return (HT_NoErr);
  1643. }
  1644.  
  1645.  
  1646.  
  1647. PR_PUBLIC_API(char *)
  1648. HT_GetViewName(HT_View view)
  1649. {
  1650.     char        *name = NULL;
  1651.  
  1652.     XP_ASSERT(view != NULL);
  1653.     XP_ASSERT(view->top != NULL);
  1654.  
  1655.     if (view != NULL)
  1656.     {
  1657.         HT_GetNodeData (view->top, gCoreVocab->RDF_name, HT_COLUMN_STRING, &name);
  1658.     }
  1659.     return(name);
  1660. }
  1661.  
  1662.  
  1663.  
  1664. void
  1665. saveWorkspaceOrder(HT_Pane pane)
  1666. {
  1667.     HT_View            view;
  1668.     uint32            viewListIndex=1, workspacePos;
  1669.  
  1670.     XP_ASSERT(pane != NULL);
  1671.     if (pane == NULL)    return;
  1672.  
  1673.     view = pane->viewList;
  1674.     while (view != NULL)
  1675.     {
  1676.         workspacePos = (uint32) RDF_GetSlotValue(gNCDB,
  1677.                     view->top->node,
  1678.                     gNavCenter->RDF_WorkspacePos,
  1679.                     RDF_INT_TYPE, false, true);
  1680.         RDF_Unassert(gNCDB, view->top->node,
  1681.                     gNavCenter->RDF_WorkspacePos,
  1682.                     (void *)&workspacePos, RDF_INT_TYPE);
  1683.         RDF_Assert(gNCDB, view->top->node,
  1684.                     gNavCenter->RDF_WorkspacePos,
  1685.                     (void *)&viewListIndex, RDF_INT_TYPE);
  1686.         ++viewListIndex;
  1687.         view = view->next;
  1688.     }
  1689. }
  1690.  
  1691.  
  1692.  
  1693. void
  1694. htDeletePane(HT_Pane pane, PRBool saveWorkspaceOrderFlag)
  1695. {
  1696.     HT_Pane            *paneList;
  1697.     HT_View            view;
  1698.  
  1699.     XP_ASSERT(pane != NULL);
  1700.     if (pane == NULL)    return;
  1701.  
  1702.     if (saveWorkspaceOrderFlag == PR_TRUE)
  1703.     {
  1704.         saveWorkspaceOrder(pane);
  1705.     }
  1706.     gPaneDeletionMode = true;
  1707.     while ((view = pane->viewList) != NULL)
  1708.     {
  1709.         HT_DeleteView(view);
  1710.     }
  1711.     gPaneDeletionMode = false;
  1712.     if (pane->hash != NULL)
  1713.     {
  1714.         PL_HashTableDestroy(pane->hash);            /* delete hash table */
  1715.         pane->hash = NULL;
  1716.     }
  1717.     if (pane->rns != NULL)
  1718.     {
  1719.         RDF_DeleteNotifiable (pane->rns);
  1720.         pane->rns = NULL;
  1721.     }
  1722.  
  1723.     paneList = &gHTTop;
  1724.     while ((*paneList) != NULL)
  1725.     {
  1726.         if ((*paneList) == pane)
  1727.         {
  1728.             (*paneList) = pane->next;
  1729.             break;
  1730.         }
  1731.         paneList = &(*paneList)->next;
  1732.     }
  1733.  
  1734.     freeMem(pane);
  1735. }
  1736.  
  1737.  
  1738.  
  1739. PR_PUBLIC_API(HT_Error)
  1740. HT_DeletePane (HT_Pane pane)
  1741. {
  1742.     XP_ASSERT(pane != NULL);
  1743.  
  1744.     htDeletePane(pane, PR_TRUE);
  1745.     return (HT_NoErr);
  1746. }
  1747.     
  1748.  
  1749.  
  1750. PR_PUBLIC_API(HT_Resource)
  1751. HT_TopNode (HT_View view)
  1752. {
  1753.     HT_Resource        top = NULL;
  1754.  
  1755.     XP_ASSERT(view != NULL);
  1756.  
  1757.     if (view != NULL)
  1758.     {
  1759.         top = view->top;
  1760.     }
  1761.  
  1762.     return (top);
  1763. }
  1764.  
  1765.  
  1766.  
  1767. void
  1768. resynchItem (HT_Resource node, void *token, void *data, PRBool assertAction)
  1769. {
  1770.     HT_Value        *value, tempValue;
  1771.  
  1772.     XP_ASSERT(node != NULL);
  1773.  
  1774.     value = &(node->values);
  1775.     while ((*value) != NULL)
  1776.     {
  1777.         if ((*value)->token == token)
  1778.         {
  1779.             if ((*value)->tokenType == HT_COLUMN_STRING ||
  1780.                 (*value)->tokenType == HT_COLUMN_DATE_STRING)
  1781.             {
  1782.                 
  1783.                 if ((*value)->data)
  1784.                 {
  1785.                     freeMem((*value)->data);
  1786.                     (*value)->data = NULL;
  1787.                 }
  1788.             }
  1789.  
  1790.             if ((assertAction == false) || (data == NULL))
  1791.             {
  1792.                 tempValue = (*value);
  1793.                 (*value) = (*value)->next;
  1794.                 freeMem(tempValue);
  1795.             }
  1796.             else if ((*value)->tokenType == HT_COLUMN_STRING ||
  1797.                 (*value)->tokenType == HT_COLUMN_DATE_STRING)
  1798.             {
  1799.                 
  1800.                 (*value)->data = copyString(data);
  1801.             }
  1802.             else
  1803.             {
  1804.                 (*value)->data = data;
  1805.             }
  1806.             break;
  1807.         }
  1808.         value = &((*value)->next);
  1809.     }
  1810. }
  1811.  
  1812.  
  1813.  
  1814. void
  1815. resynchContainer (HT_Resource container)
  1816. {
  1817.     HT_Resource        parent, tc, nc = NULL;
  1818.     RDF_Cursor        c;
  1819.     RDF_Resource        next;
  1820.     PRBool            found;
  1821.     uint32            n = 0;
  1822.  
  1823.     if ((c = RDF_GetSources(container->view->pane->db, container->node,
  1824.             gCoreVocab->RDF_parent, RDF_RESOURCE_TYPE, 1)) != NULL)
  1825.     {
  1826.         while (next = RDF_NextValue(c))
  1827.         {
  1828.             tc = container->child;
  1829.             found = 0;
  1830.             while (tc)
  1831.             {
  1832.                 if (tc->node == next)
  1833.                 {
  1834.                     tc->unsortedIndex = n;
  1835.                     found = 1;
  1836.                     break;
  1837.                 }
  1838.                 tc = tc->next;
  1839.             }
  1840.             if (!found)
  1841.             {
  1842.                 if ((nc = newHTEntry(container->view, next)) != NULL)
  1843.                 {
  1844.                     nc->dataSource = RDF_ValueDataSource(c);
  1845.                     nc->parent = container;
  1846.                     nc->next = container->child;
  1847.                     container->child = nc;
  1848.                     nc->depth = container->depth + 1;
  1849.                     ++container->numChildren;
  1850.                     nc->unsortedIndex = n;    /* container->numChildren; */
  1851.                     parent = container;
  1852.                     while (parent != NULL)
  1853.                     {
  1854.                         ++(parent->numChildrenTotal);
  1855.                         parent=parent->parent;
  1856.                     }
  1857.                 }
  1858.                 break;
  1859.             }
  1860.             ++n;
  1861.         }
  1862.         RDF_DisposeCursor(c);
  1863.     }
  1864.     if (nc != NULL)
  1865.     {
  1866.         refreshContainerIndexes(container);
  1867.         refreshItemList(nc, HT_EVENT_NODE_ADDED);
  1868.         if (gAutoEditNewNode == true)
  1869.         {
  1870.             gAutoEditNewNode = false;
  1871.             HT_SetSelection (nc);
  1872.             sendNotification(nc, HT_EVENT_NODE_EDIT);
  1873.         }
  1874.     }
  1875.     refreshItemList(container, HT_EVENT_VIEW_REFRESH);
  1876. }
  1877.  
  1878.  
  1879.  
  1880. void
  1881. refreshContainerIndexes(HT_Resource container)
  1882. {
  1883.     HT_Resource        child;
  1884.     RDF_Cursor        c;
  1885.     RDF_Resource        next;
  1886.     uint32            unsortedIndex=0;
  1887.  
  1888.     if (c = RDF_GetSources(container->view->pane->db, container->node,
  1889.               gCoreVocab->RDF_parent, RDF_RESOURCE_TYPE, 1))
  1890.     {
  1891.         while (next = RDF_NextValue(c))
  1892.         {
  1893.             child = container->child;
  1894.             while (child)
  1895.             {
  1896.                 if (child->node == next)
  1897.                 {
  1898.                     child->unsortedIndex = unsortedIndex;
  1899.                     break;
  1900.                 }
  1901.                 child = child->next;
  1902.             }
  1903.             ++unsortedIndex;
  1904.         } 
  1905.         RDF_DisposeCursor(c);
  1906.     }
  1907.  
  1908. }
  1909.  
  1910.   
  1911.  
  1912. HT_Resource
  1913. addContainerItem (HT_Resource container, RDF_Resource item)
  1914. {
  1915.     HT_Resource        nc, ch, parent;
  1916.     SBProvider        sb;
  1917.  
  1918.     if ((nc = newHTEntry(container->view, item)) != NULL)
  1919.     {
  1920.         ch = container->child;
  1921.         nc->view = container->view;
  1922.         nc->parent = container;
  1923.         nc->next = container->child;
  1924.         container->child = nc;
  1925.         nc->depth = container->depth + 1;
  1926.         ++container->numChildren;
  1927.  
  1928.         nc->unsortedIndex = container->numChildren;
  1929.         refreshContainerIndexes(container);
  1930.       
  1931.         parent = container;
  1932.         while (parent != NULL)
  1933.         {
  1934.             ++(parent->numChildrenTotal);
  1935.             parent=parent->parent;
  1936.         }
  1937.  
  1938.         sb = SBProviderOfNode(nc);
  1939.         if (sb && sb->openp)
  1940.         {
  1941.             nc->flags |= HT_OPEN_FLAG;
  1942.         }
  1943.         else
  1944.         {
  1945.             nc->flags &= (~HT_OPEN_FLAG);
  1946.         }
  1947.  
  1948.         refreshItemList(nc, HT_EVENT_NODE_ADDED);
  1949.         if (gAutoEditNewNode == true)
  1950.         {
  1951.             gAutoEditNewNode = false;
  1952.             HT_SetSelection (nc);
  1953.             sendNotification(nc, HT_EVENT_NODE_EDIT);
  1954.         }
  1955.     }
  1956.     return(nc);
  1957. }
  1958.  
  1959.  
  1960.  
  1961. void
  1962. removeHTFromHash (HT_Pane pane, HT_Resource item)
  1963. {
  1964.     HT_Resource        htr, pr;
  1965.     PLHashTable        *hash;
  1966.   
  1967.     hash    = pane->hash;
  1968.     htr   = PL_HashTableLookup(hash, item->node);
  1969.     pr = htr;
  1970.     while (htr != NULL)
  1971.     {
  1972.         if (htr == item)
  1973.         {
  1974.             if (pr == htr)
  1975.             {
  1976.                 if (htr->nextItem)
  1977.                 {
  1978.                     PL_HashTableAdd(hash, item->node,
  1979.                         htr->nextItem);
  1980.                 }
  1981.                 else
  1982.                 {
  1983.                     PL_HashTableRemove(hash, item->node);
  1984.                     RDF_ReleaseResource(pane->db, item->node);
  1985.                 }
  1986.             }
  1987.             else
  1988.             {
  1989.                 pr->nextItem = htr->nextItem;
  1990.             }
  1991.         }
  1992.     pr = htr;
  1993.     htr = htr->nextItem;
  1994.     }
  1995. }
  1996.  
  1997.  
  1998.  
  1999. void
  2000. deleteHTSubtree (HT_Resource subtree)
  2001. {
  2002.     HT_Resource        child, next;
  2003.  
  2004.     child = subtree->child;
  2005.     subtree->child = NULL;
  2006.     while (child)
  2007.     {
  2008.         next = child->next;
  2009.         if (HT_IsContainer(child))
  2010.         {
  2011.             deleteHTSubtree(child);
  2012.         }
  2013.         /* removeHTFromHash(child->view->pane, child); */
  2014.         deleteHTNode(child);
  2015.         child = next;
  2016.     }
  2017. }
  2018.  
  2019.  
  2020.  
  2021. void
  2022. deleteContainerItem (HT_Resource container, RDF_Resource item)
  2023. {
  2024.     HT_Resource        nc, pr, parent, nx = NULL;
  2025.  
  2026.     nc = container->child;
  2027.     pr = nc;
  2028.     while (nc != NULL)
  2029.     {
  2030.         if (nc->node == item)
  2031.         {
  2032.             nx = nc;
  2033.             /* removeHTFromHash(container->view->pane, nx); */
  2034.             if (nc == pr)
  2035.             {
  2036.                 container->child = nc->next;
  2037.             }
  2038.             else
  2039.             {
  2040.                 pr->next = nc->next;
  2041.             }
  2042.             break;
  2043.         }
  2044.     pr = nc;
  2045.     nc = nc->next;
  2046.     }
  2047.     if (nx == NULL) return;
  2048.     --container->numChildren;
  2049.   
  2050.     parent = container;
  2051.     while (parent != NULL)
  2052.     {
  2053.         --(parent->numChildrenTotal);
  2054.         parent=parent->parent;
  2055.     }
  2056.     if ((nx != NULL) && (HT_IsContainer(nx)))
  2057.     {
  2058.         deleteHTSubtree(nx);
  2059.     }
  2060.     if (nx)
  2061.     {
  2062.         deleteHTNode(nx);
  2063.     }
  2064.  
  2065.     if (gBatchUpdate != true)
  2066.     {
  2067.         refreshItemList(container, HT_EVENT_VIEW_REFRESH);
  2068.     }
  2069. }
  2070.  
  2071.  
  2072.  
  2073. char *
  2074. advertURLOfContainer (RDF r, RDF_Resource u)
  2075. {
  2076.     char            *url = NULL;
  2077.  
  2078.     url = RDF_GetSlotValue(r, u,  gNavCenter->RDF_HTMLURL,
  2079.                 RDF_STRING_TYPE, 0, 1);
  2080.  
  2081. #ifndef    DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  2082.     if (url != NULL)
  2083.     {
  2084.         url = copyString(url);
  2085.     }
  2086. #endif
  2087.  
  2088.     return(url);
  2089. }
  2090.  
  2091.  
  2092.  
  2093. uint32
  2094. fillContainer (HT_Resource node)
  2095. {
  2096.     HT_Resource        pr = NULL, rn;
  2097.     RDF_Cursor        c;
  2098.     RDF_Resource        next;
  2099.     uint32            numElements=0;
  2100.     char            *advertURL;
  2101.  
  2102.     XP_ASSERT(node != NULL);
  2103.     XP_ASSERT(node->view != NULL);
  2104.     XP_ASSERT(node->view->pane != NULL);
  2105.     XP_ASSERT(node->view->pane->db != NULL);
  2106.  
  2107. #ifdef WIN32
  2108.     advertURL = RDF_GetSlotValue (node->view->pane->db, node->node, 
  2109.                        gNavCenter->RDF_HTMLURL, RDF_STRING_TYPE, 0, 1);
  2110. #endif
  2111.  
  2112.     if ((c = RDF_GetSources(node->view->pane->db, node->node, 
  2113.                 gCoreVocab->RDF_parent,
  2114.                 RDF_RESOURCE_TYPE,  true)) != NULL)
  2115.     {
  2116.         while (next = RDF_NextValue(c))
  2117.         {
  2118.             if ((rn = newHTEntry(node->view, next)) == NULL)
  2119.                 break;
  2120.             rn->dataSource = RDF_ValueDataSource(c);
  2121.             rn->parent = node;
  2122.             rn->unsortedIndex = numElements++;
  2123.             rn->depth = node->depth+1;
  2124.             if (pr == NULL)
  2125.             {
  2126.                 node->child = rn;
  2127.             }
  2128.             else
  2129.             {
  2130.                 pr->next = rn;
  2131.             }
  2132.             pr = rn;
  2133.         }
  2134. #ifdef WIN32
  2135.         if (advertURL) XP_GetURLForView(node->view, advertURL);
  2136. #endif
  2137.         RDF_DisposeCursor(c);
  2138.     }
  2139.     return(numElements);
  2140. }
  2141.  
  2142.  
  2143.  
  2144. PR_PUBLIC_API(HT_Cursor)
  2145. HT_NewCursor (HT_Resource node)
  2146. {
  2147.     HT_Cursor        c;
  2148.  
  2149.     XP_ASSERT(node != NULL);
  2150.     XP_ASSERT(node->view != NULL);
  2151.  
  2152.     if ((node==NULL) || (!HT_IsContainer(node)))
  2153.     {
  2154.         return(NULL);
  2155.     }
  2156.     if (!HT_IsContainerOpen(node))
  2157.     {
  2158.         /* determine if container should be auto opened */
  2159.  
  2160.         if (node->view->inited == PR_TRUE)        return(NULL);
  2161.         if (node->view->pane->special == PR_TRUE)    return(NULL);
  2162.         if (nlocalStoreHasAssertion(gLocalStore, node->node,
  2163.             gCoreVocab->RDF_instanceOf, gNavCenter->RDF_AutoOpen,
  2164.             RDF_RESOURCE_TYPE, 1))
  2165.         {
  2166.             node->flags |= HT_OPEN_FLAG;
  2167.         }
  2168.         else
  2169.         {
  2170.             return(NULL);
  2171.         }
  2172.     }
  2173.  
  2174.     if ((c = (HT_Cursor)getMem(sizeof(HT_CursorStruct))) != NULL)
  2175.     {
  2176.         c->container = node;
  2177.         if (node->child != NULL)
  2178.         {
  2179.             c->node = node->child;
  2180.             c->numElements = node->numChildren;
  2181.         }
  2182.         else
  2183.         {
  2184.             c->numElements = fillContainer(node);
  2185.             c->node = node->child;
  2186.         }
  2187.     }
  2188.     return(c);
  2189. }
  2190.  
  2191.  
  2192.  
  2193. PR_PUBLIC_API(HT_Cursor)
  2194. HT_NewColumnCursor (HT_View view)
  2195. {
  2196.     HT_Cursor        cursor;
  2197.  
  2198.     XP_ASSERT(view != NULL);
  2199.  
  2200.     if ((cursor = (HT_Cursor)getMem(sizeof(HT_CursorStruct))) != NULL)
  2201.     {
  2202.         cursor->columns = view->columns;
  2203.     }
  2204.     return(cursor);
  2205. }
  2206.  
  2207.  
  2208.  
  2209. PR_PUBLIC_API(PRBool)
  2210. HT_GetNextColumn(HT_Cursor cursor, char **colName, uint32 *colWidth,
  2211.         void **token, uint32 *tokenType)
  2212. {
  2213.     HT_Column        column;
  2214.  
  2215.     XP_ASSERT(cursor != NULL);
  2216.  
  2217.     if ((column = cursor->columns) == NULL)    return(false);
  2218.  
  2219.     if (colName != NULL)    *colName = column->name;
  2220.     if (colWidth != NULL)    *colWidth = column->width;
  2221.     if (token != NULL)    *token = column->token;
  2222.     if (tokenType != NULL)    *tokenType = column->tokenType;
  2223.  
  2224.     cursor->columns = column->next;
  2225.     return(true);
  2226. }
  2227.  
  2228.  
  2229.  
  2230. PR_PUBLIC_API(void)
  2231. HT_DeleteColumnCursor(HT_Cursor cursor)
  2232. {
  2233.     XP_ASSERT(cursor != NULL);
  2234.  
  2235.     freeMem(cursor);
  2236. }
  2237.  
  2238.  
  2239.  
  2240. PR_PUBLIC_API(void)
  2241. HT_SetColumnOrder(HT_View view, void *srcColToken, void *destColToken, PRBool afterDestFlag)
  2242. {
  2243.     HT_Column    *columnList, *srcCol = NULL, *destCol = NULL;
  2244.  
  2245.     XP_ASSERT(view != NULL);
  2246.     XP_ASSERT(srcColToken != NULL);
  2247.     XP_ASSERT(destColToken != NULL);
  2248.  
  2249.     if (columnList = &(view->columns))
  2250.     {
  2251.         while ((*columnList) != NULL)
  2252.         {
  2253.             if ((*columnList)->token == srcColToken)
  2254.             {
  2255.                 srcCol = columnList;
  2256.             }
  2257.             else if ((*columnList)->token == destColToken)
  2258.             {
  2259.                 destCol = columnList;
  2260.             }
  2261.             columnList = &((*columnList)->next);
  2262.         }
  2263.         if ((srcCol != NULL) && (destCol != NULL))
  2264.         {
  2265.             *srcCol = (*srcCol)->next;
  2266.             if (afterDestFlag == TRUE)
  2267.             {
  2268.                 (*srcCol)->next = (*destCol)->next;
  2269.                 (*destCol)->next = *srcCol;
  2270.             }
  2271.             else
  2272.             {
  2273.                 (*srcCol)->next = *destCol;
  2274.                 *destCol = *srcCol;
  2275.             }
  2276.         }
  2277.     }
  2278. }
  2279.  
  2280.  
  2281.  
  2282. PR_PUBLIC_API(void)
  2283. HT_SetSortColumn(HT_View view, void *token, uint32 tokenType, PRBool descendingFlag)
  2284. {
  2285.     XP_ASSERT(view != NULL);
  2286.  
  2287.     view->sortToken = token;
  2288.     view->sortTokenType = tokenType;
  2289.     view->descendingFlag = descendingFlag;
  2290.     refreshItemList(view->top, HT_EVENT_VIEW_SORTING_CHANGED);
  2291. }
  2292.  
  2293.  
  2294.  
  2295. PR_PUBLIC_API(PRBool)
  2296. HT_ContainerSupportsNaturalOrderSort(HT_Resource container)
  2297. {
  2298.     HT_Resource    parent;
  2299.     PRBool        naturalOrder = PR_FALSE;
  2300.  
  2301.     if (container != NULL && HT_IsContainer(container))
  2302.     {
  2303.         if (container->node == gNavCenter->RDF_BookmarkFolderCategory)
  2304.         {
  2305.             naturalOrder = PR_TRUE;
  2306.         }
  2307.         else
  2308.         {
  2309.             parent = container->parent;
  2310.             if (parent != NULL)
  2311.             {
  2312.                 naturalOrder = nlocalStoreHasAssertion(gLocalStore, container->node,
  2313.                     gCoreVocab->RDF_parent, parent->node, RDF_RESOURCE_TYPE, 1);
  2314.             }
  2315.         }
  2316.     }
  2317.     return (naturalOrder);
  2318. }
  2319.  
  2320.  
  2321.  
  2322. PR_PUBLIC_API(HT_Error)
  2323. HT_DeleteCursor (HT_Cursor cursor)
  2324. {
  2325.     XP_ASSERT(cursor != NULL);
  2326.  
  2327.     if (cursor != NULL)
  2328.     {
  2329.         freeMem(cursor);
  2330.     }
  2331.     return(HT_NoErr);
  2332. }
  2333.  
  2334.  
  2335.  
  2336. PR_PUBLIC_API(HT_Resource)
  2337. HT_GetNextItem (HT_Cursor cursor)
  2338. {
  2339.     HT_Resource        ans = NULL;
  2340.  
  2341.     XP_ASSERT(cursor != NULL);
  2342.  
  2343.     if (cursor != NULL)
  2344.     {
  2345.         if ((ans = cursor->node) != NULL)
  2346.         {
  2347.             cursor->node = ans->next;
  2348.         }
  2349.     }
  2350.     return(ans);
  2351. }
  2352.  
  2353.  
  2354.  
  2355. HT_MenuCmd
  2356. menus[] = {
  2357.     HT_CMD_OPEN_NEW_WIN,
  2358.     HT_CMD_OPEN_COMPOSER,
  2359.     HT_CMD_SEPARATOR,
  2360.  
  2361.     HT_CMD_OPEN,
  2362.     HT_CMD_OPEN_AS_WORKSPACE,
  2363.     HT_CMD_OPEN_FILE,
  2364.     HT_CMD_PRINT_FILE,
  2365.     HT_CMD_REVEAL_FILEFOLDER,
  2366.     HT_CMD_SEPARATOR,
  2367.  
  2368.     HT_CMD_NEW_BOOKMARK,
  2369.     HT_CMD_NEW_FOLDER,
  2370.     HT_CMD_NEW_SEPARATOR,
  2371.     HT_CMD_MAKE_ALIAS,
  2372.     HT_CMD_ADD_TO_BOOKMARKS,
  2373.     HT_CMD_SAVE_AS,    
  2374.     HT_CMD_CREATE_SHORTCUT,    
  2375.     HT_CMD_EXPORT,
  2376.     HT_CMD_EXPORTALL,
  2377.     HT_CMD_RENAME,
  2378.  
  2379. #ifdef    HT_PASSWORD_RTNS
  2380.     HT_CMD_SET_PASSWORD,
  2381.     HT_CMD_REMOVE_PASSWORD,
  2382. #endif
  2383.  
  2384.     HT_CMD_SEPARATOR,
  2385.  
  2386.     HT_CMD_SET_TOOLBAR_FOLDER,
  2387.     HT_CMD_SET_BOOKMARK_MENU,
  2388.     HT_CMD_REMOVE_BOOKMARK_MENU,
  2389.     HT_CMD_SET_BOOKMARK_FOLDER,
  2390.     HT_CMD_REMOVE_BOOKMARK_FOLDER,
  2391.     HT_CMD_SEPARATOR,
  2392.  
  2393.     HT_CMD_CUT,
  2394.     HT_CMD_COPY,
  2395.     HT_CMD_PASTE,
  2396.     HT_CMD_UNDO,
  2397.     HT_CMD_DELETE_FILE,
  2398.     HT_CMD_DELETE_FOLDER,
  2399.     HT_CMD_SEPARATOR,
  2400.  
  2401.     HT_CMD_REFRESH,    
  2402.     HT_CMD_PROPERTIES,
  2403.     HT_CMD_SEPARATOR,
  2404.  
  2405.     HT_CMD_NEW_WORKSPACE,
  2406.     HT_CMD_RENAME_WORKSPACE,
  2407.     HT_CMD_DELETE_WORKSPACE,
  2408.     HT_CMD_MOVE_WORKSPACE_UP,
  2409.     HT_CMD_MOVE_WORKSPACE_DOWN,
  2410.  
  2411.     HT_CMD_SEPARATOR,
  2412.     /* commands from the graph appear at the end */
  2413.     -1,
  2414. };
  2415.  
  2416.  
  2417.  
  2418. /* obsolete/old; use HT_NewContextualMenuCursor instead */
  2419.  
  2420. PR_PUBLIC_API(HT_Cursor)
  2421. HT_NewContextMenuCursor (HT_Resource node)
  2422. {
  2423.     HT_Cursor        cursor;
  2424.  
  2425.     XP_ASSERT(node != NULL);
  2426.  
  2427.     if ((cursor = (HT_Cursor)getMem(sizeof(HT_CursorStruct))) != NULL)
  2428.     {
  2429.         cursor->node = node;
  2430.         cursor->contextMenuIndex = 0;
  2431.         cursor->commandExtensions = PR_FALSE;
  2432.         if (node != NULL)
  2433.         {
  2434.             cursor->isWorkspaceFlag = ((node->parent == NULL) ? true:false);
  2435.         }
  2436.         else
  2437.         {
  2438.             cursor->isWorkspaceFlag = false;
  2439.         }
  2440.     }
  2441.     return(cursor);
  2442. }
  2443.  
  2444.  
  2445.  
  2446. PR_PUBLIC_API(HT_Cursor)
  2447. HT_NewContextualMenuCursor (HT_View view, PRBool workspaceMenuCmds, PRBool backgroundMenuCmds)
  2448. {
  2449.     HT_Cursor        cursor;
  2450.  
  2451.     if ((cursor = (HT_Cursor)getMem(sizeof(HT_CursorStruct))) != NULL)
  2452.     {
  2453.         cursor->node = (view != NULL) ? view->top : NULL;
  2454.         cursor->contextMenuIndex = 0;
  2455.         cursor->isWorkspaceFlag = workspaceMenuCmds;
  2456.         cursor->isBackgroundFlag = backgroundMenuCmds;
  2457.         cursor->commandExtensions = PR_FALSE;
  2458.     }
  2459.     return(cursor);
  2460. }
  2461.  
  2462.  
  2463.  
  2464. PRBool
  2465. htIsMenuCmdEnabled(HT_Pane pane, HT_MenuCmd menuCmd,
  2466.         PRBool isWorkspaceFlag, PRBool isBackgroundFlag)
  2467. {
  2468.     HT_Resource        node, nextNode;
  2469.     HT_View            *viewList;
  2470.     PRBool            multSelection = false, enableFlag = false;
  2471.     XP_Bool            mcEnabled = false;
  2472.     RDF_BT            type;
  2473.     RDF_Resource        bmFolder, nbFolder, ptFolder, rNode;
  2474.     int16            menuIndex;
  2475.  
  2476.     if (menuCmd == HT_CMD_SEPARATOR)    return(false);
  2477.  
  2478.     menuIndex=0;
  2479.     while (menus[menuIndex] >=0)
  2480.     {
  2481.         if (menus[menuIndex] == menuCmd)
  2482.         {
  2483.             break;
  2484.         }
  2485.         ++menuIndex;
  2486.     }
  2487.     /*
  2488.     if (menus[menuIndex] < 0)    return(false);
  2489.     */
  2490.  
  2491.     if (isWorkspaceFlag == true || isBackgroundFlag == true)
  2492.     {
  2493.         node = NULL;
  2494.         nextNode = NULL;
  2495.     }
  2496.     else
  2497.     {
  2498.         if ((node = HT_GetNextSelection(pane->selectedView, NULL)) == NULL)
  2499.         {
  2500.             return(false);
  2501.         }
  2502.         if ((nextNode = HT_GetNextSelection(pane->selectedView, node)) != NULL)
  2503.         {
  2504.             multSelection = true;
  2505.         }
  2506.     }
  2507.  
  2508.     do
  2509.     {
  2510.         if (node != NULL)
  2511.         {
  2512.             if ((rNode = node->node) == NULL)    return(false);
  2513.  
  2514.             if (HT_IsContainer(node))
  2515.             {
  2516.                 type = resourceType(rNode);
  2517.             }
  2518.             else
  2519.             {
  2520.                 type = resourceType(node->parent->node);
  2521.             }
  2522.         }
  2523.  
  2524.         switch(menus[menuIndex])
  2525.         {
  2526.             case    HT_CMD_OPEN:
  2527.             if (node == NULL)            return(false);
  2528.             if (!HT_IsContainer(node))        return(false);
  2529.             if (node->view->pane->personaltoolbar == true)
  2530.                                 return(false);
  2531.             break;
  2532.  
  2533.             case    HT_CMD_OPEN_FILE:
  2534.             if (node == NULL)            return(false);
  2535.             if (HT_IsContainer(node))        return(false);
  2536.             if (resourceType(node->node) != LFS_RT)    return(false);
  2537.             break;
  2538.  
  2539.             case    HT_CMD_PRINT_FILE:
  2540.             if (node == NULL)            return(false);
  2541.             if (HT_IsContainer(node))        return(false);
  2542.             if (resourceType(node->node) != LFS_RT)    return(false);
  2543.             break;
  2544.  
  2545.             case    HT_CMD_OPEN_NEW_WIN:
  2546.             if (node == NULL)            return(false);
  2547.             if (HT_IsContainer(node))        return(false);
  2548.             if (HT_IsSeparator(node))        return(false);
  2549.             if (resourceType(node->node) == LFS_RT)    return(false);
  2550.             break;
  2551.  
  2552.             case    HT_CMD_OPEN_COMPOSER:
  2553. #ifdef EDITOR
  2554.             if (node == NULL)            return(false);
  2555.             if (HT_IsContainer(node))        return(false);
  2556.             if (HT_IsSeparator(node))        return(false);
  2557.             if (resourceType(node->node) == LFS_RT)    return(false);
  2558.  
  2559.             /*
  2560.                 XXX to do
  2561.             
  2562.                 Composer needs to expose a routine similar
  2563.                 to FE_MakeNewWindow() for opening a URL in
  2564.                 an editor window
  2565.             */
  2566.             return(false);
  2567. #else
  2568.             return(false);
  2569. #endif /* EDITOR */
  2570.             break;
  2571.  
  2572.             case    HT_CMD_NEW_WORKSPACE:
  2573.             if (!isWorkspaceFlag)            return(false);
  2574.             break;
  2575.  
  2576.             case    HT_CMD_OPEN_AS_WORKSPACE:
  2577.             if (node == NULL)            return(false);
  2578.             if (!HT_IsContainer(node))        return(false);
  2579.             if (htIsOpLocked(node, gNavCenter->RDF_CopyLock))
  2580.                                 return(false);
  2581.             break;
  2582.  
  2583.             case    HT_CMD_NEW_BOOKMARK:
  2584.             if (node == NULL)
  2585.             {
  2586.                 if (pane == NULL)        return(false);
  2587.                 node = HT_TopNode(pane->selectedView);
  2588.             }
  2589.             else
  2590.             {
  2591.                 if (!HT_IsLocalData(node))    return(false);
  2592.             }
  2593.             if (node == NULL)            return(false);
  2594.             if (resourceType(node->node) != RDF_RT)    return(false);
  2595.             if (multSelection == true)        return(false);
  2596.             if (!HT_IsContainer(node))
  2597.             {
  2598.                 if (node->view->pane->personaltoolbar == true)
  2599.                                 return(false);
  2600.             }
  2601.             if (htIsOpLocked(node, gNavCenter->RDF_AddLock))
  2602.                                 return(false);
  2603.             break;
  2604.  
  2605.             case    HT_CMD_NEW_FOLDER:
  2606.             if (node == NULL)
  2607.             {
  2608.                 if (pane == NULL)        return(false);
  2609.                 node = HT_TopNode(pane->selectedView);
  2610.             }
  2611.             else
  2612.             {
  2613.                 if (!HT_IsLocalData(node))    return(false);
  2614.             }
  2615.             if (node == NULL)            return(false);
  2616.             if (resourceType(node->node) != RDF_RT)    return(false);
  2617.             if (multSelection == true)        return(false);
  2618.             if (!HT_IsContainer(node))
  2619.             {
  2620.                 if (node->view->pane->personaltoolbar == true)
  2621.                                 return(false);
  2622.             }
  2623.             if (htIsOpLocked(node, gNavCenter->RDF_AddLock))
  2624.                                 return(false);
  2625.             break;
  2626.  
  2627.             case    HT_CMD_NEW_SEPARATOR:
  2628.             if (node == NULL)
  2629.             {
  2630.                 if (pane == NULL)        return(false);
  2631.                 node = HT_TopNode(pane->selectedView);
  2632.             }
  2633.             else
  2634.             {
  2635.                 if (!HT_IsLocalData(node))    return(false);
  2636.             }
  2637.             if (node == NULL)            return(false);
  2638.             if (resourceType(node->node) != RDF_RT)    return(false);
  2639.             if (multSelection == true)        return(false);
  2640.             if (!HT_IsContainer(node))
  2641.             {
  2642.                 if (node->view->pane->personaltoolbar == true)
  2643.                                 return(false);
  2644.             }
  2645.             if (htIsOpLocked(node, gNavCenter->RDF_AddLock))
  2646.                                 return(false);
  2647.             break;
  2648.  
  2649.             case    HT_CMD_MAKE_ALIAS:
  2650.             if (node == NULL)            return(false);
  2651.             if (resourceType(node->node) != LFS_RT)    return(false);
  2652.             break;
  2653.  
  2654.             case    HT_CMD_ADD_TO_BOOKMARKS:
  2655.             if (node == NULL)            return(false);
  2656.             if (multSelection == true)        return(false);
  2657.             if ((bmFolder = RDFUtil_GetQuickFileFolder()) == NULL)
  2658.                                 return(false);
  2659.             if (HT_IsContainer(node))
  2660.             {
  2661.                 if (node->node == bmFolder)    return(false);
  2662.             }
  2663.             else
  2664.             {
  2665.                 if (node->parent->node == bmFolder)
  2666.                                 return(false);
  2667.             }
  2668.             if (htIsOpLocked(node, gNavCenter->RDF_CopyLock))
  2669.                                 return(false);
  2670.             break;
  2671.  
  2672.             case    HT_CMD_SAVE_AS:
  2673.             if (node == NULL)            return(false);
  2674.             if (HT_IsContainer(node))        return(false);
  2675.             if (HT_IsSeparator(node))        return(false);
  2676.             if (resourceType(node->node) != RDF_RT)    return(false);
  2677.             break;
  2678.  
  2679.             case    HT_CMD_CREATE_SHORTCUT:
  2680.             if (node == NULL)            return(false);
  2681.             if (HT_IsContainer(node))        return(false);
  2682.             if (HT_IsSeparator(node))        return(false);
  2683.             break;
  2684.  
  2685.             case    HT_CMD_SET_TOOLBAR_FOLDER:
  2686.             if (multSelection == true)        return(false);
  2687.             if (node == NULL)            return(false);
  2688.             if (!HT_IsContainer(node))        return(false);
  2689.             if (resourceType(node->node) != RDF_RT)    return(false);
  2690.             if ((ptFolder = RDFUtil_GetPTFolder()) == NULL)
  2691.                                 return(false);
  2692.             if (node->node == ptFolder)        return(false);
  2693.             if (node->view->pane->personaltoolbar == true)
  2694.                                 return(false);
  2695.             if (!HT_IsLocalData(node))        return(false);
  2696.             break;
  2697.  
  2698.             case    HT_CMD_SET_BOOKMARK_MENU:
  2699.             if (multSelection == true)        return(false);
  2700.             if (node == NULL)            return(false);
  2701.             if (!HT_IsContainer(node))        return(false);
  2702.             if (resourceType(node->node) != RDF_RT)    return(false);
  2703.             if ((bmFolder = RDFUtil_GetQuickFileFolder()) == NULL)
  2704.                                 return(false);
  2705.             if (node->node == bmFolder)        return(false);
  2706.             if (!HT_IsLocalData(node))        return(false);
  2707.             break;
  2708.  
  2709.             case    HT_CMD_REMOVE_BOOKMARK_MENU:
  2710.             if (multSelection == true)        return(false);
  2711.             if (node == NULL)            return(false);
  2712.             if (!HT_IsContainer(node))        return(false);
  2713.             if (resourceType(node->node) != RDF_RT)    return(false);
  2714.             if ((bmFolder = RDFUtil_GetQuickFileFolder()) == NULL)
  2715.                                 return(false);
  2716.             if (node->node != bmFolder)        return(false);
  2717.             break;
  2718.  
  2719.             case    HT_CMD_SET_BOOKMARK_FOLDER:
  2720.             if (multSelection == true)        return(false);
  2721.             if (node == NULL)            return(false);
  2722.             if (!HT_IsContainer(node))        return(false);
  2723.             if (resourceType(node->node) != RDF_RT)    return(false);
  2724.             if ((nbFolder = RDFUtil_GetNewBookmarkFolder()) == NULL)
  2725.                                 return(false);
  2726.             if (node->node == nbFolder)        return(false);
  2727.             if (!HT_IsLocalData(node))        return(false);
  2728.             break;
  2729.  
  2730.             case    HT_CMD_REMOVE_BOOKMARK_FOLDER:
  2731.             if (multSelection == true)        return(false);
  2732.             if (node == NULL)            return(false);
  2733.             if (!HT_IsContainer(node))        return(false);
  2734.             if (resourceType(node->node) != RDF_RT)    return(false);
  2735.             if ((nbFolder = RDFUtil_GetNewBookmarkFolder()) == NULL)
  2736.                                 return(false);
  2737.             if (node->node != nbFolder)        return(false);
  2738.             break;
  2739.  
  2740.             case    HT_CMD_CUT:
  2741.             if (node == NULL)            return(false);
  2742.             if (node->parent == NULL)        return(false);
  2743.             if (node->parent->node == NULL)        return(false);
  2744.             if ((resourceType(node->parent->node) != RDF_RT) &&
  2745.                 (resourceType(node->parent->node) != HISTORY_RT))
  2746.                                 return(false);
  2747.             if (HT_IsContainer(node))
  2748.             {
  2749.                 if (node->node == gNavCenter->RDF_HistoryBySite ||
  2750.                     node->node == gNavCenter->RDF_HistoryByDate)
  2751.                                     return(false);
  2752.                 if ((ptFolder = RDFUtil_GetPTFolder()) != NULL)
  2753.                 {
  2754.                     if (node->node == ptFolder)
  2755.                                 return(false);
  2756.                 }
  2757.                 if ((bmFolder = RDFUtil_GetNewBookmarkFolder()) != NULL)
  2758.                 {
  2759.                     if (node->node == bmFolder)
  2760.                                 return(false);
  2761.                 }
  2762.             }
  2763.             if (htIsOpLocked(node, gNavCenter->RDF_DeleteLock))
  2764.                                 return(false);
  2765.             break;
  2766.  
  2767.             case    HT_CMD_COPY:
  2768.             if (node == NULL)            return(false);
  2769.             if (resourceType(node->node) != RDF_RT)    return(false);
  2770.             if (htIsOpLocked(node, gNavCenter->RDF_CopyLock))
  2771.                                 return(false);
  2772.             break;
  2773.  
  2774.             case    HT_CMD_PASTE:
  2775.             if (node == NULL)            return(false);
  2776.             if (!HT_IsContainer(node))        return(false);
  2777.             if (resourceType(node->node) != RDF_RT)    return(false);
  2778.             if (htIsOpLocked(node, gNavCenter->RDF_AddLock))
  2779.                                 return(false);
  2780.             break;
  2781.  
  2782.             case    HT_CMD_UNDO:
  2783.             return(false);
  2784.             break;
  2785.  
  2786.             case    HT_CMD_RENAME:
  2787.             if (node == NULL)            return(false);
  2788.             if (isWorkspaceFlag == true)        return(false);
  2789.             if (multSelection == true)        return(false);
  2790.             if (!HT_IsContainer(node))
  2791.             {
  2792.                 if (resourceType(node->parent->node) != RDF_RT)
  2793.                                 return(false);
  2794.             }
  2795.             else
  2796.             {
  2797.                 if (resourceType(node->node) != RDF_RT)
  2798.                                 return(false);
  2799.             }
  2800.             if (HT_IsSeparator(node))        return(false);
  2801.             if (htIsOpLocked(node, gNavCenter->RDF_NameLock))
  2802.                                 return(false);
  2803.             break;
  2804.  
  2805.             case    HT_CMD_DELETE_FILE:
  2806.             if (node == NULL)            return(false);
  2807.             type = resourceType(node->parent->node);
  2808.             if (type != LFS_RT && type != ES_RT && type != FTP_RT)
  2809.                                 return(false);
  2810.             if (HT_IsContainer(node))        return(false);
  2811.             break;
  2812.  
  2813.             case    HT_CMD_DELETE_FOLDER:
  2814.             if (node == NULL)            return(false);
  2815.             type = resourceType(node->node);
  2816.             if (type != LFS_RT && type != ES_RT && type != FTP_RT)
  2817.                                 return(false);
  2818.             if (!HT_IsContainer(node))        return(false);
  2819.             break;
  2820.  
  2821.             case    HT_CMD_REVEAL_FILEFOLDER:
  2822.             if (node == NULL)            return(false);
  2823. #ifdef    XP_MAC
  2824.             if (resourceType(node->node) != LFS_RT)    return(false);
  2825. #else
  2826.             return(false);
  2827. #endif
  2828.             break;
  2829.  
  2830.             case    HT_CMD_PROPERTIES:
  2831.             if (multSelection == true)        return(false);
  2832.             if (node == NULL)
  2833.             {
  2834.                 if (pane == NULL)        return(false);
  2835.                 node = HT_TopNode(pane->selectedView);
  2836.             }
  2837.             if (node != NULL)
  2838.             {
  2839.                 if (HT_IsSeparator(node))    return(false);
  2840.                 if (HT_IsContainer(node))
  2841.                 {
  2842.                     if (type == HISTORY_RT)    return(false);
  2843.                 }
  2844.             }
  2845.             break;
  2846.  
  2847.             case    HT_CMD_RENAME_WORKSPACE:
  2848.             if (!isWorkspaceFlag)            return(false);
  2849.             if (isBackgroundFlag == true)        return(false);
  2850.             if (pane == NULL)            return(false);
  2851.             if (pane->selectedView == NULL)        return(false);
  2852.             if (htIsOpLocked(pane->selectedView->top, gNavCenter->RDF_NameLock))
  2853.                                 return(false);
  2854.             break;
  2855.  
  2856.             case    HT_CMD_DELETE_WORKSPACE:
  2857.             if (!isWorkspaceFlag)            return(false);
  2858.             if (isBackgroundFlag == true)        return(false);
  2859.             if (pane == NULL)            return(false);
  2860.             if (pane->selectedView == NULL)        return(false);
  2861.             rNode = pane->selectedView->top->node;
  2862.             if (rNode == NULL)            return(false);
  2863.             if (rNode == gNavCenter->RDF_BookmarkFolderCategory ||
  2864.                 rNode == gNavCenter->RDF_LocalFiles ||
  2865.                 rNode == gNavCenter->RDF_History)
  2866.                                 return(false);
  2867.             if (htIsOpLocked(pane->selectedView->top, gNavCenter->RDF_DeleteLock))
  2868.                                 return(false);
  2869.             break;
  2870.  
  2871.             case    HT_CMD_MOVE_WORKSPACE_UP:
  2872.             if (isWorkspaceFlag == false)        return(false);
  2873.             if (isBackgroundFlag == true)        return(false);
  2874.             if (pane == NULL)            return(false);
  2875.             if (pane->selectedView == NULL)        return(false);
  2876.             if (pane->selectedView == pane->viewList)
  2877.                                 return(false);
  2878.             if (htIsOpLocked(pane->selectedView->top, gNavCenter->RDF_WorkspacePosLock))
  2879.                                 return(false);
  2880.             viewList = &(pane->viewList);
  2881.             while ((*viewList) != NULL)
  2882.             {
  2883.                 if ((*viewList)->next != NULL)
  2884.                 {
  2885.                     if ((*viewList)->next == pane->selectedView)
  2886.                     {
  2887.                         if (htIsOpLocked((*viewList)->top,
  2888.                             gNavCenter->RDF_WorkspacePosLock))
  2889.                         {
  2890.                             return(false);
  2891.                         }
  2892.                     }
  2893.                 }
  2894.                 viewList = &((*viewList)->next);
  2895.             }
  2896.             break;
  2897.  
  2898.             case    HT_CMD_MOVE_WORKSPACE_DOWN:
  2899.             if (isWorkspaceFlag == false)        return(false);
  2900.             if (isBackgroundFlag == true)        return(false);
  2901.             if (pane == NULL)            return(false);
  2902.             if (pane->selectedView == NULL)        return(false);
  2903.             if (pane->selectedView->next == NULL)    return(false);
  2904.             if (htIsOpLocked(pane->selectedView->top, gNavCenter->RDF_WorkspacePosLock))
  2905.                                 return(false);
  2906.             break;
  2907.  
  2908.             case    HT_CMD_REFRESH:
  2909.             if (node == NULL)
  2910.             {
  2911.                 if (pane == NULL)        return(false);
  2912.                 node = HT_TopNode(pane->selectedView);
  2913.             }
  2914.             if (node != NULL)
  2915.             {
  2916.                 if (!HT_IsContainer(node))    return(false);
  2917.             }
  2918.             break;
  2919.  
  2920.             case    HT_CMD_EXPORT:
  2921.             if (isBackgroundFlag == true)        return(false);
  2922.             if (node == NULL)
  2923.             {
  2924.                 if (pane == NULL)        return(false);
  2925.                 if (pane->selectedView == NULL)    return(false);
  2926.                 node = HT_TopNode(pane->selectedView);
  2927.             }
  2928.             if (node == NULL)            return(false);
  2929.             if (!HT_IsContainer(node))        return(false);
  2930.             if (resourceType(node->node) == LFS_RT)    return(false);
  2931.             if (htIsOpLocked(node, gNavCenter->RDF_CopyLock))
  2932.                                 return(false);
  2933.             break;
  2934.  
  2935.             case    HT_CMD_EXPORTALL:
  2936.             if (isWorkspaceFlag == false)            return(false);
  2937.             if (isBackgroundFlag == true)            return(false);
  2938.             if (!gMissionControlEnabled)            return(false);
  2939.             break;
  2940.  
  2941. #ifdef    HT_PASSWORD_RTNS
  2942.  
  2943.             case    HT_CMD_SET_PASSWORD:
  2944.             if (multSelection == true)            return(false);
  2945.             if (node == NULL)
  2946.             {
  2947.                 if (pane == NULL)            return(false);
  2948.                 node = HT_TopNode(pane->selectedView);
  2949.             }
  2950.             if (node != NULL)
  2951.             {
  2952.                 if (!HT_IsContainer(node))        return(false);
  2953.             }
  2954.             break;
  2955.  
  2956.             case    HT_CMD_REMOVE_PASSWORD:
  2957.             if (multSelection == true)            return(false);
  2958.             if (node == NULL)
  2959.             {
  2960.                 if (pane == NULL)            return(false);
  2961.                 node = HT_TopNode(pane->selectedView);
  2962.             }
  2963.             if (node != NULL)
  2964.             {
  2965.                 if (!HT_IsContainer(node))        return(false);
  2966.                 if (ht_hasPassword(node) == PR_FALSE)    return(false);
  2967.             }
  2968.             break;
  2969.  
  2970. #endif
  2971.  
  2972.             default:
  2973.             /* process commands from the RDF graph last */
  2974.             return(true);
  2975.             break;
  2976.         }
  2977.  
  2978.         if (node != NULL)
  2979.         {
  2980.             
  2981.             node = nextNode;
  2982.             if (node == NULL)    break;
  2983.             if (pane == NULL)
  2984.             {
  2985.                 node = NULL;
  2986.                 break;
  2987.             }
  2988.             nextNode = HT_GetNextSelection(pane->selectedView, node);
  2989.         }
  2990.     } while (node != NULL);
  2991.     return(true);
  2992. }
  2993.  
  2994.  
  2995.  
  2996. PR_PUBLIC_API(PRBool)
  2997. HT_IsMenuCmdEnabled(HT_Pane pane, HT_MenuCmd menuCmd)
  2998. {
  2999.     return(htIsMenuCmdEnabled(pane, menuCmd, false, false));
  3000. }
  3001.  
  3002.  
  3003.  
  3004. PR_PUBLIC_API(PRBool)
  3005. HT_NextContextMenuItem (HT_Cursor cursor, HT_MenuCmd *menuCmd)
  3006. {
  3007.     HT_MenuCommand        *menuList;
  3008.     HT_Resource        node;
  3009.     RDF_Resource        graphCommand;
  3010.     PRBool            sepFlag = false, enableFlag = false;
  3011.     int16            menuIndex;
  3012.  
  3013.     XP_ASSERT(cursor != NULL);
  3014.     XP_ASSERT(menuCmd != NULL);
  3015.  
  3016.     if (cursor->commandExtensions == PR_FALSE)
  3017.     {
  3018.         /* process internal, well-known commands first */
  3019.  
  3020.         menuIndex = cursor->contextMenuIndex;
  3021.         while (menus[menuIndex] >= 0)
  3022.         {
  3023.             if (menus[menuIndex] == HT_CMD_SEPARATOR)
  3024.             {
  3025.                 if (cursor->foundValidMenuItem == true)
  3026.                 {
  3027.                     sepFlag = true; 
  3028.                 }
  3029.                 ++menuIndex;
  3030.                 continue;
  3031.             }
  3032.  
  3033.             node = cursor->node;
  3034.             enableFlag = htIsMenuCmdEnabled(
  3035.                     (node != NULL) ? node->view->pane : NULL,
  3036.                     menus[menuIndex],
  3037.                     cursor->isWorkspaceFlag,
  3038.                     cursor->isBackgroundFlag);
  3039.             if (enableFlag == false)
  3040.             {
  3041.                 ++menuIndex;
  3042.                 continue;
  3043.             }
  3044.  
  3045.             if (sepFlag == true)
  3046.             {
  3047.                 *menuCmd = HT_CMD_SEPARATOR;
  3048.                 cursor->contextMenuIndex = menuIndex;
  3049.             }
  3050.             else
  3051.             {
  3052.                 *menuCmd = menus[menuIndex];
  3053.                 cursor->contextMenuIndex = ++menuIndex;
  3054.                 cursor->foundValidMenuItem = true;
  3055.             }
  3056.             break;
  3057.         }
  3058.         if ((menus[menuIndex] == -1) && (node != NULL))
  3059.         {
  3060.             cursor->commandExtensions = PR_TRUE;
  3061.             cursor->container = NULL;
  3062.             cursor->foundValidMenuItem = false;
  3063.             cursor->menuCmd = NUM_MENU_CMDS+1;
  3064.  
  3065.             /* process commands from the RDF graph last */
  3066.             freeMenuCommandList();
  3067.             while (TRUE)
  3068.             {
  3069.                 if (cursor->cursor == NULL)
  3070.                 {
  3071.                     if ((cursor->container = HT_GetNextSelection(cursor->node->view, cursor->container)) != NULL)
  3072.                     {
  3073.                         cursor->cursor = RDF_GetSources(gNCDB, cursor->container->node,
  3074.                             gNavCenter->RDF_Command, RDF_RESOURCE_TYPE, 1);
  3075.                     }
  3076.                     else
  3077.                     {
  3078.                         cursor->menuCommandList = menuCommandsList;
  3079.                         break;
  3080.                     }
  3081.                 }
  3082.                 if (cursor->cursor == NULL)    break;
  3083.                 if ((graphCommand = RDF_NextValue(cursor->cursor)) != NULL)
  3084.                 {
  3085.                     /* add graph command at end of list, and only once */
  3086.  
  3087.                     menuList = &menuCommandsList;
  3088.                     while ((*menuList) != NULL)
  3089.                     {
  3090.                         if ((*menuList)->graphCommand == graphCommand)    break;
  3091.                         menuList = &((*menuList)->next);
  3092.                     }
  3093.                     if ((*menuList) == NULL)
  3094.                     {
  3095.                         if (((*menuList) = (HT_MenuCommand)getMem(sizeof(_HT_MenuCommandStruct))) != NULL)
  3096.                         {
  3097.                             cursor->foundValidMenuItem = true;
  3098.                             (*menuList)->menuCmd = cursor->menuCmd++;
  3099.                             (*menuList)->graphCommand = graphCommand;
  3100.                             (*menuList)->name = RDF_GetSlotValue(gNCDB, graphCommand,
  3101.                                     gCoreVocab->RDF_name, RDF_STRING_TYPE, false, true);
  3102. #ifndef    DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  3103.  
  3104.                             if ((*menuList)->name != NULL)
  3105.                             {
  3106.                                 (*menuList)->name = copyString((*menuList)->name);
  3107.                             }
  3108. #endif
  3109.                         }
  3110.                     }
  3111.                 }
  3112.                 else
  3113.                 {
  3114.                     RDF_DisposeCursor(cursor->cursor);
  3115.                     cursor->cursor = NULL;
  3116.                 }
  3117.             }
  3118.  
  3119.             if (cursor->foundValidMenuItem == true)
  3120.             {
  3121.                 cursor->foundValidMenuItem = false;
  3122.                 *menuCmd = HT_CMD_SEPARATOR;
  3123.                 enableFlag = true;
  3124.             }
  3125.  
  3126.         }
  3127.     }
  3128.     else
  3129.     {
  3130.         if (cursor->menuCommandList != NULL)
  3131.         {
  3132.             *menuCmd = cursor->menuCommandList->menuCmd;
  3133.             cursor->menuCommandList = cursor->menuCommandList->next;
  3134.             enableFlag = true;
  3135.         }
  3136.  
  3137.     }
  3138.     return(enableFlag);
  3139. }
  3140.  
  3141.  
  3142.  
  3143. PR_PUBLIC_API(void)
  3144. HT_DeleteContextMenuCursor(HT_Cursor cursor)
  3145. {
  3146.     XP_ASSERT(cursor != NULL);
  3147.  
  3148.     if (cursor != NULL)
  3149.     {
  3150.         freeMem(cursor);
  3151.     }
  3152. }
  3153.  
  3154.  
  3155.  
  3156. void
  3157. freeMenuCommandList()
  3158. {
  3159.     HT_MenuCommand        menuCommand;
  3160.  
  3161.     menuCommand = menuCommandsList;
  3162.     while (menuCommand != NULL)
  3163.     {
  3164.         if (menuCommand->name != NULL)    freeMem(menuCommand->name);
  3165.         menuCommand = menuCommand->next;
  3166.     }
  3167.     menuCommandsList = NULL;
  3168. }
  3169.  
  3170.  
  3171.  
  3172. PR_PUBLIC_API(char *)
  3173. HT_GetMenuCmdName(HT_MenuCmd menuCmd)
  3174. {
  3175.     HT_MenuCommand        menuCommand;
  3176.     char            *menuName = NULL;
  3177.  
  3178.     if (menuCmd < NUM_MENU_CMDS)
  3179.     {
  3180.         menuName = XP_GetString(RDF_CMD_0 + menuCmd);
  3181.     }
  3182.     else
  3183.     {
  3184.         menuCommand = menuCommandsList;
  3185.         while (menuCommand != NULL)
  3186.         {
  3187.             if (menuCommand->menuCmd == menuCmd)
  3188.             {
  3189.                 menuName = menuCommand->name;
  3190.                 break;
  3191.             }
  3192.             menuCommand = menuCommand->next;
  3193.         }
  3194.     }
  3195.     return(menuName);
  3196. }
  3197.  
  3198.  
  3199.  
  3200. void
  3201. exportCallbackWrite(PRFileDesc *fp, char *str)
  3202. {
  3203.     XP_ASSERT(fp != NULL);
  3204.  
  3205.     if (str != NULL)
  3206.     {
  3207.         PR_Write(fp, str, strlen(str));
  3208.     }
  3209. }
  3210.  
  3211.  
  3212.  
  3213. void
  3214. exportCallback(MWContext *context, char *filename, RDF_Resource node)
  3215. {
  3216.     PRFileDesc    *fp;
  3217.     char        *fileURL;
  3218.  
  3219.     XP_ASSERT(node != NULL);
  3220.  
  3221.     if (filename != NULL)
  3222.     {
  3223.  
  3224. #ifdef    XP_WIN
  3225.         fileURL = append2Strings("file:///", filename);
  3226. #else
  3227.         fileURL = append2Strings("file://", filename);
  3228. #endif
  3229.  
  3230.         if (fileURL != NULL)
  3231.         {
  3232.             if ((fp = CallPROpenUsingFileURL(fileURL,
  3233.                 (PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE),
  3234.                 0644)) != NULL)
  3235.             {
  3236.                 outputRDFTree(gNCDB, fp, node);
  3237.                 PR_Close(fp);
  3238.             }
  3239.             freeMem(fileURL);
  3240.         }
  3241.     }
  3242. }
  3243.  
  3244.  
  3245.  
  3246. PR_PUBLIC_API(HT_Error)
  3247. HT_DoMenuCmd(HT_Pane pane, HT_MenuCmd menuCmd)
  3248. {
  3249.     Chrome            chrome;
  3250.     HT_Error        error = 0;
  3251.     HT_MenuCommand        menuCommand;
  3252.     HT_Resource        node, topNode;
  3253.     HT_View            view, *viewList;
  3254.     RDF_Resource        rNode, newTopNode=NULL;
  3255.     URL_Struct        *urls;
  3256.     PRBool            needRefresh = false, openState, emptyClipboard = PR_TRUE, doAbout = PR_FALSE;
  3257.     PRBool            onlyUpdateBookmarks = false, onlyUpdatePersonalToolbar = false;
  3258.     uint32            uniqueCount=0;
  3259.     char            *title, *url;
  3260.  
  3261. #ifdef    HT_PASSWORD_RTNS
  3262.     char        *password1, *password2;
  3263. #endif
  3264.  
  3265.     XP_ASSERT(pane != NULL);
  3266.     view = HT_GetSelectedView(pane);
  3267.     XP_ASSERT(view != NULL);
  3268.  
  3269.     gBatchUpdate = true;
  3270.     switch(menuCmd)
  3271.     {
  3272.         case    HT_CMD_NEW_WORKSPACE:
  3273.         uniqueCount = 0;
  3274.         do
  3275.         {
  3276.             url = PR_smprintf("container%d.rdf",
  3277.                 (int)++uniqueCount);
  3278.             rNode = RDF_GetResource(pane->db, url, false);
  3279.             if ((rNode != NULL) && (url != NULL))
  3280.             {
  3281.                 XP_FREE(url);
  3282.                 url = NULL;
  3283.             }
  3284.         } while (rNode != NULL);
  3285.         if ((url != NULL) && (title = FE_Prompt(((MWContext *)gRDFMWContext()),
  3286.                 XP_GetString(RDF_NEWWORKSPACEPROMPT), "")) != NULL)
  3287.         {
  3288.             if (!strcmp(title, "about"))
  3289.             {
  3290.                 XP_FREE(title);
  3291.                 title = NULL;
  3292.                 XP_FREE(url);
  3293.                 url = PR_smprintf("http://people.netscape.com/rjc/about.rdf#root");
  3294.             }
  3295.             HT_NewWorkspace(pane, url, title);
  3296.         }
  3297.         if (title != NULL)
  3298.         {
  3299.             XP_FREE(title);
  3300.             title = NULL;
  3301.         }
  3302.         if (url != NULL)
  3303.         {
  3304.             XP_FREE(url);
  3305.             url = NULL;
  3306.         }
  3307.         break;
  3308.  
  3309.         case    HT_CMD_RENAME_WORKSPACE:
  3310.         if (view == NULL)    break;
  3311.         if ((topNode = HT_TopNode(view)) == NULL)    break;
  3312.         sendNotification(topNode, HT_EVENT_WORKSPACE_EDIT);
  3313.         break;
  3314.  
  3315.         case    HT_CMD_DELETE_WORKSPACE:
  3316.         if (view == NULL)    break;
  3317.         if ((topNode = HT_TopNode(view)) == NULL)    break;
  3318.         if (FE_Confirm(((MWContext *)gRDFMWContext()),
  3319.                 PR_smprintf(XP_GetString(RDF_DELETEWORKSPACE),
  3320.                 HT_GetViewName(topNode->view))))
  3321.         {
  3322.             RDF_AssertFalse(view->pane->db, topNode->node, gCoreVocab->RDF_parent,
  3323.                 gNavCenter->RDF_Top, RDF_RESOURCE_TYPE);
  3324.         }
  3325.         break;
  3326.  
  3327.         case    HT_CMD_MOVE_WORKSPACE_UP:
  3328.         viewList = &(pane->viewList);
  3329.         while (*viewList)
  3330.         {
  3331.             if ((*viewList)->next == view)
  3332.             {
  3333.                 HT_SetWorkspaceOrder(view, *viewList, FALSE);
  3334.                 break;
  3335.             }
  3336.             viewList = &((*viewList)->next);
  3337.         }
  3338.         break;
  3339.  
  3340.         case    HT_CMD_MOVE_WORKSPACE_DOWN:
  3341.         if (view->next != NULL)
  3342.         {
  3343.             HT_SetWorkspaceOrder(view, view->next, TRUE);
  3344.         }
  3345.         break;
  3346.  
  3347.         default:
  3348.         node = HT_GetNextSelection(view, NULL);
  3349.         do
  3350.         {
  3351.             switch(menuCmd)
  3352.             {
  3353.                 case    HT_CMD_OPEN:
  3354.                 if (node == NULL)    break;
  3355.                 HT_GetOpenState(node, &openState);
  3356.                 error = HT_SetOpenState(node, !openState);
  3357.                 break;
  3358.  
  3359.                 case    HT_CMD_OPEN_NEW_WIN:
  3360.                 if (node == NULL)    break;
  3361.  
  3362.                 XP_MEMSET(&chrome, 0, sizeof(Chrome));
  3363.                 chrome.show_button_bar = TRUE;
  3364.                 chrome.show_url_bar = TRUE;
  3365.                 chrome.show_directory_buttons = TRUE;
  3366.                 chrome.show_bottom_status_bar = TRUE;
  3367.                 chrome.show_menu = TRUE;
  3368.                 chrome.show_security_bar = TRUE;
  3369.                 chrome.allow_close = TRUE;
  3370.                 chrome.allow_resize = TRUE;
  3371.                 chrome.show_scrollbar = TRUE;
  3372.  
  3373.                 urls = NET_CreateURLStruct(resourceID(node->node), NET_DONT_RELOAD);
  3374.                 FE_MakeNewWindow((MWContext *)gRDFMWContext(), urls, NULL, &chrome);
  3375.                 break;
  3376.  
  3377.                 case    HT_CMD_OPEN_COMPOSER:
  3378. #ifdef EDITOR
  3379.                 /*
  3380.                     XXX to do
  3381.                 
  3382.                     Composer needs to expose a routine similar
  3383.                     to FE_MakeNewWindow() for opening a URL in
  3384.                     an editor window
  3385.                 */
  3386. #endif EDITOR
  3387.                 break;
  3388.  
  3389.                 case    HT_CMD_NEW_BOOKMARK:
  3390.                 case    HT_CMD_NEW_FOLDER:
  3391.                 case    HT_CMD_NEW_SEPARATOR:
  3392.                 uniqueCount = 0;
  3393.                 if (menuCmd == HT_CMD_NEW_BOOKMARK)
  3394.                 {
  3395.                     if ((url = FE_Prompt(((MWContext *)gRDFMWContext()),
  3396.                             "URL:", "http://")) == NULL)    break;
  3397.  
  3398.                     if (!strcmp(url, "about"))
  3399.                     {
  3400.                         XP_FREE(url);
  3401.                         url = PR_smprintf("http://people.netscape.com/rjc/about.rdf#root");
  3402.                         doAbout = PR_TRUE;
  3403.                         menuCmd = HT_CMD_NEW_FOLDER;
  3404.                     }
  3405.                     /* for the moment, only allow direct addition of http URLs */
  3406.                     if (!startsWith("http://", url))
  3407.                     {
  3408.                         XP_FREE(url);
  3409.                         url = NULL;
  3410.                         break;
  3411.                     }
  3412.                     gAutoEditNewNode = true;
  3413.                 }
  3414.                 else
  3415.                 do
  3416.                 {
  3417.                     if (menuCmd == HT_CMD_NEW_FOLDER)
  3418.                     {
  3419.                         url = PR_smprintf("container%d.rdf",
  3420.                             (int)++uniqueCount);
  3421.                         gAutoEditNewNode = true;
  3422.                     }
  3423.                     else if (menuCmd == HT_CMD_NEW_SEPARATOR)
  3424.                     {
  3425.                         url = PR_smprintf("separator%d",
  3426.                             (int)++uniqueCount);
  3427.                     }
  3428.                     rNode = RDF_GetResource(pane->db, url, false);
  3429.                     if (rNode != NULL)
  3430.                     {
  3431.                         if (url != NULL)
  3432.                         {
  3433.                             XP_FREE(url);
  3434.                             url = NULL;
  3435.                         }
  3436.                     }
  3437.                 } while (rNode != NULL);
  3438.  
  3439.                 if ((rNode = RDF_GetResource(pane->db, url, true)) != NULL)
  3440.                 {
  3441.                     setResourceType (rNode, RDF_RT);
  3442.                     if (menuCmd == HT_CMD_NEW_BOOKMARK)
  3443.                     {
  3444.                         RDF_Assert(pane->db, rNode,
  3445.                             gCoreVocab->RDF_name,
  3446.                             XP_GetString(RDF_DATA_1), RDF_STRING_TYPE);
  3447.                     }
  3448.                     else if (menuCmd == HT_CMD_NEW_FOLDER)
  3449.                     {
  3450.                         setContainerp(rNode, true);
  3451.                         if (doAbout == PR_TRUE)
  3452.                         {
  3453.                             gAutoEditNewNode = false;
  3454.                         }
  3455.                         else
  3456.                         {
  3457.                             RDF_Assert(pane->db, rNode,
  3458.                                 gCoreVocab->RDF_name,
  3459.                                 XP_GetString(RDF_DATA_2), RDF_STRING_TYPE);
  3460.                         }
  3461.                     }
  3462.                     if (node != NULL)
  3463.                     {
  3464.                         if (HT_IsContainer(node))
  3465.                         {
  3466.                             RDF_Assert(pane->db, rNode,
  3467.                                 gCoreVocab->RDF_parent,
  3468.                                 node->node,
  3469.                                 RDF_RESOURCE_TYPE);
  3470.                             error = HT_SetOpenState(node, TRUE);
  3471.                         }
  3472.                         else
  3473.                         {
  3474.                             RDF_Assert(pane->db, rNode,
  3475.                                 gCoreVocab->RDF_parent,
  3476.                                 node->parent->node,
  3477.                                 RDF_RESOURCE_TYPE);
  3478.                         }
  3479.                     }
  3480.                     else
  3481.                     {
  3482.                         RDF_Assert(pane->db, rNode,
  3483.                             gCoreVocab->RDF_parent,
  3484.                             HT_TopNode(view)->node,
  3485.                             RDF_RESOURCE_TYPE);
  3486.                     }
  3487.  
  3488.                     node = NULL;
  3489.                 }
  3490.                 if (url != NULL)
  3491.                 {
  3492.                     XP_FREE(url);
  3493.                     url = NULL;
  3494.                 }
  3495.                 break;
  3496.  
  3497.                 case    HT_CMD_ADD_TO_BOOKMARKS:
  3498.                 if (node == NULL)    break;
  3499.                 HT_AddBookmark (resourceID(node->node), HT_GetNodeName(node));
  3500.                 break;
  3501.  
  3502.                 case    HT_CMD_OPEN_AS_WORKSPACE:
  3503.                 if (node == NULL)    break;
  3504.                 if (HT_IsContainer(node))
  3505.                 {
  3506. #ifdef    HT_PASSWORD_RTNS
  3507.                     if (ht_hasPassword(node) == PR_TRUE)
  3508.                     {
  3509.                         if (ht_checkPassword(node, false) == PR_FALSE)    break;
  3510.                     }
  3511. #endif
  3512.                 }
  3513.                 HT_NewWorkspace(pane, resourceID(node->node), NULL);
  3514.                 error = HT_NoErr;
  3515.                 break;
  3516.  
  3517.                 case    HT_CMD_PROPERTIES:
  3518.                 if (node == NULL)
  3519.                 {
  3520.                     node = HT_TopNode(view);
  3521.                 }
  3522.                 if (!HT_IsSeparator(node))
  3523.                 {
  3524. #ifdef    HT_PASSWORD_RTNS
  3525.                     if (HT_IsContainer(node))
  3526.                     {
  3527.                         if (ht_hasPassword(node) == PR_TRUE)
  3528.                         {
  3529.                             if (ht_checkPassword(node, false) == PR_FALSE)    break;
  3530.                         }
  3531.                     }
  3532. #endif
  3533.                     HT_Properties(node);
  3534.                 }
  3535.                 error = HT_NoErr;
  3536.                 break;
  3537.  
  3538.                 case    HT_CMD_REFRESH:
  3539.                 if (node == NULL)
  3540.                 {
  3541.                     node = HT_TopNode(view);
  3542.                 }
  3543.                 if (HT_IsContainer(node))
  3544.                 {
  3545.                     destroyViewInt(node, PR_TRUE);
  3546.                     refreshItemList (node, HT_EVENT_VIEW_REFRESH);
  3547.                 }
  3548.                 break;
  3549.  
  3550.                 case    HT_CMD_CUT:
  3551.                 if (node == NULL)    break;
  3552.                 if (HT_IsContainer(node))
  3553.                 {
  3554. #ifdef    HT_PASSWORD_RTNS
  3555.                     if (ht_hasPassword(node) == PR_TRUE)
  3556.                     {
  3557.                         if (ht_checkPassword(node, false) == PR_FALSE)    break;
  3558.                     }
  3559. #endif
  3560.                 }
  3561.                 if (node->parent)
  3562.                 {
  3563.                     htRemoveChild(node->parent, node, true);
  3564.                     needRefresh = true;
  3565.                 }
  3566.                 break;
  3567.  
  3568.                 case    HT_CMD_COPY:
  3569.                 if (node == NULL)    break;
  3570.                 htCopyReference(node->node, gNavCenter->RDF_Clipboard, emptyClipboard);
  3571.                 emptyClipboard = PR_FALSE;
  3572.                 break;
  3573.  
  3574.                 case    HT_CMD_PASTE:
  3575.                 if (node == NULL)    break;
  3576.                 if (HT_IsContainer(node))
  3577.                 {
  3578.                     htCopyReference(gNavCenter->RDF_Clipboard, node->node, PR_FALSE);
  3579.                 }
  3580.                 break;
  3581.  
  3582.                 case    HT_CMD_UNDO:
  3583.                 break;
  3584.  
  3585.                 case    HT_CMD_RENAME:
  3586.                 if (node == NULL)    break;
  3587.                 sendNotification(node, HT_EVENT_NODE_EDIT);
  3588.                 break;
  3589.  
  3590.                     case   HT_CMD_PRINT_FILE:
  3591.                 if (node == NULL)    break;
  3592. #ifdef WIN32
  3593.                 if ((resourceType(node->parent->node) == LFS_RT) &&
  3594.                     (!HT_IsContainer(node)))
  3595.                 {
  3596.                     FE_Print(resourceID(node->node));
  3597.                 }
  3598. #endif
  3599.                 break;
  3600.  
  3601.                 case    HT_CMD_DELETE_FILE:
  3602.                 if (node == NULL)        break;
  3603.                 if (HT_IsContainer(node))    break;
  3604.                 if (htRemoveChild(node->parent, node, false))
  3605.                 {
  3606.                     node = NULL;
  3607.                     break;
  3608.                 }
  3609.                 needRefresh = true;
  3610.                 break;
  3611.  
  3612.                 case    HT_CMD_DELETE_FOLDER:
  3613.                 if (node == NULL)        break;
  3614.                 if (!HT_IsContainer(node))    break;
  3615.                 if (htRemoveChild(node->parent, node, false))
  3616.                 {
  3617.                     node = NULL;
  3618.                     break;
  3619.                 }
  3620.                 needRefresh = true;
  3621.                 break;
  3622.  
  3623.                 case    HT_CMD_EXPORT:
  3624.                 if (node == NULL)
  3625.                 {
  3626.                     if (pane == NULL)        break;
  3627.                     if (pane->selectedView == NULL)    break;
  3628.                     node = HT_TopNode(pane->selectedView);
  3629.                 }
  3630.                 if (node == NULL)    break;
  3631.                 if (HT_IsContainer(node))
  3632.                 {
  3633. #ifdef    HT_PASSWORD_RTNS
  3634.                     if (ht_hasPassword(node) == PR_TRUE)
  3635.                     {
  3636.                         if (ht_checkPassword(node, false) == PR_FALSE)    break;
  3637.                     }
  3638. #endif
  3639.                     FE_PromptForFileName(((MWContext *)gRDFMWContext()),
  3640.                         "", NULL, false, false,
  3641.                         (ReadFileNameCallbackFunction)exportCallback,
  3642.                         (void *)node->node);
  3643.                 }
  3644.                 break;
  3645.  
  3646.                 case    HT_CMD_EXPORTALL:
  3647.                 FE_PromptForFileName(((MWContext *)gRDFMWContext()),
  3648.                     NULL, NETSCAPE_RDF_FILENAME, false, false,
  3649.                     (ReadFileNameCallbackFunction)exportCallback,
  3650.                     (void *)gNavCenter->RDF_Top);
  3651.                 break;
  3652.  
  3653.                 case    HT_CMD_SET_TOOLBAR_FOLDER:
  3654.                 if (node == NULL)    break;
  3655.                 if (HT_IsContainer(node))
  3656.                 {
  3657. #ifdef    HT_PASSWORD_RTNS
  3658.                     if (ht_hasPassword(node) == PR_TRUE)
  3659.                     {
  3660.                         if (ht_checkPassword(node, false) == PR_FALSE)    break;
  3661.                     }
  3662. #endif
  3663.                     if ((newTopNode = node->node) != NULL)
  3664.                     {
  3665.                         RDFUtil_SetPTFolder(newTopNode);
  3666.                         onlyUpdateBookmarks = false;
  3667.                         onlyUpdatePersonalToolbar = true;
  3668.                         needRefresh = true;
  3669.                     }
  3670.                 }
  3671.                 break;
  3672.  
  3673.                 case    HT_CMD_SET_BOOKMARK_MENU:
  3674.                 if (node == NULL)    break;
  3675.                 if (HT_IsContainer(node))
  3676.                 {
  3677. #ifdef    HT_PASSWORD_RTNS
  3678.                     if (ht_hasPassword(node) == PR_TRUE)
  3679.                     {
  3680.                         if (ht_checkPassword(node, false) == PR_FALSE)    break;
  3681.                     }
  3682. #endif
  3683.                     if ((newTopNode = node->node) != NULL)
  3684.                     {
  3685.                         RDFUtil_SetQuickFileFolder(newTopNode);
  3686.                         onlyUpdateBookmarks = true;
  3687.                         onlyUpdatePersonalToolbar = (newTopNode == RDFUtil_GetPTFolder()) ? true:false;
  3688.                         needRefresh = true;
  3689.                     }
  3690.                 }
  3691.                 break;
  3692.  
  3693.                 case    HT_CMD_REMOVE_BOOKMARK_MENU:
  3694.                 if (node == NULL)    break;
  3695.                 if ((topNode = HT_TopNode(view)) == NULL)    break;
  3696.                 if ((newTopNode = topNode->node) != NULL)
  3697.                 {
  3698.                     RDFUtil_SetQuickFileFolder(newTopNode);
  3699.                     onlyUpdateBookmarks = true;
  3700.                     onlyUpdatePersonalToolbar = (newTopNode == RDFUtil_GetPTFolder()) ? true:false;
  3701.                     needRefresh = true;
  3702.                 }
  3703.                 break;
  3704.  
  3705.                 case    HT_CMD_SET_BOOKMARK_FOLDER:
  3706.                 if (node == NULL)    break;
  3707.                 if (HT_IsContainer(node))
  3708.                 {
  3709.                     if ((newTopNode = node->node) != NULL)
  3710.                     {
  3711.                         RDFUtil_SetNewBookmarkFolder(newTopNode);
  3712.                         onlyUpdateBookmarks = true;
  3713.                         onlyUpdatePersonalToolbar = false;
  3714.                         needRefresh = true;
  3715.                     }
  3716.                 }
  3717.                 break;
  3718.  
  3719.                 case    HT_CMD_REMOVE_BOOKMARK_FOLDER:
  3720.                 if (node == NULL)    break;
  3721.                 if ((topNode = HT_TopNode(view)) == NULL)    break;
  3722.                 if ((newTopNode = topNode->node) != NULL)
  3723.                 {
  3724.                     RDFUtil_SetNewBookmarkFolder(newTopNode);
  3725.                     onlyUpdateBookmarks = true;
  3726.                     onlyUpdatePersonalToolbar = false;
  3727.                     needRefresh = true;
  3728.                 }
  3729.                 break;
  3730.  
  3731. #ifdef    HT_PASSWORD_RTNS
  3732.  
  3733.                 case    HT_CMD_SET_PASSWORD:
  3734.                 if (ht_hasPassword(node) == PR_TRUE)
  3735.                 {
  3736.                     if (ht_checkPassword(node, true) == PR_FALSE)    break;
  3737.                 }
  3738.                 if ((password1 = FE_PromptPassword(((MWContext *)gRDFMWContext()),
  3739.                                 XP_GetString(RDF_NEWPASSWORD))) == NULL)    break;
  3740.                 if ((password2 = FE_PromptPassword(((MWContext *)gRDFMWContext()),
  3741.                                 XP_GetString(RDF_CONFIRMPASSWORD))) == NULL)    break;
  3742.                 if (strcmp(password1, password2))
  3743.                 {
  3744.                     FE_Alert(((MWContext *)gRDFMWContext()), XP_GetString(RDF_MISMATCHPASSWORD));
  3745.                     break;
  3746.                 }
  3747.                 ht_SetPassword(node, password1);
  3748.                 break;
  3749.  
  3750.                 case    HT_CMD_REMOVE_PASSWORD:
  3751.                 if (ht_hasPassword(node) == PR_TRUE)
  3752.                 {
  3753.                     if (ht_checkPassword(node, true) == PR_FALSE)    break;
  3754.                 }
  3755.                 ht_SetPassword(node, NULL);
  3756.                 break;
  3757. #endif
  3758.  
  3759.                 default:
  3760.                 if (node == NULL)    break;
  3761.  
  3762.                 /* handle commands from the RDF graph */
  3763.                 if (menuCmd >= NUM_MENU_CMDS)
  3764.                 {
  3765.                     menuCommand = menuCommandsList;
  3766.                     while (menuCommand != NULL)
  3767.                     {
  3768.                         if (menuCommand->menuCmd == menuCmd)
  3769.                         {
  3770.                             RDF_Assert(gNCDB, node->node, gNavCenter->RDF_Command, 
  3771.                                 menuCommand->graphCommand, RDF_RESOURCE_TYPE);
  3772.                             break;
  3773.                         }
  3774.                         menuCommand = menuCommand->next;
  3775.                     }
  3776.                 }
  3777.                 break;
  3778.             }
  3779.             if (node != NULL)
  3780.             {
  3781.                 node = HT_GetNextSelection(view, node);
  3782.             }
  3783.         } while (node != NULL);
  3784.         break;
  3785.     }
  3786.  
  3787.     freeMenuCommandList();
  3788.  
  3789.     if (needRefresh == true)
  3790.     {
  3791.         refreshPanes(onlyUpdateBookmarks, onlyUpdatePersonalToolbar, newTopNode);
  3792.     }
  3793.     gBatchUpdate = false;
  3794.  
  3795.     return(error);
  3796. }
  3797.  
  3798.  
  3799.  
  3800. void
  3801. htEmptyClipboard(RDF_Resource parent)
  3802. {
  3803.     RDF_Cursor        c;
  3804.     RDF_Resource        node;
  3805.  
  3806.     XP_ASSERT(parent != NULL);
  3807.  
  3808.     if (parent != NULL)
  3809.     {
  3810.         if ((c = RDF_GetSources(gNCDB, parent, gCoreVocab->RDF_parent,
  3811.                     RDF_RESOURCE_TYPE,  true)) != NULL)
  3812.         {
  3813.             while (node = RDF_NextValue(c))
  3814.             {
  3815.                 RDF_Unassert(gNCDB, node, gCoreVocab->RDF_parent,
  3816.                     parent, RDF_RESOURCE_TYPE);
  3817.             }
  3818.             RDF_DisposeCursor(c);
  3819.         }
  3820.     }
  3821. }
  3822.  
  3823.  
  3824.  
  3825. void
  3826. htCopyReference(RDF_Resource original, RDF_Resource newParent, PRBool empty)
  3827. {
  3828.     RDF_Cursor        c;
  3829.     RDF_Resource        node;
  3830.  
  3831.     XP_ASSERT(original != NULL);
  3832.     XP_ASSERT(newParent != NULL);
  3833.  
  3834.     if (empty == PR_TRUE)
  3835.     {
  3836.         htEmptyClipboard(newParent);
  3837.     }
  3838.     
  3839.     if ((original != NULL) && (newParent != NULL))
  3840.     {
  3841.         if (original == gNavCenter->RDF_Clipboard)
  3842.         {
  3843.             if ((c = RDF_GetSources(gNCDB, original, gCoreVocab->RDF_parent,
  3844.                         RDF_RESOURCE_TYPE,  true)) != NULL)
  3845.             {
  3846.                 while (node = RDF_NextValue(c))
  3847.                 {
  3848.                     RDF_Assert(gNCDB, node, gCoreVocab->RDF_parent,
  3849.                         newParent, RDF_RESOURCE_TYPE);
  3850.                 }
  3851.                 RDF_DisposeCursor(c);
  3852.             }
  3853.         }
  3854.         else
  3855.         {
  3856.             RDF_Assert(gNCDB, original, gCoreVocab->RDF_parent,
  3857.                 newParent, RDF_RESOURCE_TYPE);
  3858.         }
  3859.     }
  3860. }
  3861.  
  3862.  
  3863.  
  3864. PR_PUBLIC_API(HT_Resource)
  3865. HT_GetNthItem (HT_View view, uint32 theIndex)
  3866. {
  3867.   uint32 count = theIndex;
  3868.   ldiv_t  cdiv  = ldiv(count , ITEM_LIST_ELEMENT_SIZE);
  3869.   uint32 bucketNum = (uint32)cdiv.quot;
  3870.   uint32 offset = (uint32)cdiv.rem;
  3871.   if (theIndex >= view->itemListCount) return NULL;
  3872.   if (*(view->itemList + bucketNum) == NULL) return NULL;
  3873.   return   *((*(view->itemList + bucketNum)) + offset);
  3874. }
  3875.  
  3876.  
  3877.  
  3878. PR_PUBLIC_API(uint32)
  3879. HT_GetNodeIndex(HT_View view, HT_Resource node)
  3880. {
  3881.     uint32        itemListIndex = 0;
  3882.  
  3883.     XP_ASSERT(node != NULL);
  3884.  
  3885.     if (node != NULL)
  3886.     {
  3887.         itemListIndex = node->itemListIndex;
  3888.     }
  3889.     return(itemListIndex);
  3890. }
  3891.  
  3892.  
  3893.  
  3894. PR_PUBLIC_API(uint32)
  3895. HT_GetViewIndex(HT_View view)
  3896. {
  3897.     HT_View        viewList = NULL;
  3898.     uint32        viewListIndex = 0;
  3899.  
  3900.     XP_ASSERT(view != NULL);
  3901.  
  3902.     if (view != NULL)
  3903.     {
  3904.         viewList = (view->pane->viewList);
  3905.         while (viewList != NULL)
  3906.         {
  3907.             if (viewList == view)    break;
  3908.             ++viewListIndex;
  3909.             viewList = viewList->next;
  3910.         }
  3911.     }
  3912.     if (viewList != view)    viewListIndex = 0;
  3913.     return(viewListIndex);
  3914. }
  3915.  
  3916.  
  3917.  
  3918. PR_PUBLIC_API(PRBool)
  3919. HT_ItemHasForwardSibling(HT_Resource r)
  3920. {
  3921.     XP_ASSERT(r != NULL);
  3922.  
  3923.     return ((r != NULL) && (r->next) ? true : false);
  3924. }
  3925.  
  3926.  
  3927.  
  3928. PR_PUBLIC_API(PRBool)
  3929. HT_ItemHasBackwardSibling(HT_Resource r)
  3930. {
  3931.     PRBool        flag = false;
  3932.  
  3933.     XP_ASSERT(r != NULL);
  3934.  
  3935.     if ((r != NULL) && r->parent && (r->parent->child != r))
  3936.     {
  3937.         flag = true;
  3938.     }
  3939.     return (flag);
  3940. }
  3941.  
  3942.  
  3943.  
  3944. PR_PUBLIC_API(uint16)
  3945. HT_GetItemIndentation (HT_Resource r)
  3946. {
  3947.     XP_ASSERT(r != NULL);
  3948.  
  3949.     return (r->depth);
  3950. }
  3951.  
  3952.  
  3953.  
  3954. PR_PUBLIC_API(uint32)
  3955. HT_GetItemListCount (HT_View v)
  3956. {
  3957.     XP_ASSERT(v != NULL);
  3958.  
  3959.     return (v->itemListCount);
  3960. }
  3961.  
  3962.  
  3963.  
  3964. PR_PUBLIC_API(uint32)
  3965. HT_GetViewListCount (HT_Pane p)
  3966. {
  3967.     uint32        count = 0;
  3968.  
  3969.     XP_ASSERT(p != NULL);
  3970.  
  3971.     if (p != NULL)
  3972.     {
  3973.         count = p->viewListCount;
  3974.     }
  3975.     return (count);
  3976. }
  3977.  
  3978.  
  3979.  
  3980. PR_PUBLIC_API(HT_View)
  3981. HT_GetNthView (HT_Pane pane, uint32 theIndex)
  3982. {
  3983.     HT_View        view = NULL;
  3984.  
  3985.     XP_ASSERT(pane != NULL);
  3986.  
  3987.     if (pane != NULL)
  3988.     {
  3989.         view = pane->viewList;
  3990.         while ((theIndex > 0) && (view != NULL))
  3991.         {
  3992.             view = view->next;
  3993.             --theIndex;
  3994.         }
  3995.     }
  3996.     return(view);
  3997. }
  3998.  
  3999.  
  4000.  
  4001. PR_PUBLIC_API(HT_Resource)
  4002. HT_GetParent (HT_Resource node)
  4003. {
  4004.     XP_ASSERT(node != NULL);
  4005.  
  4006.     if (!node) return NULL;
  4007.     return (node->parent);
  4008. }
  4009.  
  4010.  
  4011.  
  4012. PR_PUBLIC_API(HT_View)
  4013. HT_GetView (HT_Resource node)
  4014. {
  4015.     HT_View            view = NULL;
  4016.  
  4017.     if (node != NULL)
  4018.     {
  4019.         view = node->view;
  4020.     }
  4021.     return (view);
  4022. }
  4023.  
  4024.  
  4025.  
  4026. PR_PUBLIC_API(PRBool)
  4027. HT_IsSelected (HT_Resource node)
  4028. {
  4029.     PRBool            isSelected = PR_FALSE;
  4030.  
  4031.     XP_ASSERT(node != NULL);
  4032.  
  4033.     if (node != NULL)
  4034.     {
  4035.         if (node->flags & HT_SELECTED_FLAG)    isSelected = PR_TRUE;
  4036.     }
  4037.     return (isSelected);
  4038. }
  4039.  
  4040.  
  4041.  
  4042. PR_PUBLIC_API(PRBool)
  4043. HT_IsContainer (HT_Resource node)
  4044. {
  4045.     PRBool            isContainer = PR_FALSE;
  4046.  
  4047.     XP_ASSERT(node != NULL);
  4048.  
  4049.     if (node != NULL)
  4050.     {
  4051.         if (containerp(node->node))    isContainer = PR_TRUE;
  4052.     }
  4053.     return (isContainer);
  4054. }
  4055.  
  4056.  
  4057.  
  4058. PR_PUBLIC_API(PRBool)
  4059. HT_IsContainerOpen (HT_Resource node)
  4060. {
  4061.     PRBool            isOpen = PR_FALSE;
  4062.  
  4063.     XP_ASSERT(node != NULL);
  4064.  
  4065.     if (node != NULL)
  4066.     {
  4067.         if (node->flags & HT_OPEN_FLAG)    isOpen = PR_TRUE;
  4068.     }
  4069.     return (isOpen);
  4070. }
  4071.  
  4072.  
  4073.  
  4074. PR_PUBLIC_API(PRBool)
  4075. HT_IsSeparator (HT_Resource node)
  4076. {
  4077.     PRBool            isSep = PR_FALSE;
  4078.  
  4079.     XP_ASSERT(node != NULL);
  4080.     XP_ASSERT(node->node != NULL);
  4081.  
  4082.     if ((node != NULL) && (node->node != NULL))
  4083.     {
  4084.         if (isSeparator(node->node))    isSep = PR_TRUE;
  4085.     }
  4086.     return(isSep);
  4087. }
  4088.  
  4089.  
  4090.  
  4091. PRBool
  4092. ht_isURLReal(HT_Resource node)
  4093. {
  4094.     RDF_BT            type;
  4095.     PRBool            validFlag = true;
  4096.  
  4097.     XP_ASSERT(node != NULL);
  4098.     XP_ASSERT(node->node != NULL);
  4099.  
  4100.     type = resourceType(node->node);
  4101. /*
  4102.     if (type == LFS_RT)
  4103.     {
  4104.         validFlag = false;
  4105.     }
  4106.     else
  4107. */
  4108.     if (HT_IsContainer(node))
  4109.     {
  4110.         if (type == RDF_RT || type == HISTORY_RT || type == SEARCH_RT || type == PM_RT || type == IM_RT)
  4111.         {
  4112.             validFlag = false;
  4113.         }
  4114.     }
  4115.     else if (HT_IsSeparator(node))
  4116.     {
  4117.         validFlag = false;
  4118.     }
  4119.     return(validFlag);
  4120. }
  4121.  
  4122.  
  4123.  
  4124. PR_PUBLIC_API(PRBool)
  4125. HT_GetNodeData (HT_Resource node, void *token, uint32 tokenType, void **nodeData)
  4126. {
  4127.     HT_Value        values;
  4128.     PRBool            foundData = false;
  4129.     void            *data = NULL;
  4130.  
  4131.     XP_ASSERT(node != NULL);
  4132.  
  4133.     if (token != NULL && nodeData != NULL)
  4134.     {
  4135.         *nodeData = NULL;
  4136.  
  4137.         if (values = node->values)
  4138.         {
  4139.             while (values != NULL)
  4140.             {
  4141.                 if ((values->tokenType == tokenType) &&
  4142.                      (values->token == token))
  4143.                 {
  4144.                     *nodeData = values->data;
  4145.                     return(true);
  4146.                 }
  4147.                 values = values->next;
  4148.             }
  4149.         }
  4150.  
  4151.         if ((token == gWebData->RDF_URL) && (ht_isURLReal(node) == false))
  4152.         {
  4153.             /* don't return RDF container or separator URLs */
  4154.         }
  4155.         else if (tokenType == HT_COLUMN_INT || tokenType == HT_COLUMN_DATE_INT)
  4156.         {
  4157.             data = RDF_GetSlotValue(node->view->pane->db, node->node, token,
  4158.                         RDF_INT_TYPE, false, true);
  4159.             foundData = true;
  4160.         }
  4161.         else if (tokenType == HT_COLUMN_STRING || tokenType == HT_COLUMN_DATE_STRING)
  4162.         {
  4163.             if (token == gWebData->RDF_URL)
  4164.             {
  4165.                 data =  resourceID(node->node);
  4166.             }
  4167.             else
  4168.             {
  4169.                 data = RDF_GetSlotValue(node->view->pane->db, node->node,
  4170.                         token, RDF_STRING_TYPE, false, true);
  4171.             }
  4172.  
  4173. #ifndef    DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  4174.             if (data != NULL)
  4175.             {
  4176.                 data = copyString(data);
  4177.             }
  4178. #endif
  4179.  
  4180.             foundData = true;
  4181.         }
  4182.  
  4183.         if (values = (HT_Value)getMem(sizeof(HT_ValueStruct)))
  4184.         {
  4185.             values->tokenType = tokenType;
  4186.             values->token = token;
  4187.             values->data = data;
  4188.  
  4189.             values->next = node->values;
  4190.             node->values = values;
  4191.         }
  4192.         *nodeData = data;
  4193.     }
  4194.     return(foundData);
  4195. }
  4196.  
  4197.  
  4198.  
  4199. PR_PUBLIC_API(HT_Error)
  4200. HT_SetNodeData (HT_Resource node, void *token, uint32 tokenType, void *data)
  4201. {
  4202.     HT_Error        error = HT_Err;
  4203.     void            *oldData = NULL;
  4204.     PRBool            dirty = PR_TRUE;
  4205.  
  4206.     XP_ASSERT(node != NULL);
  4207.     XP_ASSERT(token != NULL);
  4208.  
  4209.     if (HT_IsNodeDataEditable(node, token, tokenType))
  4210.     {
  4211.         if (HT_GetNodeData(node, token, tokenType, &oldData))
  4212.         {
  4213.             switch(tokenType)
  4214.             {
  4215.             case    HT_COLUMN_STRING:
  4216.                 if (data != NULL && oldData != NULL)
  4217.                 {
  4218.                     if (!strcmp(data, oldData))
  4219.                     {
  4220.                         dirty = PR_FALSE;
  4221.                     }
  4222.                 }
  4223.                 if (dirty == PR_TRUE)
  4224.                 {
  4225.                     if (oldData != NULL)
  4226.                     {
  4227.                         RDF_Unassert(node->view->pane->db, node->node,
  4228.                             token, oldData, RDF_STRING_TYPE);
  4229.                     }
  4230.                     if ((data != NULL) && (((char *)data)[0] != '\0'))
  4231.                     {
  4232.                         RDF_Assert(node->view->pane->db, node->node,
  4233.                             token, data, RDF_STRING_TYPE);
  4234.                     }
  4235.                     if (token == gNavCenter->RDF_smallIcon ||
  4236.                         token == gNavCenter->RDF_largeIcon)
  4237.                     {
  4238.  
  4239. #ifdef DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  4240.                         if (node->flags & HT_FREEICON_URL_FLAG)
  4241.                         {
  4242.                             if (node->url[0] != NULL)
  4243.                             {
  4244.                                 freeMem(node->url[0]);
  4245.                                 node->url[0] = NULL;
  4246.                             }
  4247.                             if (node->url[1] != NULL)
  4248.                             {
  4249.                                 freeMem(node->url[1]);
  4250.                                 node->url[1] = NULL;
  4251.                             }
  4252.                         }
  4253. #else
  4254.                         node->url[0] = NULL;
  4255.                         node->url[1] = NULL;
  4256. #endif
  4257.  
  4258.                     }
  4259.                 }
  4260.                 error = HT_NoErr;
  4261.             break;
  4262.             }
  4263.         }
  4264.     }
  4265.     return(error);
  4266. }
  4267.  
  4268.  
  4269.  
  4270. PR_PUBLIC_API(HT_Error)
  4271. HT_SetNodeName(HT_Resource node, void *data)
  4272. {
  4273.     XP_ASSERT(node != NULL);
  4274.  
  4275.     return(HT_SetNodeData(node, gCoreVocab->RDF_name, HT_COLUMN_STRING, data));
  4276. }
  4277.  
  4278.  
  4279.  
  4280. PR_PUBLIC_API(PRBool)
  4281. HT_IsNodeDataEditable(HT_Resource node, void *token, uint32 tokenType)
  4282. {
  4283.     RDF_BT            type;
  4284.     PRBool            canEditFlag = false;
  4285.  
  4286.     XP_ASSERT(node != NULL);
  4287.     XP_ASSERT(node->node != NULL);
  4288.     XP_ASSERT(token != NULL);
  4289.  
  4290.     if (!HT_IsSeparator(node))
  4291.     {
  4292.         if (node->parent != NULL)
  4293.         {
  4294.             type = resourceType(node->parent->node);
  4295.         }
  4296.         else
  4297.         {
  4298.             type = resourceType(node->node);
  4299.         }
  4300.  
  4301.         if (((token == gCoreVocab->RDF_name) && (!htIsOpLocked(node, gNavCenter->RDF_NameLock))) ||
  4302.             ((token == gNavCenter->RDF_largeIcon) && (!htIsOpLocked(node, gNavCenter->RDF_IconLock))) ||
  4303.             ((token == gNavCenter->RDF_smallIcon) && (!htIsOpLocked(node, gNavCenter->RDF_IconLock))) ||
  4304.             (token == gWebData->RDF_description) ||
  4305.         /*  ((token == gWebData->RDF_URL) && ht_isURLReal(node)) || */
  4306. #ifdef    HT_PASSWORD_RTNS
  4307.             (token == gNavCenter->RDF_Password) ||
  4308. #endif
  4309.             ((gMissionControlEnabled == true) && 
  4310.             (token == gNavCenter->RDF_AddLock) ||
  4311.             (token == gNavCenter->RDF_DeleteLock) ||
  4312.             (token == gNavCenter->RDF_IconLock) ||
  4313.             (token == gNavCenter->RDF_NameLock) ||
  4314.             (token == gNavCenter->RDF_CopyLock) ||
  4315.             (token == gNavCenter->RDF_MoveLock) ||
  4316.             (token == gNavCenter->RDF_WorkspacePosLock)))
  4317.         {
  4318.             if (tokenType == HT_COLUMN_STRING)
  4319.             {
  4320.                 if (type == RDF_RT)
  4321.                 {
  4322.                     canEditFlag = true;
  4323.                 }
  4324.                 else if (type == LFS_RT)
  4325.                 {
  4326.                     if (node->node == gNavCenter->RDF_LocalFiles)
  4327.                     {
  4328.                         canEditFlag = true;
  4329.                     }
  4330.                 }
  4331.                 else if (type == HISTORY_RT)
  4332.                 {
  4333.                     if (node->parent == NULL)
  4334.                     {
  4335.                         canEditFlag = true;
  4336.                     }
  4337.                 }
  4338.             }
  4339.         }
  4340.     }
  4341.     return(canEditFlag);
  4342. }
  4343.  
  4344.  
  4345.  
  4346. /* XXX HT_NodeDisplayString is obsolete! Don't use. */
  4347.  
  4348. PR_PUBLIC_API(HT_Error)
  4349. HT_NodeDisplayString (HT_Resource node, char *buffer, int bufferLen)
  4350. {
  4351.     char *name = HT_GetNodeName(node);
  4352.     memset(buffer, '\0', bufferLen);
  4353.     if (name != NULL)
  4354.     {
  4355.           if (strlen(name) < (unsigned)bufferLen)
  4356.           {
  4357.               strcpy(buffer, name);
  4358.           }
  4359.           else
  4360.           {
  4361.             strncpy(buffer, name, bufferLen-2);
  4362.             name[bufferLen-1]='\0';
  4363.         }
  4364.     }  
  4365.     return HT_NoErr;
  4366. }
  4367.  
  4368.  
  4369.  
  4370. /* XXX HT_ViewDisplayString is obsolete! Don't use. */
  4371.  
  4372. PR_PUBLIC_API(HT_Error)
  4373. HT_ViewDisplayString (HT_View view, char *buffer, int bufferLen)
  4374. {
  4375.     char *name = HT_GetViewName(view);
  4376.     memset(buffer, '\0', bufferLen);
  4377.     if (name != NULL)
  4378.     {
  4379.         if (strlen(name) < (unsigned)bufferLen)
  4380.         {
  4381.             strcpy(buffer, name);
  4382.         }
  4383.         else
  4384.         {
  4385.             strncpy(buffer, name, bufferLen-2);
  4386.             name[bufferLen-1]='\0';
  4387.         }
  4388.     }  
  4389.     return HT_NoErr;
  4390. }
  4391.  
  4392.  
  4393.  
  4394. char *
  4395. buildInternalIconURL(HT_Resource node, PRBool *volatileURLFlag,
  4396.             PRBool largeIconFlag, PRBool workspaceFlag)
  4397. {
  4398.     HT_Icon            theURL, *urlEntry;
  4399.     RDF_BT            targetType;
  4400.     char            buffer[128], *object="", *objectType="", *objectInfo="";
  4401.  
  4402.     XP_ASSERT(node != NULL);
  4403.     XP_ASSERT(volatileURLFlag != NULL);
  4404.  
  4405.     *volatileURLFlag = false;
  4406.     targetType = resourceType(node->node);
  4407.     /* if (targetType == ES_RT) targetType = LFS_RT; */
  4408.     if (HT_IsContainer(node))
  4409.     {
  4410.         if (workspaceFlag)
  4411.         {
  4412.             object = "workspace";
  4413.             if (node->node == gNavCenter->RDF_Sitemaps)
  4414.             {
  4415.                 objectType = ",sitemap";
  4416.             }
  4417. /*
  4418.             else if (node->node == gNavCenter->RDF_Channels)
  4419.             {
  4420.                 objectType = ",channels";
  4421.             }
  4422. */
  4423.             else if (targetType == LDAP_RT)
  4424.             {
  4425.                 objectType = ",ldap";
  4426.             }
  4427.             else if (targetType == LFS_RT)
  4428.             {
  4429.                 objectType = ",file";
  4430.             }
  4431.             else
  4432.             {
  4433.                 objectType = ",personal";
  4434.             }
  4435.         }
  4436.         else
  4437.         {
  4438.             object = "folder";
  4439.  
  4440.             /* URL is state-based, so may change */
  4441.             *volatileURLFlag = true;
  4442.  
  4443.             if (targetType == LFS_RT)
  4444.             {
  4445.                 objectInfo = (HT_IsContainerOpen(node)) ? "/local,open" : "/local,closed";
  4446.             }
  4447.             else if (targetType == FTP_RT || targetType == ES_RT ||
  4448.                 targetType == LDAP_RT)
  4449.             {
  4450.                 objectInfo = (HT_IsContainerOpen(node)) ? "/remote,open" : "/remote,closed";
  4451.             }
  4452.             else
  4453.             {
  4454.                 objectInfo = (HT_IsContainerOpen(node)) ? "/open" : "/closed";
  4455.             }
  4456.         }
  4457.     }
  4458.     else
  4459.     {
  4460.         *volatileURLFlag = false;
  4461.  
  4462.         if (targetType == LFS_RT)
  4463.         {
  4464.             object = "file";
  4465.             objectInfo = "/local";
  4466.         }
  4467.         else if (targetType == FTP_RT || targetType == ES_RT)
  4468.         {
  4469.           object = "file";
  4470.              objectInfo = "/remote";
  4471.         }
  4472.         else
  4473.         {
  4474.             object = "url";
  4475.             if (HT_IsSeparator(node))
  4476.             {
  4477.                 object = "url/separator";
  4478.             }
  4479.             else if ((node->node != NULL) && ( resourceID(node->node) != NULL))
  4480.             {
  4481.                 if (startsWith("file:",  resourceID(node->node)))
  4482.                 {
  4483.                     object = "file/local";
  4484.                 }
  4485.                 else if (startsWith("mailbox:",  resourceID(node->node)))
  4486.                 {
  4487.                     object = "mailbox";
  4488.                 }
  4489.                 else if (startsWith("mail:", resourceID(node->node)))
  4490.                 {
  4491.                     object = "mail";
  4492.                 }
  4493.                 else if (startsWith("news:", resourceID(node->node)))
  4494.                 {
  4495.                     object = "news";
  4496.                 }
  4497.             }
  4498.         }
  4499.     }
  4500.  
  4501.     switch(targetType)
  4502.     {
  4503.         case    FTP_RT:        objectType=",ftp";        break;
  4504.         case    ES_RT:        objectType=",server";        break;
  4505.         case    SEARCH_RT:    objectType=",search";        break;
  4506.         case    HISTORY_RT:    objectType=",history";        break;
  4507.         case    LDAP_RT:    objectType=",ldap";        break;
  4508. /*
  4509.         case    SITEMAP_RT:    objectType=",sitemap";        break;
  4510.  
  4511. */
  4512.         default:
  4513.             if (object[0] == '\0')
  4514.             {
  4515.                 object="unknown";
  4516.                 objectInfo="";
  4517.                 objectType="";
  4518.             }
  4519.         break;
  4520.     }
  4521.  
  4522.     sprintf(buffer,"icon/%s:%s%s%s", ((largeIconFlag) ? "large":"small"),
  4523.         object, objectType, objectInfo);
  4524.  
  4525.     /* maintain a cache of icon types so that a lot of memory isn't wasted
  4526.      * giving each node its own copy of a relatively small number of types
  4527.          */
  4528.  
  4529.     urlEntry = &urlList;
  4530.     while (*urlEntry != NULL)
  4531.     {
  4532.         if ((*urlEntry)->name)
  4533.         {
  4534.             if (!strcmp((*urlEntry)->name, buffer))
  4535.             {
  4536.                 return((*urlEntry)->name);
  4537.             }
  4538.         }
  4539.         urlEntry = &((*urlEntry)->next);
  4540.     }
  4541.     if ((theURL = (HT_Icon)getMem(sizeof(_HT_Icon))) != NULL)
  4542.     {
  4543.         if (theURL->name = copyString(buffer))    {
  4544.             theURL->next = urlList;
  4545.             urlList = theURL;
  4546.             return(theURL->name);
  4547.             }
  4548.         freeMem(theURL);
  4549.     }
  4550.     return(NULL);
  4551. }
  4552.  
  4553.  
  4554.  
  4555. char *
  4556. getIconURL( HT_Resource node, PRBool largeIconFlag, PRBool workspaceFlag)
  4557. {
  4558.  
  4559.     RDF_Resource    res;
  4560.     PRBool        volatileURLFlag;
  4561.     int        iconIndex;
  4562.  
  4563.     iconIndex = (largeIconFlag) ? 0:1;
  4564.     res = (largeIconFlag) ? gNavCenter->RDF_largeIcon : gNavCenter->RDF_smallIcon;
  4565.  
  4566.     /* if volatile URL, flush if needed and re-create */
  4567.  
  4568.     if (node->flags & HT_VOLATILE_URL_FLAG)
  4569.     {
  4570.         node->url[0] = NULL;
  4571.         node->url[1] = NULL;
  4572.     }
  4573.  
  4574.     if (node->url[iconIndex] == NULL)
  4575.     {
  4576.         if ((node->url[iconIndex] = (char*)RDF_GetSlotValue(node->view->pane->db,
  4577.                 node->node, res, RDF_STRING_TYPE, false, true)) != NULL)
  4578.         {
  4579.             node->flags &= (~HT_VOLATILE_URL_FLAG);
  4580.             node->flags |= HT_FREEICON_URL_FLAG;
  4581.  
  4582. #ifndef    DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  4583.             node->url[iconIndex] = copyString(node->url[iconIndex]);
  4584. #endif
  4585.  
  4586.         }
  4587.         else
  4588.         {
  4589.             node->url[iconIndex] = buildInternalIconURL(node,
  4590.                 &volatileURLFlag, largeIconFlag, workspaceFlag);
  4591.             if (volatileURLFlag)
  4592.             {
  4593.                 node->flags |= HT_VOLATILE_URL_FLAG;
  4594.             }
  4595.             else
  4596.             {
  4597.                 node->flags &= (~HT_VOLATILE_URL_FLAG);
  4598.             }
  4599.         }
  4600.     }
  4601.     return(node->url[iconIndex]);
  4602. }
  4603.  
  4604.  
  4605.  
  4606. PR_PUBLIC_API(char *)
  4607. HT_GetNodeLargeIconURL (HT_Resource r)
  4608. {
  4609.     XP_ASSERT(r != NULL);
  4610.     XP_ASSERT(r->node != NULL);
  4611.  
  4612.     return (getIconURL( r, true, false));
  4613. }
  4614.  
  4615.  
  4616.  
  4617. PR_PUBLIC_API(char *)
  4618. HT_GetNodeSmallIconURL (HT_Resource r)
  4619. {
  4620.     XP_ASSERT(r != NULL);
  4621.     XP_ASSERT(r->node != NULL);
  4622.  
  4623.     return (getIconURL( r, false, false));
  4624. }
  4625.  
  4626.  
  4627.  
  4628. PR_PUBLIC_API(char *)
  4629. HT_GetWorkspaceLargeIconURL (HT_View view)
  4630. {
  4631.     XP_ASSERT(view != NULL);
  4632.  
  4633.     return (getIconURL( view->top, true, true));
  4634. }
  4635.  
  4636.  
  4637.  
  4638. PR_PUBLIC_API(char *)
  4639. HT_GetWorkspaceSmallIconURL (HT_View view)
  4640. {
  4641.     XP_ASSERT(view != NULL);
  4642.  
  4643.     return (getIconURL( view->top, false, true));
  4644. }
  4645.  
  4646.  
  4647.  
  4648. /* obsolete! */
  4649. PR_PUBLIC_API(char *)
  4650. HT_GetLargeIconURL (HT_Resource r)
  4651. {
  4652.     return(NULL);
  4653. }
  4654.  
  4655.  
  4656.  
  4657. /* obsolete! */
  4658. PR_PUBLIC_API(char *)
  4659. HT_GetSmallIconURL (HT_Resource r)
  4660. {
  4661.     return(NULL);
  4662. }
  4663.  
  4664.  
  4665.  
  4666. static PRBool
  4667. rdfProcDialogHandler(XPDialogState *dlgstate, char **argv, int argc, unsigned int button)
  4668. {
  4669.     HT_Resource        node;
  4670.     PRBool            dirty, retVal = PR_TRUE;
  4671.     _htmlElementPtr         htmlElement;
  4672.     int            loop;
  4673.     void            *data = NULL;
  4674.  
  4675.     switch(button)
  4676.     {
  4677.         case    XP_DIALOG_OK_BUTTON:
  4678.         node = htmlElementList->node;
  4679.  
  4680.         if (gMissionControlEnabled == true)
  4681.         {
  4682.             RDF_Unassert(node->view->pane->db, node->node,
  4683.                     gNavCenter->RDF_Locks, gNavCenter->RDF_AddLock,
  4684.                     RDF_RESOURCE_TYPE);
  4685.             RDF_Unassert(node->view->pane->db, node->node,
  4686.                     gNavCenter->RDF_Locks, gNavCenter->RDF_DeleteLock,
  4687.                     RDF_RESOURCE_TYPE);
  4688.             RDF_Unassert(node->view->pane->db, node->node,
  4689.                     gNavCenter->RDF_Locks, gNavCenter->RDF_IconLock,
  4690.                     RDF_RESOURCE_TYPE);
  4691.             RDF_Unassert(node->view->pane->db, node->node,
  4692.                     gNavCenter->RDF_Locks, gNavCenter->RDF_NameLock,
  4693.                     RDF_RESOURCE_TYPE);
  4694.             RDF_Unassert(node->view->pane->db, node->node,
  4695.                     gNavCenter->RDF_Locks, gNavCenter->RDF_CopyLock,
  4696.                     RDF_RESOURCE_TYPE);
  4697.             RDF_Unassert(node->view->pane->db, node->node,
  4698.                     gNavCenter->RDF_Locks, gNavCenter->RDF_MoveLock,
  4699.                     RDF_RESOURCE_TYPE);
  4700.             RDF_Unassert(node->view->pane->db, node->node,
  4701.                     gNavCenter->RDF_Locks, gNavCenter->RDF_WorkspacePosLock,
  4702.                     RDF_RESOURCE_TYPE);
  4703.         }
  4704.         for (loop=0; loop<argc; loop+=2)
  4705.         {
  4706.             htmlElement = htmlElementList;
  4707.             while (htmlElement != NULL)
  4708.             {
  4709.                 if (strcmp( resourceID(htmlElement->token), argv[loop]))
  4710.                 {
  4711.                     htmlElement = htmlElement->next;
  4712.                     continue;
  4713.                 }
  4714.  
  4715.                 if ((gMissionControlEnabled == true) &&
  4716.                    ((htmlElement->token == gNavCenter->RDF_AddLock) ||
  4717.                     (htmlElement->token == gNavCenter->RDF_DeleteLock) ||
  4718.                     (htmlElement->token == gNavCenter->RDF_IconLock) ||
  4719.                     (htmlElement->token == gNavCenter->RDF_NameLock) ||
  4720.                     (htmlElement->token == gNavCenter->RDF_CopyLock) ||
  4721.                     (htmlElement->token == gNavCenter->RDF_MoveLock) ||
  4722.                     (htmlElement->token == gNavCenter->RDF_WorkspacePosLock)))
  4723.                 {
  4724.                     RDF_Assert(htmlElement->node->view->pane->db,
  4725.                         node->node, gNavCenter->RDF_Locks,
  4726.                         htmlElement->token, RDF_RESOURCE_TYPE);
  4727.                 }
  4728.                 else if (HT_IsNodeDataEditable(htmlElement->node,
  4729.                     htmlElement->token, htmlElement->tokenType))
  4730.                 {
  4731.                     HT_GetNodeData (htmlElement->node,
  4732.                         htmlElement->token,
  4733.                         htmlElement->tokenType, &data);
  4734.  
  4735.                     dirty = FALSE;
  4736.                     switch(htmlElement->tokenType)
  4737.                     {
  4738.                         case    HT_COLUMN_STRING:
  4739.                         if (data == NULL)
  4740.                         {
  4741.                             if (argv[loop+1][0] != '\0')
  4742.                             {
  4743.                                 dirty = TRUE;
  4744.                             }
  4745.                         }
  4746.                         else if (strcmp(data,argv[loop+1]))
  4747.                         {
  4748.                             dirty = TRUE;
  4749.                         }
  4750.                         break;
  4751.                     }
  4752.                     if (dirty == TRUE)
  4753.                     {
  4754.                         HT_SetNodeData (htmlElement->node,
  4755.                                 htmlElement->token,
  4756.                                 htmlElement->tokenType,
  4757.                                 argv[loop+1]);
  4758.                     }
  4759.                 }
  4760.                 break;
  4761.             }
  4762.         }
  4763.         retVal = PR_FALSE;
  4764.         break;
  4765.  
  4766.         case    XP_DIALOG_CANCEL_BUTTON:
  4767.         retVal = PR_FALSE;
  4768.         break;
  4769.     }
  4770.  
  4771.     if (retVal == PR_FALSE)
  4772.     {
  4773.         freeHtmlElementList();
  4774.     }
  4775.     return(retVal);
  4776. }
  4777.  
  4778.  
  4779.  
  4780. void
  4781. addHtmlElement(HT_Resource node, RDF_Resource token, uint32 tokenType)
  4782. {
  4783.     _htmlElementPtr         htmlElement;
  4784.  
  4785.     if (htmlElement = (_htmlElementPtr)getMem(sizeof(_htmlElement)))
  4786.     {
  4787.         htmlElement->node = node;
  4788.         htmlElement->token = token;
  4789.         htmlElement->tokenType = tokenType;
  4790.  
  4791.         htmlElement->next = htmlElementList;
  4792.         htmlElementList = htmlElement;
  4793.     }
  4794. }
  4795.  
  4796.  
  4797.  
  4798. void
  4799. freeHtmlElementList()
  4800. {
  4801.     _htmlElementPtr        htmlElement,nextElement;
  4802.  
  4803.     htmlElement = htmlElementList;
  4804.     while (htmlElement != NULL)
  4805.     {
  4806.         nextElement = htmlElement->next;
  4807.         free(htmlElement);
  4808.         htmlElement = nextElement;
  4809.     }
  4810.     htmlElementList = NULL;
  4811. }
  4812.  
  4813.  
  4814.  
  4815. _htmlElementPtr
  4816. findHtmlElement(void *token)
  4817. {
  4818.     _htmlElementPtr         htmlElement;
  4819.  
  4820.     htmlElement = htmlElementList;
  4821.     while(htmlElement != NULL)
  4822.     {
  4823.         if (htmlElement->token == token)    break;
  4824.         htmlElement = htmlElement->next;
  4825.     }
  4826.     return(htmlElement);
  4827. }
  4828.  
  4829.  
  4830.  
  4831.  
  4832. static XPDialogInfo rdfPropDialogInfo = {
  4833.     (XP_DIALOG_OK_BUTTON | XP_DIALOG_CANCEL_BUTTON),
  4834.     rdfProcDialogHandler,
  4835.     500, 400
  4836. };
  4837.  
  4838.  
  4839.  
  4840. char *
  4841. constructHTML(char *dynStr, HT_Resource node, void *token, uint32 tokenType)
  4842. {
  4843.     struct tm        *time;
  4844.     time_t            dateVal;
  4845.     PRBool            isEditable;
  4846.     char            *html = NULL, *temp1, *temp2;
  4847.     void            *data;
  4848.     char            buffer[128];
  4849.  
  4850.     XP_ASSERT(node != NULL);
  4851.     XP_ASSERT(token != NULL);
  4852.  
  4853.     if (findHtmlElement(token) != NULL)    return(dynStr);
  4854.  
  4855.     isEditable = HT_IsNodeDataEditable(node, token, tokenType);
  4856.     if ((!HT_GetNodeData (node, token, tokenType, &data)) || (data == NULL))
  4857.     {
  4858.         data = "";
  4859.     }
  4860.     else
  4861.     {
  4862.         switch(tokenType)
  4863.         {
  4864.             case    HT_COLUMN_RESOURCE:
  4865.             data =  resourceID((RDF_Resource)token);
  4866.             break;
  4867.  
  4868.             case    HT_COLUMN_STRING:
  4869.             break;
  4870.  
  4871.             case    HT_COLUMN_DATE_STRING:
  4872.             if ((dateVal = (time_t)atol((char *)data)) == 0)        break;
  4873.             if ((time = localtime(&dateVal)) == NULL)       break;
  4874. #ifdef    XP_WIN
  4875.             strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_WINDATE),time);
  4876. #else
  4877.             strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_MACDATE),time);
  4878. #endif
  4879.             data = buffer;
  4880.             break;
  4881.  
  4882.             case    HT_COLUMN_DATE_INT:
  4883.             if ((time = localtime((time_t *) &data)) == NULL)       break;
  4884. #ifdef    XP_WIN
  4885.             strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_WINDATE),time);
  4886. #else
  4887.             strftime(buffer,sizeof(buffer),XP_GetString(RDF_HTML_MACDATE),time);
  4888. #endif
  4889.             data = buffer;
  4890.             break;
  4891.  
  4892.             case    HT_COLUMN_INT:
  4893.             sprintf(buffer,"%d",(int)data);
  4894.             data = buffer;
  4895.             break;
  4896.  
  4897.             case    HT_COLUMN_UNKNOWN:
  4898.             default:
  4899.             data = NULL;
  4900.             return(dynStr);
  4901.             break;
  4902.         }
  4903.     }
  4904.     
  4905.     addHtmlElement(node, token, tokenType);
  4906.  
  4907.     if (isEditable)
  4908.     {
  4909.  
  4910. #ifdef    HT_PASSWORD_RTNS
  4911.         if (token == gNavCenter->RDF_Password)
  4912.         {
  4913.             html = XP_GetString(RDF_HTML_STR_2);
  4914.         }
  4915.         else
  4916. #endif
  4917.         if (token == gWebData->RDF_description)
  4918.         {
  4919.             html = XP_GetString(RDF_HTML_STR_5);
  4920.         }
  4921.         else {
  4922.             html = XP_GetString(RDF_HTML_STR_1);
  4923.         }
  4924.         temp1 = PR_smprintf(html,  resourceID((RDF_Resource)token),
  4925.                  resourceID((RDF_Resource)token), (data) ? data:"");
  4926.     }
  4927.     else
  4928.     {
  4929.         html=XP_GetString(RDF_HTML_STR_3);
  4930.         temp1 = PR_smprintf(html,  resourceID((RDF_Resource)token), (data) ? data:"");
  4931.     }
  4932.     if (dynStr != NULL)
  4933.     {
  4934.         temp2 = PR_smprintf("%s%s",dynStr, temp1);
  4935.         XP_FREE(temp1);
  4936.         XP_FREE(dynStr);
  4937.         dynStr = temp2;
  4938.     }
  4939.     else
  4940.     {
  4941.         dynStr = temp1;
  4942.     }
  4943.     return(dynStr);
  4944. }
  4945.  
  4946.  
  4947.  
  4948. char *
  4949. constructHTMLPermission(char *dynStr, HT_Resource node, RDF_Resource token, char *text)
  4950. {
  4951.     char            *html, *temp1, *temp2;
  4952.     PRBool            enabledFlag = false;
  4953.  
  4954.     XP_ASSERT(node != NULL);
  4955.     XP_ASSERT(token != NULL);
  4956.     XP_ASSERT(text != NULL);
  4957.  
  4958.     html=XP_GetString(RDF_HTML_STR_4);
  4959.     if (html != NULL)
  4960.     {
  4961.         enabledFlag = htIsOpLocked(node, token);
  4962.  
  4963.         temp1 = PR_smprintf(html, resourceID((RDF_Resource)token),
  4964.                     resourceID((RDF_Resource)token),
  4965.                     (enabledFlag) ? "CHECKED":"", text);
  4966.         if (dynStr != NULL)
  4967.         {
  4968.             temp2 = PR_smprintf("%s%s",dynStr, temp1);
  4969.             XP_FREE(temp1);
  4970.             dynStr = temp2;
  4971.         }
  4972.         else
  4973.         {
  4974.             dynStr = temp1;
  4975.         }
  4976.         addHtmlElement(node, token, HT_COLUMN_RESOURCE);
  4977.     }
  4978.     return(dynStr);
  4979. }
  4980.  
  4981.  
  4982.  
  4983. PRBool
  4984. htIsOpLocked(HT_Resource node, RDF_Resource token)
  4985. {
  4986.     PRBool            lockedFlag = false;
  4987.  
  4988.     XP_ASSERT(node != NULL);
  4989.     XP_ASSERT(token != NULL);
  4990.  
  4991.     if ((node != NULL) && (node->node != NULL) && (token != NULL))
  4992.     {
  4993.         lockedFlag = RDF_HasAssertion(gNCDB, node->node,
  4994.                 gNavCenter->RDF_Locks, token,
  4995.                 RDF_RESOURCE_TYPE, 1);
  4996.     }
  4997.     return(lockedFlag);
  4998. }
  4999.  
  5000.  
  5001.  
  5002. PR_PUBLIC_API(void)
  5003. HT_Properties (HT_Resource node)
  5004. {
  5005.     RDF_BT            type;
  5006.     RDF_Cursor        c;
  5007.     RDF_Resource        r;
  5008.     PRBool            isContainer, showPermissions = false;
  5009.     XP_Bool            mcEnabled = false;
  5010.     XPDialogStrings        *strings = NULL;
  5011.     char            *dynStr = NULL, *dynStr2 = NULL;
  5012.  
  5013.     XP_ASSERT(node != NULL);
  5014.     XP_ASSERT(node->node != NULL);
  5015.  
  5016.     type = resourceType(node->node);
  5017.     if (!(isContainer=HT_IsContainer(node)))
  5018.     {
  5019.         if (node->parent != NULL)
  5020.         {
  5021.             type = resourceType(node->parent->node);
  5022.         }
  5023.     }
  5024.  
  5025.     if (gMissionControlEnabled == true)
  5026.     {
  5027.         showPermissions = true;
  5028.     }
  5029.  
  5030.     switch(type)
  5031.     {
  5032.         case    RDF_RT:
  5033.         if (HT_IsContainer(node))
  5034.         {
  5035.             dynStr = constructHTML(dynStr, node, (void *)gCoreVocab->RDF_name, HT_COLUMN_STRING);
  5036.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_description, HT_COLUMN_STRING);
  5037. #ifdef    HT_PASSWORD_RTNS
  5038.             dynStr = constructHTML(dynStr, node, (void *)gNavCenter->RDF_Password, HT_COLUMN_STRING);
  5039. #endif
  5040.             dynStr = constructHTML(dynStr, node, (void *)gNavCenter->RDF_bookmarkAddDate, HT_COLUMN_DATE_STRING);
  5041.             dynStr = constructHTML(dynStr, node, (void *)gNavCenter->RDF_largeIcon, HT_COLUMN_STRING);
  5042.             dynStr = constructHTML(dynStr, node, (void *)gNavCenter->RDF_smallIcon, HT_COLUMN_STRING);
  5043.         }
  5044.         else
  5045.         {
  5046.             dynStr = constructHTML(dynStr, node, (void *)gCoreVocab->RDF_name, HT_COLUMN_STRING);
  5047.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_URL, HT_COLUMN_STRING);
  5048.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_description, HT_COLUMN_STRING);
  5049.             dynStr = constructHTML(dynStr, node, (void *)gNavCenter->RDF_bookmarkAddDate, HT_COLUMN_DATE_STRING);
  5050.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_lastVisitDate, HT_COLUMN_DATE_STRING);
  5051.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_lastModifiedDate, HT_COLUMN_DATE_STRING);
  5052.             dynStr = constructHTML(dynStr, node, (void *)gNavCenter->RDF_largeIcon, HT_COLUMN_STRING);
  5053.             dynStr = constructHTML(dynStr, node, (void *)gNavCenter->RDF_smallIcon, HT_COLUMN_STRING);
  5054.         }
  5055.         break;
  5056.  
  5057.         case    LFS_RT:
  5058.         showPermissions = false;
  5059.         if (HT_IsContainer(node))
  5060.         {
  5061.             if (node->parent == NULL)
  5062.             {
  5063.                 showPermissions = true;
  5064.             }
  5065.             dynStr = constructHTML(dynStr, node, (void *)gCoreVocab->RDF_name, HT_COLUMN_STRING);
  5066.             if (node->node != gNavCenter->RDF_LocalFiles)
  5067.             {
  5068.                 dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_URL, HT_COLUMN_STRING);
  5069. #ifdef    NSPR20
  5070.                 dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_creationDate, HT_COLUMN_DATE_INT);
  5071. #endif
  5072.                 dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_lastModifiedDate, HT_COLUMN_DATE_INT);
  5073.             }
  5074.             else
  5075.             {
  5076.                 dynStr = constructHTML(dynStr, node, (void *)gNavCenter->RDF_largeIcon, HT_COLUMN_STRING);
  5077.                 dynStr = constructHTML(dynStr, node, (void *)gNavCenter->RDF_smallIcon, HT_COLUMN_STRING);
  5078.             }
  5079.         }
  5080.         else
  5081.         {
  5082.             dynStr = constructHTML(dynStr, node, (void *)gCoreVocab->RDF_name, HT_COLUMN_STRING);
  5083.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_URL, HT_COLUMN_STRING);
  5084.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_size, HT_COLUMN_INT);
  5085. #ifdef    NSPR20
  5086.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_creationDate, HT_COLUMN_DATE_INT);
  5087. #endif
  5088.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_lastModifiedDate, HT_COLUMN_DATE_INT);
  5089.         }
  5090.         break;
  5091.  
  5092.         case    HISTORY_RT:
  5093.         showPermissions = false;
  5094.         if (HT_IsContainer(node))
  5095.         {
  5096.             if (node->parent == NULL)
  5097.             {
  5098.                 showPermissions = true;
  5099.                 dynStr = constructHTML(dynStr, node, (void *)gCoreVocab->RDF_name, HT_COLUMN_STRING);
  5100.                 dynStr = constructHTML(dynStr, node, (void *)gNavCenter->RDF_largeIcon, HT_COLUMN_STRING);
  5101.                 dynStr = constructHTML(dynStr, node, (void *)gNavCenter->RDF_smallIcon, HT_COLUMN_STRING);
  5102.             }
  5103.         }
  5104.         else
  5105.         {
  5106.             dynStr = constructHTML(dynStr, node, (void *)gCoreVocab->RDF_name, HT_COLUMN_STRING);
  5107.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_URL, HT_COLUMN_STRING);
  5108.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_firstVisitDate, HT_COLUMN_DATE_INT);
  5109.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_lastVisitDate, HT_COLUMN_DATE_INT);
  5110.             /* XXX should also show calculated expiration date */
  5111.             dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_numAccesses, HT_COLUMN_INT);
  5112.         }
  5113.         break;
  5114.  
  5115.         case    FTP_RT:
  5116.         case    ES_RT:
  5117.         showPermissions = false;
  5118.         dynStr = constructHTML(dynStr, node, (void *)gCoreVocab->RDF_name, HT_COLUMN_STRING);
  5119.         dynStr = constructHTML(dynStr, node, (void *)gWebData->RDF_URL, HT_COLUMN_STRING);
  5120.         break;
  5121.  
  5122.         case    SEARCH_RT:
  5123.         case    LDAP_RT:
  5124.         case    PM_RT:
  5125.         case    RDM_RT:
  5126.         default:
  5127.             dynStr = NULL;
  5128.         break;
  5129.     }
  5130.  
  5131.     if (showPermissions == true)
  5132.     {
  5133.         if (HT_IsContainer(node) && (resourceType(node->node) == RDF_RT))
  5134.         {
  5135.             dynStr2 = constructHTMLPermission(dynStr2, node, gNavCenter->RDF_AddLock, XP_GetString(RDF_ADDITIONS_ALLOWED));
  5136.         }
  5137.         dynStr2 = constructHTMLPermission(dynStr2, node, gNavCenter->RDF_DeleteLock, XP_GetString(RDF_DELETION_ALLOWED));
  5138.         dynStr2 = constructHTMLPermission(dynStr2, node, gNavCenter->RDF_IconLock, XP_GetString(RDF_ICON_URL_LOCKED));
  5139.         dynStr2 = constructHTMLPermission(dynStr2, node, gNavCenter->RDF_NameLock, XP_GetString(RDF_NAME_LOCKED));
  5140.         dynStr2 = constructHTMLPermission(dynStr2, node, gNavCenter->RDF_CopyLock, XP_GetString(RDF_COPY_ALLOWED));
  5141.         dynStr2 = constructHTMLPermission(dynStr2, node, gNavCenter->RDF_MoveLock, XP_GetString(RDF_MOVE_ALLOWED));
  5142.         if (HT_IsContainer(node) && (node->parent == NULL))
  5143.         {
  5144.             dynStr2 = constructHTMLPermission(dynStr2, node, gNavCenter->RDF_WorkspacePosLock, XP_GetString(RDF_WORKSPACE_POS_LOCKED));
  5145.         }
  5146.     }
  5147.  
  5148.     if (dynStr != NULL)
  5149.     {
  5150.  
  5151.         /* dynamic property lookup */
  5152.  
  5153.         if ((c = RDF_GetTargets(node->view->pane->db, node->node, gCoreVocab->RDF_slotsHere,
  5154.                     RDF_RESOURCE_TYPE, 1)) != NULL)
  5155.         {
  5156.             while ((r = RDF_NextValue(c)) != NULL)
  5157.             {
  5158.                 dynStr = constructHTML(dynStr, node, (void *)r, HT_COLUMN_STRING);
  5159.             }
  5160.             RDF_DisposeCursor(c);
  5161.         }
  5162.     }
  5163.     
  5164.     strings = XP_GetDialogStrings(RDF_HTML_STR);
  5165.     if (strings != NULL && dynStr != NULL)
  5166.     {
  5167.         XP_CopyDialogString(strings, 0, dynStr);
  5168.         if (dynStr2 != NULL)
  5169.         {
  5170.             XP_CopyDialogString(strings, 1, dynStr2);
  5171.         }
  5172.         XP_MakeHTMLDialog(NULL, &rdfPropDialogInfo, 0,
  5173.                 strings, node, PR_FALSE);
  5174.     }
  5175.     else
  5176.     {
  5177.         freeHtmlElementList();
  5178. #ifdef    DEBUG
  5179.         XP_MakeHTMLAlert(NULL, "Properties not yet implemented for this node type.");
  5180. #endif
  5181.     }
  5182.     if (dynStr != NULL)    XP_FREE(dynStr);
  5183.     if (strings != NULL)    XP_FreeDialogStrings(strings);
  5184. }
  5185.  
  5186.  
  5187.  
  5188. PR_PUBLIC_API(RDF_Resource)
  5189. HT_GetRDFResource (HT_Resource node)
  5190. {
  5191.     XP_ASSERT(node != NULL);
  5192.  
  5193.     return (node->node);
  5194. }
  5195.  
  5196.  
  5197.  
  5198. PR_PUBLIC_API(char*)
  5199. HT_GetNodeURL(HT_Resource node)
  5200. {
  5201.     XP_ASSERT(node != NULL);
  5202.     XP_ASSERT(node->node != NULL);
  5203.  
  5204.     return  resourceID(node->node);
  5205. }
  5206.  
  5207.  
  5208.  
  5209. PR_PUBLIC_API(char*)
  5210. HT_GetNodeName(HT_Resource node)
  5211. {
  5212.     char        *name = NULL;
  5213.  
  5214.     XP_ASSERT(node != NULL);
  5215.  
  5216.     if (node != NULL)
  5217.     {
  5218.         HT_GetNodeData (node, gCoreVocab->RDF_name, HT_COLUMN_STRING, &name);
  5219.     }
  5220.     return(name);
  5221. }
  5222.  
  5223.  
  5224.  
  5225. void
  5226. setHiddenState (HT_Resource node)
  5227. {
  5228.     HT_Resource    child;
  5229.     HT_View        view;
  5230.     HT_Pane        pane;
  5231.  
  5232.     if ((child = node->child) == NULL)    return;
  5233.     if ((view = child->view) == NULL)    return;
  5234.     if ((pane = view->pane) == NULL)    return;
  5235.  
  5236.     if (!HT_IsContainerOpen(node) && pane->autoFlushFlag == true)
  5237.     {
  5238.         /* destroy all interior HT nodes */
  5239.  
  5240.         destroyViewInt(node, PR_FALSE);
  5241.     }
  5242.     else
  5243.     {
  5244.         /* hide all interior HT nodes */
  5245.  
  5246.         while (child != NULL)
  5247.         {
  5248.             if ((node->flags & HT_HIDDEN_FLAG) || (!HT_IsContainerOpen(node)))
  5249.             {
  5250.                 child->flags |= HT_HIDDEN_FLAG;
  5251.             }
  5252.             else
  5253.             {
  5254.                 child->flags &= (~HT_HIDDEN_FLAG);
  5255.             }
  5256.             if (HT_IsContainer(child))
  5257.             {
  5258.                 setHiddenState(child);
  5259.             }
  5260.             child->flags &= (~HT_SELECTED_FLAG);
  5261.             child = child->next;
  5262.         }
  5263.     }
  5264. }
  5265.  
  5266.  
  5267.  
  5268. PR_PUBLIC_API(HT_Error)
  5269. HT_SetOpenState (HT_Resource containerNode, PRBool isOpen)
  5270. {
  5271.     SBProvider        sb;
  5272.  
  5273.     XP_ASSERT(containerNode != NULL);
  5274.  
  5275.     if ((isOpen && (!HT_IsContainerOpen(containerNode))) ||
  5276.        ((!isOpen) && (HT_IsContainerOpen(containerNode))))
  5277.     {
  5278.  
  5279. #ifdef    HT_PASSWORD_RTNS
  5280.         if (isOpen && (ht_hasPassword(containerNode)))
  5281.         {
  5282.             if (ht_checkPassword(containerNode, false) == PR_FALSE)
  5283.             {
  5284.                 return(HT_Err);
  5285.             }
  5286.         }
  5287. #endif
  5288.  
  5289.         if ((containerNode->view->inited == false)
  5290. #ifdef    XP_MAC
  5291.             /* Mac bookmark menu kludge */
  5292.            || (containerNode->view->pane->special == true)
  5293. #endif
  5294.         )
  5295.         {
  5296.             if (startsWith("ftp:", resourceID(containerNode->node)) ||
  5297.                 startsWith("ldap:", resourceID(containerNode->node)))
  5298.             {
  5299.                 return(HT_NoErr);
  5300.             }
  5301.         }
  5302.  
  5303.         sendNotification(containerNode,  HT_EVENT_NODE_OPENCLOSE_CHANGING);
  5304.         if (isOpen)
  5305.         {
  5306.             containerNode->flags |= HT_OPEN_FLAG;
  5307.         }
  5308.         else
  5309.         {
  5310.             containerNode->flags &= (~HT_OPEN_FLAG);
  5311.         }
  5312.         setHiddenState(containerNode);
  5313.         refreshItemList(containerNode, HT_EVENT_NODE_OPENCLOSE_CHANGED);
  5314.     }
  5315.  
  5316.     sb = SBProviderOfNode(containerNode);
  5317.     if (sb) sb->openp = isOpen;
  5318.  
  5319.     return (HT_NoErr);
  5320. }
  5321.  
  5322.  
  5323.  
  5324. PR_PUBLIC_API(HT_Error)
  5325. HT_SetSelectedState (HT_Resource node, PRBool isSelected)
  5326. {
  5327.     XP_ASSERT(node != NULL);
  5328.  
  5329.     if ((isSelected && (!HT_IsSelected(node))) ||
  5330.        ((!isSelected) && (HT_IsSelected(node))))
  5331.     {
  5332.         if (isSelected)
  5333.         {
  5334.             node->flags |= HT_SELECTED_FLAG;
  5335.         }
  5336.         else
  5337.         {
  5338.             node->flags &= (~HT_SELECTED_FLAG);
  5339.         }
  5340.         sendNotification(node,  HT_EVENT_NODE_SELECTION_CHANGED);
  5341.     }
  5342.     return (HT_NoErr);
  5343. }
  5344.  
  5345.  
  5346.  
  5347. PR_PUBLIC_API(HT_Error)
  5348. HT_SetNotificationMask (HT_Pane pane, HT_NotificationMask mask)
  5349. {
  5350.     XP_ASSERT(pane != NULL);
  5351.  
  5352.     pane->mask = mask;
  5353.     return (HT_NoErr);
  5354. }
  5355.  
  5356.  
  5357.  
  5358. PR_PUBLIC_API(HT_Error)
  5359. HT_GetOpenState (HT_Resource containerNode, PRBool *openState)
  5360. {
  5361.     XP_ASSERT(containerNode != NULL);
  5362.     XP_ASSERT(openState != NULL);
  5363.  
  5364.     *openState = (containerNode->flags & HT_OPEN_FLAG) ? PR_TRUE:PR_FALSE;
  5365.     return (HT_NoErr);
  5366. }
  5367.  
  5368.  
  5369.  
  5370. PR_PUBLIC_API(HT_Error)
  5371. HT_GetSelectedState (HT_Resource node, PRBool *selectedState)
  5372. {
  5373.     XP_ASSERT(node != NULL);
  5374.     XP_ASSERT(selectedState != NULL);
  5375.  
  5376.     if ((node != NULL) && (selectedState != NULL))
  5377.     {
  5378.         *selectedState = (node->flags & HT_SELECTED_FLAG) ? PR_TRUE:PR_FALSE;
  5379.     }
  5380.     return (HT_NoErr);
  5381. }
  5382.  
  5383.  
  5384.  
  5385. /*
  5386.     HT_SetSelection:
  5387.     Select a given node in a view, deselecting all other nodes
  5388. */
  5389.  
  5390. PR_PUBLIC_API(HT_Error)
  5391. HT_SetSelection (HT_Resource node)
  5392. {
  5393.     HT_Resource    res;
  5394.     HT_View        view;
  5395.     uint32        itemListCount,theIndex;
  5396.  
  5397.     XP_ASSERT(node != NULL);
  5398.     view = HT_GetView(node);
  5399.     XP_ASSERT(view != NULL);
  5400.  
  5401.     itemListCount = HT_GetItemListCount(view);
  5402.     for (theIndex=0; theIndex<itemListCount; theIndex++)
  5403.     {
  5404.         if ((res=HT_GetNthItem (view, theIndex)) != NULL)
  5405.         {
  5406.             HT_SetSelectedState (res, (res==node) ? true:false);
  5407.         }
  5408.     }
  5409.     return (HT_NoErr);
  5410. }
  5411.  
  5412.  
  5413.  
  5414.  
  5415. /*
  5416.     HT_SetSelectionAll:
  5417.     Select/Deselect all nodes for a given view
  5418. */
  5419.  
  5420. PR_PUBLIC_API(HT_Error)
  5421. HT_SetSelectionAll (HT_View view, PRBool selectedState)
  5422. {
  5423.     HT_Resource    res;
  5424.     uint32        itemListCount,theIndex;
  5425.  
  5426.     XP_ASSERT(view != NULL);
  5427.  
  5428.     itemListCount = HT_GetItemListCount(view);
  5429.     for (theIndex=0; theIndex<itemListCount; theIndex++)
  5430.     {
  5431.         if ((res=HT_GetNthItem (view, theIndex)) != NULL)
  5432.         {
  5433.             HT_SetSelectedState (res, selectedState);
  5434.         }
  5435.     }
  5436.     return HT_NoErr;
  5437. }
  5438.  
  5439.  
  5440.  
  5441. /*
  5442.     HT_SetSelectionRange:
  5443.     Select any/all nodes inbetween nodes "node1" and "node2", deselecting all other nodes
  5444.  
  5445.     Note: both "node1" and "node2" should be in the same view
  5446. */
  5447.  
  5448. PR_PUBLIC_API(HT_Error)
  5449. HT_SetSelectionRange (HT_Resource node1, HT_Resource node2)
  5450. {
  5451.     HT_Resource    res;
  5452.     HT_View        view,view2;
  5453.     uint32        itemListCount,theIndex;
  5454.     PRBool        selectionState = false, invertState;
  5455.  
  5456.     XP_ASSERT(node1 != NULL);
  5457.     XP_ASSERT(node2 != NULL);
  5458.     view = HT_GetView(node1);
  5459.     view2 = HT_GetView(node2);
  5460.     XP_ASSERT(view != NULL);
  5461.     XP_ASSERT(view2 != NULL);
  5462.     XP_ASSERT(view == view2);
  5463.  
  5464.     itemListCount = HT_GetItemListCount(view);
  5465.     for (theIndex=0; theIndex<itemListCount; theIndex++)
  5466.     {
  5467.         if ((res=HT_GetNthItem (view, theIndex)) != NULL)
  5468.         {
  5469.             /* note: can't just invert selectionState as 
  5470.                  need to be inclusive on ending node */
  5471.  
  5472.             invertState = ((res == node1) || (res == node2));
  5473.             if (invertState && selectionState == false)
  5474.             {
  5475.                 selectionState = true;
  5476.                 invertState = false;
  5477.             }
  5478.             HT_SetSelectedState (res, selectionState);
  5479.             if (invertState && selectionState == true)
  5480.             {
  5481.                 selectionState = false;
  5482.             }
  5483.         }
  5484.     }
  5485.     return HT_NoErr;
  5486. }
  5487.  
  5488.  
  5489.  
  5490. /*
  5491.     HT_GetNextSelection:
  5492.     if "startingNode" is NULL, get the first selected item (returns NULL if none);
  5493.     otherwise, find the first selected node AFTER "startingNode" (returns NULL if none)
  5494. */
  5495.  
  5496. PR_PUBLIC_API(HT_Resource)
  5497. HT_GetNextSelection(HT_View view, HT_Resource startingNode)
  5498. {
  5499.     HT_Resource    node, nextNode = NULL;
  5500.     uint32        itemListCount,theIndex;
  5501.     PRBool        selectedState;
  5502.  
  5503.     XP_ASSERT(view != NULL);
  5504.  
  5505.     itemListCount = HT_GetItemListCount(view);
  5506.  
  5507.     if ((startingNode != NULL) && (view->selectedNodeHint < itemListCount) &&
  5508.         HT_GetNthItem(view, view->selectedNodeHint) == startingNode)
  5509.     {
  5510.         theIndex = view->selectedNodeHint + 1;
  5511.     }
  5512.     else
  5513.     {
  5514.         theIndex = view->selectedNodeHint = 0;
  5515.     }
  5516.  
  5517.     for (; theIndex < itemListCount; theIndex++)
  5518.     {
  5519.         if ((node=HT_GetNthItem (view, theIndex)) != NULL)
  5520.         {
  5521.             if (node == startingNode)    continue;
  5522.             HT_GetSelectedState (node, &selectedState);
  5523.             if (selectedState == true)
  5524.             {
  5525.                 view->selectedNodeHint = (uint32)theIndex;
  5526.                 nextNode = node;
  5527.                 break;
  5528.             }
  5529.         }
  5530.     }
  5531.     return (nextNode);
  5532. }
  5533.  
  5534.  
  5535.  
  5536. /*
  5537.     HT_ToggleSelection:
  5538.     for a given node, unselect it if selected, otherwise select it
  5539. */
  5540.  
  5541. PR_PUBLIC_API(void)
  5542. HT_ToggleSelection(HT_Resource node)
  5543. {
  5544.     PRBool        selectedState;
  5545.  
  5546.     XP_ASSERT(node != NULL);
  5547.  
  5548.     HT_GetSelectedState (node, &selectedState);
  5549.     HT_SetSelectedState (node, !selectedState);
  5550. }
  5551.  
  5552.  
  5553.  
  5554. PR_PUBLIC_API(void)
  5555. HT_Launch(HT_Resource node)
  5556. {
  5557.     char        *filename =  resourceID(node->node);
  5558.  
  5559.     XP_ASSERT(node != NULL);
  5560.  
  5561. #ifdef    XP_PC
  5562.  
  5563.     if (startsWith("lfs:",filename) && endsWith(".exe",filename))
  5564.     {
  5565.         /* XXX could launch the .exe */
  5566.     }
  5567. #endif
  5568.  
  5569. }
  5570.  
  5571.  
  5572.  
  5573. PR_PUBLIC_API(HT_Error)
  5574. HT_GetNotificationMask (HT_Pane pane, HT_NotificationMask *mask)
  5575. {
  5576.     XP_ASSERT(pane != NULL);
  5577.     XP_ASSERT(mask != NULL);
  5578.  
  5579.     *mask = pane->mask;
  5580.     return (HT_NoErr);
  5581. }
  5582.  
  5583.  
  5584.  
  5585. PRBool
  5586. mutableContainerp (RDF_Resource node)
  5587. {
  5588.     XP_ASSERT(node != NULL);
  5589.  
  5590.     return (containerp(node) && (resourceType(node) == RDF_RT));
  5591. }
  5592.  
  5593.  
  5594.  
  5595. PR_PUBLIC_API(HT_Resource)
  5596. HT_MakeNewContainer(HT_Resource parent, char* name)
  5597. {
  5598.     HT_Resource        hnc = NULL;
  5599.     RDF            db;
  5600.     RDF_Resource        nc;
  5601.     char            *id = NULL;
  5602.  
  5603. #ifdef    NSPR20
  5604.     PRTime            tm;
  5605. #else
  5606.     int64            tm;
  5607. #endif
  5608.  
  5609. #ifndef    HAVE_LONG_LONG
  5610.     double            doubletm;
  5611. #endif
  5612.  
  5613.     if (mutableContainerp(parent->node))
  5614.     {
  5615.         db = parent->view->pane->db;
  5616.  
  5617. #ifdef NSPR20
  5618.         tm = PR_Now();
  5619. #else
  5620.         tm = PR_LocalTime();
  5621. #endif
  5622.  
  5623. #ifdef HAVE_LONG_LONG
  5624.         id = PR_smprintf("Topic%d", (double)tm);
  5625. #else
  5626.         LL_L2D(doubletm, tm);
  5627.         id = PR_smprintf("Topic%d.rdf", doubletm);
  5628. #endif
  5629.         nc = RDF_GetResource(db, id, 1);
  5630.         setContainerp(nc, 1);
  5631.  
  5632.         RDF_Assert(db, nc, gCoreVocab->RDF_name, name, RDF_STRING_TYPE);
  5633.         RDF_Assert(db, nc, gCoreVocab->RDF_parent, parent->node, RDF_RESOURCE_TYPE);
  5634.         RDF_Assert(db, nc, gCoreVocab->RDF_name, name, RDF_STRING_TYPE); 
  5635.         hnc = newHTEntry(parent->view, nc);
  5636.  
  5637.         refreshItemList(parent, HT_EVENT_NODE_ADDED);
  5638.     }
  5639.     return (hnc);
  5640. }
  5641.  
  5642.  
  5643.  
  5644. PR_PUBLIC_API(HT_DropAction)
  5645. HT_CanDropHTROn(HT_Resource dropTarget, HT_Resource obj)
  5646. {
  5647.     return dropOn (dropTarget, obj, 1) ;
  5648. }
  5649.  
  5650.  
  5651.  
  5652. PR_PUBLIC_API(HT_DropAction)
  5653. HT_CanDropURLOn(HT_Resource dropTarget, char* url)
  5654. {
  5655.     return dropURLOn(dropTarget, url, NULL, 1);
  5656. }
  5657.  
  5658.  
  5659.  
  5660. PR_PUBLIC_API(HT_DropAction)
  5661. HT_DropHTROn(HT_Resource dropTarget, HT_Resource obj)
  5662. {
  5663.     HT_DropAction        ac;
  5664.  
  5665.     ac = dropOn(dropTarget, obj, 0);                    
  5666.     resynchContainer (dropTarget);
  5667.     refreshItemList(dropTarget, HT_EVENT_VIEW_REFRESH);
  5668.     return (ac);
  5669. }
  5670.  
  5671.  
  5672.  
  5673. PR_PUBLIC_API(HT_DropAction)
  5674. HT_DropURLOn(HT_Resource dropTarget, char* url)
  5675. {
  5676.     HT_DropAction        ac;
  5677.  
  5678.     ac = dropURLOn(dropTarget, url, NULL, 0);
  5679.     resynchContainer (dropTarget);
  5680.     refreshItemList(dropTarget, HT_EVENT_VIEW_REFRESH);
  5681.     return (ac);
  5682. }
  5683.  
  5684.  
  5685.  
  5686. void
  5687. possiblyCleanUpTitle (char* title)
  5688. {
  5689.     int16 n = charSearch(-51, title);
  5690.     if (n > -1) title[n] = '\0';
  5691. }
  5692.  
  5693.  
  5694.  
  5695. PR_PUBLIC_API(HT_DropAction)
  5696. HT_DropURLAndTitleOn(HT_Resource dropTarget, char* url, char *title)
  5697. {
  5698.     HT_DropAction        ac;
  5699.  
  5700.     possiblyCleanUpTitle(title);
  5701.     ac = dropURLOn(dropTarget, url, title, 0);
  5702.     resynchContainer (dropTarget);
  5703.     refreshItemList(dropTarget, HT_EVENT_VIEW_REFRESH);
  5704.     return (ac);
  5705. }
  5706.  
  5707.  
  5708.  
  5709. PR_PUBLIC_API(HT_DropAction)
  5710. HT_CanDropHTRAtPos(HT_Resource dropTarget, HT_Resource obj, PRBool before)
  5711. {
  5712.     HT_Resource        dropParent;
  5713.     HT_DropAction        ok;
  5714.  
  5715.     dropParent = dropTarget->parent;
  5716.     ok = dropOn(dropParent, obj, 1);
  5717.     if (ok && nlocalStoreHasAssertion(gLocalStore, dropTarget->node,
  5718.         gCoreVocab->RDF_parent, dropParent->node, RDF_RESOURCE_TYPE, 1))
  5719.     {
  5720.     }
  5721.     else
  5722.     {
  5723.         ok = DROP_NOT_ALLOWED;
  5724.     }
  5725.     return (ok);
  5726. }
  5727.  
  5728.     
  5729.   
  5730. PR_PUBLIC_API(HT_DropAction)
  5731. HT_CanDropURLAtPos(HT_Resource dropTarget, char* url, PRBool before)
  5732. {
  5733.     HT_Resource        dropParent;
  5734.     HT_DropAction        ok;
  5735.  
  5736.     dropParent = dropTarget->parent;
  5737.     ok = dropURLOn(dropParent, url, NULL, 1);
  5738.     if (ok &&  nlocalStoreHasAssertion(gLocalStore, dropTarget->node,
  5739.         gCoreVocab->RDF_parent, dropParent->node, RDF_RESOURCE_TYPE, 1))
  5740.     {
  5741.     }
  5742.     else
  5743.     {
  5744.         ok = DROP_NOT_ALLOWED;
  5745.     }
  5746.     return (ok);
  5747. }
  5748.  
  5749.  
  5750.  
  5751. PR_PUBLIC_API(HT_DropAction)
  5752. HT_DropHTRAtPos(HT_Resource dropTarget, HT_Resource obj, PRBool before)
  5753. {
  5754.     HT_DropAction        ac;
  5755.  
  5756.     ac = copyMoveRDFLinkAtPos(dropTarget, obj, before);
  5757.     resynchContainer (dropTarget->parent);
  5758.     refreshItemList(dropTarget, HT_EVENT_VIEW_REFRESH);
  5759.     return (ac);
  5760. }
  5761.  
  5762.  
  5763.  
  5764. PR_PUBLIC_API(HT_DropAction)
  5765. HT_DropURLAtPos(HT_Resource dropTarget, char* url, PRBool before)
  5766. {
  5767.     HT_DropAction        ac;
  5768.  
  5769.     ac = copyRDFLinkURLAt(dropTarget, url, NULL, before);
  5770.     resynchContainer (dropTarget->parent);
  5771.     refreshItemList(dropTarget, HT_EVENT_VIEW_REFRESH);
  5772.     return (ac);
  5773. }
  5774.  
  5775.  
  5776.  
  5777. PR_PUBLIC_API(HT_DropAction)
  5778. HT_DropURLAndTitleAtPos(HT_Resource dropTarget, char* url, char *title, PRBool before)
  5779. {
  5780.     HT_DropAction        ac;
  5781.  
  5782.     possiblyCleanUpTitle(title);
  5783.     ac = copyRDFLinkURLAt(dropTarget, url, title, before);
  5784.     resynchContainer (dropTarget->parent);
  5785.     refreshItemList(dropTarget, HT_EVENT_VIEW_REFRESH);
  5786.     return (ac);
  5787. }
  5788.  
  5789.  
  5790.  
  5791. PRBool
  5792. htRemoveChild(HT_Resource parent, HT_Resource child, PRBool moveToTrash)
  5793. {
  5794.     RDF_Resource        r;
  5795.     RDF_BT            type;
  5796.  
  5797.     /* disallow various nodes from being removed */
  5798.  
  5799.     if (child->node == gNavCenter->RDF_HistoryBySite ||
  5800.         child->node == gNavCenter->RDF_HistoryByDate)
  5801.     {
  5802.         return(true);
  5803.     }
  5804.     if ((r = RDFUtil_GetPTFolder()) != NULL)
  5805.     {
  5806.         if (child->node == r)    return(true);
  5807.     }
  5808.     if ((r = RDFUtil_GetNewBookmarkFolder()) != NULL)
  5809.     {
  5810.         if (child->node == r)    return(true);
  5811.     }
  5812.     if (htIsOpLocked(child, gNavCenter->RDF_DeleteLock))
  5813.     {
  5814.         return(true);
  5815.     }
  5816.  
  5817.     type = resourceType(child->node);
  5818.     if ((type == LFS_RT) || (type == ES_RT) || (type == FTP_RT))
  5819.     {
  5820.         if (moveToTrash == false)
  5821.         {
  5822.             if (HT_IsContainer(child))
  5823.             {
  5824.                 if (!FE_Confirm(((MWContext *)gRDFMWContext()),
  5825.                     PR_smprintf(XP_GetString(RDF_DELETEFOLDER),
  5826.                     resourceID(child->node))))    return(true);
  5827.                 if (fsRemoveDir( resourceID(child->node), true) == true)
  5828.                 {
  5829.                     FE_Alert(((MWContext *)gRDFMWContext()),
  5830.                         PR_smprintf(XP_GetString(RDF_UNABLETODELETEFOLDER),
  5831.                         resourceID(child->node)));
  5832.                     return(true);
  5833.                 }
  5834.             }
  5835.             else
  5836.             {
  5837.                 if (!FE_Confirm(((MWContext *)gRDFMWContext()),
  5838.                     PR_smprintf(XP_GetString(RDF_DELETEFILE),
  5839.                      resourceID(child->node))))    return(true);
  5840.                 if (CallPRWriteAccessFileUsingFileURL(resourceID(child->node)))
  5841.                 {
  5842.                     FE_Alert(((MWContext *)gRDFMWContext()),
  5843.                         PR_smprintf(XP_GetString(RDF_UNABLETODELETEFILE),
  5844.                         resourceID(child->node)));
  5845.                     return(true);
  5846.                 }
  5847.             }
  5848.         }
  5849.         else
  5850.         {
  5851.             /*
  5852.                 hack type so that the object can be unasserted
  5853.                 without the actual file/folder being deleted
  5854.             */
  5855.             nlocalStoreUnassert (gLocalStore, child->node,
  5856.                 gCoreVocab->RDF_parent, parent->node, RDF_RESOURCE_TYPE);
  5857.             return(false);
  5858.         }
  5859.     }
  5860.  
  5861.     /* assert into trash? */
  5862.  
  5863.     if (moveToTrash == true)
  5864.     {
  5865.         RDF_Assert(parent->view->pane->db, child->node, gCoreVocab->RDF_parent,
  5866.             gNavCenter->RDF_Trash, RDF_RESOURCE_TYPE);
  5867.     }
  5868.     RDF_Unassert(parent->view->pane->db, child->node, gCoreVocab->RDF_parent,
  5869.         parent->node, RDF_RESOURCE_TYPE);
  5870.     return(false);
  5871. }
  5872.  
  5873.  
  5874.  
  5875. PR_PUBLIC_API(PRBool)
  5876. HT_RemoveChild (HT_Resource parent, HT_Resource child)
  5877. {
  5878.     PRBool            retVal;
  5879.  
  5880.     retVal = htRemoveChild(parent, child, true);
  5881.     refreshPanes(false, false, NULL);
  5882.     return(retVal);
  5883. }
  5884.  
  5885.  
  5886.  
  5887. PR_PUBLIC_API(void*)
  5888. HT_GetViewFEData (HT_View view)
  5889. {
  5890.     return view->pdata;
  5891. }
  5892.  
  5893.  
  5894.  
  5895. PR_PUBLIC_API(void)
  5896. HT_SetViewFEData(HT_View view, void* data)
  5897. {
  5898.     view->pdata = data;
  5899. }
  5900.  
  5901.  
  5902.  
  5903. PR_PUBLIC_API(void*)
  5904. HT_GetPaneFEData (HT_Pane pane)
  5905. {
  5906.     return pane->pdata;
  5907. }
  5908.  
  5909.  
  5910.  
  5911. PR_PUBLIC_API(void)
  5912. HT_SetPaneFEData (HT_Pane pane, void* data)
  5913. {
  5914.     pane->pdata = data;
  5915. }
  5916.  
  5917.  
  5918.  
  5919. PR_PUBLIC_API(void*)
  5920. HT_GetNodeFEData (HT_Resource node)
  5921. {
  5922.     return node->feData;
  5923. }
  5924.  
  5925.  
  5926.  
  5927. PR_PUBLIC_API(void)
  5928. HT_SetNodeFEData (HT_Resource node, void* data)
  5929. {
  5930.     node->feData = data;
  5931. }
  5932.  
  5933.  
  5934.  
  5935. #ifdef    HT_PASSWORD_RTNS
  5936.  
  5937.  
  5938.  
  5939. void
  5940. ht_SetPassword(HT_Resource node, char *newPassword)
  5941. {
  5942.     char        *activePassword;
  5943.  
  5944.     XP_ASSERT(node != NULL);
  5945.     XP_ASSERT(newPassword != NULL);
  5946.  
  5947.     if ((activePassword = RDF_GetSlotValue(node->view->pane->db, node->node,
  5948.             gNavCenter->RDF_Password, RDF_STRING_TYPE, false, true)) != NULL)
  5949.     {
  5950.         RDF_Unassert(node->view->pane->db, node->node,
  5951.             gNavCenter->RDF_Password, activePassword, RDF_STRING_TYPE);
  5952.  
  5953. #ifdef    DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  5954.         freeMem(activePassword);
  5955. #endif
  5956.     }
  5957.     if ((newPassword != NULL) && (((char *)newPassword)[0] != '\0'))
  5958.     {
  5959.         RDF_Assert(node->view->pane->db, node->node, gNavCenter->RDF_Password,
  5960.             newPassword, RDF_STRING_TYPE);
  5961.     }
  5962.     else
  5963.     {
  5964.         node->flags &= (~HT_PASSWORDOK_FLAG);
  5965.     }
  5966. }
  5967.  
  5968.  
  5969.  
  5970. PRBool
  5971. ht_hasPassword(HT_Resource node)
  5972. {
  5973.     char        *activePassword;
  5974.     PRBool        hasPasswordFlag = PR_FALSE;
  5975.  
  5976.     if ((activePassword = RDF_GetSlotValue(node->view->pane->db, node->node,
  5977.             gNavCenter->RDF_Password, RDF_STRING_TYPE, false, true)) != NULL)
  5978.     {
  5979.         if ((activePassword != NULL) && (activePassword[0] != '\0'))
  5980.         {
  5981.             hasPasswordFlag = PR_TRUE;
  5982.         }
  5983.  
  5984. #ifdef    DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  5985.         freeMem(activePassword);
  5986. #endif
  5987.     }
  5988.     return(hasPasswordFlag);
  5989. }
  5990.  
  5991.  
  5992.  
  5993. PRBool
  5994. ht_checkPassword(HT_Resource node, PRBool alwaysCheck)
  5995. {
  5996.     char        *activePassword, *userPassword, *name;
  5997.     PRBool        granted = PR_TRUE;
  5998.  
  5999.     XP_ASSERT(node != NULL);
  6000.     XP_ASSERT(node->view != NULL);
  6001.     XP_ASSERT(node->view->pane != NULL);
  6002.     XP_ASSERT(node->view->pane->db != NULL);
  6003.     XP_ASSERT(node->node != NULL);
  6004.  
  6005.  
  6006.     if ((alwaysCheck == false) && (node->flags & HT_PASSWORDOK_FLAG))    return(granted);
  6007.  
  6008.     if ((activePassword = RDF_GetSlotValue(node->view->pane->db, node->node,
  6009.             gNavCenter->RDF_Password, RDF_STRING_TYPE, false, true)) != NULL)
  6010.     {
  6011.         if ((activePassword != NULL) && (activePassword[0] != '\0'))
  6012.         {
  6013.             granted = PR_FALSE;
  6014.  
  6015.             if (!(name = HT_GetNodeName(node)))
  6016.             {
  6017.                 name =      resourceID(node->node);
  6018.             }
  6019.  
  6020.             if ((userPassword = FE_PromptPassword(((MWContext *)gRDFMWContext()),
  6021.                         PR_smprintf(XP_GetString(RDF_ENTERPASSWORD),
  6022.                         name))) != NULL)
  6023.             {
  6024.                 if (!strcmp(activePassword, userPassword))
  6025.                 {
  6026.                     node->flags |= HT_PASSWORDOK_FLAG;
  6027.                     granted = PR_TRUE;
  6028.                 }
  6029.                 else
  6030.                 {
  6031.                     FE_Alert(((MWContext *)gRDFMWContext()), XP_GetString(RDF_MISMATCHPASSWORD));
  6032.                 }
  6033.             }
  6034.         }
  6035.  
  6036. #ifdef    DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  6037.         freeMem(activePassword);
  6038. #endif
  6039.  
  6040.     }
  6041.     return(granted);
  6042. }
  6043.  
  6044.  
  6045.  
  6046. #endif
  6047.  
  6048.  
  6049.  
  6050. PR_PUBLIC_API(HT_Error)
  6051. HT_SetSelectedView (HT_Pane pane, HT_View view)
  6052. {
  6053.     HT_Notification        ns;
  6054.     char            *advertURL;
  6055.  
  6056.     XP_ASSERT(pane != NULL);
  6057.     if (pane == NULL)    return(HT_NoErr);
  6058.     XP_ASSERT(pane->db != NULL);
  6059.  
  6060.     if (pane->selectedView != view)
  6061.     {
  6062. #ifdef    HT_PASSWORD_RTNS
  6063.         if (view != NULL)
  6064.         {
  6065.             if (ht_hasPassword(view->top))
  6066.             {
  6067.                 if (ht_checkPassword(view->top, false) == PR_FALSE)    return(HT_Err);
  6068.             }
  6069.         }
  6070. #endif
  6071.         pane->selectedView = view;
  6072.         if (view != NULL)
  6073.         {
  6074.             if (!HT_IsContainer(view->top))    return(HT_Err);
  6075.             RDFUtil_SetDefaultSelectedView(view->top->node);
  6076.             if (view->itemListCount == 0)
  6077.             {
  6078.                 HT_SetOpenState(view->top, PR_TRUE);
  6079. #ifdef WIN32
  6080.                 advertURL = advertURLOfContainer(pane->db, view->top->node);
  6081.                 if (advertURL != NULL)
  6082.                 {
  6083.                     XP_GetURLForView(view, advertURL);
  6084.                     freeMem(advertURL);
  6085.                 }
  6086. #endif
  6087.             } 
  6088.             sendNotification(view->top, HT_EVENT_VIEW_SELECTED);
  6089.         }
  6090.         else
  6091.         {
  6092.             RDFUtil_SetDefaultSelectedView(NULL);
  6093.  
  6094.             /*
  6095.                sendNotification() doesn't accept a NULL node,
  6096.                so send the event directly from here
  6097.             */
  6098.  
  6099.             if (pane->mask & HT_EVENT_VIEW_SELECTED)
  6100.             {
  6101.                 if ((ns = pane->ns) != NULL)
  6102.                 {
  6103.                     if (ns->notifyProc != NULL)
  6104.                     {
  6105.                         (*ns->notifyProc)(ns, NULL,
  6106.                             HT_EVENT_VIEW_SELECTED);
  6107.                     }
  6108.                 }
  6109.             }
  6110.         }
  6111.     }
  6112.     return(HT_NoErr);
  6113. }
  6114.  
  6115.  
  6116.  
  6117. PR_PUBLIC_API(HT_View)
  6118. HT_GetSelectedView (HT_Pane pane)
  6119. {
  6120.     HT_View        view = NULL;
  6121.  
  6122.     XP_ASSERT(pane != NULL);
  6123.  
  6124.     if (pane != NULL)
  6125.     {
  6126.         view = pane->selectedView;
  6127.     }
  6128.     return(view);
  6129. }
  6130.  
  6131.  
  6132.  
  6133. PR_PUBLIC_API(HT_View)
  6134. HT_GetViewType (HT_Pane pane, HT_ViewType viewType)
  6135. {
  6136.     HT_Resource    node;
  6137.     HT_View        view = NULL;
  6138.     RDF_Resource    resToFind = NULL;
  6139.  
  6140.     XP_ASSERT(pane != NULL);
  6141.  
  6142.     switch(viewType)
  6143.     {
  6144.         case    HT_VIEW_BOOKMARK:
  6145.         resToFind = gNavCenter->RDF_BookmarkFolderCategory;
  6146.         break;
  6147.  
  6148.         case    HT_VIEW_HISTORY:
  6149.         resToFind = gNavCenter->RDF_History;
  6150.         break;
  6151.  
  6152.         case    HT_VIEW_SITEMAP:
  6153.         resToFind = gNavCenter->RDF_Sitemaps;
  6154.         break;
  6155.  
  6156.         default:
  6157.         resToFind = NULL;
  6158.         break;
  6159.     }
  6160.     if (resToFind != NULL)
  6161.     {
  6162.         view = pane->viewList;
  6163.         while(view != NULL)
  6164.         {
  6165.             if ((node = HT_TopNode(view)) != NULL)
  6166.             {
  6167.                 if (node->node == resToFind)
  6168.                 {
  6169.                     break;
  6170.                 }
  6171.             }
  6172.             view = view->next;
  6173.         }
  6174.     }
  6175.     return(view);
  6176. }
  6177.  
  6178.  
  6179.  
  6180. PR_PUBLIC_API(HT_Pane)
  6181. HT_GetPane (HT_View view)
  6182. {
  6183.     XP_ASSERT(view != NULL);
  6184.  
  6185.     return view->pane;
  6186. }
  6187.  
  6188.  
  6189.  
  6190. /*******************************************************************************/
  6191. /*                             Drag and Drop Stuff                             */
  6192. /*******************************************************************************/
  6193.  
  6194.  
  6195.  
  6196. HT_DropAction
  6197. dropOn (HT_Resource dropTarget, HT_Resource dropObject, PRBool justAction)
  6198. {
  6199.     HT_Resource        elders, parent;
  6200.     RDF_BT            targetType;
  6201.     RDF_BT            objType;
  6202.  
  6203.     if (dropTarget == NULL)    return(DROP_NOT_ALLOWED);
  6204.     if (dropObject == NULL)    return(DROP_NOT_ALLOWED);
  6205.  
  6206.     targetType  = resourceType(dropTarget->node);
  6207.     objType     = resourceType(dropObject->node);
  6208.  
  6209.     if (!containerp(dropTarget->node))    return DROP_NOT_ALLOWED;
  6210.     if (objType == HISTORY_RT)        return DROP_NOT_ALLOWED;
  6211.  
  6212.     /* disallow dropping a parent folder into itself or a child folder */
  6213.     elders = dropTarget;
  6214.     while (elders != NULL)
  6215.     {
  6216.         if (elders == dropObject)  return DROP_NOT_ALLOWED;
  6217.         elders = elders->parent;
  6218.     }
  6219.  
  6220.     switch (targetType) 
  6221.     {
  6222.         case SEARCH_RT:
  6223.         case HISTORY_RT:
  6224.         return DROP_NOT_ALLOWED;
  6225.         break;
  6226.  
  6227.         case LFS_RT:
  6228. #ifdef XP_WIN32
  6229.         if (objType == LFS_RT)
  6230.         {
  6231.             if (justAction)
  6232.             {
  6233.                 return COPY_MOVE_CONTENT;
  6234.             }
  6235.             else
  6236.             {
  6237.                 parent = dropObject->parent;
  6238.                 Win32FileCopyMove(dropTarget, dropObject);
  6239.                 destroyViewInt(dropTarget, PR_FALSE);
  6240.                 refreshItemList (dropTarget, HT_EVENT_VIEW_REFRESH);
  6241.                 destroyViewInt(parent, PR_FALSE);
  6242.                 refreshItemList (parent, HT_EVENT_VIEW_REFRESH);
  6243.                 return COPY_MOVE_CONTENT;
  6244.             } 
  6245.         }
  6246.         else
  6247.         return DROP_NOT_ALLOWED;
  6248. #else
  6249.         return DROP_NOT_ALLOWED;
  6250. #endif
  6251.         break;
  6252.   
  6253.         case FTP_RT:
  6254.         case ES_RT:
  6255.         if ((objType == ES_RT) || (objType == FTP_RT))
  6256.         {
  6257.             if (justAction)
  6258.             {
  6259.                 return COPY_MOVE_CONTENT;
  6260.             }
  6261.             else
  6262.             {
  6263.                 return esfsCopyMoveContent(dropTarget, dropObject);
  6264.             }
  6265.         }
  6266.         else if (containerp(dropObject->node) && (objType == RDF_RT))
  6267.         {
  6268.             if (justAction)
  6269.             {
  6270.                 return UPLOAD_RDF;
  6271.             }
  6272.             else
  6273.             {
  6274.                 return uploadRDFFile(dropTarget, dropObject);
  6275.             }
  6276.         }
  6277.         else if (objType == LFS_RT)
  6278.         {
  6279.             if (justAction)
  6280.             {
  6281.                 return UPLOAD_LFS;
  6282.             }
  6283.             else
  6284.             {
  6285.                 return uploadLFS(dropTarget, dropObject);
  6286.             }
  6287.         }
  6288.         return DROP_NOT_ALLOWED;
  6289.         break;
  6290.  
  6291.         case LDAP_RT:
  6292.         case RDF_RT :
  6293.         if (justAction)
  6294.         {
  6295.             return COPY_MOVE_LINK;
  6296.         }
  6297.         else
  6298.         {
  6299.             return copyMoveRDFLink(dropTarget, dropObject);
  6300.         }
  6301.     }
  6302.     return DROP_NOT_ALLOWED;
  6303. }
  6304.  
  6305.  
  6306.  
  6307. #ifdef XP_WIN32
  6308.  
  6309. /* We forgot we were not supposed to implement this */
  6310.  
  6311. #include "windows.h"
  6312. #include "xp_file.h"
  6313. #include "shellapi.h"
  6314.  
  6315. void
  6316. Win32FileCopyMove(HT_Resource dropTarget, HT_Resource dropObject)
  6317. {
  6318.     char        *from =  resourceID(dropObject->node);
  6319.     char        *to =  resourceID(dropTarget->node);
  6320.     char        *lffrom;
  6321.     char        *lfto;
  6322.     char        *finalFrom;
  6323.     char        *finalTo;
  6324.     size_t        fl,ft;
  6325.     SHFILEOPSTRUCT    action;
  6326.  
  6327.     memset(&action, 0, sizeof(action));
  6328.     XP_ConvertUrlToLocalFile(from, &lffrom) ;
  6329.     XP_ConvertUrlToLocalFile(to, &lfto);
  6330.  
  6331.     fl = strlen(lffrom);
  6332.     ft = strlen(lfto);
  6333.  
  6334.     finalFrom = (char *)getMem(fl+2);
  6335.     finalTo = (char *)getMem(ft+2);
  6336.  
  6337.     strcpy(finalFrom, lffrom);
  6338.     strcpy(finalTo, lfto);
  6339.  
  6340.     finalFrom[fl+1] = '\0';
  6341.     finalTo[ft+1] = '\0';
  6342.  
  6343.     action.hwnd = NULL;
  6344.     action.wFunc = (from[8] == to[8] ? FO_MOVE : FO_COPY);
  6345.     action.pFrom = finalFrom;
  6346.     action.pTo = finalTo;
  6347.     action.fFlags = FOF_ALLOWUNDO;
  6348.  
  6349.     SHFileOperation(&action);
  6350.  
  6351.     freeMem(finalFrom);
  6352.     freeMem(finalTo);
  6353.  
  6354. }
  6355. #endif
  6356.  
  6357.  
  6358.  
  6359. HT_DropAction
  6360. copyMoveRDFLink (HT_Resource dropTarget, HT_Resource dropObject)
  6361. {
  6362.     HT_Resource        origin;
  6363.     RDF            db;
  6364.     RDF_Resource        old,new,obj;
  6365.     PRBool            moveAction;
  6366.     char            *name;
  6367.  
  6368.     XP_ASSERT(dropTarget != NULL);
  6369.     XP_ASSERT(dropObject != NULL);
  6370.     if ((dropTarget == NULL) || (dropObject == NULL))    return(DROP_NOT_ALLOWED);
  6371.  
  6372.     origin = dropObject->parent;
  6373.     db = dropTarget->view->pane->db;
  6374.     moveAction = ((origin != NULL) && 
  6375.             (origin->view->top->node == dropTarget->view->top->node));
  6376.     old = (origin == NULL ? NULL : origin->node);
  6377.     new = dropTarget->node;
  6378.     obj = dropObject->node;
  6379.     name = RDF_GetSlotValue(db, obj, gCoreVocab->RDF_name, RDF_STRING_TYPE, 0, 1);
  6380.     if (name != NULL)
  6381.     {
  6382.         RDF_Assert(db, obj, gCoreVocab->RDF_name, name, RDF_STRING_TYPE);
  6383.  
  6384. #ifdef    DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  6385.         freeMem(name);
  6386. #endif
  6387.     }
  6388.  
  6389.     /* drag&drops between personal toolbar and bookmark view should be a move action */
  6390.     if ((!moveAction) && (origin != NULL))
  6391.     {
  6392.         if ((origin->view->pane->personaltoolbar == true && 
  6393.             dropTarget->view->top->node == gNavCenter->RDF_BookmarkFolderCategory) || 
  6394.             ((dropTarget->view->pane->personaltoolbar == true && 
  6395.             origin->view->top->node == gNavCenter->RDF_BookmarkFolderCategory)))
  6396.         {
  6397.             moveAction = PR_TRUE;
  6398.         }
  6399.     }
  6400.  
  6401.     
  6402.     /* ensure object can copy/move, and target accepts additions */
  6403.     if (htIsOpLocked(dropObject, ((moveAction) ? 
  6404.         gNavCenter->RDF_MoveLock : gNavCenter->RDF_CopyLock)))
  6405.     {
  6406.         return(DROP_NOT_ALLOWED);
  6407.     }
  6408.     if (htIsOpLocked(dropTarget, gNavCenter->RDF_AddLock))
  6409.     {
  6410.         return(DROP_NOT_ALLOWED);
  6411.     }
  6412.  
  6413.     if (moveAction && old)
  6414.     {
  6415.         RDF_Unassert(db, obj, gCoreVocab->RDF_parent, old, RDF_RESOURCE_TYPE);
  6416.     }
  6417.     RDF_Assert(db, obj, gCoreVocab->RDF_parent, new, RDF_RESOURCE_TYPE);
  6418.     return COPY_MOVE_LINK;      
  6419. }
  6420.  
  6421.  
  6422.  
  6423. HT_DropAction
  6424. copyMoveRDFLinkAtPos (HT_Resource dropx, HT_Resource dropObject, PRBool before)
  6425. {
  6426.     HT_Resource        origin;
  6427.     HT_Resource        dropTarget;
  6428.     RDF            db;
  6429.     RDF_Resource        old;
  6430.     RDF_Resource        parent;
  6431.     RDF_Resource        obj;
  6432.     PRBool            moveAction;
  6433.     char            *name;
  6434.  
  6435.     if (dropx == NULL)    return(DROP_NOT_ALLOWED);
  6436.     if (dropObject == NULL)    return(DROP_NOT_ALLOWED);
  6437.  
  6438.     origin = dropObject->parent;
  6439.     dropTarget = dropx->parent;
  6440.     db = dropTarget->view->pane->db;
  6441.     moveAction = ((origin != NULL) && 
  6442.             (origin->view->top->node == dropTarget->view->top->node));
  6443.     old = (origin == NULL ? NULL : origin->node);
  6444.       parent = dropTarget->node;
  6445.     obj = dropObject->node;
  6446.     name = RDF_GetSlotValue(db, obj, gCoreVocab->RDF_name, RDF_STRING_TYPE, 0, 1);
  6447.     if (name != NULL)
  6448.     {
  6449.         RDF_Assert(db, obj, gCoreVocab->RDF_name, copyString(name), RDF_STRING_TYPE);
  6450.  
  6451. #ifdef    DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  6452.         freeMem(name);
  6453. #endif
  6454.     }
  6455.  
  6456.     /* drag&drops between personal toolbar and bookmark view should be a move action */
  6457.     if ((!moveAction) && (origin != NULL))
  6458.     {
  6459.         if ((origin->view->pane->personaltoolbar == true && 
  6460.             dropTarget->view->top->node == gNavCenter->RDF_BookmarkFolderCategory) || 
  6461.             ((dropTarget->view->pane->personaltoolbar == true && 
  6462.             origin->view->top->node == gNavCenter->RDF_BookmarkFolderCategory)))
  6463.         {
  6464.             moveAction = PR_TRUE;
  6465.         }
  6466.     }
  6467.  
  6468.     
  6469.     /* ensure object can copy/move, and target accepts additions */
  6470.     if (htIsOpLocked(dropObject, ((moveAction) ? 
  6471.         gNavCenter->RDF_MoveLock : gNavCenter->RDF_CopyLock)))
  6472.     {
  6473.         return(DROP_NOT_ALLOWED);
  6474.     }
  6475.     if (htIsOpLocked(dropTarget, gNavCenter->RDF_AddLock))
  6476.     {
  6477.         return(DROP_NOT_ALLOWED);
  6478.     }
  6479.  
  6480.     if (moveAction && old)
  6481.     {
  6482.         RDF_Unassert(db, obj, gCoreVocab->RDF_parent, old, RDF_RESOURCE_TYPE);
  6483.     }
  6484.     nlocalStoreUnassert(gLocalStore, obj, gCoreVocab->RDF_parent, parent, RDF_RESOURCE_TYPE);
  6485.     nlocalStoreAddChildAt(gLocalStore, parent, dropx->node, obj, before);
  6486.     return COPY_MOVE_LINK;      
  6487. }
  6488.  
  6489.  
  6490.  
  6491. HT_DropAction
  6492. uploadLFS (HT_Resource dropTarget, HT_Resource dropObject)
  6493. {
  6494.     XP_ASSERT(dropTarget != NULL);
  6495.     XP_ASSERT(dropObject != NULL);
  6496.  
  6497.     if ((dropTarget != NULL) && (dropObject != NULL))
  6498.     {
  6499.         RDF_Assert(gNCDB, dropObject->node, gCoreVocab->RDF_parent,
  6500.             dropTarget->node, RDF_RESOURCE_TYPE);
  6501.     }
  6502.     return 0;
  6503. }
  6504.  
  6505.  
  6506.  
  6507. HT_DropAction
  6508. uploadRDFFile (HT_Resource dropTarget, HT_Resource dropObject)
  6509. {
  6510.     return 0;
  6511.  
  6512.  
  6513.  
  6514. HT_DropAction
  6515. esfsCopyMoveContent (HT_Resource dropTarget, HT_Resource dropObject)
  6516. {
  6517.     return 0;
  6518. }
  6519.  
  6520.  
  6521.  
  6522. RDF_BT
  6523. urlResourceType (char* url)
  6524. {
  6525.     if (startsWith("file:", url)) return LFS_RT;
  6526.     return RDF_RT;
  6527. }
  6528.  
  6529.  
  6530.  
  6531. HT_DropAction
  6532. dropURLOn (HT_Resource dropTarget, char* objURL, char *objTitle, PRBool justAction)
  6533. {
  6534.     RDF_BT            targetType;
  6535.     RDF_BT            objType;
  6536.  
  6537.     if (dropTarget == NULL)    return(DROP_NOT_ALLOWED);
  6538.     if (objURL == NULL)    return(DROP_NOT_ALLOWED);
  6539.  
  6540.     targetType  = resourceType(dropTarget->node);
  6541.     objType     = urlResourceType(objURL);
  6542.  
  6543.     if (!containerp(dropTarget->node)) return DROP_NOT_ALLOWED;
  6544.     if (objType == HISTORY_RT) return DROP_NOT_ALLOWED;
  6545.  
  6546.     switch (targetType) 
  6547.     {
  6548.         case LFS_RT:
  6549.         case SEARCH_RT:
  6550.         case HISTORY_RT:
  6551.         return 0;
  6552.         break;
  6553.   
  6554.         case FTP_RT:
  6555.         case ES_RT:
  6556.         if ((objType == ES_RT) || (objType == FTP_RT))
  6557.         {
  6558.             if (justAction)
  6559.             {
  6560.                 return COPY_MOVE_CONTENT;
  6561.             }
  6562.             else
  6563.             {
  6564.                 return esfsCopyMoveContentURL(dropTarget, objURL);
  6565.             }
  6566.         }
  6567.         else if (0 /*containerp(objURL) can never be true */ && (objType == RDF_RT))
  6568.         {
  6569.             if (justAction)
  6570.             {
  6571.                 return UPLOAD_RDF;
  6572.             }
  6573.             else
  6574.             {
  6575.                 return uploadRDFFileURL(dropTarget, objURL);
  6576.             }
  6577.         }
  6578.         else if (objType == LFS_RT)
  6579.         {
  6580.             if (justAction)
  6581.             {
  6582.                 return UPLOAD_LFS;
  6583.             }
  6584.             else
  6585.             {
  6586.                 return uploadLFSURL(dropTarget, objURL);
  6587.             }
  6588.         }
  6589.         return DROP_NOT_ALLOWED;
  6590.         break;
  6591.  
  6592.         case LDAP_RT:
  6593.         case RDF_RT :
  6594.         if (justAction)
  6595.         {
  6596.             return COPY_MOVE_LINK;
  6597.         }
  6598.         else
  6599.         {
  6600.             return copyRDFLinkURL(dropTarget, objURL, objTitle);
  6601.         }
  6602.     }
  6603.     return DROP_NOT_ALLOWED;
  6604. }
  6605.  
  6606.  
  6607.  
  6608. void
  6609. replacePipeWithColon(char* url)
  6610. {
  6611.     size_t            n=0, size;
  6612.  
  6613.     XP_ASSERT(url != NULL);
  6614.  
  6615.     size = strlen(url);
  6616.     n = 0;
  6617.     while (n < size)
  6618.     {
  6619.         if (url[n] == '|')
  6620.         {
  6621.             url[n] = ':';
  6622.         }
  6623.         n++;
  6624.     }
  6625. }
  6626.  
  6627.  
  6628.  
  6629. HT_DropAction
  6630. copyRDFLinkURL (HT_Resource dropTarget, char* objURL, char *objTitle)
  6631. {
  6632.     RDF_Resource        new, obj;
  6633.     RDF            db;
  6634.  
  6635.     new = dropTarget->node;
  6636.     db = dropTarget->view->pane->db;
  6637.     replacePipeWithColon(objURL);
  6638.     obj = RDF_GetResource(db, objURL, 1);
  6639.  
  6640.     if (objTitle != NULL)
  6641.     {
  6642.         RDF_Assert(db, obj, gCoreVocab->RDF_name, objTitle, RDF_STRING_TYPE);
  6643.     }
  6644.     RDF_Assert(db, obj, gCoreVocab->RDF_parent, new, RDF_RESOURCE_TYPE);
  6645.     return COPY_MOVE_LINK;      
  6646. }
  6647.  
  6648.  
  6649.  
  6650. HT_DropAction
  6651. copyRDFLinkURLAt (HT_Resource dropx, char* objURL, char *objTitle, PRBool before)
  6652. {
  6653.     HT_Resource        dropTarget;
  6654.     RDF            db;
  6655.     RDF_Resource        parent,obj;
  6656.  
  6657.     dropTarget = dropx->parent;
  6658.     db = dropTarget->view->pane->db;
  6659.     parent = dropTarget->node;
  6660.     replacePipeWithColon(objURL);
  6661.     obj = RDF_GetResource(db, objURL, 1);
  6662.  
  6663.     if (objTitle != NULL)
  6664.     {
  6665.         RDF_Assert(db, obj, gCoreVocab->RDF_name, objTitle, RDF_STRING_TYPE);
  6666.     }
  6667.     nlocalStoreUnassert(gLocalStore, obj, gCoreVocab->RDF_parent, parent, RDF_RESOURCE_TYPE);
  6668.     nlocalStoreAddChildAt(gLocalStore, parent, dropx->node, obj, before);
  6669.     return COPY_MOVE_LINK;      
  6670. }
  6671.  
  6672.  
  6673.  
  6674. HT_DropAction
  6675. uploadLFSURL (HT_Resource dropTarget, char* objURL)
  6676. {
  6677.     RDF_Resource        r;
  6678.  
  6679.     XP_ASSERT(dropTarget != NULL);
  6680.     XP_ASSERT(objURL != NULL);
  6681.  
  6682.     if ((dropTarget != NULL) && (objURL != NULL))
  6683.     {
  6684.         if ((r = RDF_GetResource(gNCDB, objURL, 1)) != NULL)
  6685.         {
  6686.             RDF_Assert(gNCDB, r, gCoreVocab->RDF_parent,
  6687.                 dropTarget->node, RDF_RESOURCE_TYPE);
  6688.         }
  6689.     }
  6690.     return 0;
  6691. }
  6692.  
  6693.  
  6694.  
  6695. HT_DropAction
  6696. uploadRDFFileURL (HT_Resource dropTarget, char* objURL)
  6697. {
  6698.     return 0;
  6699. }
  6700.  
  6701.  
  6702.  
  6703. HT_DropAction
  6704. esfsCopyMoveContentURL (HT_Resource dropTarget, char* objURL)
  6705. {
  6706.     return 0;
  6707. }
  6708.  
  6709.  
  6710.  
  6711. PR_PUBLIC_API(RDF)
  6712. RDF_GetNavCenterDB()
  6713. {
  6714.     return gNCDB;
  6715. }
  6716.  
  6717.  
  6718. #define RDF_SITEMAP 1
  6719. #define RDF_RELATED_LINKS 2
  6720.  
  6721.  
  6722.  
  6723. HT_URLSiteMapAssoc *
  6724. makeNewSMP (char* pUrl, RDF_Resource u)
  6725. {
  6726.     HT_URLSiteMapAssoc    *nm;
  6727.  
  6728.     if ((nm = (HT_URLSiteMapAssoc*)getMem(sizeof(HT_URLSiteMapAssoc))) != NULL)
  6729.     {
  6730.         nm->sitemap = u;
  6731.         nm->url = copyString(pUrl);
  6732.     }
  6733.     return(nm);
  6734. }
  6735.  
  6736.  
  6737.  
  6738. PR_PUBLIC_API(void)
  6739. HT_AddSitemapFor(HT_Pane htPane, char *pUrl, char *pSitemapUrl, char* name)
  6740. {
  6741.     HT_URLSiteMapAssoc        *nsmp;
  6742.     RDF_Resource            nu;
  6743.     RDFT                sp;
  6744.     char                *nm;
  6745.  
  6746.     if (startsWith("file:", pUrl))    return;
  6747.     sp = htPane->db->translators[5];
  6748.     nu = RDF_GetResource(htPane->db, pSitemapUrl, 1);
  6749.     nsmp = makeNewSMP(pUrl, nu);
  6750.     if (name != NULL)
  6751.     {
  6752.         nm = copyString(name);
  6753.     }
  6754.     else
  6755.     {
  6756.         nm = copyString(XP_GetString(RDF_SITEMAPNAME));
  6757.     }
  6758.     nsmp->siteToolType = RDF_SITEMAP;
  6759.     nsmp->next = htPane->smp;
  6760.     htPane->smp = nsmp;
  6761.     setContainerp(nu, 1);
  6762.     SCookAssert3(sp, nu, gCoreVocab->RDF_name, nm,  RDF_STRING_TYPE, 1);
  6763.     SCookAssert3(sp, nu, gCoreVocab->RDF_parent, gNavCenter->RDF_Sitemaps, RDF_RESOURCE_TYPE, 1);
  6764.  
  6765. }
  6766.  
  6767.  
  6768.  
  6769. void
  6770. populateSBProviders (HT_Pane htPane)
  6771. {
  6772.     RDF_Cursor            c; 
  6773.     RDF_Resource            prov;
  6774.     RDF                db;
  6775.     SBProvider            sb;
  6776.  
  6777.     XP_ASSERT(htPane != NULL);
  6778.  
  6779.     db = htPane->db;
  6780.     c =  RDF_GetSources(htPane->db,  gNavCenter->RDF_SBProviders,
  6781.                 gCoreVocab->RDF_parent,    RDF_RESOURCE_TYPE, 1);
  6782.     while (prov = RDF_NextValue(c))
  6783.     {
  6784.         sb = (SBProvider)getMem(sizeof(SBProviderStruct));
  6785.         sb->name = RDF_GetResourceName(db, prov);
  6786.         sb->url  = copyString(resourceID(prov));
  6787.         sb->containerp = (!RDF_HasAssertion(db, prov, gNavCenter->RDF_resultType, 
  6788.                       "HTML", RDF_STRING_TYPE, 1));
  6789.         sb->next = htPane->smartBrowsingProviders;
  6790.         htPane->smartBrowsingProviders = sb;
  6791.     }
  6792.     RDF_DisposeCursor(c);
  6793. }
  6794.  
  6795.  
  6796.  
  6797. SBProvider
  6798. SBProviderOfNode (HT_Resource node)
  6799. {
  6800.     HT_Pane            htPane;
  6801.     SBProvider        prov;
  6802.  
  6803.     XP_ASSERT(node != NULL);
  6804.  
  6805.     htPane = node->view->pane;
  6806.     prov = htPane->smartBrowsingProviders;
  6807.     while (prov)
  6808.     {
  6809.         if (startsWith(prov->url, resourceID(node->node)))
  6810.         {
  6811.             return prov;
  6812.         }
  6813.         prov = prov->next;
  6814.     }
  6815.     return NULL;
  6816. }
  6817.  
  6818.  
  6819.  
  6820. PRBool
  6821. implicitDomainURL (char* url)
  6822. {
  6823.     uint16            n = 7, size;
  6824.  
  6825.     XP_ASSERT(url != NULL);
  6826.  
  6827.     size = strlen(url);
  6828.     while (n < size)
  6829.     {
  6830.         if (url[n] == '/') return 1;
  6831.         if (url[n] == '.') return 0;
  6832.         n++;
  6833.     }
  6834.     return 1;
  6835. }
  6836.  
  6837.  
  6838.  
  6839. PRBool
  6840. domainMatches (char *dom, char *url)
  6841. {
  6842.     size_t n = 0, m = 0, ns, ms;
  6843.  
  6844.     XP_ASSERT(dom != NULL);
  6845.     XP_ASSERT(url != NULL);
  6846.  
  6847.     ns = strlen(dom);
  6848.     ms = strlen(url);
  6849.     while ((n < ns) && (m < ms))
  6850.     {
  6851.         if (dom[n] == '*')
  6852.         {
  6853.             n++;
  6854.             while (m < ms)
  6855.             {
  6856.                 if (url[m] == '.') break; 
  6857.                 m++;
  6858.             }
  6859.         }
  6860.         else if (url[m] == '/')
  6861.         {
  6862.             return 0;
  6863.         }
  6864.         else if (url[m] != dom[n])
  6865.         {
  6866.             return 0;
  6867.         }
  6868.         else
  6869.         {
  6870.             m++;
  6871.             n++;
  6872.         }
  6873.     }
  6874.     return 1;
  6875. }
  6876.  
  6877.  
  6878.  
  6879. void
  6880. nextDomain (char* dom, size_t *n)
  6881. {
  6882.     PRBool            somethingSeenp = 0;
  6883.     size_t            m = 0;
  6884.     uint16            ns;
  6885.     char            c;
  6886.  
  6887.     ns = strlen(gRLForbiddenDomains);
  6888.     memset(dom, '\0', 100);
  6889.     while (*n < ns)
  6890.     {
  6891.         c = gRLForbiddenDomains[*n];
  6892.         if (c != ' ') somethingSeenp = 1;
  6893.         if (c == ',')
  6894.         {
  6895.             *n= (*n)+1;
  6896.             return;
  6897.         }
  6898.         if (somethingSeenp) dom[m++] = c;
  6899.         *n = (*n)+1;
  6900.     }
  6901. }
  6902.  
  6903.  
  6904.  
  6905. PRBool
  6906. relatedLinksEnabledURL (char* url)
  6907. {
  6908.     size_t            n = 0, ns;
  6909.     char            dom[100];
  6910.  
  6911.     if (url == NULL) return 0;
  6912.     if (strlen(url) > 100) return 0; 
  6913.     if (!startsWith("http:", url))
  6914.     {
  6915.         return 0;
  6916.     }
  6917.     else if (implicitDomainURL(url))
  6918.     {
  6919.         return 0;
  6920.     }
  6921.     else if (gRLForbiddenDomains != NULL)
  6922.     {
  6923.         ns = strlen(gRLForbiddenDomains);
  6924.         while (n < ns)
  6925.         {
  6926.             nextDomain(dom, &n);
  6927.             if (dom[0] != '\0' && domainMatches(dom, &url[7]))
  6928.             {
  6929.                 return 0;
  6930.             }
  6931.         }
  6932.         return 1;
  6933.     }
  6934.     else return 1;
  6935. }
  6936.  
  6937.  
  6938.  
  6939. PR_PUBLIC_API(void)
  6940. HT_AddRelatedLinksFor(HT_Pane htPane, char *pUrl)
  6941. {
  6942.     HT_URLSiteMapAssoc    *nsmp;
  6943.     RDF_Resource        nu;
  6944.     RDFT            sp;
  6945.     SBProvider        prov;
  6946.     char            *buffer;
  6947.  
  6948.     sp = htPane->db->translators[5];
  6949.     if (!htPane->smartBrowsingProviders) populateSBProviders(htPane);
  6950.     if (!relatedLinksEnabledURL(pUrl)) return;
  6951.     prov = htPane->smartBrowsingProviders;
  6952.     while (prov)
  6953.     {
  6954.         buffer = getMem(strlen(prov->url) + strlen(pUrl));
  6955.         sprintf(buffer, "%s%s", prov->url,  &pUrl[7]);
  6956.         nu = RDF_GetResource(htPane->db, buffer, 1);
  6957.         setContainerp(nu, prov->containerp);
  6958.         nsmp = makeNewSMP(pUrl, nu);
  6959.         nsmp->siteToolType = RDF_RELATED_LINKS;
  6960.         nsmp->next = htPane->smp;
  6961.         htPane->smp = nsmp;
  6962.         SCookAssert3(sp, nu, gCoreVocab->RDF_name, copyString(prov->name), RDF_STRING_TYPE, 1);
  6963.         SCookAssert3(sp, nu, gCoreVocab->RDF_parent, gNavCenter->RDF_Sitemaps, RDF_RESOURCE_TYPE, 1);
  6964.         prov = prov->next;
  6965.         freeMem(buffer);
  6966.     }
  6967. }
  6968.  
  6969.  
  6970.  
  6971. PR_PUBLIC_API(void)
  6972. HT_ExitPage(HT_Pane htPane, char *pUrl)
  6973. {
  6974.     HT_URLSiteMapAssoc    *nsmp;
  6975.     RDF_Resource        r;
  6976.     RDFT            sp;
  6977.  
  6978.     sp = htPane->db->translators[5];
  6979.     nsmp = htPane->smp;
  6980.     while (nsmp != NULL)
  6981.     {
  6982.         if (stringEquals(nsmp->url, pUrl))
  6983.         {
  6984.             r = nsmp->sitemap;
  6985.             SCookUnassert(sp, r, gCoreVocab->RDF_parent,
  6986.                 gNavCenter->RDF_Sitemaps, RDF_RESOURCE_TYPE);
  6987.         }
  6988.         nsmp = nsmp->next;
  6989.     }
  6990. }
  6991.  
  6992.  
  6993.  
  6994. PR_PUBLIC_API(PRBool)
  6995. HT_HasHTMLPane(HT_View htView)
  6996. {
  6997.     RDF_Resource        r;
  6998.     PRBool            hasHTML = PR_FALSE;
  6999.     char            *url = NULL;
  7000.   
  7001.     XP_ASSERT(htView != NULL);
  7002.   
  7003.     if (htView != NULL)
  7004.     {
  7005.         r = htView->top->node;
  7006.         url = RDF_GetSlotValue (htView->pane->db, r, gNavCenter->RDF_HTMLURL,
  7007.                     RDF_STRING_TYPE, 0, 1);
  7008.         if (url != NULL)
  7009.         {
  7010.             hasHTML = PR_TRUE;
  7011.  
  7012. #ifdef    DEBUG_RDF_GetSlotValue_Memory_Needs_Freedom
  7013.             freeMem(url);
  7014. #endif
  7015.  
  7016.         }
  7017.     }
  7018.     return(hasHTML);
  7019. }
  7020.