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(); } } }