Back to index

lightning-sunbird  0.9+nobinonly
nsPrintEngine.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #ifndef nsPrintEngine_h___
00038 #define nsPrintEngine_h___
00039 
00040 #include "nsCOMPtr.h"
00041 
00042 #include "nsPrintObject.h"
00043 #include "nsPrintData.h"
00044 
00045 // Interfaces
00046 #include "nsIDeviceContext.h"
00047 #include "nsIDocument.h"
00048 #include "nsIDOMWindow.h"
00049 #include "nsIObserver.h"
00050 #include "nsIPrintProgress.h"
00051 #include "nsIPrintProgressParams.h"
00052 #include "nsIPrintOptions.h"
00053 #include "nsIPrintSettings.h"
00054 #include "nsIWebProgressListener.h"
00055 #include "nsISelectionListener.h"
00056 
00057 // Other Includes
00058 #include "nsPrintPreviewListener.h"
00059 #include "nsIDocShellTreeNode.h"
00060 
00061 // Classes
00062 class nsIPageSequenceFrame;
00063 class nsPagePrintTimer;
00064 
00065 // Special Interfaces
00066 #include "nsIWebBrowserPrint.h"
00067 #include "nsIDocumentViewer.h"
00068 #include "nsIDocumentViewerPrint.h"
00069 
00070 #ifdef MOZ_LAYOUTDEBUG
00071 #include "nsIDebugObject.h"
00072 #endif
00073 
00074 //------------------------------------------------------------------------
00075 // nsPrintEngine Class
00076 //
00077 // mPreparingForPrint - indicates that we have started Printing but 
00078 //   have not gone to the timer to start printing the pages. It gets turned 
00079 //   off right before we go to the timer.
00080 //
00081 // mDocWasToBeDestroyed - Gets set when "someone" tries to unload the document
00082 //   while we were prparing to Print. This typically happens if a user starts 
00083 //   to print while a page is still loading. If they start printing and pause 
00084 //   at the print dialog and then the page comes in, we then abort printing 
00085 //   because the document is no longer stable.
00086 // 
00087 //------------------------------------------------------------------------
00088 class nsPrintEngine : public nsIWebBrowserPrint, public nsIObserver
00089 {
00090 public:
00091   //NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
00092 
00093   // nsISupports interface...
00094   NS_DECL_ISUPPORTS
00095 
00096   // nsIWebBrowserPrint
00097   NS_DECL_NSIWEBBROWSERPRINT
00098 
00099   // nsIObserver
00100   NS_DECL_NSIOBSERVER
00101 
00102   // This enum tells indicates what the default should be for the title
00103   // if the title from the document is null
00104   enum eDocTitleDefault {
00105     eDocTitleDefNone,
00106     eDocTitleDefBlank,
00107     eDocTitleDefURLDoc
00108   };
00109 
00110 
00111   nsPrintEngine();
00112   virtual ~nsPrintEngine();
00113 
00114   void Destroy();
00115   void DestroyPrintingData();
00116 
00117   nsresult Initialize(nsIDocumentViewer*      aDocViewer, 
00118                       nsIDocumentViewerPrint* aDocViewerPrint, 
00119                       nsISupports*            aContainer,
00120                       nsIDocument*            aDocument,
00121                       nsIDeviceContext*       aDevContext,
00122                       nsPresContext*         aPresContext,
00123                       nsIWidget*              aWindow,
00124                       nsIWidget*              aParentWidget,
00125                       FILE*                   aDebugFile);
00126 
00127   nsresult GetSeqFrameAndCountPages(nsIFrame*& aSeqFrame, PRInt32& aCount);
00128   PRBool   IsOldPrintPreviewPres()
00129   {
00130     return mOldPrtPreview != nsnull;
00131   }
00132   //
00133   // The following three methods are used for printing...
00134   //
00135   nsresult DocumentReadyForPrinting();
00136   nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec,
00137                                 nsIDocument ** aNewDoc);
00138 
00139   nsresult SetupToPrintContent(nsIDeviceContext* aDContext,
00140                                nsIDOMWindow* aCurrentFocusedDOMWin);
00141   nsresult EnablePOsForPrinting();
00142   nsPrintObject* FindSmallestSTF();
00143 
00144   PRBool   PrintDocContent(nsPrintObject* aPO, nsresult& aStatus);
00145   nsresult DoPrint(nsPrintObject * aPO, PRBool aDoSyncPrinting,
00146                    PRBool& aDonePrinting);
00147   void SetPrintAsIs(nsPrintObject* aPO, PRBool aAsIs = PR_TRUE);
00148 
00149   enum ePrintFlags {
00150     eSetPrintFlag = 1U,
00151     eSetHiddenFlag = 2U
00152   };
00153   void SetPrintPO(nsPrintObject* aPO, PRBool aPrint,
00154                   PRBool aIsHidden = PR_FALSE,
00155                   PRUint32 aFlags = eSetPrintFlag);
00156 
00157   void TurnScriptingOn(PRBool aDoTurnOn);
00158   PRBool CheckDocumentForPPCaching();
00159   void InstallPrintPreviewListener();
00160 
00161   // nsIDocumentViewerPrint Printing Methods
00162   PRBool   PrintPage(nsPresContext* aPresContext,
00163                      nsIPrintSettings* aPrintSettings,
00164                      nsPrintObject* aPOect, PRBool& aInRange);
00165   PRBool   DonePrintingPages(nsPrintObject* aPO, nsresult aResult);
00166 
00167   //---------------------------------------------------------------------
00168   void BuildDocTree(nsIDocShellTreeNode * aParentNode,
00169                     nsVoidArray *         aDocList,
00170                     nsPrintObject *         aPO);
00171   nsresult ReflowDocList(nsPrintObject * aPO, PRBool aSetPixelScale,
00172                          PRBool aDoCalcShrink);
00173   void SetClipRect(nsPrintObject*  aPO,
00174                    const nsRect& aClipRect,
00175                    nscoord       aOffsetX,
00176                    nscoord       aOffsetY,
00177                    PRBool        aDoingSetClip);
00178 
00179   nsresult ReflowPrintObject(nsPrintObject * aPO, PRBool aDoCalcShrink);
00180   nsresult CalcPageFrameLocation(nsIPresShell * aPresShell,
00181                                   nsPrintObject*   aPO);
00182   nsPrintObject * FindPrintObjectByDS(nsPrintObject* aPO, nsIDocShell * aDocShell);
00183   void MapContentForPO(nsPrintObject*   aRootObject,
00184                        nsIPresShell*  aPresShell,
00185                        nsIContent*    aContent);
00186   void MapContentToWebShells(nsPrintObject* aRootPO, nsPrintObject* aPO);
00187   void CheckForChildFrameSets(nsPrintObject* aPO);
00188   nsresult MapSubDocFrameLocations(nsPrintObject* aPO);
00189 
00190   void CalcNumPrintableDocsAndPages(PRInt32& aNumDocs, PRInt32& aNumPages);
00191   void DoProgressForAsIsFrames();
00192   void DoProgressForSeparateFrames();
00193   void ShowPrintProgress(PRBool aIsForPrinting, PRBool& aDoNotify);
00194   nsresult CleanupOnFailure(nsresult aResult, PRBool aIsPrinting);
00195   nsresult FinishPrintPreview();
00196   static void CloseProgressDialog(nsIWebProgressListener* aWebProgressListener);
00197 
00198   void SetDocAndURLIntoProgress(nsPrintObject* aPO,
00199                                 nsIPrintProgressParams* aParams);
00200   void ElipseLongString(PRUnichar *& aStr, const PRUint32 aLen, PRBool aDoFront);
00201   nsresult CheckForPrinters(nsIPrintOptions*  aPrintOptions,
00202                             nsIPrintSettings* aPrintSettings);
00203   void CleanupDocTitleArray(PRUnichar**& aArray, PRInt32& aCount);
00204 
00205   PRBool IsThereARangeSelection(nsIDOMWindow * aDOMWin);
00206 
00207   //---------------------------------------------------------------------
00208 
00209 
00210   // Timer Methods
00211   nsresult StartPagePrintTimer(nsPresContext * aPresContext,
00212                                nsIPrintSettings* aPrintSettings,
00213                                nsPrintObject*     aPO,
00214                                PRUint32         aDelay);
00215 
00216   PRBool IsWindowsInOurSubTree(nsIDOMWindow * aDOMWindow);
00217   PRBool IsParentAFrameSet(nsIDocShell * aParent);
00218   PRBool IsThereAnIFrameSelected(nsIDocShell* aDocShell,
00219                                  nsIDOMWindow* aDOMWin,
00220                                  PRPackedBool& aIsParentFrameSet);
00221 
00222   nsPrintObject* FindPrintObjectByDOMWin(nsPrintObject* aParentObject,
00223                                          nsIDOMWindow* aDOMWin);
00224 
00225   // get the currently infocus frame for the document viewer
00226   already_AddRefed<nsIDOMWindow> FindFocusedDOMWindow();
00227 
00228   //---------------------------------------------------------------------
00229   // Static Methods
00230   //---------------------------------------------------------------------
00231   static void GetDocumentTitleAndURL(nsIDocument* aDoc,
00232                                      PRUnichar** aTitle,
00233                                      PRUnichar** aURLStr);
00234   static void GetDisplayTitleAndURL(nsPrintObject*      aPO, 
00235                                     nsIPrintSettings* aPrintSettings, 
00236                                     const PRUnichar*  aBrandName,
00237                                     PRUnichar**       aTitle, 
00238                                     PRUnichar**       aURLStr,
00239                                     eDocTitleDefault  aDefType = eDocTitleDefNone);
00240   static void ShowPrintErrorDialog(nsresult printerror,
00241                                    PRBool aIsPrinting = PR_TRUE);
00242   static void GetPresShellAndRootContent(nsIDocShell *  aDocShell,
00243                                          nsIPresShell** aPresShell,
00244                                          nsIContent**   aContent);
00245 
00246   static PRBool HasFramesetChild(nsIContent* aContent);
00247 
00248   PRBool   CheckBeforeDestroy();
00249   nsresult Cancelled();
00250 
00251   nsresult ShowDocList(PRBool aShow);
00252 
00253   void GetNewPresentation(nsCOMPtr<nsIPresShell>& aShell, 
00254                           nsCOMPtr<nsPresContext>& aPC, 
00255                           nsCOMPtr<nsIViewManager>& aVM, 
00256                           nsCOMPtr<nsIWidget>& aW);
00257 
00258   // CachedPresentationObj is used to cache the presentation
00259   // so we can bring it back later
00260   PRBool HasCachedPres()
00261   {
00262     return mIsCachingPresentation && mCachedPresObj;
00263   }
00264   PRBool IsCachingPres()
00265   {
00266     return mIsCachingPresentation;
00267   }
00268   void SetCacheOldPres(PRBool aDoCache)
00269   {
00270     mIsCachingPresentation = aDoCache;
00271   }
00272   void CachePresentation(nsIPresShell* aShell, nsPresContext* aPC,
00273                          nsIViewManager* aVM, nsIWidget* aW);
00274   void GetCachedPresentation(nsCOMPtr<nsIPresShell>& aShell, 
00275                              nsCOMPtr<nsPresContext>& aPC, 
00276                              nsCOMPtr<nsIViewManager>& aVM, 
00277                              nsCOMPtr<nsIWidget>& aW);
00278 
00279   static nsIPresShell* GetPresShellFor(nsIDocShell* aDocShell);
00280 
00281   void SetDialogParent(nsIDOMWindow* aDOMWin)
00282   {
00283     mDialogParentWin = aDOMWin;
00284   }
00285 
00286   // These calls also update the DocViewer
00287   void SetIsPrinting(PRBool aIsPrinting);
00288   PRBool GetIsPrinting()
00289   {
00290     return mIsDoingPrinting;
00291   }
00292   void SetIsPrintPreview(PRBool aIsPrintPreview);
00293   PRBool GetIsPrintPreview()
00294   {
00295     return mIsDoingPrintPreview;
00296   }
00297   void SetIsCreatingPrintPreview(PRBool aIsCreatingPrintPreview)
00298   {
00299     mIsCreatingPrintPreview = aIsCreatingPrintPreview;
00300   }
00301   PRBool GetIsCreatingPrintPreview()
00302   {
00303     return mIsCreatingPrintPreview;
00304   }
00305 
00306 #ifdef MOZ_LAYOUTDEBUG
00307   static nsresult TestRuntimeErrorCondition(PRInt16  aRuntimeID, 
00308                                             nsresult aCurrentErrorCode, 
00309                                             nsresult aNewErrorCode);
00310 
00311   static PRBool IsDoingRuntimeTesting();
00312   static void InitializeTestRuntimeError();
00313 protected:
00314   static PRBool mIsDoingRuntimeTesting;
00315 
00316   static nsCOMPtr<nsIDebugObject> mLayoutDebugObj; // always de-referenced with the destructor
00317 #endif
00318 
00319 protected:
00320   void FirePrintCompletionEvent();
00321   nsresult ShowDocListInternal(nsPrintObject* aPO, PRBool aShow);
00322   nsresult GetSeqFrameAndCountPagesInternal(nsPrintObject*  aPO,
00323                                             nsIFrame*&      aSeqFrame,
00324                                             PRInt32&        aCount);
00325 
00326   static nsresult FindSelectionBoundsWithList(nsPresContext* aPresContext,
00327                                               nsIRenderingContext& aRC,
00328                                               nsIAtom*        aList,
00329                                               nsIFrame *      aParentFrame,
00330                                               nsRect&         aRect,
00331                                               nsIFrame *&     aStartFrame,
00332                                               nsRect&         aStartRect,
00333                                               nsIFrame *&     aEndFrame,
00334                                               nsRect&         aEndRect);
00335 
00336   static nsresult FindSelectionBounds(nsPresContext* aPresContext,
00337                                       nsIRenderingContext& aRC,
00338                                       nsIFrame *      aParentFrame,
00339                                       nsRect&         aRect,
00340                                       nsIFrame *&     aStartFrame,
00341                                       nsRect&         aStartRect,
00342                                       nsIFrame *&     aEndFrame,
00343                                       nsRect&         aEndRect);
00344 
00345   static nsresult GetPageRangeForSelection(nsIPresShell *        aPresShell,
00346                                            nsPresContext*       aPresContext,
00347                                            nsIRenderingContext&  aRC,
00348                                            nsISelection*         aSelection,
00349                                            nsIPageSequenceFrame* aPageSeqFrame,
00350                                            nsIFrame**            aStartFrame,
00351                                            PRInt32&              aStartPageNum,
00352                                            nsRect&               aStartRect,
00353                                            nsIFrame**            aEndFrame,
00354                                            PRInt32&              aEndPageNum,
00355                                            nsRect&               aEndRect);
00356 
00357   static nsIFrame * FindFrameByType(nsPresContext* aPresContext,
00358                                     nsIFrame *      aParentFrame,
00359                                     nsIAtom *       aType,
00360                                     nsRect&         aRect,
00361                                     nsRect&         aChildRect);
00362 
00363   // Static memeber variables
00364   PRBool mIsCreatingPrintPreview;
00365   PRBool mIsDoingPrinting;
00366 
00367   nsIDocumentViewerPrint* mDocViewerPrint; // [WEAK] it owns me!
00368   nsIDocumentViewer*      mDocViewer;      // [WEAK] it owns me!
00369   nsISupports*            mContainer;      // [WEAK] it owns me!
00370   nsIDeviceContext*       mDeviceContext;  // not ref counted
00371   nsPresContext*         mPresContext;    // not ref counted
00372   nsCOMPtr<nsIWidget>     mWindow;      
00373   
00374   nsPrintData*            mPrt;
00375   nsPagePrintTimer*       mPagePrintTimer;
00376   nsIPageSequenceFrame*   mPageSeqFrame;
00377 
00378   // Print Preview
00379   PRBool                  mIsDoingPrintPreview; // per DocumentViewer
00380   nsCOMPtr<nsIWidget>     mParentWidget;        
00381   nsPrintData*            mPrtPreview;
00382   nsPrintData*            mOldPrtPreview;
00383 
00384   nsCOMPtr<nsIDocument>   mDocument;
00385   nsCOMPtr<nsIDOMWindow>  mDialogParentWin;
00386 
00387   PRBool                      mIsCachingPresentation;
00388   CachedPresentationObj*      mCachedPresObj;
00389   FILE* mDebugFile;
00390 
00391 private:
00392   nsPrintEngine& operator=(const nsPrintEngine& aOther); // not implemented
00393 
00394 };
00395 
00396 #ifdef MOZ_LAYOUTDEBUG
00397 #define INIT_RUNTIME_ERROR_CHECKING() nsPrintEngine::InitializeTestRuntimeError();
00398 #define CHECK_RUNTIME_ERROR_CONDITION(_name, _currerr, _newerr) \
00399   if (nsPrintEngine::IsDoingRuntimeTesting()) { \
00400     _currerr = nsPrintEngine::TestRuntimeErrorCondition(_name, _currerr, _newerr); \
00401   }
00402 #else
00403 #define CHECK_RUNTIME_ERROR_CONDITION(_name, _currerr, _newerr)
00404 #define INIT_RUNTIME_ERROR_CHECKING()
00405 #endif
00406 
00407 #endif /* nsPrintEngine_h___ */