home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / gui / CHTMLView.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  209.7 KB  |  7,141 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. //    CHTMLView.cp
  21. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  22.  
  23. #include "CHTMLView.h"
  24.  
  25.  
  26. #include "CStLayerOriginSetter.h"
  27.  
  28. #include <algorithm>
  29.  
  30. #include "CHTMLClickrecord.h"
  31. #include "CBrowserContext.h"
  32. #include "CBrowserWindow.h"
  33. #include "CURLDispatcher.h"
  34. #include "UFormElementFactory.h"
  35. #include "RandomFrontEndCrap.h"
  36. #include "CDrawable.h"
  37. #include "CMochaHacks.h" // this includes libevent.h
  38. #include "CHyperScroller.h"
  39. #include "UGraphicGizmos.h"
  40. #include "CContextMenuAttachment.h"
  41. #include "CSharedPatternWorld.h"
  42. #include "CApplicationEventAttachment.h"
  43. #include "CViewUtils.h"
  44. #include "CTargetFramer.h"
  45. #include "uapp.h"
  46.  
  47. #include "libimg.h"
  48. //#include "allxpstr.h" THE DATA DEFINITION MOVED TO StringLibPPC
  49. #include "xlate.h"
  50. #include "xp_rect.h"
  51. #include "xp_core.h"
  52.  
  53. #include "layers.h"
  54. #include "nppriv.h"
  55.  
  56. // FIX ME!!! this is only for SCROLLER_ID  remove in favor of xxx::class_ID
  57. #include "resgui.h" 
  58. #include "macgui.h"
  59. #include "mimages.h"
  60. #include "mplugin.h"
  61.  
  62. #if defined (JAVA)
  63. #include "mjava.h"
  64. #endif /* defined (JAVA) */
  65.  
  66. #include "mforms.h"
  67. #include "mkutils.h"
  68.  
  69. #include "libi18n.h"
  70.  
  71. #include "prefapi.h"
  72. #include "secnav.h"
  73.  
  74. extern "C" {
  75. #include "typedefs_md.h"
  76.  
  77. #if defined (JAVA)
  78. #include "native.h"
  79. #include "sun_awt_macos_MComponentPeer.h"
  80. #include "java_awt_Component.h"
  81. #include "interpreter.h"
  82. #include "exceptions.h"
  83. #include "prlog.h"
  84. #endif /* defined (JAVA) */
  85.  
  86. #undef __cplusplus
  87. #define IMPLEMENT_netscape_applet_MozillaAppletContext
  88. #include "n_applet_MozillaAppletContext.h"
  89. // #include "mdmacmem.h"
  90. #include "java.h"
  91. #include "jri.h"
  92. #include "lj.h"
  93. }
  94.  
  95. #if defined (JAVA)
  96. #include "MToolkit.h"
  97. #include "MFramePeer.h"
  98. #endif /* defined (JAVA) */
  99.  
  100. #include "mprint.h"                    // 97/01/24 jrm
  101. #include "ufilemgr.h"                // 96-12-16 deeje
  102. #include "uerrmgr.h"
  103. #include "CBookmarksAttachment.h"
  104. #include "Drag.h"
  105. #include "macutil.h"
  106. #include "UStdDialogs.h"
  107. #include "findw.h"
  108. #include "CPaneEnabler.h"
  109. #include "msgcom.h"    // for MSG_MailDocument
  110.  
  111. #include <UDrawingState.h>
  112. #include <UMemoryMgr.h>
  113. #include <Sound.h>
  114.  
  115. const Int16 FocusBox_Size        =    3;
  116.  
  117. const Int16 TableBorder_TintLevel    =    20000;
  118.  
  119. const ResIDT cPaulsMiscStrListID = 16010;
  120. const Int16 cSendPageIndex = 4;
  121. const Int16 cSendFrameIndex = 5;
  122.  
  123.     // Explicit Template instantiation for StValueChanger for LO_Element*
  124.  
  125. template <class T>
  126. StValueChanger<T>::StValueChanger(
  127.     T    &ioVariable,
  128.     T    inNewValue)
  129.         : mVariable(ioVariable),
  130.           mOrigValue(ioVariable)
  131. {
  132.     ioVariable = inNewValue;
  133. }
  134.  
  135.  
  136. template <class T>
  137. StValueChanger<T>::~StValueChanger()
  138. {
  139.     mVariable = mOrigValue;
  140. }
  141.  
  142. template class StValueChanger<LO_Element*>;
  143.  
  144. // Utility function for table borders
  145. Uint16 AddWithoutOverflow(Uint16 base, Uint16 addition);
  146. Uint16 SubWithoutUnderflow(Uint16 base, Uint16 difference);
  147. void ComputeBevelColor(Boolean inRaised, RGBColor inBaseColor, RGBColor& outBevelColor);
  148.  
  149. static void MochaFocusCallback(MWContext * pContext, LO_Element * lo_element, int32 lType, void * whatever, ETEventStatus status);
  150.  
  151. Boolean HasEventHandler(MWContext *context, uint32 events);
  152.  
  153. /* returns true if any of the events specified has a handler in the context and its parents. */
  154. Boolean HasEventHandler(MWContext *context, uint32 events)
  155. {
  156.     if (context == NULL) return false;
  157.     if (context->event_bit & events)
  158.         return true;
  159.     if (context->grid_parent)
  160.         return HasEventHandler(context->grid_parent, events);
  161.     return false;
  162. }
  163.  
  164. void SafeSetCursor(ResIDT    inCursorID)
  165. {
  166.     CursPtr        cursorPtr;
  167.     CursHandle    cursorHandle;
  168.  
  169.     cursorHandle = ::GetCursor(inCursorID);
  170.     if (cursorHandle != NULL) {
  171.         cursorPtr = *cursorHandle;
  172.     }
  173.     else {
  174.         cursorPtr = &UQDGlobals::GetQDGlobals()->arrow;
  175.     }
  176.     
  177.     ::SetCursor(cursorPtr);
  178. }
  179.  
  180. UInt32 CHTMLView::sLastFormKeyPressDispatchTime = 0; // to prevent infinite event dispatching loop
  181. Boolean CHTMLView::sCachedAlwaysLoadImages = false;
  182.  
  183. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  184. //    Ñ    
  185. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  186.         
  187. CHTMLView::CHTMLView(LStream* inStream)
  188.     :    LView(inStream)
  189.     ,    LDragAndDrop(GetMacPort(), this)
  190.     ,    mContext(nil)
  191.     ,    mSuperHTMLView(nil)
  192.     ,    mCompositor(nil)
  193.     , mPendingDocDimension_IsValid(false)
  194.     ,    mCurrentClickRecord(nil)
  195.     ,    mDragElement(nil)
  196.     ,    mPatternWorld(nil)
  197.     ,    mNeedToRepaginate(false)
  198.     ,    mDontAddGridEdgeToList(false)
  199.     ,    mLoadingURL(false)
  200.     ,    mStopEnablerHackExecuted(false)
  201.     ,    mInFocusCallAlready(false)
  202. {
  203.  
  204.     // FIX ME: Use C++.  I.e., use mem-initializers where possible (as above)
  205.     mNoBorder = false;
  206.     mCachedPort = NULL;
  207.     mDefaultScrollMode = LO_SCROLL_AUTO;
  208.     mScrollMode = mDefaultScrollMode;
  209.     mHasGridCells = false;
  210.     mShowFocus = false;
  211.     mElemBaseModel = NULL;
  212.     mBackgroundImage = NULL;
  213.     mEraseBackground = TRUE;
  214.     memset(&mBackgroundColor, 0xFF, sizeof(mBackgroundColor)); // white
  215.  
  216.     mCompositor = NULL;
  217.     mLayerClip = NULL;
  218.     ::SetEmptyRgn(mSaveLayerClip);
  219.  
  220.     mSendDataUPP = NewDragSendDataProc(LDropArea::HandleDragSendData);
  221.     Assert_(mSendDataUPP != NULL);
  222.     
  223. // FIX ME!!! the scroller dependency needs to be removed
  224.     mScroller = NULL;
  225.     
  226.     mTimerURLString = NULL;
  227.  
  228.     mOffscreenDrawable = NULL;
  229.     mOnscreenDrawable = NULL;
  230.     mCurrentDrawable = NULL;
  231.     mWaitMouseUp = false;
  232.     
  233.     mLayerOrigin.h = mLayerOrigin.v = 0;
  234.  
  235.     RegisterCallBackCalls();
  236.     
  237.     // Sets sCachedAlwaysLoadImages for the first time
  238.     PrefInvalidateCachedPreference("general.always_load_images", (void *)this);
  239. }
  240.  
  241. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  242. //    Ñ    
  243. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  244.  
  245. CHTMLView::~CHTMLView()
  246. {
  247.     if (!GetSuperHTMLView())
  248.     {
  249.         UnregisterCallBackCalls();
  250.     }
  251.     if (mPatternWorld)
  252.         mPatternWorld->RemoveUser(this);
  253.     
  254.     if (mSendDataUPP != NULL)
  255.         DisposeRoutineDescriptor(mSendDataUPP);
  256.  
  257.     if ( mOnscreenDrawable != NULL )
  258.         mOnscreenDrawable->SetParent ( NULL );
  259.  
  260.     SetContext(NULL);    
  261.     //CL_DestroyCompositor(mCompositor);
  262.     // brade:  check for NULL in case compositor wasn't created yet
  263.     if ( mCompositor )
  264.         mCompositor->RemoveUser(this);
  265. }
  266.  
  267. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  268. //    Ñ    
  269. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  270.  
  271. void CHTMLView::FinishCreateSelf(void)
  272. {
  273.     LView::FinishCreateSelf();
  274.  
  275.     mCachedPort = GetMacPort();
  276.     Assert_(mCachedPort != NULL);
  277.     
  278.     // ÑÑÑ Hack, how else do we do this though?
  279.     // Main view or the frames
  280.  
  281. // FIX ME!!! the scroller dependency need to be removed
  282. //    if ((mSuperView->GetPaneID() == SCROLLER_ID ) || (mSuperView->GetPaneID() == 1005))
  283. //        mScroller = (CHyperScroller*)mSuperView;
  284.     mScroller = dynamic_cast<CHyperScroller*>(mSuperView); // - jrm
  285.  
  286.     SDimension16 theFrameSize;
  287.     GetFrameSize(theFrameSize);
  288.         
  289.     /* create our onscreen drawable that will route drawable method calls from the compositor */
  290.     /* to this view */
  291.     mOnscreenDrawable = new CRouterDrawable();
  292.     if ( mOnscreenDrawable != NULL )
  293.         {
  294.         // send all onscreen drawable method calls this way
  295.         mOnscreenDrawable->SetParent ( this );
  296.  
  297.         CL_Drawable * theDrawable = CL_NewDrawable(theFrameSize.width, theFrameSize.height, CL_WINDOW,
  298.              &mfe_drawable_vtable, (void *) mOnscreenDrawable);
  299.          
  300.         if (theDrawable != NULL)
  301.             {
  302.             CL_Drawable* theOffscreen = NULL;
  303.             
  304.             // Create our offscreen drawable. If it fails for whatever reason, we don't really care
  305.             // as we'll just always be onscreen
  306.             mOffscreenDrawable = COffscreenDrawable::AllocateOffscreen();
  307.             if ( mOffscreenDrawable != NULL )
  308.                 {
  309.                 /* have the offscreen defer all layers calls to us */
  310.                 mOffscreenDrawable->SetParent ( this );
  311.                 
  312.                 theOffscreen = CL_NewDrawable(theFrameSize.width, theFrameSize.height, CL_BACKING_STORE,
  313.                     &mfe_drawable_vtable, (void *) mOffscreenDrawable);
  314.                 }
  315.         
  316.             // now create our compositor
  317.             CL_Compositor* c = CL_NewCompositor(theDrawable, theOffscreen, 0, 0, theFrameSize.width, theFrameSize.height, 10);
  318.             mCompositor = new CSharableCompositor(c);
  319.             mCompositor->AddUser(this); // shared by context and view.
  320.             }
  321.         }
  322.  
  323.     // set up background color and pattern
  324.     // This code is here so that we display default background when
  325.     // user has blank home page. - no, that's not the only reason.  PLEASE
  326.     // TRY TO REMEMBER THAT THIS CLASS IS USED FOR MAIL MESSAGES AND COMPOSER VIEWS!
  327.     // Ñ install the user's default solid background color & pattern
  328.     InstallBackgroundColor();
  329.     // now use installed background color to set window background color
  330.     SetWindowBackgroundColor();
  331. }
  332.  
  333. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  334. //    Ñ    
  335. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  336.  
  337. void CHTMLView::SetContext(
  338.     CBrowserContext*        inNewContext)
  339. {
  340.     // jrm - I added these bookend calls to disable the compositor - 97/02/15.
  341.     //            callbacks from timer were crashing!
  342.     if (!inNewContext && mCompositor)
  343.         CL_SetCompositorEnabled(*mCompositor, PR_FALSE);
  344.     if (mContext != NULL)
  345.         {
  346.         // mContext->SetCompositor(NULL);
  347.                 // ^^^^^^^^Do NOT do this.  If you do, layout will not be able
  348.                 // to clean up properly.  This is very bad.
  349.                 // The compositor needs to stick around till the context is deleted.
  350.                 // So the context shares the CSharableCompositor
  351.         mContext->RemoveUser(this);
  352.         // set pointer to this view in MWContext to NULL
  353.         mContext->ClearMWContextViewPtr();
  354.         }
  355.         
  356.     mContext = inNewContext;
  357.         
  358.     if (mContext != NULL)
  359.         {
  360.         // Set up the character set stuff
  361.         SetFontInfo();
  362.  
  363.         mContext->SetCurrentView(this);
  364.         mContext->SetCompositor(mCompositor); // context will share it.
  365.         mContext->AddListener(this);
  366.         mContext->AddUser(this);
  367.         }
  368.     if (inNewContext && mCompositor)
  369.         CL_SetCompositorEnabled(*mCompositor, PR_TRUE);
  370. }
  371.  
  372. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  373. //
  374. #pragma mark --- ACCESSORS ---
  375. //
  376. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  377.  
  378. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  379. //    Ñ    
  380. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  381.  
  382. Boolean CHTMLView::IsBorderless(void) const
  383. {
  384.     return (mNoBorder && !IsRootHTMLView());
  385. }
  386.  
  387. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  388. //    Ñ    
  389. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  390.  
  391. Boolean CHTMLView::IsRootHTMLView(void) const
  392. {
  393.     return (mSuperHTMLView == NULL);
  394. }
  395.  
  396. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  397. //    Ñ    
  398. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  399.  
  400. Boolean CHTMLView::IsFocusedFrame(void) const
  401. {
  402.     return (mShowFocus && !mHasGridCells && IsOnDuty());
  403. }
  404.  
  405. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  406. //    Ñ    
  407. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  408.  
  409. CHTMLView* CHTMLView::GetSuperHTMLView(void)
  410. {
  411.     return mSuperHTMLView;
  412. }
  413.  
  414. // ---------------------------------------------------------------------------
  415. //        Ñ BeTarget
  416. // ---------------------------------------------------------------------------
  417. /* since CHTMLView is an LTabGroup, its default behaviour would be to cycle
  418.    among its subpanes until it found the next one that wanted to be the target.
  419.    There can be situations, however, where none of our subpanes want to be
  420.    the target; a silly impasse.  Our BeTarget then mimics the behaviour of
  421.    LTabGroup::BeTarget, but is prepared to accept the focus itself if necessary.
  422.      An added wrinkle comes from the inability of certain of our subpanes
  423.    (CPluginView) to correctly preflight whether they will be able to accept
  424.    the target (in ProcessCommand).  When this happens, CPluginView tells its
  425.    supercommander (us) to be the target and a stack explosion results.
  426.    Thus the member variable, mTargeting, which detects recursive calls*/
  427.  
  428. /* Later note: BeTarget was gutted so that CHTMLView _could_ take the focus.
  429.    This solves problems that happen with simultaneous text selection in the
  430.    CHTMLView body and in a form edit field.  If you wish to reinstate BeTarget(),
  431.    you must declare a private class boolean called mTargeting, and initialize
  432.    it to false in the constructor.
  433. */
  434.  
  435. void
  436. CHTMLView::BeTarget() {
  437.  
  438. /*
  439.     // punt if one of our [bleep]ing subcommanders is trying to put the onus back on us
  440.     if (mTargeting)
  441.         return;
  442.     StValueChanger<Boolean>    targetMode (mTargeting, true);
  443.  
  444.     LCommander        *onDutySub = GetOnDutySub();
  445.     Int32            pos,        // index of the subcommander currently handed the torch
  446.                     subCount = mSubCommanders.GetCount();
  447.  
  448.     pos = subCount;
  449.     if (onDutySub)
  450.         pos = mSubCommanders.FetchIndexOf (&onDutySub);
  451.  
  452.     // find the next willing subcommander in rotation (a la LTabGroup::BeTarget)
  453.     if (pos > 0) {
  454.         Int32        startingPos = pos;
  455.         LCommander    *newTarget;
  456.  
  457.         do {
  458.             // increment and wrap
  459.             if (++pos > subCount)
  460.                 pos = 1;
  461.             mSubCommanders.FetchItemAt (pos, &newTarget);
  462.  
  463.             if (newTarget->ProcessCommand(msg_TabSelect)) {
  464.                 if (newTarget->IsTarget())
  465.                     break;
  466.             }
  467.         } while (pos != startingPos);
  468.     }
  469. */
  470.  
  471. }
  472.  
  473. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  474. //    Ñ    Shows the pane by scrolling to it
  475. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  476.  
  477. void CHTMLView::ShowView( LPane& pane )
  478. {
  479.     if (mScroller && mScroller->HasVerticalScrollbar())
  480.  
  481. // ÑÑÑ FIX ME. We really need to know which way do we want to scroll,
  482. // and then constrain it based on whether we have scrollbars
  483.     {
  484.         SPoint32 topLeft, botRight;
  485.         SDimension16 size;
  486.         pane.GetFrameLocation(topLeft);    // This is in window coordinates
  487.         pane.GetFrameSize(size);
  488.         topLeft.v -= mImageLocation.v;    // Adjust for our view's image position
  489.         topLeft.h -= mImageLocation.h;
  490.         botRight.h = topLeft.h + size.width;
  491.         botRight.v = topLeft.v + size.height;
  492.         RevealInImage(this, topLeft, botRight);
  493.     }
  494. }
  495.  
  496. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  497. //    Ñ    
  498. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  499.  
  500. void CHTMLView::SetRepaginate(Boolean inSetting)
  501. {
  502.     mNeedToRepaginate = inSetting;
  503. }
  504.  
  505. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  506. //    Ñ    
  507. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  508.  
  509. Boolean CHTMLView::GetRepaginate()
  510. {
  511.     return mNeedToRepaginate;
  512. }
  513.  
  514. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  515. //    Ñ    
  516. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  517.  
  518. void CHTMLView::SetSuperHTMLView(CHTMLView *inView)
  519. {
  520.     // If we have a SuperHTMLView then we don't want to be called back.
  521.     if (inView && !mSuperHTMLView)
  522.     {
  523.         UnregisterCallBackCalls();
  524.     }
  525.     else if (!inView && mSuperHTMLView)
  526.     {
  527.         RegisterCallBackCalls();
  528.     }
  529.     mSuperHTMLView = inView;
  530. }
  531.  
  532. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  533. //    Ñ    
  534. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  535.  
  536. void CHTMLView::SetFormElemBaseModel(LModelObject* inModel)
  537. {
  538.     mElemBaseModel = inModel;
  539. }
  540.  
  541. LModelObject* CHTMLView::GetFormElemBaseModel(void)
  542. {
  543.     LModelObject* theBase;
  544.  
  545.     if (mElemBaseModel != NULL)
  546.         theBase = mElemBaseModel;
  547.     else
  548.         theBase = LModelObject::GetDefaultModel();
  549.  
  550.     return theBase;
  551. }
  552.  
  553. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  554. //    Ñ Reset scroll mode to default (LO_SCROLL_AUTO). Use to transition from LO_SCROLL_NEVER.
  555. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  556. void CHTMLView::ResetScrollMode(Boolean inRefresh)
  557. {
  558.     mScrollMode = LO_SCROLL_YES;
  559.     SetScrollMode(mScrollMode, inRefresh);
  560.     mScrollMode = mDefaultScrollMode;
  561. }
  562.  
  563. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  564. //    Ñ Reset scroll mode to default (LO_SCROLL_AUTO). This really resets to
  565. //    default.
  566. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  567. // 97.12.19 pchen. Add method to *REALLY* reset scroll mode to default scroll mode.
  568. void CHTMLView::ResetToDefaultScrollMode()
  569. {
  570.     SetScrollMode(mDefaultScrollMode);
  571.     mScrollMode = mDefaultScrollMode;
  572. }
  573.  
  574. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  575. //    Ñ LO_SCROLL_NEVER disallows changing the scroll mode until ResetScrollMode() called.
  576. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  577.  
  578. void CHTMLView::SetScrollMode(
  579.     Int8                     inScrollMode,
  580.     Boolean                    inRefresh)
  581. {
  582.     if (mScrollMode != LO_SCROLL_NEVER) mScrollMode = inScrollMode;
  583.     if (mScroller != NULL)
  584.         {
  585.         if ((mScrollMode == LO_SCROLL_NEVER) || (mScrollMode == LO_SCROLL_NO) || (mScrollMode == LO_SCROLL_AUTO))
  586.             mScroller->ShowScrollbars(false, false);
  587.         else
  588.             mScroller->ShowScrollbars(true, true);
  589.  
  590.         // FIX ME!!! if this is never used, take it out
  591.         if ( inRefresh )
  592.             ;// ÑÑ FIX ME
  593.         }
  594. }
  595.  
  596. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  597. //    Ñ    
  598. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  599.  
  600. Boolean CHTMLView::GetScrollMode(void) const
  601. {
  602.     return mScrollMode;
  603. }
  604.  
  605. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  606. //    Ñ    
  607. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  608.  
  609. void CHTMLView::SpendTime(const EventRecord& /* inMacEvent */)
  610. {
  611. //    // Pagination
  612. //    if (fLastLedge != NO_LEDGE && fNextLedgeUpdate < TickCount())
  613. //        DoSetDocDimension( fLastLedge, fLastWidthDelta, fLastHeightDelta );
  614. //
  615.     // Refresh timer
  616.     if (mTimerURLString &&
  617.         (mTimerURLFireTime < LMGetTicks()) &&
  618.         IsEnabled() &&
  619.         ( XP_IsContextBusy(*mContext) == false) &&
  620.         CFrontApp::GetApplication() && CFrontApp::GetApplication()->HasProperlyStartedUp())
  621.     {
  622.         URL_Struct * request = NET_CreateURLStruct (mTimerURLString, NET_NORMAL_RELOAD);
  623.         ClearTimerURL();    // ...frees mTimerURLString, so must do this _after_ |NET_CreateURLStruct|.
  624.         if (request)
  625.         {
  626.             request->referer = XP_STRDUP( mContext->GetCurrentURL() );
  627.             mContext->SwitchLoadURL( request, FO_CACHE_AND_PRESENT );
  628.         }
  629.     }
  630. }
  631. #pragma mark --- I18N SUPPORT ---
  632.  
  633. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  634. //    Ñ    
  635. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  636.  
  637. Int16 CHTMLView::DefaultCSIDForNewWindow(void)
  638. {
  639.     Int16 csid = 0;
  640.     if (mContext)
  641.     {
  642.         csid = mContext->GetDocCSID();
  643.         if(0 == csid)
  644.             csid = mContext->GetDefaultCSID();
  645.     }
  646.     return csid;
  647. }
  648. Int16 CHTMLView::GetWinCSID(void) const
  649. {
  650.     if (mContext)
  651.         return mContext->GetWinCSID();
  652.     else
  653.         return 0;
  654. }
  655.  
  656. void CHTMLView::SetFontInfo()
  657. {
  658.      Boolean found;
  659.      found = CPrefs::GetFont( GetWinCSID(), &mCharSet );
  660. }
  661.   
  662. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  663. //
  664. #pragma mark --- NOTIFICATION RESPONSE ---
  665. //
  666. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  667.  
  668. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  669. //    Ñ Mocha submit callback
  670. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  671.  
  672. void MochaFormSubmitCallback(MWContext* pContext,
  673.                              LO_Element* lo_element,
  674.                              int32 lType,
  675.                              void* whatever,
  676.                              ETEventStatus status);
  677.  
  678. void MochaFormSubmitCallback(MWContext* pContext,
  679.                              LO_Element* lo_element,
  680.                              int32 /* lType */,
  681.                              void* /* whatever */,
  682.                              ETEventStatus status)
  683. {
  684.     if (status == EVENT_OK)
  685.     {
  686.         // Call the LO module to figure out the form's context
  687.         LO_FormSubmitData* submit = LO_SubmitForm(pContext, (LO_FormElementStruct*)lo_element);
  688.         if (submit == NULL)
  689.             return;
  690.         URL_Struct* url =  NET_CreateURLStruct((char *)submit->action, NET_DONT_RELOAD);
  691.         CBrowserContext* context = ExtractBrowserContext(pContext);
  692.         if (context)
  693.         {
  694.             History_entry* current = context->GetCurrentHistoryEntry();
  695.             if (current && current->address)
  696.                 url->referer = XP_STRDUP(current->address);
  697.             NET_AddLOSubmitDataToURLStruct(submit, url);
  698.             context->SwitchLoadURL(url, FO_CACHE_AND_PRESENT);
  699.         }
  700.         LO_FreeSubmitData(submit);
  701.     }
  702. }
  703.  
  704. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  705. //    Ñ Mocha image form submit callback
  706. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  707.  
  708. struct ImageFormSubmitData
  709. {
  710.     LO_ImageStruct*    lo_image;
  711.     int32            x;
  712.     int32            y;
  713. };
  714.  
  715. void MochaImageFormSubmitCallback(MWContext* pContext,
  716.                                   LO_Element* lo_element,
  717.                                   int32 lType,
  718.                                   void* whatever,
  719.                                   ETEventStatus status);
  720.  
  721. void MochaImageFormSubmitCallback(MWContext* pContext,
  722.                                   LO_Element* /* lo_element */,
  723.                                   int32 /* lType */,
  724.                                   void* whatever,
  725.                                   ETEventStatus status)
  726. {
  727.     if (status == EVENT_OK)
  728.     {
  729.         LO_FormSubmitData *theSubmit = NULL;
  730.         ImageFormSubmitData *data = reinterpret_cast<ImageFormSubmitData*>(whatever);
  731.         try
  732.             {
  733.             theSubmit = LO_SubmitImageForm(pContext, data->lo_image, data->x, data->y);
  734. //            ThrowIfNULL_(theSubmit);
  735.             
  736.             // 97-06-07 pkc -- NULL is a valid return value from LO_SubmitImageForm
  737.             if (theSubmit)
  738.                 {
  739.                 URL_Struct* theURL = NET_CreateURLStruct((char*)theSubmit->action, NET_DONT_RELOAD); 
  740.                 ThrowIfNULL_(theURL);
  741.                 
  742.                 CBrowserContext* theContext = ExtractBrowserContext(pContext);
  743.                 
  744.                 if (theContext)
  745.                     {
  746.                     cstring theCurrentURL = theContext->GetCurrentURL();
  747.                     if (theCurrentURL.length() > 0)
  748.                         theURL->referer = XP_STRDUP(theCurrentURL);
  749.  
  750.                     if (NET_AddLOSubmitDataToURLStruct(theSubmit, theURL))
  751.                         CURLDispatcher::DispatchURL(theURL, theContext, true);
  752.  
  753.                     LO_FreeSubmitData(theSubmit);
  754.                     }
  755.                 }
  756.             }
  757.         catch (...)
  758.             {
  759.             LO_FreeSubmitData(theSubmit);
  760.             throw;            
  761.             }
  762.     }
  763. }
  764.  
  765.  
  766. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  767. //    Ñ    
  768. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  769.  
  770. void CHTMLView::ListenToMessage(
  771.     MessageT                inMessage,
  772.     void*                    ioParam)
  773. {
  774.     switch (inMessage)
  775.         {
  776.         case msg_NSCFinishedLayout:
  777.             NoteFinishedLayout();
  778.             break;
  779.     
  780.         case msg_NSCAllConnectionsComplete:
  781.             NoteAllConnectionsComplete();
  782.             
  783.             /* update any commands which might change based on allConnectionsComplete */
  784.             LCommander::SetUpdateCommandStatus(true);
  785.             break;
  786.         
  787.         case msg_NSCPEmptyRepagination:
  788.             NoteEmptyRepagination();
  789.             break;    
  790.             
  791.         case msg_NSCPAboutToRepaginate:
  792.             NoteStartRepagination();
  793.             break;
  794.             
  795.         case msg_NSCConfirmLoadNewURL:
  796.             NoteConfirmLoadNewURL(*(Boolean*)ioParam);
  797.             break;
  798.         
  799.         case msg_NSCStartLoadURL:
  800.             NoteStartLoadURL();
  801.             break;
  802.             
  803.         case msg_NSCProgressMessageChanged:
  804.             // Update Panes to enable the stop button
  805.             if (!mStopEnablerHackExecuted &&
  806.                     mLoadingURL &&
  807.                     GetContext() == GetContext()->GetTopContext())
  808.             {
  809.                 CPaneEnabler::UpdatePanes();
  810.                 mStopEnablerHackExecuted = true;
  811.             }
  812.             break;            
  813.             
  814.         case msg_NSCGridContextPreDispose:
  815.             NoteGridContextPreDispose(*(Boolean*)ioParam);
  816.             break;
  817.             
  818.         case msg_NSCGridContextDisposed:
  819.             NoteGridContextDisposed();
  820.             break;
  821.  
  822.         // FORMS
  823.         case msg_SubmitButton:        // submission
  824.         case msg_SubmitText:
  825.         {
  826.             void * formID;
  827.  
  828.             StTempFormBlur    tempBlur;    // see mforms.h for an explanation
  829.  
  830.             if (inMessage == msg_SubmitButton)
  831.             {
  832.                 LPane* thePane = (LPane*)ioParam;
  833.                 
  834.                 LControl* theControl = dynamic_cast<LControl*>(thePane);
  835.                 ThrowIfNil_(theControl);
  836.                 
  837.                 formID = (void*) theControl->GetUserCon();
  838.             }
  839.             else
  840.                 formID = ((CFormLittleText*)ioParam)->GetLayoutForm();
  841.                 
  842. /*            if ( true ) // LM_SendOnSubmit(*mContext, (LO_Element*) formID)
  843.             {
  844.                 // Call the LO module to figure out the form's context
  845.                 submit = LO_SubmitForm(*mContext,( LO_FormElementStruct *)formID);
  846.                 if (submit == NULL)
  847.                     return;
  848.                 URL_Struct * url =  NET_CreateURLStruct((char *)submit->action, NET_DONT_RELOAD);
  849.                 History_entry* current = mContext->GetCurrentHistoryEntry();
  850.                 if (current && current->address)
  851.                     url->referer = XP_STRDUP(current->address);
  852.                 NET_AddLOSubmitDataToURLStruct(submit, url);
  853.                 mContext->SwitchLoadURL(url, FO_CACHE_AND_PRESENT);
  854.                 LO_FreeSubmitData(submit);
  855.             }
  856. */
  857.             // ET_SendEvent now takes a JSEvent struct instead of an int type
  858.             JSEvent* event = XP_NEW_ZAP(JSEvent);
  859.             if (event)
  860.             {
  861.                 event->type = EVENT_SUBMIT;
  862.                 // The code above will get executed in MochaFormSubmitCallback
  863.                 ET_SendEvent(*mContext,
  864.                              (LO_Element*)formID,
  865.                              event,
  866.                              MochaFormSubmitCallback,
  867.                              NULL);
  868.             }
  869.         }
  870.         break;
  871.         
  872.         case msg_ResetButton:        // Reset the form. ioParam is LStdButton
  873.             {
  874.                 LPane* thePane = (LPane*)ioParam;
  875.                 
  876.                 LControl* theControl = dynamic_cast<LControl*>(thePane);
  877.                 ThrowIfNil_(theControl);
  878.                 
  879.                 LO_ResetForm(*mContext, (LO_FormElementStruct*) theControl->GetUserCon());
  880.             }
  881.             
  882.             break;
  883.         case msg_ControlClicked:    // Click on the radio button. Change da others
  884.             {
  885.                 LPane* thePane = (LPane*)ioParam;
  886.                 
  887.                 LControl* theControl = dynamic_cast<LControl*>(thePane);
  888.                 ThrowIfNil_(theControl);
  889.                 
  890.                 LO_FormRadioSet(*mContext, (LO_FormElementStruct*) theControl->GetUserCon());
  891.             }
  892.             break;
  893.     }
  894. }
  895.  
  896. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  897. //    Ñ    
  898. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  899.  
  900. void CHTMLView::NoteFinishedLayout(void)
  901. {
  902.     FlushPendingDocResize();
  903.  
  904.         /*
  905.             Ugly hack: since `asynchronous' layout might have slightly overwritten the
  906.             scrollbars, get just the scrollbars to redraw.
  907.         */
  908.  
  909.     if ( mScroller )
  910.         mScroller->RefreshSelf();
  911. }
  912.  
  913. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  914. //    Ñ    
  915. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  916.  
  917. void CHTMLView::NoteAllConnectionsComplete(void)
  918. {
  919. //    StopRepeating();
  920.  
  921.         // Look to see if my context, or any context enclosing my context, needs to be repaginated.
  922.     CBrowserContext* contextToRepaginate = 0;
  923.     if ( mContext )
  924.         for ( MWContext* ctx = *mContext; ctx; ctx = ctx->grid_parent )
  925.             {
  926.                 CBrowserContext* browserContext = ExtractBrowserContext(ctx);
  927.                 if ( browserContext && browserContext->IsRepagintaitonPending() )
  928.                     contextToRepaginate = browserContext;
  929.             }
  930.  
  931.         /*
  932.             Try to repaginate the most enclosing context that needs it.  If some busy child
  933.             stops the repagination, no big deal... that childs |NoteAllConnectionsComplete|
  934.             will try again.
  935.         */
  936.  
  937.     if ( contextToRepaginate )
  938.         contextToRepaginate->Repaginate();
  939.     else
  940.         ClearDeferredImageQueue();
  941.  
  942.     //Enable();
  943.     CPaneEnabler::UpdatePanes();
  944.     
  945.     mLoadingURL = false;
  946. }
  947.  
  948. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  949. //    Ñ    
  950. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  951.  
  952. void CHTMLView::NoteStartRepagination(void)
  953. {
  954.     SPoint32 theScrollPosition;
  955.     GetScrollPosition(theScrollPosition);
  956.     mContext->RememberHistoryPosition(theScrollPosition.h, theScrollPosition.v);
  957.     
  958. // FIX ME!!! may want to reset the size flush timer here
  959. }
  960.  
  961. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  962. //    Ñ    
  963. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  964.  
  965. void CHTMLView::NoteEmptyRepagination(void)
  966. {
  967.     // Adjust scroll bars
  968.     
  969.     AdjustScrollBars();    
  970. }
  971.  
  972. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  973. //    Ñ    
  974. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  975.  
  976. void CHTMLView::NoteConfirmLoadNewURL(Boolean& ioCanLoad)
  977. {
  978. //    if ( HasDownloads( *mContext ) )
  979. //        if (!ErrorManager::PlainConfirm((const char*) GetCString( ABORT_CURR_DOWNLOAD ), nil, nil, nil ))
  980. //            return;
  981.  
  982.     ioCanLoad = true;
  983. }
  984.  
  985. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  986. //    Ñ    
  987. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  988.  
  989. void CHTMLView::NoteStartLoadURL(void)
  990. {
  991.     //Disable();
  992. // FIX ME!!! we should disable the view.  it will be enabled through all connection complete
  993.  
  994.     ClearTimerURL();    // jrm 97/08/22
  995.  
  996.     SPoint32 theScrollPosition;
  997.     GetScrollPosition(theScrollPosition);
  998.     mContext->RememberHistoryPosition(theScrollPosition.h, theScrollPosition.v);
  999.     mLoadingURL = true;
  1000.     mStopEnablerHackExecuted = false;
  1001. }
  1002.  
  1003. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1004. //    Ñ    
  1005. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1006.  
  1007. void CHTMLView::NoteGridContextPreDispose(Boolean inSavingHistory)
  1008. {
  1009.     if (inSavingHistory)
  1010.         {
  1011.         SPoint32 theScrollPosition;
  1012.         GetScrollPosition(theScrollPosition);
  1013.         mContext->RememberHistoryPosition(theScrollPosition.h, theScrollPosition.v);
  1014.         }
  1015.         
  1016.     // our grid context is going to be orphaned by it's super context
  1017.     // which is our clue that we aren't supposed to be here anymore.
  1018.     // Deleting outself releases our shared interest in the context.
  1019.     //
  1020.     // FIX ME!!! This needs to change.  The assumption here is that the
  1021.     // superview of the HTML view is a scroller and was created at the
  1022.     // same time as this.  This will need to go away when the scroller
  1023.     // dependency is removed.
  1024.     delete mSuperView;
  1025. }
  1026.  
  1027. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1028. //    Ñ    
  1029. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1030.  
  1031. void CHTMLView::NoteGridContextDisposed(void)
  1032. {
  1033.     if (mContext->CountGridChildren() == 0)
  1034.         SetScrollMode(mDefaultScrollMode, true);
  1035. }
  1036.  
  1037. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1038. //    Ñ    
  1039. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1040.  
  1041. // replaces the old fCanLoad Member
  1042. void CHTMLView::EnableSelf(void)
  1043. {
  1044.     // for the click code
  1045.     mOldPoint.h = mOldPoint.v = -1;
  1046. }
  1047.  
  1048. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1049. //    Ñ    
  1050. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1051.  
  1052. void CHTMLView::DisableSelf(void)
  1053. {
  1054.     mOldPoint.h = mOldPoint.v = -1;
  1055. }
  1056.  
  1057.  
  1058. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1059. //
  1060. #pragma mark --- DRAWING AND UPDATING ---
  1061. //
  1062. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1063.  
  1064. void CHTMLView::ResetBackgroundColor() const
  1065. {
  1066.     UGraphics::SetIfBkColor(mBackgroundColor);
  1067. }
  1068.  
  1069. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1070. //    Ñ    ContextMenuPopupsEnabled
  1071. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1072. // determine whether context-sensitive popup menus are enabled by querying
  1073. // the parent browser window
  1074.  
  1075. Boolean CHTMLView::ContextMenuPopupsEnabled (void)
  1076. {
  1077.     CBrowserWindow    *browserWindow = dynamic_cast<CBrowserWindow *>(CViewUtils::GetTopMostSuperView (this));
  1078.     // 8-13-97 context menus disabled when commands are disabled unless the control key is down.
  1079.     // this is mac specific and may go away when we have an xp way to disable context menus from javascript.
  1080.     return browserWindow ? browserWindow->AllowSubviewPopups() && !browserWindow->IsHTMLHelp() && (!browserWindow->CommandsAreDisabled() || CApplicationEventAttachment::CurrentEventHasModifiers(controlKey)) : true;
  1081. }
  1082.  
  1083. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1084. //    Ñ    GetCurrentPort
  1085. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1086.  
  1087. CGrafPtr CHTMLView::GetCurrentPort(Point& outPortOrigin)
  1088. {
  1089.     if ((mCurrentDrawable == NULL) || (mCurrentDrawable == mOnscreenDrawable)) {
  1090.         outPortOrigin = mPortOrigin;
  1091.         return (CGrafPtr) GetMacPort();
  1092.     }
  1093.     else {
  1094.         outPortOrigin.h = outPortOrigin.v = 0;
  1095.         return mCurrentDrawable->GetDrawableOffscreen();
  1096.     }
  1097. }
  1098.  
  1099. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1100. //    Ñ    FocusDraw
  1101. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1102.  
  1103. Boolean CHTMLView::FocusDraw(LPane* /*inSubPane*/)
  1104. {
  1105.     Boolean bFocused = true;
  1106.     GWorldPtr gworld = NULL;
  1107.  
  1108.     // I don't really want to write my own FocusDraw, but PowerPlant has this nasty
  1109.     // habit of setting the origin and clip on me...
  1110.     bFocused = (mRevealedRect.left < mRevealedRect.right);
  1111.     
  1112.     // Skip if already in focus
  1113.     if (this != sInFocusView)
  1114.         {
  1115.         // Always set PowerPlant's origin and clip for the onscreen port.
  1116.         if (LView::EstablishPort())
  1117.             {
  1118.             // Set up local coordinate system
  1119.             ::SetOrigin(mPortOrigin.h, mPortOrigin.v);
  1120.         
  1121.             // Clip to revealed area of View
  1122.             Rect clippingRect = mRevealedRect;
  1123.             
  1124.             PortToLocalPoint( topLeft(clippingRect) );
  1125.             PortToLocalPoint( botRight(clippingRect) );
  1126.             
  1127.             // if we're focussed then we need to do some extra stuff
  1128.             if ( bFocused && IsFocusedFrame() )
  1129.                 {
  1130.                 ::InsetRect( &clippingRect, FocusBox_Size, FocusBox_Size );
  1131.                 }
  1132.  
  1133.             ::ClipRect( &clippingRect );
  1134.             }
  1135.             
  1136.         
  1137.         // Set our current Mac Port    - could be either onscreen or offscreen
  1138.         if (EstablishPort())
  1139.             {
  1140.             // If the current drawable is not us, don't screw with the origin and clip.
  1141.             // The drawable is set to nil during normal operation so that's assumed to
  1142.             // also be us.
  1143.             if ( ( mCurrentDrawable != NULL ) && ( mCurrentDrawable != mOnscreenDrawable ) )
  1144.                 {
  1145.                 // offscreen
  1146.                 Rect theFrame;
  1147.                 CalcLocalFrameRect(theFrame);
  1148.  
  1149.                 ::SetOrigin(theFrame.left, theFrame.top);
  1150.                 }
  1151.             
  1152.             // Cache current Focus
  1153.             sInFocusView = this;
  1154.             
  1155.             // be sure to reset the background color
  1156.             if ( bFocused && ( mRevealedRect.left < mRevealedRect.right ) )
  1157.                 {
  1158.                 ResetBackgroundColor();
  1159.                 }
  1160.             }
  1161.         else
  1162.             {
  1163.             SignalPStr_("\pFocus View with no GrafPort");
  1164.             }
  1165.         }
  1166.     
  1167.     // if we have a current drawable, then we need to do magic with the clip
  1168.     if ( mCurrentDrawable != NULL )
  1169.         {            
  1170.         if ( mCurrentDrawable->HasClipChanged() )
  1171.             {
  1172.             RgnHandle clip;
  1173.             
  1174.             //
  1175.             // Warning: If the drawable is our offscreen, then we need to make sure
  1176.             // to move the clip into the correct coordinate space. The problem here is that
  1177.             // the drawable has no way of knowing what its coordinate space is. To make 
  1178.             // matters worse, Drawables are shared across multiple HTMLViews.
  1179.             //
  1180.             // We could simplify this by keeping one back buffer for the browser as a whole
  1181.             // and then instantiating a COffscreenDrawable per CHTMLView. That way the HTMLView
  1182.             // could notify the offscreen whenever it's origin changes. It could then offset
  1183.             // its clip correctly whenever a new one is set.
  1184.             clip = (RgnHandle) mCurrentDrawable->GetLayerClip();
  1185.             if ( mCurrentDrawable == mOffscreenDrawable )
  1186.                 {
  1187.                 Rect theFrame;
  1188.                 
  1189.                 CalcLocalFrameRect(theFrame);
  1190.                 
  1191.                 ::OffsetRgn ( clip, theFrame.left, theFrame.top );
  1192.                 ::SetClip ( clip );
  1193.                 ::OffsetRgn ( clip, -theFrame.left, -theFrame.top );
  1194.                 }
  1195.             else
  1196.                 {
  1197.                 ::SetClip ( clip );
  1198.                 }
  1199.             }
  1200.         }
  1201.     
  1202.     return bFocused;
  1203. }
  1204.  
  1205.  
  1206. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1207. //    Ñ    EstablishPort
  1208. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1209. Boolean
  1210. CHTMLView::EstablishPort()
  1211. {
  1212.     Boolean portSet = false;
  1213.     GWorldPtr gworld = NULL;
  1214.     
  1215.     // if the current drawable, is an offscreen one, be sure to set it
  1216.     if ( mCurrentDrawable != NULL )
  1217.         {
  1218.         gworld = mCurrentDrawable->GetDrawableOffscreen();
  1219.         }
  1220.     
  1221.     if ( gworld != NULL )
  1222.         {
  1223.         portSet = true;
  1224.         if ( UQDGlobals::GetCurrentPort() != (GrafPtr) mGWorld )
  1225.             {
  1226.             SetGWorld ( gworld, NULL );
  1227.             mOffscreenDrawable->mClipChanged = true;
  1228.             }
  1229.         }
  1230.     else
  1231.         {
  1232.         // make sure to restore the main device
  1233.         SetGDevice ( GetMainDevice() );
  1234.         portSet = LView::EstablishPort();
  1235.         }
  1236.             
  1237.     return portSet;
  1238. }
  1239.  
  1240. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1241. //    Ñ    DrawSelf
  1242. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1243.  
  1244. void CHTMLView::DrawSelf(void)
  1245. {
  1246.     if (Memory_MemoryIsLow() || !mContext)
  1247.         return;
  1248.         // A CHTMLView can have a nil mContext, but if it does, it doesn't draw.
  1249.     
  1250.     // update the image display context if we need to. it would be nice to reload the images
  1251.     // on the current page, but we cuurently cannot doing so without other side effects
  1252.     // such as losing form data...
  1253.     VerifyDisplayContextColorSpace ( *mContext );
  1254.     
  1255. // this is the new (layered) drawing.  It flashes WAY to much.
  1256. // FIX ME!!! clean up
  1257.  
  1258.     if (GetRepaginate())
  1259.     {
  1260.         GetContext()->Repaginate(NET_CACHE_ONLY_RELOAD);
  1261.         SetRepaginate(false);
  1262.     }
  1263.  
  1264.     // For layers all drawing is done through the compositor 
  1265.     // BUGBUG LAYERS The assumption here is that the cutout region
  1266.     // (including plugins) will be removed from the composited
  1267.     // area...this still needs to be done.
  1268.  
  1269. //    if ( sNoTextUpdateLock )
  1270. //        return;
  1271.         
  1272.     // Get the update region
  1273.     StRegion theImageUpdateRgn(mUpdateRgnH);
  1274.     
  1275.     if (!mContext || !mContext->GetCurrentHistoryEntry())
  1276.     {
  1277.         ClearBackground();
  1278.     }
  1279.     else
  1280.     {
  1281.         /* Convert to frame coordinates */
  1282.         SPoint32 theFrameLocation;
  1283.         GetFrameLocation(theFrameLocation);
  1284.         ::OffsetRgn(theImageUpdateRgn, -theFrameLocation.h, -theFrameLocation.v);
  1285.  
  1286.         if (mCompositor && CL_GetCompositorEnabled(*mCompositor))
  1287.             CL_RefreshWindowRegion(*mCompositor, (FE_Region)static_cast<RgnHandle>(theImageUpdateRgn));
  1288.         else
  1289.             DrawBackground((*static_cast<RgnHandle>(theImageUpdateRgn))->rgnBBox);    
  1290.  
  1291.         // 07-06-11 pkc -- Update grid edges only if mContext isn't busy which means that
  1292.         // layout isn't running, i.e. calling FE_DisplayEdge directly
  1293.         /* 18.Jun.97 drm -- removed the check so we update grid edges even when layout
  1294.            is already doing that.  While layout is creating a new page, the last redraw
  1295.            that goes through tends to happen while the context is busy.  This check
  1296.            causes frame edges to not be redrawn, which leaves a bevel line from the
  1297.            enclosing CBevelView running across the end of the frame edge.
  1298.         */
  1299. //        if (!XP_IsContextBusy(*mContext))
  1300.             DrawGridEdges(theImageUpdateRgn);    
  1301.     }
  1302.     
  1303.     if (IsFocusedFrame())
  1304.         DrawFrameFocus();
  1305.     ExecuteAttachments(CTargetFramer::msg_DrawSelfDone, this);
  1306.     
  1307.  
  1308. /* this is the old drawing code
  1309.     mCalcDontDraw = false;
  1310.     
  1311.     Rect theFrame;
  1312.     CalcLocalFrameRect(theFrame);
  1313.     RgnHandle theLocalUpdateRgn = GetLocalUpdateRgn();
  1314.  
  1315.     Rect theLocalUpdateFrame = (*theLocalUpdateRgn)->rgnBBox;
  1316.     ::SectRect(&theFrame, &theLocalUpdateFrame, &theLocalUpdateFrame);
  1317.  
  1318.     if (!mHasGridCells)
  1319.         DrawBackground(theLocalUpdateFrame);
  1320.  
  1321.     SPoint32         itl, ibr;
  1322.     Point            tl, br;
  1323.     tl = topLeft( theLocalUpdateFrame );
  1324.     br = botRight( theLocalUpdateFrame );
  1325.     LocalToImagePoint( tl, itl );
  1326.     LocalToImagePoint( br, ibr );
  1327.     
  1328.     LO_RefreshArea(*mContext, itl.h, itl.v, ibr.h - itl.h, ibr.v - itl.v );
  1329.  
  1330.     if (IsFocusedFrame())
  1331.         DrawFrameFocus();
  1332.  
  1333.     ::DisposeRgn(theLocalUpdateRgn);
  1334.     mCalcDontDraw = true;
  1335. */
  1336. }
  1337.  
  1338. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1339. //    Ñ    DrawFrameFocus
  1340. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1341.  
  1342. void CHTMLView::DrawFrameFocus(void)
  1343. {
  1344.     StRegion theFocusMask;
  1345.     CalcFrameFocusMask(theFocusMask);
  1346.     
  1347.     Point    theLocalOffset = { 0, 0 };
  1348.     PortToLocalPoint(theLocalOffset);
  1349.     ::OffsetRgn(theFocusMask, theLocalOffset.h, theLocalOffset.v);
  1350.  
  1351.     StClipRgnState theClipSaver(theFocusMask);
  1352.     StColorPenState    savePen;
  1353.  
  1354.     ::PenPat(&UQDGlobals::GetQDGlobals()->black);
  1355.     ::PenMode(srcCopy);
  1356.  
  1357.     RGBColor theHiliteColor;
  1358.     LMGetHiliteRGB(&theHiliteColor);
  1359.     ::RGBForeColor(&theHiliteColor);
  1360.  
  1361.     ::PaintRgn(theFocusMask);
  1362. }
  1363.  
  1364. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1365. //    Ñ    CalcFrameFocusMask
  1366. //
  1367. //    This region is in port coordinates
  1368. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1369.  
  1370. void CHTMLView::CalcFrameFocusMask(RgnHandle outFocusMask)
  1371. {
  1372.     ::SetEmptyRgn(outFocusMask);
  1373.  
  1374.     Rect theFrame;
  1375.     CalcPortFrameRect(theFrame);
  1376.     ::SectRect(&theFrame, &mRevealedRect, &theFrame);
  1377.  
  1378.     ::RectRgn(outFocusMask, &theFrame);
  1379.     StRegion theSubFocus(theFrame);
  1380.     
  1381.     ::InsetRgn(theSubFocus, FocusBox_Size, FocusBox_Size);
  1382.     ::DiffRgn(outFocusMask, theSubFocus, outFocusMask);
  1383. }
  1384.  
  1385. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1386. //    Ñ    InvalFocusArea
  1387. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1388.  
  1389. void CHTMLView::InvalFocusArea(void)
  1390. {
  1391.     if (mShowFocus)
  1392.         {
  1393.         StRegion theFocusMask;
  1394.         CalcFrameFocusMask(theFocusMask);
  1395.         InvalPortRgn(theFocusMask);
  1396.         }
  1397. }
  1398.  
  1399. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1400. //    Ñ    AdjustScrollBars
  1401. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1402.  
  1403. // FIX ME!!! this needs to be removed when the mScroller is removed
  1404. void CHTMLView::AdjustScrollBars()
  1405. {
  1406.     if ((mScroller == NULL) || (GetScrollMode() != LO_SCROLL_AUTO))
  1407.         return;
  1408.  
  1409.     mScroller->AdjustScrollBars();
  1410.  
  1411. /*
  1412.     SDimension16 theFrameSize;
  1413.     GetFrameSize(theFrameSize);
  1414.     
  1415.     SDimension32 theImageSize;
  1416.     GetImageSize(theImageSize);
  1417.     
  1418.     // If we are only showing scrollers when needed, turn them on if we have overgrown
  1419.  
  1420.     mScroller->ShowScrollbars(
  1421.                                 theImageSize.width  > theFrameSize.width,
  1422.                                 theImageSize.height > theFrameSize.height);
  1423. */
  1424. }
  1425.  
  1426. void
  1427. CHTMLView::RegisterCallBackCalls()
  1428. {
  1429.     PREF_RegisterCallback("intl", PrefUpdateCallback, (void *)this);
  1430.     // At some point we should decide if it makes more sense to register a single
  1431.     // "browser" call back.
  1432.     PREF_RegisterCallback(    "browser.underline_anchors",
  1433.                             PrefUpdateCallback, (void *)this);
  1434.     PREF_RegisterCallback(    "browser.background_color",
  1435.                                 PrefUpdateCallback, (void *)this);
  1436.     PREF_RegisterCallback(    "browser.use_document_fonts",
  1437.                                 PrefUpdateCallback, (void *)this);
  1438.     PREF_RegisterCallback(    "browser.foreground_color",
  1439.                                 PrefUpdateCallback, (void *)this);
  1440.     PREF_RegisterCallback(    "browser.anchor_color",
  1441.                                 PrefUpdateCallback, (void *)this);
  1442.     PREF_RegisterCallback(    "browser.visited_color",
  1443.                                 PrefUpdateCallback, (void *)this);
  1444.     PREF_RegisterCallback(    "browser.use_document_colors",
  1445.                                 PrefUpdateCallback, (void *)this);
  1446.     PREF_RegisterCallback(    "general.always_load_images",
  1447.                                 PrefInvalidateCachedPreference, (void *)this);
  1448. }
  1449.  
  1450. void
  1451. CHTMLView::UnregisterCallBackCalls()
  1452. {
  1453.     PREF_UnregisterCallback("intl", PrefUpdateCallback, (void *)this);
  1454.     PREF_UnregisterCallback(    "browser.underline_anchors",
  1455.                                 PrefUpdateCallback, (void *)this);
  1456.     PREF_UnregisterCallback(    "browser.background_color",
  1457.                                 PrefUpdateCallback, (void *)this);
  1458.     PREF_UnregisterCallback(    "browser.use_document_fonts",
  1459.                                 PrefUpdateCallback, (void *)this);
  1460.     PREF_UnregisterCallback(    "browser.foreground_color",
  1461.                                 PrefUpdateCallback, (void *)this);
  1462.     PREF_UnregisterCallback(    "browser.anchor_color",
  1463.                                 PrefUpdateCallback, (void *)this);
  1464.     PREF_UnregisterCallback(    "browser.visited_color",
  1465.                                 PrefUpdateCallback, (void *)this);
  1466.     PREF_UnregisterCallback(    "browser.use_document_colors",
  1467.                                 PrefUpdateCallback, (void *)this);
  1468.     PREF_UnregisterCallback(    "general.always_load_images",
  1469.                                 PrefInvalidateCachedPreference, (void *)this);                                                
  1470. }
  1471.  
  1472. int
  1473. CHTMLView::PrefUpdateCallback(const char * /*inPrefString */, void *inCHTMLView)
  1474. {
  1475.     CHTMLView    *theView = (CHTMLView *)inCHTMLView;
  1476.     theView = dynamic_cast<CHTMLView*>(theView);
  1477.     XP_ASSERT(theView);
  1478.     XP_ASSERT(!theView->GetSuperHTMLView());
  1479.     if (theView &&
  1480.         !theView->GetRepaginate() &&    // No need to do it again if we have been here before.
  1481.         theView->IsRootHTMLView())
  1482.     {
  1483.         theView->SetRepaginate(true);
  1484.         Rect    paneRect;
  1485.         theView->CalcPortFrameRect(paneRect);
  1486.         theView->InvalPortRect(&paneRect);
  1487.     }
  1488.     return 0;    // You don't even want to know my opinion of this!
  1489. }
  1490.  
  1491. int
  1492. CHTMLView::PrefInvalidateCachedPreference(const char *inPrefString, void * /*inCHTMLView */)
  1493. {
  1494.     int    returnValue = 0;
  1495.      
  1496.     if (!XP_STRCMP(inPrefString, "general.always_load_images")) {
  1497.         XP_Bool    prefValue;
  1498.         returnValue = PREF_GetBoolPref(inPrefString, &prefValue);
  1499.         if (returnValue != PREF_OK && returnValue != PREF_NOERROR)
  1500.             sCachedAlwaysLoadImages = true;
  1501.         else
  1502.             sCachedAlwaysLoadImages = (Boolean)prefValue;
  1503.     }
  1504.     
  1505.     return returnValue;
  1506. }
  1507.  
  1508. // 97-06-11 pkc -- Code to handle redrawing grid edges
  1509. void CHTMLView::DrawGridEdges(RgnHandle inRgnHandle)
  1510. {
  1511.     // quick check -- if mGridEdgeList is empty, no grid edges to draw
  1512.     if(!mGridEdgeList.empty())
  1513.     {
  1514.         // set mDontAddGridEdgeToList to true so that that DisplayEdge does not
  1515.         // to add this LO_EdgeStruct* to mGridEdgeList
  1516.         mDontAddGridEdgeToList = true;
  1517.         // Check each grid edge to see if it intersects the update region
  1518.         vector<LO_EdgeStruct*>::iterator iter = mGridEdgeList.begin();
  1519.         while (iter != mGridEdgeList.end())
  1520.         {
  1521.             LO_EdgeStruct* edge = *iter;
  1522.             Rect edgeFrame;
  1523.             if (CalcElementPosition((LO_Element*)edge, edgeFrame))
  1524.             {
  1525.                 // grid edge is visible
  1526.                 if(::RectInRgn(&edgeFrame, inRgnHandle))
  1527.                 {
  1528.                     // grid edge is in update region, draw it
  1529.                     DisplayEdge(NULL, edge);
  1530.                 }
  1531.             }
  1532.             ++iter;
  1533.         }
  1534.         // set mDontAddGridEdgeToList to false
  1535.         mDontAddGridEdgeToList = false;
  1536.     }
  1537. }
  1538.  
  1539. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1540. //
  1541. #pragma mark --- LAYER DISPATCH ---
  1542. //
  1543. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1544.  
  1545. void CHTMLView::SetLayerOrigin(
  1546.     Int32                     inX,
  1547.     Int32                     inY)
  1548. {
  1549.     mLayerOrigin.h = inX;
  1550.     mLayerOrigin.v = inY;
  1551. }
  1552.     
  1553. void CHTMLView::GetLayerOrigin(
  1554.     Int32*                    outX,
  1555.     Int32*                    outY)
  1556. {
  1557.     /*
  1558.      * certain things like images get the current layer origin from the current hyperview.
  1559.      * If they can learn how to get this from the current drawable (through the doc context
  1560.      * then this hack can go away
  1561.      */
  1562.     if ( mCurrentDrawable != NULL && mCurrentDrawable != mOnscreenDrawable )
  1563.         {
  1564.         mCurrentDrawable->GetLayerOrigin ( outX, outY );
  1565.         }
  1566.     else
  1567.         {
  1568.         *outX = mLayerOrigin.h;
  1569.         *outY = mLayerOrigin.v;
  1570.         }
  1571. }
  1572.     
  1573. void CHTMLView::SetLayerClip(
  1574.     FE_Region                 inRegion)
  1575. {
  1576.  
  1577.     // do we need to restore a magic region?
  1578.     if ( inRegion == NULL )
  1579.         {
  1580.         mLayerClip = NULL;
  1581.         
  1582.         if (!::EmptyRgn(mSaveLayerClip))
  1583.             {
  1584.             mClipChanged = true;
  1585.             ::CopyRgn ( mSaveLayerClip, mClipRgn );
  1586.             ::SetEmptyRgn(mSaveLayerClip);
  1587.             }
  1588.         }
  1589.     else
  1590.         {
  1591.         Point portOrigin, scrollOffset;
  1592.         SPoint32 frameLocation;
  1593.  
  1594.         // do we need to save a magic region?
  1595.         if ( mLayerClip == NULL )
  1596.             {
  1597.             ::GetClip(mSaveLayerClip);
  1598.             mLayerClip = FE_GetMDRegion(inRegion);
  1599.             }
  1600.         
  1601.         // now, copy this region to our own copy and move it to the correct coordinate
  1602.         // space
  1603.         CopyRgn ( FE_GetMDRegion(inRegion), mClipRgn );
  1604.     
  1605.         // The region passed in is in frame coordinates. To use it,
  1606.         // we need to convert it to local coordinates. The scrollOffset
  1607.         // represents how much we need to offset the region for this 
  1608.         // transformation.
  1609.         GetPortOrigin(portOrigin);
  1610.         GetFrameLocation(frameLocation);
  1611.         
  1612.         scrollOffset.h = portOrigin.h + frameLocation.h;
  1613.         scrollOffset.v = portOrigin.v + frameLocation.v;
  1614.             
  1615.         ::OffsetRgn(mClipRgn, scrollOffset.h, scrollOffset.v);
  1616.         
  1617.         mClipChanged = true;
  1618.         }
  1619.  
  1620.     // because we're lame and don't know how to test if the current
  1621.     // port is us, we save the port, and then focus ourselves. since
  1622.     // we marked the clip as having changed, it will always be set
  1623.     // How can I tell if I'm the current port?
  1624.  
  1625.     GDHandle saveGD;
  1626.     CGrafPtr savePort;
  1627.     
  1628.     GetGWorld ( &savePort, &saveGD );
  1629.  
  1630.     FocusDraw();
  1631.     
  1632.     SetGWorld ( savePort, saveGD );
  1633. }
  1634.  
  1635. void CHTMLView::CopyPixels(
  1636.     CDrawable*                inSrcDrawable,
  1637.     FE_Region                inCopyRgn)
  1638. {
  1639.     GWorldPtr        srcGWorld;
  1640.     
  1641.     FocusDraw();
  1642.  
  1643.     srcGWorld = inSrcDrawable->GetDrawableOffscreen();
  1644.     if ( srcGWorld != NULL )
  1645.         {
  1646.         Rect srcRect;
  1647.         Rect dstRect;
  1648.         
  1649.         GDHandle gdh;
  1650.         CGrafPtr port;
  1651.         
  1652.         GetGWorld ( &port, &gdh );
  1653.         SetGWorld ( srcGWorld, NULL );
  1654.         
  1655.         SetOrigin ( 0, 0 );
  1656.         
  1657.         SetGWorld ( port, gdh );
  1658.         
  1659.         StColorPenState save;
  1660.         
  1661.         StColorPenState::Normalize();
  1662.         
  1663.         /* we use the bounding rectangle for the copy rgn as the src/dst rect */
  1664.         /* for the copy. however, we need to make sure that the onscreen rect is */
  1665.         /* in the correct coordinate space */
  1666.         srcRect = (*(RgnHandle) inCopyRgn)->rgnBBox;
  1667.         dstRect = srcRect;
  1668.                 
  1669.         Point portOrigin, scrollOffset;
  1670.         SPoint32 frameLocation;
  1671.         
  1672.         // The region passed in is in frame coordinates. To use it,
  1673.         // we need to convert it to local coordinates. The scrollOffset
  1674.         // represents how much we need to offset the region for this 
  1675.         // transformation.
  1676.         GetPortOrigin(portOrigin);
  1677.         GetFrameLocation(frameLocation);
  1678.         
  1679.         scrollOffset.h = portOrigin.h + frameLocation.h;
  1680.         scrollOffset.v = portOrigin.v + frameLocation.v;
  1681.                 
  1682.         ::OffsetRgn(FE_GetMDRegion(inCopyRgn), scrollOffset.h, scrollOffset.v );
  1683.         ::OffsetRect ( &dstRect, scrollOffset.h, scrollOffset.v );
  1684.         
  1685.         CopyBits ( &((GrafPtr) srcGWorld)->portBits, &qd.thePort->portBits, &srcRect,
  1686.             &dstRect, srcCopy, FE_GetMDRegion(inCopyRgn) );
  1687.         
  1688.         ::OffsetRgn(FE_GetMDRegion(inCopyRgn), -scrollOffset.h, -scrollOffset.v);
  1689.         }
  1690. }
  1691.  
  1692. // Dispatcher for events arriving from layers. These events may have originated in
  1693. // the front end and sent to layers, or they may have been synthesized.
  1694. PRBool CHTMLView::HandleLayerEvent(
  1695.     CL_Layer*                inLayer,
  1696.     CL_Event*                inEvent)
  1697. {
  1698.     CStLayerOriginSetter makeOriginInLayerOrigin(this, inLayer);
  1699.     fe_EventStruct *fe_event = (fe_EventStruct *)inEvent->fe_event;
  1700.     
  1701.     SPoint32 theLayerPoint;
  1702.     theLayerPoint.h = inEvent->x;
  1703.     theLayerPoint.v = inEvent->y;
  1704.     
  1705.     if (!fe_event)
  1706.         // Fill in FE event if the event was synthesized in the backend
  1707.         {
  1708.         EventRecord event;
  1709.         Point whereLocal, wherePort, whereGlobal;
  1710.         
  1711.         ImageToLocalPoint(theLayerPoint, whereLocal);
  1712.         wherePort = whereLocal;
  1713.         LocalToPortPoint(wherePort);
  1714.         whereGlobal = wherePort;
  1715.         PortToLocalPoint(whereGlobal);
  1716.         
  1717.         event.when = ::TickCount();
  1718.         event.where = whereGlobal;
  1719.         event.modifiers = ((inEvent->modifiers & EVENT_SHIFT_MASK) ? shiftKey : 0) |
  1720.                             ((inEvent->modifiers & EVENT_CONTROL_MASK) ? controlKey : 0) |
  1721.                             ((inEvent->modifiers & EVENT_ALT_MASK) ? optionKey : 0) |
  1722.                             ((inEvent->modifiers & EVENT_META_MASK) ? cmdKey : 0);
  1723.         
  1724.         switch (inEvent->type)
  1725.             {
  1726.             case CL_EVENT_MOUSE_BUTTON_DOWN:
  1727.             case CL_EVENT_MOUSE_BUTTON_MULTI_CLICK:
  1728.                 SMouseDownEvent mouseDownEvent;
  1729.                 LWindow *window = LWindow::FetchWindowObject(GetMacPort());
  1730.                 
  1731.                 event.what = mouseDown;
  1732.                 // event.message is undefined
  1733.                 mouseDownEvent.wherePort = wherePort;
  1734.                 mouseDownEvent.whereLocal = whereLocal;
  1735.                 mouseDownEvent.macEvent = event;
  1736.                 mouseDownEvent.delaySelect = (window != nil) ? (!UDesktop::WindowIsSelected(window) && window->HasAttribute(windAttr_DelaySelect)) : false;
  1737.                 fe_event->event.mouseDownEvent = mouseDownEvent;
  1738.                 break;
  1739.             case CL_EVENT_MOUSE_MOVE:
  1740.                 event.what = nullEvent;
  1741.                 event.message = mouseMovedMessage;
  1742.                 fe_event->event.macEvent = event;
  1743.                 break;
  1744.             case CL_EVENT_KEY_DOWN:
  1745.                 event.what = keyDown;
  1746.                 event.message = inEvent->which;
  1747.                 fe_event->event.macEvent = event;
  1748.                 break;
  1749.             default:
  1750.                 return PR_TRUE; // ignore the event
  1751.             }
  1752.         }
  1753.  
  1754. /*
  1755.     // Make sure this event came from the front-end. 
  1756.     // i.e. ignore synthesized events
  1757.         return PR_TRUE;
  1758. */
  1759.     
  1760.     // Call the per-layer event handlers
  1761.     switch (inEvent->type)
  1762.         {
  1763.         case CL_EVENT_MOUSE_BUTTON_DOWN:
  1764.         case CL_EVENT_MOUSE_BUTTON_MULTI_CLICK:
  1765.             {
  1766.             //SMouseDownEvent* mouseDown = (SMouseDownEvent *)fe_event->event;
  1767.             //ClickSelfLayer(*mouseDown, inLayer, theLayerPoint);
  1768.             SMouseDownEvent mouseDown = fe_event->event.mouseDownEvent;
  1769.             ClickSelfLayer(mouseDown, inLayer, theLayerPoint);
  1770.             }
  1771.             break;
  1772.             
  1773.         case CL_EVENT_MOUSE_MOVE:
  1774.             {
  1775.             Point portPt = fe_event->portPoint;
  1776.             //EventRecord *macEvent = (EventRecord *)fe_event->event;
  1777.             //AdjustCursorSelfForLayer(portPt, *macEvent, inLayer, theLayerPoint);
  1778.             // modified for new fe_EventStruct typedef 1997-02-25 mjc
  1779.             EventRecord macEvent = fe_event->event.macEvent;
  1780.             AdjustCursorSelfForLayer(portPt, macEvent, inLayer, theLayerPoint);
  1781.             }
  1782.             break;
  1783.         case CL_EVENT_KEY_DOWN:
  1784.             {
  1785.             EventRecord macEvent = fe_event->event.macEvent;
  1786.             HandleKeyPressLayer(macEvent, inLayer, theLayerPoint);
  1787.             break;
  1788.             }
  1789.         case CL_EVENT_KEY_UP:
  1790.         case CL_EVENT_MOUSE_BUTTON_UP:
  1791.         case CL_EVENT_KEY_FOCUS_GAINED:
  1792.         case CL_EVENT_KEY_FOCUS_LOST:
  1793.             // Nothing to do, but grab the event
  1794.             break;
  1795.         default:
  1796.             // Pass the event through
  1797.             return PR_FALSE;
  1798.     }
  1799.     
  1800.     return PR_TRUE;            
  1801.  
  1802. }
  1803.  
  1804. PRBool CHTMLView::HandleEmbedEvent(    
  1805.     LO_EmbedStruct*            inEmbed, 
  1806.     CL_Event*                inEvent)
  1807. {
  1808.     NPEmbeddedApp* app = (NPEmbeddedApp*) inEmbed->FE_Data;
  1809.     if (app && app->fe_data)
  1810.     {
  1811.         CPluginView* view = (CPluginView*) app->fe_data;
  1812.         return (PRBool)view->HandleEmbedEvent(inEvent);
  1813.     }
  1814.     return PR_FALSE;
  1815. }
  1816.     
  1817. void CHTMLView::ScrollImageBy(
  1818.     Int32                    inLeftDelta,
  1819.     Int32                    inTopDelta,
  1820.     Boolean                 inRefresh)
  1821. {
  1822.     if ( ( inLeftDelta == 0 ) && ( inTopDelta == 0 ) )
  1823.         return;
  1824.         
  1825.     // Get the image coordinates of the frame origin
  1826.     
  1827.     Rect theFrame;
  1828.     CalcLocalFrameRect(theFrame);
  1829.  
  1830.     SPoint32    imageTopLeft;
  1831.     LocalToImagePoint(topLeft(theFrame), imageTopLeft);
  1832.     imageTopLeft.h += inLeftDelta;
  1833.     imageTopLeft.v += inTopDelta;
  1834.     
  1835.     if (mCompositor != NULL)
  1836.         CL_ScrollCompositorWindow(*mCompositor, imageTopLeft.h, imageTopLeft.v);            
  1837.  
  1838. // FIX ME!!! this seems like it might be a bug.  The image can be pinned and 
  1839. // not scroll as much as the request.  It seems like the commpositor would be out of sync.
  1840.  
  1841.     // Let PowerPlant do the rest 
  1842.     Boolean mayAutoScrollLeavingTurds = inRefresh && IsTarget(); //&& mDropRow;
  1843.         // Turds will be left if we call scrollbits in ScrollImageBy
  1844.     if (mayAutoScrollLeavingTurds)
  1845.     {
  1846.         // Notify the CTargetFramer (if any) to erase the frame hilite
  1847.         ExecuteAttachments(CTargetFramer::msg_ResigningTarget, this);
  1848.     }
  1849.     LView::ScrollImageBy(inLeftDelta, inTopDelta, inRefresh);
  1850.     if (mayAutoScrollLeavingTurds && FocusDraw())
  1851.     {
  1852.         // Turn hiliting back on
  1853.         // Notify the CTargetFramer to draw the border now.
  1854.         ExecuteAttachments(CTargetFramer::msg_BecomingTarget, this); // invert
  1855.     }
  1856.     // normally, the compositor will add forms control subpanes later, during
  1857.     // LPeriodical time.  if the subpanes are being displayed now for the first time,
  1858.     // they've never been added to this view, so we need to force the compositor to
  1859.     // add them now, while the update region is still fresh.
  1860.     if (mCompositor)
  1861.         CL_CompositeNow (*mCompositor);
  1862. }
  1863.  
  1864.  
  1865. // until flag is turned on...
  1866. extern "C" {
  1867. void LO_RelayoutOnResize(MWContext *context, int32 width, int32 height, int32 leftMargin, int32 topMargin);
  1868. }
  1869.  
  1870. // This method gets called when window changes size.
  1871. // Make sure we call mContext->Repaginate()
  1872. void CHTMLView::AdaptToSuperFrameSize(
  1873.     Int32                    inSurrWidthDelta,
  1874.     Int32                    inSurrHeightDelta,
  1875.     Boolean                    inRefresh)
  1876. {
  1877.     LView::AdaptToSuperFrameSize(inSurrWidthDelta, inSurrHeightDelta, inRefresh);
  1878.  
  1879.     if (IsRootHTMLView())
  1880.         {
  1881.         if ((mContext != NULL) && ((inSurrWidthDelta != 0) || (inSurrHeightDelta != 0)) && (!mContext->IsViewSourceContext()))
  1882.             {
  1883. #if 0
  1884.             mContext->Repaginate();
  1885. #else
  1886.             SDimension16    theFrameSize;
  1887.             Rect            theFrame;
  1888.             int32            leftMargin;
  1889.             int32            topMargin;
  1890.             
  1891.             GetFrameSize(theFrameSize);
  1892.             
  1893.             leftMargin = 8;
  1894.             topMargin = 8;
  1895.             
  1896.             CalcLocalFrameRect(theFrame);
  1897.             if ( theFrame.right - theFrame.left > 0 )
  1898.                 {
  1899.                 if (leftMargin > (theFrame.right / 2 ))
  1900.                     leftMargin = MAX( theFrame.right / 2 - 50, 0);
  1901.                 }
  1902.             if ( theFrame.bottom - theFrame.top > 0 )
  1903.                 {
  1904.                 if ( topMargin > (theFrame.bottom / 2 ) )
  1905.                     topMargin = MAX(theFrame.bottom / 2 -50, 0);
  1906.                 }
  1907.             
  1908.             // set the image size to the current frame size
  1909.             SDimension16 curFrameSize;
  1910.             GetFrameSize(curFrameSize);
  1911.  
  1912.             ResizeImageTo ( curFrameSize.width, curFrameSize.height, false );
  1913.  
  1914.             // If the vertical scrollbar might be shown,
  1915.             // tell layout that we already have it, so that it does
  1916.             // the correct wrapping of text.
  1917.             // If we do not do this, when vertical scrollbar only is
  1918.             // shown, some text might be hidden
  1919.             if (GetScrollMode() == LO_SCROLL_AUTO)
  1920.                 theFrameSize.width -= 15;
  1921.             
  1922.             LO_RelayoutOnResize ( *mContext, theFrameSize.width, theFrameSize.height, leftMargin, topMargin );
  1923.             AdjustScrollBars();
  1924. #endif
  1925.             }
  1926.         }
  1927. }
  1928.  
  1929. void CHTMLView::ResizeFrameBy(
  1930.     Int16                     inWidthDelta,
  1931.     Int16                     inHeightDelta,
  1932.     Boolean                 inRefresh)
  1933. {
  1934.     // are we on drugs?
  1935.     if ( ( inWidthDelta == 0 ) && ( inHeightDelta == 0 ) )
  1936.         return;
  1937.  
  1938.     SDimension16 theFrameSize;
  1939.     GetFrameSize(theFrameSize);
  1940.     theFrameSize.width += inWidthDelta;
  1941.     theFrameSize.height += inHeightDelta;
  1942.  
  1943.     // Let PowerPlant do the rest 
  1944.     LView::ResizeFrameBy(inWidthDelta, inHeightDelta, inRefresh);
  1945.     
  1946.     // We need to adjust the compositor before the inherited call in case
  1947.     // in refresh is true (immediate draw).
  1948.     if (mCompositor != NULL)
  1949.         CL_ResizeCompositorWindow(*mCompositor, theFrameSize.width, theFrameSize.height);            
  1950.     
  1951.     // We now call Repaginate in AdaptToSuperFrameSize
  1952. }
  1953.  
  1954. void CHTMLView::SetCurrentDrawable(
  1955.     CDrawable*            inDrawable)
  1956. {
  1957.     if ( inDrawable != NULL )
  1958.         {
  1959.         mCurrentDrawable = inDrawable;
  1960.         
  1961.         /* make sure this new drawable calls us */
  1962.         mCurrentDrawable->SetParent ( this );
  1963.         }
  1964.     else
  1965.         {
  1966.         mCurrentDrawable = NULL;
  1967.         }
  1968.                     
  1969.     /* Our focus has most likely changed */
  1970.     OutOfFocus ( nil );
  1971.     FocusDraw();
  1972. }
  1973.  
  1974. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1975. //
  1976. #pragma mark --- COMMANDER OVERRIDES ---
  1977. //
  1978. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  1979.  
  1980. void MochaFocusCallback(    MWContext * /* pContext */,
  1981.                             LO_Element * /* lo_element */,
  1982.                             int32 /* lType */,
  1983.                             void * whatever,
  1984.                             ETEventStatus status    )
  1985. {
  1986.     if (status == EVENT_OK && whatever)
  1987.     {
  1988.         CHTMLView* htmlView = reinterpret_cast<CHTMLView*>(whatever);
  1989.         htmlView->ClearInFocusCallAlready();
  1990.     }
  1991. }
  1992.  
  1993. void CHTMLView::PutOnDuty(LCommander*)
  1994. {
  1995.     if (IsFocusedFrame() && FocusDraw())
  1996.         DrawFrameFocus();
  1997.     // javascript onFocus callback - 1997-02-27 mjc
  1998.     if (mContext != NULL && !mInFocusCallAlready)
  1999.     {
  2000.         JSEvent* event = XP_NEW_ZAP(JSEvent);
  2001.         if (event)
  2002.         {
  2003.             event->type = EVENT_FOCUS;
  2004.             event->layer_id = LO_DOCUMENT_LAYER_ID;
  2005.             mInFocusCallAlready = true;
  2006.             ET_SendEvent( *mContext, NULL, event, MochaFocusCallback, this );
  2007.         }
  2008.     }
  2009. }
  2010.  
  2011. void CHTMLView::TakeOffDuty(void)
  2012. {
  2013.     if (FocusDraw())
  2014.         InvalFocusArea();
  2015.     // javascript onBlur callback  - 1997-02-27 mjc
  2016.     if (mContext != NULL && !mInFocusCallAlready)
  2017.     {
  2018.         JSEvent* event = XP_NEW_ZAP(JSEvent);
  2019.         if (event)
  2020.         {
  2021.             event->type = EVENT_BLUR;
  2022.             event->layer_id = LO_DOCUMENT_LAYER_ID;
  2023.             mInFocusCallAlready = true;
  2024.             ET_SendEvent( *mContext, NULL, event, MochaFocusCallback, this );
  2025.         }
  2026.     }
  2027. }
  2028.  
  2029. void CHTMLView::FindCommandStatus(CommandT inCommand,
  2030.                                     Boolean    &outEnabled,
  2031.                                     Boolean    &outUsesMark,
  2032.                                     Char16    &outMark,
  2033.                                     Str255    outName)
  2034. {
  2035.     outUsesMark = false;
  2036.     if (!mContext) // yes, this can happen.  It happened to me!
  2037.     {
  2038.         LTabGroup::FindCommandStatus(inCommand, outEnabled, outUsesMark, outMark, outName);
  2039.         return;
  2040.     }
  2041.     
  2042.     CBrowserWindow    *browserWindow = dynamic_cast<CBrowserWindow *>(CViewUtils::GetTopMostSuperView(this));
  2043.     Boolean isRootDocInfo    = browserWindow ? browserWindow->IsRootDocInfo() : false;
  2044.     Boolean isHTMLHelp        = browserWindow ? browserWindow->IsHTMLHelp() : false;
  2045.     Boolean    isViewSource    = browserWindow ? browserWindow->IsViewSource() : false;
  2046.     
  2047.     // Disable commands which don't apply to restricted targets, at the request of javascript.
  2048.     // No special distinction needed for floaters here.
  2049.     if (browserWindow && 
  2050.         browserWindow->CommandsAreDisabled() &&
  2051.         (        
  2052.             inCommand == cmd_AddToBookmarks ||
  2053.             inCommand == cmd_ViewSource ||
  2054.             inCommand == cmd_DocumentInfo ||
  2055.             inCommand == cmd_Find ||
  2056.             inCommand == cmd_FindAgain ||
  2057.             inCommand == cmd_MailDocument ||
  2058.             inCommand == cmd_LoadImages ||
  2059.             inCommand == cmd_Reload ||
  2060.             inCommand == cmd_SaveAs))
  2061.     {
  2062.         outEnabled = false;
  2063.         return;
  2064.     }
  2065.  
  2066.     switch (inCommand)
  2067.     {            
  2068.         case cmd_LoadImages:
  2069.             if (mContext && !isViewSource)
  2070.             {
  2071.                 outEnabled = !sCachedAlwaysLoadImages;
  2072.             }
  2073.             break;
  2074.  
  2075.         case cmd_Reload:
  2076.             {
  2077.                 if (GetContext())
  2078.                 {
  2079.                     CBrowserContext* theTopContext = GetContext()->GetTopContext();
  2080.                     if ((theTopContext != nil) && (theTopContext->GetCurrentHistoryEntry() != nil) && !XP_IsContextBusy(*theTopContext))
  2081.                     {
  2082.                         outEnabled = true;
  2083.                         
  2084.                         if (CApplicationEventAttachment::CurrentEventHasModifiers(optionKey) ||
  2085.                             CApplicationEventAttachment::CurrentEventHasModifiers(shiftKey))
  2086.                         {
  2087.                             LString::CopyPStr(::GetPString(MENU_SUPER_RELOAD), outName);
  2088.                         }
  2089.                         else
  2090.                         {
  2091.                             LString::CopyPStr(::GetPString(MENU_RELOAD), outName);
  2092.                         }
  2093.                     }
  2094.                 }
  2095.             }
  2096.             break;
  2097.  
  2098.         case cmd_SecurityInfo:
  2099.         {
  2100.             outEnabled = !UDesktop::FrontWindowIsModal();
  2101.             break;
  2102.         }
  2103.         case cmd_ViewSource:
  2104.         case cmd_DocumentInfo:
  2105.         {
  2106.             outEnabled = !isHTMLHelp;
  2107.             break;
  2108.         }
  2109.         case cmd_AddToBookmarks:
  2110.             outUsesMark = false;
  2111.             outEnabled = mContext && mContext->GetCurrentHistoryEntry() && !(isRootDocInfo || isHTMLHelp);
  2112.             break;
  2113.         case cmd_SaveAs:
  2114.         {
  2115.             if ((mContext->GetCurrentHistoryEntry() != nil) && !XP_IsContextBusy(*mContext))
  2116.             {
  2117.                 outEnabled = !isHTMLHelp;
  2118.             }
  2119.             break;
  2120.         }
  2121.                 
  2122.         case cmd_Copy:
  2123.         {
  2124.             outEnabled = LO_HaveSelection(*mContext);
  2125.             break;
  2126.         }
  2127.  
  2128.         case cmd_SelectAll:
  2129.         {
  2130.             outEnabled = (mContext->GetCurrentHistoryEntry() != NULL);
  2131.             break;
  2132.         }
  2133.         
  2134.         case cmd_Find:
  2135.         {
  2136.             outEnabled = (mContext->GetCurrentHistoryEntry() != NULL);
  2137.             break;
  2138.         }
  2139.         
  2140.         case cmd_FindAgain:
  2141.         {
  2142.             outEnabled = ((mContext->GetCurrentHistoryEntry() != NULL) && CFindWindow::CanFindAgain());
  2143.             break;
  2144.         }
  2145.         
  2146.         case cmd_PageSetup:
  2147.             if (CanPrint())
  2148.                 outEnabled = TRUE;
  2149.             break;
  2150.         case cmd_Print:
  2151.         case cmd_PrintOne:
  2152.         {
  2153.             if (CanPrint())
  2154.                 outEnabled = TRUE;
  2155.             if (mContext && (MWContext (*mContext)).is_grid_cell)
  2156.                 LString::CopyPStr( GetPString( MENU_PRINT_FRAME ), outName);
  2157.             else
  2158.                 LString::CopyPStr( GetPString( MENU_PRINT ), outName);
  2159.             break;
  2160.         }
  2161.         case cmd_MailDocument:    // Send Page/Frame
  2162.             if (mContext->IsGridCell())
  2163.             {    // frame view, set menu command to "Send Frame..."
  2164.                 LStr255 sendFrameStr(cPaulsMiscStrListID, cSendFrameIndex);
  2165.                 LString::CopyPStr(sendFrameStr, outName);
  2166.                 outEnabled = !isHTMLHelp;
  2167.             }
  2168.             else if (!mContext->HasGridChildren() && !mContext->HasGridParent())
  2169.             {    // non-frame view
  2170.                 LStr255 sendPageStr(cPaulsMiscStrListID, cSendPageIndex);
  2171.                 LString::CopyPStr(sendPageStr, outName);
  2172.                 outEnabled = !isHTMLHelp;
  2173.             }
  2174.             else
  2175.             {    // frame container view
  2176.                 LStr255 sendFrameStr(cPaulsMiscStrListID, cSendFrameIndex);
  2177.                 LString::CopyPStr(sendFrameStr, outName);
  2178.                 outEnabled = false;
  2179.             }
  2180.             break;
  2181.  
  2182.         default:
  2183.             if(inCommand >= ENCODING_BASE && inCommand < ENCODING_CEILING)
  2184.             {
  2185.                 outEnabled = true;
  2186.                 outUsesMark = true;
  2187.                 
  2188.                 int16 csid = CPrefs::CmdNumToDocCsid( inCommand );
  2189.                 outMark = (csid == mContext->GetDefaultCSID()) ? checkMark : ' ';
  2190.             } else 
  2191.                 LTabGroup::FindCommandStatus(inCommand, outEnabled, outUsesMark, outMark, outName);
  2192.     }
  2193. } // CHTMLView::FindCommandStatus
  2194.  
  2195.  
  2196. void CHTMLView::GetDefaultFileNameForSaveAs(URL_Struct* url, CStr31& defaultName)
  2197. {
  2198.     // Overridden by CMessageView to use the message subject instead.
  2199.     fe_FileNameFromContext(*mContext, url->address, defaultName);
  2200. }
  2201.  
  2202. Boolean    CHTMLView::ObeyCommand(CommandT inCommand, void* ioParam)
  2203. {
  2204.     Boolean cmdHandled = false;
  2205. //    CURLDispatcher*    theDispatcher = CURLDispatcher::GetURLDispatcher();
  2206.     CHTMLClickRecord* cr = mCurrentClickRecord; // for brevity.
  2207.         // cr will be non-null when handling a context menu command.
  2208.     mCurrentClickRecord = nil; // set it back.
  2209.     LClipboard* clip = LClipboard::GetClipboard();
  2210.     switch (inCommand)
  2211.     {            
  2212.         case cmd_NEW_WINDOW_WITH_FRAME:
  2213.             History_entry* history = mContext->GetCurrentHistoryEntry();
  2214.             if (!history)
  2215.                 break;
  2216.             URL_Struct* url = SHIST_CreateURLStructFromHistoryEntry(*mContext, history);            
  2217.             if (url)
  2218.             {
  2219.                 url->history_num    = 0;
  2220.                 XP_MEMSET(&url->savedData, 0, sizeof(SHIST_SavedData));
  2221.             }
  2222.             
  2223.             DispatchURL(url, mContext, false, true);
  2224.             cmdHandled = true;
  2225.             break;
  2226.         case cmd_OPEN_LINK:
  2227.             if (cr)
  2228.             {
  2229.                 if (cr->mClickKind == eImageIcon)
  2230.                 {
  2231.                     // Make sure that we follow the link, and not load the image
  2232.                     cr->mClickKind = eImageAnchor;
  2233.                 }
  2234.                 ClickSelfLink(*(SMouseDownEvent*)ioParam, *cr, FALSE);
  2235.             }
  2236.             cmdHandled = true;
  2237.             break;
  2238.         case cmd_NEW_WINDOW:
  2239.             if (cr)
  2240.             {
  2241.                 ClickSelfLink(*(SMouseDownEvent*)ioParam, *cr, TRUE);// case C
  2242.                 cmdHandled = true;
  2243.             }
  2244.             break;
  2245.         case cmd_COPY_LINK_LOC:
  2246.             if (cr)
  2247.             {
  2248.                 try                                                    //╩case D
  2249.                 {
  2250.                     if (cr->IsAnchor() && (cr->mClickURL.length() > 0))
  2251.                         clip->SetData('TEXT', cr->mClickURL.data(), cr->mClickURL.length(), TRUE);
  2252.                     else                                            // case E
  2253.                     {
  2254.                         cstring    urlString = mContext->GetCurrentURL();
  2255.                         clip->SetData('TEXT', urlString.data(), urlString.length(), TRUE);
  2256.                     }
  2257.                 }
  2258.                 catch(...) {}
  2259.                 cmdHandled = true;
  2260.             }
  2261.             break;
  2262.         case cmd_VIEW_IMAGE:
  2263.             if (cr)
  2264.             {
  2265.                 cstring urlString = GetURLFromImageElement(mContext, (LO_ImageStruct*) cr->mElement);
  2266.                 if (urlString != "")
  2267.                 {
  2268.                     URL_Struct* url = NET_CreateURLStruct(urlString, NET_DONT_RELOAD); 
  2269.                     DispatchURL(url, mContext);
  2270.                 }
  2271.                 cmdHandled = true;
  2272.             }
  2273.             break;
  2274.         case cmd_SAVE_IMAGE_AS:
  2275.             if (cr)
  2276.             {
  2277.                 StandardFileReply reply;
  2278.                 cstring urlString = GetURLFromImageElement(mContext, (LO_ImageStruct*) cr->mElement);
  2279.                 if (urlString == "")
  2280.                     break;
  2281.                 CStr31 fileName = CFileMgr::FileNameFromURL( urlString );
  2282.                 Boolean isMailAttachment = false;
  2283.                 #ifdef MOZ_MAIL_NEWS
  2284.                 isMailAttachment = XP_STRSTR( urlString, "?part=") || XP_STRSTR(urlString, "&part=");
  2285.                 if( isMailAttachment ) 
  2286.                 {
  2287.                     fe_FileNameFromContext(*mContext, urlString, fileName);
  2288.                 }
  2289.                 #endif // MOZ_MAIL_NEWS
  2290.                 
  2291.                 StandardPutFile(GetPString(MCLICK_SAVE_IMG_AS), fileName, &reply);
  2292.                 if (reply.sfGood)
  2293.                 {
  2294.                     URL_Struct* url = NET_CreateURLStruct(urlString, NET_DONT_RELOAD);
  2295.                     XP_MEMSET(&url->savedData, 0, sizeof(SHIST_SavedData));
  2296.                     CURLDispatcher::DispatchToStorage(url, reply.sfFile);
  2297.                 }
  2298.                 cmdHandled = true;
  2299.             }
  2300.             break;
  2301.         case cmd_COPY_IMAGE:
  2302.             if (cr)
  2303.             {
  2304.                 PicHandle pict = ConvertImageElementToPICT((LO_ImageStruct*) cr->mElement);
  2305.                 if (pict != NULL)
  2306.                 {
  2307.                     try
  2308.                     {
  2309.                         clip->SetData('PICT', (Handle) pict, TRUE);
  2310.                     }
  2311.                     catch(...) 
  2312.                     {
  2313.                     }
  2314.                     KillPicture(pict);
  2315.                 }
  2316.                 cmdHandled = true;
  2317.             }
  2318.             break;
  2319.         case cmd_COPY_IMAGE_LOC:
  2320.             if (cr)
  2321.             {
  2322.                 cstring urlString = GetURLFromImageElement(mContext, (LO_ImageStruct*) cr->mElement);
  2323.                 if (urlString != "")
  2324.                 {
  2325.                     try
  2326.                     {
  2327.                         clip->SetData('TEXT', urlString, strlen(urlString), TRUE );
  2328.                     }
  2329.                     catch(...)
  2330.                     {}
  2331.                 }
  2332.                 cmdHandled = true;
  2333.             }
  2334.             break;
  2335.         case cmd_LOAD_IMAGE:
  2336.             if (cr)
  2337.             {
  2338.                 PostDeferredImage(cr->mImageURL);
  2339.                 cmdHandled = true;
  2340.             }
  2341.             break;
  2342.             
  2343.         case cmd_LoadImages:
  2344.             {
  2345.                 // Load images for the top-most browser context
  2346.                 
  2347.                 cmdHandled = true;
  2348.                 
  2349.                 if (GetContext())
  2350.                 {
  2351.                     CBrowserContext* theTopContext = GetContext()->GetTopContext();
  2352.                     if (theTopContext)
  2353.                     {
  2354.                         LO_SetForceLoadImage(NULL, TRUE);
  2355.                         theTopContext->Repaginate();
  2356.                     }
  2357.                 }
  2358.             }
  2359.             break;
  2360.  
  2361.         case cmd_ViewSource:
  2362.         {
  2363.             URL_Struct* url = NET_CreateURLStruct(mContext->GetCurrentURL(), NET_DONT_RELOAD);
  2364.             mContext->ImmediateLoadURL(url, FO_VIEW_SOURCE);
  2365.             NET_FreeURLStruct ( url );
  2366.             cmdHandled = true;
  2367.             break;
  2368.         }
  2369.         case cmd_AddToBookmarks:
  2370.         {
  2371.             // two cases: is this the "Add URL to bookmarks" from context menu or
  2372.             // using "Add Bookmarks" from the bookmark menu. 
  2373.             
  2374.             if ( cr && cr->IsAnchor() ) {
  2375.                 // strip off the protocol then truncate the middle
  2376.                 char trunkedAddress[HIST_MAX_URL_LEN + 1];
  2377.                 string url = cr->GetClickURL();
  2378.                 const char* strippedAddr = SHIST_StripProtocol( const_cast<char*>(url.c_str()) );
  2379.                 INTL_MidTruncateString( 0, strippedAddr, trunkedAddress, HIST_MAX_URL_LEN );
  2380.                 
  2381.                 CBookmarksAttachment::AddToBookmarks( cr->GetClickURL(), trunkedAddress);
  2382.             }
  2383.             else {
  2384.                 History_entry *entry = mContext->GetCurrentHistoryEntry();
  2385.                 if ( entry )
  2386.                     CBookmarksAttachment::AddToBookmarks(entry->address, entry->title);
  2387.             }
  2388.             break;
  2389.         }
  2390.         case cmd_SAVE_LINK_AS:
  2391.         case cmd_SaveAs:
  2392.         {
  2393.             URL_Struct* url = nil;
  2394.             if (cr && cr->IsAnchor() && inCommand == cmd_SAVE_LINK_AS )
  2395.                 url = NET_CreateURLStruct(cr->mClickURL, NET_DONT_RELOAD);
  2396.             else
  2397.                 url = NET_CreateURLStruct(mContext->GetCurrentURL(), NET_DONT_RELOAD);
  2398.             CStr31 fileName;
  2399.             Boolean isMailAttachment = false;
  2400.             #ifdef MOZ_MAIL_NEWS
  2401.             isMailAttachment = XP_STRSTR( url->address, "?part=") || XP_STRSTR(url->address, "&part=");
  2402.             if( isMailAttachment ) 
  2403.             {
  2404.                 CHTMLView::GetDefaultFileNameForSaveAs(url, fileName);
  2405.             }
  2406.             else
  2407.             #endif // MOZ_MAIL_NEWS
  2408.             {
  2409.                 if (inCommand == cmd_SAVE_LINK_AS)
  2410.                 {
  2411.                     fileName = CFileMgr::FileNameFromURL( url->address );
  2412.                 }
  2413.                 else
  2414.                 {
  2415.                     GetDefaultFileNameForSaveAs(url, fileName);
  2416.                 }
  2417.             }
  2418.             
  2419.             StandardFileReply reply;
  2420.             short format;
  2421.             if (cr && cr->IsAnchor() && (!strncasecomp(url->address, "ftp://", 6) || isMailAttachment ) )
  2422.                 (void) UStdDialogs::AskSaveAsSource(reply, fileName, format);
  2423.             else
  2424.                 (void) UStdDialogs::AskSaveAsTextOrSource(reply, fileName, format);
  2425.             if (reply.sfGood)
  2426.             {
  2427.                 short saveType = (format == 2) ? FO_SAVE_AS : FO_SAVE_AS_TEXT;
  2428.                 CURLDispatcher::DispatchToStorage(url, reply.sfFile, saveType, isMailAttachment );
  2429.             }
  2430.             
  2431.             cmdHandled = true;
  2432.             break;
  2433.         }
  2434.         
  2435.         case cmd_Copy:
  2436.         {
  2437.             char*        realText;
  2438.             XP_Block    copyText = LO_GetSelectionText(*mContext);
  2439.             OSErr        err = ::ZeroScrap();
  2440.             
  2441.             XP_LOCK_BLOCK(realText, char*, copyText);
  2442.             err = ::PutScrap(strlen(realText), 'TEXT', (Ptr)realText);
  2443.             ::TEFromScrap();
  2444.             XP_UNLOCK_BLOCK(copyText);
  2445.             XP_FREE_BLOCK(copyText);
  2446.             break;
  2447.         }
  2448.         
  2449.         case cmd_SelectAll:
  2450.         {
  2451.             (void) LO_SelectAll(*mContext);
  2452.             break;
  2453.         }
  2454.  
  2455.         case cmd_Find:
  2456.         {
  2457.             CFindWindow::DoFind(this);
  2458.             break;
  2459.         }
  2460.         
  2461.         case cmd_FindAgain:
  2462.         {
  2463.             DoFind();
  2464.             break;
  2465.         }
  2466.                     
  2467.         case cmd_Print:
  2468.         case cmd_PrintOne:
  2469.         {
  2470.             DoPrintCommand(inCommand);
  2471.             cmdHandled = true;
  2472.             break;
  2473.         }
  2474.  
  2475.         case cmd_SecurityInfo:
  2476.         {
  2477.             MWContext* mwcontext = *GetContext();
  2478.             if (mwcontext)
  2479.             {
  2480.                 URL_Struct* url =
  2481.                     SHIST_CreateURLStructFromHistoryEntry(
  2482.                         mwcontext,
  2483.                         GetContext()->GetCurrentHistoryEntry()
  2484.                         );
  2485.                 
  2486.                 // It's OK if we call SECNAV_SecurityAdvisor with a NULL URL
  2487.                 // which is the case when the user has a blank page as their startup
  2488.                 // BUG #66435
  2489.                 //if (url)
  2490.                     SECNAV_SecurityAdvisor(mwcontext,url);
  2491.             }
  2492.             break;
  2493.         }
  2494.  
  2495.         case cmd_DocumentInfo:
  2496.             URL_Struct* aboutURL = NET_CreateURLStruct( "about:document", NET_DONT_RELOAD );
  2497.             if ( aboutURL )
  2498.             {
  2499.                 // about:document is displayed in the doc info window, so we don't need to call CURLDispatcher.
  2500.                 // Just call SwitchLoadURL on mContext
  2501.                 mContext->SwitchLoadURL(aboutURL, FO_CACHE_AND_PRESENT);
  2502.             }
  2503.             break;
  2504.         
  2505.         case cmd_FTPUpload:
  2506.         case msg_TabSelect:
  2507.             cmdHandled = true;
  2508.             break;
  2509.         
  2510.         case cmd_MailDocument:    // Send Page/Frame
  2511.             MSG_MailDocument(*mContext);
  2512.             break;
  2513.  
  2514.         default:
  2515.             cmdHandled = LTabGroup::ObeyCommand(inCommand, ioParam);
  2516.             break;
  2517.     }
  2518.     if (cr && cr->IsAnchor())
  2519.         LO_HighlightAnchor(*mContext, cr->mElement, FALSE);
  2520.     return cmdHandled;
  2521. } // CHTMLView::ObeyCommand
  2522.  
  2523. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2524. Boolean CHTMLView::SetDefaultCSID(Int16 default_csid)
  2525. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2526. {
  2527.     if (mContext && default_csid != mContext->GetDefaultCSID())
  2528.     {
  2529.         mContext->SetDefaultCSID(default_csid);
  2530.         mContext->SetWinCSID(INTL_DocToWinCharSetID(default_csid));
  2531.         mContext->Repaginate();
  2532.     }
  2533.     return true;
  2534. } // CHTMLView::SetDefaultCSID
  2535.  
  2536.  
  2537.  
  2538. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2539. Boolean CHTMLView::CanPrint() const
  2540. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2541. {    
  2542.     // Ñ in order to be able to print we must
  2543.     //        not already be printing,
  2544.     //        not be busy loading,
  2545.     //        not be busy repaginating,
  2546.     //        have a page loaded,
  2547.     //        not be low on memory,
  2548.     //        and have a print record to print with
  2549.     return        mContext &&
  2550.                 !XP_IsContextBusy(*mContext) &&
  2551.                 !mContext->IsRepaginating() &&
  2552.                 (mContext->GetCurrentHistoryEntry() != nil) && 
  2553.                 !Memory_MemoryIsLow();
  2554. //                && CPrefs::GetPrintRecord();
  2555. /*    We no longer checking for a print record; now we allow the user to make
  2556.     the menu selection and then provide feedback about its failure) */
  2557. } // CHTMLView::CanPrint() const
  2558.  
  2559. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2560. URL_Struct *CHTMLView::GetURLForPrinting(Boolean& outSuppressURLCaption, MWContext * /* context */)
  2561. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2562. {
  2563.     MWContext *context = *GetContext();
  2564.     History_entry* current = SHIST_GetCurrent(&context->hist);
  2565.     ThrowIfNil_(current);
  2566.  
  2567.     URL_Struct* url = SHIST_CreateWysiwygURLStruct(context, current);
  2568.     ThrowIfNil_(url);
  2569.     
  2570.     outSuppressURLCaption = false;
  2571.     
  2572.     return url;
  2573. } // CHTMLView::GetURLForPrinting()
  2574.  
  2575. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2576. void CHTMLView::DoPrintCommand(CommandT inCommand)
  2577. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2578. {
  2579.     THPrint hp;
  2580.     hp = CPrefs::GetPrintRecord();
  2581.     if ( !hp )
  2582.     {
  2583.         FE_Alert( *GetContext(), GetPString ( NO_PRINTER_RESID ) );
  2584.         return;
  2585.     }
  2586.  
  2587.     UPrintingMgr::ValidatePrintRecord( hp );
  2588.  
  2589.     Boolean printOne = ( inCommand == cmd_PrintOne );
  2590.  
  2591.     //
  2592.     // If this page is a single fullscreen plugin, give the
  2593.     // plugin a chance to handle the entire print process.  If
  2594.     // it returns false, it doesn╒t want to take over printing,
  2595.     // so we should print as normal.
  2596.     //
  2597.     Boolean doPrint = true;
  2598.  
  2599.     NPEmbeddedApp* app = ((MWContext*)*mContext)->pluginList;
  2600.     if (app != NULL && app->next == NULL && app->pagePluginType == NP_FullPage)
  2601.     {
  2602.         CPluginView* plugin = (CPluginView*) app->fe_data;
  2603.         if ( plugin )
  2604.             doPrint = ( plugin->PrintFullScreen( printOne, hp ) != TRUE );
  2605.     }
  2606.  
  2607.     //
  2608.     // There wasn╒t a fullscreen plugin, or there was a plugin 
  2609.     // but it wants us to take care of printing.  In this case
  2610.     // we should show the normal dialog if necessary and print.
  2611.     //
  2612.     if ( doPrint )
  2613.     {
  2614.         if ( printOne )
  2615.         {
  2616.             (**hp).prJob.iFstPage = 1;
  2617.             (**hp).prJob.iLstPage = max_Pages;
  2618.             (**hp).prJob.iCopies = 1;
  2619.             UHTMLPrinting::BeginPrint( hp, this );
  2620.         }
  2621.         else
  2622.         {
  2623.             if ( UPrintingMgr::AskPrintJob( hp ) )
  2624.                 UHTMLPrinting::BeginPrint( hp, this );
  2625.         }
  2626.     }
  2627. } // CHTMLView::DoPrintCommand
  2628.  
  2629. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2630. //
  2631. #pragma mark --- FIND SUPPORT ---
  2632. //
  2633. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2634.  
  2635.  
  2636.  
  2637. void CHTMLView::CreateFindWindow()
  2638. {
  2639.     LWindow::CreateWindow(6000, LCommander::GetTopCommander());
  2640. }
  2641.  
  2642.     // history code, I am not sure what does it do
  2643. static void SelectionToImage(LO_Element* startElement,
  2644.                                 int32 /*startPos*/, 
  2645.                                 LO_Element* /*endElement*/,
  2646.                                 int32 /*endPos*/, 
  2647.                                 SPoint32* topLeft,
  2648.                                 SPoint32* botRight)
  2649. {
  2650.     /*
  2651.     Calculate an image rectangle which is good enough to display some portion
  2652.     of a selection. Since selections can wrap around and do other wierd stuff,
  2653.     we'll make it big enough to cover the first "element" of the selection.
  2654.     */
  2655.     
  2656.     topLeft->h = startElement->lo_any.x;
  2657.     topLeft->v = startElement->lo_any.y;
  2658.     
  2659.     botRight->h = startElement->lo_any.x + 64    /*endPos*/;
  2660.     botRight->v = startElement->lo_any.y + 20;
  2661. }
  2662.  
  2663. // Returns whether the search string was found - 1997-02-27 mjc
  2664. Boolean CHTMLView::DoFind()
  2665. {
  2666.     int32             start_position;
  2667.     int32            end_position;
  2668.     LO_Element*     start_ele_loc     = NULL;
  2669.     LO_Element*     end_ele_loc     = NULL;
  2670.     CL_Layer*         layer;
  2671.     MWContext*         gridContext;
  2672.     MWContext*         currentContext = *mContext;
  2673.     Boolean         found = false;
  2674.     char*             lookFor = CFindWindow::sLastSearch;
  2675.     Boolean            caseless = CFindWindow::sCaseless;
  2676.     Boolean            backward  = CFindWindow::sBackward;
  2677.     Boolean            doWrap = CFindWindow::sWrap;
  2678.     
  2679.     /*
  2680.         I didn't like doing that, that being "grabbing statics from a class"
  2681.         but it's a lot cleaner than before, and it works.  Mail gets this for
  2682.         free, and only need a few overrides to provide their own search dialog
  2683.         deeje 1997-01-22
  2684.     */
  2685.     
  2686.     // work within the current selection
  2687.     LO_GetSelectionEndpoints(currentContext,
  2688.                                 &start_ele_loc,
  2689.                                 &end_ele_loc,
  2690.                                 &start_position,
  2691.                                 &end_position,
  2692.                                 &layer);
  2693.  
  2694.     do {        
  2695.         gridContext = currentContext;
  2696.         found = LO_FindGridText(currentContext,
  2697.                                 &gridContext,
  2698.                                 lookFor,
  2699.                                 &start_ele_loc,
  2700.                                 &start_position,
  2701.                                 &end_ele_loc,
  2702.                                 &end_position,
  2703.                                 !caseless,
  2704.                                 !backward);
  2705.  
  2706.         if (found)
  2707.             break;
  2708.         if (doWrap) {
  2709.             /* try again from the beginning.  these are the values LO_GetSelectionEndpoints
  2710.                returns if there was no selection */
  2711.             start_ele_loc = NULL;
  2712.             end_ele_loc = NULL;
  2713.             start_position = 0;
  2714.             end_position = 0;
  2715.             doWrap = false;
  2716.         } else {
  2717.             SysBeep(1);
  2718.             return false;
  2719.         }
  2720.     } while (true);
  2721.  
  2722.     /* 6.6.97: set target even if we didn't switch cells.  do this in case the CHTMLView
  2723.        isn't the target at all.  this is entirely possible after the first Find on
  2724.        a new window. */
  2725. //    if (currentContext != gridContext)    // Text was found in a different cell
  2726. //    {
  2727.         SwitchTarget(gridContext->fe.newView);
  2728. //    }
  2729.     
  2730.     SPoint32    selTopLeft, selBotRight;
  2731.     int32        tlx, tly;
  2732.     
  2733.         // Scroll before selecting because otherwise hilighting gets screwed up
  2734.     SelectionToImage(start_ele_loc,
  2735.                         start_position,
  2736.                         end_ele_loc,
  2737.                         end_position,
  2738.                         &selTopLeft,
  2739.                         &selBotRight);
  2740.     
  2741.     RevealInImage(gridContext->fe.newView, selTopLeft, selBotRight);
  2742.     LO_SelectText(gridContext,
  2743.                     start_ele_loc,
  2744.                     start_position,
  2745.                     end_ele_loc,
  2746.                     end_position,
  2747.                     &tlx,
  2748.                     &tly);
  2749.     return true;
  2750. }
  2751.  
  2752.  
  2753. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2754. //
  2755. #pragma mark --- MOUSING AND KEYING ---
  2756. //
  2757. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2758.  
  2759. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2760. //    Ñ Converts image point to offset from the origin of the available screen rect.
  2761. //    That is, the screen origin + menubar height.
  2762. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2763.  
  2764. void CHTMLView::ImageToAvailScreenPoint(const SPoint32 &inImagePoint, Point &outPoint) const
  2765. {
  2766.     ImageToLocalPoint(inImagePoint, outPoint);
  2767.     LocalToPortPoint(outPoint);
  2768.     PortToGlobalPoint(outPoint);
  2769.     outPoint.v -= ::GetMBarHeight();
  2770. }        
  2771.  
  2772. void CHTMLView::ClickSelf(const SMouseDownEvent& inMouseDown)
  2773. {
  2774. // With LAYERS, the original method gets the compositor to dispatch
  2775. // the event, which is then dealt with (in this method) on a per-layer
  2776. // basis.
  2777.  
  2778.     if ((mContext != NULL) && FocusDraw())
  2779.         {
  2780.         Int16 clickCount = GetClickCount();
  2781.         SPoint32 theImageClick;
  2782.         LocalToImagePoint(inMouseDown.whereLocal, theImageClick);
  2783.         if (mCompositor != NULL)
  2784.             {
  2785.             fe_EventStruct    fe_event;
  2786.             fe_event.portPoint = inMouseDown.wherePort;
  2787.             //fe_event.event =  (void *)&inMouseDown;
  2788.             fe_event.event.mouseDownEvent = inMouseDown; // 1997-02-25 mjc
  2789.  
  2790.             CL_Event        event;
  2791.             
  2792.             if (clickCount > 2) return; // ignore triple (or more) clicks
  2793.             event.type = CL_EVENT_MOUSE_BUTTON_DOWN;
  2794.             event.fe_event = (void *)&fe_event;
  2795.             event.fe_event_size = sizeof(fe_EventStruct); // 1997-02-25 mjc
  2796.             event.x = theImageClick.h;
  2797.             event.y = theImageClick.v;
  2798.             event.which = 1;
  2799.             event.data = clickCount;
  2800.             event.modifiers = CMochaHacks::MochaModifiers(inMouseDown.macEvent.modifiers);  // 1997-02-27 mjc
  2801.         
  2802.             // set a wait flag that gives ClickSelfLink and EventMouseUp a chance to execute,
  2803.             // and prevents the possibility of two mouse ups occurring for one mouse down.
  2804.             // ALERT:
  2805.             // This approach may have to be revised if we need to handle double clicks in JS.
  2806.             // This is because there seem to be some cases in which a double click might cause
  2807.             // EventMouseUp to be called when ClickSelfLink should be called instead. While this
  2808.             // has no adverse affect on the browser, a script may not expect that the mouse up
  2809.             // is not followed by a click.
  2810.             mWaitMouseUp = true;
  2811.             CL_DispatchEvent(*mCompositor, &event);    
  2812.             }
  2813.         else
  2814.             {
  2815.             mWaitMouseUp = true;
  2816.             ClickSelfLayer(inMouseDown, NULL, theImageClick);
  2817.             }
  2818.     }
  2819. }
  2820.  
  2821. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2822. //    Ñ Callback for click handling for new mocha event stuff    
  2823. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2824.  
  2825. // DoExecuteClickInLinkRecord
  2826. // Used as a Mocha callback structure
  2827. // holds all the information needed to call ReallyDoExecuteClickInLink
  2828. struct DoExecuteClickInLinkRecord
  2829. {
  2830.     SMouseDownEvent mWhere;
  2831.     CHTMLClickRecord mCr;
  2832.     Boolean mMakeNewWindow;
  2833.     Boolean mSaveToDisk;
  2834.     LO_AnchorData* mMouseOverMapArea;     // for click event handling in image maps
  2835.     CHTMLView * mView;
  2836.     int32 mEventType;
  2837.     
  2838.     DoExecuteClickInLinkRecord(    CHTMLView * view, 
  2839.                                 const SMouseDownEvent& where,
  2840.                                 CHTMLClickRecord cr,
  2841.                                 Boolean makeNewWindow,
  2842.                                 Boolean saveToDisk,
  2843.                                 LO_AnchorData* mouseOverMapArea,
  2844.                                 int32 eventType)
  2845.                                 : mCr(cr)    // do we really want to use default copy contructor?
  2846.     {
  2847.         mView = view;
  2848.         mWhere = where;
  2849.         mMakeNewWindow = makeNewWindow;
  2850.         mSaveToDisk = saveToDisk;
  2851.         mMouseOverMapArea = mouseOverMapArea;
  2852.         mEventType = eventType;
  2853.     }
  2854.             
  2855.     void ExecuteClickInLink()
  2856.     {
  2857.         Assert_(mView != NULL);
  2858.         mView->PostProcessClickSelfLink(mWhere, mCr, mMakeNewWindow, mSaveToDisk, false);
  2859.     }
  2860. };
  2861.  
  2862. // Mocha callback for DoExecuteClickInLink
  2863. // Click preceded by mouse up - 1997-03-08 mjc
  2864. void MochaDoExecuteClickInLinkCallback(MWContext * pContext, LO_Element * lo_element, int32 lType, void * whatever, ETEventStatus status);
  2865. void MochaDoExecuteClickInLinkCallback(MWContext * pContext, 
  2866.                                         LO_Element * lo_element, 
  2867.                                          int32  /* lType */, 
  2868.                                          void * whatever, 
  2869.                                          ETEventStatus status)
  2870. {
  2871.     DoExecuteClickInLinkRecord * p = (DoExecuteClickInLinkRecord*)whatever;
  2872.     
  2873.     if (status == EVENT_OK)
  2874.     {
  2875.         if (p->mEventType == EVENT_MOUSEUP)
  2876.         {
  2877.             try {
  2878.                 
  2879.                 DoExecuteClickInLinkRecord* clickRecord =
  2880.                     new DoExecuteClickInLinkRecord(p->mView,
  2881.                                                    p->mWhere,
  2882.                                                    p->mCr,
  2883.                                                    p->mMakeNewWindow,
  2884.                                                    p->mSaveToDisk,
  2885.                                                    p->mMouseOverMapArea,
  2886.                                                    EVENT_CLICK);
  2887.                 
  2888.                 JSEvent* event = XP_NEW_ZAP(JSEvent);
  2889.                 if (event)
  2890.                 {
  2891.                     if (p->mMouseOverMapArea != NULL)
  2892.                     {
  2893.                         lo_element = XP_NEW_ZAP(LO_Element);    // Need to fake the element, ask chouck for details
  2894.                         lo_element->type = LO_TEXT;
  2895.                         lo_element->lo_text.anchor_href = p->mMouseOverMapArea;
  2896.                         if (lo_element->lo_text.anchor_href->anchor)
  2897.                             lo_element->lo_text.text = lo_element->lo_text.anchor_href->anchor; // to pass js freed element check
  2898.                     }
  2899.                     CL_Layer* layer = p->mCr.GetLayer();
  2900.                     event->type = EVENT_CLICK;
  2901.                     event->which = 1;
  2902.                     event->x = p->mCr.GetImageWhere().h;
  2903.                     event->y = p->mCr.GetImageWhere().v;
  2904.                     event->docx = event->x + CL_GetLayerXOrigin(layer);
  2905.                     event->docy = event->y + CL_GetLayerYOrigin(layer);
  2906.                     
  2907.                     Point screenPt = { event->docy, event->docx };
  2908.                     SPoint32 imagePt;
  2909.                     p->mView->LocalToImagePoint(screenPt, imagePt);
  2910.                     p->mView->ImageToAvailScreenPoint(imagePt, screenPt);
  2911.                     event->screenx = screenPt.h;
  2912.                     event->screeny = screenPt.v;
  2913.                     
  2914.                     event->layer_id = LO_GetIdFromLayer(pContext, layer);
  2915.                     event->modifiers = CMochaHacks::MochaModifiers(p->mWhere.macEvent.modifiers);
  2916.                     ET_SendEvent(pContext,
  2917.                                  lo_element,
  2918.                                  event,
  2919.                                  MochaDoExecuteClickInLinkCallback,
  2920.                                  clickRecord);
  2921.                 }
  2922.             } 
  2923.             catch (...) 
  2924.             {
  2925.             }
  2926.         }
  2927.         else if (p->mEventType == EVENT_CLICK && p->mCr.IsClickOnAnchor())
  2928.             p->ExecuteClickInLink();
  2929.     }
  2930.     // Free faked element after click
  2931.     if (p->mEventType == EVENT_CLICK && p->mMouseOverMapArea != NULL)
  2932.         XP_FREE(lo_element);
  2933.     delete p;
  2934. }
  2935.  
  2936. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2937. //    Ñ    
  2938. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  2939.  
  2940. // Mouse tracking.
  2941. // On click if it is an anchor, track it. If the mouse does not move, load the anchor.
  2942. // If it is not an anchor, continue the selection.
  2943.  
  2944. void CHTMLView::ClickSelfLayer(
  2945.     const SMouseDownEvent&        inMouseDown,
  2946.     CL_Layer*                    inLayer,
  2947.     SPoint32                     inLayerWhere)
  2948. {
  2949.     SPoint32 theElementWhere = inLayerWhere;
  2950.     LO_Element* theElement = LO_XYToElement(*mContext, theElementWhere.h, theElementWhere.v, inLayer);
  2951.     
  2952.     CHTMLClickRecord cr(inMouseDown.whereLocal, inLayerWhere, mContext, theElement, inLayer);
  2953.     cr.Recalc();
  2954.     
  2955.     Boolean bClickHandled = false;
  2956.  
  2957.     // Ñ with shift key, just track selection
  2958.     if ((inMouseDown.macEvent.modifiers & shiftKey) == 0)
  2959.     {
  2960.         if ((theElement != NULL) && cr.PixelReallyInElement(theElementWhere, theElement))
  2961.         {
  2962.             // Move check for edge click here; otherwise, if you hold down mouse button over
  2963.             // edge, then context menu pops up. Whoops.
  2964.             if (cr.IsClickOnEdge())
  2965.                 ClickTrackEdge(inMouseDown, cr);
  2966.             else if (cr.IsClickOnAnchor())
  2967.             {
  2968.                 Int32 theClickStart = inMouseDown.macEvent.when;
  2969.                 Point thePrevPoint = inMouseDown.whereLocal;
  2970.  
  2971.                 LO_HighlightAnchor(*mContext, theElement, true);
  2972.         
  2973.                 mCurrentClickRecord = &cr;
  2974.                 CHTMLClickRecord::EClickState theMouseAction = CHTMLClickRecord::eUndefined;
  2975.                 // Use a try block to ensure that we set it back to nil
  2976.                 try
  2977.                 {
  2978.                     theMouseAction
  2979.                         = cr.WaitForMouseAction(inMouseDown, this, GetDblTime(), ContextMenuPopupsEnabled());
  2980.                 }
  2981.                 catch(...) {}
  2982.                 mCurrentClickRecord = nil;
  2983.                 
  2984.                 // Whether we need to unhighlight after handling the click.
  2985.                 // In the mouse up early case, unhighlighting must be done before the
  2986.                 // content changes, not afterwards, otherwise we would crash because the
  2987.                 // element is no longer there.
  2988.                 Boolean doUnhighlight = true;
  2989.                 
  2990.                 switch (theMouseAction)
  2991.                 {
  2992.                     case CHTMLClickRecord::eMouseDragging:
  2993.                         ClickDragLink(inMouseDown, theElement);
  2994.                         break;
  2995.                     
  2996.                     case CHTMLClickRecord::eMouseTimeout:
  2997. /*
  2998.                     {
  2999.                         Int16 thePopResult = this->DoPopup(inMouseDown, cr);
  3000.                         if (thePopResult)
  3001.                             this->HandlePopupResult(inMouseDown, cr, thePopResult);
  3002.                         else
  3003.                             LO_HighlightAnchor(*mContext, cr.mElement, false);
  3004.                     }
  3005. */
  3006.                         break;
  3007.                     
  3008.                     case CHTMLClickRecord::eMouseUpEarly:
  3009.                         ClickSelfLink(inMouseDown, cr, false);
  3010.                         doUnhighlight = false;
  3011.                         break;
  3012.                     
  3013.                     case CHTMLClickRecord::eHandledByAttachment:
  3014.                         // Nothing else to do.
  3015.                         break;
  3016.                     default:
  3017.                         SignalPStr_("\pUnhandled click case!!!");
  3018.                         break;
  3019.                 }
  3020.                     
  3021.                 if (doUnhighlight) LO_HighlightAnchor(*mContext, cr.mElement, false);
  3022.                 bClickHandled = true;
  3023.             }
  3024.             else if ((theElement != NULL) && (theElement->type == LO_IMAGE))
  3025.             {
  3026.                 // Ñ allow dragging of non-anchor images
  3027.                 mCurrentClickRecord = &cr;
  3028.                 CHTMLClickRecord::EClickState theMouseAction = CHTMLClickRecord::eUndefined;
  3029.                 try
  3030.                 {
  3031.                     theMouseAction = cr.WaitForMouseAction(inMouseDown.whereLocal, inMouseDown.macEvent.when, GetDblTime());
  3032.                 }
  3033.                 catch(...) {}
  3034.                 mCurrentClickRecord = nil;
  3035.                 if (theMouseAction == CHTMLClickRecord::eMouseDragging)
  3036.                 {
  3037.                     ClickDragLink(inMouseDown, theElement);
  3038.                     bClickHandled = true;
  3039.                 }
  3040.             }
  3041.         }
  3042.     }
  3043.     
  3044.     // callback for form elements - mjc
  3045.     if (!bClickHandled)
  3046.     {
  3047.         if ((theElement != NULL) && 
  3048.             (theElement->type == LO_FORM_ELE) &&
  3049.             (inLayerWhere.h - theElement->lo_form.x - theElement->lo_form.x_offset <= theElement->lo_form.width) &&
  3050.             (inLayerWhere.h - theElement->lo_form.x - theElement->lo_form.x_offset >= 0) &&
  3051.             (inLayerWhere.v - theElement->lo_form.y - theElement->lo_form.y_offset <= theElement->lo_form.height) &&
  3052.             (inLayerWhere.v - theElement->lo_form.y - theElement->lo_form.y_offset >= 0))
  3053.         {
  3054.             switch (theElement->lo_form.element_data->type)
  3055.             {
  3056.                 case FORM_TYPE_SUBMIT:
  3057.                 case FORM_TYPE_RESET:
  3058.                 case FORM_TYPE_BUTTON:
  3059.                     {
  3060.                         LPane*            thePane            = ((FormFEData *)theElement->lo_form.element_data->ele_minimal.FE_Data)->fPane;
  3061.  
  3062.                         CFormButton*        theFormButton    = dynamic_cast<CFormButton*>(thePane);
  3063.                         CGAFormPushButton*    theGAFormPushButton    = dynamic_cast<CGAFormPushButton*>(thePane);
  3064.  
  3065.                         if (theFormButton)
  3066.                         {                        
  3067.                             theFormButton->ClickSelfLayer(inMouseDown);
  3068.                         }
  3069.                         else if (theGAFormPushButton)
  3070.                         {
  3071.                             theGAFormPushButton->ClickSelfLayer(inMouseDown);
  3072.                         }
  3073.                         else
  3074.                         {
  3075.                             Assert_(false);
  3076.                         }
  3077.  
  3078.                         bClickHandled = true;
  3079.                     }
  3080.                     break;
  3081.                 case FORM_TYPE_RADIO:
  3082.                     {
  3083.                         LPane*            thePane            = ((FormFEData *)theElement->lo_form.element_data->ele_minimal.FE_Data)->fPane;
  3084.  
  3085.                         CFormRadio*        theFormRadio    = dynamic_cast<CFormRadio*>(thePane);
  3086.                         CGAFormRadio*    theGAFormRadio    = dynamic_cast<CGAFormRadio*>(thePane);
  3087.  
  3088.                         if (theFormRadio)
  3089.                         {                        
  3090.                             theFormRadio->ClickSelfLayer(inMouseDown);
  3091.                         }
  3092.                         else if (theGAFormRadio)
  3093.                         {
  3094.                             theGAFormRadio->ClickSelfLayer(inMouseDown);
  3095.                         }
  3096.                         else
  3097.                         {
  3098.                             Assert_(false);
  3099.                         }
  3100.  
  3101.                         bClickHandled = true;
  3102.                     }
  3103.                     break;
  3104.                 case FORM_TYPE_CHECKBOX:
  3105.                     {
  3106.                         LPane*                thePane                = ((FormFEData *)theElement->lo_form.element_data->ele_minimal.FE_Data)->fPane;
  3107.  
  3108.                         CFormCheckbox*        theFormCheckbox        = dynamic_cast<CFormCheckbox*>(thePane);
  3109.                         CGAFormCheckbox*    theGAFormCheckbox    = dynamic_cast<CGAFormCheckbox*>(thePane);
  3110.  
  3111.                         if (theFormCheckbox)
  3112.                         {                        
  3113.                             theFormCheckbox->ClickSelfLayer(inMouseDown);
  3114.                         }
  3115.                         else if (theGAFormCheckbox)
  3116.                         {
  3117.                             theGAFormCheckbox->ClickSelfLayer(inMouseDown);
  3118.                         }
  3119.                         else
  3120.                         {
  3121.                             Assert_(false);
  3122.                         }
  3123.  
  3124.                         bClickHandled = true;
  3125.                     }
  3126.                     break;
  3127.             }
  3128.         }
  3129.     }
  3130.     
  3131.         // ÑÑÑ╩there must be a better way...
  3132.         //
  3133.         // this is just about the same code as above for handling a click
  3134.         // but it's repeated here because the code above handles clicks on graphical elements?
  3135.         //
  3136.         // also, I see two version of WaitForMouseAction being called, one global and one inside cr
  3137.         // which is appropriate?
  3138.         //
  3139.         // 96-12-18 deeje
  3140.     
  3141.     if (!bClickHandled && ContextMenuPopupsEnabled())
  3142.     {
  3143.         mCurrentClickRecord = &cr;
  3144.         CHTMLClickRecord::EClickState mouseAction = CHTMLClickRecord::eUndefined;
  3145.         try
  3146.         {
  3147.             mouseAction = CHTMLClickRecord::WaitForMouseAction(
  3148.                 inMouseDown, this, GetDblTime());
  3149.         }
  3150.         catch (...) {}
  3151.         mCurrentClickRecord = nil;
  3152.         if ( mouseAction == CHTMLClickRecord::eHandledByAttachment )
  3153.             bClickHandled = TRUE;
  3154. /*
  3155.         if ( mouseAction == CHTMLClickRecord::eMouseTimeout ) // No popup when we have grids
  3156.         {
  3157.             Int16    thePopResult = this->DoPopup(inMouseDown, cr);
  3158.             if (thePopResult)
  3159.                 this->HandlePopupResult(inMouseDown, cr, thePopResult);
  3160.             
  3161.             bClickHandled = TRUE;
  3162.         }
  3163. */
  3164.     }
  3165.  
  3166.     if (!bClickHandled)
  3167.         {
  3168.             Boolean didTrackSelection = ClickTrackSelection(inMouseDown, cr);
  3169.             // if no selection, and we're not over an element,
  3170.             // send a mouse up and click to the document
  3171.             if (!didTrackSelection && (cr.mClickKind == eNone))
  3172.             {
  3173.                 EventRecord macEvent;
  3174.         
  3175.                 GetOSEvent(mUpMask, &macEvent); // grab the mouse up event so LEventDispatcher never sees it
  3176.  
  3177.                 mWaitMouseUp = false;
  3178.                 try {
  3179.                     DoExecuteClickInLinkRecord* clickRecord =
  3180.                         new DoExecuteClickInLinkRecord(this,
  3181.                                                        inMouseDown,
  3182.                                                        cr,
  3183.                                                        false,
  3184.                                                        false,
  3185.                                                        NULL,
  3186.                                                        EVENT_MOUSEUP);
  3187.                     JSEvent* event = XP_NEW_ZAP(JSEvent);
  3188.                     if (event)
  3189.                     {
  3190.                         // 97-06-10 pkc -- Turn off grab mouse events here because we don't call
  3191.                         // compositor for mouse ups.
  3192.                         MWContext* mwContext = *mContext;
  3193.                         if (mwContext->js_dragging==TRUE) {
  3194.                             CL_GrabMouseEvents(mwContext->compositor, NULL);
  3195.                             mwContext->js_dragging = 0;
  3196.                         }
  3197.  
  3198.                         event->type = EVENT_MOUSEUP;
  3199.                         event->which = 1;
  3200.                         event->x = cr.mImageWhere.h;
  3201.                         event->y = cr.mImageWhere.v;
  3202.                         event->docx = event->x + CL_GetLayerXOrigin(cr.mLayer);
  3203.                         event->docy = event->y + CL_GetLayerYOrigin(cr.mLayer);
  3204.                         
  3205.                         Point screenPt = { event->docy, event->docx };
  3206.                         SPoint32 imagePt;
  3207.                         LocalToImagePoint(screenPt, imagePt);
  3208.                         ImageToAvailScreenPoint(imagePt, screenPt);
  3209.                         event->screenx = screenPt.h;
  3210.                         event->screeny = screenPt.v;
  3211.                         
  3212.                         event->layer_id = LO_GetIdFromLayer(*mContext, cr.mLayer);
  3213.                         event->modifiers = CMochaHacks::MochaModifiers(inMouseDown.macEvent.modifiers);
  3214.                         ET_SendEvent(*mContext,
  3215.                                      NULL,
  3216.                                      event,
  3217.                                      MochaDoExecuteClickInLinkCallback,
  3218.                                      clickRecord);
  3219.                     }
  3220.                 } catch (...) {
  3221.                 }
  3222.             }
  3223.         }
  3224. }
  3225.  
  3226. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3227. //    Ñ    
  3228. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3229.  
  3230. void CHTMLView::ClickSelfLink(
  3231.     const SMouseDownEvent&    inMouseDown,
  3232.     CHTMLClickRecord&        inClickRecord,
  3233.     Boolean                    inMakeNewWindow)
  3234. {
  3235.     // Execute this only if there was a previous mouse down which did not have a corresponding
  3236.     // mouse up.
  3237.     if (mWaitMouseUp)
  3238.     {
  3239.         EventRecord macEvent;
  3240.         
  3241.         GetOSEvent(mUpMask, &macEvent); // grab the mouse up event so LEventDispatcher never sees it
  3242.         
  3243.         mWaitMouseUp = false; // got a mouse up so clear the wait flag.
  3244.         
  3245.         Boolean bSaveToDisk = ((inMouseDown.macEvent.modifiers & optionKey) == optionKey)
  3246.                               && !inMakeNewWindow;
  3247.  
  3248.         // do we also have to use a StTempFormBlur in PostProcessClickSelfLink?
  3249.         StTempFormBlur    tempBlur;    // mforms.h for an explanation
  3250.         
  3251.         // check for event handler in containing contexts or on anchor for the events
  3252.         // we are about to send.
  3253.         LO_Element* element = inClickRecord.GetLayoutElement();
  3254.         if (HasEventHandler(*mContext, (EVENT_MOUSEUP | EVENT_CLICK)) ||
  3255.             // map area anchor with an event handler
  3256.             (CMochaHacks::GetMouseOverMapArea() && CMochaHacks::GetMouseOverMapArea()->event_handler_present) ||
  3257.             (element && 
  3258.             // ALERT: event_handler_present doesn't seem to be initialized properly so test against TRUE.
  3259.             ((element->type == LO_TEXT && element->lo_text.anchor_href && (element->lo_text.anchor_href->event_handler_present == TRUE)) ||
  3260.              (element->type == LO_IMAGE && element->lo_image.anchor_href && (element->lo_image.anchor_href->event_handler_present == TRUE)) ||
  3261.              // a plain image without an anchor could have event handlers, but there is no bit to tell us that.
  3262.              ((element->type == LO_IMAGE) && 
  3263.                  (element->lo_image.anchor_href == NULL) &&
  3264.                  (element->lo_image.image_attr->usemap_name == NULL) && // not a client-side image map
  3265.                  !(element->lo_image.image_attr->attrmask & LO_ATTR_ISMAP))))) // not a server-side image map                 
  3266.         {
  3267.             try {
  3268.                 DoExecuteClickInLinkRecord* clickRecord =
  3269.                     new DoExecuteClickInLinkRecord(this,
  3270.                                                    inMouseDown,
  3271.                                                    inClickRecord,
  3272.                                                    inMakeNewWindow,
  3273.                                                    bSaveToDisk,
  3274.                                                    CMochaHacks::GetMouseOverMapArea(),
  3275.                                                    EVENT_MOUSEUP);
  3276.                 // ET_SendEvent now takes a JSEvent struct instead of an int type
  3277.                 JSEvent* event = XP_NEW_ZAP(JSEvent);
  3278.                 if (event)
  3279.                 {
  3280.                     // 97-06-10 pkc -- Turn off grab mouse events here because we don't call
  3281.                     // compositor for mouse ups.
  3282.                     MWContext* mwContext = *mContext;
  3283.                     if (mwContext->js_dragging==TRUE) {
  3284.                         CL_GrabMouseEvents(mwContext->compositor, NULL);
  3285.                         mwContext->js_dragging = 0;
  3286.                     }
  3287.  
  3288.                     event->type = EVENT_MOUSEUP;
  3289.                     event->which = 1;
  3290.                     // send layer relative position info to mocha - mjc
  3291.                     event->x = inClickRecord.mImageWhere.h;
  3292.                     event->y = inClickRecord.mImageWhere.v;
  3293.                     event->docx = event->x + CL_GetLayerXOrigin(inClickRecord.mLayer);
  3294.                     event->docy = event->y + CL_GetLayerYOrigin(inClickRecord.mLayer);
  3295.                                         
  3296.                     Point screenPt;
  3297.                     ImageToAvailScreenPoint(inClickRecord.mImageWhere, screenPt);
  3298.                     event->screenx = screenPt.h;
  3299.                     event->screeny = screenPt.v;
  3300.                     
  3301.                     event->layer_id = LO_GetIdFromLayer(*mContext, inClickRecord.mLayer); // 1997-03-02 mjc
  3302.                     event->modifiers = CMochaHacks::MochaModifiers(inMouseDown.macEvent.modifiers); // 1997-02-27 mjc
  3303.                     ET_SendEvent(*mContext,
  3304.                                  inClickRecord.mElement,
  3305.                                  event,
  3306.                                  MochaDoExecuteClickInLinkCallback,
  3307.                                  clickRecord);
  3308.                 }
  3309.             } catch (...) {
  3310.             }
  3311.         }
  3312.         // We delay DispatchToView because we're completely handling the mouse 
  3313.         // down in the front end, so the compositor needs to unwind before we switch content.
  3314.         else PostProcessClickSelfLink(inMouseDown, inClickRecord, inMakeNewWindow, bSaveToDisk, true);
  3315.     }
  3316. }
  3317.  
  3318. // PostProcessClickSelfLink
  3319. // Mocha callback routine, post processes DoExecuteClickInLink
  3320. // Because of the new threaded mocha, we have to wait for a call back
  3321. // after mocha calls, this code used to come after the call to LM_SendOnClick in ClickSelfLink.
  3322. // Now, this code gets executed after the call to ET_SendEvent calls us back through
  3323. // MochaDoExecuteClickInLinkCallback.
  3324. //
  3325. // inDelay - set to true if there is a possibility that the content will change before the compositor
  3326. // has finished unwinding from the mouse down event dispatch. If there were intervening
  3327. // javascript or compositor calls, for example, there is no need to delay.
  3328. void CHTMLView::PostProcessClickSelfLink(
  3329.     const SMouseDownEvent&    /* inMouseDown */,
  3330.     CHTMLClickRecord&        inClickRecord,
  3331.     Boolean                    inMakeNewWindow,
  3332.     Boolean                    inSaveToDisk,
  3333.     Boolean                    inDelay)
  3334. {
  3335.     // Sniff the URL to detect mail attachment.  Set inSaveToDisk accordingly before
  3336.     // dispatching.  Note that in Constellation, mail messages may be viewed in a browser
  3337.     // view!
  3338.  
  3339. /*
  3340.     Boolean isMailAttachment = false;
  3341.     const char* url = inClickRecord.GetClickURL();
  3342.     if (!strncasecomp (url, "mailbox:", 8))
  3343.     {
  3344.       if (XP_STRSTR(url, "?part=") || XP_STRSTR(url, "&part="))
  3345.         isMailAttachment = true; // Yep, mail attachment.
  3346.     }
  3347. */
  3348.  
  3349.     CBrowserContext* theSponsorContext = (inMakeNewWindow) ? NULL : mContext;
  3350.  
  3351.     EClickKind oldClickKind = inClickRecord.mClickKind;
  3352.  
  3353.     inClickRecord.Recalc();
  3354.     
  3355.     switch (inClickRecord.mClickKind)
  3356.     {
  3357.         case eTextAnchor:
  3358.         case eImageAnchor:
  3359.         case eImageIsmap:
  3360.         case eImageAltText:
  3361.             {
  3362.             // unhighlight the anchor while it is still around (before content is switched)
  3363.             LO_HighlightAnchor(*mContext, inClickRecord.mElement, false);
  3364.             
  3365.             FO_Present_Types theType = (inSaveToDisk) ? FO_SAVE_AS : FO_CACHE_AND_PRESENT;
  3366.             URL_Struct* theURL = NET_CreateURLStruct(inClickRecord.mClickURL, NET_DONT_RELOAD);
  3367.             ThrowIfNULL_(theURL);
  3368.  
  3369.             cstring theReferer = mContext->GetCurrentURL();
  3370.             if (theReferer.length() > 0)
  3371.                 theURL->referer = XP_STRDUP(theReferer);
  3372.  
  3373.             if (inMakeNewWindow)
  3374.                 theURL->window_target = XP_STRDUP("");
  3375.             else
  3376.                 {
  3377.                 if (XP_STRCMP(inClickRecord.mWindowTarget, "") != 0)
  3378.                     theURL->window_target = XP_STRDUP(inClickRecord.mWindowTarget);
  3379.                 else
  3380.                     theURL->window_target = NULL;
  3381.                 }
  3382.             
  3383.             if (FO_SAVE_AS == theType)
  3384.             {
  3385.                 // See also the code for popup stuff.  Combine these later.  FIX ME.
  3386.                 CStr31 fileName = CFileMgr::FileNameFromURL( theURL->address );
  3387.                 //fe_FileNameFromContext(*mContext, theURL->address, fileName);
  3388.                 StandardFileReply reply;
  3389. /*
  3390.                 if (isMailAttachment)
  3391.                 {
  3392.                     // ad decoder will prompt for the name.
  3393.                     reply.sfGood = true;
  3394.                     ::FSMakeFSSpec(0, 0, fileName, &reply.sfFile);
  3395.                 }
  3396.                 else
  3397. */
  3398.                     ::StandardPutFile(GetPString(SAVE_AS_RESID), fileName, &reply);
  3399.                 if (reply.sfGood)
  3400.                 {
  3401.                     CURLDispatcher::DispatchToStorage(theURL, reply.sfFile, FO_SAVE_AS, false);
  3402.                 }
  3403.             }
  3404.             else if (FO_CACHE_AND_PRESENT == theType)
  3405.             {
  3406.                     DispatchURL(theURL, theSponsorContext, inDelay, inMakeNewWindow);
  3407.             }
  3408.             break;
  3409.         }
  3410.  
  3411.         case eImageForm:    // Image that is an ISMAP form
  3412.             {
  3413. /*            LO_FormSubmitData *theSubmit = NULL;
  3414.             try
  3415.                 {
  3416.                 theSubmit = LO_SubmitImageForm(*mContext, &inClickRecord.mElement->lo_image, inClickRecord.mImageWhere.h, inClickRecord.mImageWhere.v);
  3417.                 ThrowIfNULL_(theSubmit);
  3418.                 
  3419.                 URL_Struct* theURL = NET_CreateURLStruct((char*)theSubmit->action, NET_DONT_RELOAD); 
  3420.                 ThrowIfNULL_(theURL);
  3421.                 
  3422.                 cstring theCurrentURL = mContext->GetCurrentURL();
  3423.                 if (theCurrentURL.length() > 0)
  3424.                     theURL->referer = XP_STRDUP(theCurrentURL);
  3425.  
  3426.                 if (NET_AddLOSubmitDataToURLStruct(theSubmit, theURL))
  3427.                     theDispatcher->DispatchToView(theSponsorContext, theURL, FO_CACHE_AND_PRESENT, inMakeNewWindow, 1010, inDelay);
  3428.  
  3429.                 LO_FreeSubmitData(theSubmit);
  3430.                 }
  3431.             catch (...)
  3432.                 {
  3433.                 LO_FreeSubmitData(theSubmit);
  3434.                 throw;            
  3435.                 }*/
  3436.                         // ET_SendEvent now takes a JSEvent struct instead of an int type
  3437.             ImageFormSubmitData* data = new ImageFormSubmitData;
  3438.             LO_ImageStruct* image = &inClickRecord.mElement->lo_image;
  3439.             data->lo_image = image;
  3440.             // set the coordinates relative to the image (not the document), taking into account the border.
  3441.             data->x = inClickRecord.mImageWhere.h - (image->x + image->x_offset + image->border_width);
  3442.             data->y = inClickRecord.mImageWhere.v - (image->y + image->y_offset + image->border_width);
  3443.             JSEvent* event = XP_NEW_ZAP(JSEvent);
  3444.             if (event)
  3445.                 {
  3446.                 event->type = EVENT_SUBMIT;
  3447.                 // The code above will get executed in MochaFormSubmitCallback
  3448.                 ET_SendEvent(*mContext,
  3449.                              inClickRecord.mElement,
  3450.                              event,
  3451.                              MochaImageFormSubmitCallback,
  3452.                              data);
  3453.                 }
  3454.             }
  3455.             break;
  3456.  
  3457.         case eImageIcon:
  3458.             {
  3459.             if (!inSaveToDisk)
  3460.                 {
  3461.                 HandleImageIconClick(inClickRecord);
  3462.                 }
  3463.             else
  3464.                 {
  3465.                 URL_Struct* theURL = NET_CreateURLStruct(inClickRecord.mClickURL, NET_DONT_RELOAD);
  3466.                 if (theURL == NULL)
  3467.                     break;
  3468.  
  3469.                 cstring theReferer = theURL->address;
  3470.                 if (theReferer.length() > 0)
  3471.                     theURL->referer = XP_STRDUP(theReferer);
  3472.  
  3473.                 if (inMakeNewWindow)
  3474.                     {
  3475.                     theURL->window_target = XP_STRDUP("");
  3476.                     if (XP_STRCMP(inClickRecord.mWindowTarget, "") != 0)
  3477.                         theURL->window_target = XP_STRDUP(inClickRecord.mWindowTarget);
  3478.                     else
  3479.                         theURL->window_target = NULL;
  3480.                     }
  3481.     
  3482.                 DispatchURL(theURL, theSponsorContext, false, inMakeNewWindow);
  3483.                 }
  3484.             }
  3485.             break;
  3486.  
  3487.         case eNone:
  3488.             {
  3489.             // 97-06-10 pkc -- Hack to dispatch URL's after mocha is done loading image.
  3490.             // If oldClickKind is eImageAnchor, then we're in the case where mocha is loading
  3491.             // an image over a current image.
  3492.             if (oldClickKind == eImageAnchor && (((char*)inClickRecord.mClickURL) != NULL))
  3493.                 {
  3494.                 URL_Struct* theURL = NET_CreateURLStruct(inClickRecord.mClickURL, NET_DONT_RELOAD);
  3495.                 ThrowIfNULL_(theURL);
  3496.  
  3497.                 cstring theReferer = mContext->GetCurrentURL();
  3498.                 if (theReferer.length() > 0)
  3499.                     theURL->referer = XP_STRDUP(theReferer);
  3500.  
  3501.                 if (inMakeNewWindow)
  3502.                     theURL->window_target = XP_STRDUP("");
  3503.                 else
  3504.                     {
  3505.                     if (XP_STRCMP(inClickRecord.mWindowTarget, "") != 0)
  3506.                         theURL->window_target = XP_STRDUP(inClickRecord.mWindowTarget);
  3507.                     else
  3508.                         theURL->window_target = NULL;
  3509.                     }
  3510.                 // Call DispatchToView with inDelay = true and inWaitingForMochaImageLoad = true
  3511. //                theDispatcher->DispatchToView(theSponsorContext, theURL, FO_CACHE_AND_PRESENT, inMakeNewWindow, 1010, true, true, true);
  3512.                 CURLDispatcher::DispatchURL(theURL, theSponsorContext, true, inMakeNewWindow, BrowserWindow_ResID, true, FO_CACHE_AND_PRESENT, true);
  3513.                 }
  3514.             }
  3515.             break;
  3516.  
  3517.     
  3518.         default:
  3519.         case eWaiting:
  3520.             Assert_(false);
  3521.             break;
  3522.         }
  3523. }
  3524.  
  3525. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3526. void CHTMLView::Click(SMouseDownEvent &inMouseDown)
  3527. //    Special processing for drag-n-drop stuff, not to select the window until mouse up.
  3528. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3529. {
  3530.     LPane *clickedPane = FindSubPaneHitBy(inMouseDown.wherePort.h,
  3531.                                           inMouseDown.wherePort.v);
  3532.     if ( clickedPane != nil )
  3533.         clickedPane->Click(inMouseDown);
  3534.     else
  3535.     {
  3536.         if ( !inMouseDown.delaySelect ) LCommander::SwitchTarget(this);
  3537.         StValueChanger<Boolean> change(inMouseDown.delaySelect, false);
  3538.             // For drag-n-drop functionality
  3539.         LPane::Click(inMouseDown);    //   will process click on this View
  3540.     }
  3541. } // CHTMLView::Click
  3542.  
  3543. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3544. //    Ñ    
  3545. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3546.  
  3547. void CHTMLView::HandleImageIconClick(CHTMLClickRecord& inClickRecord)
  3548. {
  3549.     char* url = inClickRecord.mImageURL;
  3550.     // check to see if the click was on the attachment or SMime icon
  3551.     if (!XP_STRNCMP(url, "internal-smime", 14) || !XP_STRNCMP(url, "internal-attachment-icon", 24) )
  3552.     {
  3553.         URL_Struct* theURL = NET_CreateURLStruct(inClickRecord.mClickURL, NET_DONT_RELOAD);
  3554.         mContext->SwitchLoadURL(theURL, FO_CACHE_AND_PRESENT);
  3555.     }
  3556.     else
  3557.         PostDeferredImage(url);
  3558. }
  3559.  
  3560. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3561. //    Ñ    
  3562. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3563.  
  3564.     //
  3565.  
  3566. void CHTMLView::ClickDragLink(
  3567.     const SMouseDownEvent&     inMouseDown,
  3568.     LO_Element*             inElement)
  3569. {    
  3570.     FocusDraw();
  3571.  
  3572.     Rect theGlobalRect;
  3573.     Boolean bVisible = CalcElementPosition(inElement, theGlobalRect);
  3574.     ::LocalToGlobal(&topLeft(theGlobalRect));
  3575.     ::LocalToGlobal(&botRight(theGlobalRect));
  3576.  
  3577.     // account for image border
  3578.     Int32 borderWidth = 0;
  3579.     
  3580.     if (inElement->type == LO_IMAGE)
  3581.         borderWidth = inElement->lo_image.border_width;
  3582.  
  3583.     ::OffsetRect(&theGlobalRect, borderWidth, borderWidth);
  3584.     
  3585.     StValueChanger<LO_Element*>    theValueChanger(mDragElement, inElement);
  3586.     
  3587.     CDragURLTask theDragTask(inMouseDown.macEvent, theGlobalRect, *this);
  3588.     
  3589.     OSErr theErr = ::SetDragSendProc(theDragTask.GetDragReference(), mSendDataUPP, (LDragAndDrop*)this);
  3590.     ThrowIfOSErr_(theErr);
  3591.     
  3592.     theDragTask.DoDrag();
  3593. }
  3594.  
  3595. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3596. //    Ñ    
  3597. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3598.  
  3599. void CHTMLView::ClickTrackEdge(
  3600.     const SMouseDownEvent&    inMouseDown,
  3601.     CHTMLClickRecord&        inClickRecord)
  3602. {
  3603. // ÑÑÑ FIX ME!!! we need to stop the blinkers
  3604.  
  3605.     Rect limitRect, slopRect;
  3606.     Int16 axis;
  3607.     
  3608.     // Figure out the outline of the region. This should come from layout somehow
  3609.     Point topRgn = inMouseDown.whereLocal;        
  3610.     Point bottomRgn = inMouseDown.whereLocal;
  3611.     if ( inClickRecord.mIsVerticalEdge )    // Edge is vertical, we can drag horizontally.
  3612.         {
  3613.         topRgn.v = inClickRecord.mElement->lo_edge.y;
  3614.         bottomRgn.v = topRgn.v + inClickRecord.mElement->lo_edge.height;
  3615.         topRgn.h = inClickRecord.mElement->lo_edge.x;
  3616.         bottomRgn.h = topRgn.h + inClickRecord.mElement->lo_edge.width;
  3617.         limitRect.left = inClickRecord.mEdgeLowerBound;
  3618.         limitRect.right = inClickRecord.mEdgeUpperBound;
  3619.         limitRect.top = topRgn.v;
  3620.         limitRect.bottom = bottomRgn.v;
  3621.         slopRect = limitRect;
  3622.         axis = hAxisOnly;
  3623.         }
  3624.     else
  3625.         {
  3626.         topRgn.h = inClickRecord.mElement->lo_edge.x;
  3627.         bottomRgn.h = topRgn.h + inClickRecord.mElement->lo_edge.width;
  3628.         topRgn.v = inClickRecord.mElement->lo_edge.y;
  3629.         bottomRgn.v = topRgn.v + inClickRecord.mElement->lo_edge.height;
  3630.         limitRect.top = inClickRecord.mEdgeLowerBound;
  3631.         limitRect.bottom = inClickRecord.mEdgeUpperBound;
  3632.         limitRect.left = topRgn.h;
  3633.         limitRect.right = bottomRgn.h;
  3634.         slopRect = limitRect;
  3635.         axis = vAxisOnly;
  3636.         }
  3637.     
  3638.     Rect    tmp;
  3639.     tmp.top = topRgn.v;
  3640.     tmp.left = topRgn.h;
  3641.     tmp.right = bottomRgn.h;
  3642.     tmp.bottom = bottomRgn.v;
  3643.     
  3644.     StRegion        rgn(tmp);
  3645.     FocusDraw();
  3646.  
  3647.     long movedBy = ::DragGrayRgn(rgn, inMouseDown.whereLocal, &limitRect, &slopRect, axis, NULL);
  3648.     if ( HiWord( movedBy ) != -32768 )    //    We have a valid movement
  3649.         {
  3650.         // We set a null clip so we don't flicker and flash
  3651.         StClipRgnState theSavedClip(NULL);
  3652.  
  3653.         LocalToPortPoint(topLeft(tmp));
  3654.         LocalToPortPoint(botRight(tmp));
  3655.         ::InsetRect(&tmp, -2, -2);
  3656.         InvalPortRect(&tmp);
  3657.  
  3658.         Point newPoint;
  3659.         Rect newRect = tmp;
  3660.         if ( axis == vAxisOnly )
  3661.             {
  3662.             newPoint.v = inMouseDown.whereLocal.v + HiWord(movedBy);
  3663.             ::OffsetRect(&newRect, 0, HiWord(movedBy));
  3664.             }
  3665.         else
  3666.             {
  3667.             newPoint.h = inMouseDown.whereLocal.h + LoWord( movedBy );
  3668.             ::OffsetRect(&newRect, LoWord(movedBy), 0);
  3669.             }
  3670.  
  3671.         if (inClickRecord.mIsVerticalEdge)
  3672.             ::InsetRect(&newRect, -RectWidth(limitRect), -3);
  3673.         else
  3674.             ::InsetRect(&newRect, -3, -RectHeight(limitRect));
  3675.  
  3676.         ::UnionRect(&tmp, &newRect, &tmp); 
  3677.  
  3678.             {
  3679.                 StClipRgnState theClipSaver(NULL);
  3680.                 // 97-06-11 pkc -- Set mDontAddGridEdgeToList to true so that DisplayEdge
  3681.                 // doesn't add this grid edge into list and DrawGridEdge doesn't draw
  3682.                 // because LO_MoveGridEdge will call DisplayEdge
  3683.                 mDontAddGridEdgeToList = true;
  3684.                 LO_MoveGridEdge(*mContext, (LO_EdgeStruct*)inClickRecord.mElement, newPoint.h, newPoint.v );
  3685.                 mDontAddGridEdgeToList = false;
  3686.             }
  3687.         
  3688.         InvalPortRect( &tmp );
  3689.         }
  3690.  
  3691. // FIX ME!!! we need to start the blinkers
  3692. }
  3693.  
  3694. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3695. inline void CHTMLView::LocalToLayerCoordinates(
  3696.     const XP_Rect& inBoundingBox,
  3697.     Point inWhereLocal,
  3698.     SPoint32& outWhereLayer) const
  3699. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3700. {
  3701.     LocalToImagePoint(inWhereLocal, outWhereLayer);
  3702.     // Convert from image to layer coordinates
  3703.     outWhereLayer.h -= inBoundingBox.left;
  3704.     outWhereLayer.v -= inBoundingBox.top;
  3705. }
  3706.  
  3707. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3708. Boolean CHTMLView::ClickTrackSelection(
  3709.     const SMouseDownEvent&    inMouseDown,
  3710.     CHTMLClickRecord&        inClickRecord)
  3711. //    Ñ Returns true if a selection was started and extended.
  3712. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3713. {
  3714. // FIX ME!!! we need to stop the blinkers
  3715.         
  3716.     ::SetCursor(*GetCursor(iBeamCursor));
  3717.     XP_Rect theBoundingBox;
  3718.     CL_GetLayerBboxAbsolute(inClickRecord.mLayer, &theBoundingBox);
  3719.  
  3720.     // Convert from image to layer coordinates
  3721.     SPoint32 theImagePointStart;
  3722.     LocalToLayerCoordinates(theBoundingBox, inMouseDown.whereLocal, theImagePointStart);
  3723.  
  3724.     SPoint32 theImagePointEnd = theImagePointStart;
  3725.  
  3726.     if ((inMouseDown.macEvent.modifiers & shiftKey) && !inClickRecord.IsClickOnAnchor())
  3727.         LO_ExtendSelection(*mContext, theImagePointStart.h, theImagePointStart.v);
  3728.     else
  3729.         LO_StartSelection(*mContext, theImagePointStart.h, theImagePointStart.v, inClickRecord.mLayer);
  3730.  
  3731.     // track mouse till we are done
  3732.     Boolean didTrackSelection = false;
  3733.     while (::StillDown())
  3734.     {
  3735.         Point qdWhere;
  3736.         FocusDraw();    // so that we get coordinates right
  3737.         ::GetMouse(&qdWhere);
  3738.         if (AutoScrollImage(qdWhere))
  3739.         {    
  3740.             Rect theFrame;
  3741.             CalcLocalFrameRect(theFrame);
  3742.             if (qdWhere.v < theFrame.top)
  3743.                 qdWhere.v = theFrame.top;
  3744.             else if (qdWhere.v > theFrame.bottom)
  3745.                 qdWhere.v = theFrame.bottom;
  3746.         }
  3747.     
  3748.         SPoint32 theTrackImagePoint;
  3749.         LocalToLayerCoordinates(theBoundingBox, qdWhere, theTrackImagePoint);
  3750.  
  3751.         if (theTrackImagePoint.v != theImagePointEnd.v
  3752.         || theTrackImagePoint.h != theImagePointEnd.h)
  3753.         {
  3754.             didTrackSelection = true;
  3755.             LO_ExtendSelection(*mContext, theTrackImagePoint.h, theTrackImagePoint.v);
  3756.         }
  3757.         theImagePointEnd = theTrackImagePoint;
  3758.  
  3759.         // Ñ╩idling
  3760.         ::SystemTask();
  3761.         EventRecord dummy;
  3762.         ::WaitNextEvent(0, &dummy, 5, NULL);
  3763.     }
  3764.             
  3765.     LO_EndSelection(*mContext);
  3766.     return didTrackSelection;
  3767.     
  3768. // FIX ME!!! we need to restart the blinkers
  3769. } // CHTMLView::ClickTrackSelection
  3770.  
  3771. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3772. void CHTMLView::EventMouseUp(const EventRecord& inMouseUp)
  3773. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3774. {
  3775.     // FocusDraw() && SwitchTarget(this) appears to be a copy/paste error from ClickSelf.
  3776.     // We will dispatch a mouse up only if a mouse down has been dispatched. Otherwise there
  3777.     // would be a possibility of this getting called if a click selects the window containing
  3778.     // this view but does not perform a mouse down.
  3779.     if (mContext != NULL && mWaitMouseUp) /* &&  FocusDraw() && SwitchTarget(this) */
  3780.         {
  3781.         SPoint32        firstP;
  3782.         Point            localPt = inMouseUp.where;
  3783.     
  3784.         mWaitMouseUp = false;
  3785.         GlobalToPortPoint( localPt);    // 1997-02-27 mjc
  3786.         PortToLocalPoint( localPt );
  3787.         LocalToImagePoint(    localPt, firstP );
  3788.         
  3789.         if (mCompositor != NULL)
  3790.             {
  3791.             fe_EventStruct    fe_event;
  3792.             fe_event.portPoint = inMouseUp.where;
  3793.             //fe_event.event =  (void *)&inMouseUp;
  3794.             fe_event.event.macEvent = inMouseUp;     // 1997-02-27 mjc
  3795.         
  3796.             CL_Event        event;
  3797.             event.type = CL_EVENT_MOUSE_BUTTON_UP;
  3798.             event.fe_event = (void *)&fe_event;
  3799.             event.fe_event_size = sizeof(fe_EventStruct); // 1997-02-27 mjc
  3800.             event.x = firstP.h;
  3801.             event.y = firstP.v;
  3802.             event.which = 1;
  3803.             event.modifiers = CMochaHacks::MochaModifiers(inMouseUp.modifiers);
  3804.         
  3805.             CL_DispatchEvent(*mCompositor, &event);    
  3806.             }
  3807.         }
  3808. }
  3809.  
  3810. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3811. //    Ñ    
  3812. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  3813.  
  3814. Boolean CHTMLView::HandleKeyPress( const EventRecord& inKeyEvent )
  3815. {
  3816.     
  3817.     Char16        theChar = inKeyEvent.message & charCodeMask;
  3818.     short         modifiers = inKeyEvent.modifiers & (cmdKey | shiftKey | optionKey | controlKey);
  3819.     SPoint32        firstP;
  3820.     Point            localPt = inKeyEvent.where;
  3821.  
  3822.     GlobalToPortPoint(localPt);
  3823.     PortToLocalPoint( localPt );
  3824.     LocalToImagePoint(    localPt, firstP );
  3825.     
  3826. #ifdef LAYERS
  3827.     if (mCompositor)
  3828.     {
  3829.         // If no one has key event focus, set event focus to the main document.
  3830.         if (CL_IsKeyEventGrabber(*mCompositor, NULL) && CL_GetCompositorRoot(*mCompositor))
  3831.         {
  3832.             CL_GrabKeyEvents(
  3833.                             *mCompositor, 
  3834.                             CL_GetLayerChildByName(
  3835.                                                     CL_GetCompositorRoot(*mCompositor),
  3836.                                                     LO_BODY_LAYER_NAME));
  3837.         }
  3838.         
  3839.         // If there's a compositor and someone has keyboard focus, dispatch the event.
  3840.         if (!CL_IsKeyEventGrabber(*mCompositor, NULL) && (sLastFormKeyPressDispatchTime != inKeyEvent.when)) 
  3841.         {
  3842.             CL_Event        event;
  3843.             fe_EventStruct    fe_event;
  3844.  
  3845.             fe_event.event.macEvent = inKeyEvent; // 1997-02-25 mjc
  3846.  
  3847.             event.data = 0;
  3848.             switch (inKeyEvent.what)
  3849.             {
  3850.                 case keyDown:
  3851.                     event.type = CL_EVENT_KEY_DOWN;
  3852.                     break;
  3853.                 case autoKey:
  3854.                     event.type = CL_EVENT_KEY_DOWN;
  3855.                     event.data = 1; // repeating
  3856.                     break;
  3857.                 case keyUp:
  3858.                     event.type = CL_EVENT_KEY_UP;
  3859.                     break;
  3860.             }
  3861.  
  3862.             event.fe_event = (void *)&fe_event;
  3863.             event.fe_event_size = sizeof(fe_EventStruct);
  3864.             event.x = firstP.h;
  3865.             event.y = firstP.v;
  3866.             event.which = theChar;
  3867.             event.modifiers = CMochaHacks::MochaModifiers(inKeyEvent.modifiers);  // 1997-02-27 mjc
  3868.  
  3869.             CL_DispatchEvent(*mCompositor, &event);
  3870.             return true;
  3871.         }
  3872.         else return HandleKeyPressLayer(inKeyEvent, NULL, firstP);
  3873.     } else
  3874. #endif // LAYERS
  3875.     return HandleKeyPressLayer(inKeyEvent, NULL, firstP);
  3876. }
  3877.  
  3878. Boolean CHTMLView::HandleKeyPressLayer(const EventRecord&    inKeyEvent,
  3879.                                     CL_Layer            *inLayer,
  3880.                                     SPoint32            inLayerWhere )
  3881. {
  3882.     Char16        theChar = inKeyEvent.message & charCodeMask;
  3883.     short         modifiers = inKeyEvent.modifiers & (cmdKey | shiftKey | optionKey | controlKey);
  3884.     Boolean     handled = false;
  3885.     
  3886. #ifdef LAYERS
  3887.     if ((inLayer != NULL) && (sLastFormKeyPressDispatchTime != inKeyEvent.when))
  3888.     {
  3889.         SPoint32     theElementWhere = inLayerWhere;
  3890.         LO_Element* theElement = LO_XYToElement(*mContext, theElementWhere.h, theElementWhere.v, inLayer);
  3891.  
  3892.         if ((theElement != NULL) && 
  3893.             (theElement->type == LO_FORM_ELE))
  3894.         {
  3895.             switch (theElement->lo_form.element_data->type)
  3896.             {
  3897.                 case FORM_TYPE_TEXTAREA:
  3898.                     CFormBigText *bigText = (CFormBigText *)((FormFEData *)theElement->lo_form.element_data->ele_minimal.FE_Data)->fPane->FindPaneByID(formBigTextID);
  3899.                     sLastFormKeyPressDispatchTime = inKeyEvent.when;
  3900.                     handled =  bigText->HandleKeyPress(inKeyEvent);
  3901.                     break;    
  3902.                 case FORM_TYPE_TEXT:
  3903.                 case FORM_TYPE_PASSWORD:
  3904.                     CFormLittleText *text = (CFormLittleText *)((FormFEData *)theElement->lo_form.element_data->ele_minimal.FE_Data)->fPane;
  3905.                     sLastFormKeyPressDispatchTime = inKeyEvent.when;
  3906.                     handled = text->HandleKeyPress(inKeyEvent);
  3907.                     break;
  3908.             }
  3909.         }
  3910.     }
  3911. #endif
  3912.     // forms didn't handle the event
  3913.     if (!handled)
  3914.     {
  3915.         // we may get keyUp events (javascript needs them) but just ignore them - 1997-02-27 mjc
  3916.         if (keyUp == inKeyEvent.what) return TRUE;
  3917.         
  3918.         if ( modifiers == 0 )
  3919.             switch ( theChar & charCodeMask )
  3920.             {
  3921.                 case char_UpArrow:
  3922.                     if ( mScroller && mScroller->HasVerticalScrollbar())
  3923.                         mScroller->VertScroll( kControlUpButtonPart );
  3924.                 return TRUE;
  3925.                 case char_DownArrow:
  3926.                     if ( mScroller && mScroller->HasVerticalScrollbar() )
  3927.                          mScroller->VertScroll( kControlDownButtonPart );
  3928.                 return TRUE;
  3929.                 
  3930.                 // Seems only fair to allow scrolling left and right like the other platforms
  3931.                 case char_LeftArrow:
  3932.                     if ( mScroller && mScroller->HasHorizontalScrollbar())
  3933.                         mScroller->HorizScroll( kControlUpButtonPart );
  3934.                 return TRUE;
  3935.                 case char_RightArrow:
  3936.                     if ( mScroller && mScroller->HasHorizontalScrollbar() )
  3937.                          mScroller->HorizScroll( kControlDownButtonPart );
  3938.                 return TRUE;
  3939.  
  3940.                 case char_PageUp:
  3941.                 case char_Backspace:
  3942.                     if ( mScroller && mScroller->HasVerticalScrollbar())
  3943.                         mScroller->VertScroll( kControlPageUpPart );
  3944.                 return TRUE;
  3945.                 case char_PageDown:
  3946.                 case char_Space:
  3947.                     if ( mScroller && mScroller->HasVerticalScrollbar())
  3948.                         mScroller->VertScroll( kControlPageDownPart );
  3949.                 return TRUE;
  3950.                 case char_Home:
  3951.                     ScrollImageTo( 0, 0, TRUE );
  3952.                 return TRUE;
  3953.                 case char_End:
  3954.                     int32 y;
  3955.                     y = mImageSize.height - mFrameSize.height;
  3956.                     if ( y < 0)
  3957.                         y = 0;
  3958.                     ScrollImageTo( 0, y, TRUE );
  3959.                 return TRUE;
  3960.             }
  3961.         if ( ( modifiers & cmdKey ) == cmdKey )
  3962.             switch ( theChar & charCodeMask )
  3963.             {
  3964.                 case char_UpArrow:
  3965.                     if ( mScroller && mScroller->HasVerticalScrollbar() )
  3966.                         mScroller->VertScroll( kControlPageUpPart );
  3967.                 return TRUE;
  3968.  
  3969.                 case char_DownArrow:
  3970.                     if ( mScroller && mScroller->HasVerticalScrollbar() )
  3971.                         mScroller->VertScroll( kControlPageDownPart );
  3972.                 return TRUE;
  3973.             }
  3974.         if ( ( modifiers & (controlKey | optionKey ) ) == ( controlKey | optionKey ) )
  3975.             switch ( theChar & charCodeMask ) 
  3976.             {
  3977.                 case 'h' - 96:
  3978.                     if ( mScroller )
  3979.                     {
  3980.                         mScroller->ShowScrollbars( FALSE, FALSE );
  3981.                         return TRUE;
  3982.                     }
  3983.                 case 'j' - 96:
  3984.                     if ( mScroller )
  3985.                     {
  3986.                         mScroller->ShowScrollbars( TRUE, TRUE );
  3987.                         return TRUE;
  3988.                     }
  3989.                 case 'k' - 96:
  3990.                     if ( mScroller )
  3991.                     {
  3992.                         mScroller->ShowScrollbars( FALSE, TRUE );
  3993.                         return TRUE;
  3994.                     }
  3995.                 case 'l' - 96:
  3996.                     if ( mScroller )
  3997.                     {
  3998.                         mScroller->ShowScrollbars( TRUE, FALSE );
  3999.                         return TRUE;
  4000.                     }
  4001.             }
  4002.         // Tabbing. We want to shift hyperviews, and not form elements, if we
  4003.         // are going backward from the first form element, or forward from the last one
  4004.         if (theChar == char_Tab)
  4005.         {
  4006.             Boolean retVal;
  4007.  
  4008.             if (mSubCommanders.GetCount() == 0)    // no tabbing, nothing to switch
  4009.                 retVal = LCommander::HandleKeyPress(inKeyEvent);
  4010.             else
  4011.             {
  4012.                 // ÑÑÑ 98/03/26: Because of the new implementation of LTabGroup in Pro2, we get
  4013.                 // stuck in the deepest commander hierarchy and can never get back to the
  4014.                 // toplevel tab group to get to the location bar. This needs to be fixed, but
  4015.                 // not before 3/31. I'm not sure what the right fix is (pinkerton).
  4016.                 LCommander *onDutySub = GetTarget();
  4017.                 if (onDutySub == NULL)
  4018.                 {
  4019.                     LCommander    *newTarget;
  4020.                     mSubCommanders.FetchItemAt(1, newTarget);
  4021.                     SwitchTarget(newTarget);
  4022.                     retVal = TRUE;
  4023.                 }
  4024.                 else
  4025.                 {            
  4026.                     Int32    pos = mSubCommanders.FetchIndexOf(onDutySub);
  4027.                     Boolean backward = (inKeyEvent.modifiers & shiftKey) != 0;
  4028.                     if ((pos == mSubCommanders.GetCount() && !backward)    // If we are the last field,
  4029.                         || (--pos <= 0 && backward))    //
  4030.                     // Do not wrap within the view, use the commander
  4031.                         retVal = LCommander::HandleKeyPress(inKeyEvent);
  4032.                     else
  4033.                         retVal = LTabGroup::HandleKeyPress( inKeyEvent );
  4034.                 }    
  4035.             }
  4036.             return retVal;
  4037.         }
  4038.         return LTabGroup::HandleKeyPress( inKeyEvent );
  4039.     }
  4040.     return handled;
  4041. }
  4042.  
  4043. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4044. // Ñ Callback for cursor handling for new mocha event stuff    
  4045. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4046.  
  4047. // AdjustCursorRecord
  4048. // Used as a Mocha callback structure
  4049. // holds all the information needed to call MochaExecuteClickInLink
  4050. struct AdjustCursorRecord
  4051. {
  4052.     char * mMessage;
  4053.     AdjustCursorRecord(const char * message)
  4054.     {
  4055.         if (message)
  4056.             mMessage = XP_STRDUP( message );
  4057.         else
  4058.             mMessage = NULL;
  4059.     }
  4060.     ~AdjustCursorRecord()
  4061.     {
  4062.         FREEIF( mMessage );
  4063.     }
  4064. };
  4065.  
  4066. // Mocha callback for MochaAdjustCursorRecord
  4067. void MochaAdjustCursorCallback(MWContext * pContext,
  4068.                                LO_Element * lo_element,
  4069.                                int32 lType,
  4070.                                void * whatever,
  4071.                                ETEventStatus status);
  4072. void MochaAdjustCursorCallback(MWContext * pContext,
  4073.                                LO_Element * /* lo_element */,
  4074.                                int32 /* lType */,
  4075.                                void * whatever,
  4076.                                ETEventStatus status)
  4077. {
  4078.     AdjustCursorRecord * p = (AdjustCursorRecord*)whatever;
  4079.     if (status == EVENT_CANCEL)
  4080.     {
  4081.         CNSContext* nsContext = ExtractNSContext(pContext);
  4082.         nsContext->SetStatus(p->mMessage);
  4083.     }
  4084.     delete p;
  4085. }
  4086.  
  4087. // Mocha callback for MochaAdjustCursorRecord
  4088. // Also frees the layout record. Layout record needs to be allocated
  4089. // because of a hack for map areas
  4090. void MochaAdjustCursorCallbackLayoutFree(MWContext * pContext, 
  4091.                                         LO_Element * lo_element, 
  4092.                                         int32 lType, 
  4093.                                         void * whatever, 
  4094.                                         ETEventStatus status);
  4095. void MochaAdjustCursorCallbackLayoutFree(MWContext * pContext, 
  4096.                                         LO_Element * lo_element, 
  4097.                                         int32 lType, 
  4098.                                         void * whatever, 
  4099.                                         ETEventStatus status)
  4100. {
  4101.     MochaAdjustCursorCallback( pContext, lo_element, lType, whatever, status);
  4102.     XP_FREE( lo_element );
  4103. }
  4104.  
  4105.  
  4106. void CHTMLView::AdjustCursorSelf( Point inPortPt, const EventRecord& inMacEvent )
  4107. {
  4108.     // if this page is tied-up, display a watch
  4109.     if ( !IsEnabled() )
  4110.     {
  4111.         ::SafeSetCursor( watchCursor );
  4112.         return;
  4113.     }
  4114.  
  4115.     //  bail if we did not move, saves time and flickering
  4116.     if ( ( inPortPt.h == mOldPoint.h ) && ( inPortPt.v == mOldPoint.v ) )
  4117.         return;
  4118.  
  4119.     mOldPoint.h = inPortPt.h;
  4120.     mOldPoint.v = inPortPt.v;
  4121.  
  4122.     Point            localPt = inPortPt;
  4123.     SPoint32        firstP;
  4124.     
  4125.     PortToLocalPoint( localPt );
  4126.     LocalToImagePoint(    localPt, firstP );
  4127.     if (mCompositor != NULL) {
  4128.         CL_Event        event;
  4129.         fe_EventStruct    fe_event;
  4130.         
  4131.         fe_event.portPoint = inPortPt;
  4132.         //fe_event.event =  (void *)&inMacEvent;
  4133.         fe_event.event.macEvent = inMacEvent; // 1997-02-27 mjc
  4134.  
  4135.         event.type = CL_EVENT_MOUSE_MOVE;
  4136.         event.fe_event = (void *)&fe_event;
  4137.         event.fe_event_size = sizeof(fe_EventStruct); // 1997-02-27 mjc
  4138.         event.x = firstP.h;
  4139.         event.y = firstP.v;
  4140.         event.which = 1;
  4141.         event.modifiers = 0;
  4142.         
  4143.         CL_DispatchEvent(*mCompositor, &event);    
  4144.     }
  4145.     else
  4146.         AdjustCursorSelfForLayer(inPortPt, inMacEvent, NULL, firstP);
  4147. }
  4148.  
  4149. void CHTMLView::AdjustCursorSelfForLayer( Point inPortPt, const EventRecord& inMacEvent, 
  4150.                                           CL_Layer *layer, SPoint32 inLayerPt )
  4151. {
  4152. // With LAYERS, the original method gets the compositor to dispatch
  4153. // the event, which is then dealt with (in this method) on a per-layer
  4154. // basis.
  4155.     
  4156.     // find the element the cursor is above, 
  4157.     SPoint32        firstP;
  4158.     LO_Element*     element;    
  4159.     
  4160.     PortToLocalPoint( inPortPt );
  4161.     firstP = inLayerPt;
  4162.  
  4163.     FocusDraw();                                // Debugging only
  4164.     
  4165.     element = LO_XYToElement( *mContext, firstP.h, firstP.v, layer );
  4166.  
  4167.     //
  4168.     // Send MouseLeave events for layout elements
  4169.     // and areas of client-side image maps.
  4170.     //
  4171.  
  4172.     if (!CMochaHacks::IsMouseOverElement(element))
  4173.         CMochaHacks::SendOutOfElementEvent(*mContext, layer, firstP); // add where parameter - mjc
  4174.     
  4175.     //
  4176.     // If cursor is over blank space, reset and bail
  4177.     //
  4178.     // pkc (6/5/96) If there is a defaultStatus string, don't clear status area
  4179.     if ( element == NULL && mContext->GetDefaultStatus() == NULL )
  4180.     {
  4181.         CMochaHacks::SetMouseOverElement(NULL);
  4182.         CMochaHacks::ResetMochaMouse();
  4183.         ::SetCursor( &UQDGlobals::GetQDGlobals()->arrow );
  4184.         mContext->SetStatus(CStr255::sEmptyString);
  4185.         mOldEleID = -1;
  4186.         return;
  4187.     }
  4188.             
  4189.     
  4190.     //
  4191.     // If cursor is over same element as last time and that element
  4192.     // is not a client-side image map (sMouseOverMapArea != NULL), then
  4193.     // we're done
  4194.     //
  4195.     if (element
  4196.         && element->lo_any.ele_id == mOldEleID
  4197.         && !CMochaHacks::GetMouseOverMapArea() )
  4198.         return;    
  4199.  
  4200.     cstring anchor, location;
  4201.     CHTMLClickRecord cr(inPortPt, firstP, mContext, element, layer);
  4202.  
  4203.     if ( cr.IsAnchor() && !( inMacEvent.modifiers & shiftKey ) )
  4204.     {
  4205.         // tj (4/29/96): I belive this code forces us to recompute
  4206.         // every time in the case of images
  4207.         //
  4208.         // (5/2/96): Don't set the element to NULL if its an image.
  4209.         // We need to absolutely know if we're over the same image
  4210.         // the next time through this call.
  4211.         //
  4212.         // We can use mOldEleID to force a redisplay of status for
  4213.         // images (image map coords).
  4214.         //
  4215.         if ( ( element->type == LO_IMAGE &&
  4216.                 ( element->lo_image.image_attr->attrmask & LO_ATTR_ISMAP )  ) || 
  4217.             ( cr.mClickKind == eImageIcon ) ) 
  4218.             mOldEleID = -1;
  4219.         else 
  4220.             mOldEleID = element->lo_any.ele_id;
  4221.         
  4222.         // 97-06-21 pkc -- Also save MWContext along with element because if we mouse out
  4223.         // and we switch frames, the mContext when we send the mouseout event is NOT the same
  4224.         // one that contains the LO_Element.
  4225.         CMochaHacks::SetMouseOverElement(element, *mContext);        
  4226.         location = (cr.mClickKind == eImageAnchor) ? cr.mImageURL : cr.mClickURL; 
  4227.         //
  4228.         // Handle changes in client-side map area
  4229.         //     
  4230.         if (!CMochaHacks::IsMouseOverMapArea(cr.mAnchorData))
  4231.         {
  4232.             // leave the old area
  4233. //            if ( CFrontApp::sMouseOverMapArea )
  4234. //                LM_SendMouseOutOfAnchor( *mContext, CFrontApp::sMouseOverMapArea );
  4235.             CMochaHacks::SendOutOfMapAreaEvent(*mContext, layer, firstP); // add where parameter - mjc                
  4236.             CMochaHacks::SetMouseOverMapArea(cr.mAnchorData);
  4237.                         
  4238.             // If the mouseover handler returns true, then 
  4239.             // we don't change the location in the status filed
  4240.             //
  4241. //            if ( CFrontApp::sMouseOverMapArea ) 
  4242. //                showLocation = ! LM_SendMouseOverAnchor( *mContext, CFrontApp::sMouseOverMapArea );
  4243.             if (CMochaHacks::GetMouseOverMapArea())
  4244.             {
  4245.                 LO_Element * el = XP_NEW_ZAP(LO_Element);    // Need to fake the element, ask chouck for details
  4246.                 el->type = LO_TEXT;
  4247.                 el->lo_text.anchor_href = CMochaHacks::GetMouseOverMapArea();
  4248.                 el->lo_text.text = el->lo_text.anchor_href->anchor; // for js freed element test
  4249.                 AdjustCursorRecord * r = new AdjustCursorRecord(location);
  4250.                 // ET_SendEvent now takes a JSEvent struct instead of a int type
  4251.                 JSEvent* event = XP_NEW_ZAP(JSEvent);
  4252.                 if (event)
  4253.                 {
  4254.                     event->type = EVENT_MOUSEOVER;
  4255.                     event->x = firstP.h; // layer-relative coordinates - mjc
  4256.                     event->y = firstP.v;
  4257.                     event->docx = event->x + CL_GetLayerXOrigin(layer);
  4258.                     event->docy = event->y + CL_GetLayerYOrigin(layer);
  4259.                     
  4260.                     Point screenPt;
  4261.                     ImageToAvailScreenPoint(firstP, screenPt);
  4262.                     event->screenx = screenPt.h;
  4263.                     event->screeny = screenPt.v;
  4264.                     
  4265.                     event->layer_id = LO_GetIdFromLayer(*mContext, layer); // 1997-03-02 mjc
  4266.                     ET_SendEvent( *mContext, el, event, MochaAdjustCursorCallbackLayoutFree, r );
  4267.                 }
  4268.             }
  4269.         }
  4270.             
  4271.         //
  4272.         // Only send mouseover for the layout element if the cursor
  4273.         // is not over a client-side map area
  4274.         //
  4275.         if ( !CMochaHacks::GetMouseOverMapArea() )
  4276.         {
  4277. //            showLocation = !LM_SendMouseOver( *mContext, element );
  4278.             AdjustCursorRecord * r = new AdjustCursorRecord(location);
  4279.             // ET_SendEvent now takes a JSEvent struct instead of a int type
  4280.             JSEvent* event = XP_NEW_ZAP(JSEvent);
  4281.             if (event)
  4282.             {
  4283.                 event->type = EVENT_MOUSEOVER;
  4284.                 event->x = firstP.h; // layer-relative coordinates - mjc
  4285.                 event->y = firstP.v;
  4286.                 event->docx = event->x + CL_GetLayerXOrigin(layer);
  4287.                 event->docy = event->y + CL_GetLayerYOrigin(layer);
  4288.                 
  4289.                 Point screenPt;
  4290.                 ImageToAvailScreenPoint(firstP, screenPt);
  4291.                 event->screenx = screenPt.h;
  4292.                 event->screeny = screenPt.v;
  4293.                 
  4294.                 event->layer_id = LO_GetIdFromLayer(*mContext, layer); // 1997-03-02 mjc
  4295.                 ET_SendEvent( *mContext, element, event, MochaAdjustCursorCallback, r );
  4296.             }
  4297.         }
  4298.         
  4299.         ::SafeSetCursor(curs_Hand);
  4300.         return;
  4301.     }
  4302.     else if ( cr.IsEdge() )
  4303.     {
  4304.         ::SafeSetCursor( (cr.mIsVerticalEdge) ? curs_HoriDrag : curs_VertDrag );
  4305. /*    97-06-11 pkc -- what in blue blazes is all this code for?    
  4306.         mOldEleID = -1;
  4307.         {
  4308.             FocusDraw();    // Debugging only
  4309.             Rect limitRect, slopRect;
  4310.             int axis;
  4311.             StRegion rgn;
  4312.             
  4313.             // Figure out the outline of the region. This should come from layout somehow
  4314.             Point topRgn = inPortPt;        
  4315.             Point bottomRgn =  inPortPt;
  4316.             if ( cr.mIsVerticalEdge )    // Edge is vertical, we can drag horizontally.
  4317.             {
  4318.                 topRgn.v = element->lo_edge.y;
  4319.                 bottomRgn.v = topRgn.v + element->lo_edge.height;
  4320.                 topRgn.h = element->lo_edge.x;
  4321.                 bottomRgn.h = topRgn.h + element->lo_edge.width;
  4322.                 limitRect.left = cr.mEdgeLowerBound;
  4323.                 limitRect.right = cr.mEdgeUpperBound;
  4324.                 limitRect.top = topRgn.v;
  4325.                 limitRect.bottom = bottomRgn.v;
  4326.                 slopRect = limitRect;
  4327.                 axis = hAxisOnly;
  4328.             }
  4329.             else
  4330.             {
  4331.                 topRgn.h = element->lo_edge.x;
  4332.                 bottomRgn.h = topRgn.h + element->lo_edge.width;
  4333.                 topRgn.v = element->lo_edge.y;
  4334.                 bottomRgn.v = topRgn.v + element->lo_edge.height;
  4335.                 limitRect.top = cr.mEdgeLowerBound;
  4336.                 limitRect.bottom = cr.mEdgeUpperBound;
  4337.                 limitRect.left = topRgn.h;
  4338.                 limitRect.right = bottomRgn.h;
  4339.                 slopRect = limitRect;
  4340.                 axis = vAxisOnly;
  4341.             }
  4342.             OpenRgn();
  4343. //            ShowPen();
  4344.             MoveTo(topRgn.h, topRgn.v);
  4345.             LineTo(bottomRgn.h, topRgn.v);    // Framing of the rect
  4346.             LineTo(bottomRgn.h, bottomRgn.v);
  4347.             LineTo(topRgn.h, bottomRgn.v);
  4348.             LineTo(topRgn.h, topRgn.v);
  4349.             CloseRgn(rgn.mRgn);
  4350. //            FillRgn(rgn.mRgn, &qd.black);
  4351. //            FrameRect(&limitRect);
  4352.         }*/
  4353.         return;
  4354.     }
  4355.     
  4356.     
  4357.     //
  4358.     // The cursor is over blank space
  4359.     //
  4360.     
  4361.     // If we were previously over a map area, leave the old area
  4362.  
  4363.     if (CMochaHacks::GetMouseOverMapArea() != NULL) {
  4364. //        LM_SendMouseOutOfAnchor(*mContext, CFrontApp::sMouseOverMapArea);
  4365.         LO_Element * el = XP_NEW_ZAP(LO_Element);    // Need to fake the element, ask chouck for details
  4366.         el->type = LO_TEXT;
  4367.         el->lo_text.anchor_href = CMochaHacks::GetMouseOverMapArea();
  4368.         if (el->lo_text.anchor_href->anchor)
  4369.             el->lo_text.text = el->lo_text.anchor_href->anchor; // to pass js freed element check
  4370.         AdjustCursorRecord * r = new AdjustCursorRecord(location);
  4371.         // ET_SendEvent now takes a JSEvent struct instead of a int type
  4372.         JSEvent* event = XP_NEW_ZAP(JSEvent);
  4373.         if (event)
  4374.         {
  4375.             event->type = EVENT_MOUSEOUT;
  4376.             event->x = firstP.h; // layer-relative coordinates - mjc
  4377.             event->y = firstP.v;
  4378.             event->docx = event->x + CL_GetLayerXOrigin(layer);
  4379.             event->docy = event->y + CL_GetLayerYOrigin(layer);
  4380.             
  4381.             Point screenPt;
  4382.             ImageToAvailScreenPoint(firstP, screenPt);
  4383.             event->screenx = screenPt.h;
  4384.             event->screeny = screenPt.v;
  4385.             event->layer_id = LO_GetIdFromLayer(*mContext, layer); // 1997-03-02 mjc
  4386.             ET_SendEvent( *mContext, el, event, MochaAdjustCursorCallbackLayoutFree, r );
  4387.         }
  4388.         CMochaHacks::SetMouseOverMapArea(NULL);
  4389.     }
  4390.     
  4391.     ::SetCursor( &UQDGlobals::GetQDGlobals()->arrow );
  4392.     mOldEleID = -1;
  4393.     mContext->SetStatus( (    mContext->GetDefaultStatus() != NULL) ? 
  4394.                             mContext->GetDefaultStatus() :
  4395.                             CStr255::sEmptyString );
  4396. }
  4397.  
  4398.  
  4399.  
  4400.  
  4401.  
  4402.  
  4403.  
  4404. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4405. //
  4406. #pragma mark --- DRAG AND DROP ---
  4407. //
  4408. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4409.  
  4410.  
  4411.  
  4412.  
  4413. void CHTMLView::DoDragSendData(FlavorType inFlavor,
  4414.                                 ItemReference inItemRef,
  4415.                                 DragReference inDragRef)
  4416. {
  4417.     OSErr            theErr;
  4418.     cstring            theUrl;
  4419.         
  4420.     // Get the URL of the thing we're dragging...
  4421.     if (mDragElement->type == LO_IMAGE)
  4422.     {
  4423.         theUrl = GetURLFromImageElement(mContext, (LO_ImageStruct*) mDragElement);        // do this so we can get name of non-anchor images
  4424.     }
  4425.     else
  4426.     {
  4427.         PA_Block anchor;
  4428.         XP_ASSERT(mDragElement->type == LO_TEXT);
  4429.          anchor = mDragElement->lo_text.anchor_href->anchor;
  4430.          PA_LOCK (theUrl, char*, anchor);
  4431.         PA_UNLOCK(anchor);    
  4432.     }
  4433.      
  4434.          // Now send the data    
  4435.     switch (inFlavor)
  4436.     {
  4437.             // Just send the URL text
  4438.         case 'TEXT':
  4439.         {
  4440.             theErr = ::SetDragItemFlavorData(inDragRef, inItemRef, inFlavor, theUrl, strlen(theUrl), 0);
  4441.             ThrowIfOSErr_ (theErr);
  4442.             break;
  4443.         }
  4444.          
  4445.             // Send the image as a PICT
  4446.         case 'PICT':
  4447.         {
  4448.             Assert_(mDragElement->type == LO_IMAGE);
  4449.             PicHandle thePicture = ConvertImageElementToPICT((LO_ImageStruct_struct*) mDragElement);
  4450.             ThrowIfNULL_(thePicture);
  4451.             
  4452.                 {
  4453.                     StHandleLocker theLock((Handle)thePicture);
  4454.                     theErr = ::SetDragItemFlavorData(inDragRef, inItemRef, inFlavor, *thePicture, GetHandleSize((Handle)thePicture), 0);
  4455.                     ThrowIfOSErr_(theErr);
  4456.                 }
  4457.                         
  4458.             ::KillPicture(thePicture);
  4459.             break;
  4460.         }
  4461.         
  4462.         case emBookmarkFileDrag:
  4463.         {
  4464.                 // Get the target drop location
  4465.             AEDesc dropLocation;
  4466.             
  4467.             theErr = ::GetDropLocation(inDragRef, &dropLocation);
  4468.             //ThrowIfOSErr_(theErr);    
  4469.             if (theErr != noErr)
  4470.                 return;
  4471.             
  4472.                 // Get the directory ID and volume reference number from the drop location
  4473.             SInt16     volume;
  4474.             SInt32     directory;
  4475.             
  4476.             theErr = GetDropLocationDirectory(&dropLocation, &directory, &volume);
  4477.             //ThrowIfOSErr_(theErr);    
  4478.         
  4479.                 // Ok, this is a hack, and here's why:  This flavor type is sent with the FlavorFlag 'flavorSenderTranslated' which
  4480.                 // means that this send data routine will get called whenever someone accepts this flavor.  The problem is that 
  4481.                 // it is also called whenever someone calls GetFlavorDataSize().  This routine assumes that the drop location is
  4482.                 // something HFS related, but it's perfectly valid for something to query the data size, and not be a HFS
  4483.                 // derrivative (like the text widget for example).
  4484.                 // So, if the coercion to HFS thingy fails, then we just punt to the textual representation.
  4485.             if (theErr == errAECoercionFail)
  4486.             {
  4487.                 theErr = ::SetDragItemFlavorData(inDragRef, inItemRef, inFlavor, theUrl, strlen(theUrl), 0);
  4488.                 return;
  4489.             }
  4490.     
  4491.             if (theErr != noErr)
  4492.                 return;
  4493.             if (mDragElement->type == LO_IMAGE && theUrl == "")
  4494.                 break;
  4495.  
  4496.             URL_Struct*        request;        
  4497.             request = NET_CreateURLStruct(theUrl, NET_DONT_RELOAD);
  4498.                 // Combine with the unique name to make an FSSpec to the new file
  4499.             FSSpec        prototypeFilespec;
  4500.             FSSpec        locationSpec;
  4501.             prototypeFilespec.vRefNum = volume;
  4502.             prototypeFilespec.parID = directory;
  4503.             CStr31 filename;
  4504.             Boolean isMailAttachment = false;
  4505. #ifdef MOZ_MAIL_NEWS
  4506.             isMailAttachment = XP_STRSTR( request->address , "?part=") || XP_STRSTR( request->address, "&part=");
  4507.             if ( isMailAttachment ) 
  4508.             {
  4509.                 CHTMLView::GetDefaultFileNameForSaveAs( request, filename);
  4510.             }
  4511.             else
  4512. #endif // MOZ_MAIL_NEWS
  4513.             {
  4514.                 filename = CFileMgr::FileNameFromURL( request->address );
  4515.                 //GetDefaultFileNameForSaveAs( request , filename );
  4516.             }
  4517.             
  4518.             //theErr = CFileMgr::NewFileSpecFromURLStruct(filename, prototypeFilespec, locationSpec);
  4519.             theErr = CFileMgr::UniqueFileSpec( prototypeFilespec,filename, locationSpec );
  4520.             if (theErr && theErr != fnfErr) // need a unique name, so we want fnfErr!
  4521.                 ThrowIfOSErr_(theErr);
  4522.             
  4523.                 // Set the flavor data to our emBookmarkFileDrag flavor with an FSSpec to the new file.
  4524.             theErr = ::SetDragItemFlavorData (inDragRef, inItemRef, inFlavor, &locationSpec, sizeof(FSSpec), 0);
  4525.             ThrowIfOSErr_(theErr);
  4526.         
  4527.             
  4528.             XP_MEMSET(&request->savedData, 0, sizeof(SHIST_SavedData));
  4529.             CURLDispatcher::DispatchToStorage(request, locationSpec, FO_SAVE_AS, isMailAttachment);
  4530.             // ÑÑÑ both blocks of the if/then/else above call break, so does this get called?  96-12-17 deeje
  4531.             //CFileMgr::UpdateFinderDisplay(locationSpec); 
  4532.         }
  4533.             
  4534.         case emBookmarkDrag:
  4535.         {
  4536.             cstring urlAndTitle(theUrl);
  4537.             if (mDragElement->type == LO_IMAGE)
  4538.                 urlAndTitle += "\r[Image]";
  4539.             else if (mDragElement->type == LO_TEXT)
  4540.                 {
  4541.                 urlAndTitle += "\r";
  4542.                 cstring title;
  4543.                 PA_LOCK(title, char *, mDragElement->lo_text.text);
  4544.                 PA_UNLOCK(mDragElement->lo_text.text);
  4545.                 urlAndTitle += title;
  4546.                 }            
  4547.                 
  4548.             theErr = ::SetDragItemFlavorData(inDragRef, inItemRef, inFlavor, urlAndTitle, strlen(urlAndTitle), 0);
  4549.             break;    
  4550.         }
  4551.                 
  4552.         default:
  4553.         {
  4554.             Throw_(cantGetFlavorErr); // caught by PP handler
  4555.             break;
  4556.         }
  4557.     }        
  4558.  
  4559. }
  4560.  
  4561. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4562. //
  4563. #pragma mark --- TIMER URL ---
  4564. //
  4565. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4566.  
  4567. void CHTMLView::SetTimerURL(Uint32 inSeconds, const char* inURL)
  4568. {
  4569.     if (inURL)
  4570.         mTimerURLString = XP_STRDUP(inURL);
  4571.     else
  4572.         return;
  4573.     mTimerURLFireTime = ::TickCount() + inSeconds * 60;
  4574.     StartRepeating();
  4575. }
  4576.  
  4577. void CHTMLView::ClearTimerURL(void)
  4578. {
  4579.     if (mTimerURLString)
  4580.         XP_FREE(mTimerURLString);
  4581.     mTimerURLString = NULL;
  4582.     StopRepeating();
  4583. }
  4584.  
  4585. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4586. //
  4587. #pragma mark --- DEFERRED LOADING ---
  4588. //
  4589. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4590.  
  4591. void CHTMLView::PostDeferredImage(const char* inImageURL)
  4592. {
  4593.     Assert_(inImageURL != NULL);
  4594.  
  4595.     LO_SetForceLoadImage((char *)inImageURL, FALSE);
  4596.     string theURL(inImageURL);
  4597.     mImageQueue.push_back(theURL);
  4598.     mContext->Repaginate();
  4599. }
  4600.  
  4601. Boolean CHTMLView::IsImageInDeferredQueue(const char* inImageURL) const
  4602. {
  4603.     Boolean bFound = false;
  4604.     if (mImageQueue.size() > 0)
  4605.         {
  4606.         vector<string>::const_iterator theIter = mImageQueue.begin();
  4607.         while (theIter != mImageQueue.end())
  4608.             {
  4609.             if (*theIter == inImageURL)
  4610.                 {
  4611.                 bFound = true;
  4612.                 break;
  4613.                 }
  4614.             ++theIter;
  4615.             }
  4616.         }
  4617.     
  4618.     return bFound;
  4619. }
  4620.  
  4621. void CHTMLView::ClearDeferredImageQueue(void)
  4622. {
  4623.     mImageQueue.erase(mImageQueue.begin(), mImageQueue.end());
  4624. }
  4625.  
  4626. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4627. //
  4628. #pragma mark --- URL DISPATCHING ---
  4629. //
  4630. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4631.  
  4632. // 97-05-30 pkc -- These methods are here so that subclasses can alter the
  4633. // CURLDispatchInfo struct as necessary before we call CURLDispatcher::DispatchURL
  4634.  
  4635. void CHTMLView::DispatchURL(
  4636.     URL_Struct* inURLStruct,
  4637.     CNSContext* inTargetContext,
  4638.     Boolean inDelay,
  4639.     Boolean inForceCreate,
  4640.     FO_Present_Types inOutputFormat)
  4641. {
  4642.     CURLDispatchInfo* info =
  4643.         new CURLDispatchInfo(inURLStruct, inTargetContext, inOutputFormat, inDelay, inForceCreate);
  4644.     DispatchURL(info);
  4645. }
  4646.  
  4647. void CHTMLView::DispatchURL(CURLDispatchInfo* inDispatchInfo)
  4648. {
  4649.     CURLDispatcher::DispatchURL(inDispatchInfo);
  4650. }
  4651.  
  4652. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4653. //
  4654. #pragma mark --- CONTEXT CALLBACK IMPLEMENTATION ---
  4655. //
  4656. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4657.  
  4658. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4659. //    Ñ    
  4660. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4661.  
  4662. // XXX CALLBACK
  4663. void CHTMLView::LayoutNewDocument(
  4664.     URL_Struct*            /* inURL */,
  4665.     Int32*                ioWidth,
  4666.     Int32*                ioHeight,
  4667.     Int32*                ioMarginWidth,
  4668.     Int32*                ioMarginHeight)
  4669. {
  4670.     if (IsRootHTMLView())
  4671.         {
  4672.         //Assert_(mScroller != NULL); Don't HAVE to have scrollers, as long as we check for 'em.
  4673.         if (mScroller)
  4674.             {
  4675.             mScroller->ResetExpansion();
  4676.             mScroller->AdjustHyperViewBounds();
  4677.             }
  4678.         }
  4679.  
  4680.     // clear these so we don't send JavaScript mouseover/exit 
  4681.     // events for deleted elements
  4682.     // ÑÑÑ FIX ME!!!
  4683.     CMochaHacks::ResetMochaMouse();
  4684.     
  4685.     // FIX ME!!! determine why we need this here    
  4686.     // Answer:
  4687.     // Because the we may load a docuemnt in different CharSet (eg. Japanese, Korean )
  4688.     //        ftang
  4689.     SetFontInfo();
  4690.  
  4691.     mHasGridCells = FALSE;
  4692.     *ioWidth = *ioHeight = 0;
  4693.     
  4694.     if (*ioMarginWidth == 0)
  4695.         {
  4696.         *ioMarginWidth = 8;
  4697.         *ioMarginHeight = 8;
  4698.         }
  4699.     
  4700.     Assert_(mContext != NULL);
  4701.     if (IsRootHTMLView())
  4702.         SetScrollMode(mDefaultScrollMode);
  4703.  
  4704.     // Clear the previous page
  4705.     ScrollImageTo(0, 0, false);
  4706.     if (mEraseBackground)
  4707.         ClearView();
  4708.     
  4709.     Rect theFrame;
  4710.     CalcLocalFrameRect(theFrame);
  4711.  
  4712.     *ioWidth = theFrame.right;
  4713.     *ioHeight = theFrame.bottom;
  4714.  
  4715.     // Resize the images from the _current_ document size to the _preferred_ size.
  4716.     // Resize directly, because SetDocDimension does not decrease the size for main view
  4717.     ResizeImageTo(*ioWidth, *ioHeight, false);
  4718.     
  4719.     // 97-06-18 pkc -- Fix bug #70661. Don't do this margin altering code if frame width
  4720.     // and/or height is zero.
  4721.     if (theFrame.right - theFrame.left > 0)
  4722.         {
  4723.         if (*ioMarginWidth > (theFrame.right / 2 ))
  4724.             *ioMarginWidth = MAX( theFrame.right / 2 - 50, 0);
  4725.         }
  4726.     if (theFrame.bottom - theFrame.top > 0)
  4727.         {
  4728.         if (*ioMarginHeight > (theFrame.bottom / 2 ))
  4729.             *ioMarginHeight = MAX(theFrame.bottom / 2 -50, 0);
  4730.         }
  4731.  
  4732.     // If the vertical scrollbar might be shown,
  4733.     // tell layout that we already have it, so that it does
  4734.     // the correct wrapping of text.
  4735.     // If we do not do this, when vertical scrollbar only is
  4736.     // shown, some text might be hidden
  4737.     if (GetScrollMode() == LO_SCROLL_AUTO)
  4738.         *ioWidth -= 15;
  4739. }
  4740.  
  4741.  
  4742. // XXX CALLBACK
  4743.  
  4744. void CHTMLView::ClearView(
  4745.     int                     /* inWhich */)
  4746. {
  4747.     ClearBackground();
  4748.     StopRepeating();
  4749. }
  4750.  
  4751.  
  4752. void CHTMLView::InstallBackgroundColor(void)
  4753. {
  4754.     // Ñ install the user's default solid background color & pattern
  4755.     mBackgroundColor = CPrefs::GetColor(CPrefs::TextBkgnd);
  4756. }
  4757.  
  4758. void CHTMLView::GetDefaultBackgroundColor(LO_Color* outColor) const
  4759. {
  4760.     *outColor = UGraphics::MakeLOColor(mBackgroundColor);
  4761. }
  4762.  
  4763. void CHTMLView::SetWindowBackgroundColor()
  4764. {
  4765.     // Danger!  Port is not necessarily a window.
  4766.     // To fix, compare LWindow::FetchWindowObject result versus LWindow
  4767.     // found by going up view hierarchy.
  4768.     LWindow* portWindow = LWindow::FetchWindowObject(GetMacPort());
  4769.     LWindow* ourWindow = NULL;
  4770.     LView* view = this;
  4771.  
  4772.     while( view != NULL )
  4773.     {
  4774.         view = view->GetSuperView();
  4775.         if (view)
  4776.         {
  4777.             ourWindow = dynamic_cast<LWindow*>(view);
  4778.             if (ourWindow)
  4779.                 break;
  4780.         }
  4781.     }
  4782.  
  4783.     if (portWindow == ourWindow)
  4784.         UGraphics::SetWindowColor(GetMacPort(), wContentColor, mBackgroundColor);
  4785. }
  4786.  
  4787. void CHTMLView::ClearBackground(void)
  4788. {
  4789.     if (!FocusDraw())
  4790.         return;
  4791.  
  4792.     // Ñ dispose of the current background
  4793.     mBackgroundImage = NULL;
  4794.  
  4795.     // Ñ install the user's default solid background color & pattern
  4796.     InstallBackgroundColor();
  4797.  
  4798.     // Danger!  Port is not necessarily a window.
  4799. //    if (LWindow::FetchWindowObject(GetMacPort()))
  4800. //        UGraphics::SetWindowColor(GetMacPort(), wContentColor, mBackgroundColor);
  4801.     SetWindowBackgroundColor();
  4802.     ::RGBBackColor(&mBackgroundColor);
  4803.         
  4804.     // erase the widget to the user's default background
  4805.     
  4806.     Rect theFrame;
  4807.     if (CalcLocalFrameRect(theFrame))
  4808.         DrawBackground(theFrame, nil);
  4809. }
  4810.  
  4811. void CHTMLView::DrawBackground(
  4812.     const Rect&             inArea,
  4813.     LO_ImageStruct*            inBackdrop)
  4814. {
  4815.     if (!FocusDraw())
  4816.         return;
  4817.  
  4818.     // We're using this to denote that we _do_ have an outline
  4819.     Rect theFrame; //, theEraseArea;
  4820.     CalcLocalFrameRect(theFrame);
  4821.  
  4822.     ::SectRect(&theFrame, &inArea, &theFrame);
  4823.     
  4824.     //
  4825.     // Get our default clip from the port so that we use the correct clip
  4826.     // from layers
  4827.     //
  4828.     StRegion theUpdateMask;
  4829.     ::GetClip(theUpdateMask);
  4830.  
  4831.     //
  4832.     // Never erase the plug-in area -- the plug-ins
  4833.     // will take care of that for us, and we don╒t
  4834.     // want to cause flicker with redundant drawing.
  4835.     //
  4836.     StRegion thePluginMask;
  4837.     ::SetEmptyRgn(thePluginMask);
  4838.     CalcPluginMask(thePluginMask);
  4839.  
  4840.     if (!::EmptyRgn(thePluginMask))
  4841.         {
  4842.         Point    theLocalOffset = { 0, 0 };
  4843.         PortToLocalPoint(theLocalOffset);
  4844.         ::OffsetRgn(thePluginMask, theLocalOffset.h, theLocalOffset.v);
  4845.         ::DiffRgn(theUpdateMask, thePluginMask, theUpdateMask);
  4846.         }
  4847.  
  4848.     StClipRgnState theClipState(theUpdateMask);
  4849.     DrawBackgroundSelf(theFrame, inBackdrop);
  4850. }
  4851.  
  4852.  
  4853. void CHTMLView::DrawBackgroundSelf(
  4854.     const Rect&             inArea,
  4855.     LO_ImageStruct*            inBackdrop)
  4856. {
  4857.     LO_ImageStruct *backdrop;
  4858.  
  4859.     if (inBackdrop)
  4860.         backdrop = inBackdrop;
  4861.     else if (mBackgroundImage)
  4862.         backdrop = mBackgroundImage;
  4863.     else
  4864.         backdrop = NULL;
  4865.         
  4866.     // Ñ if we can't draw the image then fall back on the pattern/solid
  4867.     if ( backdrop )
  4868.         {
  4869.         }
  4870.     else
  4871.         ::EraseRect(&inArea);
  4872. }
  4873.  
  4874. void CHTMLView::EraseBackground(
  4875.     int                        /* inLocation */,
  4876.     Int32                    inX,
  4877.     Int32                    inY,
  4878.     Uint32                    inWidth,
  4879.     Uint32                    inHeight,
  4880.     LO_Color*                inColor)
  4881. {
  4882.     if (!FocusDraw())
  4883.         return;
  4884.  
  4885.     // Convert draw rect from image coordinate system to local
  4886.     SPoint32         imageTopLeft;
  4887.     imageTopLeft.h = inX;
  4888.     imageTopLeft.v = inY;
  4889.  
  4890.     SPoint32        imageBottomRight;
  4891.     imageBottomRight.h = inX + inWidth;
  4892.     imageBottomRight.v = inY + inHeight;
  4893.  
  4894.     Rect theLocalEraseArea;
  4895.     ImageToLocalPoint(imageTopLeft, topLeft(theLocalEraseArea));
  4896.     ImageToLocalPoint(imageBottomRight, botRight(theLocalEraseArea));
  4897.     
  4898.     if (inColor != NULL)
  4899.         {
  4900.         // Make sure we don't erase the scrollbars.
  4901.         // NOTE: don't call StClipRgnState() here:
  4902.         // it messes up with the text selection.
  4903.         Rect frame;
  4904.         CalcLocalFrameRect(frame);
  4905. //        StClipRgnState tempClip(frame);
  4906.         if (theLocalEraseArea.right > frame.right)
  4907.             theLocalEraseArea.right = frame.right;
  4908.         if (theLocalEraseArea.bottom > frame.bottom)
  4909.             theLocalEraseArea.bottom = frame.bottom;
  4910.  
  4911.         RGBColor theBackColor = UGraphics::MakeRGBColor(inColor->red, inColor->green, inColor->blue);
  4912.         ::RGBBackColor(&theBackColor);
  4913.         ::EraseRect(&theLocalEraseArea);
  4914.         }
  4915.     else
  4916.         DrawBackground(theLocalEraseArea);
  4917. }
  4918.  
  4919. int CHTMLView::SetColormap(
  4920.     IL_IRGB*                /* inMap */,
  4921.     int                        /* inRequested */)
  4922. {
  4923.     return 0;
  4924. }
  4925.  
  4926. void CHTMLView::SetBackgroundColor(
  4927.     Uint8                     inRed,
  4928.     Uint8                    inGreen,
  4929.     Uint8                     inBlue)
  4930. {
  4931.     RGBColor theBackground = UGraphics::MakeRGBColor(inRed, inGreen, inBlue);
  4932.     
  4933.     GrafPtr thePort = GetMacPort();
  4934.     if (thePort != NULL && mContext != NULL && IsRootHTMLView()
  4935.         && LWindow::FetchWindowObject(GetMacPort()))
  4936.         {
  4937.         UGraphics::SetWindowColor(thePort, wContentColor, theBackground);
  4938.         }
  4939.  
  4940.     if (!UGraphics::EqualColor(mBackgroundColor, theBackground))
  4941.         {
  4942.         mBackgroundColor = theBackground;
  4943.         Refresh();
  4944.         }
  4945.     
  4946.     /* now, call the image code to setup this new background color in the color map */
  4947.     SetImageContextBackgroundColor ( *GetContext(), inRed, inGreen, inBlue );
  4948. }
  4949.  
  4950. void CHTMLView::SetBackgroundImage(
  4951.     LO_ImageStruct*         inImageStruct,
  4952.     Boolean                 inRefresh)
  4953. {
  4954.     mBackgroundImage = inImageStruct;
  4955.     
  4956.     if (inRefresh)
  4957.         {
  4958.         Rect theFrame;
  4959.         CalcLocalFrameRect(theFrame);
  4960.         DrawBackground(theFrame);
  4961.         }
  4962. }
  4963.  
  4964. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4965. //    Ñ    CalcPluginMask
  4966. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4967. //
  4968. //    The following code calculates the union of all exposed plugin areas.  The
  4969. //     result is added to ioPluginRgn.  It is assumed that ioPluginRgn is a
  4970. //    valid region (already constructed with NewRgn()).  The region is port
  4971. //    relative.
  4972. //
  4973. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  4974. // REGION IS BASED ON PORT COORDINATES
  4975.  
  4976. void CHTMLView::CalcPluginMask(RgnHandle ioPluginRgn)
  4977. {
  4978.     Assert_(ioPluginRgn != NULL);
  4979.  
  4980.     if (mSubPanes.GetCount() == 0)                                // Any subpanes?
  4981.         return;
  4982.  
  4983.     LArrayIterator iter(mSubPanes);
  4984.     LPane* pane = NULL;
  4985.     while (iter.Next(&pane ))                                    // Check each subpane
  4986.         {
  4987.         if ((pane->GetPaneID() == CPluginView::class_ID)    ||
  4988.             (pane->GetPaneID() == 'java'))        // Is it a plug-in or a java pane?
  4989.             {
  4990.             CPluginView* plugin = (CPluginView*)pane;
  4991.             if (plugin->IsPositioned() &&                            // Position is valid?
  4992.                 NPL_IsEmbedWindowed(plugin->GetNPEmbeddedApp()))
  4993.                 {
  4994.                 Rect theRevealedFrame;
  4995.                 plugin->GetRevealedRect(theRevealedFrame);
  4996.                 if (!EmptyRect(&theRevealedFrame))                // Plug-in visible in page?
  4997.                     {
  4998.                     StRegion thePluginFrameRgn(theRevealedFrame);
  4999.                     ::UnionRgn(ioPluginRgn, thePluginFrameRgn, ioPluginRgn);
  5000.                     }
  5001.                 }
  5002.             }
  5003.         }
  5004. }
  5005.  
  5006. Boolean CHTMLView::IsGrowCachingEnabled() const
  5007.         /*
  5008.             ...only derived classes with special needs would need better control than this.
  5009.             See |CEditView|.
  5010.         */
  5011.     {
  5012.         return true;
  5013.     }
  5014.  
  5015.  
  5016. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5017. //    Ñ    SetDocDimension
  5018. //
  5019. //    This evidently gets called a bazillion times from within layout.  We need
  5020. //    to cache the calls so that the image is not resized all the time.
  5021. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5022. // XXX CALLBACK
  5023.  
  5024. void CHTMLView::SetDocDimension(
  5025.     int                     /* inLocation */,
  5026.     Int32                     inWidth,
  5027.     Int32                     inHeight)
  5028. {
  5029.     SDimension32 oldImageSize;
  5030.     GetImageSize(oldImageSize);
  5031.  
  5032.     SDimension32 newImageSize;
  5033.     newImageSize.width    = inWidth;
  5034.     newImageSize.height    = inHeight;
  5035.  
  5036.         // If we can cache `grows' to enhance performance...
  5037.     if ( IsGrowCachingEnabled() )
  5038.         {
  5039.                 // ...then we only need to grow if we ran out of space...
  5040.             if ( (oldImageSize.width < inWidth) || (oldImageSize.height < inHeight) )
  5041.                 {
  5042.                     SDimension16 curFrameSize;
  5043.                     GetFrameSize(curFrameSize);
  5044.                         // Warning: in some funky Java cases, |curFrameSize| can be 0,0.
  5045.  
  5046.  
  5047.                         // Start doubling from which ever is greater, the frame height or the old image height.
  5048.                     newImageSize.height = ((curFrameSize.height    >= oldImageSize.height)    ? curFrameSize.height    : oldImageSize.height);
  5049.  
  5050.                         // Ensure that doubling the height will terminate the doubling-loop.
  5051.                     if ( newImageSize.height < 1 )
  5052.                         newImageSize.height = 1;
  5053.  
  5054.                         // Now, double the current height until it's greater than the requested height
  5055.                     do
  5056.                         newImageSize.height += newImageSize.height;
  5057.                     while ( newImageSize.height < inHeight );
  5058.                         // That ought to hold 'em for a while...
  5059.                 }
  5060.             else
  5061.                     // ...else, we'll grow later, what we have now is good enough.
  5062.                 newImageSize = oldImageSize;
  5063.         }
  5064.  
  5065.  
  5066.         // Resize the image, if we need to...
  5067.     if ( (newImageSize.height != oldImageSize.height) || (newImageSize.width != oldImageSize.width) )
  5068.         ResizeImageTo(newImageSize.width, newImageSize.height, true);
  5069.         
  5070.  
  5071.         // If we didn't exactly satisfy the request, then we'll have to later...
  5072.     if ( (mPendingDocDimension_IsValid = ((newImageSize.height != inHeight) || (newImageSize.width != inWidth))) == true )
  5073.         {
  5074.             mPendingDocDimension.width    = inWidth;
  5075.             mPendingDocDimension.height    = inHeight;
  5076.         }
  5077. }
  5078.  
  5079.  
  5080. void CHTMLView::FlushPendingDocResize(void)
  5081. {
  5082.     if ( mPendingDocDimension_IsValid )
  5083.         {
  5084.             mPendingDocDimension_IsValid = false;
  5085.  
  5086.             SDimension32 imageSize;
  5087.             GetImageSize(imageSize);
  5088.  
  5089.             if ( (imageSize.width != mPendingDocDimension.width) || (imageSize.height != mPendingDocDimension.height) )
  5090.                 ResizeImageTo(mPendingDocDimension.width, mPendingDocDimension.height, true);
  5091.         }
  5092. }
  5093.  
  5094.  
  5095. // XXX CALLBACK
  5096.  
  5097. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5098. //    Ñ    SetDocPosition
  5099. //
  5100. // Scrolls the image to (inX, inY), limited to the image size minus the frame size. The x position is
  5101. // left unchanged if it is already visible.
  5102. //
  5103. // inLocation: ignored
  5104. // inX, inY: new position. Negative values will be converted to zero.
  5105. // inScrollEvenIfVisible: if true, will cause the html view to scroll even if the x position is already
  5106. // visible (defaults to false, which is the historical behavior).
  5107. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5108. void CHTMLView::SetDocPosition(
  5109.     int                     /* inLocation */,
  5110.     Int32                     inX,
  5111.     Int32                     inY,
  5112.     Boolean                    inScrollEvenIfVisible)
  5113. {
  5114.     //
  5115.     // If we're displaying a full-page plug-in, ignore the
  5116.     // request to position the document.  When displaying
  5117.     // a full-page plug-in, we don't show scroll bars and
  5118.     // all positioning is handled by the plug-in itself.
  5119.     //
  5120.     if (mContext->HasFullPagePlugin())
  5121.         return;    
  5122.  
  5123.     // Make sure our size is not our of sync, flush any pending resize
  5124.     FlushPendingDocResize();
  5125.  
  5126.     //╩Ñ╩location is the variable affecting which view are we in 
  5127.     //        Make sure that the view is big enough so that we do not get
  5128.     //        auto-cropped with PPlant when we auto-scroll
  5129.  
  5130.     SDimension16 theFrameSize;
  5131.     GetFrameSize(theFrameSize);
  5132.     
  5133.     SPoint32 theFrameLocation;
  5134.     GetFrameLocation(theFrameLocation);
  5135.     
  5136.     SDimension32 theImageSize;
  5137.     GetImageSize(theImageSize);
  5138.     
  5139.     SPoint32 theImageLocation;
  5140.     GetImageLocation(theImageLocation);
  5141.  
  5142.     theImageLocation.h -= theFrameLocation.h;
  5143.     theImageLocation.v -= theFrameLocation.v;
  5144.  
  5145.     // Ñ╩Calculate proper position.
  5146.     
  5147.     Int32 scrollToX = inX;
  5148.     Int32 scrollToY = inY;
  5149.  
  5150.     if ((scrollToY + theFrameSize.height) > theImageSize.height)
  5151.     {
  5152.         scrollToY = theImageSize.height - theFrameSize.height;
  5153.     }
  5154.     
  5155.     // rebracket this test so it's done all the time (not only when we exceed image height)  - mjc 97-9-12
  5156.     // Sometimes the image height is 0 and scrollToY goes negative. It
  5157.     // seems stupid that image height should ever be 0 - oh well.
  5158.     if (scrollToY < 0)
  5159.     {
  5160.         scrollToY = 0;
  5161.     }
  5162.  
  5163.     // If x is visible, do not change it.
  5164.     if (!inScrollEvenIfVisible && (inX >= theImageLocation.h) && (inX + 10 <= (theImageLocation.h + theFrameSize.width )))
  5165.     {
  5166.         scrollToX = theImageLocation.h;
  5167.     }
  5168.     
  5169.     // limit the x position as we do with the y position - mjc 97-9-12
  5170.     scrollToX = MIN(scrollToX, theImageSize.width - theFrameSize.width);
  5171.     if (scrollToX < 0) scrollToX = 0;
  5172.         
  5173.     ScrollImageTo(scrollToX, scrollToY, true);
  5174. }
  5175.  
  5176. // XXX CALLBACK
  5177.  
  5178. void CHTMLView::GetDocPosition(
  5179.     int                     /* inLocation */,
  5180.     Int32*                    outX,
  5181.     Int32*                    outY)
  5182. {
  5183.     // Make sure our size is not our of sync, flush any pending resize
  5184.     FlushPendingDocResize();
  5185.  
  5186.     SPoint32 theScrollPosition;
  5187.     GetScrollPosition(theScrollPosition);
  5188.     *outX = theScrollPosition.h;
  5189.     *outY = theScrollPosition.v;
  5190. }
  5191.  
  5192. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5193. //    Ñ    
  5194. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5195.  
  5196. int CHTMLView::GetTextInfo(
  5197.     LO_TextStruct*            inText,
  5198.     LO_TextInfo*            outTextInfo)
  5199. {
  5200.     Assert_(inText != NULL);
  5201.     Assert_(outTextInfo != NULL);
  5202.     Assert_(mContext != NULL);
  5203.         
  5204.     LO_TextAttr* theTextAttr = inText->text_attr;
  5205.  
  5206.     Assert_(theTextAttr != NULL);
  5207.     if (theTextAttr == NULL)
  5208.         return 1;
  5209.         
  5210.  
  5211. // FIX ME!!! need to optimize the getting of the port (cache it)
  5212. // No, don't. This is open to error, and the amount of time saved is minimal.
  5213.  
  5214.     GrafPtr theSavePort = NULL;    
  5215.     if (GetCachedPort() != qd.thePort)
  5216.         {
  5217.         theSavePort = qd.thePort;
  5218.         ::SetPort(GetCachedPort());
  5219.         }
  5220.  
  5221.     {
  5222.         HyperStyle theStyle(*mContext, &mCharSet, theTextAttr, true);
  5223.         theStyle.Apply();
  5224.         theStyle.GetFontInfo();
  5225.  
  5226.         outTextInfo->ascent = theStyle.fFontInfo.ascent;    
  5227.         outTextInfo->descent = theStyle.fFontInfo.descent;
  5228.         outTextInfo->lbearing = 0;
  5229.         
  5230.         char* theText;
  5231.         PA_LOCK(theText, char*, inText->text);
  5232.         
  5233.         // Ñ╩measure the text
  5234.         Int16 theWidth = theStyle.TextWidth(theText, 0, inText->text_len);
  5235.  
  5236.     // **** Don't know which of these is better; the first only works for native single byte scritps
  5237.     // The second will always work, but produces different results...
  5238.     // Probably need to Add a function to HyperStyle to handle this...    
  5239.  
  5240.     /*
  5241.         if (theTextAttr->fontmask & LO_FONT_ITALIC )
  5242.             outTextInfo->rbearing = theWidth + (::CharWidth(theText[inText->text_len - 1]) / 2);
  5243.         else
  5244.             outTextInfo->rbearing = 0;
  5245.     */
  5246.         if (theTextAttr->fontmask & LO_FONT_ITALIC )
  5247.             outTextInfo->rbearing = theWidth + (theStyle.fFontInfo.widMax / 2);
  5248.         else
  5249.             outTextInfo->rbearing = 0;
  5250.         
  5251.         PA_UNLOCK(inText->text);
  5252.  
  5253.         outTextInfo->max_width = theWidth;
  5254.     }    //so that theStyle goes out of scope and resets the text traits in the correct port
  5255.     
  5256.     if (theSavePort != NULL)
  5257.         ::SetPort(theSavePort);
  5258.     
  5259.     return 1;
  5260. }
  5261.  
  5262. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5263. //    Ñ    MeasureText
  5264. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5265.  
  5266. int CHTMLView::MeasureText(
  5267.     LO_TextStruct*            inText,
  5268.     short*                    outCharLocs)
  5269. {
  5270.     Assert_(inText != NULL);
  5271.     Assert_(outCharLocs != NULL);
  5272.     Assert_(mContext != NULL);
  5273.  
  5274.     LO_TextAttr* theTextAttr = inText->text_attr;
  5275.  
  5276.     Assert_(theTextAttr != NULL);
  5277.     if (theTextAttr == NULL)
  5278.         return 0;
  5279.  
  5280.     // FIX ME!!! need to optimize the getting of the port (cache it)
  5281.     GrafPtr theSavePort = NULL;    
  5282.     if (GetCachedPort() != qd.thePort)
  5283.         {
  5284.         theSavePort = qd.thePort;
  5285.         ::SetPort(GetCachedPort());
  5286.         }
  5287.  
  5288.     Int16 measuredBytes = 0;
  5289.     
  5290.     {
  5291.         HyperStyle theStyle(*mContext, &mCharSet, theTextAttr, true);
  5292.         theStyle.Apply();
  5293.  
  5294.         // FIX ME!!! we only work with Native font references for now
  5295.         CNativeFontReference* nativeFontReference =
  5296.             dynamic_cast<CNativeFontReference*>(theStyle.fFontReference);
  5297.         if (nativeFontReference != NULL)
  5298.         {
  5299.             // measure the text
  5300.             measuredBytes = nativeFontReference->MeasureText(
  5301.                                 (char*)inText->text, 0, inText->text_len, outCharLocs);
  5302.         }
  5303.     }    //so that theStyle goes out of scope and resets the text traits in the correct port
  5304.     
  5305.     if (theSavePort != NULL)
  5306.         ::SetPort(theSavePort);
  5307.     
  5308.     return measuredBytes;
  5309. }
  5310.  
  5311. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5312. //    Ñ    
  5313. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5314.  
  5315. void CHTMLView::GetTextFrame(
  5316.     LO_TextStruct*            inTextStruct,
  5317.     Int32                    inStartPos,
  5318.     Int32                    inEndPos,
  5319.     XP_Rect*                outFrame)
  5320. {
  5321.     Assert_(inTextStruct != NULL);
  5322.     Assert_(outFrame != NULL);
  5323.     
  5324.     GrafPtr theSavePort = NULL;    
  5325.     if (GetCachedPort() != qd.thePort)
  5326.     {
  5327.         theSavePort = qd.thePort;
  5328.         ::SetPort(GetCachedPort());
  5329.     }
  5330.     
  5331.     {
  5332.         LO_TextAttr* theTextAttr = inTextStruct->text_attr;
  5333.         HyperStyle theStyle(*mContext, &mCharSet, theTextAttr, true, inTextStruct);
  5334.  
  5335.         Point theLocalTopLeft = { 0, 0 };
  5336.         
  5337.         char* theText;
  5338.         PA_LOCK(theText, char*, inTextStruct->text);
  5339.         Rect theLocalFrame = theStyle.InvalBackground(theLocalTopLeft, theText, inStartPos, inEndPos, false);
  5340.         PA_UNLOCK(inTextStruct->text);
  5341.         
  5342.         // Convert to layer coordinates
  5343.         outFrame->left = theLocalFrame.left + inTextStruct->x + inTextStruct->x_offset;
  5344.         outFrame->top = theLocalFrame.top + inTextStruct->y + inTextStruct->y_offset;
  5345.         outFrame->right = theLocalFrame.right + inTextStruct->x + inTextStruct->x_offset;
  5346.         outFrame->bottom = theLocalFrame.bottom + inTextStruct->y + inTextStruct->y_offset;
  5347.     } //so that theStyle goes out of scope and resets the text traits in the correct port
  5348.     
  5349.     if (theSavePort != NULL)
  5350.         ::SetPort(theSavePort);
  5351.  
  5352. void CHTMLView::DisplaySubtext(
  5353.     int                     /* inLocation */,
  5354.     LO_TextStruct*            inText,
  5355.     Int32                     inStartPos,
  5356.     Int32                    inEndPos,
  5357.     XP_Bool                 inNeedBG)
  5358. {
  5359.     // Ñ if we can't focus, don't do anything
  5360.     if (!FocusDraw())
  5361.         return;
  5362.  
  5363.     // Ñ╩if we're not visible, don't do anything
  5364.     Rect theTextFrame;
  5365.     if (!CalcElementPosition((LO_Element*)inText, theTextFrame))
  5366.         return;
  5367.     
  5368.     LO_TextAttr* theTextAttr = inText->text_attr;
  5369.     
  5370. // FIX ME!!! this needs to do the right thing in the editor
  5371. //    Boolean bBlinks = (attr->attrmask & LO_ATTR_BLINK) && (!EDT_IS_EDITOR(*mContext));            // no blinking in the editor because of problems with moving text which is blinking
  5372.         
  5373.         
  5374.     HyperStyle style(*mContext, &mCharSet, theTextAttr, false, inText);
  5375.  
  5376.     char *theTextPtr;
  5377.     PA_LOCK(theTextPtr, char*, inText->text);
  5378.     
  5379.     if (inNeedBG)            // Ñ╩erase the background
  5380.         {
  5381.         Rect theInvalRect = style.InvalBackground( topLeft(theTextFrame), theTextPtr, inStartPos, inEndPos, false);
  5382.         
  5383.         if ( theTextAttr->no_background )
  5384.             {
  5385.             StClipRgnState theClipSaver;
  5386.             theClipSaver.ClipToIntersection(theInvalRect);
  5387.             DrawBackground(theInvalRect);
  5388.             }
  5389.         else
  5390.             {
  5391.             ::PenPat(&qd.black );
  5392.             UGraphics::SetIfColor(
  5393.                 UGraphics::MakeRGBColor(theTextAttr->bg.red,
  5394.                                         theTextAttr->bg.green,
  5395.                                         theTextAttr->bg.blue));
  5396.                                         
  5397.             ::FillRect(&theInvalRect, &qd.black);
  5398.             }
  5399.         }
  5400.  
  5401.     style.DrawText(topLeft(theTextFrame), theTextPtr, inStartPos, inEndPos);
  5402.  
  5403.     PA_UNLOCK(inText->text);
  5404. }
  5405.  
  5406. void CHTMLView::DisplayText(
  5407.     int                     inLocation,
  5408.     LO_TextStruct*            inText,
  5409.     XP_Bool                 inNeedBG)
  5410. {
  5411.      DisplaySubtext(inLocation, inText, 0, inText->text_len - 1, inNeedBG);
  5412. }
  5413.  
  5414. void CHTMLView::DisplayLineFeed(
  5415.     int                     /* inLocation */,
  5416.     LO_LinefeedStruct*        /* inLinefeedStruct */,
  5417.     XP_Bool                 /* inNeedBG */)
  5418. {
  5419. #ifdef LAYERS
  5420.     
  5421. #else
  5422.     Rect frame;
  5423.     Boolean        doDraw;
  5424.  
  5425.     // BUGBUG LAYERS: Linefeed drawing causes problems with layers (the problem
  5426.     // is not in FE code - the selection code needs to do the same special casing
  5427.     // it did for text in the case of line feeds and hrules). The temporary fix is
  5428.     // to not draw linefeeds.
  5429.  
  5430.     if ( !FocusDraw() )
  5431.         return;
  5432.  
  5433.     if ( needBg )
  5434.     {
  5435.         doDraw = CalcElementPosition( (LO_Element*)lineFeed, frame );
  5436.  
  5437.         if ( !doDraw )
  5438.             return;
  5439.             
  5440.         // Ñ╩fill the background in the color given by layout    
  5441.         if ( lineFeed->text_attr->no_background == FALSE )
  5442.         {
  5443.             UGraphics::SetIfColor(
  5444.             UGraphics::MakeRGBColor(     lineFeed->text_attr->bg.red,
  5445.                                          lineFeed->text_attr->bg.green,
  5446.                                         lineFeed->text_attr->bg.blue ) );
  5447.     
  5448.             ::FillRect( &frame, &qd.black );
  5449.         }
  5450.         else
  5451.             this->DrawBackground( frame );
  5452.     }
  5453.  
  5454.     Boolean selected = lineFeed->ele_attrmask & LO_ELE_SELECTED;
  5455.         
  5456.     if ( selected )
  5457.     {
  5458.         if ( CalcElementPosition( (LO_Element*)lineFeed, frame ) )
  5459.         {
  5460.             RGBColor        color;
  5461.             LMGetHiliteRGB( &color );
  5462.             
  5463.             ::RGBBackColor( &color );
  5464.             ::EraseRect( &frame );
  5465.         }
  5466.     }
  5467.  
  5468. #endif
  5469. }
  5470.  
  5471. void CHTMLView::DisplayHR(
  5472.     int                     /* inLocation */,
  5473.     LO_HorizRuleStruct*        inRuleStruct)
  5474. {
  5475.     if (!FocusDraw())
  5476.         return;
  5477.  
  5478.     Rect theFrame;
  5479.     if (!CalcElementPosition( (LO_Element*)inRuleStruct, theFrame))
  5480.         return;
  5481.     
  5482. // FIX ME!!! remove lame drawing
  5483.     if (((inRuleStruct->ele_attrmask & LO_ELE_SHADED)== 0) || ( theFrame.top + 1 >= theFrame.bottom ) )        // No shading, or 1 pixel rect
  5484.         {
  5485.         UGraphics::SetFore(CPrefs::Black);
  5486.         FillRect(&theFrame, &UQDGlobals::GetQDGlobals()->black);
  5487.         }
  5488.     else
  5489.         UGraphics::FrameRectShaded(theFrame, TRUE);
  5490. }
  5491.  
  5492. void CHTMLView::DisplayBullet(
  5493.     int                     /* inLocation */,
  5494.     LO_BullettStruct*        inBulletStruct)
  5495. {
  5496.     if (!FocusDraw())
  5497.         return;
  5498.     
  5499.     Rect theFrame;
  5500.     if (!CalcElementPosition((LO_Element*)inBulletStruct, theFrame))
  5501.         return;
  5502.     
  5503.     if (inBulletStruct->text_attr)
  5504.         UGraphics::SetIfColor(
  5505.         UGraphics::MakeRGBColor( inBulletStruct->text_attr->fg.red,
  5506.                                  inBulletStruct->text_attr->fg.green,
  5507.                                  inBulletStruct->text_attr->fg.blue ));
  5508.     else
  5509.         UGraphics::SetFore(CPrefs::Black);
  5510.  
  5511.     switch ( inBulletStruct->bullet_type )
  5512.         {
  5513.         case BULLET_ROUND:
  5514.             ::PenPat(&qd.black);
  5515.             ::FrameOval(&theFrame);
  5516.             break;
  5517.             
  5518.         case BULLET_SQUARE:
  5519.             ::PenPat(&qd.black);
  5520.             ::FrameRect(&theFrame);
  5521.             break;
  5522.             
  5523.         case BULLET_BASIC:
  5524.             ::FillOval(&theFrame, &UQDGlobals::GetQDGlobals()->black);
  5525.             break;
  5526.             
  5527.         case BULLET_MQUOTE:
  5528.             ::PenPat(&qd.black);
  5529.             ::MoveTo(theFrame.left, theFrame.top);
  5530.             ::LineTo(theFrame.left, theFrame.bottom);
  5531.             break;
  5532.         
  5533.         default:        // Should not happen
  5534.             ::MoveTo(theFrame.left, theFrame.bottom);
  5535.             ::DrawChar('?');
  5536.             break;
  5537.         }
  5538. }
  5539.  
  5540. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5541. //    Ñ    
  5542. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5543.  
  5544. void CHTMLView::GetEmbedSize(
  5545.     LO_EmbedStruct*            inEmbedStruct,
  5546.     NET_ReloadMethod        /* inReloadMethod */)
  5547. {
  5548.     if (inEmbedStruct->FE_Data == NULL)        // Creating plugin from scratch
  5549.     {
  5550.         Try_
  5551.         {
  5552.             NPEmbeddedApp* app = NPL_EmbedCreate(*mContext, inEmbedStruct);
  5553.             ThrowIfNil_(app);
  5554.             
  5555.             // XXX This is so bogus. Figure out how to pull the junk in
  5556.             // EmbedCreate() up here or at least rework it so it's cleaner.
  5557.             CPluginView* newPlugin = (CPluginView*) app->fe_data;
  5558.             newPlugin->EmbedCreate(*mContext, inEmbedStruct);
  5559.         }
  5560.         Catch_(inErr)
  5561.         {
  5562.             inEmbedStruct->FE_Data =  NULL;
  5563.         }
  5564.         EndCatch_
  5565.     }
  5566.     else
  5567.         NPL_EmbedSize((NPEmbeddedApp*) inEmbedStruct->FE_Data);
  5568. }
  5569.  
  5570. void CHTMLView::FreeEmbedElement(
  5571.     LO_EmbedStruct*            inEmbedStruct)
  5572. {
  5573.     NPL_EmbedDelete(*mContext, inEmbedStruct);
  5574.     inEmbedStruct->FE_Data = NULL;
  5575. }
  5576.  
  5577. void CHTMLView::CreateEmbedWindow(
  5578.     NPEmbeddedApp*            inEmbeddedApp)
  5579. {
  5580.     // Ensure that we have a layout struct so that we can size 
  5581.     // the plugin properly.
  5582.     ThrowIfNil_(inEmbeddedApp->np_data);
  5583.     LO_EmbedStruct* embed_struct = ((np_data*) inEmbeddedApp->np_data)->lo_struct;
  5584.     
  5585.     ThrowIfNil_(embed_struct);
  5586.     
  5587.     LCommander::SetDefaultCommander(LWindow::FetchWindowObject(GetMacPort()));
  5588.     LPane::SetDefaultView(NULL);
  5589.             
  5590.     CPluginView* newPlugin = NULL;
  5591.     newPlugin = (CPluginView*) UReanimator::ReadObjects('PPob', 4010);
  5592.     ThrowIfNil_(newPlugin);
  5593.             
  5594.     newPlugin->FinishCreate();
  5595.     newPlugin->PutInside(this);
  5596.     newPlugin->SetSuperCommander(this);
  5597.  
  5598.     SDimension16 hyperSize;
  5599.     this->GetFrameSize(hyperSize);                // Get the size of the hyperView
  5600.     
  5601.     newPlugin->EmbedSize(embed_struct, hyperSize);
  5602.     
  5603.     // XXX Don't we need to create the NPWindow struct here, too?
  5604.     // Ugh. Actually that's done in CPluginView::EmbedCreate(), which we
  5605.     // call after NPL_EmbedCreate(). That probably needs some massaging...
  5606.     inEmbeddedApp->fe_data = (void*) newPlugin;
  5607. }
  5608.  
  5609. void CHTMLView::SaveEmbedWindow(
  5610.     NPEmbeddedApp*            inEmbeddedApp)
  5611. {
  5612.     ThrowIfNil_(inEmbeddedApp);
  5613.     CPluginView *view = (CPluginView*) inEmbeddedApp->fe_data;
  5614.     
  5615.     ThrowIfNil_(view);
  5616.  
  5617.     //    Make sure that we are not targeting the plugin view
  5618.     //
  5619.     //    XXX Note that this will be overly aggressive in removing the
  5620.     //    focus. Probably what we really want to do is check to see if
  5621.     //    some sub-pane of the view has focus, and if so, reset it to
  5622.     //    a well-known safe place.
  5623.     LCommander::SwitchTarget(NULL);
  5624.  
  5625.     //    Un-intsall the plugin view, hide it, and re-target
  5626.     //    it to the owning window.    
  5627.     view->Hide();
  5628.  
  5629.     LView *previousParentView = NULL;
  5630.     LView *currentParentView = view->GetSuperView();
  5631.     while (currentParentView != NULL) {
  5632.         previousParentView = currentParentView;
  5633.         currentParentView = currentParentView->GetSuperView();
  5634.     }
  5635.     
  5636.     view->PutInside((LWindow *)previousParentView);
  5637.     view->SetSuperCommander((LWindow *)previousParentView);
  5638.     
  5639.     //    XXX This should probably move to the Stop() method of the JVM plugin.
  5640.     //FlushEventHierarchy(view);
  5641. }
  5642.  
  5643. void CHTMLView::RestoreEmbedWindow(
  5644.     NPEmbeddedApp*            inEmbeddedApp)
  5645. {
  5646.     CPluginView* view = (CPluginView*) inEmbeddedApp->fe_data;
  5647.     LView* parentView = view->GetSuperView();
  5648.     
  5649.     //    If we are parented inside the outermost window, then 
  5650.     //    reparent us to the hyperview.
  5651.     
  5652.     if (parentView->GetSuperView() == NULL) {
  5653.         view->PutInside(this);
  5654.         view->SetSuperCommander(this);
  5655.         
  5656.         int32 xp = 0;
  5657.         int32 yp = 0;
  5658.         
  5659.         if (XP_OK_ASSERT(inEmbeddedApp->np_data)) {
  5660.             LO_EmbedStruct* embed_struct = ((np_data*) inEmbeddedApp->np_data)->lo_struct;
  5661.             if (XP_OK_ASSERT(embed_struct)) {
  5662.                 xp = embed_struct->x + embed_struct->x_offset
  5663.                     /* - CONTEXT_DATA(*mContext)->document_x */;
  5664.                 yp = embed_struct->y + embed_struct->y_offset
  5665.                     /* - CONTEXT_DATA(*mContext)->document_y */;
  5666.             }
  5667.         }
  5668.         
  5669.         view->PlaceInSuperImageAt(xp, yp, TRUE);
  5670.     }
  5671.  
  5672.     LCommander::SetDefaultCommander(LWindow::FetchWindowObject(GetMacPort()));
  5673.     LPane::SetDefaultView(NULL);
  5674. }
  5675.  
  5676. void CHTMLView::DestroyEmbedWindow(
  5677.     NPEmbeddedApp*            inEmbeddedApp)
  5678. {
  5679.     if (inEmbeddedApp && inEmbeddedApp->fe_data)
  5680.     {
  5681.         // XXX Why does EmbedFree need the LO_EmbedStruct?
  5682.         ThrowIfNil_(inEmbeddedApp->np_data);
  5683.         LO_EmbedStruct* embed_struct = ((np_data*) inEmbeddedApp->np_data)->lo_struct;
  5684.     
  5685.         ThrowIfNil_(embed_struct);
  5686.     
  5687.         CPluginView* view = (CPluginView*) inEmbeddedApp->fe_data;
  5688.         view->EmbedFree(*mContext, embed_struct);
  5689.         delete view;
  5690.         inEmbeddedApp->fe_data = NULL;
  5691.     }
  5692. }
  5693.  
  5694. void CHTMLView::DisplayEmbed(
  5695.     int                     /* inLocation */,
  5696.     LO_EmbedStruct*            inEmbedStruct)
  5697. {
  5698.     NPEmbeddedApp* app = (NPEmbeddedApp*) inEmbedStruct->FE_Data;
  5699.     if (app && app->fe_data)
  5700.     {
  5701.         if ( !FocusDraw() )
  5702.             return;
  5703.             
  5704.         CPluginView* view = (CPluginView*) app->fe_data;
  5705.         view->EmbedDisplay(inEmbedStruct, false);
  5706.     }
  5707. }
  5708.  
  5709. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5710. //    Ñ    
  5711. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5712.  
  5713. void CHTMLView::GetJavaAppSize(
  5714.     LO_JavaAppStruct*        inJavaAppStruct,
  5715.     NET_ReloadMethod        inReloadMethod)
  5716. {
  5717.     LJ_GetJavaAppSize(*mContext, inJavaAppStruct, inReloadMethod);
  5718. }
  5719.  
  5720. static void PR_CALLBACK
  5721. FE_SaveJavaWindow(MWContext * /* context */, LJAppletData* /* ad */, void* window)
  5722. {
  5723. #if defined (JAVA)
  5724.     CJavaView* javaAppletView = (CJavaView *)window;
  5725.  
  5726.     //    Make sure that we are not targeting this
  5727.     //    java applet.
  5728.     
  5729.     LCommander::SwitchTarget(GetContainerWindow(javaAppletView));
  5730.  
  5731.     //    Un-intsall the java view, hide it, and re-target
  5732.     //    it to the owning window.    
  5733.  
  5734.     javaAppletView->Hide();
  5735.  
  5736.     LView    *currentParentView,
  5737.             *previousParentView = NULL;
  5738.     
  5739.     currentParentView = javaAppletView->GetSuperView();
  5740.     while (currentParentView != NULL)
  5741.         {
  5742.         previousParentView = currentParentView;
  5743.         currentParentView = currentParentView->GetSuperView();
  5744.         }
  5745.     
  5746.     javaAppletView->PutInside((LWindow *)previousParentView);
  5747.     javaAppletView->SetSuperCommander((LWindow *)previousParentView);
  5748.     
  5749.     FlushEventHierarchy(javaAppletView);
  5750. #endif /* defined (JAVA) */
  5751. }
  5752.  
  5753. void CHTMLView::HideJavaAppElement(
  5754.     LJAppletData*                inAppletData)
  5755. {
  5756.     LJ_HideJavaAppElement(*mContext, inAppletData, FE_SaveJavaWindow);
  5757. }
  5758.  
  5759. static void PR_CALLBACK 
  5760. FE_DisplayNoJavaIcon(MWContext *, LO_JavaAppStruct *)
  5761. {
  5762.     /* write me */
  5763. }
  5764.  
  5765. static void* PR_CALLBACK 
  5766. FE_CreateJavaWindow(MWContext *context, LO_JavaAppStruct * /* inJavaAppStruct */,
  5767.                     int32 xp, int32 yp, int32 xs, int32 ys)
  5768. {
  5769. #if defined (JAVA)
  5770.     CNSContext* theNSContext = ExtractNSContext(context);
  5771.     Assert_(theNSContext != NULL);
  5772.     CHTMLView* theCurrentView = ExtractHyperView(*theNSContext);
  5773.     Assert_(theCurrentView != NULL);
  5774.  
  5775.     CJavaView *newJavaView = NULL;
  5776.     Try_
  5777.     {
  5778.         LCommander::SetDefaultCommander(LWindow::FetchWindowObject(theCurrentView->GetMacPort()));
  5779.         LPane::SetDefaultView(NULL);
  5780.         newJavaView = (CJavaView *)UReanimator::ReadObjects('PPob', 2090);
  5781.         newJavaView->FinishCreate();
  5782.         newJavaView->PutInside(theCurrentView);
  5783.         newJavaView->SetSuperCommander(theCurrentView);
  5784.         newJavaView->PlaceInSuperImageAt(xp, yp, TRUE);
  5785.  
  5786.         newJavaView->SetPositioned();
  5787.     
  5788. /*
  5789.         // If the plugin size is 1x1, this really means that the plugin is
  5790.         // full-screen, and that we should set up the plugin╒s real width
  5791.         // for XP since it doesn╒t know how big to make it.  Since a full-
  5792.         // screen plugin should resize when its enclosing view (the hyperview)
  5793.         // resizes, we bind the plugin view on all sides to its superview.
  5794.         // -bing 11/16/95 
  5795.         //
  5796.         if (inJavaAppStruct->width == 1 && inJavaAppStruct->height == 1) {
  5797.             SBooleanRect binding = {true, true, true, true};
  5798.             newJavaView->SetFrameBinding(binding);
  5799.             SDimension16 hyperSize;
  5800.             this->GetFrameSize(hyperSize);                // Get the size of the hyperView
  5801.             inJavaAppStruct->width = hyperSize.width - 1;
  5802.             inJavaAppStruct->height = hyperSize.height - 1;
  5803.             
  5804.             const short kLeftMargin = 8;                // ÑÑÑ These should be defined in mhyper.h!!!
  5805.             const short kTopMargin = 8;
  5806.             inJavaAppStruct->x -= kLeftMargin;                // Allow the plugin to use ALL the screen space
  5807.             inJavaAppStruct->y -= kTopMargin;
  5808.         }
  5809. */
  5810.     }
  5811.  
  5812.     Catch_(inErr)
  5813.     {
  5814.     }
  5815.     EndCatch_
  5816.  
  5817.     //    Resize the image
  5818.     
  5819.     if (newJavaView != NULL) {
  5820.         newJavaView->ResizeImageTo(xs, ys, FALSE);
  5821.         newJavaView->ResizeFrameTo(xs, ys, FALSE);
  5822.     }
  5823.  
  5824.     return (void*)newJavaView;
  5825. #else
  5826.     return (void*)NULL;
  5827. #endif /* defined (JAVA) */
  5828. }
  5829.  
  5830. static void* PR_CALLBACK
  5831. FE_GetAwtWindow(MWContext * /* context */, LJAppletData* ad)
  5832. {
  5833. #if defined (JAVA)
  5834.     CJavaView* newJavaView = (CJavaView *)ad->window;
  5835.     return (void*)newJavaView->GetUserCon();
  5836. #else
  5837.     return (void*)NULL;
  5838. #endif /* defined (JAVA) */
  5839. }
  5840.  
  5841. static void PR_CALLBACK 
  5842. FE_RestoreJavaWindow(MWContext *context, LJAppletData* ad,
  5843.                        int32 xp, int32 yp, int32 /* xs */, int32 /* ys */)
  5844. {
  5845. #if defined (JAVA)
  5846.     CNSContext* theNSContext = ExtractNSContext(context);
  5847.     Assert_(theNSContext != NULL);
  5848.     CHTMLView* theCurrentView = ExtractHyperView(*theNSContext);
  5849.     Assert_(theCurrentView != NULL);
  5850.  
  5851.     CJavaView* newJavaView = (CJavaView *)ad->window;
  5852.         
  5853.     LView        *parentView = newJavaView->GetSuperView();
  5854.     
  5855.     //    If we are parented inside the outermost window, then 
  5856.     //    reparent us to the hyperview.
  5857.     
  5858.     if (parentView->GetSuperView() == NULL) {
  5859.         
  5860.         newJavaView->PutInside(theCurrentView);
  5861.         newJavaView->SetSuperCommander(theCurrentView);
  5862.         newJavaView->PlaceInSuperImageAt(xp, yp, TRUE);
  5863.             
  5864.     }
  5865.  
  5866.     LCommander::SetDefaultCommander(LWindow::FetchWindowObject(theCurrentView->GetMacPort()));
  5867.     LPane::SetDefaultView(NULL);
  5868. #endif /* defined (JAVA) */
  5869. }
  5870.  
  5871. static void PR_CALLBACK 
  5872. FE_SetJavaWindowPos(MWContext * /* context */, void* window,
  5873.                     int32 xp, int32 yp, int32 /* xs */, int32 /* ys */)
  5874. {
  5875. #if defined (JAVA)
  5876.     CJavaView* newJavaView = (CJavaView *)window;
  5877.         
  5878.     newJavaView->PlaceInSuperImageAt(xp, yp, TRUE);
  5879. #endif /* defined (JAVA) */
  5880. }
  5881.  
  5882. static void PR_CALLBACK 
  5883. FE_SetJavaWindowVisibility(MWContext *context, void* window, PRBool visible)
  5884. {
  5885. #if defined (JAVA)
  5886.     CNSContext* theNSContext = ExtractNSContext(context);
  5887.     Assert_(theNSContext != NULL);
  5888.     CHTMLView* theCurrentView = ExtractHyperView(*theNSContext);
  5889.     Assert_(theCurrentView != NULL);
  5890.  
  5891.     CJavaView* newJavaView = (CJavaView *)window;
  5892.     Boolean                isComponentVisible = TRUE;
  5893.     Hsun_awt_macos_MComponentPeer     *componentPeer = PaneToPeer(newJavaView); 
  5894.  
  5895.     if (componentPeer != NULL) {
  5896.         if (unhand(unhand(componentPeer)->target)->visible)
  5897.             isComponentVisible = TRUE;
  5898.         else
  5899.             isComponentVisible = FALSE;
  5900.     }
  5901.  
  5902.     if (newJavaView != NULL) {
  5903.         // This call could mean that either the visibility or the position of the
  5904.         // applet has changed, so we make the appropriate changes to the view.
  5905.         if ((newJavaView->IsVisible() && !visible) ||
  5906.             (isComponentVisible == FALSE))
  5907.             newJavaView->Hide();
  5908.             
  5909.         if ((!newJavaView->IsVisible() && visible) &&
  5910.             isComponentVisible)
  5911.             newJavaView->Show();
  5912.     }
  5913. #endif /* defined (JAVA) */
  5914. }
  5915.  
  5916. void CHTMLView::DisplayJavaApp(
  5917.     int                     /* inLocation */,
  5918.     LO_JavaAppStruct*        inJavaAppStruct)
  5919. {
  5920.     LJ_DisplayJavaApp(*mContext, inJavaAppStruct,
  5921.                       FE_DisplayNoJavaIcon,
  5922.                       FE_GetFullWindowSize,
  5923.                       FE_CreateJavaWindow,
  5924.                       FE_GetAwtWindow,
  5925.                       FE_RestoreJavaWindow,
  5926.                       FE_SetJavaWindowPos,
  5927.                       FE_SetJavaWindowVisibility);
  5928. }
  5929.  
  5930. static void PR_CALLBACK
  5931. FE_FreeJavaWindow(MWContext * /* context */, struct LJAppletData * /* appletData */,
  5932.           void* window)
  5933. {
  5934. #if defined (JAVA)
  5935.     CJavaView* javaAppletView = (CJavaView *)window;
  5936.     delete javaAppletView;
  5937. #endif /* defined (JAVA) */
  5938. }
  5939.  
  5940. void CHTMLView::FreeJavaAppElement(
  5941.     LJAppletData*            inAppletData)
  5942. {
  5943.     LJ_FreeJavaAppElement(*mContext, inAppletData, 
  5944.                           FE_SaveJavaWindow,
  5945.                           FE_FreeJavaWindow);
  5946. }
  5947.  
  5948. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5949. //    Ñ    
  5950. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5951.  
  5952. void CHTMLView::DrawJavaApp(
  5953.     int                     /*inLocation*/,
  5954.     LO_JavaAppStruct*        )
  5955. {
  5956. }
  5957.  
  5958. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5959. //    Ñ    
  5960. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5961.  
  5962. void CHTMLView::HandleClippingView(
  5963.     struct LJAppletData*    , 
  5964.     int                     /*x*/, 
  5965.     int                     /*y*/, 
  5966.     int                     /*width*/, 
  5967.     int                     /*height*/)
  5968. {
  5969. }
  5970.  
  5971. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5972. //    Ñ    
  5973. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  5974.  
  5975. void CHTMLView::GetFormElementInfo(
  5976.     LO_FormElementStruct*     inElement)
  5977. {
  5978.     UFormElementFactory::MakeFormElem(this, mContext, inElement);
  5979. }
  5980.  
  5981.  
  5982. void CHTMLView::ResetFormElementData(
  5983.     LO_FormElementStruct*    inElement,
  5984.     Boolean                 inRefresh,
  5985.     Boolean                    inFromDefaults)
  5986. {
  5987.     UFormElementFactory::ResetFormElementData(inElement, inRefresh, inFromDefaults, true);
  5988. }
  5989.  
  5990.  
  5991.  
  5992.  
  5993. void CHTMLView::DisplayFormElement(
  5994.     int                     /* inLocation */,
  5995.     LO_FormElementStruct*     inFormElement)
  5996. {
  5997.     CDrawable *currentDrawable = mCurrentDrawable;
  5998.     
  5999.     // When we're drawing form elements, we force our current drawable to be onscreen
  6000.     SetCurrentDrawable(nil);
  6001.     UFormElementFactory::DisplayFormElement(mContext, inFormElement);
  6002.     SetCurrentDrawable(currentDrawable);
  6003. }
  6004.  
  6005. void CHTMLView::DisplayBorder(
  6006.     int                     /* inLocation */,
  6007.     int                     inX,
  6008.     int                        inY,
  6009.     int                        inWidth,
  6010.     int                        inHeight,
  6011.     int                        inBW,
  6012.     LO_Color*                 inColor,
  6013.     LO_LineStyle            inStyle)
  6014. {
  6015.     if (!FocusDraw() || (inBW == 0))
  6016.         return;
  6017.  
  6018.     SPoint32 topLeftImage;
  6019.     Point topLeft;
  6020.     int32 layerOriginX, layerOriginY;
  6021.     Rect    borderRect;
  6022.     RGBColor borderColor;
  6023.     
  6024.     if ( mCurrentDrawable != NULL ) {
  6025.         mCurrentDrawable->GetLayerOrigin(&layerOriginX, &layerOriginY);
  6026.     }
  6027.     else {
  6028.         layerOriginX = mLayerOrigin.h;
  6029.         layerOriginY = mLayerOrigin.v;
  6030.     }
  6031.     topLeftImage.h = inX + layerOriginX;
  6032.     topLeftImage.v = inY + layerOriginY;
  6033.     ImageToLocalPoint(topLeftImage, topLeft);
  6034.  
  6035.     borderRect.left = topLeft.h;
  6036.     borderRect.top = topLeft.v;    
  6037.     borderRect.right = borderRect.left + inWidth;
  6038.     borderRect.bottom = borderRect.top + inHeight;
  6039.  
  6040.     borderColor = UGraphics::MakeRGBColor(inColor->red, inColor->green, inColor->blue);
  6041.     RGBForeColor(&borderColor);
  6042.     ::PenSize(inBW, inBW);
  6043.  
  6044.     switch (inStyle) {
  6045.         case LO_SOLID:
  6046.         ::FrameRect(&borderRect);
  6047.         break;
  6048.         
  6049.         case LO_BEVEL:
  6050.         ::UGraphics::FrameRectShaded(borderRect, FALSE);
  6051.         break;
  6052.         
  6053.         default:
  6054.         break;
  6055.     }
  6056.  
  6057.     ::PenSize(1, 1);
  6058. }
  6059.  
  6060. void CHTMLView::UpdateEnableStates()
  6061. {
  6062.     // this is a Composer function so that the state of buttons can change(enabled/disabled)
  6063. }
  6064.  
  6065. void CHTMLView::DisplayFeedback(
  6066.                     int         /*inLocation*/,
  6067.                     LO_Element*    )
  6068. {
  6069.     // this is a Composer function for showing selection of Images
  6070. }
  6071.  
  6072. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  6073. //    Ñ    
  6074. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  6075.  
  6076. void CHTMLView::FreeEdgeElement(
  6077.     LO_EdgeStruct*            inEdgeStruct)
  6078. {
  6079.     if (FocusDraw())
  6080.         {
  6081.         Rect theEdgeFrame;
  6082.         if (CalcElementPosition((LO_Element*)inEdgeStruct, theEdgeFrame))
  6083.             {
  6084.             ::InsetRect(&theEdgeFrame, -1, -1);
  6085.             ::InvalRect(&theEdgeFrame);
  6086.             }
  6087.         }
  6088.     
  6089.     // 97-06-11 pkc -- delete inEdgeStruct from edge list
  6090.     // NOTE: This line assumes that inEdgeStruct is in the list.
  6091.     vector<LO_EdgeStruct*>::iterator found = find(mGridEdgeList.begin(), mGridEdgeList.end(), inEdgeStruct);
  6092.     if (found != mGridEdgeList.end())
  6093.         mGridEdgeList.erase(found);
  6094. }
  6095.  
  6096. void CHTMLView::DisplayEdge(
  6097.     int                     /* inLocation */,
  6098.     LO_EdgeStruct*            inEdgeStruct)
  6099. {
  6100.     if ( !FocusDraw() )
  6101.         return;
  6102.  
  6103.     // 97-06-21 pkc -- In some instances, like when the Security Advisor brings the Page Info
  6104.     // window to the front, FocusDraw won't call SetPort on the window port for some reason.
  6105.     // Use an StPortOriginState to make sure the port is set correctly.
  6106.     StPortOriginState theOriginSaver((GrafPtr)GetMacPort());
  6107.  
  6108.     if (IsRootHTMLView())
  6109.         mShowFocus = FALSE;
  6110.     
  6111.     // 97-06-11 pkc -- If we're not redrawing a grid edge via DrawSelf, and we're also not
  6112.     // drawing because the user dragged an edge, then add this LO_EdgeStruct* to list
  6113.     if (!mDontAddGridEdgeToList)
  6114.     {
  6115.         mGridEdgeList.push_back(inEdgeStruct);
  6116.     }
  6117.     
  6118.     Rect        docFrame; 
  6119.     Boolean        isVisible;
  6120.     isVisible = CalcElementPosition( (LO_Element*)inEdgeStruct, docFrame );
  6121.     int32        size;
  6122.     
  6123.     if ( !isVisible )
  6124.         return;
  6125.  
  6126.     SBooleanRect thePartialBevels = { true, true, true, true };
  6127.     if ( inEdgeStruct->is_vertical )
  6128.         {
  6129.         size = inEdgeStruct->width;
  6130.         /* top - 2 ?  Try anything else and look closely at the top of the frame edge,
  6131.            where it abutts the enclosing bevel view.  -2 seems to be only benevolent;
  6132.            if you find otherwise, more tweaking may be necessary.  I suspect the unexpected
  6133.            extra pixel correction has something to do with the unfortunate circumstance
  6134.            that the first time an edge is drawn, while the frame is being laid out,
  6135.            the port origin is often one pixel off (both vertically and horizontally)
  6136.            from its final position after layout is complete. */
  6137.         docFrame.top -= 2;
  6138.         docFrame.bottom++;
  6139.         thePartialBevels.top = thePartialBevels.bottom = false;
  6140.         }
  6141.     else
  6142.         {
  6143.         size = inEdgeStruct->height;
  6144.         ::InsetRect( &docFrame, -1, 0 );
  6145.         thePartialBevels.left = thePartialBevels.right = false;
  6146.         }
  6147.  
  6148.     StClipRgnState theClipSaver(docFrame);
  6149.  
  6150.     SBevelColorDesc theBevelColors;        
  6151.     if ( inEdgeStruct->bg_color )
  6152.         {
  6153.         UGraphics::SetIfColor( UGraphics::MakeRGBColor( inEdgeStruct->bg_color->red,
  6154.             inEdgeStruct->bg_color->green,
  6155.             inEdgeStruct->bg_color->blue ) );
  6156.         ::FillRect( &docFrame, &qd.black );
  6157.         }
  6158.     else
  6159.         {
  6160.         // Cinco de Mayo '97 pkc
  6161.         // Added code to draw using background pattern like our pattern bevel views
  6162.         if (!mPatternWorld)
  6163.             {
  6164.             mPatternWorld = CSharedPatternWorld::CreateSharedPatternWorld(10000);
  6165.             if (mPatternWorld)
  6166.                 {
  6167.                 mPatternWorld->AddUser(this);
  6168.                 }
  6169.             }
  6170.  
  6171.         if (mPatternWorld)
  6172.             {
  6173.             Point theAlignment;
  6174.             CSharedPatternWorld::CalcRelativePoint(this, CSharedPatternWorld::eOrientation_Port, theAlignment);
  6175.             
  6176.             CGrafPtr thePort = (CGrafPtr)GetMacPort();
  6177.  
  6178.             mPatternWorld->Fill(thePort, docFrame, theAlignment);
  6179.             }
  6180.         else
  6181.             {
  6182.             UGraphicGizmos::LoadBevelTraits(10000, theBevelColors);
  6183.             ::PmForeColor(theBevelColors.fillColor);
  6184.             ::PaintRect(&docFrame);
  6185.             }
  6186.         }
  6187.  
  6188.     if ( size > 2 )
  6189.         {
  6190.         // shrink the beveled edges rect back to the original size specified
  6191.         if ( inEdgeStruct->is_vertical )
  6192.             ::InsetRect( &docFrame, 0, 1 );
  6193.         else
  6194.             ::InsetRect( &docFrame, 1, 0 );
  6195.         if ( inEdgeStruct->bg_color )
  6196.             {
  6197.             UGraphics::FrameRectShaded( docFrame, FALSE );
  6198.             }
  6199.         else
  6200.             {
  6201.             // Cinco de Mayo '97 pkc
  6202.             // Use BevelTintPartialRect if we're drawing using a pattern
  6203.             if (mPatternWorld)
  6204.                 {
  6205.                 UGraphicGizmos::BevelTintPartialRect(docFrame, 1, 
  6206.                             0x2000, 0x2000, thePartialBevels);
  6207.                 }
  6208.             else
  6209.                 {
  6210.                 UGraphicGizmos::BevelPartialRect(docFrame, 1, 
  6211.                             theBevelColors.topBevelColor, theBevelColors.bottomBevelColor, thePartialBevels);
  6212.                 }
  6213.             }
  6214.  
  6215.         if ( inEdgeStruct->movable )
  6216.             {
  6217.             Rect theDotFrame = { 0, 0, 2, 2 };
  6218.             UGraphicGizmos::CenterRectOnRect(theDotFrame, docFrame);
  6219.             UGraphics::FrameCircleShaded( theDotFrame, TRUE );
  6220.             }
  6221.         }
  6222. }
  6223.  
  6224. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  6225. //    Ñ    
  6226. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  6227.  
  6228. void CHTMLView::DisplayTable(
  6229.     int                     /* inLocation */,
  6230.     LO_TableStruct*            inTableStruct)
  6231. {
  6232.     if (!FocusDraw() ||
  6233.         ((inTableStruct->border_width == 0) &&
  6234.          (inTableStruct->border_top_width == 0) &&
  6235.          (inTableStruct->border_right_width == 0) &&
  6236.          (inTableStruct->border_bottom_width == 0) &&
  6237.          (inTableStruct->border_left_width == 0)))
  6238.         return;
  6239.  
  6240.     // Retain akbar (3.0) functionality -- we used to call UGraphics::FrameRectShaded
  6241.     // which set a light rgb pin color of { 60000, 60000, 60000 }. By default,
  6242.     // UGraphicGizmos has a light pin color of { 0xFFFF, 0xFFFF, 0xFFFF }. So as
  6243.     // not to diverge from akbar, set UGraphicGizmos::sLighter then restore its value
  6244.     RGBColor savedLighter = UGraphicGizmos::sLighter;
  6245.     UGraphicGizmos::sLighter.red = 0xFFFF;
  6246.     UGraphicGizmos::sLighter.green = 0xFFFF;
  6247.     UGraphicGizmos::sLighter.blue = 0xFFFF;
  6248.     // Ñ╩element->width + borderWidth, element->height + borderWidth);
  6249.     Rect theFrame;
  6250.     if (CalcElementPosition( (LO_Element*)inTableStruct, theFrame ))
  6251.         {
  6252.         RGBColor borderColor =
  6253.             UGraphics::MakeRGBColor((inTableStruct->border_color).red,
  6254.                                     (inTableStruct->border_color).green,
  6255.                                     (inTableStruct->border_color).blue);
  6256.         switch (inTableStruct->border_style)
  6257.             {
  6258.             case BORDER_NONE:
  6259.                 break;
  6260.             
  6261.             case BORDER_DOTTED:
  6262.             case BORDER_DASHED:
  6263.             case BORDER_SOLID:
  6264.                 DisplaySolidBorder(theFrame,
  6265.                                    borderColor,
  6266.                                    inTableStruct->border_top_width,
  6267.                                    inTableStruct->border_left_width,
  6268.                                    inTableStruct->border_bottom_width,
  6269.                                    inTableStruct->border_right_width);
  6270.                 break;
  6271.             
  6272.             case BORDER_DOUBLE:
  6273.                 {
  6274.                 Int32 borderTopWidth = inTableStruct->border_top_width / 3;
  6275.                 Int32 borderLeftWidth = inTableStruct->border_left_width / 3;
  6276.                 Int32 borderBottomWidth = inTableStruct->border_bottom_width / 3;
  6277.                 Int32 borderRightWidth = inTableStruct->border_right_width / 3;
  6278.  
  6279.                 // draw outer border
  6280.                 DisplaySolidBorder(theFrame,
  6281.                                    borderColor,
  6282.                                    borderTopWidth,
  6283.                                    borderLeftWidth,
  6284.                                    borderBottomWidth,
  6285.                                    borderRightWidth);
  6286.                 // adjust frame
  6287.                 theFrame.top += (inTableStruct->border_top_width - borderTopWidth);
  6288.                 theFrame.left += (inTableStruct->border_left_width - borderLeftWidth);
  6289.                 theFrame.bottom -= (inTableStruct->border_bottom_width - borderBottomWidth);
  6290.                 theFrame.right -= (inTableStruct->border_right_width - borderRightWidth);
  6291.  
  6292.                 // draw inner border
  6293.                 DisplaySolidBorder(theFrame,
  6294.                                    borderColor,
  6295.                                    borderTopWidth,
  6296.                                    borderLeftWidth,
  6297.                                    borderBottomWidth,
  6298.                                    borderRightWidth);
  6299.                 }
  6300.                 break;
  6301.             
  6302.             case BORDER_GROOVE:
  6303.                 // Groove border has sunken outer border with a raised inner border
  6304.                 DisplayGrooveRidgeBorder(theFrame,
  6305.                                          borderColor,
  6306.                                          true,
  6307.                                          inTableStruct->border_top_width,
  6308.                                          inTableStruct->border_left_width,
  6309.                                          inTableStruct->border_bottom_width,
  6310.                                          inTableStruct->border_right_width);
  6311.                 break;
  6312.             case BORDER_RIDGE:
  6313.                 // Ridge border has raised outer border with a sunken inner border
  6314.                 DisplayGrooveRidgeBorder(theFrame,
  6315.                                          borderColor,
  6316.                                          false,
  6317.                                          inTableStruct->border_top_width,
  6318.                                          inTableStruct->border_left_width,
  6319.                                          inTableStruct->border_bottom_width,
  6320.                                          inTableStruct->border_right_width);
  6321.                 break;
  6322.             
  6323.             case BORDER_INSET:
  6324.                 // sunken border
  6325.                 DisplayBevelBorder(theFrame,
  6326.                                    borderColor,
  6327.                                    false,
  6328.                                    inTableStruct->border_top_width,
  6329.                                    inTableStruct->border_left_width,
  6330.                                    inTableStruct->border_bottom_width,
  6331.                                    inTableStruct->border_right_width);
  6332.                 break;
  6333.  
  6334.             case BORDER_OUTSET:
  6335.                 // raised border
  6336.                 DisplayBevelBorder(theFrame,
  6337.                                    borderColor,
  6338.                                    true,
  6339.                                    inTableStruct->border_top_width,
  6340.                                    inTableStruct->border_left_width,
  6341.                                    inTableStruct->border_bottom_width,
  6342.                                    inTableStruct->border_right_width);
  6343.                 break;
  6344.             
  6345.             default:
  6346.                 Assert_(false);
  6347.             }
  6348.                     
  6349.         // restore UGraphicGizmos::sLighter
  6350.         UGraphicGizmos::sLighter = savedLighter;
  6351.         }
  6352. }
  6353.  
  6354. void CHTMLView::DisplaySolidBorder(
  6355.     const Rect&                inFrame,
  6356.     const RGBColor&            inBorderColor,
  6357.     Int32                    inTopWidth,
  6358.     Int32                    inLeftWidth,
  6359.     Int32                    inBottomWidth,
  6360.     Int32                    inRightWidth)
  6361. {
  6362.     StColorPenState state;
  6363.     state.Normalize();
  6364.     ::RGBForeColor(&inBorderColor);
  6365.     // Check for easy case -- all border widths equal
  6366.     if (inTopWidth == inLeftWidth &&
  6367.         inTopWidth == inBottomWidth &&
  6368.         inTopWidth == inRightWidth)
  6369.     {
  6370.         ::PenSize(inTopWidth, inTopWidth);
  6371.         ::FrameRect(&inFrame);
  6372.     }
  6373.     else
  6374.     {
  6375.         // Otherwise manually draw each side
  6376.         if (inTopWidth > 0)
  6377.         {
  6378.             ::PenSize(1, inTopWidth);
  6379.             ::MoveTo(inFrame.left, inFrame.top);
  6380.             ::LineTo(inFrame.right, inFrame.top);
  6381.         }
  6382.         if (inLeftWidth > 0)
  6383.         {
  6384.             ::PenSize(inLeftWidth, 1);
  6385.             ::MoveTo(inFrame.left, inFrame.top);
  6386.             ::LineTo(inFrame.left, inFrame.bottom);
  6387.         }
  6388.         if (inBottomWidth > 0)
  6389.         {
  6390.             ::PenSize(1, inBottomWidth);
  6391.             // Don't forget, pen draws down and to the right
  6392.             ::MoveTo(inFrame.left, inFrame.bottom - inBottomWidth);
  6393.             ::LineTo(inFrame.right, inFrame.bottom - inBottomWidth);
  6394.         }
  6395.         if (inRightWidth > 0)
  6396.         {
  6397.             ::PenSize(inRightWidth, 1);
  6398.             // Don't forget, pen draws down and to the right
  6399.             ::MoveTo(inFrame.right - inRightWidth, inFrame.bottom);
  6400.             ::LineTo(inFrame.right - inRightWidth, inFrame.top);
  6401.         }
  6402.     }
  6403. }
  6404.  
  6405. Uint16 AddWithoutOverflow(Uint16 base, Uint16 addition)
  6406. {
  6407.     if ((base + addition) > 0xFFFF)
  6408.     {
  6409.         // overflow, return max Uint16 value
  6410.         return 0xFFFF;
  6411.     }
  6412.     else
  6413.         return base + addition;
  6414. }
  6415.  
  6416. Uint16 SubWithoutUnderflow(Uint16 base, Uint16 difference)
  6417. {
  6418.     if ((base - difference) < 0x0000)
  6419.     {
  6420.         // underflow, return 0
  6421.         return 0x0000;
  6422.     }
  6423.     else
  6424.         return base - difference;
  6425. }
  6426.  
  6427. void ComputeBevelColor(Boolean inRaised, RGBColor inBaseColor, RGBColor& outBevelColor)
  6428. {
  6429.     if (inRaised)
  6430.     {
  6431.         outBevelColor.red = AddWithoutOverflow(inBaseColor.red, TableBorder_TintLevel);
  6432.         outBevelColor.green = AddWithoutOverflow(inBaseColor.green, TableBorder_TintLevel);
  6433.         outBevelColor.blue = AddWithoutOverflow(inBaseColor.blue, TableBorder_TintLevel);
  6434.     }
  6435.     else
  6436.     {
  6437.         outBevelColor.red = SubWithoutUnderflow(inBaseColor.red, TableBorder_TintLevel);
  6438.         outBevelColor.green = SubWithoutUnderflow(inBaseColor.green, TableBorder_TintLevel);
  6439.         outBevelColor.blue = SubWithoutUnderflow(inBaseColor.blue, TableBorder_TintLevel);
  6440.     }
  6441. }
  6442.  
  6443. void CHTMLView::DisplayBevelBorder(
  6444.     const Rect&                inFrame,
  6445.     const RGBColor&            inBorderColor,
  6446.     Boolean                    inRaised,
  6447.     Int32                    inTopWidth,
  6448.     Int32                    inLeftWidth,
  6449.     Int32                    inBottomWidth,
  6450.     Int32                    inRightWidth)
  6451. {
  6452.     // 97-06-10 pkc -- No longer use UGraphicGizmos::BevelRect
  6453.     StColorPenState state;
  6454.     state.Normalize();
  6455.     PolyHandle poly = NULL;
  6456.     RGBColor raisedBevelColor, loweredBevelColor;
  6457.     ComputeBevelColor(true, inBorderColor, raisedBevelColor);
  6458.     ComputeBevelColor(false, inBorderColor, loweredBevelColor);
  6459.     // First do top and left sides
  6460.     if (inTopWidth > 0 || inLeftWidth > 0)
  6461.     {
  6462.         poly = OpenPoly();
  6463.         if (inRaised)
  6464.             ::RGBForeColor(&raisedBevelColor);
  6465.         else
  6466.             ::RGBForeColor(&loweredBevelColor);
  6467.         ::MoveTo(inFrame.left, inFrame.top);
  6468.         if (inTopWidth > 0)
  6469.         {
  6470.             ::LineTo(inFrame.right, inFrame.top);
  6471.             ::LineTo(inFrame.right - inRightWidth, inFrame.top + inTopWidth);
  6472.             ::LineTo(inFrame.left + inLeftWidth, inFrame.top + inTopWidth);
  6473.         }
  6474.         if (inLeftWidth > 0)
  6475.         {
  6476.             if (inTopWidth == 0)
  6477.                 ::LineTo(inFrame.left + inLeftWidth, inFrame.top + inTopWidth);
  6478.             ::LineTo(inFrame.left + inLeftWidth, inFrame.bottom - inBottomWidth);
  6479.             ::LineTo(inFrame.left, inFrame.bottom);
  6480.         }
  6481.         ::ClosePoly();
  6482.         ::PaintPoly(poly);
  6483.         ::KillPoly(poly);
  6484.         poly = NULL;
  6485.     }
  6486.     if (inRightWidth > 0 || inBottomWidth > 0)
  6487.     {
  6488.         poly = OpenPoly();
  6489.         // Then do bottom and right sides
  6490.         if (inRaised)
  6491.             ::RGBForeColor(&loweredBevelColor);
  6492.         else
  6493.             ::RGBForeColor(&raisedBevelColor);
  6494.         ::MoveTo(inFrame.right, inFrame.bottom);
  6495.         if (inRightWidth > 0)
  6496.         {
  6497.             ::LineTo(inFrame.right, inFrame.top);
  6498.             ::LineTo(inFrame.right - inRightWidth, inFrame.top + inTopWidth);
  6499.             ::LineTo(inFrame.right - inRightWidth, inFrame.bottom - inBottomWidth);
  6500.         }
  6501.         if (inBottomWidth > 0)
  6502.         {
  6503.             if (inRightWidth == 0)
  6504.                 ::LineTo(inFrame.right - inRightWidth, inFrame.bottom - inBottomWidth);
  6505.             ::LineTo(inFrame.left + inLeftWidth, inFrame.bottom - inBottomWidth);
  6506.             ::LineTo(inFrame.left, inFrame.bottom);
  6507.         }
  6508.         ::ClosePoly();
  6509.         ::PaintPoly(poly);
  6510.         ::KillPoly(poly);
  6511.         poly = NULL;
  6512.     }
  6513. }
  6514.  
  6515. void CHTMLView::DisplayGrooveRidgeBorder(
  6516.     const Rect&                inFrame,
  6517.     const RGBColor&            inBorderColor,
  6518.     Boolean                    inIsGroove,
  6519.     Int32                    inTopWidth,
  6520.     Int32                    inLeftWidth,
  6521.     Int32                    inBottomWidth,
  6522.     Int32                    inRightWidth)
  6523. {
  6524.     Rect theFrame = inFrame;
  6525.     Int32 borderTopWidth = inTopWidth / 2;
  6526.     Int32 borderLeftWidth = inLeftWidth / 2;
  6527.     Int32 borderBottomWidth = inBottomWidth / 2;
  6528.     Int32 borderRightWidth = inRightWidth / 2;
  6529.  
  6530.     // draw outer border
  6531.     DisplayBevelBorder(theFrame,
  6532.                        inBorderColor,
  6533.                        inIsGroove ? false : true,
  6534.                        borderTopWidth,
  6535.                        borderLeftWidth,
  6536.                        borderBottomWidth,
  6537.                        borderRightWidth);
  6538.     // adjust frame
  6539.     theFrame.top += borderTopWidth;
  6540.     theFrame.left += borderLeftWidth;
  6541.     theFrame.bottom -= borderBottomWidth;
  6542.     theFrame.right -= borderRightWidth;
  6543.     // draw inner border
  6544.     DisplayBevelBorder(theFrame,
  6545.                        inBorderColor,
  6546.                        inIsGroove ? true : false,
  6547.                        borderTopWidth,
  6548.                        borderLeftWidth,
  6549.                        borderBottomWidth,
  6550.                        borderRightWidth);
  6551. }
  6552.  
  6553. void CHTMLView::DisplayCell(
  6554.     int                     /* inLocation */,
  6555.     LO_CellStruct*            inCellStruct)
  6556. {
  6557.     if (!FocusDraw() )
  6558.         return;
  6559.  
  6560.     // Ñ subdoc->width + borderWidth, subdoc->height + borderWidth);
  6561.     Rect theFrame;
  6562.     if (CalcElementPosition( (LO_Element*)inCellStruct, theFrame ))
  6563.         {
  6564.  
  6565.         // Ñ╩this is really slow LAM
  6566.         for ( int i = 1; i <= inCellStruct->border_width; i++ )
  6567.             {
  6568.             UGraphics::FrameRectShaded( theFrame, true );
  6569.             ::InsetRect( &theFrame, 1, 1 );
  6570.             }
  6571.         }
  6572. }
  6573.  
  6574. void CHTMLView::InvalidateEntireTableOrCell(LO_Element*)
  6575. {
  6576.     /* composer only */
  6577. }
  6578.  
  6579. void CHTMLView::DisplayAddRowOrColBorder(XP_Rect*, XP_Bool    /*inDoErase*/)
  6580. {
  6581.     /* composer only */
  6582. }
  6583.  
  6584. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  6585. //    Ñ    
  6586. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  6587.  
  6588. Boolean CHTMLView::CalcElementPosition(
  6589.     LO_Element*             inElement,
  6590.     Rect&                     outFrame)
  6591. {
  6592.     //    This function takes the real position of a layout element,
  6593.     //    .. and returns the local position and whether it is visible.
  6594.     //    the calculated position is valid, even if the element is not currently visible
  6595.  
  6596.     XP_Rect            absoluteFrame;
  6597.     Point            portOrigin;
  6598.     SPoint32        frameLocation;
  6599.     SDimension16    frameSize;
  6600.     SPoint32        imageLocation;
  6601.     Boolean            isVisible;
  6602.  
  6603.     portOrigin.h = 0; portOrigin.v = 0;
  6604.     PortToLocalPoint (portOrigin);
  6605.     GetFrameLocation (frameLocation);
  6606.     GetFrameSize (frameSize);
  6607.     GetImageLocation (imageLocation);
  6608.  
  6609.     long realFrameLeft         = frameLocation.h - imageLocation.h;
  6610.     long realFrameRight     = realFrameLeft + frameSize.width;
  6611.     long realFrameTop         = frameLocation.v - imageLocation.v;
  6612.     long realFrameBottom     = realFrameTop + frameSize.height;
  6613.  
  6614.     CalcAbsoluteElementPosition (inElement, absoluteFrame);
  6615.  
  6616.     isVisible = realFrameRight > absoluteFrame.left
  6617.         &&    realFrameLeft < absoluteFrame.right
  6618.         &&    realFrameBottom > absoluteFrame.top
  6619.         &&    realFrameTop < absoluteFrame.bottom;
  6620.  
  6621.     outFrame.left = absoluteFrame.left + portOrigin.h + imageLocation.h;
  6622.     outFrame.top = absoluteFrame.top + portOrigin.v + imageLocation.v;
  6623.     outFrame.right = outFrame.left + inElement->lo_any.width;
  6624.     outFrame.bottom = outFrame.top + inElement->lo_any.height;
  6625.  
  6626.     return isVisible;
  6627. }
  6628.  
  6629. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  6630. //    Ñ    
  6631. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  6632.  
  6633. void CHTMLView::CalcAbsoluteElementPosition(
  6634.     LO_Element*                inElement,
  6635.     XP_Rect&                outFrame)
  6636. {
  6637.     // calculates the position of a layout element within the document, disregarding
  6638.     // scroll positions and whatnot
  6639.  
  6640.     // make sure we have the actual element position
  6641.     long elementPosLeft     = inElement->lo_any.x + inElement->lo_any.x_offset;
  6642.     long elementPosTop         = inElement->lo_any.y + inElement->lo_any.y_offset;
  6643.  
  6644. #ifdef LAYERS
  6645.     int32    layerOriginX,layerOriginY;
  6646.  
  6647.     if (mCurrentDrawable != NULL)
  6648.         mCurrentDrawable->GetLayerOrigin ( &layerOriginX, &layerOriginY );
  6649.     else {
  6650.         layerOriginX = mLayerOrigin.h;
  6651.         layerOriginY = mLayerOrigin.v;
  6652.     }
  6653.         
  6654.     elementPosLeft += layerOriginX;
  6655.     elementPosTop += layerOriginY;
  6656. #endif
  6657.  
  6658.     outFrame.left = elementPosLeft;
  6659.     outFrame.top = elementPosTop;
  6660.     outFrame.right = outFrame.left + inElement->lo_any.width;
  6661.     outFrame.bottom = outFrame.top + inElement->lo_any.height;
  6662. }
  6663.  
  6664. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  6665. //    Ñ    
  6666. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  6667.  
  6668. void CHTMLView::CreateGridView(
  6669.     CBrowserContext*        inGridContext,
  6670.     Int32                    inX,
  6671.     Int32                     inY,
  6672.     Int32                    inWidth,
  6673.     Int32                    inHeight,
  6674.     Int8                    inScrollMode,
  6675.     Bool                     inNoEdge)
  6676. {
  6677.  
  6678.     CHyperScroller* theContainer = NULL;
  6679.  
  6680.     try
  6681.     {
  6682. //        URL_Struct*            request = NULL;
  6683. //        CHyperScroller*        theContainer;
  6684. //        MWContext*            newContext;
  6685. //        CHyperView*            newView;
  6686.  
  6687.         SetScrollMode(LO_SCROLL_NO);
  6688.         mShowFocus = false;
  6689.         
  6690.         FocusDraw();
  6691.         LCommander::SetDefaultCommander( this );
  6692.         LPane::SetDefaultView( this );
  6693.  
  6694.         theContainer = (CHyperScroller*)UReanimator::ReadObjects('PPob', 1005);
  6695.         ThrowIfNULL_(theContainer);
  6696.         theContainer->FinishCreate();
  6697.         
  6698.         CHTMLView* theNewView = (CHTMLView*)theContainer->FindPaneByID(2005);
  6699.         ThrowIfNULL_(theNewView);
  6700.     
  6701.         // Ñ position it
  6702.         theNewView->mNoBorder = inNoEdge;
  6703.         theNewView->SetSuperHTMLView(this);
  6704.  
  6705.         Rect theOwningFrame;
  6706.         CalcLocalFrameRect(theOwningFrame);
  6707.  
  6708.         Rect theNewFrame;
  6709.         CropFrameToContainer(inX, inY, inWidth, inHeight, theNewFrame);
  6710.  
  6711.         CHyperScroller* theSuperScroller = mScroller;
  6712.         if (!theNewView->mNoBorder)
  6713.             {
  6714.             //    for each side that intersects the container, 
  6715.             //    expand the container out one
  6716.             if (inX == 0)
  6717.                 if (theSuperScroller)
  6718.                     theSuperScroller->ExpandLeft();
  6719.                 
  6720.             if (inY == 0)
  6721.                 if (theSuperScroller)
  6722.                     theSuperScroller->ExpandTop();
  6723.  
  6724.             if (theNewFrame.right == theOwningFrame.right)
  6725.                 if (theSuperScroller)
  6726.                     theSuperScroller->ExpandRight();
  6727.                 
  6728.             if (theNewFrame.bottom == theOwningFrame.bottom)
  6729.                 if (theSuperScroller)
  6730.                     theSuperScroller->ExpandBottom();
  6731.             
  6732.             if (theSuperScroller)
  6733.                 theSuperScroller->AdjustHyperViewBounds();
  6734.             }
  6735.         else
  6736.             {
  6737.             theContainer->ExpandLeft();
  6738.             theContainer->ExpandTop();
  6739.             theContainer->ExpandRight();
  6740.             theContainer->ExpandBottom();
  6741.             theContainer->AdjustHyperViewBounds();
  6742.             }
  6743.                                     
  6744.         CropFrameToContainer(inX, inY, inWidth, inHeight, theNewFrame);
  6745.  
  6746.         theContainer->PlaceInSuperFrameAt(theNewFrame.left, theNewFrame.top, true);
  6747.         theContainer->ResizeFrameTo(RectWidth(theNewFrame), RectHeight(theNewFrame), false);
  6748.  
  6749.         if (theSuperScroller)
  6750.             theSuperScroller->AdjustHyperViewBounds();
  6751.         theContainer->AdjustHyperViewBounds();
  6752.  
  6753.         theNewView->SetScrollMode(inScrollMode);
  6754.         // 97-05-07 pkc -- if inNoEdge is true, we've got a borderless frame, don't
  6755.         // display frame focus
  6756.         if (!inNoEdge)
  6757.             theNewView->mShowFocus = true;
  6758.  
  6759.         // Ñ so that we call scroller's activate, and it actually enables the scrollbars
  6760. //        theContainer->ActivateSelf();
  6761. // FIX ME!!! this used to be the line above.  I hope this still works
  6762.         theContainer->Activate();
  6763.         
  6764.         if (theSuperScroller)
  6765.             theSuperScroller->Refresh();
  6766.  
  6767.         theNewView->SetContext(inGridContext);
  6768.         mHasGridCells = true;
  6769.         
  6770.             // give the grid context the same listeners as the root context
  6771.         mContext->CopyListenersToContext(inGridContext);    
  6772.         }
  6773.     catch (...)
  6774.         {
  6775.         delete theContainer;
  6776.         throw;
  6777.         }
  6778.  
  6779. }
  6780.  
  6781. void CHTMLView::CropFrameToContainer(
  6782.     Int32        inImageLeft,
  6783.     Int32        inImageTop,
  6784.     Int32        inImageWidth,
  6785.     Int32        inImageHeight,
  6786.     Rect&        outLocalFrame) const
  6787. {
  6788.     Rect theOwningFrame;
  6789.     CalcLocalFrameRect(theOwningFrame);
  6790.  
  6791.     SPoint32 theImageTopLeft;
  6792.     theImageTopLeft.h = inImageLeft;
  6793.     theImageTopLeft.v = inImageTop;
  6794.  
  6795.     SPoint32 theImageBotRight;
  6796.     theImageBotRight.h = inImageLeft + inImageWidth;
  6797.     theImageBotRight.v = inImageTop + inImageHeight;
  6798.  
  6799.     ImageToLocalPoint(theImageTopLeft, topLeft(outLocalFrame));
  6800.     ImageToLocalPoint(theImageBotRight, botRight(outLocalFrame));
  6801.     
  6802.     ::SectRect(&theOwningFrame, &outLocalFrame, &outLocalFrame);
  6803. }
  6804.  
  6805. // ---------------------------------------------------------------------------
  6806. //        Ñ CalcStandardSizeForWindowForScreen
  6807. // ---------------------------------------------------------------------------
  6808.  
  6809. void
  6810. CHTMLView::CalcStandardSizeForWindowForScreen(
  6811.     CHTMLView*            inTopMostHTMLView,
  6812.     const LWindow&        inWindow,
  6813.     const Rect&            inScreenBounds,
  6814.     SDimension16&        outStandardSize)
  6815. {
  6816.     bool                haveAnHTMLView = false;
  6817.     Rect                minMaxSize;
  6818.     SDimension16        htmlFrameSize;
  6819.     SDimension16        windowContentSize;
  6820.     SDimension32        htmlImageSize;
  6821.      CBrowserContext*    theTopContext = nil;
  6822.     Boolean                puntToADefaultStandardSize = false;
  6823.     
  6824.     if (CApplicationEventAttachment::CurrentEventHasModifiers(optionKey))
  6825.     {
  6826.         outStandardSize.width = max_Int16;
  6827.         outStandardSize.height = max_Int16;
  6828.  
  6829.         return;
  6830.     }
  6831.     
  6832.     inWindow.GetMinMaxSize(minMaxSize);
  6833.     inWindow.GetFrameSize(windowContentSize);
  6834.     
  6835.     //    Note: If inTopMostHTMLView is nil, then we use the punt size
  6836.  
  6837.     if (inTopMostHTMLView)
  6838.     {
  6839.         theTopContext = inTopMostHTMLView->GetContext();
  6840.         
  6841.         // Get the image size of the html view
  6842.         
  6843.         inTopMostHTMLView->GetImageSize(htmlImageSize);
  6844.         htmlImageSize.width = MIN(htmlImageSize.width, max_Int16);
  6845.         htmlImageSize.height = MIN(htmlImageSize.height, max_Int16);
  6846.  
  6847.         if (htmlImageSize.width != 0 && htmlImageSize.height != 0)
  6848.         {
  6849.             haveAnHTMLView = true;
  6850.         }
  6851.     }
  6852.         
  6853.     // Calculate standard size
  6854.     
  6855.     if (theTopContext && haveAnHTMLView)
  6856.     {        
  6857.         CBrowserContext* theTopContext = inTopMostHTMLView->GetContext();
  6858.         
  6859.         ThrowIfNil_(theTopContext);
  6860.         
  6861.         if (!theTopContext->CountGridChildren())
  6862.         {
  6863.             // Get the frame size of the html view
  6864.             
  6865.             inTopMostHTMLView->GetFrameSize(htmlFrameSize);
  6866.             
  6867.             outStandardSize.width = ((windowContentSize.width - htmlFrameSize.width) + htmlImageSize.width);
  6868.             outStandardSize.height = ((windowContentSize.height - htmlFrameSize.height) + htmlImageSize.height);
  6869.             
  6870.             // Shrink the standard size in each dimension if the other dimension has a scroll bar
  6871.             // which will disappear at the new standard size. We attempt to adjust the standard
  6872.             // size height first. If the standard width for the screen does cause a previous
  6873.             // horizontal scrollbar to disappear then we adjust the height. We remember whether
  6874.             // it was adjusted. Then we attempt to adjust the width. Then we try once more on the
  6875.             // height if it wasn't already adjusted.
  6876.             
  6877.             Boolean heightAdjusted = false;
  6878.             
  6879.             if (inTopMostHTMLView->GetScroller() &&
  6880.                 inTopMostHTMLView->GetScroller()->HasHorizontalScrollbar() &&
  6881.                 outStandardSize.width < (inScreenBounds.right - inScreenBounds.left))
  6882.             {
  6883.                 outStandardSize.height -= (ScrollBar_Size - 1);
  6884.                 heightAdjusted = true;
  6885.             }                
  6886.             
  6887.             if (inTopMostHTMLView->GetScroller() &&
  6888.                 inTopMostHTMLView->GetScroller()->HasVerticalScrollbar() &&
  6889.                 outStandardSize.height < (inScreenBounds.bottom - inScreenBounds.top))
  6890.             {
  6891.                 outStandardSize.width -= (ScrollBar_Size - 1);
  6892.             }                
  6893.                 
  6894.             if (inTopMostHTMLView->GetScroller() &&
  6895.                 inTopMostHTMLView->GetScroller()->HasHorizontalScrollbar() &&
  6896.                 outStandardSize.width < (inScreenBounds.right - inScreenBounds.left) &&
  6897.                 !heightAdjusted)
  6898.             {
  6899.                 outStandardSize.height -= (ScrollBar_Size - 1);
  6900.                 heightAdjusted = true;
  6901.             }                
  6902.     
  6903.             // Don't shrink window smaller than the minimum size
  6904.             
  6905.             if (outStandardSize.width < minMaxSize.left)
  6906.                 outStandardSize.width = minMaxSize.left;
  6907.             
  6908.             if (outStandardSize.height < minMaxSize.top)
  6909.                 outStandardSize.height = minMaxSize.top;
  6910.         }
  6911.         else
  6912.         {
  6913.             // We have frames.
  6914.             //
  6915.             // We will pick a "reasonable" size out of our... Note that Akbar would
  6916.             // simply reuse the mStandardSize for the previously viewed page (which
  6917.             // produces inconsistent results when zooming a given frames page). At least
  6918.             // this method will produce consistent results.
  6919.             //
  6920.             // It would be cool, of course, if we could figure out which frames should
  6921.             // contribute to the calculation of the new width and height of the window
  6922.             // to miminize scrolling and do that instead. That would produce a better
  6923.             // standard size for frame documents.
  6924.             
  6925.             puntToADefaultStandardSize = true;
  6926.         }
  6927.     }
  6928.     else
  6929.     {
  6930.         // No context or top-most context is not and html view or the user held
  6931.         // down the optionKey, so we just punt
  6932.         
  6933.         puntToADefaultStandardSize = true;
  6934.     }
  6935.     
  6936.     if (puntToADefaultStandardSize)
  6937.     {
  6938.         Int16 height    = 850;
  6939.         Int16 width        = 0.85 * height;
  6940.         
  6941.         // If the punt height is greater than the screen height then
  6942.         // recalculate with a punt height equal to the screen height.
  6943.         
  6944.         if ((inScreenBounds.bottom - inScreenBounds.top) < height)
  6945.         {
  6946.             height    = inScreenBounds.bottom - inScreenBounds.top;
  6947.             width    = 0.85 * height;
  6948.         }
  6949.         
  6950.         outStandardSize.width = width;
  6951.         outStandardSize.height = height;
  6952.     }
  6953. }
  6954.  
  6955. void CHTMLView::GetFullGridSize(
  6956.     Int32&                    outWidth,
  6957.     Int32&                    outHeight)
  6958. {
  6959.     // FIX ME!!! here's another thing that will need to change
  6960.     // when the scroller dependency is removed.
  6961.     if (mScroller != NULL)
  6962.         {
  6963.         SDimension16 theContainerSize;
  6964.         mScroller->GetFrameSize(theContainerSize);
  6965.         outWidth = theContainerSize.width;
  6966.         outHeight = theContainerSize.height;
  6967.         }
  6968.     else
  6969.         {
  6970.         Assert_(false);
  6971.         outWidth = outHeight = 0;
  6972.         }
  6973. }
  6974.  
  6975. void CHTMLView::RestructureGridView(
  6976.     Int32                    inX,
  6977.     Int32                     inY,
  6978.     Int32                    inWidth,
  6979.     Int32                    inHeight)
  6980. {
  6981.     mSuperHTMLView->FocusDraw();
  6982.     
  6983.     if (mScroller != NULL)
  6984.         {
  6985.         CHyperScroller* theSuperScroller = mScroller;
  6986.         
  6987.         Rect theNewFrame;
  6988.         mSuperHTMLView->CropFrameToContainer(inX, inY, inWidth, inHeight, theNewFrame);
  6989.         theSuperScroller->PlaceInSuperFrameAt(theNewFrame.left, theNewFrame.top, false);
  6990.         theSuperScroller->ResizeFrameTo(RectWidth(theNewFrame), RectHeight(theNewFrame), false);
  6991.         theSuperScroller->AdjustHyperViewBounds();
  6992.         }
  6993.         
  6994. //    if ( mContext )
  6995. //    {
  6996. //        History_entry* he = SHIST_GetCurrent( &fHContext->hist );
  6997. //        if ( !he || he->is_binary )
  6998. //        {
  6999. //            this->Refresh();
  7000. //            this->ReadjustScrollbars( TRUE );
  7001. //            this->Refresh();
  7002. //            return;
  7003. //        }
  7004. //    }
  7005.     
  7006.     // Ñ causes repositioning of the scrollbars
  7007.     SetScrollMode(mDefaultScrollMode, true); 
  7008.     ClearBackground();
  7009.     mContext->Repaginate();
  7010. }
  7011.  
  7012. /*
  7013. // MAY WANT TO ADD HERE AS BSE IMPLEMENTATION
  7014. void CHTMLView::BeginPreSection(void)
  7015. {
  7016.     // Empty NS_xxx implementation
  7017. }
  7018.  
  7019. void CHTMLView::EndPreSection(void)
  7020. {
  7021.     // Empty NS_xxx implementation
  7022. }
  7023.  
  7024. */
  7025.  
  7026. #pragma mark -
  7027.  
  7028. // ---------------------------------------------------------------------------
  7029. //        Ñ CDragURLTask
  7030. // ---------------------------------------------------------------------------
  7031.  
  7032. CDragURLTask::CDragURLTask(
  7033.     const EventRecord&    inEventRecord,
  7034.     const Rect&         inGlobalFrame,
  7035.     CHTMLView&             inHTMLView)
  7036.     :    mGlobalFrame(inGlobalFrame),
  7037.         mHTMLView(inHTMLView),
  7038.     
  7039.         super(inEventRecord)
  7040. {
  7041. }
  7042.  
  7043. // ---------------------------------------------------------------------------
  7044. //        Ñ AddFlavors
  7045. // ---------------------------------------------------------------------------
  7046.                                     
  7047. void
  7048. CDragURLTask::AddFlavors(
  7049.     DragReference        /* inDragRef */)
  7050. {
  7051.     OSErr theErr;
  7052.  
  7053.     // If the option-key is down and the element is an image, we drag as a PICT, even to the finder..
  7054.     // If not, we drag real image data (JPEF or GIF)..
  7055.     Boolean isOptionDown = ((mEventRecord.modifiers & optionKey) != 0);
  7056.  
  7057.     if (mHTMLView.mDragElement->type != LO_IMAGE || !isOptionDown)
  7058.     {
  7059.         AddFlavorBookmarkFile(static_cast<ItemReference>(this));
  7060.     }
  7061.  
  7062.     AddFlavorURL(static_cast<ItemReference>(this));
  7063.     
  7064.     AddFlavorBookmark(static_cast<ItemReference>(this));
  7065.     
  7066.     // Add a PICT flavor for images
  7067.  
  7068.     if (mHTMLView.mDragElement->type == LO_IMAGE)
  7069.     {
  7070.         LO_ImageStruct* imageElement = (LO_ImageStruct*)mHTMLView.mDragElement;
  7071.  
  7072.         if (!IsInternalTypeLink((char*)imageElement->image_url) || IsMailNewsReconnect((char*)imageElement->image_url))
  7073.         {
  7074.             // flavorSenderTranslated will prevent us from being saved as a PICT clipping
  7075.             // in the Finder.  When the option key is down, this is exactly what we want
  7076.             
  7077.             FlavorFlags    flavorFlags = (isOptionDown) ?  0 : flavorSenderTranslated;
  7078.             theErr = ::AddDragItemFlavor (mDragRef, (ItemReference) this, 'PICT', nil, 0, flavorFlags);
  7079.             ThrowIfOSErr_(theErr);
  7080.         }
  7081.     }
  7082. }            
  7083.  
  7084. // ---------------------------------------------------------------------------
  7085. //        Ñ MakeDragRegion
  7086. // ---------------------------------------------------------------------------
  7087.     
  7088. void
  7089. CDragURLTask::MakeDragRegion(
  7090.     DragReference            /* inDragRef */,
  7091.     RgnHandle                /* inDragRegion */)
  7092. {
  7093.     AddRectDragItem((ItemReference)mHTMLView.mDragElement, mGlobalFrame);
  7094. }
  7095.                 
  7096. #pragma mark -
  7097.  
  7098. #if defined (JAVA)
  7099. void FlushEventHierarchyRecursive(LPane *currentPane)
  7100. {
  7101.     Hsun_awt_macos_MComponentPeer    *componentPeerHandle = PaneToPeer(currentPane);
  7102.  
  7103.     //    Flush the events associated with the component;
  7104.  
  7105.     if (componentPeerHandle != NULL) {
  7106.     
  7107.         //    Clear the interface queue of events related to the component to help garbage collection.
  7108.         
  7109.         ClassClass    *interfaceEventClass;
  7110.         
  7111.         interfaceEventClass = FindClass(EE(), "sun/awt/macos/InterfaceEvent", (PRBool)TRUE);
  7112.         
  7113.         if (interfaceEventClass != NULL) {
  7114.             MToolkitExecutJavaStaticMethod(interfaceEventClass, "flushInterfaceQueue", "(Lsun/awt/macos/MComponentPeer;)V", componentPeerHandle);
  7115.         }
  7116.     
  7117.         //    Recurse on the sub-panes
  7118.         
  7119.         if (unhand(componentPeerHandle)->mIsContainer) {
  7120.         
  7121.             LArrayIterator    iterator(((LView *)currentPane)->GetSubPanes());
  7122.             LPane            *theSub;
  7123.                 
  7124.             while (iterator.Next(&theSub))
  7125.                 FlushEventHierarchyRecursive(theSub);
  7126.         }
  7127.  
  7128.     }
  7129.     
  7130. }
  7131.  
  7132. void FlushEventHierarchy(LView *javaAppletView)
  7133. {
  7134.     LPane        *canvas = javaAppletView->FindPaneByID('cvpr');
  7135.  
  7136.     FlushEventHierarchyRecursive(canvas);
  7137.  
  7138. }
  7139. #endif /* defined (JAVA) */
  7140.