mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-31 14:15:30 +00:00
882 lines
27 KiB
C
882 lines
27 KiB
C
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
|
|
|
|
#include "xp.h"
|
|
#include "xp_ncent.h"
|
|
|
|
/* xp_ncent.c
|
|
* Contains various housekeeping dealing with the NavCenter
|
|
* in an XP layer.
|
|
*/
|
|
|
|
#ifdef MOZILLA_CLIENT
|
|
|
|
/* Define this if you want frame children in the nav center.
|
|
#define WANTFRAMES
|
|
*/
|
|
|
|
|
|
|
|
static XP_List *xp_GlobalLastActiveContext = NULL;
|
|
static XP_List *xp_GlobalDockedNavCenters = NULL;
|
|
static XP_List *xp_GlobalNavCenters = NULL;
|
|
static XP_List *xp_GlobalNavCenterInfo = NULL;
|
|
static XP_List *xp_GlobalViewHTMLPanes = NULL;
|
|
|
|
/* Various info that should be displayed in a NavCenter should
|
|
* the context have some nav centers to display in.
|
|
*/
|
|
typedef struct {
|
|
MWContext *m_pContext;
|
|
char *m_pUrl;
|
|
XP_List *m_pSitemaps;
|
|
} NavCenterContextInfo;
|
|
|
|
/* HT_Pane to MWContext association for tracking docked state.
|
|
*/
|
|
typedef struct {
|
|
MWContext *m_pContext;
|
|
HT_Pane m_htPane;
|
|
} DockedNavCenter;
|
|
|
|
/* HT_View to MWContext association for loading HTML into
|
|
* a NavCenter pane.
|
|
*/
|
|
typedef struct {
|
|
HT_View m_htView;
|
|
MWContext *m_pContext;
|
|
} ViewHTMLPane;
|
|
|
|
/* Find filter for nav center contexts.
|
|
*/
|
|
static XP_Bool xp_canbenavcentertarget(MWContext *pCX)
|
|
{
|
|
XP_Bool bRetval = FALSE;
|
|
|
|
if(NULL == pCX) {
|
|
/* Invalid param.
|
|
*/
|
|
}
|
|
else if(MWContextBrowser != pCX->type) {
|
|
/* Only looking for browser contexts.
|
|
*/
|
|
}
|
|
else if(pCX->is_grid_cell) {
|
|
/* Grid cells not allowed
|
|
*/
|
|
}
|
|
else if(EDT_IS_EDITOR(pCX)) {
|
|
/* Editor contexts not allowed
|
|
*/
|
|
}
|
|
else if(pCX->name && 0 == XP_STRCASECMP(pCX->name, "Netscape_Netcaster_Drawer")) {
|
|
/* Netcaster windows not allowed
|
|
*/
|
|
}
|
|
else {
|
|
bRetval = TRUE;
|
|
}
|
|
|
|
return(bRetval);
|
|
}
|
|
|
|
/* Function to return last active context which fits nav center
|
|
* criteria.
|
|
*/
|
|
static MWContext *xp_lastactivenavcentercontext(void)
|
|
{
|
|
return(XP_GetLastActiveContext(xp_canbenavcentertarget));
|
|
}
|
|
|
|
/* Return nav center info for a context.
|
|
* Can return NULL.
|
|
*/
|
|
static NavCenterContextInfo *xp_getnavcenterinfo(MWContext *pContext)
|
|
{
|
|
NavCenterContextInfo *pInfo = NULL;
|
|
|
|
if(pContext) {
|
|
XP_List *pTraverse = xp_GlobalNavCenterInfo;
|
|
|
|
/* Go through the global list and return the object if found.
|
|
*/
|
|
while((pInfo = (NavCenterContextInfo *)XP_ListNextObject(pTraverse))) {
|
|
if(pContext == pInfo->m_pContext) {
|
|
break;
|
|
}
|
|
pInfo = NULL;
|
|
}
|
|
}
|
|
|
|
return(pInfo);
|
|
}
|
|
|
|
/* Clean out the structure except for context pointer
|
|
*/
|
|
static void xp_gutnavcenterinfo(NavCenterContextInfo *pInfo)
|
|
{
|
|
if(pInfo) {
|
|
if(pInfo->m_pUrl) {
|
|
XP_FREE(pInfo->m_pUrl);
|
|
pInfo->m_pUrl = NULL;
|
|
}
|
|
if(pInfo->m_pSitemaps) {
|
|
XP_List *pTraverse = pInfo->m_pSitemaps;
|
|
char *pTemp = NULL;
|
|
while((pTemp = (char *)XP_ListNextObject(pTraverse))) {
|
|
XP_FREE(pTemp);
|
|
}
|
|
XP_ListDestroy(pInfo->m_pSitemaps);
|
|
pInfo->m_pSitemaps = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Initialzie a nav center with various data.
|
|
* It should be emptied or uninitialized before doing this.
|
|
* Docked state, and active browser need to be set before
|
|
* doing this in order for proper operation.
|
|
*/
|
|
static void xp_initnavcenter(HT_Pane htPane, MWContext *pContext, XP_Bool bInitFlag)
|
|
{
|
|
if(bInitFlag) {
|
|
if(NULL == pContext) {
|
|
pContext = XP_GetNavCenterContext(htPane);
|
|
}
|
|
if(pContext) {
|
|
NavCenterContextInfo *pInfo = xp_getnavcenterinfo(pContext);
|
|
if(pInfo && pInfo->m_pUrl) {
|
|
HT_AddRelatedLinksFor(htPane, pInfo->m_pUrl);
|
|
if(pInfo->m_pSitemaps) {
|
|
XP_List *pLoop = pInfo->m_pSitemaps;
|
|
char *pSitemap = NULL;
|
|
while((pSitemap = (char *)XP_ListNextObject(pLoop))) {
|
|
HT_AddSitemapFor(htPane, pInfo->m_pUrl, pSitemap, NULL);
|
|
}
|
|
}
|
|
}
|
|
#ifdef WANTFRAMES
|
|
if(pContext->grid_children) {
|
|
XP_List *pTraverse = pContext->grid_children;
|
|
MWContext *pChild = NULL;
|
|
while((pChild = (MWContext *)XP_ListNextObject(pTraverse))) {
|
|
xp_initnavcenter(htPane, pChild, bInitFlag);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Uninitialize a nav center with current info.
|
|
* Use this before changing activation or docking state, or pass in
|
|
* the context to uninit from.
|
|
*/
|
|
static void xp_uninitnavcenter(HT_Pane htPane, MWContext *pContext, XP_Bool bInitFlag)
|
|
{
|
|
if(bInitFlag) {
|
|
if(NULL == pContext) {
|
|
pContext = XP_GetNavCenterContext(htPane);
|
|
}
|
|
if(pContext) {
|
|
NavCenterContextInfo *pInfo = xp_getnavcenterinfo(pContext);
|
|
if(pInfo && pInfo->m_pUrl) {
|
|
HT_ExitPage(htPane, pInfo->m_pUrl);
|
|
}
|
|
#ifdef WANTFRAMES
|
|
if(pContext->grid_children) {
|
|
XP_List *pTraverse = pContext->grid_children;
|
|
MWContext *pChild = NULL;
|
|
while((pChild = (MWContext *)XP_ListNextObject(pTraverse))) {
|
|
xp_uninitnavcenter(htPane, pChild, bInitFlag);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Call these to get a list of NavCenters which a context
|
|
* will effect.
|
|
* WARNING: The list will not be updated should any of
|
|
* the data to which it refers changes. The operation
|
|
* should be atomic and synchronous for best results.
|
|
* The object in the list is just a HT_Pane cast to void *.
|
|
* Caller must XP_ListDestroy return value when finished.
|
|
* Pass in NULL as the context to get a list of floating
|
|
* nav centers (this basically excludes docked nav
|
|
* centers).
|
|
* Could return NULL....
|
|
*/
|
|
static XP_List *xp_getnavcenterlist(MWContext *pContext)
|
|
{
|
|
XP_List *pRetval = NULL;
|
|
MWContext *pCX = XP_GetNonGridContext(pContext);
|
|
|
|
if((pCX && MWContextBrowser == pCX->type) || NULL == pCX) {
|
|
/* Create the return value up front.
|
|
* This could be optimized to only be created when needed.
|
|
*/
|
|
pRetval = XP_ListNew();
|
|
if(pRetval) {
|
|
XP_List *pTraverse = xp_GlobalDockedNavCenters;
|
|
DockedNavCenter *pDNC = NULL;
|
|
|
|
/* Is there a docked NavCenter?
|
|
*/
|
|
if(pCX) {
|
|
while((pDNC = (DockedNavCenter *)XP_ListNextObject(pTraverse))) {
|
|
if(pCX == pDNC->m_pContext) {
|
|
XP_ListAddObject(pRetval, (void *)pDNC->m_htPane);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Add any nondocked NavCenters, if the context is the active one or
|
|
* there is no context.
|
|
*/
|
|
if(NULL == pCX || xp_lastactivenavcentercontext() == pCX) {
|
|
HT_Pane htFloater = NULL;
|
|
pTraverse = xp_GlobalNavCenters;
|
|
while((htFloater = (HT_Pane)XP_ListNextObject(pTraverse))) {
|
|
if(FALSE == XP_IsNavCenterDocked(htFloater)) {
|
|
XP_ListAddObject(pRetval, (void *)htFloater);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Get rid of the list if empty.
|
|
*/
|
|
if(XP_ListIsEmpty(pRetval)) {
|
|
XP_ListDestroy(pRetval);
|
|
pRetval = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
return(pRetval);
|
|
}
|
|
|
|
/* The active top level browser window has changed.
|
|
* We need to update any floating nav centers.
|
|
*/
|
|
static void xp_unactivatebrowser(MWContext *pOld)
|
|
{
|
|
if(pOld) {
|
|
XP_List *pFloatingNavCenters = xp_getnavcenterlist(NULL);
|
|
if(pFloatingNavCenters) {
|
|
/* Handle removal of any old data.
|
|
*/
|
|
XP_List *pTraverse = pFloatingNavCenters;
|
|
HT_Pane htFloater = NULL;
|
|
while((htFloater = (HT_Pane)XP_ListNextObject(pTraverse))) {
|
|
xp_uninitnavcenter(htFloater, pOld, TRUE);
|
|
xp_initnavcenter(htFloater, NULL, TRUE);
|
|
}
|
|
|
|
XP_ListDestroy(pFloatingNavCenters);
|
|
pFloatingNavCenters = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Private docking routing, can override auto-initialization for
|
|
* custom optimization.
|
|
*/
|
|
static void xp_docknavcenter(HT_Pane htPane, MWContext *pCX, XP_Bool bInitFlag)
|
|
{
|
|
pCX = XP_GetNonGridContext(pCX);
|
|
if(pCX && MWContextBrowser == pCX->type && htPane) {
|
|
DockedNavCenter *pNew = XP_NEW_ZAP(DockedNavCenter);
|
|
|
|
/* Need to uninit nav center from current info
|
|
* if a different context.
|
|
*/
|
|
XP_Bool bInit = FALSE;
|
|
if(pCX != XP_GetNavCenterContext(htPane)) {
|
|
xp_uninitnavcenter(htPane, NULL, bInitFlag);
|
|
bInit = TRUE;
|
|
}
|
|
|
|
if(pNew) {
|
|
pNew->m_pContext = pCX;
|
|
pNew->m_htPane = htPane;
|
|
|
|
if(NULL == xp_GlobalDockedNavCenters) {
|
|
xp_GlobalDockedNavCenters = XP_ListNew();
|
|
if(NULL == xp_GlobalDockedNavCenters) {
|
|
XP_FREE(pNew);
|
|
pNew = NULL;
|
|
}
|
|
}
|
|
if(xp_GlobalDockedNavCenters) {
|
|
XP_ListAddObject(xp_GlobalDockedNavCenters, (void *)pNew);
|
|
}
|
|
}
|
|
|
|
/* nav center needs re-init.
|
|
*/
|
|
if(bInit) {
|
|
xp_initnavcenter(htPane, NULL, bInitFlag);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Private undocking routing, can override auto-initialization for
|
|
* custom optimization.
|
|
*/
|
|
static void xp_undocknavcenter(HT_Pane htPane, XP_Bool bInitFlag)
|
|
{
|
|
MWContext *pCX = XP_GetNavCenterContext(htPane);
|
|
if(pCX && htPane && xp_GlobalDockedNavCenters) {
|
|
XP_List *pTraverse = xp_GlobalDockedNavCenters;
|
|
DockedNavCenter *pDNC = NULL;
|
|
XP_Bool bInit = FALSE;
|
|
|
|
/* If this will make the nav center of a different context,
|
|
* we will need to uninit.
|
|
*/
|
|
if(pCX != xp_lastactivenavcentercontext()) {
|
|
xp_uninitnavcenter(htPane, NULL, bInitFlag);
|
|
bInit = TRUE;
|
|
}
|
|
|
|
while((pDNC = (DockedNavCenter *)XP_ListNextObject(pTraverse))) {
|
|
if(pCX == pDNC->m_pContext && htPane == pDNC->m_htPane) {
|
|
/* pTraverse points beyond pDNC now, removing it will
|
|
* not destroy the sanctity of the loop.
|
|
*/
|
|
XP_ListRemoveObject(xp_GlobalDockedNavCenters, (void *)pDNC);
|
|
XP_FREE(pDNC);
|
|
break;
|
|
}
|
|
}
|
|
if(XP_ListIsEmpty(xp_GlobalDockedNavCenters)) {
|
|
XP_ListDestroy(xp_GlobalDockedNavCenters);
|
|
xp_GlobalDockedNavCenters = NULL;
|
|
}
|
|
|
|
if(bInit) {
|
|
/* Need to re-init the nav center.
|
|
*/
|
|
xp_initnavcenter(htPane, NULL, bInitFlag);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Remove any view to context association.
|
|
*/
|
|
void xp_removeviewassociation(HT_View htView, MWContext *pCX)
|
|
{
|
|
XP_List *pTraverse = xp_GlobalViewHTMLPanes;
|
|
ViewHTMLPane *pVHP = NULL;
|
|
XP_Bool bRemove = FALSE;
|
|
|
|
while((pVHP = (ViewHTMLPane *)XP_ListNextObject(pTraverse))) {
|
|
if(pCX && pCX == pVHP->m_pContext) {
|
|
bRemove = TRUE;
|
|
}
|
|
else if(htView && htView == pVHP->m_htView) {
|
|
bRemove = TRUE;
|
|
}
|
|
|
|
if(bRemove) {
|
|
XP_ListRemoveObject(xp_GlobalViewHTMLPanes, pVHP);
|
|
XP_FREE(pVHP);
|
|
pVHP = NULL;
|
|
|
|
if(XP_ListIsEmpty(xp_GlobalViewHTMLPanes)) {
|
|
XP_ListDestroy(xp_GlobalViewHTMLPanes);
|
|
xp_GlobalViewHTMLPanes = NULL;
|
|
}
|
|
break;
|
|
}
|
|
bRemove = FALSE;
|
|
}
|
|
}
|
|
|
|
/* Return HTML Pane context in the NavCenter.
|
|
*/
|
|
MWContext *xp_gethtmlpane(HT_View htView)
|
|
{
|
|
MWContext *pRetval = NULL;
|
|
if(htView) {
|
|
XP_List *pTraverse = xp_GlobalViewHTMLPanes;
|
|
ViewHTMLPane *pVHP = NULL;
|
|
|
|
while((pVHP = (ViewHTMLPane *)XP_ListNextObject(pTraverse))) {
|
|
if(htView == pVHP->m_htView) {
|
|
pRetval = pVHP->m_pContext;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return(pRetval);
|
|
}
|
|
|
|
/* Call this when a context becomes active.
|
|
* A simple list of the contexts is kept, effectively a stack
|
|
* of active contexts.
|
|
*/
|
|
void XP_SetLastActiveContext(MWContext *pCX)
|
|
{
|
|
if(pCX) {
|
|
if(!xp_GlobalLastActiveContext) {
|
|
xp_GlobalLastActiveContext = XP_ListNew();
|
|
}
|
|
if(xp_GlobalLastActiveContext) {
|
|
MWContext *pAfterSet = NULL;
|
|
MWContext *pBeforeSet = NULL;
|
|
|
|
pBeforeSet = xp_lastactivenavcentercontext();
|
|
/* Remove the context from the stack.
|
|
* It will be added at the top.
|
|
*/
|
|
if(XP_ListPeekTopObject(xp_GlobalLastActiveContext) != pCX) {
|
|
XP_ListRemoveObject(xp_GlobalLastActiveContext, (void *)pCX);
|
|
XP_ListAddObject(xp_GlobalLastActiveContext, (void *)pCX);
|
|
}
|
|
pAfterSet = xp_lastactivenavcentercontext();
|
|
|
|
/* Did the top level browser change.
|
|
* If so, we need to notify floating nav centers.
|
|
*/
|
|
if(pBeforeSet != pAfterSet) {
|
|
xp_unactivatebrowser(pBeforeSet);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Call this to get the last active context.
|
|
* If specified, pCallMe will decide what is a valid return value
|
|
* and what is not.
|
|
*/
|
|
MWContext *XP_GetLastActiveContext(ContextMatch MatchCallback)
|
|
{
|
|
XP_List *pTraverse = xp_GlobalLastActiveContext;
|
|
MWContext *pCX = NULL;
|
|
|
|
while((pCX = (MWContext *)XP_ListNextObject(pTraverse))) {
|
|
if(MatchCallback) {
|
|
if(MatchCallback(pCX)) {
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
/* No callback, really want last active.
|
|
*/
|
|
break;
|
|
}
|
|
pCX = NULL;
|
|
}
|
|
|
|
return(pCX);
|
|
}
|
|
|
|
/* Removes context from last active stack.
|
|
* Just call this before context destruction.
|
|
*/
|
|
void XP_RemoveContextFromLastActiveStack(MWContext *pCX)
|
|
{
|
|
if(pCX && xp_GlobalLastActiveContext) {
|
|
MWContext *pBeforeRemove = NULL;
|
|
MWContext *pAfterRemove = NULL;
|
|
|
|
pBeforeRemove = xp_lastactivenavcentercontext();
|
|
XP_ListRemoveObject(xp_GlobalLastActiveContext, (void *)pCX);
|
|
pAfterRemove = xp_lastactivenavcentercontext();
|
|
if(XP_ListIsEmpty(xp_GlobalLastActiveContext)) {
|
|
XP_ListDestroy(xp_GlobalLastActiveContext);
|
|
xp_GlobalLastActiveContext = NULL;
|
|
}
|
|
|
|
/* Did the top level browser change.
|
|
* If so, we need to notify floating nav centers.
|
|
*/
|
|
if(pBeforeRemove != pAfterRemove) {
|
|
xp_unactivatebrowser(pBeforeRemove);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Inform us about a new NavCenter.
|
|
* Call this after creation of a NavCenter.
|
|
* The second parameter is only valid if created in a docked
|
|
* state. Pass in NULL otherwise.
|
|
*/
|
|
void XP_RegisterNavCenter(HT_Pane htPane, MWContext *pDocked)
|
|
{
|
|
if(htPane) {
|
|
if(NULL == xp_GlobalNavCenters) {
|
|
xp_GlobalNavCenters = XP_ListNew();
|
|
}
|
|
if(xp_GlobalNavCenters) {
|
|
XP_ListAddObject(xp_GlobalNavCenters, (void *)htPane);
|
|
}
|
|
|
|
/* Handle creation in a docked state.
|
|
*/
|
|
if(pDocked) {
|
|
xp_docknavcenter(htPane, pDocked, FALSE);
|
|
}
|
|
|
|
/* Initialize it with whatever info.
|
|
*/
|
|
xp_initnavcenter(htPane, NULL, TRUE);
|
|
}
|
|
}
|
|
|
|
/* Unregister a NavCenter.
|
|
* Call this when ready to delete the NavCenter.
|
|
*/
|
|
void XP_UnregisterNavCenter(HT_Pane htPane)
|
|
{
|
|
if(htPane) {
|
|
/* Remove whatever info it may be holding.
|
|
*/
|
|
xp_uninitnavcenter(htPane, NULL, TRUE);
|
|
|
|
/* Can obviously no longer be docked.
|
|
* Have it perform no init, uninit.
|
|
*/
|
|
if(XP_IsNavCenterDocked(htPane)) {
|
|
xp_undocknavcenter(htPane, FALSE);
|
|
}
|
|
|
|
/* List cleanup.
|
|
*/
|
|
if (xp_GlobalNavCenters) {
|
|
XP_ListRemoveObject(xp_GlobalNavCenters, (void *)htPane);
|
|
if(XP_ListIsEmpty(xp_GlobalNavCenters)) {
|
|
XP_ListDestroy(xp_GlobalNavCenters);
|
|
xp_GlobalNavCenters = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Call this when docking a NavCenter to a top level window.
|
|
* This includes creating a NavCenter in a docked state, or
|
|
* docking a nav center when it was already docked in
|
|
* a different window.
|
|
*/
|
|
void XP_DockNavCenter(HT_Pane htPane, MWContext *pCX)
|
|
{
|
|
XP_Bool bPrevDock = FALSE;
|
|
|
|
if(XP_IsNavCenterDocked(htPane)) {
|
|
bPrevDock = TRUE;
|
|
}
|
|
|
|
if(FALSE == bPrevDock) {
|
|
xp_docknavcenter(htPane, pCX, TRUE);
|
|
}
|
|
else {
|
|
/* Previously already docked.
|
|
* Avoid a redock to some context scenario.
|
|
* Optimize auto init/uninit.
|
|
*/
|
|
MWContext *pOldCX = XP_GetNavCenterContext(htPane);
|
|
if(pOldCX != pCX) {
|
|
xp_uninitnavcenter(htPane, NULL, TRUE);
|
|
xp_undocknavcenter(htPane, FALSE);
|
|
xp_docknavcenter(htPane, pCX, FALSE);
|
|
xp_initnavcenter(htPane, NULL, TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Call this when undocking a NavCenter from a top level window.
|
|
*/
|
|
void XP_UndockNavCenter(HT_Pane htPane)
|
|
{
|
|
xp_undocknavcenter(htPane, TRUE);
|
|
}
|
|
|
|
/* Returns wether or not a NavCenter is docked.
|
|
* This basically allows you to tell the difference between a docked
|
|
* or last active window return value from XP_GetNavCenterContext.
|
|
*/
|
|
XP_Bool XP_IsNavCenterDocked(HT_Pane htPane)
|
|
{
|
|
XP_Bool bRetval = FALSE;
|
|
XP_List *pTraverse = xp_GlobalDockedNavCenters;
|
|
DockedNavCenter *pDNC = NULL;
|
|
|
|
/* Look through docked list.
|
|
*/
|
|
while((pDNC = (DockedNavCenter *)XP_ListNextObject(pTraverse))) {
|
|
if(htPane == pDNC->m_htPane) {
|
|
bRetval = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return(bRetval);
|
|
}
|
|
|
|
/* Call this to determine the context which a NavCenter operation
|
|
* will target.
|
|
* If not docked, picks last active browser window.
|
|
* Could return NULL....
|
|
*/
|
|
MWContext *XP_GetNavCenterContext(HT_Pane htPane)
|
|
{
|
|
MWContext *pRetval = NULL;
|
|
XP_List *pTraverse = xp_GlobalDockedNavCenters;
|
|
DockedNavCenter *pDNC = NULL;
|
|
|
|
/* Look through docked list first.
|
|
*/
|
|
while((pDNC = (DockedNavCenter *)XP_ListNextObject(pTraverse))) {
|
|
if(htPane == pDNC->m_htPane) {
|
|
pRetval = pDNC->m_pContext;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Use last active top level browser window.
|
|
*/
|
|
if(NULL == pRetval) {
|
|
pRetval = xp_lastactivenavcentercontext();
|
|
}
|
|
|
|
return(pRetval);
|
|
}
|
|
|
|
/* Call this when visiting a new page for a context.
|
|
*/
|
|
void XP_SetNavCenterUrl(MWContext *pContext, char *pUrl)
|
|
{
|
|
if(pUrl && pContext) {
|
|
MWContext *pBrowser = XP_GetNonGridContext(pContext);
|
|
#ifndef WANTFRAMES
|
|
if(pBrowser != pContext) {
|
|
return;
|
|
}
|
|
#endif
|
|
if(MWContextBrowser == pBrowser->type) {
|
|
NavCenterContextInfo *pInfo = xp_getnavcenterinfo(pContext);
|
|
if(NULL == pInfo) {
|
|
if(NULL == xp_GlobalNavCenterInfo) {
|
|
xp_GlobalNavCenterInfo = XP_ListNew();
|
|
}
|
|
if(xp_GlobalNavCenterInfo) {
|
|
pInfo = XP_NEW_ZAP(NavCenterContextInfo);
|
|
pInfo->m_pContext = pContext;
|
|
XP_ListAddObject(xp_GlobalNavCenterInfo, (void *)pInfo);
|
|
}
|
|
}
|
|
if(pInfo) {
|
|
XP_Bool bChangedUrls = FALSE;
|
|
|
|
if(pInfo->m_pUrl) {
|
|
if(XP_STRCMP(pUrl, pInfo->m_pUrl)) {
|
|
bChangedUrls = TRUE;
|
|
}
|
|
}
|
|
else {
|
|
bChangedUrls = TRUE;
|
|
}
|
|
|
|
if(bChangedUrls) {
|
|
/* Blow away the current nav center info and gut
|
|
* our info struct.
|
|
*/
|
|
XP_List *pCenters = xp_getnavcenterlist(pContext);
|
|
if(pCenters) {
|
|
XP_List *pTraverse = pCenters;
|
|
HT_Pane htPane = NULL;
|
|
while((htPane = (HT_Pane)XP_ListNextObject(pTraverse))) {
|
|
xp_uninitnavcenter(htPane, pContext, TRUE);
|
|
}
|
|
}
|
|
xp_gutnavcenterinfo(pInfo);
|
|
|
|
/* Copy over the url.
|
|
*/
|
|
pInfo->m_pUrl = XP_STRDUP(pUrl);
|
|
|
|
/* Update any watching nav centers.
|
|
*/
|
|
if(pCenters) {
|
|
XP_List *pTraverse = pCenters;
|
|
HT_Pane htPane = NULL;
|
|
while((htPane = (HT_Pane)XP_ListNextObject(pTraverse))) {
|
|
xp_initnavcenter(htPane, pContext, TRUE);
|
|
}
|
|
XP_ListDestroy(pCenters);
|
|
pCenters = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Add a sitemap for a context.
|
|
* The url has to be set for a context before this will work.
|
|
*/
|
|
void XP_AddNavCenterSitemap(MWContext *pContext, char *pSitemap, char* name)
|
|
{
|
|
if(pSitemap && pContext) {
|
|
MWContext *pBrowser = XP_GetNonGridContext(pContext);
|
|
#ifndef WANTFRAMES
|
|
if(pBrowser != pContext) {
|
|
return;
|
|
}
|
|
#endif
|
|
if(MWContextBrowser == pBrowser->type) {
|
|
NavCenterContextInfo *pInfo = xp_getnavcenterinfo(pContext);
|
|
if(pInfo && pInfo->m_pUrl) {
|
|
XP_Bool bDuplicate = FALSE;
|
|
|
|
if(pInfo->m_pSitemaps) {
|
|
XP_List *pTraverse = pInfo->m_pSitemaps;
|
|
char *pCheck = NULL;
|
|
while((pCheck = (char *)XP_ListNextObject(pTraverse))) {
|
|
if(0 == XP_STRCMP(pCheck, pSitemap)) {
|
|
bDuplicate = TRUE;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
/* Create the list, first time.
|
|
*/
|
|
pInfo->m_pSitemaps = XP_ListNew();
|
|
}
|
|
|
|
if(FALSE == bDuplicate && pInfo->m_pSitemaps) {
|
|
char *pDup = XP_STRDUP(pSitemap);
|
|
/* Add entry to list.
|
|
*/
|
|
if(pDup) {
|
|
XP_ListAddObject(pInfo->m_pSitemaps, (void *)pDup);
|
|
}
|
|
}
|
|
|
|
if(FALSE == bDuplicate) {
|
|
/* Display entry in various nav centers.
|
|
*/
|
|
XP_List *pCenters = xp_getnavcenterlist(pContext);
|
|
if(pCenters) {
|
|
XP_List *pTraverse = pCenters;
|
|
HT_Pane htPane = NULL;
|
|
while((htPane = (HT_Pane)XP_ListNextObject(pTraverse))) {
|
|
HT_AddSitemapFor(htPane, pInfo->m_pUrl, pSitemap, name);
|
|
}
|
|
XP_ListDestroy(pCenters);
|
|
pCenters = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Call this to association an HTML Pane MWContext to a NavCenter view.
|
|
*/
|
|
void XP_RegisterViewHTMLPane(HT_View htView, MWContext *pContext)
|
|
{
|
|
if(htView && pContext) {
|
|
ViewHTMLPane *pNew = XP_NEW_ZAP(ViewHTMLPane);
|
|
if(pNew) {
|
|
pNew->m_htView = htView;
|
|
pNew->m_pContext = pContext;
|
|
|
|
if(NULL == xp_GlobalViewHTMLPanes) {
|
|
xp_GlobalViewHTMLPanes = XP_ListNew();
|
|
if(NULL == xp_GlobalViewHTMLPanes) {
|
|
XP_FREE(pNew);
|
|
pNew = NULL;
|
|
}
|
|
}
|
|
if(xp_GlobalViewHTMLPanes) {
|
|
XP_ListAddObject(xp_GlobalViewHTMLPanes, (void *)pNew);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* RDF HT Backend calls this to load content into the HTML view
|
|
* of a NavCenter HT_View.
|
|
*/
|
|
int XP_GetURLForView(HT_View htView, char *pAddress)
|
|
{
|
|
int iRetval = MK_NO_ACTION;
|
|
if(htView && pAddress) {
|
|
MWContext *pHTMLPane = xp_gethtmlpane(htView);
|
|
if(pHTMLPane) {
|
|
URL_Struct *pUrl = NET_CreateURLStruct(pAddress, NET_DONT_RELOAD);
|
|
if(pUrl) {
|
|
iRetval = FE_GetURL(pHTMLPane, pUrl);
|
|
}
|
|
}
|
|
}
|
|
return(iRetval);
|
|
}
|
|
|
|
/* Call this to remove nav center info for a context.
|
|
* Just call this before context destruction.
|
|
*/
|
|
void XP_RemoveNavCenterInfo(MWContext *pContext)
|
|
{
|
|
MWContext *pCX = XP_GetNonGridContext(pContext);
|
|
if(pCX && MWContextBrowser == pCX->type) {
|
|
XP_List *pNavCenters = xp_getnavcenterlist(pContext);
|
|
NavCenterContextInfo *pInfo = xp_getnavcenterinfo(pContext);
|
|
if(pNavCenters) {
|
|
XP_List *pTraverse = pNavCenters;
|
|
HT_Pane htPane = NULL;
|
|
while((htPane = (HT_Pane)XP_ListNextObject(pTraverse))) {
|
|
xp_uninitnavcenter(htPane, pContext, TRUE);
|
|
if(pCX == pContext && XP_IsNavCenterDocked(htPane)) {
|
|
xp_undocknavcenter(htPane, FALSE);
|
|
}
|
|
}
|
|
XP_ListDestroy(pNavCenters);
|
|
pNavCenters = NULL;
|
|
}
|
|
|
|
if(pInfo) {
|
|
XP_ListRemoveObject(xp_GlobalNavCenterInfo, (void *)pInfo);
|
|
if(XP_ListIsEmpty(xp_GlobalNavCenterInfo)) {
|
|
XP_ListDestroy(xp_GlobalNavCenterInfo);
|
|
xp_GlobalNavCenterInfo = NULL;
|
|
}
|
|
xp_gutnavcenterinfo(pInfo);
|
|
XP_FREE(pInfo);
|
|
pInfo = NULL;
|
|
}
|
|
}
|
|
|
|
/* Don't use the top level non-grid context for this one,
|
|
* as it may have grid children. though itself not
|
|
* going away.
|
|
*/
|
|
if(pContext) {
|
|
xp_removeviewassociation(NULL, pContext);
|
|
}
|
|
}
|
|
|
|
#endif /* MOZILLA_CLIENT */
|
|
|