Bug 584193. Allow print preview to work without its own widget. r=smaug a=blocking beta5
authorRobert O'Callahan <roc@ocallahan.org>
Fri, 27 Aug 2010 18:15:08 -0500
changeset 54066 6e6c4aca141c62945e291b8104f31caadf19f8c2
parent 54065 6bed5f74e09fea603dcc68da81a8a9dc64e6158d
child 54067 b9f973282e1f3a01b54580a614ac78148f7e4c62
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, blocking
bugs584193
milestone2.0b5pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 584193. Allow print preview to work without its own widget. r=smaug a=blocking beta5
layout/base/nsIDocumentViewer.h
layout/base/nsIDocumentViewerPrint.h
layout/printing/nsPrintEngine.cpp
layout/printing/nsPrintEngine.h
layout/printing/nsPrintObject.cpp
layout/printing/nsPrintObject.h
--- a/layout/base/nsIDocumentViewer.h
+++ b/layout/base/nsIDocumentViewer.h
@@ -41,29 +41,33 @@
 #define nsIDocumentViewer_h___
 
 #include "nsIContentViewer.h"
 
 class nsIDocument;
 class nsPresContext;
 class nsIPresShell;
 class nsIStyleSheet;
+class nsIView;
 
 #define NS_IDOCUMENT_VIEWER_IID \
-  { 0xf29e5537, 0x0763, 0x4977, \
-    { 0x83, 0xc2, 0x3c, 0x93, 0x6c, 0x66, 0xa9, 0xfc } }
+  { 0x79c0bdbf, 0xf508, 0x4970, \
+    { 0x94, 0x65, 0x03, 0x5e, 0xda, 0x2c, 0x02, 0x72 } }
+
 /**
  * A document viewer is a kind of content viewer that uses NGLayout
  * to manage the presentation of the content.
  */
 class nsIDocumentViewer : public nsIContentViewer
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_VIEWER_IID)
   
   NS_IMETHOD GetPresShell(nsIPresShell** aResult) = 0;
   
   NS_IMETHOD GetPresContext(nsPresContext** aResult) = 0;
+
+  virtual nsIView* FindContainerView() = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentViewer, NS_IDOCUMENT_VIEWER_IID)
 
 #endif /* nsIDocumentViewer_h___ */
--- a/layout/base/nsIDocumentViewerPrint.h
+++ b/layout/base/nsIDocumentViewerPrint.h
@@ -85,18 +85,17 @@ public:
   /**
    * Marks this viewer to be used for print preview.
    */
   virtual void InitializeForPrintPreview() = 0;
 
   /**
    * Replaces the current presentation with print preview presentation.
    */
-  virtual void SetPrintPreviewPresentation(nsIWidget* aWidget,
-                                           nsIViewManager* aViewManager,
+  virtual void SetPrintPreviewPresentation(nsIViewManager* aViewManager,
                                            nsPresContext* aPresContext,
                                            nsIPresShell* aPresShell) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentViewerPrint,
                               NS_IDOCUMENT_VIEWER_PRINT_IID)
 
 /* Use this macro when declaring classes that implement this interface. */
@@ -106,14 +105,13 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumen
   virtual void     SetIsPrintPreview(PRBool aIsPrintPreview); \
   virtual PRBool   GetIsPrintPreview(); \
   virtual nsresult CreateStyleSet(nsIDocument* aDocument, nsStyleSet** aStyleSet); \
   virtual void     IncrementDestroyRefCount(); \
   virtual void     ReturnToGalleyPresentation(); \
   virtual void     OnDonePrinting(); \
   virtual PRBool   IsInitializedForPrintPreview(); \
   virtual void     InitializeForPrintPreview(); \
-  virtual void     SetPrintPreviewPresentation(nsIWidget* aWidget, \
-                                               nsIViewManager* aViewManager, \
+  virtual void     SetPrintPreviewPresentation(nsIViewManager* aViewManager, \
                                                nsPresContext* aPresContext, \
                                                nsIPresShell* aPresShell);
 
 #endif /* nsIDocumentViewerPrint_h___ */
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -150,16 +150,17 @@ static const char kPrintingPromptService
 #include "nsGUIEvent.h"
 #include "nsHTMLReflowState.h"
 #include "nsIDOMHTMLAnchorElement.h"
 #include "nsIDOMHTMLAreaElement.h"
 #include "nsIDOMHTMLLinkElement.h"
 #include "nsIDOMHTMLImageElement.h"
 #include "nsIContentViewerContainer.h"
 #include "nsIContentViewer.h"
+#include "nsIDocumentViewer.h"
 #include "nsIDocumentViewerPrint.h"
 
 #include "nsPIDOMWindow.h"
 #include "nsFocusManager.h"
 #include "nsRange.h"
 #include "nsCDefaultURIFixup.h"
 #include "nsIURIFixup.h"
 #include "mozilla/dom/Element.h"
@@ -260,17 +261,16 @@ nsPrintEngine::nsPrintEngine() :
   mIsDoingPrinting(PR_FALSE),
   mIsDoingPrintPreview(PR_FALSE),
   mProgressDialogIsShown(PR_FALSE),
   mContainer(nsnull),
   mScreenDPI(115.0f),
   mPrt(nsnull),
   mPagePrintTimer(nsnull),
   mPageSeqFrame(nsnull),
-  mParentWidget(nsnull),
   mPrtPreview(nsnull),
   mOldPrtPreview(nsnull),
   mDebugFile(nsnull)
 {
 }
 
 //-------------------------------------------------------
 nsPrintEngine::~nsPrintEngine()
@@ -315,28 +315,26 @@ void nsPrintEngine::DestroyPrintingData(
 //-- Section: Methods needed by the DocViewer
 //---------------------------------------------------------------------------------
 
 //--------------------------------------------------------
 nsresult nsPrintEngine::Initialize(nsIDocumentViewerPrint* aDocViewerPrint, 
                                    nsISupports*            aContainer,
                                    nsIDocument*            aDocument,
                                    float                   aScreenDPI,
-                                   nsIWidget*              aParentWidget,
                                    FILE*                   aDebugFile)
 {
   NS_ENSURE_ARG_POINTER(aDocViewerPrint);
   NS_ENSURE_ARG_POINTER(aContainer);
   NS_ENSURE_ARG_POINTER(aDocument);
 
   mDocViewerPrint = aDocViewerPrint;
   mContainer      = aContainer;      // weak reference
   mDocument       = aDocument;
   mScreenDPI      = aScreenDPI;
-  mParentWidget   = aParentWidget;    
 
   mDebugFile      = aDebugFile;      // ok to be NULL
 
   return NS_OK;
 }
 
 //-------------------------------------------------------
 PRBool
@@ -1879,35 +1877,47 @@ nsPrintEngine::ReflowDocList(nsPrintObje
 nsresult
 nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO)
 {
   NS_ASSERTION(aPO, "Pointer is null!");
   if (!aPO) return NS_ERROR_FAILURE;
 
   nsSize adjSize;
   PRBool documentIsTopLevel;
-  nsIFrame* frame = nsnull;
   if (!aPO->IsPrintable())
     return NS_OK;
 
+  PRBool canCreateScrollbars = PR_TRUE;
+  nsIView* parentView = nsnull;
+
   if (aPO->mParent && aPO->mParent->IsPrintable()) {
-    frame = aPO->mContent->GetPrimaryFrame();
+    nsIFrame* frame = aPO->mContent->GetPrimaryFrame();
     // Without a frame, this document can't be displayed; therefore, there is no
     // point to reflowing it
     if (!frame) {
       SetPrintPO(aPO, PR_FALSE);
       return NS_OK;
     }
 
     //XXX If printing supported printing document hierarchies with non-constant
     // zoom this would be wrong as we use the same mPrt->mPrintDC for all
     // subdocuments.
     adjSize = frame->GetContentRect().Size();
     documentIsTopLevel = PR_FALSE;
     // presshell exists because parent is printable
+
+    // the top nsPrintObject's widget will always have scrollbars
+    if (frame && frame->GetType() == nsGkAtoms::subDocumentFrame) {
+      nsIView* view = frame->GetView();
+      NS_ENSURE_TRUE(view, NS_ERROR_FAILURE);
+      view = view->GetFirstChild();
+      NS_ENSURE_TRUE(view, NS_ERROR_FAILURE);
+      parentView = view;
+      canCreateScrollbars = PR_FALSE;
+    }
   } else {
     nscoord pageWidth, pageHeight;
     mPrt->mPrintDC->GetDeviceSurfaceDimensions(pageWidth, pageHeight);
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
     // If we're in landscape mode on Linux, the device surface will have 
     // been rotated, so for the purposes of reflowing content, we'll 
     // treat device's height as our width and its width as our height, 
     PRInt32 orientation;
@@ -1916,41 +1926,27 @@ nsPrintEngine::ReflowPrintObject(nsPrint
       adjSize = nsSize(pageHeight, pageWidth);
     } else {
       adjSize = nsSize(pageWidth, pageHeight);
     }
 #else
     adjSize = nsSize(pageWidth, pageHeight);
 #endif // XP_UNIX && !XP_MACOSX
     documentIsTopLevel = PR_TRUE;
-  }
-
-  // Here we decide whether we need scrollbars and
-  // what the parent will be of the widget
-  // How this logic presently works: Print Preview is always as-is (as far
-  // as I can tell; not sure how it would work in other cases); only the root 
-  // is not eIFrame or eFrame.  The child documents get a parent widget from
-  // logic in nsFrameFrame.  In any case, a child widget is created for the root
-  // view of the document.
-  PRBool canCreateScrollbars = PR_TRUE;
-  nsIView* parentView = nsnull;
-  // the top nsPrintObject's widget will always have scrollbars
-  if (frame && frame->GetType() == nsGkAtoms::subDocumentFrame) {
-    nsIView* view = frame->GetView();
-    NS_ENSURE_TRUE(view, NS_ERROR_FAILURE);
-    view = view->GetFirstChild();
-    NS_ENSURE_TRUE(view, NS_ERROR_FAILURE);
-    parentView = view;
-    canCreateScrollbars = PR_FALSE;
+
+    nsCOMPtr<nsIDocumentViewer> dv = do_QueryInterface(mDocViewerPrint);
+    if (dv) {
+      parentView = dv->FindContainerView();
+    }
   }
 
   NS_ASSERTION(!aPO->mPresContext, "Recreating prescontext");
 
   // create the PresContext
-  aPO->mPresContext = new nsRootPresContext(aPO->mDocument,
+  aPO->mPresContext = new nsPresContext(aPO->mDocument,
     mIsCreatingPrintPreview ? nsPresContext::eContext_PrintPreview:
                               nsPresContext::eContext_Print);
   NS_ENSURE_TRUE(aPO->mPresContext, NS_ERROR_OUT_OF_MEMORY);
   aPO->mPresContext->SetPrintSettings(mPrt->mPrintSettings);
 
   // set the presentation context to the value in the print settings
   PRBool printBGColors;
   mPrt->mPrintSettings->GetPrintBGColors(&printBGColors);
@@ -1986,31 +1982,17 @@ nsPrintEngine::ReflowPrintObject(nsPrint
   PR_PL(("In DV::ReflowPrintObject PO: %p (%9s) Setting w,h to %d,%d\n", aPO,
          gFrameTypesStr[aPO->mFrameType], adjSize.width, adjSize.height));
 
   // Create a child window of the parent that is our "root view/window"
   nsRect tbounds = nsRect(nsPoint(0, 0), adjSize);
   nsIView* rootView = aPO->mViewManager->CreateView(tbounds, parentView);
   NS_ENSURE_TRUE(rootView, NS_ERROR_OUT_OF_MEMORY);
 
-  // Only create a widget for print preview; when printing, a widget is
-  // unnecessary and unexpected
-  // Also, no widget should be needed except for the top-level document
   if (mIsCreatingPrintPreview && documentIsTopLevel) {
-    nsIWidget* widget = nsnull;
-    if (!frame)
-      widget = mParentWidget;
-    rv = widget ? rootView->CreateWidgetForParent(widget, nsnull,
-                                                  PR_TRUE, PR_TRUE,
-                                                  eContentTypeContent)
-                : rootView->CreateWidget(nsnull,
-                                         PR_TRUE, PR_TRUE,
-                                         eContentTypeContent);
-    NS_ENSURE_SUCCESS(rv, rv);
-    aPO->mWindow = rootView->GetWidget();
     aPO->mPresContext->SetPaginatedScrolling(canCreateScrollbars);
   }
 
   // Setup hierarchical relationship in view manager
   aPO->mViewManager->SetRootView(rootView);
 
   // This docshell stuff is weird; will go away when we stop having multiple
   // presentations per document
@@ -2023,18 +2005,17 @@ nsPrintEngine::ReflowPrintObject(nsPrint
   aPO->mPresContext->SetIsRootPaginatedDocument(documentIsTopLevel);
   aPO->mPresContext->SetPageScale(aPO->mZoomRatio);
   // Calculate scale factor from printer to screen
   float printDPI = float(mPrt->mPrintDC->AppUnitsPerCSSInch()) /
                    float(mPrt->mPrintDC->AppUnitsPerDevPixel());
   aPO->mPresContext->SetPrintPreviewScale(mScreenDPI / printDPI);
 
   if (mIsCreatingPrintPreview && documentIsTopLevel) {
-    mDocViewerPrint->SetPrintPreviewPresentation(aPO->mWindow,
-                                                 aPO->mViewManager,
+    mDocViewerPrint->SetPrintPreviewPresentation(aPO->mViewManager,
                                                  aPO->mPresContext,
                                                  aPO->mPresShell);
   }
 
   rv = aPO->mPresShell->InitialReflow(adjSize.width, adjSize.height);
 
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ASSERTION(aPO->mPresShell, "Presshell should still be here");
--- a/layout/printing/nsPrintEngine.h
+++ b/layout/printing/nsPrintEngine.h
@@ -100,17 +100,16 @@ public:
 
   void Destroy();
   void DestroyPrintingData();
 
   nsresult Initialize(nsIDocumentViewerPrint* aDocViewerPrint, 
                       nsISupports*            aContainer,
                       nsIDocument*            aDocument,
                       float                   aScreenDPI,
-                      nsIWidget*              aParentWidget,
                       FILE*                   aDebugFile);
 
   nsresult GetSeqFrameAndCountPages(nsIFrame*& aSeqFrame, PRInt32& aCount);
 
   //
   // The following three methods are used for printing...
   //
   nsresult DocumentReadyForPrinting();
@@ -190,18 +189,16 @@ public:
   static void ShowPrintErrorDialog(nsresult printerror,
                                    PRBool aIsPrinting = PR_TRUE);
 
   static PRBool HasFramesetChild(nsIContent* aContent);
 
   PRBool   CheckBeforeDestroy();
   nsresult Cancelled();
 
-  nsIWidget* GetPrintPreviewWindow() {return mPrtPreview->mPrintObject->mWindow;}
-
   nsIPresShell* GetPrintPreviewPresShell() {return mPrtPreview->mPrintObject->mPresShell;}
 
   float GetPrintPreviewScale() { return mPrtPreview->mPrintObject->
                                         mPresContext->GetPrintPreviewScale(); }
   
   static nsIPresShell* GetPresShellFor(nsIDocShell* aDocShell);
 
   // These calls also update the DocViewer
@@ -286,17 +283,16 @@ protected:
   nsISupports*            mContainer;      // [WEAK] it owns me!
   float                   mScreenDPI;
   
   nsPrintData*            mPrt;
   nsPagePrintTimer*       mPagePrintTimer;
   nsIPageSequenceFrame*   mPageSeqFrame;
 
   // Print Preview
-  nsCOMPtr<nsIWidget>     mParentWidget;        
   nsPrintData*            mPrtPreview;
   nsPrintData*            mOldPrtPreview;
 
   nsCOMPtr<nsIDocument>   mDocument;
 
   FILE* mDebugFile;
 
 private:
--- a/layout/printing/nsPrintObject.cpp
+++ b/layout/printing/nsPrintObject.cpp
@@ -117,17 +117,16 @@ nsPrintObject::Init(nsIDocShell* aDocShe
   return NS_OK;
 }
 
 //------------------------------------------------------------------
 // Resets PO by destroying the presentation
 void 
 nsPrintObject::DestroyPresentation()
 {
-  mWindow      = nsnull;
   mPresContext = nsnull;
   if (mPresShell) {
     mPresShell->EndObservingDocument();
     nsAutoScriptBlocker scriptBlocker;
     mPresShell->Destroy();
   }
   mPresShell   = nsnull;
   mViewManager = nsnull;
--- a/layout/printing/nsPrintObject.h
+++ b/layout/printing/nsPrintObject.h
@@ -40,17 +40,16 @@
 // Interfaces
 #include "nsCOMPtr.h"
 #include "nsIContent.h"
 #include "nsIPresShell.h"
 #include "nsStyleSet.h"
 #include "nsIViewManager.h"
 #include "nsIDocShell.h"
 #include "nsIDocument.h"
-#include "nsIWidget.h"
 
 class nsPresContext;
 
 // nsPrintObject Document Type
 enum PrintObjectType  {eDoc = 0, eFrame = 1, eIFrame = 2, eFrameSet = 3};
 
 //---------------------------------------------------
 //-- nsPrintObject Class
@@ -71,17 +70,16 @@ public:
 
   // Data Members
   nsCOMPtr<nsIDocShell>    mDocShell;
   nsCOMPtr<nsIDocument>    mDocument;
 
   nsRefPtr<nsPresContext>  mPresContext;
   nsCOMPtr<nsIPresShell>   mPresShell;
   nsCOMPtr<nsIViewManager> mViewManager;
-  nsCOMPtr<nsIWidget>      mWindow;
 
   nsCOMPtr<nsIContent>     mContent;
   PrintObjectType  mFrameType;
   
   nsTArray<nsPrintObject*> mKids;
   nsPrintObject*   mParent;
   PRPackedBool     mHasBeenPrinted;
   PRPackedBool     mDontPrint;