home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-04-08 | 49.6 KB | 1,580 lines |
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
- #include "mprint.h"
-
- #include "CHTMLView.h"
- #include "CBrowserContext.h"
- #include "CHyperScroller.h"
- #include "UGraphicGizmos.h"
-
- #include "LListener.h"
- #include "LPrintout.h"
- #include "PascalString.h"
- #include "LCaption.h"
-
- #include "MoreMixedMode.h"
-
-
- #define NONE_FORM 1
- #define PAGE_NUMBER_FORM 2
- #define DATE_FORM 3
- #define LOCATION_FORM 4
- #define TITLE_FORM 5
-
- #include "macutil.h"
- #include "earlmgr.h"
- #include "resgui.h"
- #include "macgui.h" // for UGraphics
- #include "uerrmgr.h"
- #include "shist.h"
- #include "libi18n.h"
- #include "xlate.h"
- #include "np.h"
-
- #include "mimages.h"
- #include "mplugin.h"
-
- #pragma mark --- CPrintHTMLView ---
-
- //======================================
- class CPrintHTMLView : public CHTMLView
- //======================================
- {
- private:
- typedef CHTMLView Inherited;
- public:
-
- enum { class_ID = 'PtHt' };
- enum printMode {
- epmBlockDisplay,
- epmLayout,
- epmDisplay
- };
- CPrintHTMLView(LStream* inStream);
- virtual ~CPrintHTMLView();
- void CopyCharacteristicsFrom(const CHTMLView* inHTMLView);
-
- virtual void CountPanels(Uint32 &outHorizPanels, Uint32 &outVertPanels);
- virtual Boolean ScrollToPanel (const PanelSpec &inPanel);
-
- void SetPrintMode (printMode inMode)
- { mPrintMode = inMode; }
- void InitializeCapture (void);
- void CalculatePageBreaks (void);
-
- CL_Compositor* GetCompositor (void)
- { return mCompositor->mCompositor; }
-
- // overrides
-
- virtual void AdaptToSuperFrameSize(
- Int32 inSurrWidthDelta,
- Int32 inSurrHeightDelta,
- Boolean inRefresh);
-
- protected:
- virtual void FinishCreateSelf(void);
- virtual void InstallBackgroundColor();
- // Sets mBackgroundColor. Called from ClearBackground().
- // The base class implementation uses the text background
- // preference, but derived classes can override this.
- // Here we do nothing, because the background color is set
- // in CopyCharacteristicsFrom().
- virtual void GetFullGridSize(
- Int32& outWidth,
- Int32& outHeight);
- void CapturePosition (LO_Element *inElement);
- virtual void ResetBackgroundColor() const;
- // Calls RGBBackColor(mBackgroundColor). Printview overrides.
- virtual void DrawFrameFocus();
- virtual void DrawBackground(
- const Rect& inArea,
- LO_ImageStruct* inBackdrop = nil);
- virtual void EraseBackground(
- int inLocation,
- Int32 inX,
- Int32 inY,
- Uint32 inWidth,
- Uint32 inHeight,
- LO_Color* inColor);
-
- Boolean BelongsOnPage (LO_Element *inElement);
- inline Boolean BelongsOnPage (LO_TextStruct *inElement)
- { return BelongsOnPage ((LO_Element *) inElement); }
- inline Boolean BelongsOnPage (LO_LinefeedStruct *inElement)
- { return BelongsOnPage ((LO_Element *) inElement); }
- inline Boolean BelongsOnPage (LO_HorizRuleStruct *inElement)
- { return BelongsOnPage ((LO_Element *) inElement); }
- inline Boolean BelongsOnPage (LO_BullettStruct *inElement)
- { return BelongsOnPage ((LO_Element *) inElement); }
- inline Boolean BelongsOnPage (LO_EmbedStruct *inElement)
- { return BelongsOnPage ((LO_Element *) inElement); }
- inline Boolean BelongsOnPage (LO_TableStruct *inElement)
- { return BelongsOnPage ((LO_Element *) inElement); }
- inline Boolean BelongsOnPage (LO_CellStruct *inElement)
- { return BelongsOnPage ((LO_Element *) inElement); }
- Boolean BelongsOnPage (LO_FormElementStruct *inElement);
-
- virtual void DisplaySubtext(
- int inLocation,
- LO_TextStruct* inText,
- Int32 inStartPos,
- Int32 inEndPos,
- XP_Bool inNeedBG);
-
- virtual void DisplayText(
- int inLocation,
- LO_TextStruct* inText,
- XP_Bool inNeedBG);
-
- virtual void DisplayLineFeed(
- int inLocation,
- LO_LinefeedStruct* inLinefeedStruct,
- XP_Bool inNeedBG);
-
- virtual void DisplayHR(
- int inLocation,
- LO_HorizRuleStruct* inRuleStruct);
-
- virtual void DisplayBullet(
- int inLocation,
- LO_BullettStruct* inBulletStruct);
-
- virtual void DisplayEmbed(
- int inLocation,
- LO_EmbedStruct* inEmbedStruct);
-
- virtual void DisplayFormElement(
- int inLocation,
- LO_FormElementStruct* inFormElement);
-
- virtual void DisplayEdge(
- int inLocation,
- LO_EdgeStruct* inEdgeStruct);
-
- virtual void DisplayTable(
- int inLocation,
- LO_TableStruct* inTableStruct);
-
- virtual void DisplayCell(
- int inLocation,
- LO_CellStruct* inCellStruct);
-
- virtual void CreateGridView(
- CBrowserContext* inGridContext,
- Int32 inX,
- Int32 inY,
- Int32 inWidth,
- Int32 inHeight,
- Int8 inScrollMode,
- Bool inNoEdge);
-
- printMode mPrintMode;
- LArray mElementRects;
- LArray mVPanelRects;
- }; // class CPrintHTMLView
-
- //-----------------------------------
- CPrintHTMLView::CPrintHTMLView(LStream* inStream)
- : mElementRects(sizeof(XP_Rect)),
- mVPanelRects(sizeof(XP_Rect)),
-
- Inherited(inStream)
- //-----------------------------------
- {
- SetPrintMode (epmDisplay);
- SetScrollMode(LO_SCROLL_NO, false);
- }
-
- //-----------------------------------
- CPrintHTMLView::~CPrintHTMLView()
- //-----------------------------------
- {
- }
-
- // Override method to skip code in CHTMLView so that we don't call Repaginate() which
- // will destroy CPrintHTMLView early in printing process.
- //-----------------------------------
- void CPrintHTMLView::AdaptToSuperFrameSize(
- //-----------------------------------
- Int32 inSurrWidthDelta,
- Int32 inSurrHeightDelta,
- Boolean inRefresh)
- {
- LView::AdaptToSuperFrameSize(inSurrWidthDelta, inSurrHeightDelta, inRefresh);
- }
-
- //-----------------------------------
- void CPrintHTMLView::CopyCharacteristicsFrom(const CHTMLView* inHTMLView)
- //-----------------------------------
- {
- if (CPrefs::GetBoolean(CPrefs::PrintBackground))
- {
- // Transfer the back color from the view we're printing to the print view.
- // This is necessary because, e.g., message views and browser views have
- // different default background colors.
- LO_Color bc = UGraphics::MakeLOColor(inHTMLView->GetBackgroundColor());
- SetBackgroundColor(bc.red, bc.green, bc.blue);
- }
- }
-
- //-----------------------------------
- // our version works much like the inherited version (LView's), except we take into
- // account an HTML page's variable height.
- void CPrintHTMLView::CountPanels(
- //-----------------------------------
- Uint32 &outHorizPanels,
- Uint32 &outVertPanels)
- {
- SDimension32 imageSize;
- GetImageSize(imageSize);
-
- SDimension16 frameSize;
- GetFrameSize(frameSize);
-
- outHorizPanels = 1;
- if (frameSize.width > 0 && imageSize.width > 0)
- outHorizPanels = ((imageSize.width - 1) / frameSize.width) + 1;
-
- outVertPanels = mVPanelRects.GetCount();
- }
-
- //-----------------------------------
- Boolean CPrintHTMLView::ScrollToPanel (const PanelSpec &inPanel) {
- //-----------------------------------
-
- Boolean panelInImage;
- SDimension16 frameSize;
- GetFrameSize(frameSize);
-
- Uint32 horizPanelCount;
- Uint32 vertPanelCount;
- CountPanels(horizPanelCount, vertPanelCount);
-
- // rely on horizPanelCount, but use mVPanelRects for vertical displacement
- // the simple horizontal calculation is sufficient, since we don't mess with
- // horizontal displacement. But since we munge page heights, that's more complicated.
-
- panelInImage = false;
- if (inPanel.horizIndex <= horizPanelCount && inPanel.vertIndex <= vertPanelCount) {
- Int32 horizPos = frameSize.width * (inPanel.horizIndex - 1);
- Int32 vertPos;
- int32 pageHeight;
- XP_Rect panelVRect;
-
- panelInImage = mVPanelRects.FetchItemAt (inPanel.vertIndex, &panelVRect);
- vertPos = panelVRect.top;
- pageHeight = panelVRect.bottom - panelVRect.top;
- if (panelInImage) {
- ScrollImageTo (horizPos, vertPos, false);
-
- // now make XP_CheckElementSpan work for this page
- PrintInfo *pageInfo = ((MWContext *) *mContext)->prInfo;
- pageInfo->page_topy = vertPos;
- pageInfo->page_break = vertPos + pageHeight;
- pageInfo->page_height = pageHeight;
- pageInfo->page_width = frameSize.width;
-
- if (mCompositor)
- CL_ResizeCompositorWindow (*mCompositor, frameSize.width, pageHeight);
- }
- }
-
- return panelInImage;
- }
-
- //-----------------------------------
- void CPrintHTMLView::InitializeCapture (void)
- //-----------------------------------
- {
- mElementRects.RemoveItemsAt (mElementRects.GetCount(), LArray::index_First);
- mVPanelRects.RemoveItemsAt (mVPanelRects.GetCount(), LArray::index_First);
- }
-
- //-----------------------------------
- void CPrintHTMLView::CalculatePageBreaks (void)
- //-----------------------------------
- {
- Boolean breakBigElements; // a large element straddles the boundary; break it
- Rect pageArea;
- short pageHeight;
- XP_Rect vPanelRect, // page rect
- elementRect; // element rectangle
- int32 pageMajorLimit, // refuse to truncate the page past this point
- pageMinorLimit; // secondary page truncation limit
- ArrayIndexT element; // index into list of element rectangles
-
- CalcPortFrameRect (pageArea);
-
- pageHeight = pageArea.bottom - pageArea.top;
-
- vPanelRect.left = pageArea.left;
- vPanelRect.right = pageArea.right;
- vPanelRect.top = 0;
- vPanelRect.bottom = pageHeight;
-
- do {
- pageMajorLimit = vPanelRect.bottom - pageHeight / 2;
- pageMinorLimit = vPanelRect.bottom - pageHeight / 32;
- element = LArray::index_First;
- breakBigElements = false;
- while (mElementRects.FetchItemAt (element, &elementRect)) {
- element++;
- // if it spans the page boundary, it's trouble:
- if (elementRect.top < vPanelRect.bottom && elementRect.bottom > vPanelRect.bottom)
- // if it's bigger than a whole page, don't even consider it
- if (elementRect.bottom - elementRect.top < pageHeight) {
- // if we've decided to break on a big element, consider only small elements
- if (breakBigElements && elementRect.top < pageMinorLimit)
- continue;
- // bump up page bottom. if it's been bumped too far, reset and punt
- vPanelRect.bottom = elementRect.top;
- element = LArray::index_First;
- if (vPanelRect.bottom < pageMajorLimit) {
- vPanelRect.bottom = vPanelRect.top + pageHeight;
- breakBigElements = true;
- }
- }
- }
-
- // remove all elements occurring on this page
- element = LArray::index_First;
- while (mElementRects.FetchItemAt (element, &elementRect))
- if (elementRect.top < vPanelRect.bottom)
- mElementRects.RemoveItemsAt (1, element);
- else
- element++;
-
- // store page rect and prepare for next page
- mVPanelRects.InsertItemsAt (1, LArray::index_Last, &vPanelRect);
- vPanelRect.top = vPanelRect.bottom + 1;
- vPanelRect.bottom = vPanelRect.top + pageHeight;
- } while (mElementRects.GetCount() > 0);
- }
-
- //-----------------------------------
- void CPrintHTMLView::FinishCreateSelf(void)
- //-----------------------------------
- {
- /* Printing contexts want to be drawn back-to-front, only, and all in one pass,
- rather than on a delayed call-back system. The inherited method creates
- a compositor; we modify it. Note that while a CHTMLView's mCompositor
- is intended to be a _shared_ object, it appears that this one is used only
- while printing, so it seems safe to make printing-specific changes to it.
- */
- Inherited::FinishCreateSelf();
- CL_SetCompositorDrawingMethod (*mCompositor, CL_DRAWING_METHOD_BACK_TO_FRONT_ONLY);
- CL_SetCompositorFrameRate (*mCompositor, 0);
- }
-
- //-----------------------------------
- void CPrintHTMLView::InstallBackgroundColor()
- // Overridden to use a white background
- //-----------------------------------
- {
- if (!CPrefs::GetBoolean(CPrefs::PrintBackground))
- memset(&mBackgroundColor, 0xFF, sizeof(mBackgroundColor)); // white
- // Else do nothing: use the background color that we copied from the view
- // we're printing.
- }
- //-----------------------------------
- void CPrintHTMLView::ResetBackgroundColor() const
- //-----------------------------------
- {
- // do nothing.
- }
-
- //-----------------------------------
- void CPrintHTMLView::GetFullGridSize(
- Int32& outWidth,
- Int32& outHeight)
- //-----------------------------------
- {
- // We never have scrollers, but is this right? I'm fairly clueless...
- // The base class gets the size from mScroller which, of course, is null
- // for a print view...
- SDimension16 theContainerSize;
- this->GetFrameSize(theContainerSize);
- outWidth = theContainerSize.width;
- outHeight = theContainerSize.height;
- } // CPrintHTMLView::GetFullGridSize
-
- //-----------------------------------
- void CPrintHTMLView::CapturePosition (LO_Element *inElement) {
- //-----------------------------------
-
- XP_Rect rect;
-
- CalcAbsoluteElementPosition (inElement, rect);
-
- try {
- mElementRects.InsertItemsAt (1, LArray::index_Last, &rect);
- } catch (...) {
- // there's really no one to report this error to. if we're this out of memory,
- // something else is going to fail worse than this. failure to add this rect
- // to the list will only cause pagination to happen at inopportune positions.
- }
- }
-
- //-----------------------------------
- // does an object with the given top and height want to be rendered on the current page?
- Boolean
- CPrintHTMLView::BelongsOnPage (LO_Element *inElement) {
- //-----------------------------------
-
- Rect frame;
- return CalcElementPosition (inElement, frame);
- }
-
- //-----------------------------------
- // does an object with the given top and height want to be rendered on the current page?
- Boolean
- CPrintHTMLView::BelongsOnPage (LO_FormElementStruct *inElement) {
- //-----------------------------------
-
- Rect frame;
- Boolean rtnVal;
- #ifdef LAYERS
- // hack! HACK! HAAAACK!
- /* The element position calculation takes layer positions into account.
- That's normally good, except for form elements, which are implemented as PowerPlant
- subpanes. That's normally good, except that the compositor sticks each form element
- subpane into a layer of its own. No doubt the compositor thinks that's good, and
- normally we don't have a problem with that. But here, it results in the calculated
- position of the frame being multiplied by two (since the layer's position is added
- to the element's position). Here's where we temporarily convince our superclass
- that the current layer is at (0,0):
- */
- // note: if this ever gives you problems, you can probably replace it with simply
- // "return true" and let clipping decide who to display.
- CDrawable *drawable = mCurrentDrawable;
- SPoint32 origin = mLayerOrigin;
- mCurrentDrawable = NULL;
- mLayerOrigin.h = 0;
- mLayerOrigin.v = 0;
- #endif
- rtnVal = CalcElementPosition ((LO_Element *) inElement, frame);
- #ifdef LAYERS
- mCurrentDrawable = drawable;
- mLayerOrigin = origin;
- #endif
- return rtnVal;
- }
-
-
- //-----------------------------------
- void CPrintHTMLView::DisplaySubtext(
- int inLocation,
- LO_TextStruct* inText,
- Int32 inStartPos,
- Int32 inEndPos,
- XP_Bool inNeedBG)
- //-----------------------------------
- {
- switch (mPrintMode) {
- case epmBlockDisplay:
- break;
- case epmLayout:
- // do it all in DisplayText. the assumption here is that DisplaySubtext
- // will be called more often, but DisplayText will be called for each line
- break;
- case epmDisplay:
- if (FocusDraw() && BelongsOnPage (inText))
- Inherited::DisplaySubtext(inLocation, inText, inStartPos, inEndPos, inNeedBG);
- }
- } // CPrintHTMLView::DisplaySubtext
-
- //-----------------------------------
- void CPrintHTMLView::DisplayText(
- int inLocation,
- LO_TextStruct* inText,
- XP_Bool inNeedBG) {
- //-----------------------------------
-
- switch (mPrintMode) {
- case epmBlockDisplay:
- break;
- case epmLayout:
- CapturePosition ((LO_Element *) inText);
- break;
- case epmDisplay:
- if (FocusDraw() && BelongsOnPage (inText))
- Inherited::DisplayText (inLocation, inText, inNeedBG);
- }
- }
-
- //-----------------------------------
- void CPrintHTMLView::DisplayLineFeed(
- int inLocation,
- LO_LinefeedStruct* inLinefeedStruct,
- XP_Bool inNeedBG) {
- //-----------------------------------
-
- switch (mPrintMode) {
- case epmBlockDisplay:
- break;
- case epmLayout:
- CapturePosition ((LO_Element *) inLinefeedStruct);
- break;
- case epmDisplay:
- if (FocusDraw() && BelongsOnPage (inLinefeedStruct))
- Inherited::DisplayLineFeed(inLocation, inLinefeedStruct, inNeedBG);
- }
- }
-
-
- //-----------------------------------
- void CPrintHTMLView::DisplayHR(
- int inLocation,
- LO_HorizRuleStruct* inRuleStruct)
- //-----------------------------------
- {
- switch (mPrintMode) {
- case epmBlockDisplay:
- break;
- case epmLayout:
- CapturePosition ((LO_Element *) inRuleStruct);
- break;
- case epmDisplay:
- if (FocusDraw() && BelongsOnPage (inRuleStruct))
- Inherited::DisplayHR (inLocation, inRuleStruct);
- }
- } // CPrintHTMLView::DisplayHR
-
- //-----------------------------------
- void CPrintHTMLView::DisplayBullet(
- int inLocation,
- LO_BullettStruct* inBulletStruct) {
- //-----------------------------------
-
- switch (mPrintMode) {
- case epmBlockDisplay:
- break;
- case epmLayout:
- CapturePosition ((LO_Element *) inBulletStruct);
- break;
- case epmDisplay:
- if (FocusDraw() && BelongsOnPage (inBulletStruct))
- Inherited::DisplayBullet (inLocation, inBulletStruct);
- }
- } // CPrintHTMLView::DisplayBullet
-
- //-----------------------------------
- void CPrintHTMLView::DisplayEmbed(
- int /*inLocation*/,
- LO_EmbedStruct* inEmbedStruct) {
- //-----------------------------------
-
- switch (mPrintMode) {
- case epmBlockDisplay:
- break;
- case epmLayout:
- CapturePosition ((LO_Element *) inEmbedStruct);
- break;
- case epmDisplay:
- if (FocusDraw() && BelongsOnPage (inEmbedStruct))
- {
- NPEmbeddedApp* app = (NPEmbeddedApp*) inEmbedStruct->FE_Data;
- CPluginView* view = (CPluginView*) app->fe_data;
- view->EmbedDisplay(inEmbedStruct, true);
- }
- }
- }
-
- //-----------------------------------
- void CPrintHTMLView::DisplayFormElement(
- int inLocation,
- LO_FormElementStruct* inFormElement) {
- //-----------------------------------
-
- switch (mPrintMode) {
- case epmBlockDisplay:
- break;
- case epmLayout:
- CapturePosition ((LO_Element *) inFormElement);
- break;
- case epmDisplay:
- if (FocusDraw() && BelongsOnPage (inFormElement))
- Inherited::DisplayFormElement(inLocation, inFormElement);
- }
- }
-
- //-----------------------------------
- void CPrintHTMLView::DisplayEdge(
- int /*inLocation*/,
- LO_EdgeStruct* /*inEdgeStruct*/)
- //-----------------------------------
- {
- // Do nothing for printing.
- }
-
- //-----------------------------------
- void CPrintHTMLView::DisplayTable(
- int inLocation,
- LO_TableStruct* inTableStruct) {
- //-----------------------------------
-
- switch (mPrintMode) {
- case epmBlockDisplay:
- break;
- case epmLayout:
- CapturePosition ((LO_Element *) inTableStruct);
- break;
- case epmDisplay:
- if (FocusDraw() && BelongsOnPage (inTableStruct))
- Inherited::DisplayTable(inLocation, inTableStruct);
- }
- } // CPrintHTMLView::DisplayTable
-
- //-----------------------------------
- void CPrintHTMLView::DisplayCell(
- int inLocation,
- LO_CellStruct* inCellStruct) {
- //-----------------------------------
-
- switch (mPrintMode) {
- case epmBlockDisplay:
- break;
- case epmLayout:
- CapturePosition ((LO_Element *) inCellStruct);
- break;
- case epmDisplay:
- if (FocusDraw() && BelongsOnPage (inCellStruct))
- Inherited::DisplayCell (inLocation, inCellStruct);
- }
- } // CPrintHTMLView::DisplayCell
-
- //-----------------------------------
- void CPrintHTMLView::DrawFrameFocus()
- //-----------------------------------
- {
- // Do nothing for printing.
- } // CPrintHTMLView::DrawFrameFocus
-
- //-----------------------------------
- void CPrintHTMLView::DrawBackground(
- const Rect& inArea,
- LO_ImageStruct* inBackdrop)
- //-----------------------------------
- {
- // Ñ default white background for printing (also black text)
- if (!CPrefs::GetBoolean(CPrefs::PrintBackground))
- return;
- Inherited::DrawBackground(inArea, inBackdrop);
- } // CPrintHTMLView::DrawBackground
-
- //-----------------------------------
- void CPrintHTMLView::EraseBackground(
- int inLocation,
- Int32 inX,
- Int32 inY,
- Uint32 inWidth,
- Uint32 inHeight,
- LO_Color* inColor)
- //-----------------------------------
- {
- if (inColor != nil && !CPrefs::GetBoolean(CPrefs::PrintBackground))
- return;
- Inherited::EraseBackground(inLocation, inX, inY, inWidth, inHeight, inColor);
- } // CPrintHTMLView::EraseBackground
-
-
- //-----------------------------------
- void CPrintHTMLView::CreateGridView(
- CBrowserContext* inGridContext,
- Int32 inX,
- Int32 inY,
- Int32 inWidth,
- Int32 inHeight,
- Int8 inScrollMode,
- Bool inNoEdge)
- //-----------------------------------
- {
-
- CHyperScroller* theContainer = NULL;
-
- try
- {
- SetScrollMode(LO_SCROLL_NO, false);
- mShowFocus = false;
-
- FocusDraw();
- LCommander::SetDefaultCommander( this );
- LPane::SetDefaultView( this );
-
- theContainer = (CHyperScroller*)UReanimator::ReadObjects('PPob', 1002);
- ThrowIfNULL_(theContainer);
- theContainer->FinishCreate();
-
- CPrintHTMLView* theNewView = (CPrintHTMLView*)theContainer->FindPaneByID(2005);
- ThrowIfNULL_(theNewView);
-
- // Ñ position it
- theNewView->mNoBorder = inNoEdge;
- theNewView->SetSuperHTMLView(this);
-
- Rect theOwningFrame;
- CalcLocalFrameRect(theOwningFrame);
-
- Rect theNewFrame;
- CropFrameToContainer(inX, inY, inWidth, inHeight, theNewFrame);
-
- CHyperScroller* theSuperScroller = mScroller;
- if (!theNewView->mNoBorder)
- {
- // for each side that intersects the container,
- // expand the container out one
- if (inX == 0)
- if (theSuperScroller)
- theSuperScroller->ExpandLeft();
-
- if (inY == 0)
- if (theSuperScroller)
- theSuperScroller->ExpandTop();
-
- if (theNewFrame.right == theOwningFrame.right)
- if (theSuperScroller)
- theSuperScroller->ExpandRight();
-
- if (theNewFrame.bottom == theOwningFrame.bottom)
- if (theSuperScroller)
- theSuperScroller->ExpandBottom();
-
- if (theSuperScroller)
- theSuperScroller->AdjustHyperViewBounds();
- }
- else
- {
- theContainer->ExpandLeft();
- theContainer->ExpandTop();
- theContainer->ExpandRight();
- theContainer->ExpandBottom();
- theContainer->AdjustHyperViewBounds();
- }
-
- CropFrameToContainer(inX, inY, inWidth, inHeight, theNewFrame);
-
- theContainer->PlaceInSuperFrameAt(theNewFrame.left, theNewFrame.top, false);
- theContainer->ResizeFrameTo(RectWidth(theNewFrame), RectHeight(theNewFrame), false);
-
- if (theSuperScroller)
- theSuperScroller->AdjustHyperViewBounds();
- theContainer->AdjustHyperViewBounds();
-
- theNewView->SetScrollMode(inScrollMode);
- theNewView->mShowFocus = true;
-
- // Ñ so that we call scroller's activate, and it actually enables the scrollbars
- // theContainer->ActivateSelf();
- // FIX ME!!! this used to be the line above. I hope this still works
- theContainer->Activate();
-
- if (theSuperScroller)
- theSuperScroller->Refresh();
-
- theNewView->SetContext(inGridContext);
- mHasGridCells = true;
-
- // give the grid context the same listeners as the root context
- mContext->CopyListenersToContext(inGridContext);
- }
- catch (...)
- {
- delete theContainer;
- throw;
- }
-
- } // CPrintHTMLView::CreateGridView
-
- #pragma mark --- CPrintContext ---
- //======================================
- class CPrintContext : public CBrowserContext
- //======================================
- {
- public:
- CPrintContext();
- operator MWContext*() { return &mContext; }
- operator MWContext&() { return mContext; }
- }; // class CPrintContext
-
- //-----------------------------------
- CPrintContext::CPrintContext()
- : CBrowserContext(MWContextPrint)
- //-----------------------------------
- {
- mContext.fancyFTP = false;
- mContext.fancyNews = false;
-
- mContext.convertPixX = 1;
- mContext.convertPixY = 1;
- mContext.fe.view = nil;
- // mContext.fe.realContext = this;
- mContext.is_grid_cell = false;
-
- IL_DisplayData data;
- data.dither_mode = IL_ClosestColor;
- IL_SetDisplayMode(mContext.img_cx, IL_DITHER_MODE, &data);
- }
-
- #pragma mark --- CCustomPageSetup ---
-
- #define NUM_POPUPS 6
- #define NUM_CONTROLS 7
- #define BACKGROUND_CHECKBOX 6 // member of fControls[] which is treated specially
-
- //======================================
- class CCustomPageSetup
- //======================================
- {
- public:
- static void InitCustomPageSetup();
- static void OpenPageSetup( THPrint hPrint );
-
- static pascal TPPrDlg CustomStyleDialogInit( THPrint hPrint );
- PROCDECL( static, CustomStyleDialogInit )
-
- static long GetControlValue( long i );
- protected:
- struct ControlStruct
- {
- ControlHandle handle;
- CPrefs::PrefEnum prefEnum;
- };
-
- static pascal void CustomStyleItems( DialogPtr xdialogPtr, short itemNo );
- PROCDECL( static, CustomStyleItems )
-
- static TPPrDlg sPageSetupDialog; // pointer to style dialog
- static PItemUPP sItemProc; // we need to store the old itemProc here
- static long sFirstItem; // save our first item here
-
- static ControlStruct fControls[ NUM_CONTROLS ];
- }; // class CCustomPageSetup
-
- TPPrDlg CCustomPageSetup::sPageSetupDialog = nil;// pointer to style dialog
- PItemUPP CCustomPageSetup::sItemProc = nil; // we need to store the old itemProc here
- long CCustomPageSetup::sFirstItem = nil; // save our first item here
- CCustomPageSetup::ControlStruct CCustomPageSetup::fControls[ NUM_CONTROLS ];
-
- //-----------------------------------
- void CCustomPageSetup::InitCustomPageSetup()
- //-----------------------------------
- {
- fControls[ 0 ].prefEnum = CPrefs::TopLeftHeader;
- fControls[ 1 ].prefEnum = CPrefs::TopMidHeader;
- fControls[ 2 ].prefEnum = CPrefs::TopRightHeader;
- fControls[ 3 ].prefEnum = CPrefs::BottomLeftFooter;
- fControls[ 4 ].prefEnum = CPrefs::BottomMidFooter;
- fControls[ 5 ].prefEnum = CPrefs::BottomRightFooter;
- fControls[ BACKGROUND_CHECKBOX ].prefEnum = CPrefs::PrintBackground;
- }
-
- //-----------------------------------
- void CCustomPageSetup::OpenPageSetup( THPrint hp )
- //-----------------------------------
- {
- sPageSetupDialog = ::PrStlInit( hp );
-
- if ( PrError() == noErr )
- {
- if ( ::PrDlgMain( hp, (PDlgInitUPP) &PROCPTR( CCustomPageSetup::CustomStyleDialogInit ) ) )
- ;
- }
- }
-
- //-----------------------------------
- long CCustomPageSetup::GetControlValue( long i )
- //-----------------------------------
- {
- if (i == BACKGROUND_CHECKBOX)
- return CPrefs::GetBoolean (fControls[BACKGROUND_CHECKBOX].prefEnum);
- return CPrefs::GetLong (fControls[i].prefEnum);
- }
-
- //-----------------------------------
- pascal void CCustomPageSetup::CustomStyleItems( DialogPtr xdialogPtr, short itemNo )
- //-----------------------------------
- {
- TPPrDlg dialogPtr = (TPPrDlg)xdialogPtr;
- long value = 0;
- short myItem = itemNo - sFirstItem; // "localize" current item No
- if ( myItem >= 0 ) // if localized item > 0, it's one of ours
- {
- if ( fControls[ myItem ].handle )
- {
- value = ::GetControlValue( fControls[ myItem ].handle );
- if ( myItem == BACKGROUND_CHECKBOX )
- {
- value = !value;
- ::SetControlValue( fControls[ myItem ].handle, value );
- CPrefs::SetBoolean( value, fControls[ myItem ].prefEnum );
- }
- else
- CPrefs::SetLong( value, fControls[ myItem ].prefEnum );
- }
- }
- else
- CallPItemProc( sItemProc, (DialogPtr)dialogPtr, itemNo );
- }
-
-
- PROCEDURE( CCustomPageSetup::CustomStyleItems, uppPItemProcInfo )
-
- //-----------------------------------
- pascal TPPrDlg CCustomPageSetup::CustomStyleDialogInit( THPrint /*hPrint*/ )
- // this routine appends items to the standard style dialog and sets up the
- // user fields of the printing dialog record TPRDlg
- // This routine will be called by PrDlgMain
- //-----------------------------------
- {
- short itemType = 0; // needed for GetDialogItem/SetDItem call
- Handle itemH = nil;
- Rect itemBox;
- Handle ditlList;
-
- // Ñ╩append the items from the resource
- ditlList = GetResource( 'DITL', 256 );
- sFirstItem = CountDITL( (DialogPtr)sPageSetupDialog ) + 1;
- AppendDITL( (DialogPtr)sPageSetupDialog, ditlList, appendDITLBottom );
- ReleaseResource( ditlList );
-
- // Ñ╩init all the control values
- for ( long i = 0; i < NUM_CONTROLS; i++ )
- {
- ::GetDialogItem( (DialogPtr) sPageSetupDialog, sFirstItem + i, &itemType, &itemH, &itemBox );
- fControls[ i ].handle = (ControlHandle)itemH;
- ::SetControlValue( (ControlHandle)itemH, GetControlValue(i) );
- }
-
- // Ñ patch in our item handler
- // sItemProc is the original item proc,
- // pItemProc becomes our custom item proc
- sItemProc = sPageSetupDialog->pItemProc;
- sPageSetupDialog->pItemProc = &PROCPTR( CCustomPageSetup::CustomStyleItems );
-
- // Ñ╩PrDlgMain expects a pointer to the modified dialog to be returned╔
- return sPageSetupDialog;
- } // CCustomPageSetup::CustomStyleDialogInit
- PROCEDURE( CCustomPageSetup::CustomStyleDialogInit, uppPDlgInitProcInfo )
-
- //======================================
- #pragma mark --- CPrintHeaderCaption ---
- //======================================
-
- //======================================
- class CPrintHeaderCaption: public LCaption
- //======================================
- {
- public:
- enum { class_ID = 'HPPE' };
-
- CPrintHeaderCaption( LStream* inStream );
- virtual void PrintPanelSelf( const PanelSpec& inPanel );
-
- static void CreateString( long type, CStr255& string, const PanelSpec& inPanel );
- static void SetPrintContext( MWContext* cntx )
- {
- sContext = cntx;
- }
- static void SetTemporaryFile( Boolean b ) { sIsTemporaryFile = b; }
- protected:
- static MWContext* sContext;
- static Boolean sIsTemporaryFile;
- }; // class CPrintHeaderCaption
-
- MWContext* CPrintHeaderCaption::sContext = nil;
- Boolean CPrintHeaderCaption::sIsTemporaryFile = false;
-
- //-----------------------------------
- CPrintHeaderCaption::CPrintHeaderCaption( LStream* inStream ): LCaption( inStream )
- //-----------------------------------
- {
- }
-
- //-----------------------------------
- void CPrintHeaderCaption::CreateString( long form, CStr255& string, const PanelSpec& panel )
- //-----------------------------------
- {
- switch ( form )
- {
- case PAGE_NUMBER_FORM:
- {
- char buffer[ 30 ];
- CStr255 format = GetPString( PG_NUM_FORM_RESID );
- PR_snprintf( buffer, 30, format, panel.pageNumber );
- string = buffer;
- }
- break;
-
- case DATE_FORM:
- GetDateTimeString( string );
- break;
-
- case LOCATION_FORM:
- if ( sContext && !sIsTemporaryFile )
- {
- History_entry* current;
- current = SHIST_GetCurrent( &sContext->hist );
- if ( current && current->address )
- {
- char *urlPath = NULL;
- // if the URL starts with ftp or http then we'll make an attempt to remove password
- if ( (XP_STRNCMP(current->address, "ftp", 3) == 0 || XP_STRNCMP(current->address, "http", 4) == 0 )
- && NET_ParseUploadURL( current->address, &urlPath, NULL, NULL ) )
- {
- string = urlPath;
- if ( urlPath )
- XP_FREE( urlPath );
- }
- else // unknown URL; use it as is
- string = current->address;
- }
- }
- break;
-
- case TITLE_FORM:
- if ( sContext && !sIsTemporaryFile )
- {
- History_entry* current;
- current = SHIST_GetCurrent( &sContext->hist );
- if ( current )
- string = current->title;
- }
- break;
- }
- }
-
- //-----------------------------------
- void CPrintHeaderCaption::PrintPanelSelf( const PanelSpec& inPanel )
- //-----------------------------------
- {
- long value = CCustomPageSetup::GetControlValue( mUserCon );
- CStr255 string;
- CPrintHeaderCaption::CreateString( value, string, inPanel );
-
- unsigned short win_csid = INTL_DefaultWinCharSetID(sContext);
- if (value == TITLE_FORM &&
- ((INTL_CharSetNameToID(INTL_ResourceCharSet()) & ~CS_AUTO )
- != (win_csid & ~CS_AUTO)))
- {
- // Save the origional font name and number
- TextTraitsH origTT = UTextTraits::LoadTextTraits(this->GetTextTraitsID());
- Int16 origFontNumber = (*origTT)->fontNumber;
- Str255 origFontName;
- ::BlockMoveData(origFontName, (*origTT)->fontName, (*origTT)->fontName[0]+1);
-
- // SetHandleSize- the handle is compressed.
- ::SetHandleSize((Handle)origTT, sizeof(TextTraitsRecord));
- StHandleLocker lock((Handle) origTT );
-
- // Set the Font name and number in the TextTraits to the one in buttonF
- TextTraitsH csidTT
- = UTextTraits::LoadTextTraits(CPrefs::GetButtonFontTextResIDs(win_csid));
-
- (*origTT)->fontNumber = (*csidTT)->fontNumber;
- ::BlockMoveData((*origTT)->fontName, (*csidTT)->fontName, (*csidTT)->fontName[0]+1);
-
- // Do the usual job
- this->SetDescriptor(string);
- this->DrawSelf();
-
- // Restore the font name, number to the origional TextTraits
- (*origTT)->fontNumber = origFontNumber;
- ::BlockMoveData((*origTT)->fontName, origFontName, origFontName[0]+1);
- }
- else
- {
- this->SetDescriptor( string );
- this->DrawSelf();
- }
- } // CPrintHeaderCaption::PrintPanelSelf
-
- //======================================
- #pragma mark --- CHTMLPrintout ---
- //======================================
-
- //======================================
- class CHTMLPrintout
- : public LPrintout
- , public LListener
- //======================================
- {
- public:
- enum { class_ID = 'HPPT' };
- typedef LPrintout super;
-
- CHTMLPrintout( LStream* inStream );
- virtual ~CHTMLPrintout();
-
- virtual void FinishCreateSelf();
- virtual void ListenToMessage(
- MessageT inMessage,
- void* ioParam);
-
- virtual void DoProgress( const char* message, int level );
- static void BeginPrint( THPrint hp, CHTMLView* view );
- static CHTMLPrintout* Get() { return sHTMLPrintout; }
- CPrintHTMLView* GetPrintHTMLView() const { return mPrintHTMLView; }
- void LoadPageForPrint(URL_Struct* url,
- MWContext *printcontext, MWContext *viewContext);
- void StashPrintRecord(THPrint inPrintRecordH);
- Boolean PrintFinished(void)
- { return mPrinted && LMGetTicks() >= mFinishedTime; }
-
- protected:
-
- void Paginate (void);
- void CapturePositions (void);
-
- static CHTMLPrintout* sHTMLPrintout;
-
- CPrintHTMLView* mPrintHTMLView;
- CPrintContext* mContext;
- Boolean mFinishedLayout,
- mConnectionsCompleted,
- mPrinted;
- SInt32 mFinishedTime;
- }; // class CHTMLPrintout
-
- CHTMLPrintout* CHTMLPrintout::sHTMLPrintout = nil;
-
- extern void BuildAWindowPalette( MWContext* context, WindowPtr window );
-
- //-----------------------------------
- CHTMLPrintout::CHTMLPrintout( LStream* inStream )
- //-----------------------------------
- : LPrintout( inStream )
- , mContext(nil)
- , mPrintHTMLView(nil)
- , mPrinted(false)
- {
- sHTMLPrintout = this;
- }
-
- //-----------------------------------
- CHTMLPrintout::~CHTMLPrintout()
- //-----------------------------------
- {
- if ( XP_IsContextBusy( *mContext ) )
- NET_InterruptWindow( *mContext );
- XP_CleanupPrintInfo(*mContext);
- DestroyImageContext( *mContext );
- mContext->RemoveListener(this);
- mContext->RemoveUser(this);
- sHTMLPrintout = nil;
- }
-
- //-----------------------------------
- void CHTMLPrintout::FinishCreateSelf()
- //-----------------------------------
- {
- LPrintout::FinishCreateSelf();
- mContext = new CPrintContext();
- ThrowIfNil_(mContext);
- mContext->AddUser(this);
- mContext->AddListener(this); // listen for msg_NSCAllConnectionsComplete
-
- CreateImageContext( *mContext );
-
- mPrintHTMLView = (CPrintHTMLView*)FindPaneByID('PtHt');
- mPrintHTMLView->SetContext(mContext);
- }
-
- // editor callback
- void EditorPrintingCallback( char *completeURL, void *data )
- {
- Try_
- {
- URL_Struct* url = NET_CreateURLStruct( completeURL, NET_DONT_RELOAD );
- ThrowIfNil_(url);
-
- CPrintHeaderCaption::SetTemporaryFile( true );
- CHTMLPrintout::Get()->LoadPageForPrint( url, (MWContext *)data, (MWContext *)data );
- }
- Catch_( err )
- {
- Throw_( err );
- }
- EndCatch_
-
- }
-
-
- //-----------------------------------
- void CHTMLPrintout::StashPrintRecord (THPrint inPrintRecordH)
- //-----------------------------------
- {
-
- /* StashPrintRecord is based on LPrintout::SetPrintRecord. You might think we'd override
- that method, but it isn't virtual. So we changed the name to make it obvious that
- it's a different function, then just called it ourself after LPrintout is finished
- calling its version.
- I don't understand why the LPrintout version of this method is supposed to work.
- It sizes the LPrintout to match the size of the paper, rather than the page. The
- comments in that method mumble something about the coordinate system working out
- better that way. You can work around this by building into the PPob describing
- the LPrintout an offset which accounts for the unprintable margin, but that works
- only as long as the size of the printer margins is about the size built into the PPob.
- This breaks down terribly if you print at reduced size, which effectively increases
- the size of the printer margins.
- So I've changed the PPob to completely fill its parent view, and here I effectively
- change PowerPlant to use the page size. As far as I can tell, this works in all
- cases.
- */
-
- // do what LPrintout::SetPrintRecord does, but size ourselves to the page,
- // rather than the paper
- UPrintingMgr::ValidatePrintRecord(inPrintRecordH);
- mPrintRecordH = inPrintRecordH;
-
- Rect pageRect = (**inPrintRecordH).prInfo.rPage;
-
- ResizeFrameTo(pageRect.right - pageRect.left,
- pageRect.bottom - pageRect.top, false);
- ResizeImageTo(pageRect.right - pageRect.left,
- pageRect.bottom - pageRect.top, false);
- PlaceInSuperImageAt(pageRect.left, pageRect.top, false);
- }
-
- //-----------------------------------
- void CHTMLPrintout::LoadPageForPrint(URL_Struct* url, MWContext *printcontext, MWContext *viewContext)
- //-----------------------------------
- {
- // SHIST_CreateURLStructFromHistoryEntry copies pointers but not
- // the saved data structures, so we must zero them out to prevent
- // double-deletions. An alternative that would preserve saved data
- // for clients that find it useful (e.g. forms, embeds) would be to
- // deep copy the saved data objects.
- XP_MEMSET( &url->savedData, 0, sizeof( SHIST_SavedData ) );
-
- NPL_PreparePrint( viewContext, &( url->savedData ) );
- if ( printcontext->prSetup )
- printcontext->prSetup->url = url;
- url->position_tag = 0;
- if ( url->address )
- XP_STRTOK( url->address, "#" );
-
- CPrintHeaderCaption::SetPrintContext( viewContext );
- EarlManager::StartLoadURL( url, printcontext, FO_PRESENT );
- OutOfFocus( nil );
- }
-
-
- //-----------------------------------
- void CHTMLPrintout::Paginate (void) {
- //-----------------------------------
-
- mPrintHTMLView->InitializeCapture();
- CapturePositions();
- mPrintHTMLView->CalculatePageBreaks();
- mPrintHTMLView->SetPrintMode (CPrintHTMLView::epmDisplay);
- }
-
- //-----------------------------------
- void CHTMLPrintout::CapturePositions (void) {
- //-----------------------------------
-
- Rect pageArea;
- short pageWidth,
- pageHeight;
- CL_Compositor *compositor = mPrintHTMLView->GetCompositor();
-
- mPrintHTMLView->CalcPortFrameRect (pageArea);
- pageHeight = pageArea.bottom - pageArea.top;
- pageWidth = pageArea.right - pageArea.left;
-
- // For capturing, we want all the elements in a document to display.
- // Since we can't size the compositor window to be the size of the
- // document (the compositor window must have coordinates that fit into
- // a 16-bit coordinate space), we take snapshots. In other words,
- // we make the compositor window the size of the physical page and
- // keep scrolling down till capture the entire document.
-
- if (compositor) {
- XP_Rect drawingRect;
- SDimension32 documentSize;
- int pass;
- int32 captureScrollOffset;
-
- // The compositor window is the size of the page (minus margins)
- CL_ResizeCompositorWindow (compositor, pageWidth, pageHeight);
-
- drawingRect.left = 0;
- drawingRect.top = 0;
- drawingRect.right = pageWidth;
- drawingRect.bottom = pageHeight;
-
- // We display all the elements twice. This is to deal with the
- // fact that certain elements (images, embeds and applets for
- // instance) are always displayed in a compositor pass after
- // the containing HTML content. We only capture during the
- // second pass.
- mPrintHTMLView->SetPrintMode (CPrintHTMLView::epmBlockDisplay);
- mPrintHTMLView->GetImageSize (documentSize);
- for (pass = 0; pass < 2; pass++) {
- // Till we've covered the entire document, we keep scrolling
- // down and taking snapshots
- for (captureScrollOffset = 0;
- captureScrollOffset <= documentSize.height;
- captureScrollOffset += pageHeight) {
-
- CL_ScrollCompositorWindow (compositor, 0, captureScrollOffset);
- CL_RefreshWindowRect (compositor, &drawingRect);
- }
- mPrintHTMLView->SetPrintMode (CPrintHTMLView::epmLayout);
- }
-
- CL_ScrollCompositorWindow (compositor, 0, 0);
- } else {
- mPrintHTMLView->SetPrintMode (CPrintHTMLView::epmLayout);
- LO_RefreshArea (*mContext, 0, 0, 0x7FFFFFFF, 0x7FFFFFFF);
- }
- } // end CapturePositions
-
-
- //-----------------------------------
- void CHTMLPrintout::DoProgress( const char* /*message*/, int /*level*/ )
- //-----------------------------------
- {
- }
-
- #ifdef PRE_JRM
- MWContext* CHTMLPrintout::CreateGridContext()
- {
- MWContext* newContext = mContext->CreateGridContext();
- newContext->type = MWContextPrint;
- return newContext;
- }
- #endif
-
- //-----------------------------------
- void CHTMLPrintout::BeginPrint(THPrint hp, CHTMLView* inViewToPrint)
- //-----------------------------------
- {
- if (!hp)
- return;
- if (!sHTMLPrintout)
- sHTMLPrintout = (CHTMLPrintout*)LPrintout::CreatePrintout(1001);
- ThrowIfNil_(sHTMLPrintout);
- CPrintHTMLView* printHTMLView = sHTMLPrintout->GetPrintHTMLView();
- ThrowIfNil_(printHTMLView);
-
- // Ñ set the printout (unlike PP, we have our own SAVED print record )
- sHTMLPrintout->StashPrintRecord(hp);
-
- // Ñ setup psfe's structs for measurements
-
- //
- // Keep a reference in the print context to the list of plugin instances
- // in the on-screen context. This information is used in mplugin.cp when
- // printing plugins to avoid creating new instantiations of all the plugins.
- //
- ((MWContext*)sHTMLPrintout->mContext)->pEmbeddedApp
- = ((MWContext*)inViewToPrint->GetContext())->pluginList;
-
- // Ñ╩set the encoding type
- #ifdef PRE_JRM
- sHTMLPrintout->fContext.fe.realContext->default_csid
- = inViewToPrint->fHContext->fe.realContext->default_csid;
- #endif
-
- XP_InitializePrintInfo((MWContext*)*(sHTMLPrintout->mContext));
-
- sHTMLPrintout->mFinishedLayout = false;
- sHTMLPrintout->mConnectionsCompleted = false;
- sHTMLPrintout->mPrinted = false;
-
- // Ñ it's very important that mainLedge actually be enabled and
- // not latent, otherwise controls that are printed do not
- // behave properly
- printHTMLView->SetPrintMode (CPrintHTMLView::epmBlockDisplay);
- printHTMLView->Enable();
- printHTMLView->CopyCharacteristicsFrom(inViewToPrint);
-
- // Ñ go print
- Try_
- {
- URL_Struct *url;
- Boolean doSuppressURL = false;
- url = inViewToPrint->GetURLForPrinting( doSuppressURL, *(sHTMLPrintout->mContext) );
- if ( url )
- {
- CPrintHeaderCaption::SetTemporaryFile( doSuppressURL );
- sHTMLPrintout->LoadPageForPrint( url, ((MWContext*)*(sHTMLPrintout->mContext)), (MWContext*)*inViewToPrint->GetContext());
- }
- }
- Catch_( err )
- {
- Throw_( err );
- }
- EndCatch_
- } // CHTMLPrintout::BeginPrint
-
- //-----------------------------------
- void CHTMLPrintout::ListenToMessage(
- MessageT inMessage,
- void* /*ioParam*/)
- //-----------------------------------
- {
- CHTMLView *htmlView = ExtractHyperView (*mContext);
-
- switch (inMessage) {
- case msg_NSCFinishedLayout:
- // htmlView->NoteFinishedLayout(); (seems likely, but protected)
- mFinishedLayout = true;
- break;
- case msg_NSCAllConnectionsComplete:
- // for frames, don't do print stuff until all contexts are done
- // htmlView->NoteAllConnectionsComplete();
- mConnectionsCompleted = !XP_IsContextBusy((MWContext*)*mContext);
- break;
- }
- // the check for mPrinted is necessary; JavaScript will call FinishedLayout twice
- if (mConnectionsCompleted && mFinishedLayout && !mPrinted) {
- // lay out for printing
- Paginate();
- DoPrintJob();
-
- #if GENERATING68K
- // ***** HACK ***** Fixed weird crash where 68K printer code
- // spammed us with an invalid port -- a vivid example of why
- // one should not have an invalid port.
- WindowPtr front = FrontWindow();
- if (front)
- SetPort(front);
- else {
- CGrafPtr windowMgrPort;
- GetCWMgrPort(&windowMgrPort);
- SetPort((GrafPtr)windowMgrPort);
- }
- #endif
-
- mPrinted = true;
- }
- mFinishedTime = LMGetTicks() + 600; // wait 10 seconds for Java to finish
- } // CHTMLPrintout::ListenToMessage
-
- //======================================
- #pragma mark --- CPrintingCleanupTimer ---
- //======================================
- /* CPrintingCleanupTimer gives periodic attention to sHTMLPrintout, waiting for it
- to finish printing. When sMTMLPrintout claims it's finished, we delete it.
- This is a (small) change in architecture: originally, sHTMLPrintout deleted itself
- as soon as it was finished printing. I hacked in this timer thing to support
- printing pages with JavaScript.
- There's no good way to tell whether JavaScript has finished laying out a page.
- Notably, a page containing JavaScript seems to always get two "finished layout"
- messages. Before this timer thing was installed, the first such message caused
- the page to be printed and deleted. The second such message brought the machine
- down. Now we wait to delete the object until it stops getting messages from
- layout. We define "stopped getting messages" as "haven't seen one in ten seconds."
- This sucks, and will cause your machine to crash if a big delay happens for some
- reason, but I'm led to believe JavaScript itself must be full of such things,
- and can't come up with a better plan today.
- */
-
- //-----------------------------------
- // class definition
- class CPrintingCleanupTimer : public LPeriodical {
-
- public:
- CPrintingCleanupTimer();
- virtual void SpendTime(const EventRecord &inMacEvent);
- static void QueueCleanup(void);
-
- private:
- static CPrintingCleanupTimer sTheTimer;
- };
-
- //-----------------------------------
- CPrintingCleanupTimer::CPrintingCleanupTimer()
- // constructor: like the base class, but don't start repeating until told to
- //-----------------------------------
- {
- // when we're initialized at app load time, don't yet start asking for time
- StopRepeating();
- }
-
- //-----------------------------------
- void CPrintingCleanupTimer::QueueCleanup(void)
- // public access to turn on the timer; call when an sHTMLPrintout has been allocated
- //-----------------------------------
- {
- sTheTimer.StartRepeating();
- }
-
- //-----------------------------------
- void CPrintingCleanupTimer::SpendTime(const EventRecord &)
- // internal workings of the timer: wait until sHTMLPrintout says it's finished,
- // then delete it and shut yourself down
- //-----------------------------------
- {
- CHTMLPrintout *activePrintout = CHTMLPrintout::Get();
-
- if (activePrintout && activePrintout->PrintFinished()) {
- delete activePrintout; // which sets sHTMLPrintout to 0 */
- StopRepeating();
- }
- }
-
- //-----------------------------------
- CPrintingCleanupTimer CPrintingCleanupTimer::sTheTimer;
-
- //======================================
- #pragma mark --- UHTMLPrinting ---
- //======================================
-
- //-----------------------------------
- void UHTMLPrinting::RegisterHTMLPrintClasses()
- //-----------------------------------
- {
- //#define REGISTER_(letter,root) \
- // RegisterClass_(letter##root::class_ID, \
- // (ClassCreatorFunc)letter##root::Create##root##Stream);
-
- #define REGISTER_(letter,root) RegisterClass_(letter##root);
-
- #define REGISTERC(root) REGISTER_(C,root)
- #define REGISTERL(root) REGISTER_(L,root)
- REGISTERC(HTMLPrintout) // 97/01/24 jrm
- REGISTERC(PrintHTMLView) // 97/01/24 jrm
- REGISTERC(PrintHeaderCaption) // 97/01/24 jrm
- } // UHTMLPrinting::RegisterHTMLPrintClasses
-
- //-----------------------------------
- void UHTMLPrinting::InitCustomPageSetup()
- //-----------------------------------
- {
- CCustomPageSetup::InitCustomPageSetup();
- }
-
- //-----------------------------------
- void UHTMLPrinting::OpenPageSetup( THPrint hPrint )
- //-----------------------------------
- {
- CCustomPageSetup::OpenPageSetup(hPrint);
- }
-
- //-----------------------------------
- void UHTMLPrinting::BeginPrint( THPrint hPrint, CHTMLView* inView )
- //-----------------------------------
- {
- CPrintingCleanupTimer::QueueCleanup();
- CHTMLPrintout::BeginPrint(hPrint, inView);
- }