home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / xp / xp_ncent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  27.7 KB  |  880 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19.  
  20. #include "xp.h"
  21. #include "xp_ncent.h"
  22.  
  23. /*  xp_ncent.c
  24.  *  Contains various housekeeping dealing with the NavCenter
  25.  *      in an XP layer.
  26.  */
  27.  
  28. #ifdef MOZILLA_CLIENT
  29.  
  30. /*  Define this if you want frame children in the nav center.
  31. #define WANTFRAMES
  32.  */
  33.  
  34.  
  35.  
  36. static XP_List *xp_GlobalLastActiveContext = NULL;
  37. static XP_List *xp_GlobalDockedNavCenters = NULL;
  38. static XP_List *xp_GlobalNavCenters = NULL;
  39. static XP_List *xp_GlobalNavCenterInfo = NULL;
  40. static XP_List *xp_GlobalViewHTMLPanes = NULL;
  41.  
  42. /*  Various info that should be displayed in a NavCenter should
  43.  *      the context have some nav centers to display in.
  44.  */
  45. typedef struct {
  46.     MWContext *m_pContext;
  47.     char *m_pUrl;
  48.     XP_List *m_pSitemaps;
  49. } NavCenterContextInfo;
  50.  
  51. /*  HT_Pane to MWContext association for tracking docked state.
  52.  */
  53. typedef struct {
  54.     MWContext *m_pContext;
  55.     HT_Pane m_htPane;
  56. } DockedNavCenter;
  57.  
  58. /*  HT_View to MWContext association for loading HTML into
  59.  *      a NavCenter pane.
  60.  */
  61. typedef struct  {
  62.     HT_View m_htView;
  63.     MWContext *m_pContext;
  64. } ViewHTMLPane;
  65.  
  66. /*  Find filter for nav center contexts.
  67.  */
  68. static XP_Bool xp_canbenavcentertarget(MWContext *pCX)
  69. {
  70.     XP_Bool bRetval = FALSE;
  71.     
  72.     if(NULL == pCX) {
  73.         /*  Invalid param.
  74.          */
  75.     }
  76.     else if(MWContextBrowser != pCX->type) {
  77.         /*  Only looking for browser contexts.
  78.          */
  79.     }
  80.     else if(pCX->is_grid_cell) {
  81.         /*  Grid cells not allowed
  82.          */
  83.     }
  84.     else if(EDT_IS_EDITOR(pCX)) {
  85.         /*  Editor contexts not allowed
  86.          */
  87.     }
  88.     else if(pCX->name && 0 == XP_STRCASECMP(pCX->name, "Netscape_Netcaster_Drawer")) {
  89.         /*  Netcaster windows not allowed
  90.          */
  91.     }
  92.     else {
  93.         bRetval = TRUE;
  94.     }
  95.     
  96.     return(bRetval);
  97. }
  98.  
  99. /*  Function to return last active context which fits nav center
  100.  *      criteria.
  101.  */
  102. static MWContext *xp_lastactivenavcentercontext(void)
  103. {
  104.     return(XP_GetLastActiveContext(xp_canbenavcentertarget));
  105. }
  106.  
  107. /*  Return nav center info for a context.
  108.  *  Can return NULL.
  109.  */
  110. static NavCenterContextInfo *xp_getnavcenterinfo(MWContext *pContext)
  111. {
  112.     NavCenterContextInfo *pInfo = NULL;
  113.     
  114.     if(pContext) {
  115.         XP_List *pTraverse = xp_GlobalNavCenterInfo;
  116.         
  117.         /*  Go through the global list and return the object if found.
  118.          */
  119.         while((pInfo = (NavCenterContextInfo *)XP_ListNextObject(pTraverse))) {
  120.             if(pContext == pInfo->m_pContext) {
  121.                 break;
  122.             }
  123.             pInfo = NULL;
  124.         }
  125.     }
  126.     
  127.     return(pInfo);
  128. }
  129.  
  130. /*  Clean out the structure except for context pointer
  131.  */
  132. static void xp_gutnavcenterinfo(NavCenterContextInfo *pInfo)
  133. {
  134.     if(pInfo) {
  135.         if(pInfo->m_pUrl) {
  136.             XP_FREE(pInfo->m_pUrl);
  137.             pInfo->m_pUrl = NULL;
  138.         }
  139.         if(pInfo->m_pSitemaps) {
  140.             XP_List *pTraverse = pInfo->m_pSitemaps;
  141.             char *pTemp = NULL;
  142.             while((pTemp = (char *)XP_ListNextObject(pTraverse))) {
  143.                 XP_FREE(pTemp);
  144.             }
  145.             XP_ListDestroy(pInfo->m_pSitemaps);
  146.             pInfo->m_pSitemaps = NULL;
  147.         }
  148.     }
  149. }
  150.  
  151. /*  Initialzie a nav center with various data.
  152.  *  It should be emptied or uninitialized before doing this.
  153.  *  Docked state, and active browser need to be set before
  154.  *      doing this in order for proper operation.
  155.  */
  156. static void xp_initnavcenter(HT_Pane htPane, MWContext *pContext, XP_Bool bInitFlag)
  157. {
  158.     if(bInitFlag) {
  159.         if(NULL == pContext) {
  160.             pContext = XP_GetNavCenterContext(htPane);
  161.         }
  162.         if(pContext) {
  163.             NavCenterContextInfo *pInfo = xp_getnavcenterinfo(pContext);
  164.             if(pInfo && pInfo->m_pUrl) {
  165.                 HT_AddRelatedLinksFor(htPane, pInfo->m_pUrl);
  166.                 if(pInfo->m_pSitemaps) {
  167.                     XP_List *pLoop = pInfo->m_pSitemaps;
  168.                     char *pSitemap = NULL;
  169.                     while((pSitemap = (char *)XP_ListNextObject(pLoop))) {
  170.                         HT_AddSitemapFor(htPane, pInfo->m_pUrl, pSitemap, NULL);
  171.                     }
  172.                 }
  173.             }
  174. #ifdef WANTFRAMES
  175.             if(pContext->grid_children) {
  176.                 XP_List *pTraverse = pContext->grid_children;
  177.                 MWContext *pChild = NULL;
  178.                 while((pChild = (MWContext *)XP_ListNextObject(pTraverse))) {
  179.                     xp_initnavcenter(htPane, pChild, bInitFlag);
  180.                 }
  181.             }
  182. #endif
  183.         }
  184.     }
  185. }
  186.  
  187. /*  Uninitialize a nav center with current info.
  188.  *  Use this before changing activation or docking state, or pass in
  189.  *      the context to uninit from.
  190.  */
  191. static void xp_uninitnavcenter(HT_Pane htPane, MWContext *pContext, XP_Bool bInitFlag)
  192. {
  193.     if(bInitFlag) {
  194.         if(NULL == pContext) {
  195.             pContext = XP_GetNavCenterContext(htPane);
  196.         }
  197.         if(pContext) {
  198.             NavCenterContextInfo *pInfo = xp_getnavcenterinfo(pContext);
  199.             if(pInfo && pInfo->m_pUrl) {
  200.                 HT_ExitPage(htPane, pInfo->m_pUrl);
  201.             }
  202. #ifdef WANTFRAMES
  203.             if(pContext->grid_children) {
  204.                 XP_List *pTraverse = pContext->grid_children;
  205.                 MWContext *pChild = NULL;
  206.                 while((pChild = (MWContext *)XP_ListNextObject(pTraverse))) {
  207.                     xp_uninitnavcenter(htPane, pChild, bInitFlag);
  208.                 }
  209.             }
  210. #endif
  211.         }
  212.     }
  213. }
  214.  
  215. /*  Call these to get a list of NavCenters which a context
  216.  *      will effect.
  217.  *  WARNING:    The list will not be updated should any of
  218.  *      the data to which it refers changes.  The operation
  219.  *      should be atomic and synchronous for best results.
  220.  *  The object in the list is just a HT_Pane cast to void *.
  221.  *  Caller must XP_ListDestroy return value when finished.
  222.  *  Pass in NULL as the context to get a list of floating
  223.  *      nav centers (this basically excludes docked nav
  224.  *      centers).
  225.  *  Could return NULL....
  226.  */
  227. static XP_List *xp_getnavcenterlist(MWContext *pContext)
  228. {
  229.     XP_List *pRetval = NULL;
  230.     MWContext *pCX = XP_GetNonGridContext(pContext);
  231.     
  232.     if((pCX && MWContextBrowser == pCX->type) || NULL == pCX) {
  233.         /*  Create the return value up front.
  234.          *  This could be optimized to only be created when needed.
  235.          */
  236.         pRetval = XP_ListNew();
  237.         if(pRetval) {
  238.             XP_List *pTraverse = xp_GlobalDockedNavCenters;
  239.             DockedNavCenter *pDNC = NULL;
  240.             
  241.             /*  Is there a docked NavCenter?
  242.              */
  243.             if(pCX) {
  244.                 while((pDNC = (DockedNavCenter *)XP_ListNextObject(pTraverse))) {
  245.                     if(pCX == pDNC->m_pContext) {
  246.                         XP_ListAddObject(pRetval, (void *)pDNC->m_htPane);
  247.                         break;
  248.                     }
  249.                 }
  250.             }
  251.             
  252.             /*  Add any nondocked NavCenters, if the context is the active one or
  253.              *      there is no context.
  254.              */
  255.             if(NULL == pCX || xp_lastactivenavcentercontext() == pCX) {
  256.                 HT_Pane htFloater = NULL;
  257.                 pTraverse = xp_GlobalNavCenters;
  258.                 while((htFloater = (HT_Pane)XP_ListNextObject(pTraverse))) {
  259.                     if(FALSE == XP_IsNavCenterDocked(htFloater)) {
  260.                         XP_ListAddObject(pRetval, (void *)htFloater);
  261.                     }
  262.                 }
  263.             }
  264.             
  265.             /*  Get rid of the list if empty.
  266.              */
  267.             if(XP_ListIsEmpty(pRetval)) {
  268.                 XP_ListDestroy(pRetval);
  269.                 pRetval = NULL;
  270.             }
  271.         }
  272.     }
  273.     
  274.     return(pRetval);
  275. }
  276.  
  277. /*  The active top level browser window has changed.
  278.  *  We need to update any floating nav centers.
  279.  */
  280. static void xp_unactivatebrowser(MWContext *pOld)
  281. {
  282.     if(pOld) {
  283.         XP_List *pFloatingNavCenters = xp_getnavcenterlist(NULL);
  284.         if(pFloatingNavCenters) {
  285.             /*  Handle removal of any old data.
  286.              */
  287.             XP_List *pTraverse = pFloatingNavCenters;
  288.             HT_Pane htFloater = NULL;
  289.             while((htFloater = (HT_Pane)XP_ListNextObject(pTraverse))) {
  290.                 xp_uninitnavcenter(htFloater, pOld, TRUE);
  291.                 xp_initnavcenter(htFloater, NULL, TRUE);
  292.             }
  293.             
  294.             XP_ListDestroy(pFloatingNavCenters);
  295.             pFloatingNavCenters = NULL;
  296.         }
  297.     }
  298. }
  299.  
  300. /*  Private docking routing, can override auto-initialization for
  301.  *      custom optimization.
  302.  */
  303. static void xp_docknavcenter(HT_Pane htPane, MWContext *pCX, XP_Bool bInitFlag)
  304. {
  305.     pCX = XP_GetNonGridContext(pCX);
  306.     if(pCX && MWContextBrowser == pCX->type && htPane) {
  307.         DockedNavCenter *pNew = XP_NEW_ZAP(DockedNavCenter);
  308.         
  309.         /*  Need to uninit nav center from current info
  310.          *      if a different context.
  311.          */
  312.         XP_Bool bInit = FALSE;
  313.         if(pCX != XP_GetNavCenterContext(htPane)) {
  314.             xp_uninitnavcenter(htPane, NULL, bInitFlag);
  315.             bInit = TRUE;
  316.         }
  317.         
  318.         if(pNew) {
  319.             pNew->m_pContext = pCX;
  320.             pNew->m_htPane = htPane;
  321.             
  322.             if(NULL == xp_GlobalDockedNavCenters) {
  323.                 xp_GlobalDockedNavCenters = XP_ListNew();
  324.                 if(NULL == xp_GlobalDockedNavCenters) {
  325.                     XP_FREE(pNew);
  326.                     pNew = NULL;
  327.                 }
  328.             }
  329.             if(xp_GlobalDockedNavCenters) {
  330.                 XP_ListAddObject(xp_GlobalDockedNavCenters, (void *)pNew);
  331.             }
  332.         }
  333.         
  334.         /*  nav center needs re-init.
  335.          */
  336.         if(bInit) {
  337.             xp_initnavcenter(htPane, NULL, bInitFlag);
  338.         }
  339.     }
  340. }
  341.  
  342. /*  Private undocking routing, can override auto-initialization for
  343.  *      custom optimization.
  344.  */
  345. static void xp_undocknavcenter(HT_Pane htPane, XP_Bool bInitFlag)
  346. {
  347.     MWContext *pCX = XP_GetNavCenterContext(htPane);
  348.     if(pCX && htPane && xp_GlobalDockedNavCenters) {
  349.         XP_List *pTraverse = xp_GlobalDockedNavCenters;
  350.         DockedNavCenter *pDNC = NULL;
  351.         XP_Bool bInit = FALSE;
  352.         
  353.         /*  If this will make the nav center of a different context,
  354.          *      we will need to uninit.
  355.          */
  356.         if(pCX != xp_lastactivenavcentercontext()) {
  357.             xp_uninitnavcenter(htPane, NULL, bInitFlag);
  358.             bInit = TRUE;
  359.         }
  360.         
  361.         while((pDNC = (DockedNavCenter *)XP_ListNextObject(pTraverse))) {
  362.             if(pCX == pDNC->m_pContext && htPane == pDNC->m_htPane) {
  363.                 /* pTraverse points beyond pDNC now, removing it will
  364.                  *  not destroy the sanctity of the loop.
  365.                  */
  366.                 XP_ListRemoveObject(xp_GlobalDockedNavCenters, (void *)pDNC);
  367.                 XP_FREE(pDNC);
  368.                 break;
  369.             }
  370.         }
  371.         if(XP_ListIsEmpty(xp_GlobalDockedNavCenters)) {
  372.             XP_ListDestroy(xp_GlobalDockedNavCenters);
  373.             xp_GlobalDockedNavCenters = NULL;
  374.         }
  375.         
  376.         if(bInit) {
  377.             /*  Need to re-init the nav center.
  378.              */
  379.             xp_initnavcenter(htPane, NULL, bInitFlag);
  380.         }
  381.     }
  382. }
  383.  
  384. /*  Remove any view to context association.
  385.  */
  386. void xp_removeviewassociation(HT_View htView, MWContext *pCX)
  387. {
  388.     XP_List *pTraverse = xp_GlobalViewHTMLPanes;
  389.     ViewHTMLPane *pVHP = NULL;
  390.     XP_Bool bRemove = FALSE;
  391.     
  392.     while((pVHP = (ViewHTMLPane *)XP_ListNextObject(pTraverse))) {
  393.         if(pCX && pCX == pVHP->m_pContext) {
  394.             bRemove = TRUE;
  395.         }
  396.         else if(htView && htView == pVHP->m_htView) {
  397.             bRemove = TRUE;
  398.         }
  399.         
  400.         if(bRemove) {
  401.             XP_ListRemoveObject(xp_GlobalViewHTMLPanes, pVHP);
  402.             XP_FREE(pVHP);
  403.             pVHP = NULL;
  404.             
  405.             if(XP_ListIsEmpty(xp_GlobalViewHTMLPanes)) {
  406.                 XP_ListDestroy(xp_GlobalViewHTMLPanes);
  407.                 xp_GlobalViewHTMLPanes = NULL;
  408.             }
  409.             break;
  410.         }
  411.         bRemove = FALSE;
  412.     }
  413. }
  414.  
  415. /*  Return HTML Pane context in the NavCenter.
  416.  */
  417. MWContext *xp_gethtmlpane(HT_View htView)
  418. {
  419.     MWContext *pRetval = NULL;
  420.     if(htView) {
  421.         XP_List *pTraverse = xp_GlobalViewHTMLPanes;
  422.         ViewHTMLPane *pVHP = NULL;
  423.         
  424.         while((pVHP = (ViewHTMLPane *)XP_ListNextObject(pTraverse))) {
  425.             if(htView == pVHP->m_htView) {
  426.                 pRetval = pVHP->m_pContext;
  427.                 break;
  428.             }
  429.         }
  430.     }
  431.     return(pRetval);
  432. }
  433.  
  434. /*  Call this when a context becomes active.
  435.  *  A simple list of the contexts is kept, effectively a stack
  436.  *      of active contexts.
  437.  */
  438. void XP_SetLastActiveContext(MWContext *pCX)
  439. {
  440.     if(pCX) {
  441.         if(!xp_GlobalLastActiveContext) {
  442.             xp_GlobalLastActiveContext = XP_ListNew();
  443.         }
  444.         if(xp_GlobalLastActiveContext) {
  445.             MWContext *pAfterSet = NULL;
  446.             MWContext *pBeforeSet = NULL;
  447.             
  448.             pBeforeSet = xp_lastactivenavcentercontext();
  449.             /*  Remove the context from the stack.
  450.              *  It will be added at the top.
  451.              */
  452.             if(XP_ListPeekTopObject(xp_GlobalLastActiveContext) != pCX) {
  453.                 XP_ListRemoveObject(xp_GlobalLastActiveContext, (void *)pCX);
  454.                 XP_ListAddObject(xp_GlobalLastActiveContext, (void *)pCX);
  455.             }
  456.             pAfterSet = xp_lastactivenavcentercontext();
  457.             
  458.             /*  Did the top level browser change.
  459.              *  If so, we need to notify floating nav centers.
  460.              */
  461.             if(pBeforeSet != pAfterSet) {
  462.                 xp_unactivatebrowser(pBeforeSet);
  463.             }
  464.         }
  465.     }
  466. }
  467.  
  468. /*  Call this to get the last active context.
  469.  *  If specified, pCallMe will decide what is a valid return value
  470.  *      and what is not.
  471.  */
  472. MWContext *XP_GetLastActiveContext(ContextMatch MatchCallback)
  473. {
  474.     XP_List *pTraverse = xp_GlobalLastActiveContext;
  475.     MWContext *pCX = NULL;
  476.     
  477.     while((pCX = (MWContext *)XP_ListNextObject(pTraverse))) {
  478.         if(MatchCallback) {
  479.             if(MatchCallback(pCX)) {
  480.                 break;
  481.             }
  482.         }
  483.         else {
  484.             /*  No callback, really want last active.
  485.              */
  486.             break;
  487.         }
  488.         pCX = NULL;
  489.     }
  490.     
  491.     return(pCX);
  492. }
  493.  
  494. /*  Removes context from last active stack.
  495.  *  Just call this before context destruction.
  496.  */
  497. void XP_RemoveContextFromLastActiveStack(MWContext *pCX)
  498. {
  499.     if(pCX && xp_GlobalLastActiveContext) {
  500.         MWContext *pBeforeRemove = NULL;
  501.         MWContext *pAfterRemove = NULL;
  502.         
  503.         pBeforeRemove = xp_lastactivenavcentercontext();
  504.         XP_ListRemoveObject(xp_GlobalLastActiveContext, (void *)pCX);
  505.         pAfterRemove = xp_lastactivenavcentercontext();
  506.         if(XP_ListIsEmpty(xp_GlobalLastActiveContext)) {
  507.             XP_ListDestroy(xp_GlobalLastActiveContext);
  508.             xp_GlobalLastActiveContext = NULL;
  509.         }
  510.         
  511.         /*  Did the top level browser change.
  512.          *  If so, we need to notify floating nav centers.
  513.          */
  514.         if(pBeforeRemove != pAfterRemove) {
  515.             xp_unactivatebrowser(pBeforeRemove);
  516.         }
  517.     }
  518. }
  519.  
  520. /*  Inform us about a new NavCenter.
  521.  *  Call this after creation of a NavCenter.
  522.  *  The second parameter is only valid if created in a docked
  523.  *      state.  Pass in NULL otherwise.
  524.  */
  525. void XP_RegisterNavCenter(HT_Pane htPane, MWContext *pDocked)
  526. {
  527.     if(htPane) {
  528.         if(NULL == xp_GlobalNavCenters) {
  529.             xp_GlobalNavCenters = XP_ListNew();
  530.         }
  531.         if(xp_GlobalNavCenters) {
  532.             XP_ListAddObject(xp_GlobalNavCenters, (void *)htPane);
  533.         }
  534.         
  535.         /*  Handle creation in a docked state.
  536.          */
  537.         if(pDocked) {
  538.             xp_docknavcenter(htPane, pDocked, FALSE);
  539.         }
  540.         
  541.         /*  Initialize it with whatever info.
  542.          */
  543.         xp_initnavcenter(htPane, NULL, TRUE);
  544.     }
  545. }
  546.  
  547. /*  Unregister a NavCenter.
  548.  *  Call this when ready to delete the NavCenter.
  549.  */
  550. void XP_UnregisterNavCenter(HT_Pane htPane)
  551. {
  552.     if(htPane && xp_GlobalNavCenters) {
  553.         /*  Remove whatever info it may be holding.
  554.          */
  555.         xp_uninitnavcenter(htPane, NULL, TRUE);
  556.         
  557.         /*  Can obviously no longer be docked.
  558.          *  Have it perform no init, uninit.
  559.          */
  560.         if(XP_IsNavCenterDocked(htPane)) {
  561.             xp_undocknavcenter(htPane, FALSE);
  562.         }
  563.         
  564.         /*  List cleanup.
  565.          */
  566.         XP_ListRemoveObject(xp_GlobalNavCenters, (void *)htPane);
  567.         if(XP_ListIsEmpty(xp_GlobalNavCenters)) {
  568.             XP_ListDestroy(xp_GlobalNavCenters);
  569.             xp_GlobalNavCenters = NULL;
  570.         }
  571.     }
  572. }
  573.  
  574. /*  Call this when docking a NavCenter to a top level window.
  575.  *  This includes creating a NavCenter in a docked state, or
  576.  *      docking a nav center when it was already docked in
  577.  *      a different window.
  578.  */
  579. void XP_DockNavCenter(HT_Pane htPane, MWContext *pCX)
  580. {
  581.     XP_Bool bPrevDock = FALSE;
  582.     
  583.     if(XP_IsNavCenterDocked(htPane)) {
  584.         bPrevDock = TRUE;
  585.     }
  586.     
  587.     if(FALSE == bPrevDock) {
  588.         xp_docknavcenter(htPane, pCX, TRUE);
  589.     }
  590.     else {
  591.         /*  Previously already docked.
  592.          *  Avoid a redock to some context scenario.
  593.          *  Optimize auto init/uninit.
  594.          */
  595.         MWContext *pOldCX = XP_GetNavCenterContext(htPane);
  596.         if(pOldCX != pCX) {
  597.             xp_uninitnavcenter(htPane, NULL, TRUE);
  598.             xp_undocknavcenter(htPane, FALSE);
  599.             xp_docknavcenter(htPane, pCX, FALSE);
  600.             xp_initnavcenter(htPane, NULL, TRUE);
  601.         }
  602.     }
  603. }
  604.  
  605. /*  Call this when undocking a NavCenter from a top level window.
  606.  */
  607. void XP_UndockNavCenter(HT_Pane htPane)
  608. {
  609.     xp_undocknavcenter(htPane, TRUE);
  610. }
  611.  
  612. /*  Returns wether or not a NavCenter is docked.
  613.  *  This basically allows you to tell the difference between a docked
  614.  *      or last active window return value from XP_GetNavCenterContext.
  615.  */
  616. XP_Bool XP_IsNavCenterDocked(HT_Pane htPane)
  617. {
  618.     XP_Bool bRetval = FALSE;
  619.     XP_List *pTraverse = xp_GlobalDockedNavCenters;
  620.     DockedNavCenter *pDNC = NULL;
  621.     
  622.     /*  Look through docked list.
  623.      */
  624.     while((pDNC = (DockedNavCenter *)XP_ListNextObject(pTraverse))) {
  625.         if(htPane == pDNC->m_htPane) {
  626.             bRetval = TRUE;
  627.             break;
  628.         }
  629.     }
  630.     
  631.     return(bRetval);
  632. }
  633.  
  634. /*  Call this to determine the context which a NavCenter operation
  635.  *      will target.
  636.  *  If not docked, picks last active browser window.
  637.  *  Could return NULL....
  638.  */
  639. MWContext *XP_GetNavCenterContext(HT_Pane htPane)
  640. {
  641.     MWContext *pRetval = NULL;
  642.     XP_List *pTraverse = xp_GlobalDockedNavCenters;
  643.     DockedNavCenter *pDNC = NULL;
  644.     
  645.     /*  Look through docked list first.
  646.      */
  647.     while((pDNC = (DockedNavCenter *)XP_ListNextObject(pTraverse))) {
  648.         if(htPane == pDNC->m_htPane) {
  649.             pRetval = pDNC->m_pContext;
  650.             break;
  651.         }
  652.     }
  653.     
  654.     /*  Use last active top level browser window.
  655.      */
  656.     if(NULL == pRetval) {
  657.         pRetval = xp_lastactivenavcentercontext();
  658.     }
  659.     
  660.     return(pRetval);
  661. }
  662.  
  663. /*  Call this when visiting a new page for a context.
  664.  */
  665. void XP_SetNavCenterUrl(MWContext *pContext, char *pUrl)
  666. {
  667.     if(pUrl && pContext) {
  668.         MWContext *pBrowser = XP_GetNonGridContext(pContext);
  669. #ifndef WANTFRAMES
  670.         if(pBrowser != pContext) {
  671.             return;
  672.         }
  673. #endif
  674.         if(MWContextBrowser == pBrowser->type) {
  675.             NavCenterContextInfo *pInfo = xp_getnavcenterinfo(pContext);
  676.             if(NULL == pInfo) {
  677.                 if(NULL == xp_GlobalNavCenterInfo) {
  678.                     xp_GlobalNavCenterInfo = XP_ListNew();
  679.                 }
  680.                 if(xp_GlobalNavCenterInfo) {
  681.                     pInfo = XP_NEW_ZAP(NavCenterContextInfo);
  682.                     pInfo->m_pContext = pContext;
  683.                     XP_ListAddObject(xp_GlobalNavCenterInfo, (void *)pInfo);
  684.                 }
  685.             }
  686.             if(pInfo) {
  687.                 XP_Bool bChangedUrls = FALSE;
  688.                 
  689.                 if(pInfo->m_pUrl) {
  690.                     if(XP_STRCMP(pUrl, pInfo->m_pUrl)) {
  691.                         bChangedUrls = TRUE;
  692.                     }
  693.                 }
  694.                 else {
  695.                     bChangedUrls = TRUE;
  696.                 }
  697.                 
  698.                 if(bChangedUrls) {
  699.                     /*  Blow away the current nav center info and gut
  700.                      *      our info struct.
  701.                      */
  702.                     XP_List *pCenters = xp_getnavcenterlist(pContext);
  703.                     if(pCenters) {
  704.                         XP_List *pTraverse = pCenters;
  705.                         HT_Pane htPane = NULL;
  706.                         while((htPane = (HT_Pane)XP_ListNextObject(pTraverse))) {
  707.                             xp_uninitnavcenter(htPane, pContext, TRUE);
  708.                         }
  709.                     }
  710.                     xp_gutnavcenterinfo(pInfo);
  711.                     
  712.                     /*  Copy over the url.
  713.                      */
  714.                     pInfo->m_pUrl = XP_STRDUP(pUrl);
  715.                     
  716.                     /*  Update any watching nav centers.
  717.                      */
  718.                     if(pCenters) {
  719.                         XP_List *pTraverse = pCenters;
  720.                         HT_Pane htPane = NULL;
  721.                         while((htPane = (HT_Pane)XP_ListNextObject(pTraverse))) {
  722.                             xp_initnavcenter(htPane, pContext, TRUE);
  723.                         }
  724.                         XP_ListDestroy(pCenters);
  725.                         pCenters = NULL;
  726.                     }
  727.                 }
  728.             }
  729.         }
  730.     }
  731. }
  732.  
  733. /*  Add a sitemap for a context.
  734.  *  The url has to be set for a context before this will work.
  735.  */
  736. void XP_AddNavCenterSitemap(MWContext *pContext, char *pSitemap, char* name)
  737. {
  738.     if(pSitemap && pContext) {
  739.         MWContext *pBrowser = XP_GetNonGridContext(pContext);
  740. #ifndef WANTFRAMES
  741.         if(pBrowser != pContext) {
  742.             return;
  743.         }
  744. #endif
  745.         if(MWContextBrowser == pBrowser->type) {
  746.             NavCenterContextInfo *pInfo = xp_getnavcenterinfo(pContext);
  747.             if(pInfo && pInfo->m_pUrl) {
  748.                 XP_Bool bDuplicate = FALSE;
  749.                 
  750.                 if(pInfo->m_pSitemaps) {
  751.                     XP_List *pTraverse = pInfo->m_pSitemaps;
  752.                     char *pCheck = NULL;
  753.                     while((pCheck = (char *)XP_ListNextObject(pTraverse))) {
  754.                         if(0 == XP_STRCMP(pCheck, pSitemap)) {
  755.                             bDuplicate = TRUE;
  756.                         }
  757.                     }
  758.                 }
  759.                 else {
  760.                     /*  Create the list, first time.
  761.                      */
  762.                     pInfo->m_pSitemaps = XP_ListNew();
  763.                 }
  764.                 
  765.                 if(FALSE == bDuplicate && pInfo->m_pSitemaps) {
  766.                     char *pDup = XP_STRDUP(pSitemap);
  767.                     /*  Add entry to list.
  768.                      */
  769.                     if(pDup) {
  770.                         XP_ListAddObject(pInfo->m_pSitemaps, (void *)pDup);
  771.                     }
  772.                 }
  773.                 
  774.                 if(FALSE == bDuplicate) {
  775.                     /*  Display entry in various nav centers.
  776.                      */
  777.                     XP_List *pCenters = xp_getnavcenterlist(pContext);
  778.                     if(pCenters) {
  779.                         XP_List *pTraverse = pCenters;
  780.                         HT_Pane htPane = NULL;
  781.                         while((htPane = (HT_Pane)XP_ListNextObject(pTraverse))) {
  782.                             HT_AddSitemapFor(htPane, pInfo->m_pUrl, pSitemap, name);
  783.                         }
  784.                         XP_ListDestroy(pCenters);
  785.                         pCenters = NULL;
  786.                     }
  787.                 }
  788.             }
  789.         }
  790.     }
  791. }
  792.  
  793. /*  Call this to association an HTML Pane MWContext to a NavCenter view.
  794.  */
  795. void XP_RegisterViewHTMLPane(HT_View htView, MWContext *pContext)
  796. {
  797.     if(htView && pContext) {
  798.         ViewHTMLPane *pNew = XP_NEW_ZAP(ViewHTMLPane);
  799.         if(pNew) {
  800.             pNew->m_htView = htView;
  801.             pNew->m_pContext = pContext;
  802.             
  803.             if(NULL == xp_GlobalViewHTMLPanes) {
  804.                 xp_GlobalViewHTMLPanes = XP_ListNew();
  805.                 if(NULL == xp_GlobalViewHTMLPanes) {
  806.                     XP_FREE(pNew);
  807.                     pNew = NULL;
  808.                 }
  809.             }
  810.             if(xp_GlobalViewHTMLPanes) {
  811.                 XP_ListAddObject(xp_GlobalViewHTMLPanes, (void *)pNew);
  812.             }
  813.         }
  814.     }
  815. }
  816.  
  817. /*  RDF HT Backend calls this to load content into the HTML view
  818.  *      of a NavCenter HT_View.
  819.  */
  820. int XP_GetURLForView(HT_View htView, char *pAddress)
  821. {
  822.     int iRetval = MK_NO_ACTION;
  823.     if(htView && pAddress) {
  824.         MWContext *pHTMLPane = xp_gethtmlpane(htView);
  825.         if(pHTMLPane) {
  826.             URL_Struct *pUrl = NET_CreateURLStruct(pAddress, NET_DONT_RELOAD);
  827.             if(pUrl) {
  828.                 iRetval = FE_GetURL(pHTMLPane, pUrl);
  829.             }
  830.         }
  831.     }
  832.     return(iRetval);
  833. }
  834.  
  835. /*  Call this to remove nav center info for a context.
  836.  *  Just call this before context destruction.
  837.  */
  838. void XP_RemoveNavCenterInfo(MWContext *pContext)
  839. {
  840.     MWContext *pCX = XP_GetNonGridContext(pContext);
  841.     if(pCX && MWContextBrowser == pCX->type) {
  842.         XP_List *pNavCenters = xp_getnavcenterlist(pContext);
  843.         NavCenterContextInfo *pInfo = xp_getnavcenterinfo(pContext);
  844.         if(pNavCenters) {
  845.             XP_List *pTraverse = pNavCenters;
  846.             HT_Pane htPane = NULL;
  847.             while((htPane = (HT_Pane)XP_ListNextObject(pTraverse))) {
  848.                 xp_uninitnavcenter(htPane, pContext, TRUE);
  849.                 if(pCX == pContext && XP_IsNavCenterDocked(htPane)) {
  850.                     xp_undocknavcenter(htPane, FALSE);
  851.                 }
  852.             }
  853.             XP_ListDestroy(pNavCenters);
  854.             pNavCenters = NULL;
  855.         }
  856.         
  857.         if(pInfo) {
  858.             XP_ListRemoveObject(xp_GlobalNavCenterInfo, (void *)pInfo);
  859.             if(XP_ListIsEmpty(xp_GlobalNavCenterInfo)) {
  860.                 XP_ListDestroy(xp_GlobalNavCenterInfo);
  861.                 xp_GlobalNavCenterInfo = NULL;
  862.             }
  863.             xp_gutnavcenterinfo(pInfo);
  864.             XP_FREE(pInfo);
  865.             pInfo = NULL;
  866.         }
  867.     }
  868.     
  869.     /*  Don't use the top level non-grid context for this one,
  870.      *      as it may have grid children. though itself not
  871.      *      going away.
  872.      */
  873.     if(pContext) {
  874.         xp_removeviewassociation(NULL, pContext);
  875.     }
  876. }
  877.  
  878. #endif /* MOZILLA_CLIENT */
  879.  
  880.