From 4d135d7b9bea917e6ec06a2df602b0658f489d1f Mon Sep 17 00:00:00 2001 From: "rods%netscape.com" Date: Tue, 12 Feb 2002 13:33:39 +0000 Subject: [PATCH] 1) It moves the BeginDocument to a earlier place in the call change 2) Fixes the negitive page range display problem 3) Improves performance by reducing the delay on pages not in the page range, i.e. before if you printed the 30th page out of 31 you had to wait 15 secs to get to the 30th page to print it. 4) Added AbortDocument, so now when Print jobs are cancelled we call AbortDocument and remove them from the print spooler 5) Fixed a couple of minor issue with Canceling and cancelling mail printings 6) selection was not printing correctly. The problem with selection was that the clip was not being set corrctly. Bug 115227 & 123181 r=dcone,sspitzer sr=attainasi git-svn-id: svn://10.0.0.236/trunk@114276 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsDocumentViewer.cpp | 384 +++++++++++------- mozilla/gfx/public/nsDeviceContext.h | 2 + mozilla/gfx/public/nsIDeviceContext.h | 7 + mozilla/gfx/src/mac/nsDeviceContextMac.cpp | 9 + mozilla/gfx/src/mac/nsDeviceContextMac.h | 1 + mozilla/gfx/src/mac/nsDeviceContextSpecX.cpp | 5 + mozilla/gfx/src/mac/nsDeviceContextSpecX.h | 2 + mozilla/gfx/src/os2/nsDeviceContextOS2.cpp | 58 +-- mozilla/gfx/src/os2/nsDeviceContextOS2.h | 2 + mozilla/gfx/src/photon/nsDeviceContextPh.cpp | 4 + mozilla/gfx/src/photon/nsDeviceContextPh.h | 1 + .../src/windows/nsDeviceContextSpecWin.cpp | 5 +- .../gfx/src/windows/nsDeviceContextWin.cpp | 15 + mozilla/gfx/src/windows/nsDeviceContextWin.h | 1 + mozilla/gfx/src/xprint/nsDeviceContextXP.cpp | 8 + mozilla/gfx/src/xprint/nsDeviceContextXP.h | 1 + mozilla/layout/base/nsDocumentViewer.cpp | 384 +++++++++++------- .../layout/base/public/nsIPageSequenceFrame.h | 2 + mozilla/layout/generic/nsIPageSequenceFrame.h | 2 + mozilla/layout/generic/nsObjectFrame.cpp | 4 +- mozilla/layout/generic/nsPageContentFrame.cpp | 19 +- mozilla/layout/generic/nsPageFrame.cpp | 74 ++-- .../layout/generic/nsSimplePageSequence.cpp | 58 ++- mozilla/layout/generic/nsSimplePageSequence.h | 4 + .../layout/html/base/src/nsObjectFrame.cpp | 4 +- .../html/base/src/nsPageContentFrame.cpp | 19 +- mozilla/layout/html/base/src/nsPageFrame.cpp | 74 ++-- .../html/base/src/nsSimplePageSequence.cpp | 58 ++- .../html/base/src/nsSimplePageSequence.h | 4 + .../mailnews/base/src/nsMsgPrintEngine.cpp | 4 + 30 files changed, 738 insertions(+), 477 deletions(-) diff --git a/mozilla/content/base/src/nsDocumentViewer.cpp b/mozilla/content/base/src/nsDocumentViewer.cpp index 9fff07953a8..8655787d505 100644 --- a/mozilla/content/base/src/nsDocumentViewer.cpp +++ b/mozilla/content/base/src/nsDocumentViewer.cpp @@ -344,6 +344,8 @@ public: nsRect mClipRect; PRUint16 mImgAnimationMode; + PRUnichar* mDocTitle; + PRUnichar* mDocURL; private: PrintObject& operator=(const PrintObject& aOther); // not implemented @@ -391,6 +393,7 @@ public: PRPackedBool mPrintingAsIsSubDoc; PRInt16 mPrintFrameType; PRPackedBool mOnStartSent; + PRPackedBool mIsAborted; PRInt32 mNumPrintableDocs; PRInt32 mNumDocsPrinted; PRInt32 mNumPrintablePages; @@ -457,11 +460,20 @@ public: nsresult CallChildren(CallChildFunc aFunc, void* aClosure); // Printing Methods - PRBool PrintPage(nsIPresContext* aPresContext,nsIPrintSettings* aPrintSettings,PrintObject* aPOect); + PRBool PrintPage(nsIPresContext* aPresContext,nsIPrintSettings* aPrintSettings,PrintObject* aPOect, PRBool& aInRange); PRBool DonePrintingPages(PrintObject* aPO); // helper method - static void GetWebShellTitleAndURL(nsIWebShell * aWebShell, nsIPrintSettings* aPrintSettings, PRUnichar** aTitle, PRUnichar** aURLStr); + static void GetWebShellTitleAndURL(nsIWebShell * aWebShell, PRUnichar** aTitle, PRUnichar** aURLStr); + + // This enum tells indicates what the default should be for the title + // if the title from the document is null + enum eDocTitleDefault {eDocTitleDefNone, eDocTitleDefBlank, eDocTitleDefDocument, eDocTitleDefURLDoc}; + static void GetDisplayTitleAndURL(PrintObject* aPO, + nsIPrintSettings* aPrintSettings, + PRUnichar** aTitle, + PRUnichar** aURLStr, + eDocTitleDefault aDefType = eDocTitleDefNone); protected: virtual ~DocumentViewerImpl(); @@ -515,7 +527,7 @@ private: void DoProgressForAsIsFrames(); void DoProgressForSeparateFrames(); void DoPrintProgress(PRBool aIsForPrinting); - void SetDocAndURLIntoProgress(nsIWebShell* aWebShell, nsIPrintProgressParams* aParams); + void SetDocAndURLIntoProgress(PrintObject* aPO, nsIPrintProgressParams* aParams); nsresult CheckForPrinters(nsIPrintOptions* aPrintOptions, nsIPrintSettings* aPrintSettings, PRUint32 aErrorCode, @@ -658,14 +670,14 @@ public: } - nsresult StartTimer() + nsresult StartTimer(PRBool aUseDelay = PR_TRUE) { nsresult result; mTimer = do_CreateInstance("@mozilla.org/timer;1", &result); if (NS_FAILED(result)) { NS_WARNING("unable to start the timer"); } else { - mTimer->Init(this, mDelay, NS_PRIORITY_NORMAL, NS_TYPE_ONE_SHOT); + mTimer->Init(this, aUseDelay?mDelay:0, NS_PRIORITY_NORMAL, NS_TYPE_ONE_SHOT); } return result; } @@ -680,7 +692,8 @@ public: // Check to see if we are done // donePrinting will be true if it completed successfully or // if the printing was cancelled - PRBool donePrinting = mDocViewer->PrintPage(mPresContext, mPrintSettings, mPrintObj); + PRBool inRange; + PRBool donePrinting = mDocViewer->PrintPage(mPresContext, mPrintSettings, mPrintObj, inRange); if (donePrinting) { // now clean up print or print the next webshell if (mDocViewer->DonePrintingPages(mPrintObj)) { @@ -690,7 +703,7 @@ public: Stop(); if (initNewTimer) { - nsresult result = StartTimer(); + nsresult result = StartTimer(inRange); if (NS_FAILED(result)) { donePrinting = PR_TRUE; // had a failure.. we are finished.. DocumentViewerImpl::mIsDoingPrinting = PR_FALSE; @@ -722,7 +735,7 @@ public: PRUint32 aDelay) { Init(aDocViewerImpl, aPresContext, aPrintSettings, aPO, aDelay); - return StartTimer(); + return StartTimer(PR_FALSE); } @@ -771,7 +784,9 @@ PrintData::PrintData() : mShowProgressDialog(PR_TRUE), mPrintDocList(nsnull), mIsIFrameSelected(PR_FALSE), mIsParentAFrameSet(PR_FALSE), mPrintingAsIsSubDoc(PR_FALSE), mPrintFrameType(nsIPrintSettings::kFramesAsIs), mOnStartSent(PR_FALSE), - mNumPrintableDocs(0), mNumDocsPrinted(0), mNumPrintablePages(0), mNumPagesPrinted(0) + mNumPrintableDocs(0), mNumDocsPrinted(0), mNumPrintablePages(0), mNumPagesPrinted(0), + mIsAborted(PR_FALSE) + { #ifdef DEBUG_PRINTING mDebugFD = fopen("printing.log", "w"); @@ -789,9 +804,17 @@ PrintData::~PrintData() #ifdef DEBUG_PRINTING fprintf(mDebugFD, "****************** End Document ************************\n"); #endif - nsresult rv = mPrintDC->EndDocument(); + PRBool isCancelled = PR_FALSE; + mPrintSettings->GetIsCancelled(&isCancelled); + + nsresult rv = NS_OK; + if (!isCancelled && !mIsAborted) { + rv = mPrintDC->EndDocument(); + } else { + rv = mPrintDC->AbortDocument(); + } if (NS_FAILED(rv)) { - DocumentViewerImpl::ShowPrintErrorDialog(rv, PR_TRUE); + DocumentViewerImpl::ShowPrintErrorDialog(rv); } } @@ -842,6 +865,8 @@ PrintData::DoOnProgressChange(nsVoidArray& aListeners, PRBool aDoStartStop, PRInt32 aFlag) { + if (aProgess == 0) return; + for (PRInt32 i=0;iDestroy(); + } + + if (mDocTitle) nsMemory::Free(mDocTitle); + if (mDocURL) nsMemory::Free(mDocURL); + } //------------------------------------------------------------------ @@ -1963,23 +1996,13 @@ static void DumpPrintObjectsTree(PrintObject * aPO, int aLevel= 0, FILE* aFD = n static void GetDocTitleAndURL(PrintObject* aPO, char *& aDocStr, char *& aURLStr) { - PRUnichar * docTitleStr; - PRUnichar * docURLStr; - nsAutoString strDocTitle; - nsAutoString strURL; - DocumentViewerImpl::GetWebShellTitleAndURL(aPO->mWebShell, nsnull, &docTitleStr, &docURLStr); - - if (!docTitleStr) { - if (docURLStr) { - docTitleStr = docURLStr; - docURLStr = nsnull; - } else { - docTitleStr = ToNewUnicode(NS_LITERAL_STRING("Document")); - } - } aDocStr = nsnull; aURLStr = nsnull; + PRUnichar * docTitleStr; + PRUnichar * docURLStr; + DocumentViewerImpl::GetDisplayTitleAndURL(aPO, nsnull, &docTitleStr, &docURLStr, DocumentViewerImpl::eDocTitleDefURLDoc); + if (docTitleStr) { nsAutoString strDocTitle(docTitleStr); aDocStr = ToNewCString(strDocTitle); @@ -2364,7 +2387,6 @@ DocumentViewerImpl::IsWebShellAFrameSet(nsIWebShell * aWebShell) //------------------------------------------------------- void DocumentViewerImpl::GetWebShellTitleAndURL(nsIWebShell * aWebShell, - nsIPrintSettings* aPrintSettings, PRUnichar** aTitle, PRUnichar** aURLStr) { @@ -2375,58 +2397,106 @@ DocumentViewerImpl::GetWebShellTitleAndURL(nsIWebShell * aWebShell, *aTitle = nsnull; *aURLStr = nsnull; + // now get the actual values if the PrintSettings didn't have any + nsCOMPtr docShell(do_QueryInterface(aWebShell)); + if (!docShell) return; + + nsCOMPtr presShell; + docShell->GetPresShell(getter_AddRefs(presShell)); + if (!presShell) return; + + nsCOMPtr doc; + presShell->GetDocument(getter_AddRefs(doc)); + if (!doc) return; + + const nsString* docTitle = doc->GetDocumentTitle(); + if (docTitle && !docTitle->IsEmpty()) { + *aTitle = ToNewUnicode(*docTitle); + } + + nsCOMPtr url; + doc->GetDocumentURL(getter_AddRefs(url)); + if (!url) return; + + nsXPIDLCString urlCStr; + url->GetSpec(getter_Copies(urlCStr)); + if (urlCStr.get()) { + *aURLStr = ToNewUnicode(urlCStr); + } +} + +//------------------------------------------------------- +// This will first use a Title and/or URL from the PrintSettings +// if one isn't set then it uses the one from the document +// then if not title is there we will make sure we send something back +// depending on the situation. +void +DocumentViewerImpl::GetDisplayTitleAndURL(PrintObject* aPO, + nsIPrintSettings* aPrintSettings, + PRUnichar** aTitle, + PRUnichar** aURLStr, + eDocTitleDefault aDefType) +{ + NS_ASSERTION(aPO, "Pointer is null!"); + NS_ASSERTION(aTitle, "Pointer is null!"); + NS_ASSERTION(aURLStr, "Pointer is null!"); + + *aTitle = nsnull; + *aURLStr = nsnull; + // First check to see if the PrintSettings has defined an alternate title // and use that if it did PRUnichar * docTitleStrPS = nsnull; PRUnichar * docURLStrPS = nsnull; - if (aPrintSettings != nsnull) { + if (aPrintSettings) { aPrintSettings->GetTitle(&docTitleStrPS); aPrintSettings->GetDocURL(&docURLStrPS); - if (docTitleStrPS != nsnull && nsCRT::strlen(docTitleStrPS) > 0) { + if (docTitleStrPS && nsCRT::strlen(docTitleStrPS) > 0) { *aTitle = docTitleStrPS; } - if (docURLStrPS != nsnull && nsCRT::strlen(docURLStrPS) > 0) { + if (docURLStrPS && nsCRT::strlen(docURLStrPS) > 0) { *aURLStr = docURLStrPS; } // short circut - if (docTitleStrPS != nsnull && docURLStrPS != nsnull) { + if (docTitleStrPS && docURLStrPS) { return; } } - // now get the actual values if the PrintSettings didn't have any - nsCOMPtr docShell(do_QueryInterface(aWebShell)); - if (docShell) { - nsCOMPtr presShell; - docShell->GetPresShell(getter_AddRefs(presShell)); - if (presShell) { - nsCOMPtr doc; - presShell->GetDocument(getter_AddRefs(doc)); - if (doc) { - if (docTitleStrPS == nsnull) { - const nsString* docTitle = doc->GetDocumentTitle(); - if (docTitle && !docTitle->IsEmpty()) { - *aTitle = ToNewUnicode(*docTitle); - } - } - - if (docURLStrPS == nsnull) { - nsCOMPtr url; - doc->GetDocumentURL(getter_AddRefs(url)); - if (url) { - nsXPIDLCString urlCStr; - url->GetSpec(getter_Copies(urlCStr)); - if (urlCStr.get()) { - *aURLStr = ToNewUnicode(urlCStr); - } - } - } - } + if (!docURLStrPS) { + if (aPO->mDocURL) { + *aURLStr = nsCRT::strdup(aPO->mDocURL); } } + + if (!docTitleStrPS) { + if (aPO->mDocTitle) { + *aTitle = nsCRT::strdup(aPO->mDocTitle); + } else { + switch (aDefType) { + case eDocTitleDefBlank: *aTitle = ToNewUnicode(NS_LITERAL_STRING("")); + break; + + case eDocTitleDefDocument: *aTitle = ToNewUnicode(NS_LITERAL_STRING("Mozilla Document")); + break; + + case eDocTitleDefURLDoc: + if (*aURLStr) { + *aTitle = nsCRT::strdup(*aURLStr); + } else { + *aTitle = ToNewUnicode(NS_LITERAL_STRING("Mozilla Document")); + } + break; + + default: + break; + } // switch + } + } + } @@ -2463,7 +2533,8 @@ DocumentViewerImpl::DonePrintingPages(PrintObject* aPO) PRBool DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, nsIPrintSettings* aPrintSettings, - PrintObject* aPO) + PrintObject* aPO, + PRBool& aInRange) { NS_ASSERTION(aPresContext, "Pointer is null!"); NS_ASSERTION(aPrintSettings, "Pointer is null!"); @@ -2472,23 +2543,24 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, PRINT_DEBUG_MSG1("-----------------------------------\n"); PRINT_DEBUG_MSG3("------ In DV::PrintPage PO: %p (%s)\n", aPO, gFrameTypesStr[aPO->mFrameType]); - if (aPrintSettings != nsnull) { - PRBool isCancelled; - aPrintSettings->GetIsCancelled(&isCancelled); - // DO NOT allow the print job to be cancelled if it is Print FrameAsIs - // because it is only printing one page. - if (isCancelled && mPrt->mPrintFrameType != nsIPrintSettings::kFramesAsIs) { - aPrintSettings->SetIsCancelled(PR_FALSE); - return PR_TRUE; + PRBool isCancelled = PR_FALSE; + + // Check setting to see if someone request it be cancelled (programatically) + aPrintSettings->GetIsCancelled(&isCancelled); + if (!isCancelled) { + // If not, see if the user has cancelled it + if (mPrt->mPrintProgress) { + mPrt->mPrintProgress->GetProcessCanceledByUser(&isCancelled); } } - if (mPrt->mPrintProgress) { - PRBool isCancelled; - mPrt->mPrintProgress->GetProcessCanceledByUser(&isCancelled); - // DO NOT allow the print job to be cancelled if it is Print FrameAsIs - // because it is only printing one page. - if (isCancelled && mPrt->mPrintFrameType != nsIPrintSettings::kFramesAsIs) { + + // DO NOT allow the print job to be cancelled if it is Print FrameAsIs + // because it is only printing one page. + if (isCancelled) { + if (mPrt->mPrintFrameType == nsIPrintSettings::kFramesAsIs) { aPrintSettings->SetIsCancelled(PR_FALSE); + } else { + aPrintSettings->SetIsCancelled(PR_TRUE); return PR_TRUE; } } @@ -2517,8 +2589,10 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, PRINT_DEBUG_MSG4("****** Printing Page %d printing from %d to page %d\n", pageNum, fromPage, toPage); donePrinting = pageNum >= toPage; - curPage = pageNum - fromPage; - endPage = toPage - fromPage; + aInRange = pageNum >= fromPage && pageNum <= toPage; + PRInt32 pageInc = pageNum - fromPage + 1; + curPage = pageInc >= 0?pageInc+1:0; + endPage = (toPage - fromPage)+1; } else { PRInt32 numPages; mPageSeqFrame->GetNumPages(&numPages); @@ -2526,8 +2600,9 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, PRINT_DEBUG_MSG3("****** Printing Page %d of %d page(s)\n", pageNum, numPages); donePrinting = pageNum >= numPages; - curPage = pageNum; + curPage = pageNum+1; endPage = numPages; + aInRange = PR_TRUE; } // NOTE: mPrt->mPrintFrameType gets set to "kFramesAsIs" when a @@ -2537,7 +2612,7 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, } else if (mPrt->mPrintFrameType != nsIPrintSettings::kFramesAsIs || mPrt->mPrintObject->mFrameType == eDoc && aPO == mPrt->mPrintObject) { - PrintData::DoOnProgressChange(mPrt->mPrintProgressListeners, curPage+1, endPage); + PrintData::DoOnProgressChange(mPrt->mPrintProgressListeners, curPage, endPage); } // Set Clip when Printing "AsIs" or @@ -2568,6 +2643,9 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, } //switch if (setClip) { + // Always set the clip x,y to zero because it isn't going to have any margins + aPO->mClipRect.x = 0; + aPO->mClipRect.y = 0; mPageSeqFrame->SetClipRect(aPO->mPresContext, &aPO->mClipRect); } @@ -2575,9 +2653,15 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, // if a print job was cancelled externally, an EndPage or BeginPage may // fail and the failure is passed back here. // Returning PR_TRUE means we are done printing. + // + // When rv == NS_ERROR_ABORT, it means we want out of the + // print job without displaying any error messages nsresult rv = mPageSeqFrame->PrintNextPage(aPresContext); if (NS_FAILED(rv)) { - ShowPrintErrorDialog(rv, PR_TRUE); + if (rv != NS_ERROR_ABORT) { + ShowPrintErrorDialog(rv); + mPrt->mIsAborted = PR_TRUE; + } return PR_TRUE; } @@ -2653,6 +2737,9 @@ DocumentViewerImpl::BuildDocTree(nsIDocShellTreeNode * aParentNode, NS_ASSERTION(aDocList, "Pointer is null!"); NS_ASSERTION(aPO, "Pointer is null!"); + // Get the Doc and Title String + GetWebShellTitleAndURL(aPO->mWebShell, &aPO->mDocTitle, &aPO->mDocURL); + PRInt32 childWebshellCount; aParentNode->GetChildCount(&childWebshellCount); if (childWebshellCount > 0) { @@ -3123,7 +3210,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO) if (printRangeType == nsIPrintSettings::kRangeSelection && IsThereARangeSelection(domWinIntl)) { - height = 0x0FFFFFFF; + height = NS_UNCONSTRAINEDSIZE; } nsRect tbounds = nsRect(0, 0, width, height); @@ -3630,40 +3717,8 @@ DocumentViewerImpl::SetupToPrintContent(nsIWebShell* aParent, // it will check to see if there are more webshells to be printed and // then PrintDocContent will be called again. - nsCOMPtr webContainer(do_QueryInterface(mContainer)); - PRUnichar * docTitleStr; - PRUnichar * docURLStr; - GetWebShellTitleAndURL(webContainer, mPrt->mPrintSettings, &docTitleStr, &docURLStr); - - if (!docTitleStr) { - if (docURLStr) { - docTitleStr = docURLStr; - docURLStr = nsnull; - } else { - docTitleStr = ToNewUnicode(NS_LITERAL_STRING("Document")); - } - } - nsresult rv = NS_OK; if (mIsDoingPrinting) { - // BeginDocument may pass back a FAILURE code - // i.e. On Windows, if you are printing to a file and hit "Cancel" - // to the "File Name" dialog, this comes back as an error - // Don't start printing when regression test are executed - rv = mPrt->mDebugFilePtr ? NS_OK: mPrt->mPrintDC->BeginDocument(docTitleStr); - PRINT_DEBUG_MSG1("****************** Begin Document ************************\n"); - - if (docTitleStr != nsnull) { - nsMemory::Free(docTitleStr); - } - if (docURLStr != nsnull) { - nsMemory::Free(docURLStr); - } - - if (NS_FAILED(rv)) { - return rv; - } - PrintDocContent(mPrt->mPrintObject, rv); // ignore return value } @@ -3688,7 +3743,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a NS_ASSERTION(webShell, "The WebShell can't be NULL!"); if (mPrt->mPrintProgressParams) { - SetDocAndURLIntoProgress(aPO->mWebShell, mPrt->mPrintProgressParams); + SetDocAndURLIntoProgress(aPO, mPrt->mPrintProgressParams); } if (webShell != nsnull) { @@ -3835,12 +3890,10 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a if (!skipSetTitle) { PRUnichar * docTitleStr; PRUnichar * docURLStr; - GetWebShellTitleAndURL(webShell, mPrt->mPrintSettings, &docTitleStr, &docURLStr); - - if (!docTitleStr) { - docTitleStr = ToNewUnicode(NS_LITERAL_STRING("")); - } + GetDisplayTitleAndURL(aPO, mPrt->mPrintSettings, &docTitleStr, &docURLStr, eDocTitleDefBlank); + // Set them down into the PrintOptions so + // they can used by the DeviceContext if (docTitleStr) { mPrt->mPrintOptions->SetTitle(docTitleStr); nsMemory::Free(docTitleStr); @@ -3892,12 +3945,25 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a nsRect areaRect; nsIFrame * areaFrame = FindFrameByType(poPresContext, startFrame, nsHTMLAtoms::body, rect, areaRect); if (areaFrame) { - startRect.y -= margin.top; + nsRect areaRect; + areaFrame->GetRect(areaRect); + startRect.y -= margin.top+areaRect.y; endRect.y -= margin.top; areaRect.y -= startRect.y; areaRect.x -= margin.left; // XXX This is temporary fix for printing more than one page of a selection pageSequence->SetSelectionHeight(startRect.y, endRect.y+endRect.height-startRect.y); + + // calc total pages by getting calculating the selection's height + // and then dividing it by how page content frames will fit. + nscoord selectionHgt = endRect.y + endRect.height - startRect.y; + PRInt32 pageWidth, pageHeight; + mPrt->mPrintDocDC->GetDeviceSurfaceDimensions(pageWidth, pageHeight); + nsMargin margin(0,0,0,0); + mPrt->mPrintSettings->GetMarginInTwips(margin); + pageHeight -= margin.top + margin.bottom; + PRInt32 totalPages = PRInt32((float(selectionHgt) / float(pageHeight))+0.99); + pageSequence->SetTotalNumPages(totalPages); } } } @@ -3941,7 +4007,8 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a DoProgressForAsIsFrames(); // Print the page synchronously PRINT_DEBUG_MSG3("Async Print of PO: %p (%s) \n", aPO, gFrameTypesStr[aPO->mFrameType]); - aDonePrinting = PrintPage(poPresContext, mPrt->mPrintSettings, aPO); + PRBool inRange; + aDonePrinting = PrintPage(poPresContext, mPrt->mPrintSettings, aPO, inRange); } } } else { @@ -5261,7 +5328,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) /* cleanup done, let's fire-up an error dialog to notify the user * what went wrong... */ - ShowPrintErrorDialog(rv); + ShowPrintErrorDialog(rv, PR_FALSE); TurnScriptingOn(PR_TRUE); mIsCreatingPrintPreview = PR_FALSE; mIsDoingPrintPreview = PR_FALSE; @@ -5287,22 +5354,22 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) void -DocumentViewerImpl::SetDocAndURLIntoProgress(nsIWebShell* aWebShell, - nsIPrintProgressParams* aParams) +DocumentViewerImpl::SetDocAndURLIntoProgress(PrintObject* aPO, nsIPrintProgressParams* aParams) { - NS_ASSERTION(aWebShell, "Must have vaild nsIWebShell"); + NS_ASSERTION(aPO, "Must have vaild PrintObject"); NS_ASSERTION(aParams, "Must have vaild nsIPrintProgressParams"); - if (aWebShell == nsnull || aParams == nsnull) { + + if (!aPO || !aPO->mWebShell || !aParams) { return; } const PRInt32 kTitleLength = 64; PRUnichar * docTitleStr; PRUnichar * docURLStr; - GetWebShellTitleAndURL(aWebShell, mPrt->mPrintSettings, &docTitleStr, &docURLStr); + GetDisplayTitleAndURL(aPO, mPrt->mPrintSettings, &docTitleStr, &docURLStr, eDocTitleDefDocument); // Make sure the URLS don't get too long for the progress dialog - if (docURLStr != nsnull && nsCRT::strlen(docURLStr) > kTitleLength) { + if (docURLStr && nsCRT::strlen(docURLStr) > kTitleLength) { PRUnichar * ptr = &docURLStr[nsCRT::strlen(docURLStr)-kTitleLength+3]; nsAutoString newURLStr; newURLStr.AppendWithConversion("..."); @@ -5342,7 +5409,7 @@ DocumentViewerImpl::DoPrintProgress(PRBool aIsForPrinting) nsCOMPtr params; rv = prtProgressParams->QueryInterface(NS_GET_IID(nsIPrintProgressParams), (void**)getter_AddRefs(mPrt->mPrintProgressParams)); if (NS_SUCCEEDED(rv) && mPrt->mPrintProgressParams) { - SetDocAndURLIntoProgress(mPrt->mPrintObject->mWebShell, mPrt->mPrintProgressParams); + SetDocAndURLIntoProgress(mPrt->mPrintObject, mPrt->mPrintProgressParams); nsCOMPtr wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1")); if (wwatch) { @@ -5452,6 +5519,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, return NS_ERROR_FAILURE; } } + mPrt->mPrintSettings->SetIsCancelled(PR_FALSE); // Let's print ... mIsDoingPrinting = PR_TRUE; @@ -5688,28 +5756,41 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, } } - DoPrintProgress(PR_TRUE); + PRUnichar * docTitleStr; + PRUnichar * docURLStr; + GetDisplayTitleAndURL(mPrt->mPrintObject, mPrt->mPrintSettings, &docTitleStr, &docURLStr, eDocTitleDefURLDoc); - // Print listener setup... - if (mPrt != nsnull) { - mPrt->OnStartPrinting(); - } + // BeginDocument may pass back a FAILURE code + // i.e. On Windows, if you are printing to a file and hit "Cancel" + // to the "File Name" dialog, this comes back as an error + // Don't start printing when regression test are executed + rv = mPrt->mDebugFilePtr ? NS_OK: mPrt->mPrintDC->BeginDocument(docTitleStr); + PRINT_DEBUG_MSG1("****************** Begin Document ************************\n"); - // - // The mIsPrinting flag is set when the ImageGroup observer is - // notified that images must be loaded as a result of the - // InitialReflow... - // - if(!mIsPrinting || (mPrt->mDebugFilePtr != nsnull)) { - rv = DocumentReadyForPrinting(); -#ifdef DEBUG_dcone - printf("PRINT JOB ENDING, OBSERVER WAS NOT CALLED\n"); -#endif - } else { - // use the observer mechanism to finish the printing -#ifdef DEBUG_dcone - printf("PRINTING OBSERVER STARTED\n"); -#endif + if (docTitleStr) nsMemory::Free(docTitleStr); + if (docURLStr) nsMemory::Free(docURLStr); + + if (NS_SUCCEEDED(rv)) { + + DoPrintProgress(PR_TRUE); + + // Print listener setup... + if (mPrt != nsnull) { + mPrt->OnStartPrinting(); + } + + // + // The mIsPrinting flag is set when the ImageGroup observer is + // notified that images must be loaded as a result of the + // InitialReflow... + // + if(!mIsPrinting || mPrt->mDebugFilePtr) { + rv = DocumentReadyForPrinting(); + PRINT_DEBUG_MSG1("PRINT JOB ENDING, OBSERVER WAS NOT CALLED\n"); + } else { + // use the observer mechanism to finish the printing + PRINT_DEBUG_MSG1("PRINTING OBSERVER STARTED\n"); + } } } } @@ -5737,6 +5818,9 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, /* cleanup done, let's fire-up an error dialog to notify the user * what went wrong... + * + * When rv == NS_ERROR_ABORT, it means we want out of the + * print job without displaying any error messages */ if (rv != NS_ERROR_ABORT) { ShowPrintErrorDialog(rv); @@ -6747,7 +6831,7 @@ DocumentViewerImpl::EnumerateDocumentNames(PRUint32* aCount, NS_ASSERTION(po, "PrintObject can't be null!"); PRUnichar * docTitleStr; PRUnichar * docURLStr; - GetWebShellTitleAndURL(po->mWebShell, nsnull, &docTitleStr, &docURLStr); + GetWebShellTitleAndURL(po->mWebShell, &docTitleStr, &docURLStr); // Use the URL if the doc is empty if (!docTitleStr || !*docTitleStr) { diff --git a/mozilla/gfx/public/nsDeviceContext.h b/mozilla/gfx/public/nsDeviceContext.h index 3c62b5bbb94..8e3de7e0166 100644 --- a/mozilla/gfx/public/nsDeviceContext.h +++ b/mozilla/gfx/public/nsDeviceContext.h @@ -136,6 +136,8 @@ public: NS_IMETHOD GetPaletteInfo(nsPaletteInfo& aPaletteInfo); + NS_IMETHOD AbortDocument(void) { return NS_OK; } + #ifdef NS_PRINT_PREVIEW NS_IMETHOD SetAltDevice(nsIDeviceContext* aAltDC); NS_IMETHOD GetAltDevice(nsIDeviceContext** aAltDC) { *aAltDC = mAltDC.get(); NS_IF_ADDREF(*aAltDC); return NS_OK;} diff --git a/mozilla/gfx/public/nsIDeviceContext.h b/mozilla/gfx/public/nsIDeviceContext.h index 9ef2048fc29..830c5835fd8 100644 --- a/mozilla/gfx/public/nsIDeviceContext.h +++ b/mozilla/gfx/public/nsIDeviceContext.h @@ -473,6 +473,13 @@ public: */ NS_IMETHOD EndDocument(void) = 0; + /** + * Inform the output device that output of a document is being aborted. + * Must be matched 1:1 with BeginDocument() + * @return error status + */ + NS_IMETHOD AbortDocument(void) = 0; + /** * Inform the output device that output of a page is beginning * Used for print related device contexts. Must be matched 1:1 with diff --git a/mozilla/gfx/src/mac/nsDeviceContextMac.cpp b/mozilla/gfx/src/mac/nsDeviceContextMac.cpp index 27c9c744607..b9ea14eef42 100644 --- a/mozilla/gfx/src/mac/nsDeviceContextMac.cpp +++ b/mozilla/gfx/src/mac/nsDeviceContextMac.cpp @@ -692,6 +692,15 @@ NS_IMETHODIMP nsDeviceContextMac::EndDocument(void) #endif } +/** --------------------------------------------------- + * See documentation in nsIDeviceContext.h + * @update 12/9/98 dwc + */ +NS_IMETHODIMP nsDeviceContextMac::AbortDocument(void) +{ + return EndDocument(); +} + /** --------------------------------------------------- * See documentation in nsIDeviceContext.h diff --git a/mozilla/gfx/src/mac/nsDeviceContextMac.h b/mozilla/gfx/src/mac/nsDeviceContextMac.h index f5f08e854a5..c4db92f3e64 100644 --- a/mozilla/gfx/src/mac/nsDeviceContextMac.h +++ b/mozilla/gfx/src/mac/nsDeviceContextMac.h @@ -81,6 +81,7 @@ public: NS_IMETHOD BeginDocument(PRUnichar * aTitle); NS_IMETHOD EndDocument(void); + NS_IMETHOD AbortDocument(void); NS_IMETHOD BeginPage(void); NS_IMETHOD EndPage(void); diff --git a/mozilla/gfx/src/mac/nsDeviceContextSpecX.cpp b/mozilla/gfx/src/mac/nsDeviceContextSpecX.cpp index 57ebe43cc9d..b763aae0cae 100644 --- a/mozilla/gfx/src/mac/nsDeviceContextSpecX.cpp +++ b/mozilla/gfx/src/mac/nsDeviceContextSpecX.cpp @@ -169,6 +169,11 @@ NS_IMETHODIMP nsDeviceContextSpecX::EndDocument() return NS_OK; } +NS_IMETHODIMP nsDeviceContextSpecX::AbortDocument() +{ + return EndDocument(); +} + NS_IMETHODIMP nsDeviceContextSpecX::BeginPage() { // see http://devworld.apple.com/techpubs/carbon/graphics/CarbonPrintingManager/Carbon_Printing_Manager/Functions/PMSessionBeginPage.html diff --git a/mozilla/gfx/src/mac/nsDeviceContextSpecX.h b/mozilla/gfx/src/mac/nsDeviceContextSpecX.h index ea60f12a834..762596b22b2 100644 --- a/mozilla/gfx/src/mac/nsDeviceContextSpecX.h +++ b/mozilla/gfx/src/mac/nsDeviceContextSpecX.h @@ -88,6 +88,8 @@ public: NS_IMETHOD EndDocument(); + NS_IMETHOD AbortDocument(); + NS_IMETHOD BeginPage(); NS_IMETHOD EndPage(); diff --git a/mozilla/gfx/src/os2/nsDeviceContextOS2.cpp b/mozilla/gfx/src/os2/nsDeviceContextOS2.cpp index 617bda8bd65..eb1c44a2aef 100644 --- a/mozilla/gfx/src/os2/nsDeviceContextOS2.cpp +++ b/mozilla/gfx/src/os2/nsDeviceContextOS2.cpp @@ -68,6 +68,7 @@ nsDeviceContextOS2 :: nsDeviceContextOS2() mCachedClientRect = PR_FALSE; mCachedFullRect = PR_FALSE; mSupportsRasterFonts = PR_FALSE; + mPrintingStarted = PR_FALSE; mPelsPerMeter = 0; #ifdef XP_OS2 mPrintState = nsPrintState_ePreBeginDoc; @@ -164,10 +165,6 @@ nsresult nsDeviceContextOS2::Init( nsNativeDeviceContext aContext, printf( "mPixelScale = %f\n", mPixelScale); #endif - // We need to begin a document now, because the client is entitled at - // this point to do stuff like create fonts, which required the PS to - // be associated with a DC which has been DEVESC_STARTDOC'd. - BeginDocument(nsnull); #endif return NS_OK; @@ -901,19 +898,12 @@ nsresult nsDeviceContextOS2::BeginDocument(PRUnichar * aTitle) PSZ pszDocName = title != nsnull?title:"Mozilla Document"; - long lResult; - - // ENDDOC first so we work on Lexmark printer drivers - long lOutCount = 2; - USHORT usJobID = 0; - lResult = ::DevEscape(mPrintDC, DEVESC_ENDDOC, - 0, NULL, - &lOutCount, (PBYTE)&usJobID); - long lDummy = 0; - lResult = ::DevEscape(mPrintDC, DEVESC_STARTDOC, - strlen(pszDocName) + 1, pszDocName, - &lDummy, NULL); + long lResult = ::DevEscape(mPrintDC, DEVESC_STARTDOC, + strlen(pszDocName) + 1, pszDocName, + &lDummy, NULL); + + mPrintingStarted = PR_TRUE; if (lResult == DEV_OK) rv = NS_OK; @@ -946,16 +936,32 @@ nsresult nsDeviceContextOS2::EndDocument() return NS_OK; } -nsresult nsDeviceContextOS2::BeginPage() -{ - return NS_OK; -} - -nsresult nsDeviceContextOS2::EndPage() +nsresult nsDeviceContextOS2::AbortDocument() { if (NULL != mPrintDC) { + long ldummy = 0; + long lResult = ::DevEscape(mPrintDC, DEVESC_ABORTDOC, 0, NULL, + &ldummy, NULL); + if (lResult == DEV_OK) + return NS_OK; + else + return NS_ERROR_ABORT; + } + return NS_OK; +} + + +nsresult nsDeviceContextOS2::BeginPage() +{ + if (mPrintingStarted) { + mPrintingStarted = PR_FALSE; + return NS_OK; + } + + if (NULL != mPrintDC) + { long lDummy = 0; long lResult = ::DevEscape(mPrintDC, DEVESC_NEWFRAME, 0, NULL, &lDummy, NULL); @@ -963,10 +969,16 @@ nsresult nsDeviceContextOS2::EndPage() if (lResult == DEV_OK) return NS_OK; else - return NS_ERROR_GFX_PRINTER_ENDPAGE; + return NS_ERROR_GFX_PRINTER_STARTPAGE; } return NS_OK; + +} + +nsresult nsDeviceContextOS2::EndPage() +{ + return NS_OK; } char* diff --git a/mozilla/gfx/src/os2/nsDeviceContextOS2.h b/mozilla/gfx/src/os2/nsDeviceContextOS2.h index e8ddef19f6d..f290f7f75a1 100644 --- a/mozilla/gfx/src/os2/nsDeviceContextOS2.h +++ b/mozilla/gfx/src/os2/nsDeviceContextOS2.h @@ -90,6 +90,7 @@ public: NS_IMETHOD BeginDocument(PRUnichar * aTitle); NS_IMETHOD EndDocument(void); + NS_IMETHOD AbortDocument(void); NS_IMETHOD BeginPage(void); NS_IMETHOD EndPage(void); @@ -107,6 +108,7 @@ protected: PRBool mCachedClientRect; PRBool mCachedFullRect; + PRBool mPrintingStarted; nsDrawingSurface mSurface; PRUint32 mDepth; // bit depth of device diff --git a/mozilla/gfx/src/photon/nsDeviceContextPh.cpp b/mozilla/gfx/src/photon/nsDeviceContextPh.cpp index 0168f58f22e..3c1d3aaf251 100644 --- a/mozilla/gfx/src/photon/nsDeviceContextPh.cpp +++ b/mozilla/gfx/src/photon/nsDeviceContextPh.cpp @@ -456,6 +456,10 @@ NS_IMETHODIMP nsDeviceContextPh :: EndDocument( void ) { return NS_OK; } +NS_IMETHODIMP nsDeviceContextPh :: AbortDocument( void ) { + return EndDocument(); + } + NS_IMETHODIMP nsDeviceContextPh :: BeginPage( void ) { PpPrintContext_t *pc = ((nsDeviceContextSpecPh *)mSpec)->GetPrintContext(); if( !mIsPrintingStart ) PpPrintNewPage( pc ); diff --git a/mozilla/gfx/src/photon/nsDeviceContextPh.h b/mozilla/gfx/src/photon/nsDeviceContextPh.h index 1cd7c907241..f975571e822 100644 --- a/mozilla/gfx/src/photon/nsDeviceContextPh.h +++ b/mozilla/gfx/src/photon/nsDeviceContextPh.h @@ -86,6 +86,7 @@ public: NS_IMETHOD BeginDocument(PRUnichar *t); NS_IMETHOD EndDocument(void); + NS_IMETHOD AbortDocument(void); NS_IMETHOD BeginPage(void); NS_IMETHOD EndPage(void); diff --git a/mozilla/gfx/src/windows/nsDeviceContextSpecWin.cpp b/mozilla/gfx/src/windows/nsDeviceContextSpecWin.cpp index 9ffa9fe561c..2b95c9edcc5 100644 --- a/mozilla/gfx/src/windows/nsDeviceContextSpecWin.cpp +++ b/mozilla/gfx/src/windows/nsDeviceContextSpecWin.cpp @@ -1651,10 +1651,7 @@ nsDeviceContextSpecWin :: ShowXPPrintDialog(PRBool aQuiet) if (printerName != nsnull) { // Gets DEVMODE, Device and Driver Names - rv = GetDataFromPrinter(printerName); - - // Set into DevMode Paper Size and Orientation here - SetupPaperInfoFromSettings(); + rv = GetDataFromPrinter(printerName, mPrintSettings); nsMemory::Free(printerName); } else { diff --git a/mozilla/gfx/src/windows/nsDeviceContextWin.cpp b/mozilla/gfx/src/windows/nsDeviceContextWin.cpp index 09bd327d464..2d529cc8315 100644 --- a/mozilla/gfx/src/windows/nsDeviceContextWin.cpp +++ b/mozilla/gfx/src/windows/nsDeviceContextWin.cpp @@ -1073,6 +1073,21 @@ NS_IMETHODIMP nsDeviceContextWin :: EndDocument(void) return NS_OK; } +NS_IMETHODIMP nsDeviceContextWin :: AbortDocument(void) +{ + if (NULL != mDC) + { + if (::AbortDoc(mDC) > 0) { + return NS_OK; + } else { + DISPLAY_LAST_ERROR + return NS_ERROR_ABORT; + } + } + + return NS_OK; +} + NS_IMETHODIMP nsDeviceContextWin :: BeginPage(void) { if (NULL != mDC) diff --git a/mozilla/gfx/src/windows/nsDeviceContextWin.h b/mozilla/gfx/src/windows/nsDeviceContextWin.h index bd81ad3c80b..90895b4c119 100644 --- a/mozilla/gfx/src/windows/nsDeviceContextWin.h +++ b/mozilla/gfx/src/windows/nsDeviceContextWin.h @@ -86,6 +86,7 @@ public: NS_IMETHOD BeginDocument(PRUnichar * aTitle); NS_IMETHOD EndDocument(void); + NS_IMETHOD AbortDocument(void); NS_IMETHOD BeginPage(void); NS_IMETHOD EndPage(void); diff --git a/mozilla/gfx/src/xprint/nsDeviceContextXP.cpp b/mozilla/gfx/src/xprint/nsDeviceContextXP.cpp index f5eb70d37f6..1747802c70c 100644 --- a/mozilla/gfx/src/xprint/nsDeviceContextXP.cpp +++ b/mozilla/gfx/src/xprint/nsDeviceContextXP.cpp @@ -299,6 +299,14 @@ NS_IMETHODIMP nsDeviceContextXp::EndDocument(void) return rv; } +/** --------------------------------------------------- + * See documentation in nsIDeviceContext.h + */ +NS_IMETHODIMP nsDeviceContextXp::AbortDocument(void) +{ + return EndDocument(); +} + /** --------------------------------------------------- * See documentation in nsIDeviceContext.h */ diff --git a/mozilla/gfx/src/xprint/nsDeviceContextXP.h b/mozilla/gfx/src/xprint/nsDeviceContextXP.h index 0ec54f9d079..53113cd1350 100644 --- a/mozilla/gfx/src/xprint/nsDeviceContextXP.h +++ b/mozilla/gfx/src/xprint/nsDeviceContextXP.h @@ -82,6 +82,7 @@ public: NS_IMETHOD GetSystemFont(nsSystemFontID anID, nsFont *aFont) const; NS_IMETHOD BeginDocument(PRUnichar * aTitle); NS_IMETHOD EndDocument(void); + NS_IMETHOD AbortDocument(void); NS_IMETHOD BeginPage(void); NS_IMETHOD EndPage(void); diff --git a/mozilla/layout/base/nsDocumentViewer.cpp b/mozilla/layout/base/nsDocumentViewer.cpp index 9fff07953a8..8655787d505 100644 --- a/mozilla/layout/base/nsDocumentViewer.cpp +++ b/mozilla/layout/base/nsDocumentViewer.cpp @@ -344,6 +344,8 @@ public: nsRect mClipRect; PRUint16 mImgAnimationMode; + PRUnichar* mDocTitle; + PRUnichar* mDocURL; private: PrintObject& operator=(const PrintObject& aOther); // not implemented @@ -391,6 +393,7 @@ public: PRPackedBool mPrintingAsIsSubDoc; PRInt16 mPrintFrameType; PRPackedBool mOnStartSent; + PRPackedBool mIsAborted; PRInt32 mNumPrintableDocs; PRInt32 mNumDocsPrinted; PRInt32 mNumPrintablePages; @@ -457,11 +460,20 @@ public: nsresult CallChildren(CallChildFunc aFunc, void* aClosure); // Printing Methods - PRBool PrintPage(nsIPresContext* aPresContext,nsIPrintSettings* aPrintSettings,PrintObject* aPOect); + PRBool PrintPage(nsIPresContext* aPresContext,nsIPrintSettings* aPrintSettings,PrintObject* aPOect, PRBool& aInRange); PRBool DonePrintingPages(PrintObject* aPO); // helper method - static void GetWebShellTitleAndURL(nsIWebShell * aWebShell, nsIPrintSettings* aPrintSettings, PRUnichar** aTitle, PRUnichar** aURLStr); + static void GetWebShellTitleAndURL(nsIWebShell * aWebShell, PRUnichar** aTitle, PRUnichar** aURLStr); + + // This enum tells indicates what the default should be for the title + // if the title from the document is null + enum eDocTitleDefault {eDocTitleDefNone, eDocTitleDefBlank, eDocTitleDefDocument, eDocTitleDefURLDoc}; + static void GetDisplayTitleAndURL(PrintObject* aPO, + nsIPrintSettings* aPrintSettings, + PRUnichar** aTitle, + PRUnichar** aURLStr, + eDocTitleDefault aDefType = eDocTitleDefNone); protected: virtual ~DocumentViewerImpl(); @@ -515,7 +527,7 @@ private: void DoProgressForAsIsFrames(); void DoProgressForSeparateFrames(); void DoPrintProgress(PRBool aIsForPrinting); - void SetDocAndURLIntoProgress(nsIWebShell* aWebShell, nsIPrintProgressParams* aParams); + void SetDocAndURLIntoProgress(PrintObject* aPO, nsIPrintProgressParams* aParams); nsresult CheckForPrinters(nsIPrintOptions* aPrintOptions, nsIPrintSettings* aPrintSettings, PRUint32 aErrorCode, @@ -658,14 +670,14 @@ public: } - nsresult StartTimer() + nsresult StartTimer(PRBool aUseDelay = PR_TRUE) { nsresult result; mTimer = do_CreateInstance("@mozilla.org/timer;1", &result); if (NS_FAILED(result)) { NS_WARNING("unable to start the timer"); } else { - mTimer->Init(this, mDelay, NS_PRIORITY_NORMAL, NS_TYPE_ONE_SHOT); + mTimer->Init(this, aUseDelay?mDelay:0, NS_PRIORITY_NORMAL, NS_TYPE_ONE_SHOT); } return result; } @@ -680,7 +692,8 @@ public: // Check to see if we are done // donePrinting will be true if it completed successfully or // if the printing was cancelled - PRBool donePrinting = mDocViewer->PrintPage(mPresContext, mPrintSettings, mPrintObj); + PRBool inRange; + PRBool donePrinting = mDocViewer->PrintPage(mPresContext, mPrintSettings, mPrintObj, inRange); if (donePrinting) { // now clean up print or print the next webshell if (mDocViewer->DonePrintingPages(mPrintObj)) { @@ -690,7 +703,7 @@ public: Stop(); if (initNewTimer) { - nsresult result = StartTimer(); + nsresult result = StartTimer(inRange); if (NS_FAILED(result)) { donePrinting = PR_TRUE; // had a failure.. we are finished.. DocumentViewerImpl::mIsDoingPrinting = PR_FALSE; @@ -722,7 +735,7 @@ public: PRUint32 aDelay) { Init(aDocViewerImpl, aPresContext, aPrintSettings, aPO, aDelay); - return StartTimer(); + return StartTimer(PR_FALSE); } @@ -771,7 +784,9 @@ PrintData::PrintData() : mShowProgressDialog(PR_TRUE), mPrintDocList(nsnull), mIsIFrameSelected(PR_FALSE), mIsParentAFrameSet(PR_FALSE), mPrintingAsIsSubDoc(PR_FALSE), mPrintFrameType(nsIPrintSettings::kFramesAsIs), mOnStartSent(PR_FALSE), - mNumPrintableDocs(0), mNumDocsPrinted(0), mNumPrintablePages(0), mNumPagesPrinted(0) + mNumPrintableDocs(0), mNumDocsPrinted(0), mNumPrintablePages(0), mNumPagesPrinted(0), + mIsAborted(PR_FALSE) + { #ifdef DEBUG_PRINTING mDebugFD = fopen("printing.log", "w"); @@ -789,9 +804,17 @@ PrintData::~PrintData() #ifdef DEBUG_PRINTING fprintf(mDebugFD, "****************** End Document ************************\n"); #endif - nsresult rv = mPrintDC->EndDocument(); + PRBool isCancelled = PR_FALSE; + mPrintSettings->GetIsCancelled(&isCancelled); + + nsresult rv = NS_OK; + if (!isCancelled && !mIsAborted) { + rv = mPrintDC->EndDocument(); + } else { + rv = mPrintDC->AbortDocument(); + } if (NS_FAILED(rv)) { - DocumentViewerImpl::ShowPrintErrorDialog(rv, PR_TRUE); + DocumentViewerImpl::ShowPrintErrorDialog(rv); } } @@ -842,6 +865,8 @@ PrintData::DoOnProgressChange(nsVoidArray& aListeners, PRBool aDoStartStop, PRInt32 aFlag) { + if (aProgess == 0) return; + for (PRInt32 i=0;iDestroy(); + } + + if (mDocTitle) nsMemory::Free(mDocTitle); + if (mDocURL) nsMemory::Free(mDocURL); + } //------------------------------------------------------------------ @@ -1963,23 +1996,13 @@ static void DumpPrintObjectsTree(PrintObject * aPO, int aLevel= 0, FILE* aFD = n static void GetDocTitleAndURL(PrintObject* aPO, char *& aDocStr, char *& aURLStr) { - PRUnichar * docTitleStr; - PRUnichar * docURLStr; - nsAutoString strDocTitle; - nsAutoString strURL; - DocumentViewerImpl::GetWebShellTitleAndURL(aPO->mWebShell, nsnull, &docTitleStr, &docURLStr); - - if (!docTitleStr) { - if (docURLStr) { - docTitleStr = docURLStr; - docURLStr = nsnull; - } else { - docTitleStr = ToNewUnicode(NS_LITERAL_STRING("Document")); - } - } aDocStr = nsnull; aURLStr = nsnull; + PRUnichar * docTitleStr; + PRUnichar * docURLStr; + DocumentViewerImpl::GetDisplayTitleAndURL(aPO, nsnull, &docTitleStr, &docURLStr, DocumentViewerImpl::eDocTitleDefURLDoc); + if (docTitleStr) { nsAutoString strDocTitle(docTitleStr); aDocStr = ToNewCString(strDocTitle); @@ -2364,7 +2387,6 @@ DocumentViewerImpl::IsWebShellAFrameSet(nsIWebShell * aWebShell) //------------------------------------------------------- void DocumentViewerImpl::GetWebShellTitleAndURL(nsIWebShell * aWebShell, - nsIPrintSettings* aPrintSettings, PRUnichar** aTitle, PRUnichar** aURLStr) { @@ -2375,58 +2397,106 @@ DocumentViewerImpl::GetWebShellTitleAndURL(nsIWebShell * aWebShell, *aTitle = nsnull; *aURLStr = nsnull; + // now get the actual values if the PrintSettings didn't have any + nsCOMPtr docShell(do_QueryInterface(aWebShell)); + if (!docShell) return; + + nsCOMPtr presShell; + docShell->GetPresShell(getter_AddRefs(presShell)); + if (!presShell) return; + + nsCOMPtr doc; + presShell->GetDocument(getter_AddRefs(doc)); + if (!doc) return; + + const nsString* docTitle = doc->GetDocumentTitle(); + if (docTitle && !docTitle->IsEmpty()) { + *aTitle = ToNewUnicode(*docTitle); + } + + nsCOMPtr url; + doc->GetDocumentURL(getter_AddRefs(url)); + if (!url) return; + + nsXPIDLCString urlCStr; + url->GetSpec(getter_Copies(urlCStr)); + if (urlCStr.get()) { + *aURLStr = ToNewUnicode(urlCStr); + } +} + +//------------------------------------------------------- +// This will first use a Title and/or URL from the PrintSettings +// if one isn't set then it uses the one from the document +// then if not title is there we will make sure we send something back +// depending on the situation. +void +DocumentViewerImpl::GetDisplayTitleAndURL(PrintObject* aPO, + nsIPrintSettings* aPrintSettings, + PRUnichar** aTitle, + PRUnichar** aURLStr, + eDocTitleDefault aDefType) +{ + NS_ASSERTION(aPO, "Pointer is null!"); + NS_ASSERTION(aTitle, "Pointer is null!"); + NS_ASSERTION(aURLStr, "Pointer is null!"); + + *aTitle = nsnull; + *aURLStr = nsnull; + // First check to see if the PrintSettings has defined an alternate title // and use that if it did PRUnichar * docTitleStrPS = nsnull; PRUnichar * docURLStrPS = nsnull; - if (aPrintSettings != nsnull) { + if (aPrintSettings) { aPrintSettings->GetTitle(&docTitleStrPS); aPrintSettings->GetDocURL(&docURLStrPS); - if (docTitleStrPS != nsnull && nsCRT::strlen(docTitleStrPS) > 0) { + if (docTitleStrPS && nsCRT::strlen(docTitleStrPS) > 0) { *aTitle = docTitleStrPS; } - if (docURLStrPS != nsnull && nsCRT::strlen(docURLStrPS) > 0) { + if (docURLStrPS && nsCRT::strlen(docURLStrPS) > 0) { *aURLStr = docURLStrPS; } // short circut - if (docTitleStrPS != nsnull && docURLStrPS != nsnull) { + if (docTitleStrPS && docURLStrPS) { return; } } - // now get the actual values if the PrintSettings didn't have any - nsCOMPtr docShell(do_QueryInterface(aWebShell)); - if (docShell) { - nsCOMPtr presShell; - docShell->GetPresShell(getter_AddRefs(presShell)); - if (presShell) { - nsCOMPtr doc; - presShell->GetDocument(getter_AddRefs(doc)); - if (doc) { - if (docTitleStrPS == nsnull) { - const nsString* docTitle = doc->GetDocumentTitle(); - if (docTitle && !docTitle->IsEmpty()) { - *aTitle = ToNewUnicode(*docTitle); - } - } - - if (docURLStrPS == nsnull) { - nsCOMPtr url; - doc->GetDocumentURL(getter_AddRefs(url)); - if (url) { - nsXPIDLCString urlCStr; - url->GetSpec(getter_Copies(urlCStr)); - if (urlCStr.get()) { - *aURLStr = ToNewUnicode(urlCStr); - } - } - } - } + if (!docURLStrPS) { + if (aPO->mDocURL) { + *aURLStr = nsCRT::strdup(aPO->mDocURL); } } + + if (!docTitleStrPS) { + if (aPO->mDocTitle) { + *aTitle = nsCRT::strdup(aPO->mDocTitle); + } else { + switch (aDefType) { + case eDocTitleDefBlank: *aTitle = ToNewUnicode(NS_LITERAL_STRING("")); + break; + + case eDocTitleDefDocument: *aTitle = ToNewUnicode(NS_LITERAL_STRING("Mozilla Document")); + break; + + case eDocTitleDefURLDoc: + if (*aURLStr) { + *aTitle = nsCRT::strdup(*aURLStr); + } else { + *aTitle = ToNewUnicode(NS_LITERAL_STRING("Mozilla Document")); + } + break; + + default: + break; + } // switch + } + } + } @@ -2463,7 +2533,8 @@ DocumentViewerImpl::DonePrintingPages(PrintObject* aPO) PRBool DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, nsIPrintSettings* aPrintSettings, - PrintObject* aPO) + PrintObject* aPO, + PRBool& aInRange) { NS_ASSERTION(aPresContext, "Pointer is null!"); NS_ASSERTION(aPrintSettings, "Pointer is null!"); @@ -2472,23 +2543,24 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, PRINT_DEBUG_MSG1("-----------------------------------\n"); PRINT_DEBUG_MSG3("------ In DV::PrintPage PO: %p (%s)\n", aPO, gFrameTypesStr[aPO->mFrameType]); - if (aPrintSettings != nsnull) { - PRBool isCancelled; - aPrintSettings->GetIsCancelled(&isCancelled); - // DO NOT allow the print job to be cancelled if it is Print FrameAsIs - // because it is only printing one page. - if (isCancelled && mPrt->mPrintFrameType != nsIPrintSettings::kFramesAsIs) { - aPrintSettings->SetIsCancelled(PR_FALSE); - return PR_TRUE; + PRBool isCancelled = PR_FALSE; + + // Check setting to see if someone request it be cancelled (programatically) + aPrintSettings->GetIsCancelled(&isCancelled); + if (!isCancelled) { + // If not, see if the user has cancelled it + if (mPrt->mPrintProgress) { + mPrt->mPrintProgress->GetProcessCanceledByUser(&isCancelled); } } - if (mPrt->mPrintProgress) { - PRBool isCancelled; - mPrt->mPrintProgress->GetProcessCanceledByUser(&isCancelled); - // DO NOT allow the print job to be cancelled if it is Print FrameAsIs - // because it is only printing one page. - if (isCancelled && mPrt->mPrintFrameType != nsIPrintSettings::kFramesAsIs) { + + // DO NOT allow the print job to be cancelled if it is Print FrameAsIs + // because it is only printing one page. + if (isCancelled) { + if (mPrt->mPrintFrameType == nsIPrintSettings::kFramesAsIs) { aPrintSettings->SetIsCancelled(PR_FALSE); + } else { + aPrintSettings->SetIsCancelled(PR_TRUE); return PR_TRUE; } } @@ -2517,8 +2589,10 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, PRINT_DEBUG_MSG4("****** Printing Page %d printing from %d to page %d\n", pageNum, fromPage, toPage); donePrinting = pageNum >= toPage; - curPage = pageNum - fromPage; - endPage = toPage - fromPage; + aInRange = pageNum >= fromPage && pageNum <= toPage; + PRInt32 pageInc = pageNum - fromPage + 1; + curPage = pageInc >= 0?pageInc+1:0; + endPage = (toPage - fromPage)+1; } else { PRInt32 numPages; mPageSeqFrame->GetNumPages(&numPages); @@ -2526,8 +2600,9 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, PRINT_DEBUG_MSG3("****** Printing Page %d of %d page(s)\n", pageNum, numPages); donePrinting = pageNum >= numPages; - curPage = pageNum; + curPage = pageNum+1; endPage = numPages; + aInRange = PR_TRUE; } // NOTE: mPrt->mPrintFrameType gets set to "kFramesAsIs" when a @@ -2537,7 +2612,7 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, } else if (mPrt->mPrintFrameType != nsIPrintSettings::kFramesAsIs || mPrt->mPrintObject->mFrameType == eDoc && aPO == mPrt->mPrintObject) { - PrintData::DoOnProgressChange(mPrt->mPrintProgressListeners, curPage+1, endPage); + PrintData::DoOnProgressChange(mPrt->mPrintProgressListeners, curPage, endPage); } // Set Clip when Printing "AsIs" or @@ -2568,6 +2643,9 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, } //switch if (setClip) { + // Always set the clip x,y to zero because it isn't going to have any margins + aPO->mClipRect.x = 0; + aPO->mClipRect.y = 0; mPageSeqFrame->SetClipRect(aPO->mPresContext, &aPO->mClipRect); } @@ -2575,9 +2653,15 @@ DocumentViewerImpl::PrintPage(nsIPresContext* aPresContext, // if a print job was cancelled externally, an EndPage or BeginPage may // fail and the failure is passed back here. // Returning PR_TRUE means we are done printing. + // + // When rv == NS_ERROR_ABORT, it means we want out of the + // print job without displaying any error messages nsresult rv = mPageSeqFrame->PrintNextPage(aPresContext); if (NS_FAILED(rv)) { - ShowPrintErrorDialog(rv, PR_TRUE); + if (rv != NS_ERROR_ABORT) { + ShowPrintErrorDialog(rv); + mPrt->mIsAborted = PR_TRUE; + } return PR_TRUE; } @@ -2653,6 +2737,9 @@ DocumentViewerImpl::BuildDocTree(nsIDocShellTreeNode * aParentNode, NS_ASSERTION(aDocList, "Pointer is null!"); NS_ASSERTION(aPO, "Pointer is null!"); + // Get the Doc and Title String + GetWebShellTitleAndURL(aPO->mWebShell, &aPO->mDocTitle, &aPO->mDocURL); + PRInt32 childWebshellCount; aParentNode->GetChildCount(&childWebshellCount); if (childWebshellCount > 0) { @@ -3123,7 +3210,7 @@ DocumentViewerImpl::ReflowPrintObject(PrintObject * aPO) if (printRangeType == nsIPrintSettings::kRangeSelection && IsThereARangeSelection(domWinIntl)) { - height = 0x0FFFFFFF; + height = NS_UNCONSTRAINEDSIZE; } nsRect tbounds = nsRect(0, 0, width, height); @@ -3630,40 +3717,8 @@ DocumentViewerImpl::SetupToPrintContent(nsIWebShell* aParent, // it will check to see if there are more webshells to be printed and // then PrintDocContent will be called again. - nsCOMPtr webContainer(do_QueryInterface(mContainer)); - PRUnichar * docTitleStr; - PRUnichar * docURLStr; - GetWebShellTitleAndURL(webContainer, mPrt->mPrintSettings, &docTitleStr, &docURLStr); - - if (!docTitleStr) { - if (docURLStr) { - docTitleStr = docURLStr; - docURLStr = nsnull; - } else { - docTitleStr = ToNewUnicode(NS_LITERAL_STRING("Document")); - } - } - nsresult rv = NS_OK; if (mIsDoingPrinting) { - // BeginDocument may pass back a FAILURE code - // i.e. On Windows, if you are printing to a file and hit "Cancel" - // to the "File Name" dialog, this comes back as an error - // Don't start printing when regression test are executed - rv = mPrt->mDebugFilePtr ? NS_OK: mPrt->mPrintDC->BeginDocument(docTitleStr); - PRINT_DEBUG_MSG1("****************** Begin Document ************************\n"); - - if (docTitleStr != nsnull) { - nsMemory::Free(docTitleStr); - } - if (docURLStr != nsnull) { - nsMemory::Free(docURLStr); - } - - if (NS_FAILED(rv)) { - return rv; - } - PrintDocContent(mPrt->mPrintObject, rv); // ignore return value } @@ -3688,7 +3743,7 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a NS_ASSERTION(webShell, "The WebShell can't be NULL!"); if (mPrt->mPrintProgressParams) { - SetDocAndURLIntoProgress(aPO->mWebShell, mPrt->mPrintProgressParams); + SetDocAndURLIntoProgress(aPO, mPrt->mPrintProgressParams); } if (webShell != nsnull) { @@ -3835,12 +3890,10 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a if (!skipSetTitle) { PRUnichar * docTitleStr; PRUnichar * docURLStr; - GetWebShellTitleAndURL(webShell, mPrt->mPrintSettings, &docTitleStr, &docURLStr); - - if (!docTitleStr) { - docTitleStr = ToNewUnicode(NS_LITERAL_STRING("")); - } + GetDisplayTitleAndURL(aPO, mPrt->mPrintSettings, &docTitleStr, &docURLStr, eDocTitleDefBlank); + // Set them down into the PrintOptions so + // they can used by the DeviceContext if (docTitleStr) { mPrt->mPrintOptions->SetTitle(docTitleStr); nsMemory::Free(docTitleStr); @@ -3892,12 +3945,25 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a nsRect areaRect; nsIFrame * areaFrame = FindFrameByType(poPresContext, startFrame, nsHTMLAtoms::body, rect, areaRect); if (areaFrame) { - startRect.y -= margin.top; + nsRect areaRect; + areaFrame->GetRect(areaRect); + startRect.y -= margin.top+areaRect.y; endRect.y -= margin.top; areaRect.y -= startRect.y; areaRect.x -= margin.left; // XXX This is temporary fix for printing more than one page of a selection pageSequence->SetSelectionHeight(startRect.y, endRect.y+endRect.height-startRect.y); + + // calc total pages by getting calculating the selection's height + // and then dividing it by how page content frames will fit. + nscoord selectionHgt = endRect.y + endRect.height - startRect.y; + PRInt32 pageWidth, pageHeight; + mPrt->mPrintDocDC->GetDeviceSurfaceDimensions(pageWidth, pageHeight); + nsMargin margin(0,0,0,0); + mPrt->mPrintSettings->GetMarginInTwips(margin); + pageHeight -= margin.top + margin.bottom; + PRInt32 totalPages = PRInt32((float(selectionHgt) / float(pageHeight))+0.99); + pageSequence->SetTotalNumPages(totalPages); } } } @@ -3941,7 +4007,8 @@ DocumentViewerImpl::DoPrint(PrintObject * aPO, PRBool aDoSyncPrinting, PRBool& a DoProgressForAsIsFrames(); // Print the page synchronously PRINT_DEBUG_MSG3("Async Print of PO: %p (%s) \n", aPO, gFrameTypesStr[aPO->mFrameType]); - aDonePrinting = PrintPage(poPresContext, mPrt->mPrintSettings, aPO); + PRBool inRange; + aDonePrinting = PrintPage(poPresContext, mPrt->mPrintSettings, aPO, inRange); } } } else { @@ -5261,7 +5328,7 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) /* cleanup done, let's fire-up an error dialog to notify the user * what went wrong... */ - ShowPrintErrorDialog(rv); + ShowPrintErrorDialog(rv, PR_FALSE); TurnScriptingOn(PR_TRUE); mIsCreatingPrintPreview = PR_FALSE; mIsDoingPrintPreview = PR_FALSE; @@ -5287,22 +5354,22 @@ DocumentViewerImpl::PrintPreview(nsIPrintSettings* aPrintSettings) void -DocumentViewerImpl::SetDocAndURLIntoProgress(nsIWebShell* aWebShell, - nsIPrintProgressParams* aParams) +DocumentViewerImpl::SetDocAndURLIntoProgress(PrintObject* aPO, nsIPrintProgressParams* aParams) { - NS_ASSERTION(aWebShell, "Must have vaild nsIWebShell"); + NS_ASSERTION(aPO, "Must have vaild PrintObject"); NS_ASSERTION(aParams, "Must have vaild nsIPrintProgressParams"); - if (aWebShell == nsnull || aParams == nsnull) { + + if (!aPO || !aPO->mWebShell || !aParams) { return; } const PRInt32 kTitleLength = 64; PRUnichar * docTitleStr; PRUnichar * docURLStr; - GetWebShellTitleAndURL(aWebShell, mPrt->mPrintSettings, &docTitleStr, &docURLStr); + GetDisplayTitleAndURL(aPO, mPrt->mPrintSettings, &docTitleStr, &docURLStr, eDocTitleDefDocument); // Make sure the URLS don't get too long for the progress dialog - if (docURLStr != nsnull && nsCRT::strlen(docURLStr) > kTitleLength) { + if (docURLStr && nsCRT::strlen(docURLStr) > kTitleLength) { PRUnichar * ptr = &docURLStr[nsCRT::strlen(docURLStr)-kTitleLength+3]; nsAutoString newURLStr; newURLStr.AppendWithConversion("..."); @@ -5342,7 +5409,7 @@ DocumentViewerImpl::DoPrintProgress(PRBool aIsForPrinting) nsCOMPtr params; rv = prtProgressParams->QueryInterface(NS_GET_IID(nsIPrintProgressParams), (void**)getter_AddRefs(mPrt->mPrintProgressParams)); if (NS_SUCCEEDED(rv) && mPrt->mPrintProgressParams) { - SetDocAndURLIntoProgress(mPrt->mPrintObject->mWebShell, mPrt->mPrintProgressParams); + SetDocAndURLIntoProgress(mPrt->mPrintObject, mPrt->mPrintProgressParams); nsCOMPtr wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1")); if (wwatch) { @@ -5452,6 +5519,7 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, return NS_ERROR_FAILURE; } } + mPrt->mPrintSettings->SetIsCancelled(PR_FALSE); // Let's print ... mIsDoingPrinting = PR_TRUE; @@ -5688,28 +5756,41 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, } } - DoPrintProgress(PR_TRUE); + PRUnichar * docTitleStr; + PRUnichar * docURLStr; + GetDisplayTitleAndURL(mPrt->mPrintObject, mPrt->mPrintSettings, &docTitleStr, &docURLStr, eDocTitleDefURLDoc); - // Print listener setup... - if (mPrt != nsnull) { - mPrt->OnStartPrinting(); - } + // BeginDocument may pass back a FAILURE code + // i.e. On Windows, if you are printing to a file and hit "Cancel" + // to the "File Name" dialog, this comes back as an error + // Don't start printing when regression test are executed + rv = mPrt->mDebugFilePtr ? NS_OK: mPrt->mPrintDC->BeginDocument(docTitleStr); + PRINT_DEBUG_MSG1("****************** Begin Document ************************\n"); - // - // The mIsPrinting flag is set when the ImageGroup observer is - // notified that images must be loaded as a result of the - // InitialReflow... - // - if(!mIsPrinting || (mPrt->mDebugFilePtr != nsnull)) { - rv = DocumentReadyForPrinting(); -#ifdef DEBUG_dcone - printf("PRINT JOB ENDING, OBSERVER WAS NOT CALLED\n"); -#endif - } else { - // use the observer mechanism to finish the printing -#ifdef DEBUG_dcone - printf("PRINTING OBSERVER STARTED\n"); -#endif + if (docTitleStr) nsMemory::Free(docTitleStr); + if (docURLStr) nsMemory::Free(docURLStr); + + if (NS_SUCCEEDED(rv)) { + + DoPrintProgress(PR_TRUE); + + // Print listener setup... + if (mPrt != nsnull) { + mPrt->OnStartPrinting(); + } + + // + // The mIsPrinting flag is set when the ImageGroup observer is + // notified that images must be loaded as a result of the + // InitialReflow... + // + if(!mIsPrinting || mPrt->mDebugFilePtr) { + rv = DocumentReadyForPrinting(); + PRINT_DEBUG_MSG1("PRINT JOB ENDING, OBSERVER WAS NOT CALLED\n"); + } else { + // use the observer mechanism to finish the printing + PRINT_DEBUG_MSG1("PRINTING OBSERVER STARTED\n"); + } } } } @@ -5737,6 +5818,9 @@ DocumentViewerImpl::Print(nsIPrintSettings* aPrintSettings, /* cleanup done, let's fire-up an error dialog to notify the user * what went wrong... + * + * When rv == NS_ERROR_ABORT, it means we want out of the + * print job without displaying any error messages */ if (rv != NS_ERROR_ABORT) { ShowPrintErrorDialog(rv); @@ -6747,7 +6831,7 @@ DocumentViewerImpl::EnumerateDocumentNames(PRUint32* aCount, NS_ASSERTION(po, "PrintObject can't be null!"); PRUnichar * docTitleStr; PRUnichar * docURLStr; - GetWebShellTitleAndURL(po->mWebShell, nsnull, &docTitleStr, &docURLStr); + GetWebShellTitleAndURL(po->mWebShell, &docTitleStr, &docURLStr); // Use the URL if the doc is empty if (!docTitleStr || !*docTitleStr) { diff --git a/mozilla/layout/base/public/nsIPageSequenceFrame.h b/mozilla/layout/base/public/nsIPageSequenceFrame.h index 6bce36a3ac0..07457f7c3b3 100644 --- a/mozilla/layout/base/public/nsIPageSequenceFrame.h +++ b/mozilla/layout/base/public/nsIPageSequenceFrame.h @@ -147,6 +147,8 @@ public: NS_IMETHOD SuppressHeadersAndFooters(PRBool aDoSup) = 0; NS_IMETHOD SetClipRect(nsIPresContext* aPresContext, nsRect* aSize) = 0; NS_IMETHOD SetSelectionHeight(nscoord aYOffset, nscoord aHeight) = 0; + + NS_IMETHOD SetTotalNumPages(PRInt32 aTotal) = 0; private: NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; diff --git a/mozilla/layout/generic/nsIPageSequenceFrame.h b/mozilla/layout/generic/nsIPageSequenceFrame.h index 6bce36a3ac0..07457f7c3b3 100644 --- a/mozilla/layout/generic/nsIPageSequenceFrame.h +++ b/mozilla/layout/generic/nsIPageSequenceFrame.h @@ -147,6 +147,8 @@ public: NS_IMETHOD SuppressHeadersAndFooters(PRBool aDoSup) = 0; NS_IMETHOD SetClipRect(nsIPresContext* aPresContext, nsRect* aSize) = 0; NS_IMETHOD SetSelectionHeight(nscoord aYOffset, nscoord aHeight) = 0; + + NS_IMETHOD SetTotalNumPages(PRInt32 aTotal) = 0; private: NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; diff --git a/mozilla/layout/generic/nsObjectFrame.cpp b/mozilla/layout/generic/nsObjectFrame.cpp index bccbd6cf1a6..5674eebd14f 100644 --- a/mozilla/layout/generic/nsObjectFrame.cpp +++ b/mozilla/layout/generic/nsObjectFrame.cpp @@ -91,6 +91,7 @@ #include "nsXPIDLString.h" #include "nsIDOMRange.h" #include "nsIPrintContext.h" +#include "nsIPrintPreviewContext.h" #include "nsIWidget.h" #include "nsGUIEvent.h" #include "nsIRenderingContext.h" @@ -1615,7 +1616,8 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext, // determine if we are printing nsCOMPtr thePrinterContext = do_QueryInterface(aPresContext); - if (thePrinterContext) { + nsCOMPtr thePrintPreviewContext = do_QueryInterface(aPresContext); + if (thePrinterContext || thePrintPreviewContext) { // we only want to print on the content layer pass if (eFramePaintLayer_Content != aWhichLayer) return NS_OK; diff --git a/mozilla/layout/generic/nsPageContentFrame.cpp b/mozilla/layout/generic/nsPageContentFrame.cpp index 17b3efe4b98..0abb4c14249 100644 --- a/mozilla/layout/generic/nsPageContentFrame.cpp +++ b/mozilla/layout/generic/nsPageContentFrame.cpp @@ -123,7 +123,9 @@ NS_IMETHODIMP nsPageContentFrame::Reflow(nsIPresContext* aPresContext, } // Return our desired size aDesiredSize.width = aReflowState.availableWidth; - aDesiredSize.height = aReflowState.availableHeight; + if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) { + aDesiredSize.height = aReflowState.availableHeight; + } } return NS_OK; @@ -169,14 +171,25 @@ nsPageContentFrame::Paint(nsIPresContext* aPresContext, rect = mClipRect; } else { rect = mRect; + rect.x = 0; + rect.y = 0; } - rect.x = 0; - rect.y = 0; + PRBool clipEmpty; aRenderingContext.SetClipRect(rect, nsClipCombine_kReplace, clipEmpty); nsresult rv = nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { + nsRect r = mRect; + r.x = 0; + r.y = 0; + aRenderingContext.SetColor(NS_RGB(0, 0, 0)); + aRenderingContext.DrawRect(r); + } +#endif + aRenderingContext.PopState(clipEmpty); return rv; diff --git a/mozilla/layout/generic/nsPageFrame.cpp b/mozilla/layout/generic/nsPageFrame.cpp index 4c18a09e05a..a53424eef15 100644 --- a/mozilla/layout/generic/nsPageFrame.cpp +++ b/mozilla/layout/generic/nsPageFrame.cpp @@ -122,20 +122,6 @@ nsPageFrame::~nsPageFrame() { } -static NS_DEFINE_CID(kRegionCID, NS_REGION_CID); -static nsIRegion* CreateRegion() -{ - nsIRegion* region; - nsresult rv = nsComponentManager::CreateInstance(kRegionCID, nsnull, NS_GET_IID(nsIRegion), (void**)®ion); - if (NS_SUCCEEDED(rv)) { - if (NS_SUCCEEDED(region->Init())) { - return region; - } else { - NS_RELEASE(region); - } - } - return nsnull; -} NS_IMETHODIMP nsPageFrame::SetInitialChildList(nsIPresContext* aPresContext, @@ -201,27 +187,23 @@ NS_IMETHODIMP nsPageFrame::Reflow(nsIPresContext* aPresContext, // XXX Pay attention to the page's border and padding... if (mFrames.NotEmpty()) { nsIFrame* frame = mFrames.FirstChild(); + // When availableHeight is NS_UNCONSTRAINEDSIZE it means we are reflowing a single page + // to print selection. So this means we want to use NS_UNCONSTRAINEDSIZE without altering it + nscoord avHeight; + if (aReflowState.availableHeight == NS_UNCONSTRAINEDSIZE) { + avHeight = NS_UNCONSTRAINEDSIZE; + } else { + avHeight = mPD->mReflowRect.height - mPD->mReflowMargin.top - mPD->mReflowMargin.bottom; + } nsSize maxSize(mPD->mReflowRect.width - mPD->mReflowMargin.right - mPD->mReflowMargin.left, - mPD->mReflowRect.height - mPD->mReflowMargin.top - mPD->mReflowMargin.bottom); + avHeight); nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize); kidReflowState.mFlags.mIsTopOfPage = PR_TRUE; - kidReflowState.availableWidth = maxSize.width; - kidReflowState.availableHeight = maxSize.height; // calc location of frame nscoord xc = mPD->mReflowMargin.left + mPD->mDeadSpaceMargin.left + mPD->mExtraMargin.left; nscoord yc = mPD->mReflowMargin.top + mPD->mDeadSpaceMargin.top + mPD->mExtraMargin.top; - nsIView * view; - frame->GetView(aPresContext, &view); - if (view) { - nsCOMPtr vm; - view->GetViewManager(*getter_AddRefs(vm)); - nsCOMPtr region = dont_AddRef(CreateRegion()); - region->SetTo(0,0, maxSize.width,maxSize.height); - vm->SetViewChildClipRegion(view, region); - } - // Get the child's desired size ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, xc, yc, 0, aStatus); @@ -230,10 +212,21 @@ NS_IMETHODIMP nsPageFrame::Reflow(nsIPresContext* aPresContext, FinishReflowChild(frame, aPresContext, &kidReflowState, aDesiredSize, xc, yc, 0); // Make sure the child is at least as tall as our max size (the containing window) - if (aDesiredSize.height < aReflowState.availableHeight) { + if (aDesiredSize.height < aReflowState.availableHeight && + aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) { aDesiredSize.height = aReflowState.availableHeight; } + nsIView * view; + frame->GetView(aPresContext, &view); + if (view) { + nsCOMPtr vm; + view->GetViewManager(*getter_AddRefs(vm)); + nsCOMPtr region = dont_AddRef(nsSimplePageSequenceFrame::CreateRegion()); + region->SetTo(0,0, aDesiredSize.width, aDesiredSize.height); + vm->SetViewChildClipRegion(view, region); + } + #ifdef NS_DEBUG // Is the frame complete? if (NS_FRAME_IS_COMPLETE(aStatus)) { @@ -249,7 +242,9 @@ NS_IMETHODIMP nsPageFrame::Reflow(nsIPresContext* aPresContext, // Return our desired size aDesiredSize.width = aReflowState.availableWidth; - aDesiredSize.height = aReflowState.availableHeight; + if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) { + aDesiredSize.height = aReflowState.availableHeight; + } } PRINT_DEBUG_MSG2("PageFrame::Reflow %p ", this); PRINT_DEBUG_MSG3("[%d,%d]\n", aReflowState.availableWidth, aReflowState.availableHeight); @@ -619,8 +614,6 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, printf("*** ClipRect: %5d,%5d,%5d,%5d\n", mClipRect.x, mClipRect.y, mClipRect.width, mClipRect.height); } #endif - mClipRect.x = 0; - mClipRect.y = 0; aRenderingContext.SetClipRect(mClipRect, nsClipCombine_kReplace, clipEmpty); rect = mClipRect; } else { @@ -667,7 +660,6 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, #if defined(DEBUG_rods) || defined(DEBUG_dcone) if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { - nsRect r; fprintf(mDebugFD, "PF::Paint -> %p SupHF: %s Rect: [%5d,%5d,%5d,%5d] SC:%s\n", this, mSupressHF?"Yes":"No", mRect.x, mRect.y, mRect.width, mRect.height, specialClipIsSet?"Yes":"No"); fprintf(stdout, "PF::Paint -> %p SupHF: %s Rect: [%5d,%5d,%5d,%5d] SC:%s\n", this, @@ -690,24 +682,6 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, rect.SetRect(0, 0, mRect.width - mPD->mShadowSize.width, mRect.height - mPD->mShadowSize.height); -#if defined(DEBUG_rods) || defined(DEBUG_dcone) - { - nsRect rct = rect; - // XXX Paint a one-pixel border around the page so it's easy to see where - // each page begins and ends when we're - rct.Deflate(mMargin); - rct.Deflate(mPD->mDeadSpaceMargin); - //float p2t; - //aPresContext->GetPixelsToTwips(&p2t); - //rect.Deflate(NSToCoordRound(p2t), NSToCoordRound(p2t)); - aRenderingContext.SetColor(NS_RGB(0, 0, 0)); - aRenderingContext.DrawRect(rct); - //rect.Inflate(NSToCoordRound(p2t), NSToCoordRound(p2t)); - fprintf(mDebugFD, "PageFr::PaintChild -> Painting Frame %p Page No: %d\n", this, mPageNum); - } -#endif - - aRenderingContext.SetFont(*mPD->mHeadFootFont); aRenderingContext.SetColor(NS_RGB(0,0,0)); diff --git a/mozilla/layout/generic/nsSimplePageSequence.cpp b/mozilla/layout/generic/nsSimplePageSequence.cpp index 53251e242f1..089821697f5 100644 --- a/mozilla/layout/generic/nsSimplePageSequence.cpp +++ b/mozilla/layout/generic/nsSimplePageSequence.cpp @@ -144,6 +144,7 @@ NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) nsSimplePageSequenceFrame::nsSimplePageSequenceFrame() : mIsPrintingSelection(PR_FALSE), + mTotalPages(-1), mSelectionHeight(-1), mYSelOffset(0) { @@ -395,13 +396,24 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics kidSize(nsnull); for (nsIFrame* kidFrame = mFrames.FirstChild(); nsnull != kidFrame; ) { // Reflow the page + // The availableHeight always comes in NS_UNCONSTRAINEDSIZE, so we need to check + // the "adjusted rect" to see if that is being reflowed NS_UNCONSTRAINEDSIZE or not + // When it is NS_UNCONSTRAINEDSIZE it means we are reflowing a single page + // to print selection. So this means we want to use NS_UNCONSTRAINEDSIZE without altering it + nsRect actualRect; + nsRect adjRect; + aPresContext->GetPageDim(&actualRect, &adjRect); + nscoord avHeight; + if (adjRect.height == NS_UNCONSTRAINEDSIZE) { + avHeight = NS_UNCONSTRAINEDSIZE; + } else { + avHeight = pageSize.height+deadSpaceMargin.top+deadSpaceMargin.bottom+shadowSize.height+extraMargin.top+extraMargin.bottom; + } nsSize availSize(pageSize.width+deadSpaceMargin.right+deadSpaceMargin.left+shadowSize.width+extraMargin.right+extraMargin.left, - pageSize.height+deadSpaceMargin.top+deadSpaceMargin.bottom+shadowSize.height+extraMargin.top+extraMargin.bottom); + avHeight); nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, availSize, reflowReason); nsReflowStatus status; - kidReflowState.availableWidth = availSize.width; - kidReflowState.availableHeight = availSize.height; kidReflowState.mComputedWidth = kidReflowState.availableWidth; //kidReflowState.mComputedHeight = kidReflowState.availableHeight; @@ -599,7 +611,7 @@ nsSimplePageSequenceFrame::SetPageNumberFormat(const char* aPropName, const char } -static nsIRegion* CreateRegion() +nsIRegion* nsSimplePageSequenceFrame::CreateRegion() { nsIRegion* region; nsresult rv = nsComponentManager::CreateInstance(kRegionCID, nsnull, NS_GET_IID(nsIRegion), (void**)®ion); @@ -743,9 +755,7 @@ nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext, } // adjust total number of pages - if (nsIPrintSettings::kRangeSelection == mPrintRangeType) { - totalPages = mToPageNum - mFromPageNum + 1; - } else { + if (nsIPrintSettings::kRangeSelection != mPrintRangeType) { totalPages = pageNum - 1; } } @@ -782,9 +792,12 @@ nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext, mPageNum = 1; mPrintedPageNum = 1; - mTotalPages = totalPages; mCurrentPageFrame = mFrames.FirstChild(); + if (mTotalPages == -1) { + mTotalPages = totalPages; + } + return rv; } @@ -854,14 +867,6 @@ nsSimplePageSequenceFrame::PrintNextPage(nsIPresContext* aPresContext) } if (mPrintThisPage) { - if (!mSkipPageBegin) { - PRINT_DEBUG_MSG1("\n***************** BeginPage *****************\n"); - rv = dc->BeginPage(); - if (NS_FAILED(rv)) { - return rv; - } - } - // XXX This is temporary fix for printing more than one page of a selection // This does a poor man's "dump" pagination (see Bug 89353) // It has laid out as one long page and now we are just moving or view up/down @@ -873,6 +878,7 @@ nsSimplePageSequenceFrame::PrintNextPage(nsIPresContext* aPresContext) PRInt32 width, height; dc->GetDeviceSurfaceDimensions(width, height); nsRect clipRect(0, 0, width, height); + nsRect slidingRect(-1, -1, -1, -1); height -= mMargin.top + mMargin.bottom; width -= mMargin.left + mMargin.right; nscoord selectionY = height; @@ -886,25 +892,31 @@ nsSimplePageSequenceFrame::PrintNextPage(nsIPresContext* aPresContext) NS_ASSERTION(containerView != nsnull, "Container view can't be null!"); containerView->GetBounds(containerRect); containerRect.y -= mYSelOffset; - containerRect.height = height-mYSelOffset; + slidingRect.SetRect(0,mYSelOffset,width,height); vm->MoveViewTo(containerView, containerRect.x, containerRect.y); nsRect r(0, 0, containerRect.width, containerRect.height); vm->ResizeView(containerView, r, PR_FALSE); clipRect.SetRect(mMargin.left, mMargin.right, width, height); - - nsPageFrame * pf = NS_STATIC_CAST(nsPageFrame*, childFrame); - nsRect nullClipRect(-1,-1,-1,-1); - pf->SetClipRect(&nullClipRect); } while (continuePrinting) { + if (!mSkipPageBegin) { + PRINT_DEBUG_MSG1("\n***************** BeginPage *****************\n"); + rv = dc->BeginPage(); + if (NS_FAILED(rv)) { + return rv; + } + } // cast the frame to be a page frame nsPageFrame * pf = NS_STATIC_CAST(nsPageFrame*, mCurrentPageFrame); if (pf != nsnull) { pf->SetPageNumInfo(mPrintedPageNum, mTotalPages); pf->SetSharedPageData(mPageData); + if (mSelectionHeight > -1) { + pf->SetClipRect(&slidingRect); + } } // Print the page @@ -946,6 +958,10 @@ nsSimplePageSequenceFrame::PrintNextPage(nsIPresContext* aPresContext) vm->MoveViewTo(containerView, containerRect.x, containerRect.y); nsRect r(0, 0, containerRect.width, containerRect.height); vm->ResizeView(containerView, r, PR_FALSE); + if (pf != nsnull) { + slidingRect.y += height; + } + } else { continuePrinting = PR_FALSE; } diff --git a/mozilla/layout/generic/nsSimplePageSequence.h b/mozilla/layout/generic/nsSimplePageSequence.h index 27016628aca..b92404a202d 100644 --- a/mozilla/layout/generic/nsSimplePageSequence.h +++ b/mozilla/layout/generic/nsSimplePageSequence.h @@ -91,6 +91,7 @@ public: NS_IMETHOD SetOffsets(nscoord aStartOffset, nscoord aEndOffset); NS_IMETHOD SetPageNo(PRInt32 aPageNo) { return NS_OK;} NS_IMETHOD SetSelectionHeight(nscoord aYOffset, nscoord aHeight) { mYSelOffset = aYOffset; mSelectionHeight = aHeight; return NS_OK; } + NS_IMETHOD SetTotalNumPages(PRInt32 aTotal) { mTotalPages = aTotal; return NS_OK; } // Async Printing NS_IMETHOD StartPrint(nsIPresContext* aPresContext, @@ -111,6 +112,9 @@ public: NS_IMETHOD SizeTo(nsIPresContext* aPresContext, nscoord aWidth, nscoord aHeight); + + static nsIRegion* CreateRegion(); + #ifdef NS_DEBUG // Debugging NS_IMETHOD GetFrameName(nsAString& aResult) const; diff --git a/mozilla/layout/html/base/src/nsObjectFrame.cpp b/mozilla/layout/html/base/src/nsObjectFrame.cpp index bccbd6cf1a6..5674eebd14f 100644 --- a/mozilla/layout/html/base/src/nsObjectFrame.cpp +++ b/mozilla/layout/html/base/src/nsObjectFrame.cpp @@ -91,6 +91,7 @@ #include "nsXPIDLString.h" #include "nsIDOMRange.h" #include "nsIPrintContext.h" +#include "nsIPrintPreviewContext.h" #include "nsIWidget.h" #include "nsGUIEvent.h" #include "nsIRenderingContext.h" @@ -1615,7 +1616,8 @@ nsObjectFrame::Paint(nsIPresContext* aPresContext, // determine if we are printing nsCOMPtr thePrinterContext = do_QueryInterface(aPresContext); - if (thePrinterContext) { + nsCOMPtr thePrintPreviewContext = do_QueryInterface(aPresContext); + if (thePrinterContext || thePrintPreviewContext) { // we only want to print on the content layer pass if (eFramePaintLayer_Content != aWhichLayer) return NS_OK; diff --git a/mozilla/layout/html/base/src/nsPageContentFrame.cpp b/mozilla/layout/html/base/src/nsPageContentFrame.cpp index 17b3efe4b98..0abb4c14249 100644 --- a/mozilla/layout/html/base/src/nsPageContentFrame.cpp +++ b/mozilla/layout/html/base/src/nsPageContentFrame.cpp @@ -123,7 +123,9 @@ NS_IMETHODIMP nsPageContentFrame::Reflow(nsIPresContext* aPresContext, } // Return our desired size aDesiredSize.width = aReflowState.availableWidth; - aDesiredSize.height = aReflowState.availableHeight; + if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) { + aDesiredSize.height = aReflowState.availableHeight; + } } return NS_OK; @@ -169,14 +171,25 @@ nsPageContentFrame::Paint(nsIPresContext* aPresContext, rect = mClipRect; } else { rect = mRect; + rect.x = 0; + rect.y = 0; } - rect.x = 0; - rect.y = 0; + PRBool clipEmpty; aRenderingContext.SetClipRect(rect, nsClipCombine_kReplace, clipEmpty); nsresult rv = nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { + nsRect r = mRect; + r.x = 0; + r.y = 0; + aRenderingContext.SetColor(NS_RGB(0, 0, 0)); + aRenderingContext.DrawRect(r); + } +#endif + aRenderingContext.PopState(clipEmpty); return rv; diff --git a/mozilla/layout/html/base/src/nsPageFrame.cpp b/mozilla/layout/html/base/src/nsPageFrame.cpp index 4c18a09e05a..a53424eef15 100644 --- a/mozilla/layout/html/base/src/nsPageFrame.cpp +++ b/mozilla/layout/html/base/src/nsPageFrame.cpp @@ -122,20 +122,6 @@ nsPageFrame::~nsPageFrame() { } -static NS_DEFINE_CID(kRegionCID, NS_REGION_CID); -static nsIRegion* CreateRegion() -{ - nsIRegion* region; - nsresult rv = nsComponentManager::CreateInstance(kRegionCID, nsnull, NS_GET_IID(nsIRegion), (void**)®ion); - if (NS_SUCCEEDED(rv)) { - if (NS_SUCCEEDED(region->Init())) { - return region; - } else { - NS_RELEASE(region); - } - } - return nsnull; -} NS_IMETHODIMP nsPageFrame::SetInitialChildList(nsIPresContext* aPresContext, @@ -201,27 +187,23 @@ NS_IMETHODIMP nsPageFrame::Reflow(nsIPresContext* aPresContext, // XXX Pay attention to the page's border and padding... if (mFrames.NotEmpty()) { nsIFrame* frame = mFrames.FirstChild(); + // When availableHeight is NS_UNCONSTRAINEDSIZE it means we are reflowing a single page + // to print selection. So this means we want to use NS_UNCONSTRAINEDSIZE without altering it + nscoord avHeight; + if (aReflowState.availableHeight == NS_UNCONSTRAINEDSIZE) { + avHeight = NS_UNCONSTRAINEDSIZE; + } else { + avHeight = mPD->mReflowRect.height - mPD->mReflowMargin.top - mPD->mReflowMargin.bottom; + } nsSize maxSize(mPD->mReflowRect.width - mPD->mReflowMargin.right - mPD->mReflowMargin.left, - mPD->mReflowRect.height - mPD->mReflowMargin.top - mPD->mReflowMargin.bottom); + avHeight); nsHTMLReflowState kidReflowState(aPresContext, aReflowState, frame, maxSize); kidReflowState.mFlags.mIsTopOfPage = PR_TRUE; - kidReflowState.availableWidth = maxSize.width; - kidReflowState.availableHeight = maxSize.height; // calc location of frame nscoord xc = mPD->mReflowMargin.left + mPD->mDeadSpaceMargin.left + mPD->mExtraMargin.left; nscoord yc = mPD->mReflowMargin.top + mPD->mDeadSpaceMargin.top + mPD->mExtraMargin.top; - nsIView * view; - frame->GetView(aPresContext, &view); - if (view) { - nsCOMPtr vm; - view->GetViewManager(*getter_AddRefs(vm)); - nsCOMPtr region = dont_AddRef(CreateRegion()); - region->SetTo(0,0, maxSize.width,maxSize.height); - vm->SetViewChildClipRegion(view, region); - } - // Get the child's desired size ReflowChild(frame, aPresContext, aDesiredSize, kidReflowState, xc, yc, 0, aStatus); @@ -230,10 +212,21 @@ NS_IMETHODIMP nsPageFrame::Reflow(nsIPresContext* aPresContext, FinishReflowChild(frame, aPresContext, &kidReflowState, aDesiredSize, xc, yc, 0); // Make sure the child is at least as tall as our max size (the containing window) - if (aDesiredSize.height < aReflowState.availableHeight) { + if (aDesiredSize.height < aReflowState.availableHeight && + aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) { aDesiredSize.height = aReflowState.availableHeight; } + nsIView * view; + frame->GetView(aPresContext, &view); + if (view) { + nsCOMPtr vm; + view->GetViewManager(*getter_AddRefs(vm)); + nsCOMPtr region = dont_AddRef(nsSimplePageSequenceFrame::CreateRegion()); + region->SetTo(0,0, aDesiredSize.width, aDesiredSize.height); + vm->SetViewChildClipRegion(view, region); + } + #ifdef NS_DEBUG // Is the frame complete? if (NS_FRAME_IS_COMPLETE(aStatus)) { @@ -249,7 +242,9 @@ NS_IMETHODIMP nsPageFrame::Reflow(nsIPresContext* aPresContext, // Return our desired size aDesiredSize.width = aReflowState.availableWidth; - aDesiredSize.height = aReflowState.availableHeight; + if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) { + aDesiredSize.height = aReflowState.availableHeight; + } } PRINT_DEBUG_MSG2("PageFrame::Reflow %p ", this); PRINT_DEBUG_MSG3("[%d,%d]\n", aReflowState.availableWidth, aReflowState.availableHeight); @@ -619,8 +614,6 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, printf("*** ClipRect: %5d,%5d,%5d,%5d\n", mClipRect.x, mClipRect.y, mClipRect.width, mClipRect.height); } #endif - mClipRect.x = 0; - mClipRect.y = 0; aRenderingContext.SetClipRect(mClipRect, nsClipCombine_kReplace, clipEmpty); rect = mClipRect; } else { @@ -667,7 +660,6 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, #if defined(DEBUG_rods) || defined(DEBUG_dcone) if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { - nsRect r; fprintf(mDebugFD, "PF::Paint -> %p SupHF: %s Rect: [%5d,%5d,%5d,%5d] SC:%s\n", this, mSupressHF?"Yes":"No", mRect.x, mRect.y, mRect.width, mRect.height, specialClipIsSet?"Yes":"No"); fprintf(stdout, "PF::Paint -> %p SupHF: %s Rect: [%5d,%5d,%5d,%5d] SC:%s\n", this, @@ -690,24 +682,6 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, rect.SetRect(0, 0, mRect.width - mPD->mShadowSize.width, mRect.height - mPD->mShadowSize.height); -#if defined(DEBUG_rods) || defined(DEBUG_dcone) - { - nsRect rct = rect; - // XXX Paint a one-pixel border around the page so it's easy to see where - // each page begins and ends when we're - rct.Deflate(mMargin); - rct.Deflate(mPD->mDeadSpaceMargin); - //float p2t; - //aPresContext->GetPixelsToTwips(&p2t); - //rect.Deflate(NSToCoordRound(p2t), NSToCoordRound(p2t)); - aRenderingContext.SetColor(NS_RGB(0, 0, 0)); - aRenderingContext.DrawRect(rct); - //rect.Inflate(NSToCoordRound(p2t), NSToCoordRound(p2t)); - fprintf(mDebugFD, "PageFr::PaintChild -> Painting Frame %p Page No: %d\n", this, mPageNum); - } -#endif - - aRenderingContext.SetFont(*mPD->mHeadFootFont); aRenderingContext.SetColor(NS_RGB(0,0,0)); diff --git a/mozilla/layout/html/base/src/nsSimplePageSequence.cpp b/mozilla/layout/html/base/src/nsSimplePageSequence.cpp index 53251e242f1..089821697f5 100644 --- a/mozilla/layout/html/base/src/nsSimplePageSequence.cpp +++ b/mozilla/layout/html/base/src/nsSimplePageSequence.cpp @@ -144,6 +144,7 @@ NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) nsSimplePageSequenceFrame::nsSimplePageSequenceFrame() : mIsPrintingSelection(PR_FALSE), + mTotalPages(-1), mSelectionHeight(-1), mYSelOffset(0) { @@ -395,13 +396,24 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics kidSize(nsnull); for (nsIFrame* kidFrame = mFrames.FirstChild(); nsnull != kidFrame; ) { // Reflow the page + // The availableHeight always comes in NS_UNCONSTRAINEDSIZE, so we need to check + // the "adjusted rect" to see if that is being reflowed NS_UNCONSTRAINEDSIZE or not + // When it is NS_UNCONSTRAINEDSIZE it means we are reflowing a single page + // to print selection. So this means we want to use NS_UNCONSTRAINEDSIZE without altering it + nsRect actualRect; + nsRect adjRect; + aPresContext->GetPageDim(&actualRect, &adjRect); + nscoord avHeight; + if (adjRect.height == NS_UNCONSTRAINEDSIZE) { + avHeight = NS_UNCONSTRAINEDSIZE; + } else { + avHeight = pageSize.height+deadSpaceMargin.top+deadSpaceMargin.bottom+shadowSize.height+extraMargin.top+extraMargin.bottom; + } nsSize availSize(pageSize.width+deadSpaceMargin.right+deadSpaceMargin.left+shadowSize.width+extraMargin.right+extraMargin.left, - pageSize.height+deadSpaceMargin.top+deadSpaceMargin.bottom+shadowSize.height+extraMargin.top+extraMargin.bottom); + avHeight); nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, availSize, reflowReason); nsReflowStatus status; - kidReflowState.availableWidth = availSize.width; - kidReflowState.availableHeight = availSize.height; kidReflowState.mComputedWidth = kidReflowState.availableWidth; //kidReflowState.mComputedHeight = kidReflowState.availableHeight; @@ -599,7 +611,7 @@ nsSimplePageSequenceFrame::SetPageNumberFormat(const char* aPropName, const char } -static nsIRegion* CreateRegion() +nsIRegion* nsSimplePageSequenceFrame::CreateRegion() { nsIRegion* region; nsresult rv = nsComponentManager::CreateInstance(kRegionCID, nsnull, NS_GET_IID(nsIRegion), (void**)®ion); @@ -743,9 +755,7 @@ nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext, } // adjust total number of pages - if (nsIPrintSettings::kRangeSelection == mPrintRangeType) { - totalPages = mToPageNum - mFromPageNum + 1; - } else { + if (nsIPrintSettings::kRangeSelection != mPrintRangeType) { totalPages = pageNum - 1; } } @@ -782,9 +792,12 @@ nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext, mPageNum = 1; mPrintedPageNum = 1; - mTotalPages = totalPages; mCurrentPageFrame = mFrames.FirstChild(); + if (mTotalPages == -1) { + mTotalPages = totalPages; + } + return rv; } @@ -854,14 +867,6 @@ nsSimplePageSequenceFrame::PrintNextPage(nsIPresContext* aPresContext) } if (mPrintThisPage) { - if (!mSkipPageBegin) { - PRINT_DEBUG_MSG1("\n***************** BeginPage *****************\n"); - rv = dc->BeginPage(); - if (NS_FAILED(rv)) { - return rv; - } - } - // XXX This is temporary fix for printing more than one page of a selection // This does a poor man's "dump" pagination (see Bug 89353) // It has laid out as one long page and now we are just moving or view up/down @@ -873,6 +878,7 @@ nsSimplePageSequenceFrame::PrintNextPage(nsIPresContext* aPresContext) PRInt32 width, height; dc->GetDeviceSurfaceDimensions(width, height); nsRect clipRect(0, 0, width, height); + nsRect slidingRect(-1, -1, -1, -1); height -= mMargin.top + mMargin.bottom; width -= mMargin.left + mMargin.right; nscoord selectionY = height; @@ -886,25 +892,31 @@ nsSimplePageSequenceFrame::PrintNextPage(nsIPresContext* aPresContext) NS_ASSERTION(containerView != nsnull, "Container view can't be null!"); containerView->GetBounds(containerRect); containerRect.y -= mYSelOffset; - containerRect.height = height-mYSelOffset; + slidingRect.SetRect(0,mYSelOffset,width,height); vm->MoveViewTo(containerView, containerRect.x, containerRect.y); nsRect r(0, 0, containerRect.width, containerRect.height); vm->ResizeView(containerView, r, PR_FALSE); clipRect.SetRect(mMargin.left, mMargin.right, width, height); - - nsPageFrame * pf = NS_STATIC_CAST(nsPageFrame*, childFrame); - nsRect nullClipRect(-1,-1,-1,-1); - pf->SetClipRect(&nullClipRect); } while (continuePrinting) { + if (!mSkipPageBegin) { + PRINT_DEBUG_MSG1("\n***************** BeginPage *****************\n"); + rv = dc->BeginPage(); + if (NS_FAILED(rv)) { + return rv; + } + } // cast the frame to be a page frame nsPageFrame * pf = NS_STATIC_CAST(nsPageFrame*, mCurrentPageFrame); if (pf != nsnull) { pf->SetPageNumInfo(mPrintedPageNum, mTotalPages); pf->SetSharedPageData(mPageData); + if (mSelectionHeight > -1) { + pf->SetClipRect(&slidingRect); + } } // Print the page @@ -946,6 +958,10 @@ nsSimplePageSequenceFrame::PrintNextPage(nsIPresContext* aPresContext) vm->MoveViewTo(containerView, containerRect.x, containerRect.y); nsRect r(0, 0, containerRect.width, containerRect.height); vm->ResizeView(containerView, r, PR_FALSE); + if (pf != nsnull) { + slidingRect.y += height; + } + } else { continuePrinting = PR_FALSE; } diff --git a/mozilla/layout/html/base/src/nsSimplePageSequence.h b/mozilla/layout/html/base/src/nsSimplePageSequence.h index 27016628aca..b92404a202d 100644 --- a/mozilla/layout/html/base/src/nsSimplePageSequence.h +++ b/mozilla/layout/html/base/src/nsSimplePageSequence.h @@ -91,6 +91,7 @@ public: NS_IMETHOD SetOffsets(nscoord aStartOffset, nscoord aEndOffset); NS_IMETHOD SetPageNo(PRInt32 aPageNo) { return NS_OK;} NS_IMETHOD SetSelectionHeight(nscoord aYOffset, nscoord aHeight) { mYSelOffset = aYOffset; mSelectionHeight = aHeight; return NS_OK; } + NS_IMETHOD SetTotalNumPages(PRInt32 aTotal) { mTotalPages = aTotal; return NS_OK; } // Async Printing NS_IMETHOD StartPrint(nsIPresContext* aPresContext, @@ -111,6 +112,9 @@ public: NS_IMETHOD SizeTo(nsIPresContext* aPresContext, nscoord aWidth, nscoord aHeight); + + static nsIRegion* CreateRegion(); + #ifdef NS_DEBUG // Debugging NS_IMETHOD GetFrameName(nsAString& aResult) const; diff --git a/mozilla/mailnews/base/src/nsMsgPrintEngine.cpp b/mozilla/mailnews/base/src/nsMsgPrintEngine.cpp index 96bce1b1e87..a1a7f42b762 100644 --- a/mozilla/mailnews/base/src/nsMsgPrintEngine.cpp +++ b/mozilla/mailnews/base/src/nsMsgPrintEngine.cpp @@ -189,6 +189,10 @@ nsMsgPrintEngine::OnStateChange(nsIWebProgress* aWebProgress, StartNextPrintOperation(); rv = NS_OK; } + } + else + { + mWindow->Close(); } } }