gecko-dev/layout/printing/nsPrintEngine.h
2002-11-22 13:02:05 +00:00

376 lines
16 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsPrintEngine_h___
#define nsPrintEngine_h___
#include "nsPrintObject.h"
#include "nsPrintData.h"
// Interfaces
#include "nsIDeviceContext.h"
#include "nsIDocument.h"
#include "nsIDOMWindow.h"
#include "nsIDOMWindowInternal.h"
#include "nsIObserver.h"
#include "nsIPrintProgress.h"
#include "nsIPrintProgressParams.h"
#include "nsIPrintOptions.h"
#include "nsIPrintSettings.h"
#include "nsIWebProgressListener.h"
#include "nsISelectionListener.h"
// Other Includes
#include "nsPrintPreviewListener.h"
#include "nsIDocShellTreeNode.h"
// Classes
class nsIPageSequenceFrame;
class nsPagePrintTimer;
// Special Interfaces
#include "nsIWebBrowserPrint.h"
#include "nsIDocumentViewer.h"
#include "nsIDocumentViewerPrint.h"
#ifdef MOZ_LAYOUTDEBUG
#include "nsIDebugObject.h"
#endif
//------------------------------------------------------------------------
// nsPrintEngine Class
//
// mPreparingForPrint - indicates that we have started Printing but
// have not gone to the timer to start printing the pages. It gets turned
// off right before we go to the timer.
//
// mDocWasToBeDestroyed - Gets set when "someone" tries to unload the document
// while we were prparing to Print. This typically happens if a user starts
// to print while a page is still loading. If they start printing and pause
// at the print dialog and then the page comes in, we then abort printing
// because the document is no longer stable.
//
//------------------------------------------------------------------------
class nsPrintEngine : public nsIWebBrowserPrint, public nsIObserver {
public:
//NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
// nsISupports interface...
NS_DECL_ISUPPORTS
// nsIWebBrowserPrint
NS_DECL_NSIWEBBROWSERPRINT
// nsIObserver
NS_DECL_NSIOBSERVER
// This enum tells indicates what the default should be for the title
// if the title from the document is null
enum eDocTitleDefault {
eDocTitleDefNone,
eDocTitleDefBlank,
eDocTitleDefURLDoc
};
nsPrintEngine();
virtual ~nsPrintEngine();
void Destroy();
void DestroyPrintingData();
nsresult Initialize(nsIDocumentViewer* aDocViewer,
nsIDocumentViewerPrint* aDocViewerPrint,
nsISupports* aContainer,
nsIDocument* aDocument,
nsIDeviceContext* aDevContext,
nsIPresContext* aPresContext,
nsIWidget* aWindow,
nsIWidget* aParentWidget,
FILE* aDebugFile);
nsresult GetSeqFrameAndCountPages(nsIFrame*& aSeqFrame, PRInt32& aCount);
PRBool IsOldPrintPreviewPres() { return mOldPrtPreview != nsnull; }
//
// The following three methods are used for printing...
//
nsresult DocumentReadyForPrinting();
nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec,
nsIDocument ** aNewDoc);
nsresult SetupToPrintContent(nsIDeviceContext* aDContext,
nsIDOMWindowInternal* aCurrentFocusedDOMWin);
nsresult EnablePOsForPrinting();
nsPrintObject* FindSmallestSTF();
PRBool PrintDocContent(nsPrintObject* aPO, nsresult& aStatus);
nsresult DoPrint(nsPrintObject * aPO, PRBool aDoSyncPrinting,
PRBool& aDonePrinting);
void SetPrintAsIs(nsPrintObject* aPO, PRBool aAsIs = PR_TRUE);
enum ePrintFlags {eSetPrintFlag = 1U, eSetHiddenFlag = 2U };
void SetPrintPO(nsPrintObject* aPO, PRBool aPrint, PRBool aIsHidden = PR_FALSE, PRUint32 aFlags = eSetPrintFlag);
void TurnScriptingOn(PRBool aDoTurnOn);
PRBool CheckDocumentForPPCaching();
void InstallPrintPreviewListener();
// nsIDocumentViewerPrint Printing Methods
PRBool PrintPage(nsIPresContext* aPresContext,
nsIPrintSettings* aPrintSettings,
nsPrintObject* aPOect, PRBool& aInRange);
PRBool DonePrintingPages(nsPrintObject* aPO, nsresult aResult);
//---------------------------------------------------------------------
void BuildDocTree(nsIDocShellTreeNode * aParentNode,
nsVoidArray * aDocList,
nsPrintObject * aPO);
nsresult ReflowDocList(nsPrintObject * aPO, PRBool aSetPixelScale,
PRBool aDoCalcShrink);
void SetClipRect(nsPrintObject* aPO,
const nsRect& aClipRect,
nscoord aOffsetX,
nscoord aOffsetY,
PRBool aDoingSetClip);
nsresult ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink);
nsresult CalcPageFrameLocation(nsIPresShell * aPresShell,
nsPrintObject* aPO);
nsPrintObject * FindPrintObjectByWS(nsPrintObject* aPO, nsIWebShell * aWebShell);
void MapContentForPO(nsPrintObject* aRootObject,
nsIPresShell* aPresShell,
nsIContent* aContent);
void MapContentToWebShells(nsPrintObject* aRootPO, nsPrintObject* aPO);
void CheckForChildFrameSets(nsPrintObject* aPO);
nsresult MapSubDocFrameLocations(nsPrintObject* aPO);
void CalcNumPrintableDocsAndPages(PRInt32& aNumDocs, PRInt32& aNumPages);
void DoProgressForAsIsFrames();
void DoProgressForSeparateFrames();
void ShowPrintProgress(PRBool aIsForPrinting, PRBool& aDoNotify);
nsresult CleanupOnFailure(nsresult aResult, PRBool aIsPrinting);
nsresult FinishPrintPreview();
static void CloseProgressDialog(nsIWebProgressListener* aWebProgressListener);
void SetDocAndURLIntoProgress(nsPrintObject* aPO,
nsIPrintProgressParams* aParams);
void ElipseLongString(PRUnichar *& aStr, const PRUint32 aLen, PRBool aDoFront);
nsresult CheckForPrinters(nsIPrintOptions* aPrintOptions,
nsIPrintSettings* aPrintSettings,
PRUint32 aErrorCode,
PRBool aIsPrinting);
void CleanupDocTitleArray(PRUnichar**& aArray, PRInt32& aCount);
void CheckForHiddenFrameSetFrames();
PRBool IsThereARangeSelection(nsIDOMWindowInternal * aDOMWin);
//---------------------------------------------------------------------
// Timer Methods
nsresult StartPagePrintTimer(nsIPresContext * aPresContext,
nsIPrintSettings* aPrintSettings,
nsPrintObject* aPO,
PRUint32 aDelay);
//---------------------------------------------------------------------
// Static Methods
//---------------------------------------------------------------------
PRBool IsWindowsInOurSubTree(nsIDOMWindowInternal * aDOMWindow);
PRBool IsParentAFrameSet(nsIWebShell * aParent);
PRBool IsThereAnIFrameSelected(nsIWebShell* aWebShell,
nsIDOMWindowInternal * aDOMWin,
PRPackedBool& aIsParentFrameSet);
nsPrintObject* FindPrintObjectByDOMWin(nsPrintObject* aParentObject,
nsIDOMWindowInternal * aDOMWin);
// get the DOMWindow for a given WebShell
nsIDOMWindowInternal * GetDOMWinForWebShell(nsIWebShell* aWebShell);
// get the currently infocus frame for the document viewer
nsIDOMWindowInternal * FindFocusedDOMWindowInternal();
void GetWebShellTitleAndURL(nsIWebShell* aWebShell, nsIDocument* aDoc,
PRUnichar** aTitle, PRUnichar** aURLStr);
static void GetDisplayTitleAndURL(nsPrintObject* aPO,
nsIPrintSettings* aPrintSettings,
const PRUnichar* aBrandName,
PRUnichar** aTitle,
PRUnichar** aURLStr,
eDocTitleDefault aDefType = eDocTitleDefNone);
static void ShowPrintErrorDialog(nsresult printerror,
PRBool aIsPrinting = PR_TRUE);
PRBool CheckBeforeDestroy();
nsresult Cancelled();
nsresult ShowDocList(PRBool aShow);
void GetNewPresentation(nsCOMPtr<nsIPresShell>& aShell,
nsCOMPtr<nsIPresContext>& aPC,
nsCOMPtr<nsIViewManager>& aVM,
nsCOMPtr<nsIWidget>& aW);
// CachedPresentationObj is used to cache the presentation
// so we can bring it back later
PRBool HasCachedPres() { return mIsCachingPresentation && mCachedPresObj; }
PRBool IsCachingPres() { return mIsCachingPresentation; }
void SetCacheOldPres(PRBool aDoCache) { mIsCachingPresentation = aDoCache; }
void CachePresentation(nsIPresShell* aShell, nsIPresContext* aPC, nsIViewManager* aVM, nsIWidget* aW);
void GetCachedPresentation(nsCOMPtr<nsIPresShell>& aShell,
nsCOMPtr<nsIPresContext>& aPC,
nsCOMPtr<nsIViewManager>& aVM,
nsCOMPtr<nsIWidget>& aW);
static nsIPresShell* GetPresShellFor(nsIDocShell* aDocShell);
void SetDialogParent(nsIDOMWindowInternal* aDOMWin) { mDialogParentWin = aDOMWin; }
// These calls also update the DocViewer
void SetIsPrinting(PRBool aIsPrinting);
PRBool GetIsPrinting() { return mIsDoingPrinting; }
void SetIsPrintPreview(PRBool aIsPrintPreview);
PRBool GetIsPrintPreview() { return mIsDoingPrintPreview; }
void SetIsCreatingPrintPreview(PRBool aIsCreatingPrintPreview) { mIsCreatingPrintPreview = aIsCreatingPrintPreview; }
PRBool GetIsCreatingPrintPreview() { return mIsCreatingPrintPreview; }
#ifdef MOZ_LAYOUTDEBUG
static nsresult TestRuntimeErrorCondition(PRInt16 aRuntimeID,
nsresult aCurrentErrorCode,
nsresult aNewErrorCode);
static PRBool IsDoingRuntimeTesting();
static void InitializeTestRuntimeError();
protected:
static PRBool mIsDoingRuntimeTesting;
static nsCOMPtr<nsIDebugObject> mLayoutDebugObj; // always de-referenced with the destructor
#endif
protected:
void FirePrintCompletionEvent();
nsresult ShowDocListInternal(nsPrintObject* aPO, PRBool aShow);
nsresult GetSeqFrameAndCountPagesInternal(nsPrintObject* aPO,
nsIFrame*& aSeqFrame,
PRInt32& aCount);
static nsresult FindSelectionBoundsWithList(nsIPresContext* aPresContext,
nsIRenderingContext& aRC,
nsIAtom* aList,
nsIFrame * aParentFrame,
nsRect& aRect,
nsIFrame *& aStartFrame,
nsRect& aStartRect,
nsIFrame *& aEndFrame,
nsRect& aEndRect);
static nsresult FindSelectionBounds(nsIPresContext* aPresContext,
nsIRenderingContext& aRC,
nsIFrame * aParentFrame,
nsRect& aRect,
nsIFrame *& aStartFrame,
nsRect& aStartRect,
nsIFrame *& aEndFrame,
nsRect& aEndRect);
static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell,
nsIPresContext* aPresContext,
nsIRenderingContext& aRC,
nsISelection* aSelection,
nsIPageSequenceFrame* aPageSeqFrame,
nsIFrame** aStartFrame,
PRInt32& aStartPageNum,
nsRect& aStartRect,
nsIFrame** aEndFrame,
PRInt32& aEndPageNum,
nsRect& aEndRect);
static nsIFrame * FindFrameByType(nsIPresContext* aPresContext,
nsIFrame * aParentFrame,
nsIAtom * aType,
nsRect& aRect,
nsRect& aChildRect);
// Static memeber variables
PRBool mIsCreatingPrintPreview;
PRBool mIsDoingPrinting;
nsIDocumentViewerPrint* mDocViewerPrint; // [WEAK] it owns me!
nsIDocumentViewer* mDocViewer; // [WEAK] it owns me!
nsISupports* mContainer; // [WEAK] it owns me!
nsIDeviceContext* mDeviceContext; // not ref counted
nsIPresContext* mPresContext; // not ref counted
nsCOMPtr<nsIWidget> mWindow;
nsPrintData* mPrt;
nsPagePrintTimer* mPagePrintTimer;
nsIPageSequenceFrame* mPageSeqFrame;
// Print Preview
PRBool mIsDoingPrintPreview; // per DocumentViewer
nsCOMPtr<nsIWidget> mParentWidget;
nsPrintData* mPrtPreview;
nsPrintData* mOldPrtPreview;
nsCOMPtr<nsIDocument> mDocument;
nsCOMPtr<nsIDOMWindowInternal> mDialogParentWin;
PRBool mIsCachingPresentation;
CachedPresentationObj* mCachedPresObj;
FILE* mDebugFile;
private:
nsPrintEngine& operator=(const nsPrintEngine& aOther); // not implemented
};
#ifdef MOZ_LAYOUTDEBUG
#define INIT_RUNTIME_ERROR_CHECKING() nsPrintEngine::InitializeTestRuntimeError();
#define CHECK_RUNTIME_ERROR_CONDITION(_name, _currerr, _newerr) \
if (nsPrintEngine::IsDoingRuntimeTesting()) { \
_currerr = nsPrintEngine::TestRuntimeErrorCondition(_name, _currerr, _newerr); \
}
#else
#define CHECK_RUNTIME_ERROR_CONDITION(_name, _currerr, _newerr)
#define INIT_RUNTIME_ERROR_CHECKING()
#endif
#endif /* nsPrintEngine_h___ */