LCOV - code coverage report
Current view: directory - layout/printing - nsPrintEngine.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 1405 2 0.1 %
Date: 2012-06-02 Functions: 86 2 2.3 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "nsPrintEngine.h"
      40                 : 
      41                 : #include "nsIStringBundle.h"
      42                 : #include "nsReadableUtils.h"
      43                 : #include "nsCRT.h"
      44                 : 
      45                 : #include "nsISelection.h"
      46                 : #include "nsIScriptGlobalObject.h"
      47                 : #include "nsPIDOMWindow.h"
      48                 : #include "nsIDocShell.h"
      49                 : #include "nsIFrame.h"
      50                 : #include "nsIURI.h"
      51                 : #include "nsITextToSubURI.h"
      52                 : #include "nsContentErrors.h"
      53                 : 
      54                 : // Print Options
      55                 : #include "nsIPrintSettings.h"
      56                 : #include "nsIPrintSettingsService.h"
      57                 : #include "nsIPrintOptions.h"
      58                 : #include "nsIPrintSession.h"
      59                 : #include "nsGfxCIID.h"
      60                 : #include "nsIServiceManager.h"
      61                 : #include "nsGkAtoms.h"
      62                 : #include "nsXPCOM.h"
      63                 : #include "nsISupportsPrimitives.h"
      64                 : 
      65                 : static const char sPrintSettingsServiceContractID[] = "@mozilla.org/gfx/printsettings-service;1";
      66                 : 
      67                 : // Printing Events
      68                 : #include "nsPrintPreviewListener.h"
      69                 : #include "nsThreadUtils.h"
      70                 : 
      71                 : // Printing
      72                 : #include "nsIWebBrowserPrint.h"
      73                 : #include "nsIDOMHTMLFrameElement.h"
      74                 : #include "nsIDOMHTMLFrameSetElement.h"
      75                 : #include "nsIDOMHTMLIFrameElement.h"
      76                 : #include "nsIDOMHTMLObjectElement.h"
      77                 : #include "nsIDOMHTMLEmbedElement.h"
      78                 : 
      79                 : // Print Preview
      80                 : #include "imgIContainer.h" // image animation mode constants
      81                 : #include "nsIWebBrowserPrint.h" // needed for PrintPreview Navigation constants
      82                 : 
      83                 : // Print Progress
      84                 : #include "nsIPrintProgress.h"
      85                 : #include "nsIPrintProgressParams.h"
      86                 : #include "nsIObserver.h"
      87                 : 
      88                 : // Print error dialog
      89                 : #include "nsIPrompt.h"
      90                 : #include "nsIWindowWatcher.h"
      91                 : 
      92                 : // Printing Prompts
      93                 : #include "nsIPrintingPromptService.h"
      94                 : static const char kPrintingPromptService[] = "@mozilla.org/embedcomp/printingprompt-service;1";
      95                 : 
      96                 : // Printing Timer
      97                 : #include "nsPagePrintTimer.h"
      98                 : 
      99                 : // FrameSet
     100                 : #include "nsIDocument.h"
     101                 : 
     102                 : // Focus
     103                 : #include "nsIDOMEventTarget.h"
     104                 : #include "nsISelectionController.h"
     105                 : 
     106                 : // Misc
     107                 : #include "nsISupportsUtils.h"
     108                 : #include "nsIScriptContext.h"
     109                 : #include "nsILinkHandler.h"
     110                 : #include "nsIDOMDocument.h"
     111                 : #include "nsISelectionListener.h"
     112                 : #include "nsISelectionPrivate.h"
     113                 : #include "nsIDOMHTMLDocument.h"
     114                 : #include "nsIDOMHTMLCollection.h"
     115                 : #include "nsIDOMHTMLElement.h"
     116                 : #include "nsIDOMRange.h"
     117                 : #include "nsContentCID.h"
     118                 : #include "nsLayoutCID.h"
     119                 : #include "nsContentUtils.h"
     120                 : #include "nsIPresShell.h"
     121                 : #include "nsLayoutUtils.h"
     122                 : #include "mozilla/Preferences.h"
     123                 : 
     124                 : #include "nsViewsCID.h"
     125                 : #include "nsWidgetsCID.h"
     126                 : #include "nsIDeviceContextSpec.h"
     127                 : #include "nsIViewManager.h"
     128                 : #include "nsIView.h"
     129                 : #include "nsRenderingContext.h"
     130                 : 
     131                 : #include "nsIPageSequenceFrame.h"
     132                 : #include "nsIURL.h"
     133                 : #include "nsIContentViewerEdit.h"
     134                 : #include "nsIContentViewerFile.h"
     135                 : #include "nsIMarkupDocumentViewer.h"
     136                 : #include "nsIInterfaceRequestor.h"
     137                 : #include "nsIInterfaceRequestorUtils.h"
     138                 : #include "nsIDocShellTreeItem.h"
     139                 : #include "nsIDocShellTreeNode.h"
     140                 : #include "nsIDocShellTreeOwner.h"
     141                 : #include "nsIWebBrowserChrome.h"
     142                 : #include "nsIBaseWindow.h"
     143                 : #include "nsILayoutHistoryState.h"
     144                 : #include "nsFrameManager.h"
     145                 : #include "nsIParser.h"
     146                 : #include "nsGUIEvent.h"
     147                 : #include "nsHTMLReflowState.h"
     148                 : #include "nsIDOMHTMLAnchorElement.h"
     149                 : #include "nsIDOMHTMLAreaElement.h"
     150                 : #include "nsIDOMHTMLLinkElement.h"
     151                 : #include "nsIDOMHTMLImageElement.h"
     152                 : #include "nsIContentViewerContainer.h"
     153                 : #include "nsIContentViewer.h"
     154                 : #include "nsIDocumentViewerPrint.h"
     155                 : 
     156                 : #include "nsFocusManager.h"
     157                 : #include "nsRange.h"
     158                 : #include "nsCDefaultURIFixup.h"
     159                 : #include "nsIURIFixup.h"
     160                 : #include "mozilla/dom/Element.h"
     161                 : 
     162                 : using namespace mozilla;
     163                 : using namespace mozilla::dom;
     164                 : 
     165                 : //-----------------------------------------------------
     166                 : // PR LOGGING
     167                 : #ifdef MOZ_LOGGING
     168                 : #define FORCE_PR_LOG /* Allow logging in the release build */
     169                 : #endif
     170                 : 
     171                 : #include "prlog.h"
     172                 : 
     173                 : #ifdef PR_LOGGING
     174                 : 
     175                 : #ifdef NS_DEBUG
     176                 : // PR_LOGGING is force to always be on (even in release builds)
     177                 : // but we only want some of it on,
     178                 : //#define EXTENDED_DEBUG_PRINTING 
     179                 : #endif
     180                 : 
     181                 : #define DUMP_LAYOUT_LEVEL 9 // this turns on the dumping of each doucment's layout info
     182                 : 
     183            1464 : static PRLogModuleInfo * kPrintingLogMod = PR_NewLogModule("printing");
     184                 : #define PR_PL(_p1)  PR_LOG(kPrintingLogMod, PR_LOG_DEBUG, _p1);
     185                 : 
     186                 : #ifdef EXTENDED_DEBUG_PRINTING
     187                 : static PRUint32 gDumpFileNameCnt   = 0;
     188                 : static PRUint32 gDumpLOFileNameCnt = 0;
     189                 : #endif
     190                 : 
     191                 : #define PRT_YESNO(_p) ((_p)?"YES":"NO")
     192                 : static const char * gFrameTypesStr[]       = {"eDoc", "eFrame", "eIFrame", "eFrameSet"};
     193                 : static const char * gPrintFrameTypeStr[]   = {"kNoFrames", "kFramesAsIs", "kSelectedFrame", "kEachFrameSep"};
     194                 : static const char * gFrameHowToEnableStr[] = {"kFrameEnableNone", "kFrameEnableAll", "kFrameEnableAsIsAndEach"};
     195                 : static const char * gPrintRangeStr[]       = {"kRangeAllPages", "kRangeSpecifiedPageRange", "kRangeSelection", "kRangeFocusFrame"};
     196                 : #else
     197                 : #define PRT_YESNO(_p)
     198                 : #define PR_PL(_p1)
     199                 : #endif
     200                 : 
     201                 : #ifdef EXTENDED_DEBUG_PRINTING
     202                 : // Forward Declarations
     203                 : static void DumpPrintObjectsListStart(const char * aStr, nsTArray<nsPrintObject*> * aDocList);
     204                 : static void DumpPrintObjectsTree(nsPrintObject * aPO, int aLevel= 0, FILE* aFD = nsnull);
     205                 : static void DumpPrintObjectsTreeLayout(nsPrintObject * aPO,nsDeviceContext * aDC, int aLevel= 0, FILE * aFD = nsnull);
     206                 : 
     207                 : #define DUMP_DOC_LIST(_title) DumpPrintObjectsListStart((_title), mPrt->mPrintDocList);
     208                 : #define DUMP_DOC_TREE DumpPrintObjectsTree(mPrt->mPrintObject);
     209                 : #define DUMP_DOC_TREELAYOUT DumpPrintObjectsTreeLayout(mPrt->mPrintObject, mPrt->mPrintDC);
     210                 : #else
     211                 : #define DUMP_DOC_LIST(_title)
     212                 : #define DUMP_DOC_TREE
     213                 : #define DUMP_DOC_TREELAYOUT
     214                 : #endif
     215                 : 
     216                 : class nsScriptSuppressor
     217                 : {
     218                 : public:
     219               0 :   nsScriptSuppressor(nsPrintEngine* aPrintEngine)
     220               0 :   : mPrintEngine(aPrintEngine), mSuppressed(false) {}
     221                 : 
     222               0 :   ~nsScriptSuppressor() { Unsuppress(); }
     223                 : 
     224               0 :   void Suppress()
     225                 :   {
     226               0 :     if (mPrintEngine) {
     227               0 :       mSuppressed = true;
     228               0 :       mPrintEngine->TurnScriptingOn(false);
     229                 :     }
     230               0 :   }
     231                 :   
     232               0 :   void Unsuppress()
     233                 :   {
     234               0 :     if (mPrintEngine && mSuppressed) {
     235               0 :       mPrintEngine->TurnScriptingOn(true);
     236                 :     }
     237               0 :     mSuppressed = false;
     238               0 :   }
     239                 : 
     240               0 :   void Disconnect() { mPrintEngine = nsnull; }
     241                 : protected:
     242                 :   nsRefPtr<nsPrintEngine> mPrintEngine;
     243                 :   bool                    mSuppressed;
     244                 : };
     245                 : 
     246                 : // Class IDs
     247                 : static NS_DEFINE_CID(kViewManagerCID,       NS_VIEW_MANAGER_CID);
     248                 : 
     249               0 : NS_IMPL_ISUPPORTS1(nsPrintEngine, nsIObserver)
     250                 : 
     251                 : //---------------------------------------------------
     252                 : //-- nsPrintEngine Class Impl
     253                 : //---------------------------------------------------
     254               0 : nsPrintEngine::nsPrintEngine() :
     255                 :   mIsCreatingPrintPreview(false),
     256                 :   mIsDoingPrinting(false),
     257                 :   mIsDoingPrintPreview(false),
     258                 :   mProgressDialogIsShown(false),
     259                 :   mScreenDPI(115.0f),
     260                 :   mPrt(nsnull),
     261                 :   mPagePrintTimer(nsnull),
     262                 :   mPageSeqFrame(nsnull),
     263                 :   mPrtPreview(nsnull),
     264                 :   mOldPrtPreview(nsnull),
     265               0 :   mDebugFile(nsnull)
     266                 : {
     267               0 : }
     268                 : 
     269                 : //-------------------------------------------------------
     270               0 : nsPrintEngine::~nsPrintEngine()
     271                 : {
     272               0 :   Destroy(); // for insurance
     273               0 : }
     274                 : 
     275                 : //-------------------------------------------------------
     276               0 : void nsPrintEngine::Destroy()
     277                 : {
     278               0 :   if (mPrt) {
     279               0 :     delete mPrt;
     280               0 :     mPrt = nsnull;
     281                 :   }
     282                 : 
     283                 : #ifdef NS_PRINT_PREVIEW
     284               0 :   if (mPrtPreview) {
     285               0 :     delete mPrtPreview;
     286               0 :     mPrtPreview = nsnull;
     287                 :   }
     288                 : 
     289                 :   // This is insruance
     290               0 :   if (mOldPrtPreview) {
     291               0 :     delete mOldPrtPreview;
     292               0 :     mOldPrtPreview = nsnull;
     293                 :   }
     294                 : 
     295                 : #endif
     296               0 :   mDocViewerPrint = nsnull;
     297               0 : }
     298                 : 
     299                 : //-------------------------------------------------------
     300               0 : void nsPrintEngine::DestroyPrintingData()
     301                 : {
     302               0 :   if (mPrt) {
     303               0 :     delete mPrt;
     304               0 :     mPrt = nsnull;
     305                 :   }
     306               0 : }
     307                 : 
     308                 : //---------------------------------------------------------------------------------
     309                 : //-- Section: Methods needed by the DocViewer
     310                 : //---------------------------------------------------------------------------------
     311                 : 
     312                 : //--------------------------------------------------------
     313               0 : nsresult nsPrintEngine::Initialize(nsIDocumentViewerPrint* aDocViewerPrint, 
     314                 :                                    nsIWeakReference*       aContainer,
     315                 :                                    nsIDocument*            aDocument,
     316                 :                                    float                   aScreenDPI,
     317                 :                                    FILE*                   aDebugFile)
     318                 : {
     319               0 :   NS_ENSURE_ARG_POINTER(aDocViewerPrint);
     320               0 :   NS_ENSURE_ARG_POINTER(aContainer);
     321               0 :   NS_ENSURE_ARG_POINTER(aDocument);
     322                 : 
     323               0 :   mDocViewerPrint = aDocViewerPrint;
     324               0 :   mContainer      = aContainer;
     325               0 :   mDocument       = aDocument;
     326               0 :   mScreenDPI      = aScreenDPI;
     327                 : 
     328               0 :   mDebugFile      = aDebugFile;      // ok to be NULL
     329                 : 
     330               0 :   return NS_OK;
     331                 : }
     332                 : 
     333                 : //-------------------------------------------------------
     334                 : bool
     335               0 : nsPrintEngine::CheckBeforeDestroy()
     336                 : {
     337               0 :   if (mPrt && mPrt->mPreparingForPrint) {
     338               0 :     mPrt->mDocWasToBeDestroyed = true;
     339               0 :     return true;
     340                 :   }
     341               0 :   return false;
     342                 : }
     343                 : 
     344                 : //-------------------------------------------------------
     345                 : nsresult
     346               0 : nsPrintEngine::Cancelled()
     347                 : {
     348               0 :   if (mPrt && mPrt->mPrintSettings) {
     349               0 :     return mPrt->mPrintSettings->SetIsCancelled(true);
     350                 :   }
     351               0 :   return NS_ERROR_FAILURE;
     352                 : }
     353                 : 
     354                 : //-------------------------------------------------------
     355                 : // Install our event listeners on the document to prevent 
     356                 : // some events from being processed while in PrintPreview 
     357                 : //
     358                 : // No return code - if this fails, there isn't much we can do
     359                 : void
     360               0 : nsPrintEngine::InstallPrintPreviewListener()
     361                 : {
     362               0 :   if (!mPrt->mPPEventListeners) {
     363               0 :     nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mContainer);
     364               0 :     nsCOMPtr<nsPIDOMWindow> win(do_GetInterface(docShell));
     365               0 :     if (win) {
     366               0 :       nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(win->GetFrameElementInternal()));
     367               0 :       mPrt->mPPEventListeners = new nsPrintPreviewListener(target);
     368               0 :       mPrt->mPPEventListeners->AddListeners();
     369                 :     }
     370                 :   }
     371               0 : }
     372                 : 
     373                 : //----------------------------------------------------------------------
     374                 : nsresult 
     375               0 : nsPrintEngine::GetSeqFrameAndCountPagesInternal(nsPrintObject*  aPO,
     376                 :                                                 nsIFrame*&    aSeqFrame,
     377                 :                                                 PRInt32&      aCount)
     378                 : {
     379               0 :   NS_ENSURE_ARG_POINTER(aPO);
     380                 : 
     381                 :   // Finds the SimplePageSequencer frame
     382               0 :   nsIPageSequenceFrame* seqFrame = aPO->mPresShell->GetPageSequenceFrame();
     383               0 :   if (seqFrame) {
     384               0 :     aSeqFrame = do_QueryFrame(seqFrame);
     385                 :   } else {
     386               0 :     aSeqFrame = nsnull;
     387                 :   }
     388               0 :   if (aSeqFrame == nsnull) return NS_ERROR_FAILURE;
     389                 : 
     390                 :   // first count the total number of pages
     391               0 :   aCount = 0;
     392               0 :   nsIFrame* pageFrame = aSeqFrame->GetFirstPrincipalChild();
     393               0 :   while (pageFrame != nsnull) {
     394               0 :     aCount++;
     395               0 :     pageFrame = pageFrame->GetNextSibling();
     396                 :   }
     397                 : 
     398               0 :   return NS_OK;
     399                 : 
     400                 : }
     401                 : 
     402                 : //-----------------------------------------------------------------
     403               0 : nsresult nsPrintEngine::GetSeqFrameAndCountPages(nsIFrame*& aSeqFrame, PRInt32& aCount)
     404                 : {
     405               0 :   NS_ASSERTION(mPrtPreview, "mPrtPreview can't be null!");
     406               0 :   return GetSeqFrameAndCountPagesInternal(mPrtPreview->mPrintObject, aSeqFrame, aCount);
     407                 : }
     408                 : //---------------------------------------------------------------------------------
     409                 : //-- Done: Methods needed by the DocViewer
     410                 : //---------------------------------------------------------------------------------
     411                 : 
     412                 : 
     413                 : //---------------------------------------------------------------------------------
     414                 : //-- Section: nsIWebBrowserPrint
     415                 : //---------------------------------------------------------------------------------
     416                 : 
     417                 : // Foward decl for Debug Helper Functions
     418                 : #ifdef EXTENDED_DEBUG_PRINTING
     419                 : static int RemoveFilesInDir(const char * aDir);
     420                 : static void GetDocTitleAndURL(nsPrintObject* aPO, char *& aDocStr, char *& aURLStr);
     421                 : static void DumpPrintObjectsTree(nsPrintObject * aPO, int aLevel, FILE* aFD);
     422                 : static void DumpPrintObjectsList(nsTArray<nsPrintObject*> * aDocList);
     423                 : static void RootFrameList(nsPresContext* aPresContext, FILE* out, PRInt32 aIndent);
     424                 : static void DumpViews(nsIDocShell* aDocShell, FILE* out);
     425                 : static void DumpLayoutData(char* aTitleStr, char* aURLStr,
     426                 :                            nsPresContext* aPresContext,
     427                 :                            nsDeviceContext * aDC, nsIFrame * aRootFrame,
     428                 :                            nsIDocShell * aDocShell, FILE* aFD);
     429                 : #endif
     430                 : 
     431                 : //--------------------------------------------------------------------------------
     432                 : 
     433                 : nsresult
     434               0 : nsPrintEngine::CommonPrint(bool                    aIsPrintPreview,
     435                 :                            nsIPrintSettings*       aPrintSettings,
     436                 :                            nsIWebProgressListener* aWebProgressListener,
     437                 :                            nsIDOMDocument* aDoc) {
     438                 :   nsresult rv = DoCommonPrint(aIsPrintPreview, aPrintSettings,
     439               0 :                               aWebProgressListener, aDoc);
     440               0 :   if (NS_FAILED(rv)) {
     441               0 :     if (aIsPrintPreview) {
     442               0 :       SetIsCreatingPrintPreview(false);
     443               0 :       SetIsPrintPreview(false);
     444                 :     } else {
     445               0 :       SetIsPrinting(false);
     446                 :     }
     447               0 :     if (mProgressDialogIsShown)
     448               0 :       CloseProgressDialog(aWebProgressListener);
     449               0 :     if (rv != NS_ERROR_ABORT && rv != NS_ERROR_OUT_OF_MEMORY)
     450               0 :       ShowPrintErrorDialog(rv, !aIsPrintPreview);
     451               0 :     delete mPrt;
     452               0 :     mPrt = nsnull;
     453                 :   }
     454                 : 
     455               0 :   return rv;
     456                 : }
     457                 : 
     458                 : nsresult
     459               0 : nsPrintEngine::DoCommonPrint(bool                    aIsPrintPreview,
     460                 :                              nsIPrintSettings*       aPrintSettings,
     461                 :                              nsIWebProgressListener* aWebProgressListener,
     462                 :                              nsIDOMDocument*         aDoc)
     463                 : {
     464                 :   nsresult rv;
     465                 : 
     466               0 :   if (aIsPrintPreview) {
     467                 :     // The WebProgressListener can be QI'ed to nsIPrintingPromptService
     468                 :     // then that means the progress dialog is already being shown.
     469               0 :     nsCOMPtr<nsIPrintingPromptService> pps(do_QueryInterface(aWebProgressListener));
     470               0 :     mProgressDialogIsShown = pps != nsnull;
     471                 : 
     472               0 :     if (mIsDoingPrintPreview) {
     473               0 :       mOldPrtPreview = mPrtPreview;
     474               0 :       mPrtPreview = nsnull;
     475                 :     }
     476                 :   } else {
     477               0 :     mProgressDialogIsShown = false;
     478                 :   }
     479                 : 
     480                 :   mPrt = new nsPrintData(aIsPrintPreview ? nsPrintData::eIsPrintPreview :
     481               0 :                                            nsPrintData::eIsPrinting);
     482               0 :   NS_ENSURE_TRUE(mPrt, NS_ERROR_OUT_OF_MEMORY);
     483                 : 
     484                 :   // if they don't pass in a PrintSettings, then get the Global PS
     485               0 :   mPrt->mPrintSettings = aPrintSettings;
     486               0 :   if (!mPrt->mPrintSettings) {
     487               0 :     rv = GetGlobalPrintSettings(getter_AddRefs(mPrt->mPrintSettings));
     488               0 :     NS_ENSURE_SUCCESS(rv, rv);
     489                 :   }
     490                 : 
     491               0 :   rv = CheckForPrinters(mPrt->mPrintSettings);
     492               0 :   NS_ENSURE_SUCCESS(rv, rv);
     493                 : 
     494               0 :   mPrt->mPrintSettings->SetIsCancelled(false);
     495               0 :   mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit);
     496                 : 
     497               0 :   if (aIsPrintPreview) {
     498               0 :     SetIsCreatingPrintPreview(true);
     499               0 :     SetIsPrintPreview(true);
     500                 :     nsCOMPtr<nsIMarkupDocumentViewer> viewer =
     501               0 :       do_QueryInterface(mDocViewerPrint);
     502               0 :     if (viewer) {
     503               0 :       viewer->SetTextZoom(1.0f);
     504               0 :       viewer->SetFullZoom(1.0f);
     505               0 :       viewer->SetMinFontSize(0);
     506                 :     }
     507                 :   }
     508                 : 
     509                 :   // Create a print session and let the print settings know about it.
     510                 :   // The print settings hold an nsWeakPtr to the session so it does not
     511                 :   // need to be cleared from the settings at the end of the job.
     512                 :   // XXX What lifetime does the printSession need to have?
     513               0 :   nsCOMPtr<nsIPrintSession> printSession;
     514               0 :   if (!aIsPrintPreview) {
     515               0 :     printSession = do_CreateInstance("@mozilla.org/gfx/printsession;1", &rv);
     516               0 :     NS_ENSURE_SUCCESS(rv, rv);
     517               0 :     mPrt->mPrintSettings->SetPrintSession(printSession);
     518                 :   }
     519                 : 
     520               0 :   if (aWebProgressListener != nsnull) {
     521               0 :     mPrt->mPrintProgressListeners.AppendObject(aWebProgressListener);
     522                 :   }
     523                 : 
     524                 :   // Get the currently focused window and cache it
     525                 :   // because the Print Dialog will "steal" focus and later when you try
     526                 :   // to get the currently focused windows it will be NULL
     527               0 :   mPrt->mCurrentFocusWin = FindFocusedDOMWindow();
     528                 : 
     529                 :   // Check to see if there is a "regular" selection
     530               0 :   bool isSelection = IsThereARangeSelection(mPrt->mCurrentFocusWin);
     531                 : 
     532                 :   // Get the docshell for this documentviewer
     533               0 :   nsCOMPtr<nsIDocShell> webContainer(do_QueryReferent(mContainer, &rv));
     534               0 :   NS_ENSURE_SUCCESS(rv, rv);
     535                 : 
     536               0 :   mPrt->mPrintObject = new nsPrintObject();
     537               0 :   NS_ENSURE_TRUE(mPrt->mPrintObject, NS_ERROR_OUT_OF_MEMORY);
     538               0 :   rv = mPrt->mPrintObject->Init(webContainer, aDoc, aIsPrintPreview);
     539               0 :   NS_ENSURE_SUCCESS(rv, rv);
     540                 : 
     541               0 :   NS_ENSURE_TRUE(mPrt->mPrintDocList.AppendElement(mPrt->mPrintObject),
     542                 :                  NS_ERROR_OUT_OF_MEMORY);
     543                 : 
     544               0 :   mPrt->mIsParentAFrameSet = IsParentAFrameSet(webContainer);
     545               0 :   mPrt->mPrintObject->mFrameType = mPrt->mIsParentAFrameSet ? eFrameSet : eDoc;
     546                 : 
     547                 :   // Build the "tree" of PrintObjects
     548                 :   nsCOMPtr<nsIDocShellTreeNode> parentAsNode =
     549               0 :     do_QueryInterface(mPrt->mPrintObject->mDocShell);
     550               0 :   BuildDocTree(parentAsNode, &mPrt->mPrintDocList, mPrt->mPrintObject);
     551                 : 
     552               0 :   if (!aIsPrintPreview) {
     553               0 :     SetIsPrinting(true);
     554                 :   }
     555                 : 
     556                 :   // XXX This isn't really correct...
     557               0 :   if (!mPrt->mPrintObject->mDocument ||
     558               0 :       !mPrt->mPrintObject->mDocument->GetRootElement())
     559               0 :     return NS_ERROR_GFX_PRINTER_STARTDOC;
     560                 : 
     561                 :   // Create the linkage from the sub-docs back to the content element
     562                 :   // in the parent document
     563               0 :   MapContentToWebShells(mPrt->mPrintObject, mPrt->mPrintObject);
     564                 : 
     565               0 :   mPrt->mIsIFrameSelected = IsThereAnIFrameSelected(webContainer, mPrt->mCurrentFocusWin, mPrt->mIsParentAFrameSet);
     566                 : 
     567                 :   // Setup print options for UI
     568               0 :   if (mPrt->mIsParentAFrameSet) {
     569               0 :     if (mPrt->mCurrentFocusWin) {
     570               0 :       mPrt->mPrintSettings->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAll);
     571                 :     } else {
     572               0 :       mPrt->mPrintSettings->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAsIsAndEach);
     573                 :     }
     574                 :   } else {
     575               0 :     mPrt->mPrintSettings->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableNone);
     576                 :   }
     577                 :   // Now determine how to set up the Frame print UI
     578               0 :   mPrt->mPrintSettings->SetPrintOptions(nsIPrintSettings::kEnableSelectionRB, isSelection || mPrt->mIsIFrameSelected);
     579                 : 
     580                 :   nsCOMPtr<nsIDeviceContextSpec> devspec
     581               0 :     (do_CreateInstance("@mozilla.org/gfx/devicecontextspec;1", &rv));
     582               0 :   NS_ENSURE_SUCCESS(rv, rv);
     583                 : 
     584               0 :   nsScriptSuppressor scriptSuppressor(this);
     585               0 :   if (!aIsPrintPreview) {
     586                 : #ifdef NS_DEBUG
     587               0 :     mPrt->mDebugFilePtr = mDebugFile;
     588                 : #endif
     589                 : 
     590               0 :     scriptSuppressor.Suppress();
     591                 :     bool printSilently;
     592               0 :     mPrt->mPrintSettings->GetPrintSilent(&printSilently);
     593                 : 
     594                 :     // Check prefs for a default setting as to whether we should print silently
     595                 :     printSilently =
     596               0 :       Preferences::GetBool("print.always_print_silent", printSilently);
     597                 : 
     598                 :     // Ask dialog to be Print Shown via the Plugable Printing Dialog Service
     599                 :     // This service is for the Print Dialog and the Print Progress Dialog
     600                 :     // If printing silently or you can't get the service continue on
     601               0 :     if (!printSilently) {
     602               0 :       nsCOMPtr<nsIPrintingPromptService> printPromptService(do_GetService(kPrintingPromptService));
     603               0 :       if (printPromptService) {
     604               0 :         nsIDOMWindow *domWin = mDocument->GetWindow(); 
     605               0 :         NS_ENSURE_TRUE(domWin, NS_ERROR_FAILURE);
     606                 : 
     607                 :         // Platforms not implementing a given dialog for the service may
     608                 :         // return NS_ERROR_NOT_IMPLEMENTED or an error code.
     609                 :         //
     610                 :         // NS_ERROR_NOT_IMPLEMENTED indicates they want default behavior
     611                 :         // Any other error code means we must bail out
     612                 :         //
     613               0 :         nsCOMPtr<nsIWebBrowserPrint> wbp(do_QueryInterface(mDocViewerPrint));
     614               0 :         rv = printPromptService->ShowPrintDialog(domWin, wbp,
     615               0 :                                                  mPrt->mPrintSettings);
     616                 :         //
     617                 :         // ShowPrintDialog triggers an event loop which means we can't assume
     618                 :         // that the state of this->{anything} matches the state we've checked
     619                 :         // above. Including that a given {thing} is non null.
     620                 : 
     621               0 :         if (NS_SUCCEEDED(rv)) {
     622                 :           // since we got the dialog and it worked then make sure we 
     623                 :           // are telling GFX we want to print silent
     624               0 :           printSilently = true;
     625                 : 
     626               0 :           if (mPrt && mPrt->mPrintSettings) {
     627                 :             // The user might have changed shrink-to-fit in the print dialog, so update our copy of its state
     628               0 :             mPrt->mPrintSettings->GetShrinkToFit(&mPrt->mShrinkToFit);
     629                 :           }
     630               0 :         } else if (rv == NS_ERROR_NOT_IMPLEMENTED) {
     631                 :           // This means the Dialog service was there,
     632                 :           // but they choose not to implement this dialog and
     633                 :           // are looking for default behavior from the toolkit
     634               0 :           rv = NS_OK;
     635                 :         }
     636                 :       } else {
     637               0 :         rv = NS_ERROR_GFX_NO_PRINTROMPTSERVICE;
     638                 :       }
     639                 :     } else {
     640                 :       // Call any code that requires a run of the event loop.
     641               0 :       rv = mPrt->mPrintSettings->SetupSilentPrinting();
     642                 :     }
     643                 :     // Check explicitly for abort because it's expected
     644               0 :     if (rv == NS_ERROR_ABORT) 
     645               0 :       return rv;
     646               0 :     NS_ENSURE_SUCCESS(rv, rv);
     647                 :   }
     648                 : 
     649               0 :   rv = devspec->Init(nsnull, mPrt->mPrintSettings, aIsPrintPreview);
     650               0 :   NS_ENSURE_SUCCESS(rv, rv);
     651                 : 
     652               0 :   mPrt->mPrintDC = new nsDeviceContext();
     653               0 :   rv = mPrt->mPrintDC->InitForPrinting(devspec);
     654               0 :   NS_ENSURE_SUCCESS(rv, rv);
     655                 : 
     656               0 :   if (aIsPrintPreview) {
     657               0 :     mPrt->mPrintSettings->SetPrintFrameType(nsIPrintSettings::kFramesAsIs);
     658                 : 
     659                 :     // override any UI that wants to PrintPreview any selection or page range
     660                 :     // we want to view every page in PrintPreview each time
     661               0 :     mPrt->mPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages);
     662                 :   } else {
     663                 :     // Always check and set the print settings first and then fall back
     664                 :     // onto the PrintService if there isn't a PrintSettings
     665                 :     //
     666                 :     // Posiible Usage values:
     667                 :     //   nsIPrintSettings::kUseInternalDefault
     668                 :     //   nsIPrintSettings::kUseSettingWhenPossible
     669                 :     //
     670                 :     // NOTE: The consts are the same for PrintSettings and PrintSettings
     671               0 :     PRInt16 printFrameTypeUsage = nsIPrintSettings::kUseSettingWhenPossible;
     672               0 :     mPrt->mPrintSettings->GetPrintFrameTypeUsage(&printFrameTypeUsage);
     673                 : 
     674                 :     // Ok, see if we are going to use our value and override the default
     675               0 :     if (printFrameTypeUsage == nsIPrintSettings::kUseSettingWhenPossible) {
     676                 :       // Get the Print Options/Settings PrintFrameType to see what is preferred
     677               0 :       PRInt16 printFrameType = nsIPrintSettings::kEachFrameSep;
     678               0 :       mPrt->mPrintSettings->GetPrintFrameType(&printFrameType);
     679                 : 
     680                 :       // Don't let anybody do something stupid like try to set it to
     681                 :       // kNoFrames when we are printing a FrameSet
     682               0 :       if (printFrameType == nsIPrintSettings::kNoFrames) {
     683               0 :         mPrt->mPrintFrameType = nsIPrintSettings::kEachFrameSep;
     684               0 :         mPrt->mPrintSettings->SetPrintFrameType(mPrt->mPrintFrameType);
     685                 :       } else {
     686                 :         // First find out from the PrinService what options are available
     687                 :         // to us for Printing FrameSets
     688                 :         PRInt16 howToEnableFrameUI;
     689               0 :         mPrt->mPrintSettings->GetHowToEnableFrameUI(&howToEnableFrameUI);
     690               0 :         if (howToEnableFrameUI != nsIPrintSettings::kFrameEnableNone) {
     691               0 :           switch (howToEnableFrameUI) {
     692                 :           case nsIPrintSettings::kFrameEnableAll:
     693               0 :             mPrt->mPrintFrameType = printFrameType;
     694               0 :             break;
     695                 : 
     696                 :           case nsIPrintSettings::kFrameEnableAsIsAndEach:
     697               0 :             if (printFrameType != nsIPrintSettings::kSelectedFrame) {
     698               0 :               mPrt->mPrintFrameType = printFrameType;
     699                 :             } else { // revert back to a good value
     700               0 :               mPrt->mPrintFrameType = nsIPrintSettings::kEachFrameSep;
     701                 :             }
     702               0 :             break;
     703                 :           } // switch
     704               0 :           mPrt->mPrintSettings->SetPrintFrameType(mPrt->mPrintFrameType);
     705                 :         }
     706                 :       }
     707                 :     } else {
     708               0 :       mPrt->mPrintSettings->GetPrintFrameType(&mPrt->mPrintFrameType);
     709                 :     }
     710                 :   }
     711                 : 
     712               0 :   if (aIsPrintPreview) {
     713               0 :     bool notifyOnInit = false;
     714               0 :     ShowPrintProgress(false, notifyOnInit);
     715                 : 
     716                 :     // Very important! Turn Off scripting
     717               0 :     TurnScriptingOn(false);
     718                 : 
     719               0 :     if (!notifyOnInit) {
     720               0 :       rv = FinishPrintPreview();
     721                 :     } else {
     722               0 :       rv = NS_OK;
     723                 :     }
     724               0 :     NS_ENSURE_SUCCESS(rv, rv);
     725                 :   } else {
     726                 :     bool doNotify;
     727               0 :     ShowPrintProgress(true, doNotify);
     728               0 :     if (!doNotify) {
     729                 :       // Print listener setup...
     730               0 :       mPrt->OnStartPrinting();
     731               0 :       rv = DocumentReadyForPrinting();
     732               0 :       NS_ENSURE_SUCCESS(rv, rv);
     733                 :     }
     734                 :   }
     735                 : 
     736                 :   // We will enable scripting later after printing has finished.
     737               0 :   scriptSuppressor.Disconnect();
     738                 : 
     739               0 :   return NS_OK;
     740                 : }
     741                 : 
     742                 : //---------------------------------------------------------------------------------
     743                 : NS_IMETHODIMP
     744               0 : nsPrintEngine::Print(nsIPrintSettings*       aPrintSettings,
     745                 :                      nsIWebProgressListener* aWebProgressListener)
     746                 : {
     747                 :   // If we have a print preview document, use that instead of the original
     748                 :   // mDocument. That way animated images etc. get printed using the same state
     749                 :   // as in print preview.
     750                 :   nsCOMPtr<nsIDOMDocument> doc =
     751                 :     do_QueryInterface(mPrtPreview && mPrtPreview->mPrintObject ?
     752               0 :                         mPrtPreview->mPrintObject->mDocument : mDocument);
     753                 : 
     754               0 :   return CommonPrint(false, aPrintSettings, aWebProgressListener, doc);
     755                 : }
     756                 : 
     757                 : NS_IMETHODIMP
     758               0 : nsPrintEngine::PrintPreview(nsIPrintSettings* aPrintSettings, 
     759                 :                                  nsIDOMWindow *aChildDOMWin, 
     760                 :                                  nsIWebProgressListener* aWebProgressListener)
     761                 : {
     762                 :   // Get the DocShell and see if it is busy
     763                 :   // (We can't Print Preview this document if it is still busy)
     764               0 :   nsCOMPtr<nsIDocShell> docShell(do_QueryReferent(mContainer));
     765               0 :   NS_ENSURE_STATE(docShell);
     766                 : 
     767               0 :   PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE;
     768               0 :   if (NS_FAILED(docShell->GetBusyFlags(&busyFlags)) ||
     769                 :       busyFlags != nsIDocShell::BUSY_FLAGS_NONE) {
     770               0 :     CloseProgressDialog(aWebProgressListener);
     771               0 :     ShowPrintErrorDialog(NS_ERROR_GFX_PRINTER_DOC_IS_BUSY_PP, false);
     772               0 :     return NS_ERROR_FAILURE;
     773                 :   }
     774                 : 
     775               0 :   NS_ENSURE_STATE(aChildDOMWin);
     776               0 :   nsCOMPtr<nsIDOMDocument> doc;
     777               0 :   aChildDOMWin->GetDocument(getter_AddRefs(doc));
     778               0 :   NS_ENSURE_STATE(doc);
     779                 : 
     780                 :   // Document is not busy -- go ahead with the Print Preview
     781               0 :   return CommonPrint(true, aPrintSettings, aWebProgressListener, doc);
     782                 : }
     783                 : 
     784                 : //----------------------------------------------------------------------------------
     785                 : /* readonly attribute boolean isFramesetDocument; */
     786                 : NS_IMETHODIMP
     787               0 : nsPrintEngine::GetIsFramesetDocument(bool *aIsFramesetDocument)
     788                 : {
     789               0 :   nsCOMPtr<nsIDocShell> webContainer(do_QueryReferent(mContainer));
     790               0 :   *aIsFramesetDocument = IsParentAFrameSet(webContainer);
     791               0 :   return NS_OK;
     792                 : }
     793                 : 
     794                 : //----------------------------------------------------------------------------------
     795                 : /* readonly attribute boolean isIFrameSelected; */
     796                 : NS_IMETHODIMP 
     797               0 : nsPrintEngine::GetIsIFrameSelected(bool *aIsIFrameSelected)
     798                 : {
     799               0 :   *aIsIFrameSelected = false;
     800                 : 
     801                 :   // Get the docshell for this documentviewer
     802               0 :   nsCOMPtr<nsIDocShell> webContainer(do_QueryReferent(mContainer));
     803                 :   // Get the currently focused window
     804               0 :   nsCOMPtr<nsIDOMWindow> currentFocusWin = FindFocusedDOMWindow();
     805               0 :   if (currentFocusWin && webContainer) {
     806                 :     // Get whether the doc contains a frameset 
     807                 :     // Also, check to see if the currently focus docshell
     808                 :     // is a child of this docshell
     809                 :     bool isParentFrameSet;
     810               0 :     *aIsIFrameSelected = IsThereAnIFrameSelected(webContainer, currentFocusWin, isParentFrameSet);
     811                 :   }
     812               0 :   return NS_OK;
     813                 : }
     814                 : 
     815                 : //----------------------------------------------------------------------------------
     816                 : /* readonly attribute boolean isRangeSelection; */
     817                 : NS_IMETHODIMP 
     818               0 : nsPrintEngine::GetIsRangeSelection(bool *aIsRangeSelection)
     819                 : {
     820                 :   // Get the currently focused window 
     821               0 :   nsCOMPtr<nsIDOMWindow> currentFocusWin = FindFocusedDOMWindow();
     822               0 :   *aIsRangeSelection = IsThereARangeSelection(currentFocusWin);
     823               0 :   return NS_OK;
     824                 : }
     825                 : 
     826                 : //----------------------------------------------------------------------------------
     827                 : /* readonly attribute boolean isFramesetFrameSelected; */
     828                 : NS_IMETHODIMP 
     829               0 : nsPrintEngine::GetIsFramesetFrameSelected(bool *aIsFramesetFrameSelected)
     830                 : {
     831                 :   // Get the currently focused window 
     832               0 :   nsCOMPtr<nsIDOMWindow> currentFocusWin = FindFocusedDOMWindow();
     833               0 :   *aIsFramesetFrameSelected = currentFocusWin != nsnull;
     834               0 :   return NS_OK;
     835                 : }
     836                 : 
     837                 : //----------------------------------------------------------------------------------
     838                 : /* readonly attribute long printPreviewNumPages; */
     839                 : NS_IMETHODIMP
     840               0 : nsPrintEngine::GetPrintPreviewNumPages(PRInt32 *aPrintPreviewNumPages)
     841                 : {
     842               0 :   NS_ENSURE_ARG_POINTER(aPrintPreviewNumPages);
     843                 : 
     844               0 :   nsIFrame* seqFrame  = nsnull;
     845               0 :   *aPrintPreviewNumPages = 0;
     846               0 :   if (!mPrtPreview ||
     847               0 :       NS_FAILED(GetSeqFrameAndCountPagesInternal(mPrtPreview->mPrintObject, seqFrame, *aPrintPreviewNumPages))) {
     848               0 :     return NS_ERROR_FAILURE;
     849                 :   }
     850               0 :   return NS_OK;
     851                 : }
     852                 : 
     853                 : //----------------------------------------------------------------------------------
     854                 : // Enumerate all the documents for their titles
     855                 : NS_IMETHODIMP
     856               0 : nsPrintEngine::EnumerateDocumentNames(PRUint32* aCount,
     857                 :                                       PRUnichar*** aResult)
     858                 : {
     859               0 :   NS_ENSURE_ARG(aCount);
     860               0 :   NS_ENSURE_ARG_POINTER(aResult);
     861                 : 
     862               0 :   *aCount = 0;
     863               0 :   *aResult = nsnull;
     864                 : 
     865               0 :   PRInt32     numDocs = mPrt->mPrintDocList.Length();
     866               0 :   PRUnichar** array   = (PRUnichar**) nsMemory::Alloc(numDocs * sizeof(PRUnichar*));
     867               0 :   if (!array)
     868               0 :     return NS_ERROR_OUT_OF_MEMORY;
     869                 : 
     870               0 :   for (PRInt32 i=0;i<numDocs;i++) {
     871               0 :     nsPrintObject* po = mPrt->mPrintDocList.ElementAt(i);
     872               0 :     NS_ASSERTION(po, "nsPrintObject can't be null!");
     873                 :     PRUnichar * docTitleStr;
     874                 :     PRUnichar * docURLStr;
     875               0 :     GetDocumentTitleAndURL(po->mDocument, &docTitleStr, &docURLStr);
     876                 : 
     877                 :     // Use the URL if the doc is empty
     878               0 :     if (!docTitleStr || !*docTitleStr) {
     879               0 :       if (docURLStr && *docURLStr) {
     880               0 :         nsMemory::Free(docTitleStr);
     881               0 :         docTitleStr = docURLStr;
     882                 :       } else {
     883               0 :         nsMemory::Free(docURLStr);
     884                 :       }
     885               0 :       docURLStr = nsnull;
     886               0 :       if (!docTitleStr || !*docTitleStr) {
     887               0 :         CleanupDocTitleArray(array, i);
     888               0 :         return NS_ERROR_OUT_OF_MEMORY;
     889                 :       }
     890                 :     }
     891               0 :     array[i] = docTitleStr;
     892               0 :     if (docURLStr) nsMemory::Free(docURLStr);
     893                 :   }
     894               0 :   *aCount  = numDocs;
     895               0 :   *aResult = array;
     896                 : 
     897               0 :   return NS_OK;
     898                 : 
     899                 : }
     900                 : 
     901                 : //----------------------------------------------------------------------------------
     902                 : /* readonly attribute nsIPrintSettings globalPrintSettings; */
     903                 : nsresult
     904               0 : nsPrintEngine::GetGlobalPrintSettings(nsIPrintSettings **aGlobalPrintSettings)
     905                 : {
     906               0 :   NS_ENSURE_ARG_POINTER(aGlobalPrintSettings);
     907                 : 
     908               0 :   nsresult rv = NS_ERROR_FAILURE;
     909                 :   nsCOMPtr<nsIPrintSettingsService> printSettingsService =
     910               0 :     do_GetService(sPrintSettingsServiceContractID, &rv);
     911               0 :   if (NS_SUCCEEDED(rv)) {
     912               0 :     rv = printSettingsService->GetGlobalPrintSettings(aGlobalPrintSettings);
     913                 :   }
     914               0 :   return rv;
     915                 : }
     916                 : 
     917                 : //----------------------------------------------------------------------------------
     918                 : /* readonly attribute boolean doingPrint; */
     919                 : NS_IMETHODIMP
     920               0 : nsPrintEngine::GetDoingPrint(bool *aDoingPrint)
     921                 : {
     922               0 :   NS_ENSURE_ARG_POINTER(aDoingPrint);
     923               0 :   *aDoingPrint = mIsDoingPrinting;
     924               0 :   return NS_OK;
     925                 : }
     926                 : 
     927                 : //----------------------------------------------------------------------------------
     928                 : /* readonly attribute boolean doingPrintPreview; */
     929                 : NS_IMETHODIMP
     930               0 : nsPrintEngine::GetDoingPrintPreview(bool *aDoingPrintPreview)
     931                 : {
     932               0 :   NS_ENSURE_ARG_POINTER(aDoingPrintPreview);
     933               0 :   *aDoingPrintPreview = mIsDoingPrintPreview;
     934               0 :   return NS_OK;
     935                 : }
     936                 : 
     937                 : //----------------------------------------------------------------------------------
     938                 : /* readonly attribute nsIPrintSettings currentPrintSettings; */
     939                 : NS_IMETHODIMP
     940               0 : nsPrintEngine::GetCurrentPrintSettings(nsIPrintSettings * *aCurrentPrintSettings)
     941                 : {
     942               0 :   NS_ENSURE_ARG_POINTER(aCurrentPrintSettings);
     943                 : 
     944               0 :   if (mPrt) {
     945               0 :     *aCurrentPrintSettings = mPrt->mPrintSettings;
     946                 : 
     947               0 :   } else if (mPrtPreview) {
     948               0 :     *aCurrentPrintSettings = mPrtPreview->mPrintSettings;
     949                 : 
     950                 :   } else {
     951               0 :     *aCurrentPrintSettings = nsnull;
     952                 :   }
     953               0 :   NS_IF_ADDREF(*aCurrentPrintSettings);
     954               0 :   return NS_OK;
     955                 : }
     956                 : 
     957                 : //-----------------------------------------------------------------
     958                 : //-- Section: Pre-Reflow Methods
     959                 : //-----------------------------------------------------------------
     960                 : 
     961                 : //---------------------------------------------------------------------
     962                 : // This method checks to see if there is at least one printer defined
     963                 : // and if so, it sets the first printer in the list as the default name
     964                 : // in the PrintSettings which is then used for Printer Preview
     965                 : nsresult
     966               0 : nsPrintEngine::CheckForPrinters(nsIPrintSettings* aPrintSettings)
     967                 : {
     968                 : #if defined(XP_MACOSX) || defined(ANDROID)
     969                 :   // Mac doesn't support retrieving a printer list.
     970                 :   return NS_OK;
     971                 : #else
     972               0 :   NS_ENSURE_ARG_POINTER(aPrintSettings);
     973                 : 
     974                 :   // See if aPrintSettings already has a printer
     975               0 :   nsXPIDLString printerName;
     976               0 :   nsresult rv = aPrintSettings->GetPrinterName(getter_Copies(printerName));
     977               0 :   if (NS_SUCCEEDED(rv) && !printerName.IsEmpty()) {
     978               0 :     return NS_OK;
     979                 :   }
     980                 : 
     981                 :   // aPrintSettings doesn't have a printer set. Try to fetch the default.
     982                 :   nsCOMPtr<nsIPrintSettingsService> printSettingsService =
     983               0 :     do_GetService(sPrintSettingsServiceContractID, &rv);
     984               0 :   NS_ENSURE_SUCCESS(rv, rv);
     985                 : 
     986               0 :   rv = printSettingsService->GetDefaultPrinterName(getter_Copies(printerName));
     987               0 :   if (NS_SUCCEEDED(rv) && !printerName.IsEmpty()) {
     988               0 :     rv = aPrintSettings->SetPrinterName(printerName.get());
     989                 :   }
     990               0 :   return rv;
     991                 : #endif
     992                 : }
     993                 : 
     994                 : //----------------------------------------------------------------------
     995                 : // Set up to use the "pluggable" Print Progress Dialog
     996                 : void
     997               0 : nsPrintEngine::ShowPrintProgress(bool aIsForPrinting, bool& aDoNotify)
     998                 : {
     999                 :   // default to not notifying, that if something here goes wrong
    1000                 :   // or we aren't going to show the progress dialog we can straight into 
    1001                 :   // reflowing the doc for printing.
    1002               0 :   aDoNotify = false;
    1003                 : 
    1004                 :   // Assume we can't do progress and then see if we can
    1005               0 :   bool showProgresssDialog = false;
    1006                 : 
    1007                 :   // if it is already being shown then don't bother to find out if it should be
    1008                 :   // so skip this and leave mShowProgressDialog set to FALSE
    1009               0 :   if (!mProgressDialogIsShown) {
    1010               0 :     showProgresssDialog = Preferences::GetBool("print.show_print_progress");
    1011                 :   }
    1012                 : 
    1013                 :   // Turning off the showing of Print Progress in Prefs overrides
    1014                 :   // whether the calling PS desire to have it on or off, so only check PS if 
    1015                 :   // prefs says it's ok to be on.
    1016               0 :   if (showProgresssDialog) {
    1017               0 :     mPrt->mPrintSettings->GetShowPrintProgress(&showProgresssDialog);
    1018                 :   }
    1019                 : 
    1020                 :   // Now open the service to get the progress dialog
    1021                 :   // If we don't get a service, that's ok, then just don't show progress
    1022               0 :   if (showProgresssDialog) {
    1023               0 :     nsCOMPtr<nsIPrintingPromptService> printPromptService(do_GetService(kPrintingPromptService));
    1024               0 :     if (printPromptService) {
    1025               0 :       nsPIDOMWindow *domWin = mDocument->GetWindow(); 
    1026               0 :       if (!domWin) return;
    1027                 : 
    1028                 :       nsCOMPtr<nsIDocShellTreeItem> docShellItem =
    1029               0 :         do_QueryInterface(domWin->GetDocShell());
    1030               0 :       if (!docShellItem) return;
    1031               0 :       nsCOMPtr<nsIDocShellTreeOwner> owner;
    1032               0 :       docShellItem->GetTreeOwner(getter_AddRefs(owner));
    1033               0 :       nsCOMPtr<nsIWebBrowserChrome> browserChrome = do_GetInterface(owner);
    1034               0 :       if (!browserChrome) return;
    1035               0 :       bool isModal = true;
    1036               0 :       browserChrome->IsWindowModal(&isModal);
    1037               0 :       if (isModal) {
    1038                 :         // Showing a print progress dialog when printing a modal window
    1039                 :         // isn't supported. See bug 301560.
    1040                 :         return;
    1041                 :       }
    1042                 : 
    1043               0 :       nsCOMPtr<nsIWebProgressListener> printProgressListener;
    1044                 : 
    1045               0 :       nsCOMPtr<nsIWebBrowserPrint> wbp(do_QueryInterface(mDocViewerPrint));
    1046               0 :       nsresult rv = printPromptService->ShowProgress(domWin, wbp, mPrt->mPrintSettings, this, aIsForPrinting,
    1047               0 :                                                      getter_AddRefs(printProgressListener), 
    1048               0 :                                                      getter_AddRefs(mPrt->mPrintProgressParams), 
    1049               0 :                                                      &aDoNotify);
    1050               0 :       if (NS_SUCCEEDED(rv)) {
    1051               0 :         if (printProgressListener && mPrt->mPrintProgressParams) {
    1052               0 :           mPrt->mPrintProgressListeners.AppendObject(printProgressListener);
    1053               0 :           SetDocAndURLIntoProgress(mPrt->mPrintObject, mPrt->mPrintProgressParams);
    1054                 :         }
    1055                 :       }
    1056                 :     }
    1057                 :   }
    1058                 : }
    1059                 : 
    1060                 : //---------------------------------------------------------------------
    1061                 : bool
    1062               0 : nsPrintEngine::IsThereARangeSelection(nsIDOMWindow* aDOMWin)
    1063                 : {
    1064               0 :   nsCOMPtr<nsIPresShell> presShell;
    1065               0 :   if (aDOMWin) {
    1066               0 :     nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(aDOMWin));
    1067               0 :     window->GetDocShell()->GetPresShell(getter_AddRefs(presShell));
    1068                 :   }
    1069                 : 
    1070               0 :   if (!presShell)
    1071               0 :     return false;
    1072                 : 
    1073                 :   // check here to see if there is a range selection
    1074                 :   // so we know whether to turn on the "Selection" radio button
    1075               0 :   nsCOMPtr<nsISelection> selection;
    1076               0 :   selection = presShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
    1077               0 :   if (selection) {
    1078                 :     PRInt32 count;
    1079               0 :     selection->GetRangeCount(&count);
    1080               0 :     if (count == 1) {
    1081               0 :       nsCOMPtr<nsIDOMRange> range;
    1082               0 :       if (NS_SUCCEEDED(selection->GetRangeAt(0, getter_AddRefs(range)))) {
    1083                 :         // check to make sure it isn't an insertion selection
    1084                 :         bool isCollapsed;
    1085               0 :         selection->GetIsCollapsed(&isCollapsed);
    1086               0 :         return !isCollapsed;
    1087                 :       }
    1088                 :     }
    1089               0 :     if (count > 1) return true;
    1090                 :   }
    1091               0 :   return false;
    1092                 : }
    1093                 : 
    1094                 : //---------------------------------------------------------------------
    1095                 : bool
    1096               0 : nsPrintEngine::IsParentAFrameSet(nsIDocShell * aParent)
    1097                 : {
    1098                 :   // See if the incoming doc is the root document
    1099               0 :   nsCOMPtr<nsIDocShellTreeItem> parentAsItem(do_QueryInterface(aParent));
    1100               0 :   if (!parentAsItem) return false;
    1101                 : 
    1102                 :   // When it is the top level document we need to check
    1103                 :   // to see if it contains a frameset. If it does, then
    1104                 :   // we only want to print the doc's children and not the document itself
    1105                 :   // For anything else we always print all the children and the document
    1106                 :   // for example, if the doc contains an IFRAME we eant to print the child
    1107                 :   // document (the IFRAME) and then the rest of the document.
    1108                 :   //
    1109                 :   // XXX we really need to search the frame tree, and not the content
    1110                 :   // but there is no way to distinguish between IFRAMEs and FRAMEs
    1111                 :   // with the GetFrameType call.
    1112                 :   // Bug 53459 has been files so we can eventually distinguish
    1113                 :   // between IFRAME frames and FRAME frames
    1114               0 :   bool isFrameSet = false;
    1115                 :   // only check to see if there is a frameset if there is
    1116                 :   // NO parent doc for this doc. meaning this parent is the root doc
    1117               0 :   nsCOMPtr<nsIDOMDocument> domDoc = do_GetInterface(aParent);
    1118               0 :   nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
    1119               0 :   if (doc) {
    1120               0 :     nsIContent *rootElement = doc->GetRootElement();
    1121               0 :     if (rootElement) {
    1122               0 :       isFrameSet = HasFramesetChild(rootElement);
    1123                 :     }
    1124                 :   }
    1125               0 :   return isFrameSet;
    1126                 : }
    1127                 : 
    1128                 : 
    1129                 : //---------------------------------------------------------------------
    1130                 : // Recursively build a list of sub documents to be printed
    1131                 : // that mirrors the document tree
    1132                 : void
    1133               0 : nsPrintEngine::BuildDocTree(nsIDocShellTreeNode *      aParentNode,
    1134                 :                             nsTArray<nsPrintObject*> * aDocList,
    1135                 :                             nsPrintObject *            aPO)
    1136                 : {
    1137               0 :   NS_ASSERTION(aParentNode, "Pointer is null!");
    1138               0 :   NS_ASSERTION(aDocList, "Pointer is null!");
    1139               0 :   NS_ASSERTION(aPO, "Pointer is null!");
    1140                 : 
    1141                 :   PRInt32 childWebshellCount;
    1142               0 :   aParentNode->GetChildCount(&childWebshellCount);
    1143               0 :   if (childWebshellCount > 0) {
    1144               0 :     for (PRInt32 i=0;i<childWebshellCount;i++) {
    1145               0 :       nsCOMPtr<nsIDocShellTreeItem> child;
    1146               0 :       aParentNode->GetChildAt(i, getter_AddRefs(child));
    1147               0 :       nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
    1148                 : 
    1149               0 :       nsCOMPtr<nsIContentViewer>  viewer;
    1150               0 :       childAsShell->GetContentViewer(getter_AddRefs(viewer));
    1151               0 :       if (viewer) {
    1152               0 :         nsCOMPtr<nsIContentViewerFile> viewerFile(do_QueryInterface(viewer));
    1153               0 :         if (viewerFile) {
    1154               0 :           nsCOMPtr<nsIDocShell> childDocShell(do_QueryInterface(child));
    1155               0 :           nsCOMPtr<nsIDocShellTreeNode> childNode(do_QueryInterface(child));
    1156               0 :           nsCOMPtr<nsIDOMDocument> doc = do_GetInterface(childDocShell);
    1157               0 :           nsPrintObject * po = new nsPrintObject();
    1158               0 :           po->mParent = aPO;
    1159               0 :           nsresult rv = po->Init(childDocShell, doc, aPO->mPrintPreview);
    1160               0 :           if (NS_FAILED(rv))
    1161               0 :             NS_NOTREACHED("Init failed?");
    1162               0 :           aPO->mKids.AppendElement(po);
    1163               0 :           aDocList->AppendElement(po);
    1164               0 :           BuildDocTree(childNode, aDocList, po);
    1165                 :         }
    1166                 :       }
    1167                 :     }
    1168                 :   }
    1169               0 : }
    1170                 : 
    1171                 : //---------------------------------------------------------------------
    1172                 : void
    1173               0 : nsPrintEngine::GetDocumentTitleAndURL(nsIDocument* aDoc,
    1174                 :                                       PRUnichar**  aTitle,
    1175                 :                                       PRUnichar**  aURLStr)
    1176                 : {
    1177               0 :   NS_ASSERTION(aDoc,      "Pointer is null!");
    1178               0 :   NS_ASSERTION(aTitle,    "Pointer is null!");
    1179               0 :   NS_ASSERTION(aURLStr,   "Pointer is null!");
    1180                 : 
    1181               0 :   *aTitle  = nsnull;
    1182               0 :   *aURLStr = nsnull;
    1183                 : 
    1184               0 :   nsAutoString docTitle;
    1185               0 :   nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(aDoc);
    1186               0 :   doc->GetTitle(docTitle);
    1187               0 :   if (!docTitle.IsEmpty()) {
    1188               0 :     *aTitle = ToNewUnicode(docTitle);
    1189                 :   }
    1190                 : 
    1191               0 :   nsIURI* url = aDoc->GetDocumentURI();
    1192               0 :   if (!url) return;
    1193                 : 
    1194               0 :   nsCOMPtr<nsIURIFixup> urifixup(do_GetService(NS_URIFIXUP_CONTRACTID));
    1195               0 :   if (!urifixup) return;
    1196                 : 
    1197               0 :   nsCOMPtr<nsIURI> exposableURI;
    1198               0 :   urifixup->CreateExposableURI(url, getter_AddRefs(exposableURI));
    1199                 : 
    1200               0 :   if (!exposableURI) return;
    1201                 : 
    1202               0 :   nsCAutoString urlCStr;
    1203               0 :   exposableURI->GetSpec(urlCStr);
    1204                 : 
    1205                 :   nsresult rv;
    1206                 :   nsCOMPtr<nsITextToSubURI> textToSubURI = 
    1207               0 :     do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
    1208               0 :   if (NS_FAILED(rv)) return;
    1209                 : 
    1210               0 :   nsAutoString unescapedURI;
    1211               0 :   rv = textToSubURI->UnEscapeURIForUI(NS_LITERAL_CSTRING("UTF-8"),
    1212               0 :                                       urlCStr, unescapedURI);
    1213               0 :   if (NS_FAILED(rv)) return;
    1214                 : 
    1215               0 :   *aURLStr = ToNewUnicode(unescapedURI);
    1216                 : }
    1217                 : 
    1218                 : //---------------------------------------------------------------------
    1219                 : // The walks the PO tree and for each document it walks the content
    1220                 : // tree looking for any content that are sub-shells
    1221                 : //
    1222                 : // It then sets the mContent pointer in the "found" PO object back to the
    1223                 : // the document that contained it.
    1224                 : void
    1225               0 : nsPrintEngine::MapContentToWebShells(nsPrintObject* aRootPO,
    1226                 :                                      nsPrintObject* aPO)
    1227                 : {
    1228               0 :   NS_ASSERTION(aRootPO, "Pointer is null!");
    1229               0 :   NS_ASSERTION(aPO, "Pointer is null!");
    1230                 : 
    1231                 :   // Recursively walk the content from the root item
    1232                 :   // XXX Would be faster to enumerate the subdocuments, although right now
    1233                 :   //     nsIDocument doesn't expose quite what would be needed.
    1234               0 :   nsCOMPtr<nsIContentViewer> viewer;
    1235               0 :   aPO->mDocShell->GetContentViewer(getter_AddRefs(viewer));
    1236               0 :   if (!viewer) return;
    1237                 : 
    1238               0 :   nsCOMPtr<nsIDOMDocument> domDoc;
    1239               0 :   viewer->GetDOMDocument(getter_AddRefs(domDoc));
    1240               0 :   nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
    1241               0 :   if (!doc) return;
    1242                 : 
    1243               0 :   Element* rootElement = doc->GetRootElement();
    1244               0 :   if (rootElement) {
    1245               0 :     MapContentForPO(aPO, rootElement);
    1246                 :   } else {
    1247               0 :     NS_WARNING("Null root content on (sub)document.");
    1248                 :   }
    1249                 : 
    1250                 :   // Continue recursively walking the chilren of this PO
    1251               0 :   for (PRUint32 i=0;i<aPO->mKids.Length();i++) {
    1252               0 :     MapContentToWebShells(aRootPO, aPO->mKids[i]);
    1253                 :   }
    1254                 : 
    1255                 : }
    1256                 : 
    1257                 : //-------------------------------------------------------
    1258                 : // A Frame's sub-doc may contain content or a FrameSet
    1259                 : // When it contains a FrameSet the mFrameType for the PrintObject
    1260                 : // is always set to an eFrame. Which is fine when printing "AsIs"
    1261                 : // but is incorrect when when printing "Each Frame Separately".
    1262                 : // When printing "Each Frame Separately" the Frame really acts like
    1263                 : // a frameset.
    1264                 : //
    1265                 : // This method walks the PO tree and checks to see if the PrintObject is
    1266                 : // an eFrame and has children that are eFrames (meaning it's a Frame containing a FrameSet)
    1267                 : // If so, then the mFrameType need to be changed to eFrameSet
    1268                 : //
    1269                 : // Also note: We only want to call this we are printing "Each Frame Separately"
    1270                 : //            when printing "As Is" leave it as an eFrame
    1271                 : void
    1272               0 : nsPrintEngine::CheckForChildFrameSets(nsPrintObject* aPO)
    1273                 : {
    1274               0 :   NS_ASSERTION(aPO, "Pointer is null!");
    1275                 : 
    1276                 :   // Continue recursively walking the chilren of this PO
    1277               0 :   bool hasChildFrames = false;
    1278               0 :   for (PRUint32 i=0;i<aPO->mKids.Length();i++) {
    1279               0 :     nsPrintObject* po = aPO->mKids[i];
    1280               0 :     if (po->mFrameType == eFrame) {
    1281               0 :       hasChildFrames = true;
    1282               0 :       CheckForChildFrameSets(po);
    1283                 :     }
    1284                 :   }
    1285                 : 
    1286               0 :   if (hasChildFrames && aPO->mFrameType == eFrame) {
    1287               0 :     aPO->mFrameType = eFrameSet;
    1288                 :   }
    1289               0 : }
    1290                 : 
    1291                 : //---------------------------------------------------------------------
    1292                 : // This method is key to the entire print mechanism.
    1293                 : //
    1294                 : // This "maps" or figures out which sub-doc represents a
    1295                 : // given Frame or IFrame in its parent sub-doc.
    1296                 : //
    1297                 : // So the Mcontent pointer in the child sub-doc points to the
    1298                 : // content in the its parent document, that caused it to be printed.
    1299                 : // This is used later to (after reflow) to find the absolute location
    1300                 : // of the sub-doc on its parent's page frame so it can be
    1301                 : // printed in the correct location.
    1302                 : //
    1303                 : // This method recursvely "walks" the content for a document finding
    1304                 : // all the Frames and IFrames, then sets the "mFrameType" data member
    1305                 : // which tells us what type of PO we have
    1306                 : void
    1307               0 : nsPrintEngine::MapContentForPO(nsPrintObject*   aPO,
    1308                 :                                nsIContent*      aContent)
    1309                 : {
    1310               0 :   NS_PRECONDITION(aPO && aContent, "Null argument");
    1311                 : 
    1312               0 :   nsIDocument* doc = aContent->GetDocument();
    1313                 : 
    1314               0 :   NS_ASSERTION(doc, "Content without a document from a document tree?");
    1315                 : 
    1316               0 :   nsIDocument* subDoc = doc->GetSubDocumentFor(aContent);
    1317                 : 
    1318               0 :   if (subDoc) {
    1319               0 :     nsCOMPtr<nsISupports> container = subDoc->GetContainer();
    1320               0 :     nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container));
    1321                 : 
    1322               0 :     if (docShell) {
    1323               0 :       nsPrintObject * po = nsnull;
    1324               0 :       PRInt32 cnt = aPO->mKids.Length();
    1325               0 :       for (PRInt32 i=0;i<cnt;i++) {
    1326               0 :         nsPrintObject* kid = aPO->mKids.ElementAt(i);
    1327               0 :         if (kid->mDocument == subDoc) {
    1328               0 :           po = kid;
    1329               0 :           break;
    1330                 :         }
    1331                 :       }
    1332                 : 
    1333                 :       // XXX If a subdocument has no onscreen presentation, there will be no PO
    1334                 :       //     This is even if there should be a print presentation
    1335               0 :       if (po) {
    1336                 : 
    1337               0 :         nsCOMPtr<nsIDOMHTMLFrameElement> frame(do_QueryInterface(aContent));
    1338                 :         // "frame" elements not in a frameset context should be treated
    1339                 :         // as iframes
    1340               0 :         if (frame && po->mParent->mFrameType == eFrameSet) {
    1341               0 :           po->mFrameType = eFrame;
    1342                 :         } else {
    1343                 :           // Assume something iframe-like, i.e. iframe, object, or embed
    1344               0 :           po->mFrameType = eIFrame;
    1345               0 :           SetPrintAsIs(po, true);
    1346               0 :           NS_ASSERTION(po->mParent, "The root must be a parent");
    1347               0 :           po->mParent->mPrintAsIs = true;
    1348                 :         }
    1349                 :       }
    1350                 :     }
    1351                 :   }
    1352                 : 
    1353                 :   // walk children content
    1354               0 :   for (nsIContent* child = aContent->GetFirstChild();
    1355                 :        child;
    1356               0 :        child = child->GetNextSibling()) {
    1357               0 :     MapContentForPO(aPO, child);
    1358                 :   }
    1359               0 : }
    1360                 : 
    1361                 : //---------------------------------------------------------------------
    1362                 : bool
    1363               0 : nsPrintEngine::IsThereAnIFrameSelected(nsIDocShell* aDocShell,
    1364                 :                                        nsIDOMWindow* aDOMWin,
    1365                 :                                        bool& aIsParentFrameSet)
    1366                 : {
    1367               0 :   aIsParentFrameSet = IsParentAFrameSet(aDocShell);
    1368               0 :   bool iFrameIsSelected = false;
    1369               0 :   if (mPrt && mPrt->mPrintObject) {
    1370               0 :     nsPrintObject* po = FindPrintObjectByDOMWin(mPrt->mPrintObject, aDOMWin);
    1371               0 :     iFrameIsSelected = po && po->mFrameType == eIFrame;
    1372                 :   } else {
    1373                 :     // First, check to see if we are a frameset
    1374               0 :     if (!aIsParentFrameSet) {
    1375                 :       // Check to see if there is a currenlt focused frame
    1376                 :       // if so, it means the selected frame is either the main docshell
    1377                 :       // or an IFRAME
    1378               0 :       if (aDOMWin) {
    1379                 :         // Get the main docshell's DOMWin to see if it matches 
    1380                 :         // the frame that is selected
    1381               0 :         nsCOMPtr<nsIDOMWindow> domWin = do_GetInterface(aDocShell);
    1382               0 :         if (domWin != aDOMWin) {
    1383               0 :           iFrameIsSelected = true; // we have a selected IFRAME
    1384                 :         }
    1385                 :       }
    1386                 :     }
    1387                 :   }
    1388                 : 
    1389               0 :   return iFrameIsSelected;
    1390                 : }
    1391                 : 
    1392                 : //---------------------------------------------------------------------
    1393                 : // Recursively sets all the PO items to be printed
    1394                 : // from the given item down into the tree
    1395                 : void
    1396               0 : nsPrintEngine::SetPrintPO(nsPrintObject* aPO, bool aPrint)
    1397                 : {
    1398               0 :   NS_ASSERTION(aPO, "Pointer is null!");
    1399                 : 
    1400                 :   // Set whether to print flag
    1401               0 :   aPO->mDontPrint = !aPrint;
    1402                 : 
    1403               0 :   for (PRUint32 i=0;i<aPO->mKids.Length();i++) {
    1404               0 :     SetPrintPO(aPO->mKids[i], aPrint);
    1405                 :   } 
    1406               0 : }
    1407                 : 
    1408                 : //---------------------------------------------------------------------
    1409                 : // This will first use a Title and/or URL from the PrintSettings
    1410                 : // if one isn't set then it uses the one from the document
    1411                 : // then if not title is there we will make sure we send something back
    1412                 : // depending on the situation.
    1413                 : void
    1414               0 : nsPrintEngine::GetDisplayTitleAndURL(nsPrintObject*    aPO,
    1415                 :                                      PRUnichar**       aTitle, 
    1416                 :                                      PRUnichar**       aURLStr,
    1417                 :                                      eDocTitleDefault  aDefType)
    1418                 : {
    1419               0 :   NS_ASSERTION(aPO, "Pointer is null!");
    1420               0 :   NS_ASSERTION(aTitle, "Pointer is null!");
    1421               0 :   NS_ASSERTION(aURLStr, "Pointer is null!");
    1422                 : 
    1423               0 :   *aTitle  = nsnull;
    1424               0 :   *aURLStr = nsnull;
    1425                 : 
    1426               0 :   if (!mPrt)
    1427               0 :     return;
    1428                 : 
    1429                 :   // First check to see if the PrintSettings has defined an alternate title
    1430                 :   // and use that if it did
    1431               0 :   PRUnichar * docTitleStrPS = nsnull;
    1432               0 :   PRUnichar * docURLStrPS   = nsnull;
    1433               0 :   if (mPrt->mPrintSettings) {
    1434               0 :     mPrt->mPrintSettings->GetTitle(&docTitleStrPS);
    1435               0 :     mPrt->mPrintSettings->GetDocURL(&docURLStrPS);
    1436                 : 
    1437               0 :     if (docTitleStrPS && *docTitleStrPS) {
    1438               0 :       *aTitle  = docTitleStrPS;
    1439                 :     }
    1440                 : 
    1441               0 :     if (docURLStrPS && *docURLStrPS) {
    1442               0 :       *aURLStr  = docURLStrPS;
    1443                 :     }
    1444                 : 
    1445                 :     // short circut
    1446               0 :     if (docTitleStrPS && docURLStrPS) {
    1447               0 :       return;
    1448                 :     }
    1449                 :   }
    1450                 : 
    1451                 :   PRUnichar* docTitle;
    1452                 :   PRUnichar* docUrl;
    1453               0 :   GetDocumentTitleAndURL(aPO->mDocument, &docTitle, &docUrl);
    1454                 : 
    1455               0 :   if (docUrl) {
    1456               0 :     if (!docURLStrPS)
    1457               0 :       *aURLStr = docUrl;
    1458                 :     else
    1459               0 :       nsMemory::Free(docUrl);
    1460                 :   }
    1461                 : 
    1462               0 :   if (docTitle) {
    1463               0 :     if (!docTitleStrPS)
    1464               0 :       *aTitle = docTitle;
    1465                 :     else
    1466               0 :       nsMemory::Free(docTitle);
    1467               0 :   } else if (!docTitleStrPS) {
    1468               0 :     switch (aDefType) {
    1469               0 :       case eDocTitleDefBlank: *aTitle = ToNewUnicode(EmptyString());
    1470               0 :         break;
    1471                 : 
    1472                 :       case eDocTitleDefURLDoc:
    1473               0 :         if (*aURLStr) {
    1474               0 :           *aTitle = NS_strdup(*aURLStr);
    1475               0 :         } else if (mPrt->mBrandName) {
    1476               0 :           *aTitle = NS_strdup(mPrt->mBrandName);
    1477                 :         }
    1478               0 :         break;
    1479                 :       case eDocTitleDefNone:
    1480                 :         // *aTitle defaults to nsnull
    1481               0 :         break;
    1482                 :     }
    1483                 :   }
    1484                 : }
    1485                 : 
    1486                 : //---------------------------------------------------------------------
    1487               0 : nsresult nsPrintEngine::DocumentReadyForPrinting()
    1488                 : {
    1489               0 :   if (mPrt->mPrintFrameType == nsIPrintSettings::kEachFrameSep) {
    1490               0 :     CheckForChildFrameSets(mPrt->mPrintObject);
    1491                 :   }
    1492                 : 
    1493                 :   //
    1494                 :   // Send the document to the printer...
    1495                 :   //
    1496               0 :   nsresult rv = SetupToPrintContent();
    1497               0 :   if (NS_FAILED(rv)) {
    1498                 :     // The print job was canceled or there was a problem
    1499                 :     // So remove all other documents from the print list
    1500               0 :     DonePrintingPages(nsnull, rv);
    1501                 :   }
    1502               0 :   return rv;
    1503                 : }
    1504                 : 
    1505                 : /** ---------------------------------------------------
    1506                 :  *  Cleans up when an error occurred
    1507                 :  */
    1508               0 : nsresult nsPrintEngine::CleanupOnFailure(nsresult aResult, bool aIsPrinting)
    1509                 : {
    1510               0 :   PR_PL(("****  Failed %s - rv 0x%X", aIsPrinting?"Printing":"Print Preview", aResult));
    1511                 : 
    1512                 :   /* cleanup... */
    1513               0 :   if (mPagePrintTimer) {
    1514               0 :     mPagePrintTimer->Stop();
    1515               0 :     NS_RELEASE(mPagePrintTimer);
    1516                 :   }
    1517                 :   
    1518               0 :   if (aIsPrinting) {
    1519               0 :     SetIsPrinting(false);
    1520                 :   } else {
    1521               0 :     SetIsPrintPreview(false);
    1522               0 :     SetIsCreatingPrintPreview(false);
    1523                 :   }
    1524                 : 
    1525                 :   /* cleanup done, let's fire-up an error dialog to notify the user
    1526                 :    * what went wrong... 
    1527                 :    * 
    1528                 :    * When rv == NS_ERROR_ABORT, it means we want out of the 
    1529                 :    * print job without displaying any error messages
    1530                 :    */
    1531               0 :   if (aResult != NS_ERROR_ABORT) {
    1532               0 :     ShowPrintErrorDialog(aResult, aIsPrinting);
    1533                 :   }
    1534                 : 
    1535               0 :   FirePrintCompletionEvent();
    1536                 : 
    1537               0 :   return aResult;
    1538                 : 
    1539                 : }
    1540                 : 
    1541                 : //---------------------------------------------------------------------
    1542                 : void
    1543               0 : nsPrintEngine::ShowPrintErrorDialog(nsresult aPrintError, bool aIsPrinting)
    1544                 : {
    1545                 : 
    1546               0 :   PR_PL(("nsPrintEngine::ShowPrintErrorDialog(nsresult aPrintError=%lx, bool aIsPrinting=%d)\n", (long)aPrintError, (int)aIsPrinting));
    1547                 : 
    1548               0 :   nsCAutoString stringName;
    1549                 : 
    1550               0 :   switch(aPrintError)
    1551                 :   {
    1552                 : #define NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(nserr) case nserr: stringName.AssignLiteral(#nserr); break;
    1553               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_CMD_NOT_FOUND)
    1554               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_CMD_FAILURE)
    1555               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE)
    1556               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND)
    1557               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_ACCESS_DENIED)
    1558               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_INVALID_ATTRIBUTE)
    1559               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_PRINTER_NOT_READY)
    1560               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_OUT_OF_PAPER)
    1561               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_PRINTER_IO_ERROR)
    1562               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE)
    1563               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_FILE_IO_ERROR)
    1564               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_PRINTPREVIEW)
    1565               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_UNEXPECTED)
    1566               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_OUT_OF_MEMORY)
    1567               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_NOT_IMPLEMENTED)
    1568               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_NOT_AVAILABLE)
    1569               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_ABORT)
    1570               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_STARTDOC)
    1571               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_ENDDOC)
    1572               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_STARTPAGE)
    1573               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_ENDPAGE)
    1574               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_PRINT_WHILE_PREVIEW)
    1575               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_PAPER_SIZE_NOT_SUPPORTED)
    1576               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_ORIENTATION_NOT_SUPPORTED)
    1577               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_COLORSPACE_NOT_SUPPORTED)
    1578               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_TOO_MANY_COPIES)
    1579               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_DRIVER_CONFIGURATION_ERROR)
    1580               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_DOC_IS_BUSY_PP)
    1581               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_DOC_WAS_DESTORYED)
    1582               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_NO_PRINTDIALOG_IN_TOOLKIT)
    1583               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_NO_PRINTROMPTSERVICE)
    1584               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_NO_XUL)   // Temporary code for Bug 136185 / bug 240490
    1585               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_PLEX_NOT_SUPPORTED)
    1586               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_DOC_IS_BUSY)
    1587               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED)
    1588               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_COULD_NOT_LOAD_PRINT_MODULE)
    1589               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_GFX_PRINTER_RESOLUTION_NOT_SUPPORTED)
    1590                 : 
    1591                 :     default:
    1592               0 :       NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG(NS_ERROR_FAILURE)
    1593                 : #undef NS_ERROR_TO_LOCALIZED_PRINT_ERROR_MSG
    1594                 :   }
    1595                 : 
    1596               0 :   PR_PL(("ShowPrintErrorDialog:  stringName='%s'\n", stringName.get()));
    1597                 : 
    1598               0 :   nsXPIDLString msg, title;
    1599                 :   nsresult rv =
    1600                 :     nsContentUtils::GetLocalizedString(nsContentUtils::ePRINTING_PROPERTIES,
    1601               0 :                                        stringName.get(), msg);
    1602               0 :   if (NS_FAILED(rv)) {
    1603               0 :     PR_PL(("GetLocalizedString failed\n"));
    1604                 :     return;
    1605                 :   }
    1606                 : 
    1607                 :   rv = nsContentUtils::GetLocalizedString(nsContentUtils::ePRINTING_PROPERTIES,
    1608                 :       aIsPrinting ? "print_error_dialog_title"
    1609                 :                   : "printpreview_error_dialog_title",
    1610               0 :       title);
    1611                 : 
    1612               0 :   nsCOMPtr<nsIWindowWatcher> wwatch = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
    1613               0 :   if (NS_FAILED(rv)) {
    1614               0 :     PR_PL(("ShowPrintErrorDialog(): wwatch==nsnull\n"));
    1615                 :     return;
    1616                 :   }
    1617                 : 
    1618               0 :   nsCOMPtr<nsIDOMWindow> active;
    1619               0 :   wwatch->GetActiveWindow(getter_AddRefs(active));
    1620                 : 
    1621               0 :   nsCOMPtr<nsIPrompt> dialog;
    1622                 :   /* |GetNewPrompter| allows that |active| is |nsnull| 
    1623                 :    * (see bug 234982 ("nsPrintEngine::ShowPrintErrorDialog() fails in many cases")) */
    1624               0 :   wwatch->GetNewPrompter(active, getter_AddRefs(dialog));
    1625               0 :   if (!dialog) {
    1626               0 :     PR_PL(("ShowPrintErrorDialog(): dialog==nsnull\n"));
    1627                 :     return;
    1628                 :   }
    1629                 : 
    1630               0 :   dialog->Alert(title.get(), msg.get());
    1631               0 :   PR_PL(("ShowPrintErrorDialog(): alert displayed successfully.\n"));
    1632                 : }
    1633                 : 
    1634                 : //-----------------------------------------------------------------
    1635                 : //-- Section: Reflow Methods
    1636                 : //-----------------------------------------------------------------
    1637                 : 
    1638                 : //-------------------------------------------------------
    1639                 : nsresult
    1640               0 : nsPrintEngine::SetupToPrintContent()
    1641                 : {
    1642                 :   // In this step we figure out which documents should be printed
    1643                 :   // i.e. if we are printing the selection then only enable that nsPrintObject
    1644                 :   // for printing
    1645               0 :   if (NS_FAILED(EnablePOsForPrinting())) {
    1646               0 :     return NS_ERROR_FAILURE;
    1647                 :   }
    1648                 :   DUMP_DOC_LIST("\nAfter Enable------------------------------------------");
    1649                 : 
    1650                 :   // This is an Optimization
    1651                 :   // If we are in PP then we already know all the shrinkage information
    1652                 :   // so just transfer it to the PrintData and we will skip the extra shrinkage reflow
    1653                 :   //
    1654                 :   // doSetPixelScale tells Reflow whether to set the shrinkage value into the DC
    1655                 :   // The first time we do not want to do this, the second time through we do
    1656               0 :   bool doSetPixelScale = false;
    1657               0 :   bool ppIsShrinkToFit = mPrtPreview && mPrtPreview->mShrinkToFit;
    1658               0 :   if (ppIsShrinkToFit) {
    1659               0 :     mPrt->mShrinkRatio = mPrtPreview->mShrinkRatio;
    1660               0 :     doSetPixelScale = true;
    1661                 :   }
    1662                 : 
    1663                 :   // Here we reflow all the PrintObjects
    1664               0 :   nsresult rv = ReflowDocList(mPrt->mPrintObject, doSetPixelScale);
    1665               0 :   if (NS_FAILED(rv)) {
    1666               0 :     return NS_ERROR_FAILURE;
    1667                 :   }
    1668                 : 
    1669                 :   // Here is where we do the extra reflow for shrinking the content
    1670                 :   // But skip this step if we are in PrintPreview
    1671               0 :   if (mPrt->mShrinkToFit && !ppIsShrinkToFit) {
    1672                 :     // Now look for the PO that has the smallest percent for shrink to fit
    1673               0 :     if (mPrt->mPrintDocList.Length() > 1 && mPrt->mPrintObject->mFrameType == eFrameSet) {
    1674               0 :       nsPrintObject* smallestPO = FindSmallestSTF();
    1675               0 :       NS_ASSERTION(smallestPO, "There must always be an XMost PO!");
    1676               0 :       if (smallestPO) {
    1677                 :         // Calc the shrinkage based on the entire content area
    1678               0 :         mPrt->mShrinkRatio = smallestPO->mShrinkRatio;
    1679                 :       }
    1680                 :     } else {
    1681                 :       // Single document so use the Shrink as calculated for the PO
    1682               0 :       mPrt->mShrinkRatio = mPrt->mPrintObject->mShrinkRatio;
    1683                 :     }
    1684                 : 
    1685                 :     // Only Shrink if we are smaller
    1686               0 :     if (mPrt->mShrinkRatio < 0.998f) {
    1687               0 :       for (PRUint32 i=0;i<mPrt->mPrintDocList.Length();i++) {
    1688               0 :         nsPrintObject* po = mPrt->mPrintDocList.ElementAt(i);
    1689               0 :         NS_ASSERTION(po, "nsPrintObject can't be null!");
    1690                 :         // Wipe out the presentation before we reflow
    1691               0 :         po->DestroyPresentation();
    1692                 :       }
    1693                 : 
    1694                 : #if (defined(XP_WIN) || defined(XP_OS2)) && defined(EXTENDED_DEBUG_PRINTING)
    1695                 :       // We need to clear all the output files here
    1696                 :       // because they will be re-created with second reflow of the docs
    1697                 :       if (kPrintingLogMod && kPrintingLogMod->level == DUMP_LAYOUT_LEVEL) {
    1698                 :         RemoveFilesInDir(".\\");
    1699                 :         gDumpFileNameCnt   = 0;
    1700                 :         gDumpLOFileNameCnt = 0;
    1701                 :       }
    1702                 : #endif
    1703                 : 
    1704                 :       // Here we reflow all the PrintObjects a second time
    1705                 :       // this time using the shrinkage values
    1706                 :       // The last param here tells reflow to NOT calc the shrinkage values
    1707               0 :       if (NS_FAILED(ReflowDocList(mPrt->mPrintObject, true))) {
    1708               0 :         return NS_ERROR_FAILURE;
    1709                 :       }
    1710                 :     }
    1711                 : 
    1712                 : #ifdef PR_LOGGING
    1713                 :     {
    1714               0 :       float calcRatio = 0.0f;
    1715               0 :       if (mPrt->mPrintDocList.Length() > 1 && mPrt->mPrintObject->mFrameType == eFrameSet) {
    1716               0 :         nsPrintObject* smallestPO = FindSmallestSTF();
    1717               0 :         NS_ASSERTION(smallestPO, "There must always be an XMost PO!");
    1718               0 :         if (smallestPO) {
    1719                 :           // Calc the shrinkage based on the entire content area
    1720               0 :           calcRatio = smallestPO->mShrinkRatio;
    1721                 :         }
    1722                 :       } else {
    1723                 :         // Single document so use the Shrink as calculated for the PO
    1724               0 :         calcRatio = mPrt->mPrintObject->mShrinkRatio;
    1725                 :       }
    1726               0 :       PR_PL(("**************************************************************************\n"));
    1727               0 :       PR_PL(("STF Ratio is: %8.5f Effective Ratio: %8.5f Diff: %8.5f\n", mPrt->mShrinkRatio, calcRatio,  mPrt->mShrinkRatio-calcRatio));
    1728               0 :       PR_PL(("**************************************************************************\n"));
    1729                 :     }
    1730                 : #endif
    1731                 :   }
    1732                 : 
    1733                 :   DUMP_DOC_LIST(("\nAfter Reflow------------------------------------------"));
    1734               0 :   PR_PL(("\n"));
    1735               0 :   PR_PL(("-------------------------------------------------------\n"));
    1736               0 :   PR_PL(("\n"));
    1737                 : 
    1738               0 :   CalcNumPrintablePages(mPrt->mNumPrintablePages);
    1739                 : 
    1740               0 :   PR_PL(("--- Printing %d pages\n", mPrt->mNumPrintablePages));
    1741                 :   DUMP_DOC_TREELAYOUT;
    1742                 : 
    1743                 :   // Print listener setup...
    1744               0 :   if (mPrt != nsnull) {
    1745               0 :     mPrt->OnStartPrinting();    
    1746                 :   }
    1747                 : 
    1748               0 :   PRUnichar* fileName = nsnull;
    1749                 :   // check to see if we are printing to a file
    1750               0 :   bool isPrintToFile = false;
    1751               0 :   mPrt->mPrintSettings->GetPrintToFile(&isPrintToFile);
    1752               0 :   if (isPrintToFile) {
    1753                 :   // On some platforms The BeginDocument needs to know the name of the file
    1754                 :   // and it uses the PrintService to get it, so we need to set it into the PrintService here
    1755               0 :     mPrt->mPrintSettings->GetToFileName(&fileName);
    1756                 :   }
    1757                 : 
    1758                 :   PRUnichar * docTitleStr;
    1759                 :   PRUnichar * docURLStr;
    1760               0 :   GetDisplayTitleAndURL(mPrt->mPrintObject, &docTitleStr, &docURLStr, eDocTitleDefURLDoc); 
    1761                 : 
    1762               0 :   PRInt32 startPage = 1;
    1763               0 :   PRInt32 endPage   = mPrt->mNumPrintablePages;
    1764                 : 
    1765               0 :   PRInt16 printRangeType = nsIPrintSettings::kRangeAllPages;
    1766               0 :   mPrt->mPrintSettings->GetPrintRange(&printRangeType);
    1767               0 :   if (printRangeType == nsIPrintSettings::kRangeSpecifiedPageRange) {
    1768               0 :     mPrt->mPrintSettings->GetStartPageRange(&startPage);
    1769               0 :     mPrt->mPrintSettings->GetEndPageRange(&endPage);
    1770               0 :     if (endPage > mPrt->mNumPrintablePages) {
    1771               0 :       endPage = mPrt->mNumPrintablePages;
    1772                 :     }
    1773                 :   }
    1774                 : 
    1775               0 :   rv = NS_OK;
    1776                 :   // BeginDocument may pass back a FAILURE code
    1777                 :   // i.e. On Windows, if you are printing to a file and hit "Cancel" 
    1778                 :   //      to the "File Name" dialog, this comes back as an error
    1779                 :   // Don't start printing when regression test are executed  
    1780               0 :   if (!mPrt->mDebugFilePtr && mIsDoingPrinting) {
    1781               0 :     rv = mPrt->mPrintDC->BeginDocument(docTitleStr, fileName, startPage, endPage);
    1782                 :   } 
    1783                 : 
    1784               0 :   if (mIsCreatingPrintPreview) {
    1785                 :     // Print Preview -- Pass ownership of docTitleStr and docURLStr
    1786                 :     // to the pageSequenceFrame, to be displayed in the header
    1787               0 :     nsIPageSequenceFrame *seqFrame = mPrt->mPrintObject->mPresShell->GetPageSequenceFrame();
    1788               0 :     if (seqFrame) {
    1789                 :       seqFrame->StartPrint(mPrt->mPrintObject->mPresContext, 
    1790               0 :                            mPrt->mPrintSettings, docTitleStr, docURLStr);
    1791               0 :       docTitleStr = nsnull;
    1792               0 :       docURLStr = nsnull;
    1793                 :     }
    1794                 :   }
    1795               0 :   if (docTitleStr) nsMemory::Free(docTitleStr);
    1796               0 :   if (docURLStr) nsMemory::Free(docURLStr);
    1797                 : 
    1798               0 :   PR_PL(("****************** Begin Document ************************\n"));
    1799                 : 
    1800               0 :   NS_ENSURE_SUCCESS(rv, rv);
    1801                 : 
    1802                 :   // This will print the docshell document
    1803                 :   // when it completes asynchronously in the DonePrintingPages method
    1804                 :   // it will check to see if there are more docshells to be printed and
    1805                 :   // then PrintDocContent will be called again.
    1806                 : 
    1807               0 :   if (mIsDoingPrinting) {
    1808               0 :     PrintDocContent(mPrt->mPrintObject, rv); // ignore return value
    1809                 :   }
    1810                 : 
    1811               0 :   return rv;
    1812                 : }
    1813                 : 
    1814                 : //-------------------------------------------------------
    1815                 : // Recursively reflow each sub-doc and then calc
    1816                 : // all the frame locations of the sub-docs
    1817                 : nsresult
    1818               0 : nsPrintEngine::ReflowDocList(nsPrintObject* aPO, bool aSetPixelScale)
    1819                 : {
    1820               0 :   NS_ENSURE_ARG_POINTER(aPO);
    1821                 : 
    1822                 :   // Check to see if the subdocument's element has been hidden by the parent document
    1823               0 :   if (aPO->mParent && aPO->mParent->mPresShell) {
    1824               0 :     nsIFrame* frame = aPO->mContent ? aPO->mContent->GetPrimaryFrame() : nsnull;
    1825               0 :     if (!frame || !frame->GetStyleVisibility()->IsVisible()) {
    1826               0 :       aPO->mDontPrint = true;
    1827               0 :       aPO->mInvisible = true;
    1828               0 :       return NS_OK;
    1829                 :     }
    1830                 :   }
    1831                 : 
    1832                 :   // Here is where we set the shrinkage value into the DC
    1833                 :   // and this is what actually makes it shrink
    1834               0 :   if (aSetPixelScale && aPO->mFrameType != eIFrame) {
    1835                 :     float ratio;
    1836               0 :     if (mPrt->mPrintFrameType == nsIPrintSettings::kFramesAsIs || mPrt->mPrintFrameType == nsIPrintSettings::kNoFrames) {
    1837               0 :       ratio = mPrt->mShrinkRatio - 0.005f; // round down
    1838                 :     } else {
    1839               0 :       ratio = aPO->mShrinkRatio - 0.005f; // round down
    1840                 :     }
    1841               0 :     aPO->mZoomRatio = ratio;
    1842               0 :   } else if (!mPrt->mShrinkToFit) {
    1843                 :     double scaling;
    1844               0 :     mPrt->mPrintSettings->GetScaling(&scaling);
    1845               0 :     aPO->mZoomRatio = float(scaling);
    1846                 :   }
    1847                 : 
    1848                 :   nsresult rv;
    1849                 :   // Reflow the PO
    1850               0 :   rv = ReflowPrintObject(aPO);
    1851               0 :   NS_ENSURE_SUCCESS(rv, rv);
    1852                 : 
    1853               0 :   PRInt32 cnt = aPO->mKids.Length();
    1854               0 :   for (PRInt32 i=0;i<cnt;i++) {
    1855               0 :     rv = ReflowDocList(aPO->mKids[i], aSetPixelScale);
    1856               0 :     NS_ENSURE_SUCCESS(rv, rv);
    1857                 :   }
    1858               0 :   return NS_OK;
    1859                 : }
    1860                 : 
    1861                 : //-------------------------------------------------------
    1862                 : // Reflow a nsPrintObject
    1863                 : nsresult
    1864               0 : nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO)
    1865                 : {
    1866               0 :   NS_ASSERTION(aPO, "Pointer is null!");
    1867               0 :   if (!aPO) return NS_ERROR_FAILURE;
    1868                 : 
    1869               0 :   nsSize adjSize;
    1870                 :   bool documentIsTopLevel;
    1871               0 :   if (!aPO->IsPrintable())
    1872               0 :     return NS_OK;
    1873                 : 
    1874               0 :   bool canCreateScrollbars = true;
    1875               0 :   nsIView* parentView = nsnull;
    1876                 : 
    1877               0 :   if (aPO->mParent && aPO->mParent->IsPrintable()) {
    1878               0 :     nsIFrame* frame = aPO->mContent ? aPO->mContent->GetPrimaryFrame() : nsnull;
    1879                 :     // Without a frame, this document can't be displayed; therefore, there is no
    1880                 :     // point to reflowing it
    1881               0 :     if (!frame) {
    1882               0 :       SetPrintPO(aPO, false);
    1883               0 :       return NS_OK;
    1884                 :     }
    1885                 : 
    1886                 :     //XXX If printing supported printing document hierarchies with non-constant
    1887                 :     // zoom this would be wrong as we use the same mPrt->mPrintDC for all
    1888                 :     // subdocuments.
    1889               0 :     adjSize = frame->GetContentRect().Size();
    1890               0 :     documentIsTopLevel = false;
    1891                 :     // presshell exists because parent is printable
    1892                 : 
    1893                 :     // the top nsPrintObject's widget will always have scrollbars
    1894               0 :     if (frame && frame->GetType() == nsGkAtoms::subDocumentFrame) {
    1895               0 :       nsIView* view = frame->GetView();
    1896               0 :       NS_ENSURE_TRUE(view, NS_ERROR_FAILURE);
    1897               0 :       view = view->GetFirstChild();
    1898               0 :       NS_ENSURE_TRUE(view, NS_ERROR_FAILURE);
    1899               0 :       parentView = view;
    1900               0 :       canCreateScrollbars = false;
    1901                 :     }
    1902                 :   } else {
    1903                 :     nscoord pageWidth, pageHeight;
    1904               0 :     mPrt->mPrintDC->GetDeviceSurfaceDimensions(pageWidth, pageHeight);
    1905               0 :     adjSize = nsSize(pageWidth, pageHeight);
    1906               0 :     documentIsTopLevel = true;
    1907                 : 
    1908               0 :     if (mIsCreatingPrintPreview) {
    1909               0 :       nsCOMPtr<nsIContentViewer> cv = do_QueryInterface(mDocViewerPrint);
    1910               0 :       if (cv) {
    1911               0 :         parentView = cv->FindContainerView();
    1912                 :       }
    1913                 :     }
    1914                 :   }
    1915                 : 
    1916               0 :   NS_ASSERTION(!aPO->mPresContext, "Recreating prescontext");
    1917                 : 
    1918                 :   // create the PresContext
    1919                 :   aPO->mPresContext = new nsPresContext(aPO->mDocument,
    1920                 :     mIsCreatingPrintPreview ? nsPresContext::eContext_PrintPreview:
    1921               0 :                               nsPresContext::eContext_Print);
    1922               0 :   NS_ENSURE_TRUE(aPO->mPresContext, NS_ERROR_OUT_OF_MEMORY);
    1923               0 :   aPO->mPresContext->SetPrintSettings(mPrt->mPrintSettings);
    1924                 : 
    1925                 :   // set the presentation context to the value in the print settings
    1926                 :   bool printBGColors;
    1927               0 :   mPrt->mPrintSettings->GetPrintBGColors(&printBGColors);
    1928               0 :   aPO->mPresContext->SetBackgroundColorDraw(printBGColors);
    1929               0 :   mPrt->mPrintSettings->GetPrintBGImages(&printBGColors);
    1930               0 :   aPO->mPresContext->SetBackgroundImageDraw(printBGColors);
    1931                 : 
    1932                 :   // init it with the DC
    1933               0 :   nsresult rv = aPO->mPresContext->Init(mPrt->mPrintDC);
    1934               0 :   NS_ENSURE_SUCCESS(rv, rv);
    1935                 : 
    1936               0 :   aPO->mViewManager = do_CreateInstance(kViewManagerCID, &rv);
    1937               0 :   NS_ENSURE_SUCCESS(rv,rv);
    1938                 : 
    1939               0 :   rv = aPO->mViewManager->Init(mPrt->mPrintDC);
    1940               0 :   NS_ENSURE_SUCCESS(rv,rv);
    1941                 : 
    1942                 :   nsStyleSet* styleSet;
    1943               0 :   rv = mDocViewerPrint->CreateStyleSet(aPO->mDocument, &styleSet);
    1944               0 :   NS_ENSURE_SUCCESS(rv, rv);
    1945                 : 
    1946               0 :   rv = aPO->mDocument->CreateShell(aPO->mPresContext, aPO->mViewManager,
    1947               0 :                                    styleSet, getter_AddRefs(aPO->mPresShell));
    1948               0 :   if (NS_FAILED(rv)) {
    1949               0 :     delete styleSet;
    1950               0 :     return rv;
    1951                 :   }
    1952                 : 
    1953               0 :   styleSet->EndUpdate();
    1954                 :   
    1955                 :   // The pres shell now owns the style set object.
    1956                 : 
    1957               0 :   PR_PL(("In DV::ReflowPrintObject PO: %p (%9s) Setting w,h to %d,%d\n", aPO,
    1958                 :          gFrameTypesStr[aPO->mFrameType], adjSize.width, adjSize.height));
    1959                 : 
    1960                 :   // Create a child window of the parent that is our "root view/window"
    1961               0 :   nsRect tbounds = nsRect(nsPoint(0, 0), adjSize);
    1962               0 :   nsIView* rootView = aPO->mViewManager->CreateView(tbounds, parentView);
    1963               0 :   NS_ENSURE_TRUE(rootView, NS_ERROR_OUT_OF_MEMORY);
    1964                 : 
    1965               0 :   if (mIsCreatingPrintPreview && documentIsTopLevel) {
    1966               0 :     aPO->mPresContext->SetPaginatedScrolling(canCreateScrollbars);
    1967                 :   }
    1968                 : 
    1969                 :   // Setup hierarchical relationship in view manager
    1970               0 :   aPO->mViewManager->SetRootView(rootView);
    1971                 : 
    1972                 :   // This docshell stuff is weird; will go away when we stop having multiple
    1973                 :   // presentations per document
    1974               0 :   nsCOMPtr<nsISupports> supps(do_QueryInterface(aPO->mDocShell));
    1975               0 :   aPO->mPresContext->SetContainer(supps);
    1976                 : 
    1977               0 :   aPO->mPresShell->BeginObservingDocument();
    1978                 : 
    1979               0 :   aPO->mPresContext->SetPageSize(adjSize);
    1980               0 :   aPO->mPresContext->SetIsRootPaginatedDocument(documentIsTopLevel);
    1981               0 :   aPO->mPresContext->SetPageScale(aPO->mZoomRatio);
    1982                 :   // Calculate scale factor from printer to screen
    1983               0 :   float printDPI = float(mPrt->mPrintDC->AppUnitsPerCSSInch()) /
    1984               0 :                    float(mPrt->mPrintDC->AppUnitsPerDevPixel());
    1985               0 :   aPO->mPresContext->SetPrintPreviewScale(mScreenDPI / printDPI);
    1986                 : 
    1987               0 :   if (mIsCreatingPrintPreview && documentIsTopLevel) {
    1988               0 :     mDocViewerPrint->SetPrintPreviewPresentation(aPO->mViewManager,
    1989                 :                                                  aPO->mPresContext,
    1990               0 :                                                  aPO->mPresShell);
    1991                 :   }
    1992                 : 
    1993               0 :   rv = aPO->mPresShell->InitialReflow(adjSize.width, adjSize.height);
    1994                 : 
    1995               0 :   NS_ENSURE_SUCCESS(rv, rv);
    1996               0 :   NS_ASSERTION(aPO->mPresShell, "Presshell should still be here");
    1997                 : 
    1998                 :   // Process the reflow event InitialReflow posted
    1999               0 :   aPO->mPresShell->FlushPendingNotifications(Flush_Layout);
    2000                 : 
    2001               0 :   nsCOMPtr<nsIPresShell> displayShell;
    2002               0 :   aPO->mDocShell->GetPresShell(getter_AddRefs(displayShell));
    2003                 :   // Transfer Selection Ranges to the new Print PresShell
    2004               0 :   nsCOMPtr<nsISelection> selection, selectionPS;
    2005                 :   // It's okay if there is no display shell, just skip copying the selection
    2006               0 :   if (displayShell) {
    2007               0 :     selection = displayShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
    2008                 :   }
    2009               0 :   selectionPS = aPO->mPresShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
    2010               0 :   if (selection && selectionPS) {
    2011                 :     PRInt32 cnt;
    2012               0 :     selection->GetRangeCount(&cnt);
    2013                 :     PRInt32 inx;
    2014               0 :     for (inx=0;inx<cnt;inx++) {
    2015               0 :       nsCOMPtr<nsIDOMRange> range;
    2016               0 :       if (NS_SUCCEEDED(selection->GetRangeAt(inx, getter_AddRefs(range))))
    2017               0 :         selectionPS->AddRange(range);
    2018                 :     }
    2019                 :   }
    2020                 : 
    2021                 :   // If we are trying to shrink the contents to fit on the page
    2022                 :   // we must first locate the "pageContent" frame
    2023                 :   // Then we walk the frame tree and look for the "xmost" frame
    2024                 :   // this is the frame where the right-hand side of the frame extends
    2025                 :   // the furthest
    2026               0 :   if (mPrt->mShrinkToFit && documentIsTopLevel) {
    2027               0 :     nsIPageSequenceFrame* pageSequence = aPO->mPresShell->GetPageSequenceFrame();
    2028               0 :     NS_ENSURE_STATE(pageSequence);
    2029               0 :     pageSequence->GetSTFPercent(aPO->mShrinkRatio);
    2030                 :   }
    2031                 : 
    2032                 : #ifdef EXTENDED_DEBUG_PRINTING
    2033                 :     if (kPrintingLogMod && kPrintingLogMod->level == DUMP_LAYOUT_LEVEL) {
    2034                 :       char * docStr;
    2035                 :       char * urlStr;
    2036                 :       GetDocTitleAndURL(aPO, docStr, urlStr);
    2037                 :       char filename[256];
    2038                 :       sprintf(filename, "print_dump_%d.txt", gDumpFileNameCnt++);
    2039                 :       // Dump all the frames and view to a a file
    2040                 :       FILE * fd = fopen(filename, "w");
    2041                 :       if (fd) {
    2042                 :         nsIFrame *theRootFrame =
    2043                 :           aPO->mPresShell->FrameManager()->GetRootFrame();
    2044                 :         fprintf(fd, "Title: %s\n", docStr?docStr:"");
    2045                 :         fprintf(fd, "URL:   %s\n", urlStr?urlStr:"");
    2046                 :         fprintf(fd, "--------------- Frames ----------------\n");
    2047                 :         nsRefPtr<nsRenderingContext> renderingContext;
    2048                 :         mPrt->mPrintDocDC->CreateRenderingContext(*getter_AddRefs(renderingContext));
    2049                 :         RootFrameList(aPO->mPresContext, fd, 0);
    2050                 :         //DumpFrames(fd, aPO->mPresContext, renderingContext, theRootFrame, 0);
    2051                 :         fprintf(fd, "---------------------------------------\n\n");
    2052                 :         fprintf(fd, "--------------- Views From Root Frame----------------\n");
    2053                 :         nsIView* v = theRootFrame->GetView();
    2054                 :         if (v) {
    2055                 :           v->List(fd);
    2056                 :         } else {
    2057                 :           printf("View is null!\n");
    2058                 :         }
    2059                 :         if (docShell) {
    2060                 :           fprintf(fd, "--------------- All Views ----------------\n");
    2061                 :           DumpViews(docShell, fd);
    2062                 :           fprintf(fd, "---------------------------------------\n\n");
    2063                 :         }
    2064                 :         fclose(fd);
    2065                 :       }
    2066                 :       if (docStr) nsMemory::Free(docStr);
    2067                 :       if (urlStr) nsMemory::Free(urlStr);
    2068                 :     }
    2069                 : #endif
    2070                 : 
    2071               0 :   return NS_OK;
    2072                 : }
    2073                 : 
    2074                 : //-------------------------------------------------------
    2075                 : // Figure out how many documents and how many total pages we are printing
    2076                 : void
    2077               0 : nsPrintEngine::CalcNumPrintablePages(PRInt32& aNumPages)
    2078                 : {
    2079               0 :   aNumPages = 0;
    2080                 :   // Count the number of printable documents
    2081                 :   // and printable pages
    2082               0 :   for (PRUint32 i=0; i<mPrt->mPrintDocList.Length(); i++) {
    2083               0 :     nsPrintObject* po = mPrt->mPrintDocList.ElementAt(i);
    2084               0 :     NS_ASSERTION(po, "nsPrintObject can't be null!");
    2085               0 :     if (po->mPresContext && po->mPresContext->IsRootPaginatedDocument()) {
    2086               0 :       nsIPageSequenceFrame* pageSequence = po->mPresShell->GetPageSequenceFrame();
    2087               0 :       nsIFrame * seqFrame = do_QueryFrame(pageSequence);
    2088               0 :       if (seqFrame) {
    2089               0 :         nsIFrame* frame = seqFrame->GetFirstPrincipalChild();
    2090               0 :         while (frame) {
    2091               0 :           aNumPages++;
    2092               0 :           frame = frame->GetNextSibling();
    2093                 :         }
    2094                 :       }
    2095                 :     }
    2096                 :   }
    2097               0 : }
    2098                 : //-----------------------------------------------------------------
    2099                 : //-- Done: Reflow Methods
    2100                 : //-----------------------------------------------------------------
    2101                 : 
    2102                 : //-----------------------------------------------------------------
    2103                 : //-- Section: Printing Methods
    2104                 : //-----------------------------------------------------------------
    2105                 : 
    2106                 : //-------------------------------------------------------
    2107                 : // Called for each DocShell that needs to be printed
    2108                 : bool
    2109               0 : nsPrintEngine::PrintDocContent(nsPrintObject* aPO, nsresult& aStatus)
    2110                 : {
    2111               0 :   NS_ASSERTION(aPO, "Pointer is null!");
    2112               0 :   aStatus = NS_OK;
    2113                 : 
    2114               0 :   if (!aPO->mHasBeenPrinted && aPO->IsPrintable()) {
    2115               0 :     aStatus = DoPrint(aPO);
    2116               0 :     return true;
    2117                 :   }
    2118                 : 
    2119                 :   // If |aPO->mPrintAsIs| and |aPO->mHasBeenPrinted| are true,
    2120                 :   // the kids frames are already processed in |PrintPage|.
    2121               0 :   if (!aPO->mInvisible && !(aPO->mPrintAsIs && aPO->mHasBeenPrinted)) {
    2122               0 :     for (PRUint32 i=0;i<aPO->mKids.Length();i++) {
    2123               0 :       nsPrintObject* po = aPO->mKids[i];
    2124               0 :       bool printed = PrintDocContent(po, aStatus);
    2125               0 :       if (printed || NS_FAILED(aStatus)) {
    2126               0 :         return true;
    2127                 :       }
    2128                 :     }
    2129                 :   }
    2130               0 :   return false;
    2131                 : }
    2132                 : 
    2133                 : static already_AddRefed<nsIDOMNode>
    2134               0 : GetEqualNodeInCloneTree(nsIDOMNode* aNode, nsIDocument* aDoc)
    2135                 : {
    2136               0 :   nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
    2137                 :   // Selections in anonymous subtrees aren't supported.
    2138               0 :   if (content && content->IsInAnonymousSubtree()) {
    2139               0 :     return nsnull;
    2140                 :   }
    2141                 : 
    2142               0 :   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
    2143               0 :   NS_ENSURE_TRUE(node, nsnull);
    2144                 : 
    2145               0 :   nsTArray<PRInt32> indexArray;
    2146               0 :   nsINode* current = node;
    2147               0 :   NS_ENSURE_TRUE(current, nsnull);
    2148               0 :   while (current) {
    2149               0 :     nsINode* parent = current->GetNodeParent();
    2150               0 :     if (!parent) {
    2151               0 :      break;
    2152                 :     }
    2153               0 :     PRInt32 index = parent->IndexOf(current);
    2154               0 :     NS_ENSURE_TRUE(index >= 0, nsnull);
    2155               0 :     indexArray.AppendElement(index);
    2156               0 :     current = parent;
    2157                 :   }
    2158               0 :   NS_ENSURE_TRUE(current->IsNodeOfType(nsINode::eDOCUMENT), nsnull);
    2159                 : 
    2160               0 :   current = aDoc;
    2161               0 :   for (PRInt32 i = indexArray.Length() - 1; i >= 0; --i) {
    2162               0 :     current = current->GetChildAt(indexArray[i]);
    2163               0 :     NS_ENSURE_TRUE(current, nsnull);
    2164                 :   }
    2165               0 :   nsCOMPtr<nsIDOMNode> result = do_QueryInterface(current);
    2166               0 :   return result.forget();
    2167                 : }
    2168                 : 
    2169               0 : static nsresult CloneRangeToSelection(nsIDOMRange* aRange,
    2170                 :                                       nsIDocument* aDoc,
    2171                 :                                       nsISelection* aSelection)
    2172                 : {
    2173               0 :   bool collapsed = false;
    2174               0 :   aRange->GetCollapsed(&collapsed);
    2175               0 :   if (collapsed) {
    2176               0 :     return NS_OK;
    2177                 :   }
    2178                 : 
    2179               0 :   nsCOMPtr<nsIDOMNode> startContainer, endContainer;
    2180               0 :   PRInt32 startOffset = -1, endOffset = -1;
    2181               0 :   aRange->GetStartContainer(getter_AddRefs(startContainer));
    2182               0 :   aRange->GetStartOffset(&startOffset);
    2183               0 :   aRange->GetEndContainer(getter_AddRefs(endContainer));
    2184               0 :   aRange->GetEndOffset(&endOffset);
    2185               0 :   NS_ENSURE_STATE(startContainer && endContainer);
    2186                 : 
    2187               0 :   nsCOMPtr<nsIDOMNode> newStart = GetEqualNodeInCloneTree(startContainer, aDoc);
    2188               0 :   nsCOMPtr<nsIDOMNode> newEnd = GetEqualNodeInCloneTree(endContainer, aDoc);
    2189               0 :   NS_ENSURE_STATE(newStart && newEnd);
    2190                 : 
    2191               0 :   nsRefPtr<nsRange> range = new nsRange();
    2192               0 :   nsresult rv = range->SetStart(newStart, startOffset);
    2193               0 :   NS_ENSURE_SUCCESS(rv, rv);
    2194               0 :   rv = range->SetEnd(newEnd, endOffset);
    2195               0 :   NS_ENSURE_SUCCESS(rv, rv);
    2196                 : 
    2197               0 :   return aSelection->AddRange(range);
    2198                 : }
    2199                 : 
    2200               0 : static nsresult CloneSelection(nsIDocument* aOrigDoc, nsIDocument* aDoc)
    2201                 : {
    2202               0 :   nsIPresShell* origShell = aOrigDoc->GetShell();
    2203               0 :   nsIPresShell* shell = aDoc->GetShell();
    2204               0 :   NS_ENSURE_STATE(origShell && shell);
    2205                 : 
    2206                 :   nsCOMPtr<nsISelection> origSelection =
    2207               0 :     origShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
    2208                 :   nsCOMPtr<nsISelection> selection =
    2209               0 :     shell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
    2210               0 :   NS_ENSURE_STATE(origSelection && selection);
    2211                 : 
    2212               0 :   PRInt32 rangeCount = 0;
    2213               0 :   origSelection->GetRangeCount(&rangeCount);
    2214               0 :   for (PRInt32 i = 0; i < rangeCount; ++i) {
    2215               0 :     nsCOMPtr<nsIDOMRange> range;
    2216               0 :     origSelection->GetRangeAt(i, getter_AddRefs(range));
    2217               0 :     if (range) {
    2218               0 :       CloneRangeToSelection(range, aDoc, selection);
    2219                 :     }
    2220                 :   }
    2221               0 :   return NS_OK;
    2222                 : }
    2223                 : 
    2224                 : //-------------------------------------------------------
    2225                 : nsresult
    2226               0 : nsPrintEngine::DoPrint(nsPrintObject * aPO)
    2227                 : {
    2228               0 :   PR_PL(("\n"));
    2229               0 :   PR_PL(("**************************** %s ****************************\n", gFrameTypesStr[aPO->mFrameType]));
    2230               0 :   PR_PL(("****** In DV::DoPrint   PO: %p \n", aPO));
    2231                 : 
    2232               0 :   nsIPresShell*   poPresShell   = aPO->mPresShell;
    2233               0 :   nsPresContext*  poPresContext = aPO->mPresContext;
    2234                 : 
    2235               0 :   NS_ASSERTION(poPresContext, "PrintObject has not been reflowed");
    2236               0 :   NS_ASSERTION(poPresContext->Type() != nsPresContext::eContext_PrintPreview,
    2237                 :                "How did this context end up here?");
    2238                 : 
    2239               0 :   if (mPrt->mPrintProgressParams) {
    2240               0 :     SetDocAndURLIntoProgress(aPO, mPrt->mPrintProgressParams);
    2241                 :   }
    2242                 : 
    2243                 :   {
    2244               0 :     PRInt16 printRangeType = nsIPrintSettings::kRangeAllPages;
    2245                 :     nsresult rv;
    2246               0 :     if (mPrt->mPrintSettings != nsnull) {
    2247               0 :       mPrt->mPrintSettings->GetPrintRange(&printRangeType);
    2248                 :     }
    2249                 : 
    2250                 :     // Ask the page sequence frame to print all the pages
    2251               0 :     nsIPageSequenceFrame* pageSequence = poPresShell->GetPageSequenceFrame();
    2252               0 :     NS_ASSERTION(nsnull != pageSequence, "no page sequence frame");
    2253                 : 
    2254                 :     // We are done preparing for printing, so we can turn this off
    2255               0 :     mPrt->mPreparingForPrint = false;
    2256                 : 
    2257                 :     // mPrt->mDebugFilePtr this is onlu non-null when compiled for debugging
    2258               0 :     if (nsnull != mPrt->mDebugFilePtr) {
    2259                 : #ifdef NS_DEBUG
    2260                 :       // output the regression test
    2261               0 :       nsIFrame* root = poPresShell->FrameManager()->GetRootFrame();
    2262               0 :       root->DumpRegressionData(poPresContext, mPrt->mDebugFilePtr, 0);
    2263               0 :       fclose(mPrt->mDebugFilePtr);
    2264               0 :       SetIsPrinting(false);
    2265                 : #endif
    2266                 :     } else {
    2267                 : #ifdef EXTENDED_DEBUG_PRINTING
    2268                 :       nsIFrame* rootFrame = poPresShell->FrameManager()->GetRootFrame();
    2269                 :       if (aPO->IsPrintable()) {
    2270                 :         char * docStr;
    2271                 :         char * urlStr;
    2272                 :         GetDocTitleAndURL(aPO, docStr, urlStr);
    2273                 :         DumpLayoutData(docStr, urlStr, poPresContext, mPrt->mPrintDocDC, rootFrame, docShell, nsnull);
    2274                 :         if (docStr) nsMemory::Free(docStr);
    2275                 :         if (urlStr) nsMemory::Free(urlStr);
    2276                 :       }
    2277                 : #endif
    2278                 : 
    2279               0 :       if (!mPrt->mPrintSettings) {
    2280                 :         // not sure what to do here!
    2281               0 :         SetIsPrinting(false);
    2282               0 :         return NS_ERROR_FAILURE;
    2283                 :       }
    2284                 : 
    2285               0 :       PRUnichar * docTitleStr = nsnull;
    2286               0 :       PRUnichar * docURLStr   = nsnull;
    2287                 : 
    2288               0 :       GetDisplayTitleAndURL(aPO, &docTitleStr, &docURLStr, eDocTitleDefBlank);
    2289                 : 
    2290               0 :       if (nsIPrintSettings::kRangeSelection == printRangeType) {
    2291               0 :         CloneSelection(aPO->mDocument->GetOriginalDocument(), aPO->mDocument);
    2292                 : 
    2293               0 :         poPresContext->SetIsRenderingOnlySelection(true);
    2294                 :         // temporarily creating rendering context
    2295                 :         // which is needed to find the selection frames
    2296               0 :         nsRefPtr<nsRenderingContext> rc;
    2297               0 :         mPrt->mPrintDC->CreateRenderingContext(*getter_AddRefs(rc));
    2298                 : 
    2299                 :         // find the starting and ending page numbers
    2300                 :         // via the selection
    2301                 :         nsIFrame* startFrame;
    2302                 :         nsIFrame* endFrame;
    2303                 :         PRInt32   startPageNum;
    2304                 :         PRInt32   endPageNum;
    2305               0 :         nsRect    startRect;
    2306               0 :         nsRect    endRect;
    2307                 : 
    2308               0 :         nsCOMPtr<nsISelection> selectionPS;
    2309               0 :         selectionPS = poPresShell->GetCurrentSelection(nsISelectionController::SELECTION_NORMAL);
    2310                 : 
    2311               0 :         rv = GetPageRangeForSelection(poPresShell, poPresContext, *rc, selectionPS, pageSequence,
    2312                 :                                       &startFrame, startPageNum, startRect,
    2313               0 :                                       &endFrame, endPageNum, endRect);
    2314               0 :         if (NS_SUCCEEDED(rv)) {
    2315               0 :           mPrt->mPrintSettings->SetStartPageRange(startPageNum);
    2316               0 :           mPrt->mPrintSettings->SetEndPageRange(endPageNum);
    2317               0 :           nsIntMargin marginTwips(0,0,0,0);
    2318               0 :           nsIntMargin unwrtMarginTwips(0,0,0,0);
    2319               0 :           mPrt->mPrintSettings->GetMarginInTwips(marginTwips);
    2320               0 :           mPrt->mPrintSettings->GetUnwriteableMarginInTwips(unwrtMarginTwips);
    2321                 :           nsMargin totalMargin = poPresContext->CSSTwipsToAppUnits(marginTwips +
    2322               0 :                                                                    unwrtMarginTwips);
    2323               0 :           if (startPageNum == endPageNum) {
    2324               0 :             startRect.y -= totalMargin.top;
    2325               0 :             endRect.y   -= totalMargin.top;
    2326                 : 
    2327                 :             // Clip out selection regions above the top of the first page
    2328               0 :             if (startRect.y < 0) {
    2329                 :               // Reduce height to be the height of the positive-territory
    2330                 :               // region of original rect
    2331               0 :               startRect.height = NS_MAX(0, startRect.YMost());
    2332               0 :               startRect.y = 0;
    2333                 :             }
    2334               0 :             if (endRect.y < 0) {
    2335                 :               // Reduce height to be the height of the positive-territory
    2336                 :               // region of original rect
    2337               0 :               endRect.height = NS_MAX(0, endRect.YMost());
    2338               0 :               endRect.y = 0;
    2339                 :             }
    2340               0 :             NS_ASSERTION(endRect.y >= startRect.y,
    2341                 :                          "Selection end point should be after start point");
    2342               0 :             NS_ASSERTION(startRect.height >= 0,
    2343                 :                          "rect should have non-negative height.");
    2344               0 :             NS_ASSERTION(endRect.height >= 0,
    2345                 :                          "rect should have non-negative height.");
    2346                 : 
    2347               0 :             nscoord selectionHgt = endRect.y + endRect.height - startRect.y;
    2348                 :             // XXX This is temporary fix for printing more than one page of a selection
    2349                 :             pageSequence->SetSelectionHeight(startRect.y * aPO->mZoomRatio,
    2350               0 :                                              selectionHgt * aPO->mZoomRatio);
    2351                 : 
    2352                 :             // calc total pages by getting calculating the selection's height
    2353                 :             // and then dividing it by how page content frames will fit.
    2354                 :             nscoord pageWidth, pageHeight;
    2355               0 :             mPrt->mPrintDC->GetDeviceSurfaceDimensions(pageWidth, pageHeight);
    2356               0 :             pageHeight -= totalMargin.top + totalMargin.bottom;
    2357               0 :             PRInt32 totalPages = NSToIntCeil(float(selectionHgt) * aPO->mZoomRatio / float(pageHeight));
    2358               0 :             pageSequence->SetTotalNumPages(totalPages);
    2359                 :           }
    2360                 :         }
    2361                 :       }
    2362                 : 
    2363               0 :       nsIFrame * seqFrame = do_QueryFrame(pageSequence);
    2364               0 :       if (!seqFrame) {
    2365               0 :         SetIsPrinting(false);
    2366               0 :         if (docTitleStr) nsMemory::Free(docTitleStr);
    2367               0 :         if (docURLStr) nsMemory::Free(docURLStr);
    2368               0 :         return NS_ERROR_FAILURE;
    2369                 :       }
    2370                 : 
    2371               0 :       mPageSeqFrame = pageSequence;
    2372               0 :       mPageSeqFrame->StartPrint(poPresContext, mPrt->mPrintSettings, docTitleStr, docURLStr);
    2373                 : 
    2374                 :       // Schedule Page to Print
    2375               0 :       PR_PL(("Scheduling Print of PO: %p (%s) \n", aPO, gFrameTypesStr[aPO->mFrameType]));
    2376               0 :       StartPagePrintTimer(aPO);
    2377                 :     }
    2378                 :   }
    2379                 : 
    2380               0 :   return NS_OK;
    2381                 : }
    2382                 : 
    2383                 : //---------------------------------------------------------------------
    2384                 : void
    2385               0 : nsPrintEngine::SetDocAndURLIntoProgress(nsPrintObject* aPO,
    2386                 :                                         nsIPrintProgressParams* aParams)
    2387                 : {
    2388               0 :   NS_ASSERTION(aPO, "Must have vaild nsPrintObject");
    2389               0 :   NS_ASSERTION(aParams, "Must have vaild nsIPrintProgressParams");
    2390                 : 
    2391               0 :   if (!aPO || !aPO->mDocShell || !aParams) {
    2392               0 :     return;
    2393                 :   }
    2394               0 :   const PRUint32 kTitleLength = 64;
    2395                 : 
    2396                 :   PRUnichar * docTitleStr;
    2397                 :   PRUnichar * docURLStr;
    2398               0 :   GetDisplayTitleAndURL(aPO, &docTitleStr, &docURLStr, eDocTitleDefURLDoc);
    2399                 : 
    2400                 :   // Make sure the Titles & URLS don't get too long for the progress dialog
    2401               0 :   ElipseLongString(docTitleStr, kTitleLength, false);
    2402               0 :   ElipseLongString(docURLStr, kTitleLength, true);
    2403                 : 
    2404               0 :   aParams->SetDocTitle(docTitleStr);
    2405               0 :   aParams->SetDocURL(docURLStr);
    2406                 : 
    2407               0 :   if (docTitleStr != nsnull) nsMemory::Free(docTitleStr);
    2408               0 :   if (docURLStr != nsnull) nsMemory::Free(docURLStr);
    2409                 : }
    2410                 : 
    2411                 : //---------------------------------------------------------------------
    2412                 : void
    2413               0 : nsPrintEngine::ElipseLongString(PRUnichar *& aStr, const PRUint32 aLen, bool aDoFront)
    2414                 : {
    2415                 :   // Make sure the URLS don't get too long for the progress dialog
    2416               0 :   if (aStr && nsCRT::strlen(aStr) > aLen) {
    2417               0 :     if (aDoFront) {
    2418               0 :       PRUnichar * ptr = &aStr[nsCRT::strlen(aStr)-aLen+3];
    2419               0 :       nsAutoString newStr;
    2420               0 :       newStr.AppendLiteral("...");
    2421               0 :       newStr += ptr;
    2422               0 :       nsMemory::Free(aStr);
    2423               0 :       aStr = ToNewUnicode(newStr);
    2424                 :     } else {
    2425               0 :       nsAutoString newStr(aStr);
    2426               0 :       newStr.SetLength(aLen-3);
    2427               0 :       newStr.AppendLiteral("...");
    2428               0 :       nsMemory::Free(aStr);
    2429               0 :       aStr = ToNewUnicode(newStr);
    2430                 :     }
    2431                 :   }
    2432               0 : }
    2433                 : 
    2434                 : //-------------------------------------------------------
    2435                 : bool
    2436               0 : nsPrintEngine::PrintPage(nsPrintObject*    aPO,
    2437                 :                          bool&           aInRange)
    2438                 : {
    2439               0 :   NS_ASSERTION(aPO,            "aPO is null!");
    2440               0 :   NS_ASSERTION(mPageSeqFrame,  "mPageSeqFrame is null!");
    2441               0 :   NS_ASSERTION(mPrt,           "mPrt is null!");
    2442                 : 
    2443                 :   // Although these should NEVER be NULL
    2444                 :   // This is added insurance, to make sure we don't crash in optimized builds
    2445               0 :   if (!mPrt || !aPO || !mPageSeqFrame) {
    2446               0 :     ShowPrintErrorDialog(NS_ERROR_FAILURE);
    2447               0 :     return true; // means we are done printing
    2448                 :   }
    2449                 : 
    2450               0 :   PR_PL(("-----------------------------------\n"));
    2451               0 :   PR_PL(("------ In DV::PrintPage PO: %p (%s)\n", aPO, gFrameTypesStr[aPO->mFrameType]));
    2452                 : 
    2453                 :   // Check setting to see if someone request it be cancelled
    2454               0 :   bool isCancelled = false;
    2455               0 :   mPrt->mPrintSettings->GetIsCancelled(&isCancelled);
    2456               0 :   if (isCancelled)
    2457               0 :     return true;
    2458                 : 
    2459                 :   PRInt32 pageNum, numPages, endPage;
    2460               0 :   mPageSeqFrame->GetCurrentPageNum(&pageNum);
    2461               0 :   mPageSeqFrame->GetNumPages(&numPages);
    2462                 : 
    2463                 :   bool donePrinting;
    2464                 :   bool isDoingPrintRange;
    2465               0 :   mPageSeqFrame->IsDoingPrintRange(&isDoingPrintRange);
    2466               0 :   if (isDoingPrintRange) {
    2467                 :     PRInt32 fromPage;
    2468                 :     PRInt32 toPage;
    2469               0 :     mPageSeqFrame->GetPrintRange(&fromPage, &toPage);
    2470                 : 
    2471               0 :     if (fromPage > numPages) {
    2472               0 :       return true;
    2473                 :     }
    2474               0 :     if (toPage > numPages) {
    2475               0 :       toPage = numPages;
    2476                 :     }
    2477                 : 
    2478               0 :     PR_PL(("****** Printing Page %d printing from %d to page %d\n", pageNum, fromPage, toPage));
    2479                 : 
    2480               0 :     donePrinting = pageNum >= toPage;
    2481               0 :     aInRange = pageNum >= fromPage && pageNum <= toPage;
    2482               0 :     endPage = (toPage - fromPage)+1;
    2483                 :   } else {
    2484               0 :     PR_PL(("****** Printing Page %d of %d page(s)\n", pageNum, numPages));
    2485                 : 
    2486               0 :     donePrinting = pageNum >= numPages;
    2487               0 :     endPage = numPages;
    2488               0 :     aInRange = true;
    2489                 :   }
    2490                 : 
    2491                 :   // XXX This is wrong, but the actual behavior in the presence of a print
    2492                 :   // range sucks.
    2493               0 :   if (mPrt->mPrintFrameType == nsIPrintSettings::kEachFrameSep)
    2494               0 :     endPage = mPrt->mNumPrintablePages;
    2495                 :   
    2496               0 :   mPrt->DoOnProgressChange(++mPrt->mNumPagesPrinted, endPage, false, 0);
    2497                 : 
    2498                 :   // Print the Page
    2499                 :   // if a print job was cancelled externally, an EndPage or BeginPage may
    2500                 :   // fail and the failure is passed back here.
    2501                 :   // Returning true means we are done printing.
    2502                 :   //
    2503                 :   // When rv == NS_ERROR_ABORT, it means we want out of the
    2504                 :   // print job without displaying any error messages
    2505               0 :   nsresult rv = mPageSeqFrame->PrintNextPage();
    2506               0 :   if (NS_FAILED(rv)) {
    2507               0 :     if (rv != NS_ERROR_ABORT) {
    2508               0 :       ShowPrintErrorDialog(rv);
    2509               0 :       mPrt->mIsAborted = true;
    2510                 :     }
    2511               0 :     return true;
    2512                 :   }
    2513                 : 
    2514               0 :   mPageSeqFrame->DoPageEnd();
    2515                 : 
    2516               0 :   return donePrinting;
    2517                 : }
    2518                 : 
    2519                 : /** ---------------------------------------------------
    2520                 :  *  Find by checking frames type
    2521                 :  */
    2522                 : nsresult 
    2523               0 : nsPrintEngine::FindSelectionBoundsWithList(nsPresContext* aPresContext,
    2524                 :                                            nsRenderingContext& aRC,
    2525                 :                                            nsFrameList::Enumerator& aChildFrames,
    2526                 :                                            nsIFrame *      aParentFrame,
    2527                 :                                            nsRect&         aRect,
    2528                 :                                            nsIFrame *&     aStartFrame,
    2529                 :                                            nsRect&         aStartRect,
    2530                 :                                            nsIFrame *&     aEndFrame,
    2531                 :                                            nsRect&         aEndRect)
    2532                 : {
    2533               0 :   NS_ASSERTION(aPresContext, "Pointer is null!");
    2534               0 :   NS_ASSERTION(aParentFrame, "Pointer is null!");
    2535                 : 
    2536               0 :   aRect += aParentFrame->GetPosition();
    2537               0 :   for (; !aChildFrames.AtEnd(); aChildFrames.Next()) {
    2538               0 :     nsIFrame* child = aChildFrames.get();
    2539               0 :     if (child->IsSelected() && child->IsVisibleForPainting()) {
    2540               0 :       nsRect r = child->GetRect();
    2541               0 :       if (aStartFrame == nsnull) {
    2542               0 :         aStartFrame = child;
    2543               0 :         aStartRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height);
    2544                 :       } else {
    2545               0 :         aEndFrame = child;
    2546               0 :         aEndRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height);
    2547                 :       }
    2548                 :     }
    2549               0 :     FindSelectionBounds(aPresContext, aRC, child, aRect, aStartFrame, aStartRect, aEndFrame, aEndRect);
    2550               0 :     child = child->GetNextSibling();
    2551                 :   }
    2552               0 :   aRect -= aParentFrame->GetPosition();
    2553               0 :   return NS_OK;
    2554                 : }
    2555                 : 
    2556                 : //-------------------------------------------------------
    2557                 : // Find the Frame that is XMost
    2558                 : nsresult 
    2559               0 : nsPrintEngine::FindSelectionBounds(nsPresContext* aPresContext,
    2560                 :                                    nsRenderingContext& aRC,
    2561                 :                                    nsIFrame *      aParentFrame,
    2562                 :                                    nsRect&         aRect,
    2563                 :                                    nsIFrame *&     aStartFrame,
    2564                 :                                    nsRect&         aStartRect,
    2565                 :                                    nsIFrame *&     aEndFrame,
    2566                 :                                    nsRect&         aEndRect)
    2567                 : {
    2568               0 :   NS_ASSERTION(aPresContext, "Pointer is null!");
    2569               0 :   NS_ASSERTION(aParentFrame, "Pointer is null!");
    2570                 : 
    2571                 :   // loop through named child lists
    2572               0 :   nsIFrame::ChildListIterator lists(aParentFrame);
    2573               0 :   for (; !lists.IsDone(); lists.Next()) {
    2574               0 :     nsFrameList::Enumerator childFrames(lists.CurrentList());
    2575               0 :     nsresult rv = FindSelectionBoundsWithList(aPresContext, aRC, childFrames, aParentFrame, aRect, aStartFrame, aStartRect, aEndFrame, aEndRect);
    2576               0 :     NS_ENSURE_SUCCESS(rv, rv);
    2577                 :   }
    2578               0 :   return NS_OK;
    2579                 : }
    2580                 : 
    2581                 : /** ---------------------------------------------------
    2582                 :  *  This method finds the starting and ending page numbers
    2583                 :  *  of the selection and also returns rect for each where
    2584                 :  *  the x,y of the rect is relative to the very top of the
    2585                 :  *  frame tree (absolutely positioned)
    2586                 :  */
    2587                 : nsresult 
    2588               0 : nsPrintEngine::GetPageRangeForSelection(nsIPresShell *        aPresShell,
    2589                 :                                         nsPresContext*       aPresContext,
    2590                 :                                         nsRenderingContext&  aRC,
    2591                 :                                         nsISelection*         aSelection,
    2592                 :                                         nsIPageSequenceFrame* aPageSeqFrame,
    2593                 :                                         nsIFrame**            aStartFrame,
    2594                 :                                         PRInt32&              aStartPageNum,
    2595                 :                                         nsRect&               aStartRect,
    2596                 :                                         nsIFrame**            aEndFrame,
    2597                 :                                         PRInt32&              aEndPageNum,
    2598                 :                                         nsRect&               aEndRect)
    2599                 : {
    2600               0 :   NS_ASSERTION(aPresShell, "Pointer is null!");
    2601               0 :   NS_ASSERTION(aPresContext, "Pointer is null!");
    2602               0 :   NS_ASSERTION(aSelection, "Pointer is null!");
    2603               0 :   NS_ASSERTION(aPageSeqFrame, "Pointer is null!");
    2604               0 :   NS_ASSERTION(aStartFrame, "Pointer is null!");
    2605               0 :   NS_ASSERTION(aEndFrame, "Pointer is null!");
    2606                 : 
    2607               0 :   nsIFrame * seqFrame = do_QueryFrame(aPageSeqFrame);
    2608               0 :   if (!seqFrame) {
    2609               0 :     return NS_ERROR_FAILURE;
    2610                 :   }
    2611                 : 
    2612               0 :   nsIFrame * startFrame = nsnull;
    2613               0 :   nsIFrame * endFrame   = nsnull;
    2614                 : 
    2615                 :   // start out with the sequence frame and search the entire frame tree
    2616                 :   // capturing the starting and ending child frames of the selection
    2617                 :   // and their rects
    2618               0 :   nsRect r = seqFrame->GetRect();
    2619                 :   FindSelectionBounds(aPresContext, aRC, seqFrame, r,
    2620               0 :                       startFrame, aStartRect, endFrame, aEndRect);
    2621                 : 
    2622                 : #ifdef DEBUG_rodsX
    2623                 :   printf("Start Frame: %p\n", startFrame);
    2624                 :   printf("End Frame:   %p\n", endFrame);
    2625                 : #endif
    2626                 : 
    2627                 :   // initial the page numbers here
    2628                 :   // in case we don't find and frames
    2629               0 :   aStartPageNum = -1;
    2630               0 :   aEndPageNum   = -1;
    2631                 : 
    2632                 :   nsIFrame * startPageFrame;
    2633                 :   nsIFrame * endPageFrame;
    2634                 : 
    2635                 :   // check to make sure we found a starting frame
    2636               0 :   if (startFrame != nsnull) {
    2637                 :     // Now search up the tree to find what page the
    2638                 :     // start/ending selections frames are on
    2639                 :     //
    2640                 :     // Check to see if start should be same as end if
    2641                 :     // the end frame comes back null
    2642               0 :     if (endFrame == nsnull) {
    2643                 :       // XXX the "GetPageFrame" step could be integrated into
    2644                 :       // the FindSelectionBounds step, but walking up to find
    2645                 :       // the parent of a child frame isn't expensive and it makes
    2646                 :       // FindSelectionBounds a little easier to understand
    2647               0 :       startPageFrame = nsLayoutUtils::GetPageFrame(startFrame);
    2648               0 :       endPageFrame   = startPageFrame;
    2649               0 :       aEndRect       = aStartRect;
    2650                 :     } else {
    2651               0 :       startPageFrame = nsLayoutUtils::GetPageFrame(startFrame);
    2652               0 :       endPageFrame   = nsLayoutUtils::GetPageFrame(endFrame);
    2653                 :     }
    2654                 :   } else {
    2655               0 :     return NS_ERROR_FAILURE;
    2656                 :   }
    2657                 : 
    2658                 : #ifdef DEBUG_rodsX
    2659                 :   printf("Start Page: %p\n", startPageFrame);
    2660                 :   printf("End Page:   %p\n", endPageFrame);
    2661                 : 
    2662                 :   // dump all the pages and their pointers
    2663                 :   {
    2664                 :   PRInt32 pageNum = 1;
    2665                 :   nsIFrame* child = seqFrame->GetFirstPrincipalChild();
    2666                 :   while (child != nsnull) {
    2667                 :     printf("Page: %d - %p\n", pageNum, child);
    2668                 :     pageNum++;
    2669                 :     child = child->GetNextSibling();
    2670                 :   }
    2671                 :   }
    2672                 : #endif
    2673                 : 
    2674                 :   // Now that we have the page frames
    2675                 :   // find out what the page numbers are for each frame
    2676               0 :   PRInt32 pageNum = 1;
    2677               0 :   nsIFrame* page = seqFrame->GetFirstPrincipalChild();
    2678               0 :   while (page != nsnull) {
    2679               0 :     if (page == startPageFrame) {
    2680               0 :       aStartPageNum = pageNum;
    2681                 :     }
    2682               0 :     if (page == endPageFrame) {
    2683               0 :       aEndPageNum = pageNum;
    2684                 :     }
    2685               0 :     pageNum++;
    2686               0 :     page = page->GetNextSibling();
    2687                 :   }
    2688                 : 
    2689                 : #ifdef DEBUG_rodsX
    2690                 :   printf("Start Page No: %d\n", aStartPageNum);
    2691                 :   printf("End Page No:   %d\n", aEndPageNum);
    2692                 : #endif
    2693                 : 
    2694               0 :   *aStartFrame = startPageFrame;
    2695               0 :   *aEndFrame   = endPageFrame;
    2696                 : 
    2697               0 :   return NS_OK;
    2698                 : }
    2699                 : 
    2700                 : //-----------------------------------------------------------------
    2701                 : //-- Done: Printing Methods
    2702                 : //-----------------------------------------------------------------
    2703                 : 
    2704                 : 
    2705                 : //-----------------------------------------------------------------
    2706                 : //-- Section: Misc Support Methods
    2707                 : //-----------------------------------------------------------------
    2708                 : 
    2709                 : //---------------------------------------------------------------------
    2710               0 : void nsPrintEngine::SetIsPrinting(bool aIsPrinting)
    2711                 : { 
    2712               0 :   mIsDoingPrinting = aIsPrinting;
    2713                 :   // Calling SetIsPrinting while in print preview confuses the document viewer
    2714                 :   // This is safe because we prevent exiting print preview while printing
    2715               0 :   if (!mIsDoingPrintPreview &&
    2716               0 :       mPrt && mPrt->mPrintObject && mPrt->mPrintObject->mDocShell) {
    2717               0 :     nsCOMPtr<nsIContentViewer> viewer;
    2718               0 :     mPrt->mPrintObject->mDocShell->GetContentViewer(getter_AddRefs(viewer));
    2719               0 :     nsCOMPtr<nsIDocumentViewerPrint> docViewerPrint = do_QueryInterface(viewer);
    2720               0 :     if (docViewerPrint) {
    2721               0 :       docViewerPrint->SetIsPrinting(aIsPrinting);
    2722                 :     }
    2723                 :   }
    2724               0 :   if (mPrt && aIsPrinting) {
    2725               0 :     mPrt->mPreparingForPrint = true;
    2726                 :   }
    2727               0 : }
    2728                 : 
    2729                 : //---------------------------------------------------------------------
    2730               0 : void nsPrintEngine::SetIsPrintPreview(bool aIsPrintPreview) 
    2731                 : { 
    2732               0 :   mIsDoingPrintPreview = aIsPrintPreview; 
    2733                 : 
    2734               0 :   if (mDocViewerPrint) {
    2735               0 :     mDocViewerPrint->SetIsPrintPreview(aIsPrintPreview);
    2736                 :   }
    2737               0 : }
    2738                 : 
    2739                 : //---------------------------------------------------------------------
    2740                 : void
    2741               0 : nsPrintEngine::CleanupDocTitleArray(PRUnichar**& aArray, PRInt32& aCount)
    2742                 : {
    2743               0 :   for (PRInt32 i = aCount - 1; i >= 0; i--) {
    2744               0 :     nsMemory::Free(aArray[i]);
    2745                 :   }
    2746               0 :   nsMemory::Free(aArray);
    2747               0 :   aArray = NULL;
    2748               0 :   aCount = 0;
    2749               0 : }
    2750                 : 
    2751                 : //---------------------------------------------------------------------
    2752                 : // static
    2753               0 : bool nsPrintEngine::HasFramesetChild(nsIContent* aContent)
    2754                 : {
    2755               0 :   if (!aContent) {
    2756               0 :     return false;
    2757                 :   }
    2758                 : 
    2759                 :   // do a breadth search across all siblings
    2760               0 :   for (nsIContent* child = aContent->GetFirstChild();
    2761                 :        child;
    2762               0 :        child = child->GetNextSibling()) {
    2763               0 :     if (child->IsHTML(nsGkAtoms::frameset)) {
    2764               0 :       return true;
    2765                 :     }
    2766                 :   }
    2767                 : 
    2768               0 :   return false;
    2769                 : }
    2770                 :  
    2771                 : 
    2772                 : 
    2773                 : /** ---------------------------------------------------
    2774                 :  *  Get the Focused Frame for a documentviewer
    2775                 :  */
    2776                 : already_AddRefed<nsIDOMWindow>
    2777               0 : nsPrintEngine::FindFocusedDOMWindow()
    2778                 : {
    2779               0 :   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
    2780               0 :   NS_ENSURE_TRUE(fm, nsnull);
    2781                 : 
    2782               0 :   nsCOMPtr<nsPIDOMWindow> window(mDocument->GetWindow());
    2783               0 :   NS_ENSURE_TRUE(window, nsnull);
    2784                 : 
    2785               0 :   nsCOMPtr<nsPIDOMWindow> rootWindow = window->GetPrivateRoot();
    2786               0 :   NS_ENSURE_TRUE(rootWindow, nsnull);
    2787                 : 
    2788                 :   nsPIDOMWindow* focusedWindow;
    2789               0 :   nsFocusManager::GetFocusedDescendant(rootWindow, true, &focusedWindow);
    2790               0 :   NS_ENSURE_TRUE(focusedWindow, nsnull);
    2791                 : 
    2792               0 :   if (IsWindowsInOurSubTree(focusedWindow)) {
    2793               0 :     return focusedWindow;
    2794                 :   }
    2795                 : 
    2796               0 :   NS_IF_RELEASE(focusedWindow);
    2797               0 :   return nsnull;
    2798                 : }
    2799                 : 
    2800                 : //---------------------------------------------------------------------
    2801                 : bool
    2802               0 : nsPrintEngine::IsWindowsInOurSubTree(nsPIDOMWindow * window)
    2803                 : {
    2804               0 :   bool found = false;
    2805                 : 
    2806                 :   // now check to make sure it is in "our" tree of docshells
    2807               0 :   if (window) {
    2808                 :     nsCOMPtr<nsIDocShellTreeItem> docShellAsItem =
    2809               0 :       do_QueryInterface(window->GetDocShell());
    2810                 : 
    2811               0 :     if (docShellAsItem) {
    2812                 :       // get this DocViewer docshell
    2813               0 :       nsCOMPtr<nsIDocShell> thisDVDocShell(do_QueryReferent(mContainer));
    2814               0 :       while (!found) {
    2815               0 :         nsCOMPtr<nsIDocShell> parentDocshell(do_QueryInterface(docShellAsItem));
    2816               0 :         if (parentDocshell) {
    2817               0 :           if (parentDocshell == thisDVDocShell) {
    2818               0 :             found = true;
    2819                 :             break;
    2820                 :           }
    2821                 :         } else {
    2822                 :           break; // at top of tree
    2823                 :         }
    2824               0 :         nsCOMPtr<nsIDocShellTreeItem> docShellParent;
    2825               0 :         docShellAsItem->GetSameTypeParent(getter_AddRefs(docShellParent));
    2826               0 :         docShellAsItem = docShellParent;
    2827                 :       } // while
    2828                 :     }
    2829                 :   } // scriptobj
    2830                 : 
    2831               0 :   return found;
    2832                 : }
    2833                 : 
    2834                 : //-------------------------------------------------------
    2835                 : bool
    2836               0 : nsPrintEngine::DonePrintingPages(nsPrintObject* aPO, nsresult aResult)
    2837                 : {
    2838                 :   //NS_ASSERTION(aPO, "Pointer is null!");
    2839               0 :   PR_PL(("****** In DV::DonePrintingPages PO: %p (%s)\n", aPO, aPO?gFrameTypesStr[aPO->mFrameType]:""));
    2840                 : 
    2841               0 :   if (aPO != nsnull) {
    2842               0 :     aPO->mHasBeenPrinted = true;
    2843                 :     nsresult rv;
    2844               0 :     bool didPrint = PrintDocContent(mPrt->mPrintObject, rv);
    2845               0 :     if (NS_SUCCEEDED(rv) && didPrint) {
    2846               0 :       PR_PL(("****** In DV::DonePrintingPages PO: %p (%s) didPrint:%s (Not Done Printing)\n", aPO, gFrameTypesStr[aPO->mFrameType], PRT_YESNO(didPrint)));
    2847               0 :       return false;
    2848                 :     }
    2849                 :   }
    2850                 : 
    2851               0 :   if (NS_SUCCEEDED(aResult)) {
    2852               0 :     FirePrintCompletionEvent();
    2853                 :   }
    2854                 : 
    2855               0 :   TurnScriptingOn(true);
    2856               0 :   SetIsPrinting(false);
    2857                 : 
    2858                 :   // Release reference to mPagePrintTimer; the timer object destroys itself
    2859                 :   // after this returns true
    2860               0 :   NS_IF_RELEASE(mPagePrintTimer);
    2861                 : 
    2862               0 :   return true;
    2863                 : }
    2864                 : 
    2865                 : //-------------------------------------------------------
    2866                 : // Recursively sets the PO items to be printed "As Is"
    2867                 : // from the given item down into the tree
    2868                 : void
    2869               0 : nsPrintEngine::SetPrintAsIs(nsPrintObject* aPO, bool aAsIs)
    2870                 : {
    2871               0 :   NS_ASSERTION(aPO, "Pointer is null!");
    2872                 : 
    2873               0 :   aPO->mPrintAsIs = aAsIs;
    2874               0 :   for (PRUint32 i=0;i<aPO->mKids.Length();i++) {
    2875               0 :     SetPrintAsIs(aPO->mKids[i], aAsIs);
    2876                 :   }
    2877               0 : }
    2878                 : 
    2879                 : //-------------------------------------------------------
    2880                 : // Given a DOMWindow it recursively finds the PO object that matches
    2881                 : nsPrintObject*
    2882               0 : nsPrintEngine::FindPrintObjectByDOMWin(nsPrintObject* aPO,
    2883                 :                                        nsIDOMWindow* aDOMWin)
    2884                 : {
    2885               0 :   NS_ASSERTION(aPO, "Pointer is null!");
    2886                 : 
    2887                 :   // Often the CurFocused DOMWindow is passed in
    2888                 :   // andit is valid for it to be null, so short circut
    2889               0 :   if (!aDOMWin) {
    2890               0 :     return nsnull;
    2891                 :   }
    2892                 : 
    2893               0 :   nsCOMPtr<nsIDOMDocument> domDoc;
    2894               0 :   aDOMWin->GetDocument(getter_AddRefs(domDoc));
    2895               0 :   nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
    2896               0 :   if (aPO->mDocument && aPO->mDocument->GetOriginalDocument() == doc) {
    2897               0 :     return aPO;
    2898                 :   }
    2899                 : 
    2900               0 :   PRInt32 cnt = aPO->mKids.Length();
    2901               0 :   for (PRInt32 i = 0; i < cnt; ++i) {
    2902               0 :     nsPrintObject* po = FindPrintObjectByDOMWin(aPO->mKids[i], aDOMWin);
    2903               0 :     if (po) {
    2904               0 :       return po;
    2905                 :     }
    2906                 :   }
    2907                 : 
    2908               0 :   return nsnull;
    2909                 : }
    2910                 : 
    2911                 : //-------------------------------------------------------
    2912                 : nsresult
    2913               0 : nsPrintEngine::EnablePOsForPrinting()
    2914                 : {
    2915                 :   // NOTE: All POs have been "turned off" for printing
    2916                 :   // this is where we decided which POs get printed.
    2917               0 :   mPrt->mSelectedPO = nsnull;
    2918                 : 
    2919               0 :   if (mPrt->mPrintSettings == nsnull) {
    2920               0 :     return NS_ERROR_FAILURE;
    2921                 :   }
    2922                 : 
    2923               0 :   mPrt->mPrintFrameType = nsIPrintSettings::kNoFrames;
    2924               0 :   mPrt->mPrintSettings->GetPrintFrameType(&mPrt->mPrintFrameType);
    2925                 : 
    2926               0 :   PRInt16 printHowEnable = nsIPrintSettings::kFrameEnableNone;
    2927               0 :   mPrt->mPrintSettings->GetHowToEnableFrameUI(&printHowEnable);
    2928                 : 
    2929               0 :   PRInt16 printRangeType = nsIPrintSettings::kRangeAllPages;
    2930               0 :   mPrt->mPrintSettings->GetPrintRange(&printRangeType);
    2931                 : 
    2932               0 :   PR_PL(("\n"));
    2933               0 :   PR_PL(("********* nsPrintEngine::EnablePOsForPrinting *********\n"));
    2934               0 :   PR_PL(("PrintFrameType:     %s \n", gPrintFrameTypeStr[mPrt->mPrintFrameType]));
    2935               0 :   PR_PL(("HowToEnableFrameUI: %s \n", gFrameHowToEnableStr[printHowEnable]));
    2936               0 :   PR_PL(("PrintRange:         %s \n", gPrintRangeStr[printRangeType]));
    2937               0 :   PR_PL(("----\n"));
    2938                 : 
    2939                 :   // ***** This is the ultimate override *****
    2940                 :   // if we are printing the selection (either an IFrame or selection range)
    2941                 :   // then set the mPrintFrameType as if it were the selected frame
    2942               0 :   if (printRangeType == nsIPrintSettings::kRangeSelection) {
    2943               0 :     mPrt->mPrintFrameType = nsIPrintSettings::kSelectedFrame;
    2944               0 :     printHowEnable        = nsIPrintSettings::kFrameEnableNone;
    2945                 :   }
    2946                 : 
    2947                 :   // This tells us that the "Frame" UI has turned off,
    2948                 :   // so therefore there are no FrameSets/Frames/IFrames to be printed
    2949                 :   //
    2950                 :   // This means there are not FrameSets,
    2951                 :   // but the document could contain an IFrame
    2952               0 :   if (printHowEnable == nsIPrintSettings::kFrameEnableNone) {
    2953                 : 
    2954                 :     // Print all the pages or a sub range of pages
    2955               0 :     if (printRangeType == nsIPrintSettings::kRangeAllPages ||
    2956                 :         printRangeType == nsIPrintSettings::kRangeSpecifiedPageRange) {
    2957               0 :       SetPrintPO(mPrt->mPrintObject, true);
    2958                 : 
    2959                 :       // Set the children so they are PrinAsIs
    2960                 :       // In this case, the children are probably IFrames
    2961               0 :       if (mPrt->mPrintObject->mKids.Length() > 0) {
    2962               0 :         for (PRUint32 i=0;i<mPrt->mPrintObject->mKids.Length();i++) {
    2963               0 :           nsPrintObject* po = mPrt->mPrintObject->mKids[i];
    2964               0 :           NS_ASSERTION(po, "nsPrintObject can't be null!");
    2965               0 :           SetPrintAsIs(po);
    2966                 :         }
    2967                 : 
    2968                 :         // ***** Another override *****
    2969               0 :         mPrt->mPrintFrameType = nsIPrintSettings::kFramesAsIs;
    2970                 :       }
    2971               0 :       PR_PL(("PrintFrameType:     %s \n", gPrintFrameTypeStr[mPrt->mPrintFrameType]));
    2972               0 :       PR_PL(("HowToEnableFrameUI: %s \n", gFrameHowToEnableStr[printHowEnable]));
    2973               0 :       PR_PL(("PrintRange:         %s \n", gPrintRangeStr[printRangeType]));
    2974               0 :       return NS_OK;
    2975                 :     }
    2976                 : 
    2977                 :     // This means we are either printed a selected IFrame or
    2978                 :     // we are printing the current selection
    2979               0 :     if (printRangeType == nsIPrintSettings::kRangeSelection) {
    2980                 : 
    2981                 :       // If the currentFocusDOMWin can'r be null if something is selected
    2982               0 :       if (mPrt->mCurrentFocusWin) {
    2983                 :         // Find the selected IFrame
    2984               0 :         nsPrintObject * po = FindPrintObjectByDOMWin(mPrt->mPrintObject, mPrt->mCurrentFocusWin);
    2985               0 :         if (po != nsnull) {
    2986               0 :           mPrt->mSelectedPO = po;
    2987                 :           // Makes sure all of its children are be printed "AsIs"
    2988               0 :           SetPrintAsIs(po);
    2989                 : 
    2990                 :           // Now, only enable this POs (the selected PO) and all of its children
    2991               0 :           SetPrintPO(po, true);
    2992                 : 
    2993                 :           // check to see if we have a range selection,
    2994                 :           // as oppose to a insert selection
    2995                 :           // this means if the user just clicked on the IFrame then
    2996                 :           // there will not be a selection so we want the entire page to print
    2997                 :           //
    2998                 :           // XXX this is sort of a hack right here to make the page
    2999                 :           // not try to reposition itself when printing selection
    3000                 :           nsCOMPtr<nsIDOMWindow> domWin =
    3001               0 :             do_QueryInterface(po->mDocument->GetOriginalDocument()->GetWindow());
    3002               0 :           if (!IsThereARangeSelection(domWin)) {
    3003               0 :             printRangeType = nsIPrintSettings::kRangeAllPages;
    3004               0 :             mPrt->mPrintSettings->SetPrintRange(printRangeType);
    3005                 :           }
    3006               0 :           PR_PL(("PrintFrameType:     %s \n", gPrintFrameTypeStr[mPrt->mPrintFrameType]));
    3007               0 :           PR_PL(("HowToEnableFrameUI: %s \n", gFrameHowToEnableStr[printHowEnable]));
    3008               0 :           PR_PL(("PrintRange:         %s \n", gPrintRangeStr[printRangeType]));
    3009               0 :           return NS_OK;
    3010                 :         }
    3011                 :       } else {
    3012               0 :         for (PRUint32 i=0;i<mPrt->mPrintDocList.Length();i++) {
    3013               0 :           nsPrintObject* po = mPrt->mPrintDocList.ElementAt(i);
    3014               0 :           NS_ASSERTION(po, "nsPrintObject can't be null!");
    3015               0 :           nsCOMPtr<nsIDOMWindow> domWin = do_GetInterface(po->mDocShell);
    3016               0 :           if (IsThereARangeSelection(domWin)) {
    3017               0 :             mPrt->mCurrentFocusWin = domWin;
    3018               0 :             SetPrintPO(po, true);
    3019                 :             break;
    3020                 :           }
    3021                 :         }
    3022               0 :         return NS_OK;
    3023                 :       }
    3024                 :     }
    3025                 :   }
    3026                 : 
    3027                 :   // check to see if there is a selection when a FrameSet is present
    3028               0 :   if (printRangeType == nsIPrintSettings::kRangeSelection) {
    3029                 :     // If the currentFocusDOMWin can'r be null if something is selected
    3030               0 :     if (mPrt->mCurrentFocusWin) {
    3031                 :       // Find the selected IFrame
    3032               0 :       nsPrintObject * po = FindPrintObjectByDOMWin(mPrt->mPrintObject, mPrt->mCurrentFocusWin);
    3033               0 :       if (po != nsnull) {
    3034               0 :         mPrt->mSelectedPO = po;
    3035                 :         // Makes sure all of its children are be printed "AsIs"
    3036               0 :         SetPrintAsIs(po);
    3037                 : 
    3038                 :         // Now, only enable this POs (the selected PO) and all of its children
    3039               0 :         SetPrintPO(po, true);
    3040                 : 
    3041                 :         // check to see if we have a range selection,
    3042                 :         // as oppose to a insert selection
    3043                 :         // this means if the user just clicked on the IFrame then
    3044                 :         // there will not be a selection so we want the entire page to print
    3045                 :         //
    3046                 :         // XXX this is sort of a hack right here to make the page
    3047                 :         // not try to reposition itself when printing selection
    3048                 :         nsCOMPtr<nsIDOMWindow> domWin =
    3049               0 :           do_QueryInterface(po->mDocument->GetOriginalDocument()->GetWindow());
    3050               0 :         if (!IsThereARangeSelection(domWin)) {
    3051               0 :           printRangeType = nsIPrintSettings::kRangeAllPages;
    3052               0 :           mPrt->mPrintSettings->SetPrintRange(printRangeType);
    3053                 :         }
    3054               0 :         PR_PL(("PrintFrameType:     %s \n", gPrintFrameTypeStr[mPrt->mPrintFrameType]));
    3055               0 :         PR_PL(("HowToEnableFrameUI: %s \n", gFrameHowToEnableStr[printHowEnable]));
    3056               0 :         PR_PL(("PrintRange:         %s \n", gPrintRangeStr[printRangeType]));
    3057               0 :         return NS_OK;
    3058                 :       }
    3059                 :     }
    3060                 :   }
    3061                 : 
    3062                 :   // If we are printing "AsIs" then sets all the POs to be printed as is
    3063               0 :   if (mPrt->mPrintFrameType == nsIPrintSettings::kFramesAsIs) {
    3064               0 :     SetPrintAsIs(mPrt->mPrintObject);
    3065               0 :     SetPrintPO(mPrt->mPrintObject, true);
    3066               0 :     return NS_OK;
    3067                 :   }
    3068                 : 
    3069                 :   // If we are printing the selected Frame then
    3070                 :   // find that PO for that selected DOMWin and set it all of its
    3071                 :   // children to be printed
    3072               0 :   if (mPrt->mPrintFrameType == nsIPrintSettings::kSelectedFrame) {
    3073                 : 
    3074               0 :     if ((mPrt->mIsParentAFrameSet && mPrt->mCurrentFocusWin) || mPrt->mIsIFrameSelected) {
    3075               0 :       nsPrintObject * po = FindPrintObjectByDOMWin(mPrt->mPrintObject, mPrt->mCurrentFocusWin);
    3076               0 :       if (po != nsnull) {
    3077               0 :         mPrt->mSelectedPO = po;
    3078                 :         // NOTE: Calling this sets the "po" and
    3079                 :         // we don't want to do this for documents that have no children,
    3080                 :         // because then the "DoEndPage" gets called and it shouldn't
    3081               0 :         if (po->mKids.Length() > 0) {
    3082                 :           // Makes sure that itself, and all of its children are printed "AsIs"
    3083               0 :           SetPrintAsIs(po);
    3084                 :         }
    3085                 : 
    3086                 :         // Now, only enable this POs (the selected PO) and all of its children
    3087               0 :         SetPrintPO(po, true);
    3088                 :       }
    3089                 :     }
    3090               0 :     return NS_OK;
    3091                 :   }
    3092                 : 
    3093                 :   // If we are print each subdoc separately,
    3094                 :   // then don't print any of the FraneSet Docs
    3095               0 :   if (mPrt->mPrintFrameType == nsIPrintSettings::kEachFrameSep) {
    3096               0 :     SetPrintPO(mPrt->mPrintObject, true);
    3097               0 :     PRInt32 cnt = mPrt->mPrintDocList.Length();
    3098               0 :     for (PRInt32 i=0;i<cnt;i++) {
    3099               0 :       nsPrintObject* po = mPrt->mPrintDocList.ElementAt(i);
    3100               0 :       NS_ASSERTION(po, "nsPrintObject can't be null!");
    3101               0 :       if (po->mFrameType == eFrameSet) {
    3102               0 :         po->mDontPrint = true;
    3103                 :       }
    3104                 :     }
    3105                 :   }
    3106                 : 
    3107               0 :   return NS_OK;
    3108                 : }
    3109                 : 
    3110                 : //-------------------------------------------------------
    3111                 : // Return the nsPrintObject with that is XMost (The widest frameset frame) AND
    3112                 : // contains the XMost (widest) layout frame
    3113                 : nsPrintObject*
    3114               0 : nsPrintEngine::FindSmallestSTF()
    3115                 : {
    3116               0 :   float smallestRatio = 1.0f;
    3117               0 :   nsPrintObject* smallestPO = nsnull;
    3118                 : 
    3119               0 :   for (PRUint32 i=0;i<mPrt->mPrintDocList.Length();i++) {
    3120               0 :     nsPrintObject* po = mPrt->mPrintDocList.ElementAt(i);
    3121               0 :     NS_ASSERTION(po, "nsPrintObject can't be null!");
    3122               0 :     if (po->mFrameType != eFrameSet && po->mFrameType != eIFrame) {
    3123               0 :       if (po->mShrinkRatio < smallestRatio) {
    3124               0 :         smallestRatio = po->mShrinkRatio;
    3125               0 :         smallestPO    = po;
    3126                 :       }
    3127                 :     }
    3128                 :   }
    3129                 : 
    3130                 : #ifdef EXTENDED_DEBUG_PRINTING
    3131                 :   if (smallestPO) printf("*PO: %p  Type: %d  %10.3f\n", smallestPO, smallestPO->mFrameType, smallestPO->mShrinkRatio);
    3132                 : #endif
    3133               0 :   return smallestPO;
    3134                 : }
    3135                 : 
    3136                 : //-------------------------------------------------------
    3137                 : void
    3138               0 : nsPrintEngine::TurnScriptingOn(bool aDoTurnOn)
    3139                 : {
    3140               0 :   if (mIsDoingPrinting && aDoTurnOn && mDocViewerPrint &&
    3141               0 :       mDocViewerPrint->GetIsPrintPreview()) {
    3142                 :     // We don't want to turn scripting on if print preview is shown still after
    3143                 :     // printing.
    3144               0 :     return;
    3145                 :   }
    3146                 : 
    3147               0 :   nsPrintData* prt = mPrt;
    3148                 : #ifdef NS_PRINT_PREVIEW
    3149               0 :   if (!prt) {
    3150               0 :     prt = mPrtPreview;
    3151                 :   }
    3152                 : #endif
    3153               0 :   if (!prt) {
    3154               0 :     return;
    3155                 :   }
    3156                 : 
    3157               0 :   NS_ASSERTION(mDocument, "We MUST have a document.");
    3158                 :   // First, get the script global object from the document...
    3159                 : 
    3160               0 :   for (PRUint32 i=0;i<prt->mPrintDocList.Length();i++) {
    3161               0 :     nsPrintObject* po = prt->mPrintDocList.ElementAt(i);
    3162               0 :     NS_ASSERTION(po, "nsPrintObject can't be null!");
    3163                 : 
    3164               0 :     nsIDocument* doc = po->mDocument;
    3165               0 :     if (!doc) {
    3166               0 :       continue;
    3167                 :     }
    3168                 : 
    3169                 :     // get the script global object
    3170               0 :     nsIScriptGlobalObject *scriptGlobalObj = doc->GetScriptGlobalObject();
    3171                 : 
    3172               0 :     if (scriptGlobalObj) {
    3173               0 :       nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(scriptGlobalObj);
    3174               0 :       NS_ASSERTION(window, "Can't get nsPIDOMWindow");
    3175               0 :       nsIScriptContext *scx = scriptGlobalObj->GetContext();
    3176               0 :       NS_WARN_IF_FALSE(scx, "Can't get nsIScriptContext");
    3177               0 :       nsresult propThere = NS_PROPTABLE_PROP_NOT_THERE;
    3178                 :       doc->GetProperty(nsGkAtoms::scriptEnabledBeforePrintOrPreview,
    3179               0 :                        &propThere);
    3180               0 :       if (aDoTurnOn) {
    3181               0 :         if (propThere != NS_PROPTABLE_PROP_NOT_THERE) {
    3182               0 :           doc->DeleteProperty(nsGkAtoms::scriptEnabledBeforePrintOrPreview);
    3183               0 :           if (scx) {
    3184               0 :             scx->SetScriptsEnabled(true, false);
    3185                 :           }
    3186               0 :           window->ResumeTimeouts(false);
    3187                 :         }
    3188                 :       } else {
    3189                 :         // Have to be careful, because people call us over and over again with
    3190                 :         // aDoTurnOn == false.  So don't set the property if it's already
    3191                 :         // set, since in that case we'd set it to the wrong value.
    3192               0 :         if (propThere == NS_PROPTABLE_PROP_NOT_THERE) {
    3193                 :           // Stash the current value of IsScriptEnabled on the document, so
    3194                 :           // that layout code running in print preview doesn't get confused.
    3195                 :           doc->SetProperty(nsGkAtoms::scriptEnabledBeforePrintOrPreview,
    3196               0 :                            NS_INT32_TO_PTR(doc->IsScriptEnabled()));
    3197               0 :           if (scx) {
    3198               0 :             scx->SetScriptsEnabled(false, false);
    3199                 :           }
    3200               0 :           window->SuspendTimeouts(1, false);
    3201                 :         }
    3202                 :       }
    3203                 :     }
    3204                 :   }
    3205                 : }
    3206                 : 
    3207                 : //-----------------------------------------------------------------
    3208                 : //-- Done: Misc Support Methods
    3209                 : //-----------------------------------------------------------------
    3210                 : 
    3211                 : 
    3212                 : //-----------------------------------------------------------------
    3213                 : //-- Section: Finishing up or Cleaning up
    3214                 : //-----------------------------------------------------------------
    3215                 : 
    3216                 : //-----------------------------------------------------------------
    3217                 : void
    3218               0 : nsPrintEngine::CloseProgressDialog(nsIWebProgressListener* aWebProgressListener)
    3219                 : {
    3220               0 :   if (aWebProgressListener) {
    3221               0 :     aWebProgressListener->OnStateChange(nsnull, nsnull, nsIWebProgressListener::STATE_STOP|nsIWebProgressListener::STATE_IS_DOCUMENT, nsnull);
    3222                 :   }
    3223               0 : }
    3224                 : 
    3225                 : //-----------------------------------------------------------------
    3226                 : nsresult
    3227               0 : nsPrintEngine::FinishPrintPreview()
    3228                 : {
    3229               0 :   nsresult rv = NS_OK;
    3230                 : 
    3231                 : #ifdef NS_PRINT_PREVIEW
    3232                 : 
    3233               0 :   if (!mPrt) {
    3234                 :     /* we're already finished with print preview */
    3235               0 :     return rv;
    3236                 :   }
    3237                 : 
    3238               0 :   rv = DocumentReadyForPrinting();
    3239                 : 
    3240               0 :   SetIsCreatingPrintPreview(false);
    3241                 : 
    3242                 :   /* cleaup on failure + notify user */
    3243               0 :   if (NS_FAILED(rv)) {
    3244                 :     /* cleanup done, let's fire-up an error dialog to notify the user
    3245                 :      * what went wrong...
    3246                 :      */
    3247               0 :     mPrt->OnEndPrinting();
    3248               0 :     TurnScriptingOn(true);
    3249                 : 
    3250               0 :     return rv;
    3251                 :   }
    3252                 : 
    3253                 :   // At this point we are done preparing everything
    3254                 :   // before it is to be created
    3255                 : 
    3256                 : 
    3257               0 :   if (mIsDoingPrintPreview && mOldPrtPreview) {
    3258               0 :     delete mOldPrtPreview;
    3259               0 :     mOldPrtPreview = nsnull;
    3260                 :   }
    3261                 : 
    3262               0 :   InstallPrintPreviewListener();
    3263                 : 
    3264               0 :   mPrt->OnEndPrinting();
    3265                 : 
    3266                 :   // PrintPreview was built using the mPrt (code reuse)
    3267                 :   // then we assign it over
    3268               0 :   mPrtPreview = mPrt;
    3269               0 :   mPrt        = nsnull;
    3270                 : 
    3271                 : #endif // NS_PRINT_PREVIEW
    3272                 : 
    3273               0 :   return NS_OK;
    3274                 : }
    3275                 : 
    3276                 : //-----------------------------------------------------------------
    3277                 : //-- Done: Finishing up or Cleaning up
    3278                 : //-----------------------------------------------------------------
    3279                 : 
    3280                 : 
    3281                 : /*=============== Timer Related Code ======================*/
    3282                 : nsresult
    3283               0 : nsPrintEngine::StartPagePrintTimer(nsPrintObject* aPO)
    3284                 : {
    3285               0 :   if (!mPagePrintTimer) {
    3286               0 :     nsresult rv = NS_NewPagePrintTimer(&mPagePrintTimer);
    3287               0 :     NS_ENSURE_SUCCESS(rv, rv);
    3288                 : 
    3289                 :     // Get the delay time in between the printing of each page
    3290                 :     // this gives the user more time to press cancel
    3291               0 :     PRInt32 printPageDelay = 50;
    3292               0 :     mPrt->mPrintSettings->GetPrintPageDelay(&printPageDelay);
    3293                 : 
    3294               0 :     mPagePrintTimer->Init(this, mDocViewerPrint, printPageDelay);
    3295                 :   }
    3296                 : 
    3297               0 :   return mPagePrintTimer->Start(aPO);
    3298                 : }
    3299                 : 
    3300                 : /*=============== nsIObserver Interface ======================*/
    3301                 : NS_IMETHODIMP 
    3302               0 : nsPrintEngine::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
    3303                 : {
    3304               0 :   nsresult rv = NS_ERROR_FAILURE;
    3305                 : 
    3306               0 :   if (mIsDoingPrinting) {
    3307               0 :     rv = DocumentReadyForPrinting();
    3308                 :  
    3309                 :     /* cleaup on failure + notify user */
    3310               0 :     if (NS_FAILED(rv)) {
    3311               0 :       CleanupOnFailure(rv, true);
    3312                 :     }
    3313                 :   } else {
    3314               0 :     rv = FinishPrintPreview();
    3315               0 :     if (NS_FAILED(rv)) {
    3316               0 :       CleanupOnFailure(rv, false);
    3317                 :     }
    3318               0 :     if (mPrtPreview) {
    3319               0 :       mPrtPreview->OnEndPrinting();
    3320                 :     }
    3321               0 :     rv = NS_OK;
    3322                 :   }
    3323                 : 
    3324               0 :   return rv;
    3325                 : 
    3326                 : }
    3327                 : 
    3328                 : //---------------------------------------------------------------
    3329                 : //-- PLEvent Notification
    3330                 : //---------------------------------------------------------------
    3331               0 : class nsPrintCompletionEvent : public nsRunnable {
    3332                 : public:
    3333               0 :   nsPrintCompletionEvent(nsIDocumentViewerPrint *docViewerPrint)
    3334               0 :     : mDocViewerPrint(docViewerPrint) {
    3335               0 :     NS_ASSERTION(mDocViewerPrint, "mDocViewerPrint is null.");
    3336               0 :   }
    3337                 : 
    3338               0 :   NS_IMETHOD Run() {
    3339               0 :     if (mDocViewerPrint)
    3340               0 :       mDocViewerPrint->OnDonePrinting();
    3341               0 :     return NS_OK;
    3342                 :   }
    3343                 : 
    3344                 : private:
    3345                 :   nsCOMPtr<nsIDocumentViewerPrint> mDocViewerPrint;
    3346                 : };
    3347                 : 
    3348                 : //-----------------------------------------------------------
    3349                 : void
    3350               0 : nsPrintEngine::FirePrintCompletionEvent()
    3351                 : {
    3352               0 :   nsCOMPtr<nsIRunnable> event = new nsPrintCompletionEvent(mDocViewerPrint);
    3353               0 :   if (NS_FAILED(NS_DispatchToCurrentThread(event)))
    3354               0 :     NS_WARNING("failed to dispatch print completion event");
    3355            4392 : }
    3356                 : 
    3357                 : //---------------------------------------------------------------
    3358                 : //---------------------------------------------------------------
    3359                 : //-- Debug helper routines
    3360                 : //---------------------------------------------------------------
    3361                 : //---------------------------------------------------------------
    3362                 : #if (defined(XP_WIN) || defined(XP_OS2)) && defined(EXTENDED_DEBUG_PRINTING)
    3363                 : #include "windows.h"
    3364                 : #include "process.h"
    3365                 : #include "direct.h"
    3366                 : 
    3367                 : #define MY_FINDFIRST(a,b) FindFirstFile(a,b)
    3368                 : #define MY_FINDNEXT(a,b) FindNextFile(a,b)
    3369                 : #define ISDIR(a) (a.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    3370                 : #define MY_FINDCLOSE(a) FindClose(a)
    3371                 : #define MY_FILENAME(a) a.cFileName
    3372                 : #define MY_FILESIZE(a) (a.nFileSizeHigh * MAXDWORD) + a.nFileSizeLow
    3373                 : 
    3374                 : int RemoveFilesInDir(const char * aDir)
    3375                 : {
    3376                 :         WIN32_FIND_DATA data_ptr;
    3377                 :         HANDLE find_handle;
    3378                 : 
    3379                 :   char path[MAX_PATH];
    3380                 : 
    3381                 :   strcpy(path, aDir);
    3382                 : 
    3383                 :         // Append slash to the end of the directory names if not there
    3384                 :         if (path[strlen(path)-1] != '\\')
    3385                 :     strcat(path, "\\");
    3386                 : 
    3387                 :   char findPath[MAX_PATH];
    3388                 :   strcpy(findPath, path);
    3389                 :   strcat(findPath, "*.*");
    3390                 : 
    3391                 :         find_handle = MY_FINDFIRST(findPath, &data_ptr);
    3392                 : 
    3393                 :         if (find_handle != INVALID_HANDLE_VALUE) {
    3394                 :                 do  {
    3395                 :                         if (ISDIR(data_ptr)
    3396                 :                                 && (stricmp(MY_FILENAME(data_ptr),"."))
    3397                 :                                 && (stricmp(MY_FILENAME(data_ptr),".."))) {
    3398                 :                                         // skip
    3399                 :                         }
    3400                 :                         else if (!ISDIR(data_ptr)) {
    3401                 :         if (!strncmp(MY_FILENAME(data_ptr), "print_dump", 10)) {
    3402                 :           char fileName[MAX_PATH];
    3403                 :           strcpy(fileName, aDir);
    3404                 :           strcat(fileName, "\\");
    3405                 :           strcat(fileName, MY_FILENAME(data_ptr));
    3406                 :                                   printf("Removing %s\n", fileName);
    3407                 :           remove(fileName);
    3408                 :         }
    3409                 :                         }
    3410                 :                 } while(MY_FINDNEXT(find_handle,&data_ptr));
    3411                 :                 MY_FINDCLOSE(find_handle);
    3412                 :         }
    3413                 :         return TRUE;
    3414                 : }
    3415                 : #endif
    3416                 : 
    3417                 : #ifdef EXTENDED_DEBUG_PRINTING
    3418                 : 
    3419                 : /** ---------------------------------------------------
    3420                 :  *  Dumps Frames for Printing
    3421                 :  */
    3422                 : static void RootFrameList(nsPresContext* aPresContext, FILE* out, PRInt32 aIndent)
    3423                 : {
    3424                 :   if (!aPresContext || !out)
    3425                 :     return;
    3426                 : 
    3427                 :   nsIPresShell *shell = aPresContext->GetPresShell();
    3428                 :   if (shell) {
    3429                 :     nsIFrame* frame = shell->FrameManager()->GetRootFrame();
    3430                 :     if (frame) {
    3431                 :       frame->List(aPresContext, out, aIndent);
    3432                 :     }
    3433                 :   }
    3434                 : }
    3435                 : 
    3436                 : /** ---------------------------------------------------
    3437                 :  *  Dumps Frames for Printing
    3438                 :  */
    3439                 : static void DumpFrames(FILE*                 out,
    3440                 :                        nsPresContext*       aPresContext,
    3441                 :                        nsRenderingContext * aRendContext,
    3442                 :                        nsIFrame *            aFrame,
    3443                 :                        PRInt32               aLevel)
    3444                 : {
    3445                 :   NS_ASSERTION(out, "Pointer is null!");
    3446                 :   NS_ASSERTION(aPresContext, "Pointer is null!");
    3447                 :   NS_ASSERTION(aRendContext, "Pointer is null!");
    3448                 :   NS_ASSERTION(aFrame, "Pointer is null!");
    3449                 : 
    3450                 :   nsIFrame* child = aFrame->GetFirstPrincipalChild();
    3451                 :   while (child != nsnull) {
    3452                 :     for (PRInt32 i=0;i<aLevel;i++) {
    3453                 :      fprintf(out, "  ");
    3454                 :     }
    3455                 :     nsAutoString tmp;
    3456                 :     child->GetFrameName(tmp);
    3457                 :     fputs(NS_LossyConvertUTF16toASCII(tmp).get(), out);
    3458                 :     bool isSelected;
    3459                 :     if (NS_SUCCEEDED(child->IsVisibleForPainting(aPresContext, *aRendContext, true, &isSelected))) {
    3460                 :       fprintf(out, " %p %s", child, isSelected?"VIS":"UVS");
    3461                 :       nsRect rect = child->GetRect();
    3462                 :       fprintf(out, "[%d,%d,%d,%d] ", rect.x, rect.y, rect.width, rect.height);
    3463                 :       fprintf(out, "v: %p ", (void*)child->GetView());
    3464                 :       fprintf(out, "\n");
    3465                 :       DumpFrames(out, aPresContext, aRendContext, child, aLevel+1);
    3466                 :       child = child->GetNextSibling();
    3467                 :     }
    3468                 :   }
    3469                 : }
    3470                 : 
    3471                 : 
    3472                 : /** ---------------------------------------------------
    3473                 :  *  Dumps the Views from the DocShell
    3474                 :  */
    3475                 : static void
    3476                 : DumpViews(nsIDocShell* aDocShell, FILE* out)
    3477                 : {
    3478                 :   NS_ASSERTION(aDocShell, "Pointer is null!");
    3479                 :   NS_ASSERTION(out, "Pointer is null!");
    3480                 : 
    3481                 :   if (nsnull != aDocShell) {
    3482                 :     fprintf(out, "docshell=%p \n", aDocShell);
    3483                 :     nsIPresShell* shell = nsPrintEngine::GetPresShellFor(aDocShell);
    3484                 :     if (shell) {
    3485                 :       nsIViewManager* vm = shell->GetViewManager();
    3486                 :       if (vm) {
    3487                 :         nsIView* root = vm->GetRootView();
    3488                 :         if (root) {
    3489                 :           root->List(out);
    3490                 :         }
    3491                 :       }
    3492                 :     }
    3493                 :     else {
    3494                 :       fputs("null pres shell\n", out);
    3495                 :     }
    3496                 : 
    3497                 :     // dump the views of the sub documents
    3498                 :     PRInt32 i, n;
    3499                 :     nsCOMPtr<nsIDocShellTreeNode> docShellAsNode(do_QueryInterface(aDocShell));
    3500                 :     docShellAsNode->GetChildCount(&n);
    3501                 :     for (i = 0; i < n; i++) {
    3502                 :       nsCOMPtr<nsIDocShellTreeItem> child;
    3503                 :       docShellAsNode->GetChildAt(i, getter_AddRefs(child));
    3504                 :       nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child));
    3505                 :       if (childAsShell) {
    3506                 :         DumpViews(childAsShell, out);
    3507                 :       }
    3508                 :     }
    3509                 :   }
    3510                 : }
    3511                 : 
    3512                 : /** ---------------------------------------------------
    3513                 :  *  Dumps the Views and Frames
    3514                 :  */
    3515                 : void DumpLayoutData(char*              aTitleStr,
    3516                 :                     char*              aURLStr,
    3517                 :                     nsPresContext*    aPresContext,
    3518                 :                     nsDeviceContext * aDC,
    3519                 :                     nsIFrame *         aRootFrame,
    3520                 :                     nsIDocShekk *      aDocShell,
    3521                 :                     FILE*              aFD = nsnull)
    3522                 : {
    3523                 :   if (!kPrintingLogMod || kPrintingLogMod->level != DUMP_LAYOUT_LEVEL) return;
    3524                 : 
    3525                 :   if (aPresContext == nsnull || aDC == nsnull) {
    3526                 :     return;
    3527                 :   }
    3528                 : 
    3529                 : #ifdef NS_PRINT_PREVIEW
    3530                 :   if (aPresContext->Type() == nsPresContext::eContext_PrintPreview) {
    3531                 :     return;
    3532                 :   }
    3533                 : #endif
    3534                 : 
    3535                 :   NS_ASSERTION(aRootFrame, "Pointer is null!");
    3536                 :   NS_ASSERTION(aDocShell, "Pointer is null!");
    3537                 : 
    3538                 :   // Dump all the frames and view to a a file
    3539                 :   char filename[256];
    3540                 :   sprintf(filename, "print_dump_layout_%d.txt", gDumpLOFileNameCnt++);
    3541                 :   FILE * fd = aFD?aFD:fopen(filename, "w");
    3542                 :   if (fd) {
    3543                 :     fprintf(fd, "Title: %s\n", aTitleStr?aTitleStr:"");
    3544                 :     fprintf(fd, "URL:   %s\n", aURLStr?aURLStr:"");
    3545                 :     fprintf(fd, "--------------- Frames ----------------\n");
    3546                 :     fprintf(fd, "--------------- Frames ----------------\n");
    3547                 :     nsRefPtr<nsRenderingContext> renderingContext;
    3548                 :     aDC->CreateRenderingContext(*getter_AddRefs(renderingContext));
    3549                 :     RootFrameList(aPresContext, fd, 0);
    3550                 :     //DumpFrames(fd, aPresContext, renderingContext, aRootFrame, 0);
    3551                 :     fprintf(fd, "---------------------------------------\n\n");
    3552                 :     fprintf(fd, "--------------- Views From Root Frame----------------\n");
    3553                 :     nsIView* v = aRootFrame->GetView();
    3554                 :     if (v) {
    3555                 :       v->List(fd);
    3556                 :     } else {
    3557                 :       printf("View is null!\n");
    3558                 :     }
    3559                 :     if (aDocShell) {
    3560                 :       fprintf(fd, "--------------- All Views ----------------\n");
    3561                 :       DumpViews(aDocShell, fd);
    3562                 :       fprintf(fd, "---------------------------------------\n\n");
    3563                 :     }
    3564                 :     if (aFD == nsnull) {
    3565                 :       fclose(fd);
    3566                 :     }
    3567                 :   }
    3568                 : }
    3569                 : 
    3570                 : //-------------------------------------------------------------
    3571                 : static void DumpPrintObjectsList(nsTArray<nsPrintObject*> * aDocList)
    3572                 : {
    3573                 :   if (!kPrintingLogMod || kPrintingLogMod->level != DUMP_LAYOUT_LEVEL) return;
    3574                 : 
    3575                 :   NS_ASSERTION(aDocList, "Pointer is null!");
    3576                 : 
    3577                 :   const char types[][3] = {"DC", "FR", "IF", "FS"};
    3578                 :   PR_PL(("Doc List\n***************************************************\n"));
    3579                 :   PR_PL(("T  P A H    PO    DocShell   Seq     Page      Root     Page#    Rect\n"));
    3580                 :   PRInt32 cnt = aDocList->Length();
    3581                 :   for (PRInt32 i=0;i<cnt;i++) {
    3582                 :     nsPrintObject* po = aDocList->ElementAt(i);
    3583                 :     NS_ASSERTION(po, "nsPrintObject can't be null!");
    3584                 :     nsIFrame* rootFrame = nsnull;
    3585                 :     if (po->mPresShell) {
    3586                 :       rootFrame = po->mPresShell->FrameManager()->GetRootFrame();
    3587                 :       while (rootFrame != nsnull) {
    3588                 :         nsIPageSequenceFrame * sqf = do_QueryFrame(rootFrame);
    3589                 :         if (sqf) {
    3590                 :           break;
    3591                 :         }
    3592                 :         rootFrame = rootFrame->GetFirstPrincipalChild();
    3593                 :       }
    3594                 :     }
    3595                 : 
    3596                 :     PR_PL(("%s %d %d %d %p %p %p %p %p   %d   %d,%d,%d,%d\n", types[po->mFrameType],
    3597                 :             po->IsPrintable(), po->mPrintAsIs, po->mHasBeenPrinted, po, po->mDocShell.get(), po->mSeqFrame,
    3598                 :             po->mPageFrame, rootFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height));
    3599                 :   }
    3600                 : }
    3601                 : 
    3602                 : //-------------------------------------------------------------
    3603                 : static void DumpPrintObjectsTree(nsPrintObject * aPO, int aLevel, FILE* aFD)
    3604                 : {
    3605                 :   if (!kPrintingLogMod || kPrintingLogMod->level != DUMP_LAYOUT_LEVEL) return;
    3606                 : 
    3607                 :   NS_ASSERTION(aPO, "Pointer is null!");
    3608                 : 
    3609                 :   FILE * fd = aFD?aFD:stdout;
    3610                 :   const char types[][3] = {"DC", "FR", "IF", "FS"};
    3611                 :   if (aLevel == 0) {
    3612                 :     fprintf(fd, "DocTree\n***************************************************\n");
    3613                 :     fprintf(fd, "T     PO    DocShell   Seq      Page     Page#    Rect\n");
    3614                 :   }
    3615                 :   PRInt32 cnt = aPO->mKids.Length();
    3616                 :   for (PRInt32 i=0;i<cnt;i++) {
    3617                 :     nsPrintObject* po = aPO->mKids.ElementAt(i);
    3618                 :     NS_ASSERTION(po, "nsPrintObject can't be null!");
    3619                 :     for (PRInt32 k=0;k<aLevel;k++) fprintf(fd, "  ");
    3620                 :     fprintf(fd, "%s %p %p %p %p %d %d,%d,%d,%d\n", types[po->mFrameType], po, po->mDocShell.get(), po->mSeqFrame,
    3621                 :            po->mPageFrame, po->mPageNum, po->mRect.x, po->mRect.y, po->mRect.width, po->mRect.height);
    3622                 :   }
    3623                 : }
    3624                 : 
    3625                 : //-------------------------------------------------------------
    3626                 : static void GetDocTitleAndURL(nsPrintObject* aPO, char *& aDocStr, char *& aURLStr)
    3627                 : {
    3628                 :   aDocStr = nsnull;
    3629                 :   aURLStr = nsnull;
    3630                 : 
    3631                 :   PRUnichar * docTitleStr;
    3632                 :   PRUnichar * docURLStr;
    3633                 :   nsPrintEngine::GetDisplayTitleAndURL(aPO,
    3634                 :                                             &docTitleStr, &docURLStr,
    3635                 :                                             nsPrintEngine::eDocTitleDefURLDoc); 
    3636                 : 
    3637                 :   if (docTitleStr) {
    3638                 :     nsAutoString strDocTitle(docTitleStr);
    3639                 :     aDocStr = ToNewCString(strDocTitle);
    3640                 :     nsMemory::Free(docTitleStr);
    3641                 :   }
    3642                 : 
    3643                 :   if (docURLStr) {
    3644                 :     nsAutoString strURL(docURLStr);
    3645                 :     aURLStr = ToNewCString(strURL);
    3646                 :     nsMemory::Free(docURLStr);
    3647                 :   }
    3648                 : }
    3649                 : 
    3650                 : //-------------------------------------------------------------
    3651                 : static void DumpPrintObjectsTreeLayout(nsPrintObject * aPO,
    3652                 :                                        nsDeviceContext * aDC,
    3653                 :                                        int aLevel, FILE * aFD)
    3654                 : {
    3655                 :   if (!kPrintingLogMod || kPrintingLogMod->level != DUMP_LAYOUT_LEVEL) return;
    3656                 : 
    3657                 :   NS_ASSERTION(aPO, "Pointer is null!");
    3658                 :   NS_ASSERTION(aDC, "Pointer is null!");
    3659                 : 
    3660                 :   const char types[][3] = {"DC", "FR", "IF", "FS"};
    3661                 :   FILE * fd = nsnull;
    3662                 :   if (aLevel == 0) {
    3663                 :     fd = fopen("tree_layout.txt", "w");
    3664                 :     fprintf(fd, "DocTree\n***************************************************\n");
    3665                 :     fprintf(fd, "***************************************************\n");
    3666                 :     fprintf(fd, "T     PO    DocShell   Seq      Page     Page#    Rect\n");
    3667                 :   } else {
    3668                 :     fd = aFD;
    3669                 :   }
    3670                 :   if (fd) {
    3671                 :     nsIFrame* rootFrame = nsnull;
    3672                 :     if (aPO->mPresShell) {
    3673                 :       rootFrame = aPO->mPresShell->FrameManager()->GetRootFrame();
    3674                 :     }
    3675                 :     for (PRInt32 k=0;k<aLevel;k++) fprintf(fd, "  ");
    3676                 :     fprintf(fd, "%s %p %p %p %p %d %d,%d,%d,%d\n", types[aPO->mFrameType], aPO, aPO->mDocShell.get(), aPO->mSeqFrame,
    3677                 :            aPO->mPageFrame, aPO->mPageNum, aPO->mRect.x, aPO->mRect.y, aPO->mRect.width, aPO->mRect.height);
    3678                 :     if (aPO->IsPrintable()) {
    3679                 :       char * docStr;
    3680                 :       char * urlStr;
    3681                 :       GetDocTitleAndURL(aPO, docStr, urlStr);
    3682                 :       DumpLayoutData(docStr, urlStr, aPO->mPresContext, aDC, rootFrame, aPO->mDocShell, fd);
    3683                 :       if (docStr) nsMemory::Free(docStr);
    3684                 :       if (urlStr) nsMemory::Free(urlStr);
    3685                 :     }
    3686                 :     fprintf(fd, "<***************************************************>\n");
    3687                 : 
    3688                 :     PRInt32 cnt = aPO->mKids.Length();
    3689                 :     for (PRInt32 i=0;i<cnt;i++) {
    3690                 :       nsPrintObject* po = aPO->mKids.ElementAt(i);
    3691                 :       NS_ASSERTION(po, "nsPrintObject can't be null!");
    3692                 :       DumpPrintObjectsTreeLayout(po, aDC, aLevel+1, fd);
    3693                 :     }
    3694                 :   }
    3695                 :   if (aLevel == 0 && fd) {
    3696                 :     fclose(fd);
    3697                 :   }
    3698                 : }
    3699                 : 
    3700                 : //-------------------------------------------------------------
    3701                 : static void DumpPrintObjectsListStart(const char * aStr, nsTArray<nsPrintObject*> * aDocList)
    3702                 : {
    3703                 :   if (!kPrintingLogMod || kPrintingLogMod->level != DUMP_LAYOUT_LEVEL) return;
    3704                 : 
    3705                 :   NS_ASSERTION(aStr, "Pointer is null!");
    3706                 :   NS_ASSERTION(aDocList, "Pointer is null!");
    3707                 : 
    3708                 :   PR_PL(("%s\n", aStr));
    3709                 :   DumpPrintObjectsList(aDocList);
    3710                 : }
    3711                 : 
    3712                 : #define DUMP_DOC_LIST(_title) DumpPrintObjectsListStart((_title), mPrt->mPrintDocList);
    3713                 : #define DUMP_DOC_TREE DumpPrintObjectsTree(mPrt->mPrintObject);
    3714                 : #define DUMP_DOC_TREELAYOUT DumpPrintObjectsTreeLayout(mPrt->mPrintObject, mPrt->mPrintDC);
    3715                 : 
    3716                 : #else
    3717                 : #define DUMP_DOC_LIST(_title)
    3718                 : #define DUMP_DOC_TREE
    3719                 : #define DUMP_DOC_TREELAYOUT
    3720                 : #endif
    3721                 : 
    3722                 : //---------------------------------------------------------------
    3723                 : //---------------------------------------------------------------
    3724                 : //-- End of debug helper routines
    3725                 : //---------------------------------------------------------------

Generated by: LCOV version 1.7