home *** CD-ROM | disk | FTP | other *** search
- /* -*- 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 "stdafx.h"
-
- #include "cxabstra.h"
-
- #include "xp_thrmo.h"
- #include "timer.h" // for nettimer since can't call base class
- #include "libi18n.h" // International function
- #include "template.h"
- #include "dialog.h"
- #include "mainfrm.h"
- #ifdef MOZ_MAIL_NEWS
- #include "fldrfrm.h"
- #include "thrdfrm.h"
- #include "msgfrm.h"
- #include "msgcom.h"
- #include "wfemsg.h"
- #endif /* MOZ_MAIL_NEWS */
- #include "winclose.h"
- #include "libevent.h"
- #include "np.h"
- #include "intl_csi.h"
- #include "mkhelp.h" // for HelpInfoStruct
- #include "feimage.h"
- #include "cxicon.h"
- #ifdef EDITOR
- #include "edt.h"
- #endif /* EDITOR */
- #include "mozilla.h"
-
- CAbstractCX::CAbstractCX() {
- // Purpose: Constructor for the abstract base class.
- // Arguments: void
- // Returns: none
- // Comments: Responsible for creating the XP context.
-
- m_pLastStatus = NULL;
-
- // First set our context type.
- // This is really irrelevant, just a reminder to those which derive from us.
- m_cxType = Abstract;
-
- // Create the XP context.
- m_pXPCX = XP_NewContext();
- m_pImageGroupContext = 0;
- m_bImagesLoading = FALSE;
- m_bImagesLooping = FALSE;
- m_bImagesDelayed = FALSE;
- m_bMochaImagesLoading = FALSE;
- m_bMochaImagesLooping = FALSE;
- m_bMochaImagesDelayed = FALSE;
-
- m_bNetHelpWnd = FALSE;
-
- // Set its type to an invalid default.
- // Up to others to correctly set.
- m_pXPCX->type = MWContextAny;
-
- m_pXPCX->fontScalingPercentage = 1.0;
-
- // Assign in the common front end functions.
- m_pXPCX->funcs = new ContextFuncs;
- #define MAKE_FE_FUNCS_PREFIX(funkage) CFE_##funkage
- #define MAKE_FE_FUNCS_ASSIGN m_pXPCX->funcs->
- #include "mk_cx_fn.h"
-
- // Set the FE data to simply point to this class.
- m_pXPCX->fe.cx = this;
-
- // Initialize the global history of the object.
- SHIST_InitSession(m_pXPCX);
-
- // We haven't been told to attempt to interrupt the load.
- // Nor have we decided to self destruct.
- m_bIdleInterrupt = FALSE;
- m_bIdleDestroy = FALSE;
-
- // We have no client pull information.
- m_pClientPullData = FALSE;
- m_pClientPullTimeout = FALSE;
-
- // Reset our stopwatch, in case it never gets initialized.
- ResetStopwatch();
-
- // We haven't been destroyed yet.
- m_bDestroyed = FALSE;
-
- // We have ncapi data yet.
- m_pNcapiUrlData = NULL;
-
- // We are initially allowing clicks.
- GetContext()->waitingMode = FALSE;
-
- // Add the context to the XP list.
- XP_AddContextToList(GetContext());
-
- // No levels of interruptedness.
- m_iInterruptNest = 0;
- }
-
- int16 CAbstractCX::GetWinCsid()
- {
- return INTL_GetCSIWinCSID(LO_GetDocumentCharacterSetInfo(m_pXPCX));
- }
- /*
- * Mocha has removed all of its info from this context, it's
- * safe to trash it now
- */
- void CAbstractCX::MochaDestructionComplete()
- {
- // Now, attempt to interrupt. This allows us to clean up a context, even
- // if the network library is blocking.
- // Eventually, this will cause this context to delete itself.
- Interrupt();
- }
-
- /*
- * Mocha has removed all of its info from this context
- */
- void mocha_done_callback(void * data)
- {
- ((CAbstractCX *)data)->MochaDestructionComplete();
- }
-
- void CAbstractCX::DestroyContext() {
- // Purpose: Before deleting a context, you must destroy it for proper cleanup.
- // Arguments: void
- // Returns: void
- // Comments: Because the XP libraries perform calls on a context when it is going
- // away, and those calls are virtual, we must first "destroy" a context,
- // and then we are able to delete it properly.
-
- if(m_bDestroyed == FALSE) {
- // Only call in here once, please.
- // We have to lock the application from exiting until we receive
- // a series of callbacks and eventually remove the context
- // from memory.
- // This lock is removed in the destructor.
- AfxOleLockApp();
-
- // Have the document interrupt.
- // We call again when we get the mocha complete callback, but that
- // causes us to get deleted physically after the destroyed flag
- // is set.
- Interrupt();
-
- // Layout needs to cleanup.
- LO_DiscardDocument(m_pXPCX);
-
- // End the session history of the context.
- SHIST_EndSession(m_pXPCX);
-
- #ifdef MOZ_MAIL_NEWS
- // Free any memory used for MIME objects
- MimeDestroyContextData(m_pXPCX);
- #endif /* MOZ_MAIL_NEWS */
-
- // We are now destroyed, set a member to let us know.
- m_bDestroyed = TRUE;
-
- if(m_pImageGroupContext) {
- IL_RemoveGroupObserver(m_pImageGroupContext, ImageGroupObserver, (void*)GetContext());
- IL_DestroyGroupContext(m_pImageGroupContext);
- m_pXPCX->img_cx = NULL;
- }
-
- if (m_pXPCX->color_space) {
- IL_ReleaseColorSpace(m_pXPCX->color_space);
- m_pXPCX->color_space = NULL;
- }
-
- // Remove ourselves from the XP context list.
- // Must be done before call to mocha, or lists in
- // unstable state.
- XP_RemoveContextFromList(m_pXPCX);
-
- // Have mocha perform cleanup and continue destruction in the
- // callback
- ET_RemoveWindowContext(m_pXPCX, mocha_done_callback, this);
- }
- }
-
- /*-----------------------------------------------**
- ** Let a load complete before self destructing. **
- **-----------------------------------------------*/
- void CAbstractCX::NiceDestroyContext() {
- m_bIdleDestroy = FALSE;
- if(m_bDestroyed == FALSE && GetContext()) {
- if(XP_IsContextBusy(GetContext())) {
- // Try again later.
- m_bIdleDestroy = TRUE;
- FEU_RequestIdleProcessing(GetContext());
- }
- else {
- // Time's up.
- DestroyContext();
- return;
- }
- }
- }
-
- // Routine to detect when we can exit.
- void fe_finish_exit(void *pClosure)
- {
- BOOL bCanExit = TRUE;
- static void *pExitTimer = NULL;
-
- if(pClosure != NULL) {
- // Called via timeout.
- // Clear the timeout backpointer.
- pExitTimer = NULL;
- }
- else {
- // Called via destructor (anal).
- // Make sure we haven't already set the timer.
- if(pExitTimer != NULL) {
- return;
- }
- }
-
- #ifdef MOZ_LOC_INDEP
- /* li_stuff - time to do last synch */
- if (theApp.LIStuffEnd() == FALSE) {
- // synching files.
- bCanExit = FALSE;
- }
- #endif // MOZ_LOC_INDEP
-
- if(AfxOleCanExitApp() == FALSE) {
- // Outstanding com lock.
- bCanExit = FALSE;
- }
-
- if(XP_ListCount(XP_GetGlobalContextList()) != 0) {
- // Context is out there.
- bCanExit = FALSE;
- }
-
- if(theApp.m_pMainWnd != NULL) {
- if(bCanExit) {
- TRACE("Posting WM_CLOSE to %p hidden frame to exit app.\n", theApp.m_pMainWnd);
- theApp.m_pMainWnd->PostMessage(WM_CLOSE);
- }
- else {
- // Have to retry in a little while.
- pExitTimer = FE_SetTimeout(fe_finish_exit, (void *)-1, 1000);
- ASSERT(pExitTimer != NULL);
- }
- }
- }
-
- CAbstractCX::~CAbstractCX() {
- // Purpose: Destroy the context.
- // Arguments: void
- // Returns: none
- // Comments: Perform any necessary cleanup also.
-
- // Can remove lock set in DestroyContext.
- // Window of instability gone.
- AfxOleUnlockApp();
-
- // Let those watching this context that it is no more (NCAPI).
- CWindowChangeItem::Closing(GetContextID());
-
- // If you get this ASSERTION, then you should call DestroyContext and
- // NEVER delete the context.
- ASSERT(m_bDestroyed == TRUE);
-
- // Get rid of the last and default status.
- if (m_pLastStatus) {
- XP_FREE(m_pLastStatus);
- m_pLastStatus = NULL;
- }
- if(m_pXPCX->defaultStatus != NULL) {
- XP_FREE(m_pXPCX->defaultStatus);
- m_pXPCX->defaultStatus = NULL;
- }
-
- // If we allocated a title for the context, get rid of it.
- if(m_pXPCX->title != NULL) {
- XP_FREE(m_pXPCX->title);
- m_pXPCX->title = NULL;
- }
-
- // Get rid of its name.
- if(m_pXPCX->name != NULL) {
- XP_FREE(m_pXPCX->name);
- m_pXPCX->name = NULL;
- }
-
- // Free the transparent pixel used by the Image Library.
- if(m_pXPCX->transparent_pixel) {
- XP_FREE(m_pXPCX->transparent_pixel);
- m_pXPCX->transparent_pixel = NULL;
- }
-
- /* EA: Remove any help information associated with this context */
- if (m_pXPCX && (m_pXPCX->pHelpInfo != NULL)) {
- if (((HelpInfoStruct *) m_pXPCX->pHelpInfo)->topicURL != NULL) {
- XP_FREE(((HelpInfoStruct *) m_pXPCX->pHelpInfo)->topicURL);
- ((HelpInfoStruct *) m_pXPCX->pHelpInfo)->topicURL = NULL;
- }
-
- XP_FREE(m_pXPCX->pHelpInfo);
- m_pXPCX->pHelpInfo = NULL;
- }
-
- // Delete our function table in the XP context.
- memset(m_pXPCX->funcs, 0, sizeof(*(m_pXPCX->funcs)));
- delete m_pXPCX->funcs;
- m_pXPCX->funcs = NULL;
-
- // Delete our XP context.
- XP_DeleteContext(m_pXPCX);
- m_pXPCX = NULL;
-
- // NOTE: Frames and Views should be taken care of by sub-classes
-
- // There are three "hiding" contexts
- #ifdef MOZ_MAIL_NEWS
- #define HIDDENCXS 4
- #else
- #define HIDDENCXS 2
- #endif /* MOZ_MAIL_NEWS */
- // bookmarks window
- // address book window
- // biff / check mail context
- // Misc. URL loader context which switch context, ie: NetHelp, etc.
- // Check the number of items in the context list to see if we should exit.
- if(XP_ListCount(XP_GetGlobalContextList()) == HIDDENCXS) {
- // These are the stragglers that we need to see if visible,
- // and if not, remove them at this time.
- // All or none.
- // Do in seperate for loops or list state is undefined.
- CAbstractCX *pCXs[HIDDENCXS];
- int iTraverse;
- for(iTraverse = 0; iTraverse < HIDDENCXS; iTraverse++) {
- pCXs[iTraverse] = ABSTRACTCX((MWContext *)XP_ListGetObjectNum(XP_GetGlobalContextList(), iTraverse + 1));
- }
- for(iTraverse = 0; iTraverse < HIDDENCXS; iTraverse++) {
- if(pCXs[iTraverse]) {
- pCXs[iTraverse]->DestroyContext();
- }
- }
-
- // Because we've killed off the hidden contexts, clear pointers
- // to them.
- theApp.m_pSlaveCX = NULL;
- theApp.m_pRDFCX = NULL;
-
- // Start to detect when we can exit the application.
- fe_finish_exit(NULL);
- }
- }
-
- void CAbstractCX::SetContextName(const char *pName) {
- // Set the context name.
- if(GetContext()->name != NULL) {
- XP_FREE(GetContext()->name);
- }
- if(pName != NULL) {
- GetContext()->name = XP_STRDUP(pName);
- }
- else {
- GetContext()->name = NULL;
- }
- }
-
- void CAbstractCX::SetParentContext(MWContext *pParentContext) {
- // Set the context's parent context.
- GetContext()->grid_parent = pParentContext;
-
- // Also set that this is a grid cell.
- // Can't have a grid parent if not a true grid.
- GetContext()->is_grid_cell = TRUE;
-
- // Finally, update what is called the parent's list of children.
- // Removal is taken care of automagically.
- XP_UpdateParentContext(GetContext());
- }
-
- BOOL CAbstractCX::IsGridCell() const {
- return(GetContext()->is_grid_cell);
- }
-
- BOOL CAbstractCX::IsGridParent() const {
- BOOL bRetval = FALSE;
- MWContext *pContext = GetContext();
- if(pContext) {
- bRetval = !XP_ListIsEmpty(pContext->grid_children);
- }
- return bRetval;
- }
-
- CWnd *CAbstractCX::GetDialogOwner() const {
- // Purpose: Return the parent/owner of any dialogs for the context.
- // Arguments: void
- // Returns: CWnd * The parent as needed.
- // Comments: Generic use function to more easily define the owner
- // of any dialogs.
-
- // As a default, we'll be returning the desktop window.
- return(CWnd::GetDesktopWindow());
- }
-
- // This routine changes the context of the specified URL structure to be
- // a browser context. Returns the new context if successful and NULL otherwise
- MWContext *SwitchToBrowserContext(URL_Struct* pUrlStruct)
- {
- ASSERT(NET_IsSafeForNewContext(pUrlStruct));
-
- // Use an existing browser window if we have one
- CFrameWnd* pFrameWnd = FEU_GetLastActiveFrame(MWContextBrowser, FEU_FINDBROWSERONLY);
- MWContext* pNewContext = NULL;
-
- if (pFrameWnd) {
- CFrameGlue *pGlue = CFrameGlue::GetFrameGlue(pFrameWnd);
- CWinCX* pWinCX;
-
- if (pGlue && ((pWinCX = pGlue->GetMainWinContext()) != NULL)) {
- pNewContext = pWinCX->GetContext();
-
- // Don't use this context if it's busy or doesn't want to be used.
- if (ABSTRACTCX(pNewContext)->IsContextStoppable()
- || pNewContext->restricted_target)
- pNewContext = NULL; // create a new context instead
- else {
- pWinCX->GetUrl( pUrlStruct, FO_CACHE_AND_PRESENT, TRUE );
- // Make sure the window is visible
- if(pFrameWnd->IsIconic())
- pFrameWnd->ShowWindow(SW_RESTORE);
- else {
- #ifdef XP_WIN16
- pFrameWnd->BringWindowToTop();
- #else
- pFrameWnd->SetForegroundWindow();
- #endif
- }
- }
- }
- }
-
- // If we couldn't find an existing browser window, then create a new one
- if (!pNewContext) {
- // Create a new browser window
- pNewContext = CFE_CreateNewDocWindow(NULL, pUrlStruct);
- }
-
- return pNewContext;
- }
-
- int CAbstractCX::NormalGetUrl(const char *pUrl, const char *pReferrer, const char *pTarget, BOOL bForceNew) {
- // Generic brain dead interface to GetUrl.
- URL_Struct *pUrlStruct = NET_CreateURLStruct(pUrl, NET_DONT_RELOAD);
-
- // Add the referrer field.
- if(pReferrer != NULL) {
- pUrlStruct->referer = XP_STRDUP(pReferrer);
- }
-
- // Add the target name.
- if(pTarget != NULL) {
- if (pTarget[0] == '_') {
- pUrlStruct->window_target = XP_STRDUP("");
- }
- else {
- pUrlStruct->window_target = XP_STRDUP(pTarget);
- }
- }
-
- // Load it.
- #ifdef EDITOR
- // Use Edit present type to filter mime types we can't edit
- return( GetUrl(pUrlStruct, EDT_IS_EDITOR(GetContext()) ? FO_CACHE_AND_EDIT : FO_CACHE_AND_PRESENT, TRUE, bForceNew));
- #else
- return(GetUrl(pUrlStruct, FO_CACHE_AND_PRESENT, TRUE, bForceNew));
- #endif
- }
-
- int CAbstractCX::GetUrl(URL_Struct *pUrl, FO_Present_Types iFormatOut, BOOL bReallyLoad, BOOL bForceNew) {
- // Purpose: Load a url into the context class.
- // Arguments: pUrl The URL to load
- // iFormatOut The format out of the load (helps determine the content type converter
- // along with the mime type).
- // bReallyLoading Is a switch to tell us not to actually request the URL.
- // This helps and context changing URLs to bootstrap the loading UI.
- // Returns: int As NET_GetURL
- // Comments: Use this instead of NET_GetURL
-
- // Determine URL type. -1 is out of range.
- int iUrlType = -1;
- if(pUrl && pUrl->address) {
- iUrlType = NET_URL_Type(pUrl->address);
- }
-
- // Switch on URL type to see how we should handle.
- int iRetval = MK_NO_ACTION;
- switch(iUrlType) {
- case NETHELP_TYPE_URL: {
- MWContext *pNetHelpCX = FE_GetNetHelpContext();
- if(pNetHelpCX) {
- iRetval = NET_GetURL(pUrl, FO_PRESENT, pNetHelpCX, CFE_SimpleGetUrlExitRoutine);
- }
- break;
- }
- default: {
- // See if this is the current page (named anchor), if so don't load.
- // But don't do this if we're not really initiating the load ourselves.
- // Also make sure that this is a present type, if not, don't check
- // for this named anchor stuff.
- // If this isn't acceptable behaviour, we really need to split what
- // you're doing into a new context (view source dialog could be this
- // way as an example).
- int32 lX, lY;
- BOOL bNamedAnchor = FALSE;
- if(((iFormatOut & 0x1f ) == FO_PRESENT) && bReallyLoad == TRUE && XP_FindNamedAnchor(GetContext(), pUrl, &lX, &lY) == TRUE) {
- if(IsWindowContext()) {
- // Make the location visible on the screen....
- PANECX(GetContext())->MakeElementVisible(lX, lY);
- }
- if(pUrl->history_num == 0) {
- // Create URL from prev history entry to preserve security attributes, etc.
- History_entry *pHist = SHIST_GetCurrent(&GetContext()->hist);
- URL_Struct *pCopyURL = SHIST_CreateURLStructFromHistoryEntry(GetContext(), pHist);
-
- // Swap addresses.
- char *pSaveAddr = pUrl->address;
- pUrl->address = pCopyURL->address;
- pCopyURL->address = pSaveAddr;
-
- // Free old URL, and reassign.
- NET_FreeURLStruct(pUrl);
- pUrl = pCopyURL;
-
- SHIST_AddDocument(GetContext(), SHIST_CreateHistoryEntry(pUrl, pHist->title));
- }
- else {
- SHIST_SetCurrent(&GetContext()->hist, pUrl->history_num);
- }
-
- // Didn't have to perform a load.
- // However, we should call the normal routines to stop all the UI....
- bReallyLoad = FALSE;
- bNamedAnchor = TRUE;
- }
-
- // The URLs anchor and referrer may be a local file path.
- // Change them to be network worthy.
- CString csUrl;
- if(pUrl->address != NULL) {
- WFE_ConvertFile2Url(csUrl, pUrl->address);
- XP_FREE(pUrl->address);
- pUrl->address = XP_STRDUP(csUrl);
- }
- if(pUrl->referer != NULL) {
- WFE_ConvertFile2Url(csUrl, pUrl->referer);
- XP_FREE(pUrl->referer);
- pUrl->referer = XP_STRDUP(csUrl);
- }
-
- #ifdef MOZ_MAIL_NEWS
- if ((((iFormatOut & 0x1f ) == FO_PRESENT)
- && (GetContext()->type != MWContextMetaFile)
- && MSG_NewWindowRequired(GetContext(), pUrl->address))
- || bForceNew)
-
- {
- MWContextType type = MWContextBrowser;
- if ( MSG_RequiresMailWindow ( pUrl->address ) )
- type = MWContextMail;
- else if ( MSG_RequiresNewsWindow ( pUrl->address ) )
- type = MWContextNews;
-
- if (( ( type == MWContextNews ) || ( type == MWContextMail ) ) && !bForceNew )
- {
- CMailNewsFrame *pMailNewsFrame = NULL;
- MSG_PaneType paneType = MSG_PaneTypeForURL(pUrl->address);
-
- switch ( paneType )
- {
- case MSG_THREADPANE:
- {
- MSG_FolderInfo *folder = MSG_GetFolderInfoFromURL(WFE_MSGGetMaster(), pUrl->address);
- BOOL bContinue = FALSE;
- if (folder){
- C3PaneMailFrame::Open(folder, MSG_MESSAGEKEYNONE, &bContinue);
- }
- if (!bContinue)
- return MK_CHANGING_CONTEXT;
- else
- break;
- }
- case MSG_MESSAGEPANE:
- {
- C3PaneMailFrame *pThreadFrame = CMailNewsFrame::GetLastThreadFrame();
- if (pThreadFrame && pThreadFrame == CWnd::GetActiveWindow() &&
- pThreadFrame->GetMainContext() == this)
- break;
- pMailNewsFrame = CMessageFrame::Open();
- if ( pMailNewsFrame ) {
- pUrl->msg_pane = pMailNewsFrame->GetPane();
- pMailNewsFrame->GetContext()->GetUrl( pUrl, iFormatOut, bReallyLoad );
- }
- return MK_CHANGING_CONTEXT;
- }
- case MSG_FOLDERPANE:
- default:
- pMailNewsFrame = CFolderFrame::Open();
- if ( pMailNewsFrame )
- pMailNewsFrame->GetContext()->GetUrl( pUrl, iFormatOut, bReallyLoad );
- return MK_CHANGING_CONTEXT;
- }
- }
- else if (GetContextType() != IconCX && GetContextType() != Pane) {
- MWContext* pNewContext = SwitchToBrowserContext(pUrl);
- return MK_CHANGING_CONTEXT;
- }
- }
- #endif // MOZ_MAIL_NEWS
-
- // Our first (well, almost) task is to interrupt the load.
- // Only one load per window should be instantiated by the front end.
- // Do this only if this is the context which is going to handle it.
- // If this is a view source request, don't interrupt the context
- // because we will be creating a new window.
- if(bNamedAnchor == FALSE && bReallyLoad == TRUE &&
- iFormatOut != FO_CACHE_AND_VIEW_SOURCE) {
- Interrupt();
- }
-
- // Disable clicking.
- GetContext()->waitingMode = TRUE;
-
- // The fun part about all this is, is that we don't want to call reentrantly
- // into the netlib, or else our idle interrupt routine will interrupt
- // both requests. Check to see if we're waiting for an idle interrupt.
- // Use the client pull mechanism to get around this.
- // Also, if we're not supposed to really call to load this URL, then don't.
- if(bReallyLoad == TRUE) {
- if(m_bIdleInterrupt == FALSE) {
- // Simply call the netlib routine, filling in some default data.
- // Pass along the common exit routine, which will call the appropriate
- // contexts exit routine.
- int iOldInProcessNet = winfeInProcessNet;
- winfeInProcessNet = TRUE;
- StartAnimation();
- if ( m_cxType == IconCX)
- iRetval = NET_GetURL(pUrl, iFormatOut, GetContext(), Icon_GetUrlExitRoutine);
- else
- iRetval = NET_GetURL(pUrl, iFormatOut, GetContext(), CFE_GetUrlExitRoutine);
- FE_UpdateStopState(GetContext());
-
- winfeInProcessNet = iOldInProcessNet;
- }
- else {
- // Set client pull on this URL.
- FEU_ClientPull(GetContext(), 250, pUrl, iFormatOut, TRUE);
-
- // Return that no action was taken, yet.
- iRetval = MK_NO_ACTION;
- }
- }
- else {
- // Indicate that we skipped loading since we're allowing someone to change
- // context.
- iRetval = MK_CHANGING_CONTEXT;
- }
-
- // If we were a named anchor, clean everything we did up.
- if(bNamedAnchor == TRUE) {
- iRetval = MK_DATA_LOADED;
-
- // We need to update the location bar's text, since LayoutNewDocument was never
- // called (routine responsible for this).
- if(IsFrameContext() && GetContext()->type == MWContextBrowser && !EDT_IS_EDITOR(GetContext())){
-
- if(IsGridCell() == FALSE) {
- TRACE("Updating location bar for named anchor\n");
- CWinCX *pWinCX = WINCX(GetContext());
- CFrameGlue *pFrame = pWinCX->GetFrame();
-
- if(pFrame){
- CURLBar *pUrlBar = (CURLBar *)pFrame->GetChrome()->GetToolbar(ID_LOCATION_TOOLBAR);
- if(pUrlBar)
- pUrlBar->UpdateFields(pUrl->address);
- }
- }
- }
-
- // Call the exit routine on the URL.
- // Just use the common one that would have been used anyhow.
- CFE_GetUrlExitRoutine(pUrl, iRetval, GetContext());
-
- // If there aren't any connections for the window, also call all connections
- // complete.
- // Context by context version, don't use XP_IsContextBusy.
- if(NET_AreThereActiveConnectionsForWindow(GetContext()) == FALSE) {
- FE_AllConnectionsComplete(GetContext());
- }
- }
- break;
- }
- }
-
- // All Done.
- return(iRetval);
- }
-
- void CAbstractCX::Reload(NET_ReloadMethod iReloadType) {
- // Purpose: Reloads the current document in the context's history.
- // Arguments: void
- // Returns: void
- // Comments: Standard stuff.
-
- if(CanCreateUrlFromHist()) {
- URL_Struct *pUrl = CreateUrlFromHist(FALSE, NULL, iReloadType == NET_RESIZE_RELOAD);
-
- // Force the load (normally).
- if(pUrl) {
- pUrl->force_reload = iReloadType;
-
- GetUrl(pUrl, FO_CACHE_AND_PRESENT);
- }
- }
- }
-
- extern "C" Bool LO_LayingOut(MWContext * context);
-
- void CAbstractCX::NiceReload(int usePassInType, NET_ReloadMethod iReloadType ) {
- // Purpose: Reloads the current document in the context's history, only
- // if we're currently not loading.
- // Arguments: void
- // Returns: void
- // Comments: Standard stuff.
-
- MWContext * context = GetContext();
- if(XP_IsContextBusy(context) == TRUE || LO_LayingOut(context)) {
- FEU_RequestIdleProcessing(context);
- context->reSize = TRUE;
- }
- else {
- context->reSize = FALSE;
- NPL_SamePage(context);
- if( usePassInType ) {
- Reload( iReloadType );
- return;
- }
-
- if (MAIL_NEWS_TYPE(context->type)) {
- Reload(NET_NORMAL_RELOAD);
- }
- else {
- Reload(NET_RESIZE_RELOAD);
- }
- }
- }
-
- void CAbstractCX::Back() {
- // Purpose: Goes back one in the history.
- // Arguments: void
- // Returns: void
- // Comments: Standard stuff.
-
- History_entry *pHist = SHIST_GetPrevious(GetContext());
- if (GetContext()->grid_children) {
- if (LO_BackInGrid(GetDocumentContext())) {
- return;
- }
- }
- if(pHist) {
- GetUrl(SHIST_CreateURLStructFromHistoryEntry(GetContext(), pHist), FO_CACHE_AND_PRESENT);
- }
- }
-
- void CAbstractCX::Forward() {
- // Purpose: Goes forward one in the history.
- // Arguments: void
- // Returns: void
- // Comments: Standard stuff.
-
- History_entry *pHist = SHIST_GetNext(GetContext());
- if (GetContext()->grid_children) {
- if (LO_ForwardInGrid(GetDocumentContext())) {
- return;
- }
- }
- if(pHist) {
- GetUrl(SHIST_CreateURLStructFromHistoryEntry(GetContext(), pHist), FO_CACHE_AND_PRESENT);
- }
- }
-
- XL_TextTranslation CAbstractCX::TranslateText(URL_Struct *pUrl, const char *pFileName, const char *pPrefix, int iWidth) {
- // Purpose: Translate a url into text.
- // Arguments: pUrl The URL to translate.
- // pFileName The file in which to save the translation, CANNOT BE NULL.
- // pPrefix A prefix for each line, CANNOT BE NULL.
- // iWidth The width in characters of each line.
- // Returns: XL_TextTranslation as XL_TranslateText
- // Comments: Wraps all the work of manually calling the text translation routines.
- // There's no need to track the PrintSetup struct we create in this function,
- // as it will come back in the translation exit routine and can be
- // freed there.
-
- // Create a new print setup.
- PrintSetup *pTextFE = XP_NEW(PrintSetup);
-
- // Initialize.
- XL_InitializeTextSetup(pTextFE);
-
- // Assign in the needed members.
- pTextFE->width = iWidth;
- if(pPrefix)
- pTextFE->prefix = XP_STRDUP(pPrefix);
- else
- pTextFE->prefix = XP_STRDUP("");
- pTextFE->eol = "\r\n";
- pTextFE->filename = XP_STRDUP(pFileName);
- pTextFE->out = fopen(pFileName, "wb");
- pTextFE->completion = CFE_TextTranslationExitRoutine; // Abstracted exit routine.
- pTextFE->url = pUrl;
- pTextFE->carg = CX2VOID(this, CAbstractCX);
-
- // Do it.
- return(XL_TranslateText(GetContext(), pUrl, pTextFE));
- }
-
- void CAbstractCX::Interrupt() {
- // Purpose: Interrupt any loads in a context.
- // Arguments: void
- // Returns: void
- // Comments: If able, this will interrupt any loads in a context.
- // If unable, then sets a flag for idle time interrupting.
-
- // Increment our level of nested ness in the Interrupt function.
- // Problem is, that this is the only function which actually deletes
- // a context.
- // If we're nested several levels, then each tries to free the context.
- m_iInterruptNest++;
-
- // Provide a way to interrupt even if we're winfeInProcessNet but there
- // is currently no activity.
- // If we're not busy, then there's no need to interrupt.
- if(IsContextStoppable() == FALSE) {
- // Clear the idle interrupt if already set.
- m_bIdleInterrupt = FALSE;
- }
- // Reentrant safe version.
- else if(winfeInProcessNet == FALSE) {
- winfeInProcessNet = TRUE;
- XP_InterruptContext(GetContext());
- winfeInProcessNet = FALSE;
-
- // Set the flag that we need no idle interrupt.
- // This is to avoid cases where we have set to idle interrupt, and get
- // called again where we actually do interrupt.
- m_bIdleInterrupt = FALSE;
- }
- else {
- // Request some idle processing.
- FEU_RequestIdleProcessing(GetContext());
- m_bIdleInterrupt = TRUE;
- }
-
- // Decrement the level of nestedness.
- m_iInterruptNest--;
-
- // Check to see if we're supposed to delete this thing.
- // Idle interrupt will be true if unable to do anything, and will need
- // idle time so we don't destroy it then.
- // m_bDestroyed will be true, requesting the deletion.
- // m_iInterruptNest will be 0, indicating that we are at the bottom
- // most level of interrupt call.
- if(m_bDestroyed == TRUE &&
- m_bIdleInterrupt == FALSE &&
- m_iInterruptNest == 0) {
-
- // Delete.
- delete this;
- }
-
- return;
- }
-
- BOOL CAbstractCX::IsContextStoppableRecurse() {
- MWContext *pChild;
-
- if (!GetContext())
- return FALSE;
- if ((m_bImagesLoading || m_bImagesLooping) && !m_bImagesDelayed)
- return TRUE;
-
- if ((m_bMochaImagesLoading || m_bMochaImagesLooping) && !m_bMochaImagesDelayed)
- return TRUE;
-
- XP_List *pTraverse = GetContext()->grid_children;
- while (pChild = (MWContext *)XP_ListNextObject(pTraverse)) {
- if (ABSTRACTCX(pChild)->IsContextStoppableRecurse())
- return TRUE;
- }
-
- return FALSE;
- }
-
- // A wrapper around XP_IsContextStoppable. This is necessary
- // because a context is stoppable if its image context is
- // stoppable, and the image context is owned by the Front End.
- BOOL CAbstractCX::IsContextStoppable() {
- return (IsContextStoppableRecurse() ||
- XP_IsContextStoppable(GetContext()));
- }
-
- void CAbstractCX::MailDocument() {
- #ifdef MOZ_MAIL_NEWS
- if(CanMailDocument()) {
- #ifdef EDITOR
- if (EDT_IS_EDITOR(GetContext())) {
- // Don't need to force saving document, EDT_MailDocument
- // will do the right thing.
- EDT_MailDocument(GetContext());
- }
- else {
- MSG_MailDocumentURL(GetContext(),NULL);
- }
- #endif
- }
- #endif /* MOZ_MAIL_NEWS */
- }
-
- BOOL CAbstractCX::CanMailDocument() {
- BOOL bRetval = TRUE;
-
- #ifdef MOZ_MAIL_NEWS
- if (!theApp.m_hPostalLib)
- return(FALSE);
- #endif // MOZ_MAIL_NEWS
-
- if(IsDestroyed()) {
- bRetval = FALSE;
- }
- else if(CanCreateUrlFromHist() == FALSE) {
- bRetval = FALSE;
- }
- else if(IsGridParent()) {
- bRetval = FALSE;
- }
-
- return(bRetval);
- }
-
- void CAbstractCX::OpenUrl() {
- // If we've a parent context, let them deal with this.
- if( GetParentContext() ) {
- ABSTRACTCX(GetParentContext())->OpenUrl();
- } else if( !IsDestroyed() ) {
- ASSERT( GetDialogOwner() );
- // Have the frame bring up the open url dialog.
- if( GetDialogOwner() ) {
- CDialogURL urlDlg(GetDialogOwner(), GetContext());
- urlDlg.DoModal();
- }
- }
- }
-
- BOOL CAbstractCX::CanOpenUrl() {
- // If we've a parent context, let them deal with this.
- if(GetParentContext()) {
- return(ABSTRACTCX(GetParentContext())->CanOpenUrl());
- } else if(IsDestroyed()) {
- return(FALSE);
- } else {
- // Perhaps not if we're in some kiosk mode.
- return( GetDialogOwner() ? TRUE : FALSE);
- }
- }
-
- void CAbstractCX::NewWindow() {
- // Create a new window.
- if(CanNewWindow()) {
- CFE_CreateNewDocWindow(GetContext(), NULL);
- }
- }
-
- BOOL CAbstractCX::CanNewWindow() {
- // Can always get a new window (well....)
- BOOL bRetval = TRUE;
- if(IsDestroyed() == TRUE) {
- bRetval = FALSE;
- }
- else {
- // Limit windows only for win16
- #ifdef XP_WIN16
- // Limit to 8 top level browser contexts.
- // We may have Edit windows open and we run into
- // the limit of four real quick!
- if(XP_ContextCount(MWContextBrowser, TRUE) >= 8) {
- bRetval = FALSE;
- }
- #endif
- }
-
- return(bRetval);
- }
-
- static void UpdateUI(CAbstractCX *pCX)
- {
- if(pCX->IsFrameContext() == TRUE) {
- CWinCX *pWinCX = WINCX(pCX->GetContext());
- CFrameGlue *pFrame = pWinCX->GetFrame();
- // We need to make sure the toolbar buttons are correctly updated.
- // Most importantly, the stop button needs to be updated
- if(pFrame){
- CFrameWnd* pFrameWnd = pFrame->GetFrameWnd();
-
- if (pFrameWnd)
- pFrameWnd->SendMessageToDescendants(WM_IDLEUPDATECMDUI, (WPARAM)TRUE, (LPARAM)0);
- }
- }
- }
-
- void CAbstractCX::AllBack() {
- // Pass up to the parent for the ALL effect.
- if(GetParentContext()) {
- ABSTRACTCX(GetParentContext())->AllBack();
- }
- else if(IsDestroyed() == FALSE) {
- Back();
- UpdateUI(this);
- }
- }
-
- BOOL CAbstractCX::CanAllBack() {
- // Ask the parent for the ALL effect.
- if(GetParentContext()) {
- return(ABSTRACTCX(GetParentContext())->CanAllBack());
- }
-
- BOOL bRetval = TRUE;
- if(IsDestroyed()) {
- bRetval = FALSE;
- }
- else {
- // Ask the session history.
- bRetval = SHIST_CanGoBack((GetContext()));
- }
-
- return(bRetval);
- }
-
- void CAbstractCX::AllForward() {
- // Pass up to the parent for the ALL effect.
- if(GetParentContext()) {
- ABSTRACTCX(GetParentContext())->AllForward();
- }
- else if(IsDestroyed() == FALSE) {
- Forward();
- UpdateUI(this);
- }
- }
-
- BOOL CAbstractCX::CanAllForward() {
- // Ask the parent for the ALL effect.
- if(GetParentContext()) {
- return(ABSTRACTCX(GetParentContext())->CanAllForward());
- }
-
- BOOL bRetval = TRUE;
- if(IsDestroyed()) {
- bRetval = FALSE;
- }
- else {
- // Ask the session history.
- bRetval = SHIST_CanGoForward((GetContext()));
- }
-
- return(bRetval);
- }
-
- void CAbstractCX::AllInterrupt() {
- // Pass up to the parent for the ALL effect.
- if(GetParentContext()) {
- ABSTRACTCX(GetParentContext())->AllInterrupt();
- }
- else if(IsDestroyed() == FALSE) {
- Interrupt();
- }
- }
-
- BOOL CAbstractCX::CanAllInterrupt() {
- // Ask the parent for the ALL effect.
- if(GetParentContext()) {
- return(ABSTRACTCX(GetParentContext())->CanAllInterrupt());
- }
-
- BOOL bRetval = TRUE;
- if(IsDestroyed()) {
- bRetval = FALSE;
- }
- else {
- // See if the context is busy.
- bRetval = IsContextStoppable();
- }
-
- return(bRetval);
- }
-
- void CAbstractCX::AllReload(NET_ReloadMethod iReloadType) {
- // Pass up to the parent for the ALL effect.
- if(GetParentContext()) {
- ABSTRACTCX(GetParentContext())->AllReload(iReloadType);
- }
- else if(IsDestroyed() == FALSE) {
- Reload(iReloadType);
- }
- }
-
- BOOL CAbstractCX::CanAllReload() {
- // Ask the parent for the ALL effect.
- if(GetParentContext()) {
- return(ABSTRACTCX(GetParentContext())->CanAllReload());
- }
-
- BOOL bRetval = TRUE;
- if(IsDestroyed()) {
- bRetval = FALSE;
- }
- else {
- // See if the context can be reloaded (has history).
- History_entry *pHist = SHIST_GetCurrent(&(GetContext()->hist));
- if(pHist == NULL) {
- bRetval = FALSE;
- }
- }
-
- return(bRetval);
- }
-
- BOOL CAbstractCX::CanAddToBookmarks()
- {
- if( GetParentContext() ) {
- return(ABSTRACTCX(GetParentContext())->CanAddToBookmarks());
- }
-
- if( IsDestroyed() ) {
- return(FALSE);
- }
-
- // Can only do this if we have something currently loaded.
- if( !CanCreateUrlFromHist() ) {
- return(FALSE);
- }
-
- return(TRUE);
- }
-
- void CAbstractCX::AddToBookmarks()
- {
- if( GetParentContext() ) {
- ABSTRACTCX(GetParentContext())->AddToBookmarks();
- return;
- }
-
- if( !CanAddToBookmarks() ) {
- return;
- }
-
- History_entry *pHistEnt = SHIST_GetCurrent( &(GetContext()->hist) );
- ASSERT(pHistEnt);
-
- HT_AddBookmark( pHistEnt->address, GetContext()->title );
- }
-
- void CAbstractCX::CopySelection() {
- if(CanCopySelection() == FALSE) {
- return;
- }
-
- HANDLE h;
- HANDLE hData;
- char * string;
- char * text;
-
- text = (char *)LO_GetSelectionText(GetDocumentContext());
- if(!text) {
- // Layout is reporting a selection, but we can't get it.
- ASSERT(0);
- return;
- }
-
- if(!::OpenClipboard(NULL)) {
- FE_Alert(GetContext(), szLoadString(IDS_OPEN_CLIPBOARD));
- return;
- }
-
- if(!::EmptyClipboard()) {
- FE_Alert(GetContext(), szLoadString(IDS_EMPTY_CLIPBOARD));
- return;
- }
-
- int len = XP_STRLEN(text) + 1;
-
- hData = GlobalAlloc(GMEM_MOVEABLE, (DWORD) len);
- string = (char *) GlobalLock(hData);
- strncpy(string, text, len);
- string[len - 1] = '\0';
- GlobalUnlock(hData);
-
- h = ::SetClipboardData(CF_TEXT, hData);
-
- #ifdef XP_WIN32
- int datacsid = GetWinCsid() & ~CS_AUTO;
- if((CS_USER_DEFINED_ENCODING != datacsid) && (0 != datacsid))
- {
- len = CASTINT((INTL_StrToUnicodeLen(datacsid, (unsigned char*)text)+1) * 2);
- hData = GlobalAlloc(GMEM_MOVEABLE, (DWORD) len);
- string = (char *) GlobalLock(hData);
- INTL_StrToUnicode(datacsid, (unsigned char*)text, (INTL_Unicode*)string, len);
-
- GlobalUnlock(hData);
- }
- h = ::SetClipboardData(CF_UNICODETEXT, hData);
-
- #endif
-
- ::CloseClipboard();
- XP_FREE(text);
- }
-
- BOOL CAbstractCX::CanCopySelection() {
- BOOL bRetval;
- History_entry *pHist = SHIST_GetCurrent(&(GetContext()->hist));
- if(IsDestroyed()) {
- bRetval = FALSE;
- }
- else if(pHist == NULL) {
- bRetval = FALSE;
- }
- else {
- // Is there anything selected to be copied?
- bRetval = LO_HaveSelection(GetDocumentContext());
- }
-
- return(bRetval);
- }
-
- // Look up a context via ID.
- // Used mainly by DDE and external application context lookup (out of process).
- // Returns NULL on failure.
- // To get the context ID, call FE_GetContextID or CAbstractCX::GetContextID
- CAbstractCX *CAbstractCX::FindContextByID(DWORD dwID)
- {
- MWContext *pTraverseContext = NULL;
- CAbstractCX *pTraverseCX = NULL;
-
- XP_List * thelist = XP_GetGlobalContextList();
- while (pTraverseContext = (MWContext *)XP_ListNextObject(thelist)) {
- if(pTraverseContext != NULL && ABSTRACTCX(pTraverseContext) != NULL) {
- pTraverseCX = ABSTRACTCX(pTraverseContext);
-
- if(pTraverseCX->GetContextID() == dwID) {
- break;
- }
- pTraverseCX = NULL;
- }
- }
-
- return(pTraverseCX);
- }
-
- // Create a url struct from the history, with appropriate checking
- // for NULL and such, so that we don't have this code scattered
- // throughout the client.
- // bClearStateData is a flag set to erase any data that can't be
- // tossed around without upsetting the client (form data).
- // It's off by default, so be careful out there.
- URL_Struct *CAbstractCX::CreateUrlFromHist(BOOL bClearStateData, SHIST_SavedData *pSavedData, BOOL bWysiwyg)
- {
- TRACE("Creating URL from the current history entry.\n");
-
- // Make sure that we're not destroyed.
- if(IsDestroyed()) {
- return(NULL);
- }
-
- // Do we have a history entry from which to create
- // the url?
- History_entry *pHistoryEntry = SHIST_GetCurrent(&(GetContext()->hist));
- if(pHistoryEntry == NULL || pHistoryEntry->address == NULL) {
- return(NULL);
- }
-
- URL_Struct *pUrl = NULL;
- if(!bWysiwyg) {
- pUrl = SHIST_CreateURLStructFromHistoryEntry(GetContext(), pHistoryEntry);
- }
- else {
- pUrl = SHIST_CreateWysiwygURLStruct(GetContext(), pHistoryEntry);
- }
-
- if(pUrl == NULL) {
- return(NULL);
- }
-
- if(bClearStateData != FALSE) {
- TRACE("Clearing URL state data.\n");
-
- // We may be wanting to copy the form data beyond the scope of this function.
- // Make sure layout saves the current state.
- LO_SaveFormData(GetDocumentContext());
-
- // Are we to copy the session history to the parameter passed in (used in
- // subsequent call to copy the form data)?
- if(pSavedData) {
- memcpy(pSavedData, (void *)&(pUrl->savedData), sizeof(SHIST_SavedData));
- }
-
- // If this structure changes in the future to hold data which can be carried
- // across contexts, then we lose.
- memset((void *)&(pUrl->savedData), 0, sizeof(SHIST_SavedData));
- }
-
- return(pUrl);
- }
-
- // Used mainly in cmdui enablers to determine if we could load from
- // the current history entry.
- BOOL CAbstractCX::CanCreateUrlFromHist()
- {
- // Make sure that we're not destroyed.
- if(IsDestroyed()) {
- return(FALSE);
- }
-
- // Do we have a history entry from which to create
- // the url?
- History_entry *pHistoryEntry = SHIST_GetCurrent(&(GetContext()->hist));
- if(pHistoryEntry == NULL || pHistoryEntry->address == NULL) {
- return(FALSE);
- }
-
- // Looks safe.
- return(TRUE);
- }
-
- void CAbstractCX::ResetStopwatch()
- {
- m_ttStopwatch = theApp.GetTime();
- m_ttOldwatch = m_ttStopwatch - 1;
- }
-
-
-