1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsPrintJob_h
7 #define nsPrintJob_h
8 
9 #include "mozilla/Attributes.h"
10 #include "mozilla/UniquePtr.h"
11 
12 #include "nsCOMPtr.h"
13 
14 #include "nsPrintObject.h"
15 #include "nsPrintData.h"
16 #include "nsFrameList.h"
17 #include "nsIFrame.h"
18 #include "nsIWebProgress.h"
19 #include "mozilla/dom/HTMLCanvasElement.h"
20 #include "nsIWebProgressListener.h"
21 #include "nsWeakReference.h"
22 
23 // Interfaces
24 #include "nsIObserver.h"
25 
26 // Classes
27 class nsPagePrintTimer;
28 class nsIDocShell;
29 class nsIDocument;
30 class nsIDocumentViewerPrint;
31 class nsPrintObject;
32 class nsIDocShell;
33 class nsIPageSequenceFrame;
34 
35 /**
36  * A print job may be instantiated either for printing to an actual physical
37  * printer, or for creating a print preview.
38  */
39 class nsPrintJob final : public nsIObserver,
40                          public nsIWebProgressListener,
41                          public nsSupportsWeakReference {
42  public:
43   static nsresult GetGlobalPrintSettings(nsIPrintSettings** aPrintSettings);
44   static void CloseProgressDialog(nsIWebProgressListener* aWebProgressListener);
45 
46   nsPrintJob() = default;
47 
48   // nsISupports interface...
49   NS_DECL_ISUPPORTS
50 
51   // nsIObserver
52   NS_DECL_NSIOBSERVER
53 
54   NS_DECL_NSIWEBPROGRESSLISTENER
55 
56   // Old nsIWebBrowserPrint methods; not cleaned up yet
57   NS_IMETHOD Print(nsIPrintSettings* aPrintSettings,
58                    nsIWebProgressListener* aWebProgressListener);
59   NS_IMETHOD PrintPreview(nsIPrintSettings* aPrintSettings,
60                           mozIDOMWindowProxy* aChildDOMWin,
61                           nsIWebProgressListener* aWebProgressListener);
62   NS_IMETHOD GetIsFramesetDocument(bool* aIsFramesetDocument);
63   NS_IMETHOD GetIsIFrameSelected(bool* aIsIFrameSelected);
64   NS_IMETHOD GetIsRangeSelection(bool* aIsRangeSelection);
65   NS_IMETHOD GetIsFramesetFrameSelected(bool* aIsFramesetFrameSelected);
66   NS_IMETHOD GetPrintPreviewNumPages(int32_t* aPrintPreviewNumPages);
67   NS_IMETHOD EnumerateDocumentNames(uint32_t* aCount, char16_t*** aResult);
68   NS_IMETHOD GetDoingPrint(bool* aDoingPrint);
69   NS_IMETHOD GetDoingPrintPreview(bool* aDoingPrintPreview);
70   NS_IMETHOD GetCurrentPrintSettings(nsIPrintSettings** aCurrentPrintSettings);
71 
72   // This enum tells indicates what the default should be for the title
73   // if the title from the document is null
74   enum eDocTitleDefault { eDocTitleDefBlank, eDocTitleDefURLDoc };
75 
76   void Destroy();
77   void DestroyPrintingData();
78 
79   nsresult Initialize(nsIDocumentViewerPrint* aDocViewerPrint,
80                       nsIDocShell* aContainer, nsIDocument* aDocument,
81                       float aScreenDPI);
82 
83   nsresult GetSeqFrameAndCountPages(nsIFrame*& aSeqFrame, int32_t& aCount);
84 
85   //
86   // The following three methods are used for printing...
87   //
88   nsresult DocumentReadyForPrinting();
89   nsresult GetSelectionDocument(nsIDeviceContextSpec* aDevSpec,
90                                 nsIDocument** aNewDoc);
91 
92   nsresult SetupToPrintContent();
93   nsresult EnablePOsForPrinting();
94   nsPrintObject* FindSmallestSTF();
95 
96   bool PrintDocContent(const mozilla::UniquePtr<nsPrintObject>& aPO,
97                        nsresult& aStatus);
98   nsresult DoPrint(const mozilla::UniquePtr<nsPrintObject>& aPO);
99 
100   void SetPrintPO(nsPrintObject* aPO, bool aPrint);
101 
102   void TurnScriptingOn(bool aDoTurnOn);
103   bool CheckDocumentForPPCaching();
104   void InstallPrintPreviewListener();
105 
106   // nsIDocumentViewerPrint Printing Methods
107   bool HasPrintCallbackCanvas();
108   bool PrePrintPage();
109   bool PrintPage(nsPrintObject* aPOect, bool& aInRange);
110   bool DonePrintingPages(nsPrintObject* aPO, nsresult aResult);
111 
112   //---------------------------------------------------------------------
113   void BuildDocTree(nsIDocShell* aParentNode,
114                     nsTArray<nsPrintObject*>* aDocList,
115                     const mozilla::UniquePtr<nsPrintObject>& aPO);
116   nsresult ReflowDocList(const mozilla::UniquePtr<nsPrintObject>& aPO,
117                          bool aSetPixelScale);
118 
119   nsresult ReflowPrintObject(const mozilla::UniquePtr<nsPrintObject>& aPO);
120 
121   void CheckForChildFrameSets(const mozilla::UniquePtr<nsPrintObject>& aPO);
122 
123   void CalcNumPrintablePages(int32_t& aNumPages);
124   void ShowPrintProgress(bool aIsForPrinting, bool& aDoNotify);
125   nsresult CleanupOnFailure(nsresult aResult, bool aIsPrinting);
126   // If FinishPrintPreview() fails, caller may need to reset the state of the
127   // object, for example by calling CleanupOnFailure().
128   nsresult FinishPrintPreview();
129   void SetDocAndURLIntoProgress(const mozilla::UniquePtr<nsPrintObject>& aPO,
130                                 nsIPrintProgressParams* aParams);
131   void EllipseLongString(nsAString& aStr, const uint32_t aLen, bool aDoFront);
132   nsresult CheckForPrinters(nsIPrintSettings* aPrintSettings);
133   void CleanupDocTitleArray(char16_t**& aArray, int32_t& aCount);
134 
135   bool IsThereARangeSelection(nsPIDOMWindowOuter* aDOMWin);
136 
137   void FirePrintingErrorEvent(nsresult aPrintError);
138   //---------------------------------------------------------------------
139 
140   // Timer Methods
141   nsresult StartPagePrintTimer(const mozilla::UniquePtr<nsPrintObject>& aPO);
142 
143   bool IsWindowsInOurSubTree(nsPIDOMWindowOuter* aDOMWindow);
144   bool IsThereAnIFrameSelected(nsIDocShell* aDocShell,
145                                nsPIDOMWindowOuter* aDOMWin,
146                                bool& aIsParentFrameSet);
147 
148   // get the currently infocus frame for the document viewer
149   already_AddRefed<nsPIDOMWindowOuter> FindFocusedDOMWindow();
150 
151   void GetDisplayTitleAndURL(const mozilla::UniquePtr<nsPrintObject>& aPO,
152                              nsAString& aTitle, nsAString& aURLStr,
153                              eDocTitleDefault aDefType);
154 
155   bool CheckBeforeDestroy();
156   nsresult Cancelled();
157 
GetPrintPreviewPresShell()158   nsIPresShell* GetPrintPreviewPresShell() {
159     return mPrtPreview->mPrintObject->mPresShell;
160   }
161 
GetPrintPreviewScale()162   float GetPrintPreviewScale() {
163     return mPrtPreview->mPrintObject->mPresContext->GetPrintPreviewScale();
164   }
165 
166   // These calls also update the DocViewer
167   void SetIsPrinting(bool aIsPrinting);
GetIsPrinting()168   bool GetIsPrinting() { return mIsDoingPrinting; }
169   void SetIsPrintPreview(bool aIsPrintPreview);
GetIsPrintPreview()170   bool GetIsPrintPreview() { return mIsDoingPrintPreview; }
GetIsCreatingPrintPreview()171   bool GetIsCreatingPrintPreview() { return mIsCreatingPrintPreview; }
172 
SetDisallowSelectionPrint(bool aDisallowSelectionPrint)173   void SetDisallowSelectionPrint(bool aDisallowSelectionPrint) {
174     mDisallowSelectionPrint = aDisallowSelectionPrint;
175   }
176 
177  private:
178   nsPrintJob& operator=(const nsPrintJob& aOther) = delete;
179 
180   ~nsPrintJob();
181 
182   nsresult CommonPrint(bool aIsPrintPreview, nsIPrintSettings* aPrintSettings,
183                        nsIWebProgressListener* aWebProgressListener,
184                        nsIDOMDocument* aDoc);
185 
186   nsresult DoCommonPrint(bool aIsPrintPreview, nsIPrintSettings* aPrintSettings,
187                          nsIWebProgressListener* aWebProgressListener,
188                          nsIDOMDocument* aDoc);
189 
190   void FirePrintCompletionEvent();
191 
192   void DisconnectPagePrintTimer();
193 
194   nsresult AfterNetworkPrint(bool aHandleError);
195 
196   nsresult SetRootView(nsPrintObject* aPO, bool& aDoReturn,
197                        bool& aDocumentIsTopLevel, nsSize& aAdjSize);
198   nsView* GetParentViewForRoot();
199   bool DoSetPixelScale();
200   void UpdateZoomRatio(nsPrintObject* aPO, bool aSetPixelScale);
201   nsresult ReconstructAndReflow(bool aDoSetPixelScale);
202   nsresult UpdateSelectionAndShrinkPrintObject(nsPrintObject* aPO,
203                                                bool aDocumentIsTopLevel);
204   nsresult InitPrintDocConstruction(bool aHandleError);
205   void FirePrintPreviewUpdateEvent();
206 
207   void PageDone(nsresult aResult);
208 
209   nsCOMPtr<nsIDocument> mDocument;
210   nsCOMPtr<nsIDocumentViewerPrint> mDocViewerPrint;
211 
212   nsWeakPtr mContainer;
213   WeakFrame mPageSeqFrame;
214 
215   // We are the primary owner of our nsPrintData member vars.  These vars
216   // are refcounted so that functions (e.g. nsPrintData methods) can create
217   // temporary owning references when they need to fire a callback that
218   // could conceivably destroy this nsPrintJob owner object and all its
219   // member-data.
220   RefPtr<nsPrintData> mPrt;
221 
222   // Print Preview
223   RefPtr<nsPrintData> mPrtPreview;
224   RefPtr<nsPrintData> mOldPrtPreview;
225 
226   nsPagePrintTimer* mPagePrintTimer = nullptr;
227 
228   float mScreenDPI = 115.0f;
229   int32_t mLoadCounter = 0;
230 
231   bool mIsCreatingPrintPreview = false;
232   bool mIsDoingPrinting = false;
233   bool mIsDoingPrintPreview = false;
234   bool mProgressDialogIsShown = false;
235   bool mDidLoadDataForPrinting = false;
236   bool mIsDestroying = false;
237   bool mDisallowSelectionPrint = false;
238 };
239 
240 #endif  // nsPrintJob_h
241