LCOV - app.info - layout/printing/nsPrintEngine.cpp

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-04-21 | 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            1396 : 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            4188 : }
        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