From b23e7af50b0f956d15976877a6277b014b349b88 Mon Sep 17 00:00:00 2001 From: "rods%netscape.com" Date: Sat, 27 Jan 2001 14:09:34 +0000 Subject: [PATCH] This checkin enables mozilla to support the printing of selection, the printing of page ranges, and the printing of headers and footers. Printing of selection is implemented by the frames figuring out if they are in the selection and painting if they or not they they don't paint. This also only allows the printing of the first page of selections, alothough it is well documented where this is implemeted so it can be removed. Bugs 63426, 31218, 61075 r=dcone,kmcclusk,erik,buster sr=waterson git-svn-id: svn://10.0.0.236/trunk@85624 18797224-902f-48f8-a5cc-f745e15eee43 --- .../mac/build_scripts/MozillaBuildList.pm | 1 + mozilla/content/base/src/nsDocumentViewer.cpp | 771 +++++++++++++++++- mozilla/gfx/idl/nsIPrintOptions.idl | 135 ++- mozilla/gfx/src/gtk/nsDeviceContextSpecG.cpp | 75 +- mozilla/gfx/src/nsPrintOptionsImpl.cpp | 460 ++++++++++- mozilla/gfx/src/nsPrintOptionsImpl.h | 31 +- .../windows/nsDeviceContextSpecFactoryW.cpp | 69 +- mozilla/layout/base/nsCSSFrameConstructor.cpp | 3 +- mozilla/layout/base/nsDocumentViewer.cpp | 771 +++++++++++++++++- mozilla/layout/base/nsPresContext.cpp | 10 + mozilla/layout/base/nsPresContext.h | 6 + mozilla/layout/base/public/nsIFrame.h | 13 + .../layout/base/public/nsIPageSequenceFrame.h | 24 +- mozilla/layout/base/public/nsIPresContext.h | 6 + mozilla/layout/base/public/nsPresContext.h | 6 + mozilla/layout/base/src/nsDocumentViewer.cpp | 771 +++++++++++++++++- mozilla/layout/base/src/nsPresContext.cpp | 10 + mozilla/layout/base/src/nsPresContext.h | 5 +- .../layout/forms/nsComboboxControlFrame.cpp | 4 + mozilla/layout/forms/nsFieldSetFrame.cpp | 7 +- mozilla/layout/forms/nsFileControlFrame.cpp | 7 +- mozilla/layout/forms/nsFormControlFrame.cpp | 4 + mozilla/layout/forms/nsFormControlHelper.cpp | 6 +- mozilla/layout/forms/nsFormControlHelper.h | 7 +- .../layout/forms/nsGfxButtonControlFrame.cpp | 7 +- .../forms/nsGfxCheckboxControlFrame.cpp | 6 +- .../layout/forms/nsGfxRadioControlFrame.cpp | 9 +- .../layout/forms/nsHTMLButtonControlFrame.cpp | 16 +- mozilla/layout/forms/nsIsIndexFrame.cpp | 16 +- mozilla/layout/forms/nsIsIndexFrame.h | 5 + mozilla/layout/forms/nsLegendFrame.cpp | 13 + mozilla/layout/forms/nsLegendFrame.h | 5 + mozilla/layout/forms/nsListControlFrame.cpp | 52 +- mozilla/layout/forms/nsListControlFrame.h | 5 + mozilla/layout/generic/nsBlockFrame.cpp | 13 + mozilla/layout/generic/nsBlockReflowState.cpp | 13 + mozilla/layout/generic/nsBlockReflowState.h | 13 + mozilla/layout/generic/nsBulletFrame.cpp | 7 +- mozilla/layout/generic/nsFrame.cpp | 52 ++ mozilla/layout/generic/nsFrame.h | 6 + mozilla/layout/generic/nsHTMLFrame.cpp | 2 +- mozilla/layout/generic/nsIFrame.h | 13 + mozilla/layout/generic/nsIPageSequenceFrame.h | 24 +- mozilla/layout/generic/nsImageFrame.cpp | 6 +- mozilla/layout/generic/nsLeafFrame.cpp | 6 + mozilla/layout/generic/nsPageFrame.cpp | 285 ++++++- mozilla/layout/generic/nsPageFrame.h | 53 +- .../layout/generic/nsSimplePageSequence.cpp | 345 ++++++-- mozilla/layout/generic/nsSimplePageSequence.h | 26 +- mozilla/layout/generic/nsTextFrame.cpp | 395 +++++++-- .../layout/html/base/src/MANIFEST_PROPERTIES | 1 + mozilla/layout/html/base/src/Makefile.in | 1 + mozilla/layout/html/base/src/jar.mn | 3 + mozilla/layout/html/base/src/makefile.win | 1 + mozilla/layout/html/base/src/nsBlockFrame.cpp | 13 + .../html/base/src/nsBlockReflowState.cpp | 13 + .../layout/html/base/src/nsBlockReflowState.h | 13 + .../layout/html/base/src/nsBulletFrame.cpp | 7 +- mozilla/layout/html/base/src/nsFrame.cpp | 52 ++ mozilla/layout/html/base/src/nsFrame.h | 6 + mozilla/layout/html/base/src/nsHTMLFrame.cpp | 2 +- mozilla/layout/html/base/src/nsImageFrame.cpp | 6 +- mozilla/layout/html/base/src/nsLeafFrame.cpp | 6 + mozilla/layout/html/base/src/nsPageFrame.cpp | 285 ++++++- mozilla/layout/html/base/src/nsPageFrame.h | 53 +- .../html/base/src/nsSimplePageSequence.cpp | 345 ++++++-- .../html/base/src/nsSimplePageSequence.h | 26 +- mozilla/layout/html/base/src/nsTextFrame.cpp | 395 +++++++-- .../layout/html/base/src/printing.properties | 42 + .../html/forms/src/nsComboboxControlFrame.cpp | 4 + .../layout/html/forms/src/nsFieldSetFrame.cpp | 7 +- .../html/forms/src/nsFileControlFrame.cpp | 7 +- .../html/forms/src/nsFormControlFrame.cpp | 4 + .../html/forms/src/nsFormControlHelper.cpp | 6 +- .../html/forms/src/nsFormControlHelper.h | 7 +- .../forms/src/nsGfxButtonControlFrame.cpp | 7 +- .../forms/src/nsGfxCheckboxControlFrame.cpp | 6 +- .../html/forms/src/nsGfxRadioControlFrame.cpp | 9 +- .../html/forms/src/nsGfxTextControlFrame2.cpp | 13 + .../html/forms/src/nsGfxTextControlFrame2.h | 5 + .../forms/src/nsHTMLButtonControlFrame.cpp | 16 +- .../layout/html/forms/src/nsIsIndexFrame.cpp | 16 +- .../layout/html/forms/src/nsIsIndexFrame.h | 5 + .../layout/html/forms/src/nsLabelFrame.cpp | 4 + .../layout/html/forms/src/nsLegendFrame.cpp | 13 + mozilla/layout/html/forms/src/nsLegendFrame.h | 5 + .../html/forms/src/nsListControlFrame.cpp | 52 +- .../html/forms/src/nsListControlFrame.h | 5 + .../html/style/src/nsCSSFrameConstructor.cpp | 3 +- .../html/table/src/nsTableCellFrame.cpp | 4 + .../layout/html/table/src/nsTableColFrame.cpp | 4 + .../html/table/src/nsTableColGroupFrame.cpp | 4 + .../html/table/src/nsTableOuterFrame.cpp | 4 + .../layout/html/table/src/nsTableRowFrame.cpp | 4 + .../html/table/src/nsTableRowGroupFrame.cpp | 4 + mozilla/layout/tables/nsTableCellFrame.cpp | 4 + mozilla/layout/tables/nsTableColFrame.cpp | 4 + .../layout/tables/nsTableColGroupFrame.cpp | 4 + mozilla/layout/tables/nsTableOuterFrame.cpp | 4 + mozilla/layout/tables/nsTableRowFrame.cpp | 4 + .../layout/tables/nsTableRowGroupFrame.cpp | 4 + mozilla/view/public/nsIViewManager.h | 2 +- mozilla/view/src/nsViewManager.cpp | 54 +- mozilla/view/src/nsViewManager.h | 2 +- mozilla/view/src/nsViewManager2.cpp | 55 +- mozilla/view/src/nsViewManager2.h | 2 +- .../resources/content/unix/printdialog.js | 66 +- .../resources/content/unix/printdialog.xul | 24 +- .../locale/en-US/unix/printdialog.dtd | 7 + 109 files changed, 5659 insertions(+), 660 deletions(-) create mode 100644 mozilla/layout/html/base/src/MANIFEST_PROPERTIES create mode 100644 mozilla/layout/html/base/src/jar.mn create mode 100644 mozilla/layout/html/base/src/printing.properties diff --git a/mozilla/build/mac/build_scripts/MozillaBuildList.pm b/mozilla/build/mac/build_scripts/MozillaBuildList.pm index 6758e434e7f..9da35a79281 100644 --- a/mozilla/build/mac/build_scripts/MozillaBuildList.pm +++ b/mozilla/build/mac/build_scripts/MozillaBuildList.pm @@ -297,6 +297,7 @@ sub ProcessJarManifests() CreateJarFromManifest(":mozilla:extensions:wallet:jar.mn", $chrome_dir, \%jars); CreateJarFromManifest(":mozilla:intl:uconv:src:jar.mn", $chrome_dir, \%jars); CreateJarFromManifest(":mozilla:layout:html:forms:src:jar.mn", $chrome_dir, \%jars); + CreateJarFromManifest(":mozilla:layout:html:base:src:jar.mn", $chrome_dir, \%jars); CreateJarFromManifest(":mozilla:mailnews:jar.mn", $chrome_dir, \%jars); CreateJarFromManifest(":mozilla:netwerk:resources:jar.mn", $chrome_dir, \%jars); CreateJarFromManifest(":mozilla:profile:pref-migrator:resources:jar.mn", $chrome_dir, \%jars); diff --git a/mozilla/content/base/src/nsDocumentViewer.cpp b/mozilla/content/base/src/nsDocumentViewer.cpp index d900d3b3abc..b337f40a507 100644 --- a/mozilla/content/base/src/nsDocumentViewer.cpp +++ b/mozilla/content/base/src/nsDocumentViewer.cpp @@ -87,6 +87,13 @@ #include "nsIEventQueueService.h" #include "nsIEventQueue.h" +// Print Options +#include "nsIPrintOptions.h" +#include "nsGfxCIID.h" +#include "nsIServiceManager.h" +static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID); +#include "nsHTMLAtoms.h" // XXX until atoms get factored into nsLayoutAtoms + //focus #include "nsIDOMEventReceiver.h" #include "nsIDOMFocusListener.h" @@ -248,12 +255,16 @@ private: const nsRect& aBounds); nsresult GetDocumentSelection(nsISelection **aSelection); + nsresult GetDocumentSelection(nsIPresShell * aPresShell, nsISelection **aSelection); nsresult FindFrameSetWithIID(nsIContent * aParentContent, const nsIID& aIID); + PRBool IsThereASelection(); // // The following three methods are used for printing... // void DocumentReadyForPrinting(); + //nsresult PrintSelection(nsIDeviceContextSpec * aDevSpec); + nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc); static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent); static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent); @@ -297,6 +308,8 @@ protected: nsIViewManager *mPrintVM; nsIView *mPrintView; FILE *mFilePointer; // a file where information can go to when printing + nsIDocument *mSelectionDoc; + nsIDocShell *mSelectionDocShell; nsCOMPtr mPrintListener; // An observer for printing... @@ -339,6 +352,7 @@ DocumentViewerImpl::DocumentViewerImpl() mEnableRendering = PR_TRUE; mFilePointer = nsnull; mPrintListener = nsnull; + mSelectionDoc = nsnull; } DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext) @@ -879,6 +893,386 @@ DocumentViewerImpl::FindFrameSetWithIID(nsIContent * aParentContent, const nsIID return NS_ERROR_FAILURE; } +//--------------------------------------------------------------- +//--------------------------------------------------------------- +//-- Debug helper routines +//--------------------------------------------------------------- +//--------------------------------------------------------------- +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + +/** --------------------------------------------------- + * Dumps Frames for Printing + */ +static void DumpFrames(FILE* out, + nsIPresContext* aPresContext, + nsIRenderingContext * aRendContext, + nsIFrame * aFrame, + PRInt32 aLevel) +{ + nsIFrame * child; + aFrame->FirstChild(aPresContext, nsnull, &child); + while (child != nsnull) { + for (PRInt32 i=0;iQueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) { + frameDebug->GetFrameName(tmp); + } + fputs(tmp, out); + nsFrameState state; + child->GetFrameState(&state); + PRBool isSelected; + if (NS_SUCCEEDED(child->IsVisibleForPainting(aPresContext, *aRendContext, PR_TRUE, &isSelected))) { + fprintf(out, " %p %s", child, isSelected?"VIS":"UVS"); + nsRect rect; + child->GetRect(rect); + fprintf(out, "[%d,%d,%d,%d] ", rect.x, rect.y, rect.width, rect.height); + nsIView * view; + child->GetView(aPresContext, &view); + fprintf(out, "v: %p ", view); + fprintf(out, "\n"); + DumpFrames(out, aPresContext, aRendContext, child, aLevel+1); + child->GetNextSibling(&child); + } + } +} + +/** --------------------------------------------------- + * Helper function needed for "DumpViews" + */ +static nsIPresShell* +GetPresShellFor(nsIDocShell* aDocShell) +{ + nsIPresShell* shell = nsnull; + if (nsnull != aDocShell) { + nsIContentViewer* cv = nsnull; + aDocShell->GetContentViewer(&cv); + if (nsnull != cv) { + nsIDocumentViewer* docv = nsnull; + cv->QueryInterface(NS_GET_IID(nsIDocumentViewer), (void**) &docv); + if (nsnull != docv) { + nsIPresContext* cx; + docv->GetPresContext(cx); + if (nsnull != cx) { + cx->GetShell(&shell); + NS_RELEASE(cx); + } + NS_RELEASE(docv); + } + NS_RELEASE(cv); + } + } + return shell; +} + +/** --------------------------------------------------- + * Dumps the Views from the DocShell + */ +static void +DumpViews(nsIDocShell* aDocShell, FILE* out) +{ + if (nsnull != aDocShell) { + fprintf(out, "docshell=%p \n", aDocShell); + nsIPresShell* shell = GetPresShellFor(aDocShell); + if (nsnull != shell) { + nsCOMPtr vm; + shell->GetViewManager(getter_AddRefs(vm)); + if (vm) { + nsIView* root; + vm->GetRootView(root); + if (nsnull != root) { + root->List(out); + } + } + NS_RELEASE(shell); + } + else { + fputs("null pres shell\n", out); + } + + // dump the views of the sub documents + PRInt32 i, n; + nsCOMPtr docShellAsNode(do_QueryInterface(aDocShell)); + docShellAsNode->GetChildCount(&n); + for (i = 0; i < n; i++) { + nsCOMPtr child; + docShellAsNode->GetChildAt(i, getter_AddRefs(child)); + nsCOMPtr childAsShell(do_QueryInterface(child)); + if (childAsShell) { + DumpViews(childAsShell, out); + } + } + } +} + +/** --------------------------------------------------- + * Dumps the Views and Frames + */ +void DumpLayoutData(nsIPresContext* aPresContext, + nsIDeviceContext * aDC, + nsIFrame * aRootFrame, + nsIWebShell * aWebShell) +{ + // Dump all the frames and view to a a file + FILE * fd = fopen("dump.txt", "w"); + if (fd) { + fprintf(fd, "--------------- Frames ----------------\n"); + nsCOMPtr renderingContext; + aDC->CreateRenderingContext(*getter_AddRefs(renderingContext)); + DumpFrames(fd, aPresContext, renderingContext, aRootFrame, 0); + fprintf(fd, "---------------------------------------\n\n"); + fprintf(fd, "--------------- Views From Root Frame----------------\n"); + nsIView * v; + aRootFrame->GetView(aPresContext, &v); + if (v) { + v->List(fd); + } else { + printf("View is null!\n"); + } + nsCOMPtr docShell(do_QueryInterface(aWebShell)); + if (docShell) { + fprintf(fd, "--------------- All Views ----------------\n"); + DumpViews(docShell, fd); + fprintf(fd, "---------------------------------------\n\n"); + } + fclose(fd); + } +} + +#endif +//--------------------------------------------------------------- +//--------------------------------------------------------------- +//-- End of debug helper routines +//--------------------------------------------------------------- +//--------------------------------------------------------------- + +/** --------------------------------------------------- + * Giving a child frame it searches "up" the tree until it + * finds a "Page" frame. + */ +static nsIFrame * GetPageFrame(nsIFrame * aFrame) +{ + nsIFrame * frame = aFrame; + while (frame != nsnull) { + nsCOMPtr type; + frame->GetFrameType(getter_AddRefs(type)); + if (type.get() == nsLayoutAtoms::pageFrame) { + return frame; + } + frame->GetParent(&frame); + } + return nsnull; +} + + +/** --------------------------------------------------- + * Find by checking content's tag type + */ +static nsIFrame * FindFrameByType(nsIPresContext* aPresContext, + nsIFrame * aParentFrame, + nsIAtom * aType, + nsRect& aRect, + nsRect& aChildRect) +{ + nsIFrame * child; + nsRect rect; + aParentFrame->GetRect(rect); + aRect.x += rect.x; + aRect.y += rect.y; + aParentFrame->FirstChild(aPresContext, nsnull, &child); + while (child != nsnull) { + nsCOMPtr content; + child->GetContent(getter_AddRefs(content)); + if (content) { + nsCOMPtr type; + content->GetTag(*getter_AddRefs(type)); + if (type.get() == aType) { + nsRect r; + child->GetRect(r); + aChildRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height); + aRect.x -= rect.x; + aRect.y -= rect.y; + return child; + } + } + nsIFrame * fndFrame = FindFrameByType(aPresContext, child, aType, aRect, aChildRect); + if (fndFrame != nsnull) { + return fndFrame; + } + child->GetNextSibling(&child); + } + aRect.x -= rect.x; + aRect.y -= rect.y; + return nsnull; +} + +/** --------------------------------------------------- + * Find by checking frames type + */ +static nsresult FindSelectionBounds(nsIPresContext* aPresContext, + nsIRenderingContext& aRC, + nsIFrame * aParentFrame, + nsRect& aRect, + nsIFrame *& aStartFrame, + nsRect& aStartRect, + nsIFrame *& aEndFrame, + nsRect& aEndRect) +{ + nsIFrame * child; + aParentFrame->FirstChild(aPresContext, nsnull, &child); + nsRect rect; + aParentFrame->GetRect(rect); + aRect.x += rect.x; + aRect.y += rect.y; + while (child != nsnull) { + nsFrameState state; + child->GetFrameState(&state); + // only leaf frames have this bit flipped + // then check the hard way + PRBool isSelected = (state & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + if (isSelected) { + if (NS_FAILED(child->IsVisibleForPainting(aPresContext, aRC, PR_TRUE, &isSelected))) { + return NS_ERROR_FAILURE; + } + } + + if (isSelected) { + nsRect r; + child->GetRect(r); + if (aStartFrame == nsnull) { + aStartFrame = child; + aStartRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height); + } else { + child->GetRect(r); + aEndFrame = child; + aEndRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height); + } + } + FindSelectionBounds(aPresContext, aRC, child, aRect, aStartFrame, aStartRect, aEndFrame, aEndRect); + child->GetNextSibling(&child); + } + aRect.x -= rect.x; + aRect.y -= rect.y; + return NS_OK; +} + +/** --------------------------------------------------- + * This method finds the starting and ending page numbers + * of the selection and also returns rect for each where + * the x,y of the rect is relative to the very top of the + * frame tree (absolutely positioned) + */ +static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, + nsIPresContext* aPresContext, + nsIRenderingContext& aRC, + nsISelection* aSelection, + nsIPageSequenceFrame* aPageSeqFrame, + nsIFrame** aStartFrame, + PRInt32& aStartPageNum, + nsRect& aStartRect, + nsIFrame** aEndFrame, + PRInt32& aEndPageNum, + nsRect& aEndRect) +{ + nsIFrame * seqFrame; + if (NS_FAILED(aPageSeqFrame->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + return NS_ERROR_FAILURE; + } + + nsIFrame * startFrame = nsnull; + nsIFrame * endFrame = nsnull; + nsRect rect; + seqFrame->GetRect(rect); + + // start out with the sequence frame and search the entire frame tree + // capturing the the starting and ending child frames of the selection + // and their rects + FindSelectionBounds(aPresContext, aRC, seqFrame, rect, startFrame, aStartRect, endFrame, aEndRect); + +#ifdef DEBUG_rods + printf("Start Frame: %p\n", startFrame); + printf("End Frame: %p\n", endFrame); +#endif + + // initial the page numbers here + // in case we don't find and frames + aStartPageNum = -1; + aEndPageNum = -1; + + nsIFrame * startPageFrame; + nsIFrame * endPageFrame; + + // check to make sure we found a starting frame + if (startFrame != nsnull) { + // Now search up the tree to find what page the + // start/ending selections frames are on + // + // Check to see if start should be same as end if + // the end frame comes back null + if (endFrame == nsnull) { + // XXX the "GetPageFrame" step could be integrated into + // the FindSelectionBounds step, but walking up to find + // the parent of a child frame isn't expensive and it makes + // FindSelectionBounds a little easier to understand + startPageFrame = GetPageFrame(startFrame); + endPageFrame = startPageFrame; + aEndRect = aStartRect; + } else { + startPageFrame = GetPageFrame(startFrame); + endPageFrame = GetPageFrame(endFrame); + } + } else { + return NS_ERROR_FAILURE; + } + +#ifdef DEBUG_rods + printf("Start Page: %p\n", startPageFrame); + printf("End Page: %p\n", endPageFrame); + + // dump all the pages and their pointers + { + PRInt32 pageNum = 1; + nsIFrame * child; + seqFrame->FirstChild(aPresContext, nsnull, &child); + while (child != nsnull) { + printf("Page: %d - %p\n", pageNum, child); + pageNum++; + child->GetNextSibling(&child); + } + } +#endif + + // Now that we have the page frames + // find out what the page numbers are for each frame + PRInt32 pageNum = 1; + nsIFrame * page; + seqFrame->FirstChild(aPresContext, nsnull, &page); + while (page != nsnull) { + if (page == startPageFrame) { + aStartPageNum = pageNum; + } + if (page == endPageFrame) { + aEndPageNum = pageNum; + } + pageNum++; + page->GetNextSibling(&page); + } + +#ifdef DEBUG_rods + printf("Start Page No: %d\n", aStartPageNum); + printf("End Page No: %d\n", aEndPageNum); +#endif + + *aStartFrame = startPageFrame; + *aEndFrame = endPageFrame; + + return NS_OK; +} + +//------------------------------------------------------- nsresult DocumentViewerImpl::PrintContent(nsIWebShell * aParent, nsIDeviceContext * aDContext) @@ -889,7 +1283,6 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, nsCOMPtr ss; nsCOMPtr vm; PRInt32 width, height; - nsIView *view; nsresult rv; PRInt32 count,i; nsCOMPtr viewer; @@ -922,7 +1315,10 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, nsCOMPtr doc; shell->GetDocument(getter_AddRefs(doc)); if (doc) { - nsCOMPtr rootContent = getter_AddRefs(mDocument->GetRootContent()); + if (mSelectionDoc) { + doc = mSelectionDoc; + } + nsCOMPtr rootContent = getter_AddRefs(doc->GetRootContent()); if (rootContent) { if (NS_SUCCEEDED(FindFrameSetWithIID(rootContent, NS_GET_IID(nsIDOMHTMLFrameSetElement)))) { doesContainFrameSet = PR_TRUE; @@ -955,6 +1351,16 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, NS_ENSURE_SUCCESS( aDContext->BeginDocument(), NS_ERROR_FAILURE ); aDContext->GetDeviceSurfaceDimensions(width, height); + // XXX - Hack Alert + // OK, so ther eis a selection, we will print the entire selection + // on one page and then crop the page. + // This means you can never print any selection that is longer than one page + // put it keeps it from page breaking in the middle of your print of the selection + // (see also nsSimplePageSequence.cpp) + if (IsThereASelection()) { + height = 0x0FFFFFFF; + } + nsCOMPtr cx; nsCOMPtr printcon; rv = NS_NewPrintContext(getter_AddRefs(printcon)); @@ -992,17 +1398,18 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, nsRect tbounds = nsRect(0, 0, width, height); // Create a child window of the parent that is our "root view/window" - rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&view); + nsIView* rootView; + rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&rootView); if (NS_FAILED(rv)) { return rv; } - rv = view->Init(vm, tbounds, nsnull); + rv = rootView->Init(vm, tbounds, nsnull); if (NS_FAILED(rv)) { return rv; } // Setup hierarchical relationship in view manager - vm->SetRootView(view); + vm->SetRootView(rootView); ps->Init(mDocument, cx, vm, ss); @@ -1018,10 +1425,30 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE); presShell->CaptureHistoryState(getter_AddRefs(layoutState),PR_TRUE); + ps->BeginObservingDocument(); //lay it out... ps->InitialReflow(width, height); + // Transfer Selection Ranges to the new Print PresShell + nsCOMPtr selection; + nsCOMPtr selectionPS; + GetDocumentSelection(getter_AddRefs(selection)); + if (selection) { + GetDocumentSelection(ps, getter_AddRefs(selectionPS)); + if (selectionPS) { + PRInt32 cnt; + selection->GetRangeCount(&cnt); + PRInt32 inx; + for (inx=0;inx range; + if (NS_SUCCEEDED(selection->GetRangeAt(inx, getter_AddRefs(range)))) { + selectionPS->AddRange(range); + } + } + } + } + // update the history from the old presentation shell nsCOMPtr fm; rv = ps->GetFrameManager(getter_AddRefs(fm)); @@ -1034,8 +1461,8 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, // Ask the page sequence frame to print all the pages nsIPageSequenceFrame* pageSequence; - nsPrintOptions options; + // ps->GetPageSequenceFrame(&pageSequence); NS_ASSERTION(nsnull != pageSequence, "no page sequence frame"); @@ -1051,7 +1478,97 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, } fclose(mFilePointer); } else { - pageSequence->Print(cx, options, nsnull); + nsIFrame* rootFrame; + ps->GetRootFrame(&rootFrame); + +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + DumpLayoutData(cx, aDContext, rootFrame, aParent); +#endif + + nsPrintRange printRangeType = ePrintRange_AllPages; + NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv); + if (NS_SUCCEEDED(rv) && printService) { + PRInt32 printType; + printService->GetPrintRange(&printType); + printRangeType = (nsPrintRange)printType; + + // get the document title + const nsString* docTitle = mDocument->GetDocumentTitle(); + PRUnichar * docStr = docTitle->ToNewUnicode(); + printService->SetTitle(docStr); + nsMemory::Free(docStr); + + // Get Document URL String + nsCOMPtr url(getter_AddRefs(mDocument->GetDocumentURL())); + char * urlCStr; + url->GetSpec(&urlCStr); + nsAutoString urlStr; + urlStr.AssignWithConversion(urlCStr); + PRUnichar * urlUStr = urlStr.ToNewUnicode(); + printService->SetURL(urlUStr); + nsMemory::Free(urlUStr); + nsMemory::Free(urlCStr); + + if (ePrintRange_Selection == printRangeType) { + cx->SetIsRenderingOnlySelection(PR_TRUE); + + // temporarily creating rendering context + // which is needed to dinf the selection frames + nsCOMPtr rc; + aDContext->CreateRenderingContext(*getter_AddRefs(rc)); + + // find the starting and ending page numbers + // via the selection + nsIFrame* startFrame; + nsIFrame* endFrame; + PRInt32 startPageNum; + PRInt32 endPageNum; + nsRect startRect; + nsRect endRect; + rv = GetPageRangeForSelection(ps, cx, *rc, selectionPS, pageSequence, + &startFrame, startPageNum, startRect, + &endFrame, endPageNum, endRect); + if (NS_SUCCEEDED(rv)) { + printService->SetPageRange(startPageNum, endPageNum); + if (startPageNum == endPageNum) { + nsIFrame * seqFrame; + if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + return NS_ERROR_FAILURE; + } + nsRect rect(0,0,0,0); + nsRect areaRect; + nsIFrame * areaFrame = FindFrameByType(cx, startFrame, nsHTMLAtoms::body, rect, areaRect); + if (areaFrame) { + areaRect.y = areaRect.y - startRect.y; + areaFrame->SetRect(cx, areaRect); + } + } + } + } + + nsIFrame * seqFrame; + if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + return NS_ERROR_FAILURE; + } + + nsRect srect; + seqFrame->GetRect(srect); + + nsRect r; + rootView->GetBounds(r); + r.height = srect.height; + rootView->SetBounds(r); + + rootFrame->GetRect(r); + r.height = srect.height; + rootFrame->SetRect(cx, r); + + pageSequence->Print(cx, printService, nsnull); + + } else { + // not sure what to do here! + return NS_ERROR_FAILURE; + } } aDContext->EndDocument(); @@ -1287,17 +1804,23 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, return rv; } -nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection) +nsresult DocumentViewerImpl::GetDocumentSelection(nsIPresShell * aPresShell, nsISelection **aSelection) { if (!aSelection) return NS_ERROR_NULL_POINTER; - if (!mPresShell) return NS_ERROR_NOT_INITIALIZED; + if (!aPresShell) return NS_ERROR_NULL_POINTER; nsCOMPtr selcon; - selcon = do_QueryInterface(mPresShell); + selcon = do_QueryInterface(aPresShell); if (selcon) return selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, aSelection); return NS_ERROR_FAILURE; } +nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection) +{ + if (!mPresShell) return NS_ERROR_NOT_INITIALIZED; + return GetDocumentSelection(mPresShell, aSelection); +} + NS_IMETHODIMP DocumentViewerImpl::CreateDocumentViewerUsing(nsIPresContext* aPresContext, nsIDocumentViewer*& aResult) @@ -1386,6 +1909,8 @@ void DocumentViewerImpl::DocumentReadyForPrinting() NS_RELEASE(mPrintVM); NS_RELEASE(mPrintSS); NS_RELEASE(mPrintDC); + NS_IF_RELEASE(mSelectionDoc); + } } @@ -1535,6 +2060,198 @@ DocumentViewerImpl::GetSaveable(PRBool *aSaveable) static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTORY_CID); +//------------------------------------------------------------------ +#include "nsINodeInfo.h" +#include "nsIDocument.h" +#include "nsHTMLAtoms.h" +#include "nsIHTMLContent.h" +#include "nsINameSpaceManager.h" +#include "nsIWebShell.h" + +static NS_DEFINE_IID(kWebShellCID, NS_WEB_SHELL_CID); +static NS_DEFINE_IID(kCViewCID, NS_VIEW_CID); +static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID); + +#if 0 +nsresult +DocumentViewerImpl::CreateDocShell(nsIPresContext* aPresContext, const nsSize& aSize) +{ + nsresult rv; + mSelectionDocShell = do_CreateInstance(kWebShellCID); + NS_ENSURE_TRUE(mSelectionDocShell, NS_ERROR_FAILURE); + + // pass along marginwidth and marginheight so sub document can use it + mSelectionDocShell->SetMarginWidth(0); + mSelectionDocShell->SetMarginHeight(0); + + /* our parent must be a docshell. we need to get our prefs from our parent */ + nsCOMPtr container; + aPresContext->GetContainer(getter_AddRefs(container)); + NS_ENSURE_TRUE(container, NS_ERROR_UNEXPECTED); + + nsCOMPtr outerShell = do_QueryInterface(container); + NS_ENSURE_TRUE(outerShell, NS_ERROR_UNEXPECTED); + + float t2p; + aPresContext->GetTwipsToPixels(&t2p); + nsCOMPtr presShell; + rv = aPresContext->GetShell(getter_AddRefs(presShell)); + if (NS_FAILED(rv)) { return rv; } + + // create, init, set the parent of the view + nsIView* view; + rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, NS_GET_IID(nsIView), + (void **)&view); + if (NS_FAILED(rv)) { return rv; } + + nsIView* parView; + nsPoint origin; + GetOffsetFromView(aPresContext, origin, &parView); + + nsRect viewBounds(origin.x, origin.y, aSize.width, aSize.height); +#ifdef NOISY + printf("%p view bounds: x=%d, y=%d, w=%d, h=%d\n", view, origin.x, origin.y, aSize.width, aSize.height); +#endif + + nsCOMPtr viewMan; + presShell->GetViewManager(getter_AddRefs(viewMan)); + rv = view->Init(viewMan, viewBounds, parView); + if (NS_FAILED(rv)) { return rv; } + viewMan->InsertChild(parView, view, 0); + rv = view->CreateWidget(kCChildCID); + if (NS_FAILED(rv)) { return rv; } + SetView(aPresContext, view); + + // if the visibility is hidden, reflect that in the view + const nsStyleDisplay* display; + GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display)); + if (!display->IsVisible()) { + view->SetVisibility(nsViewVisibility_kHide); + } + + const nsStyleSpacing* spacing; + GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing); + nsMargin border; + spacing->CalcBorderFor(this, border); + + nsCOMPtr widget; + view->GetWidget(*getter_AddRefs(widget)); + + mSelectionDocShell->SetAllowPlugins(PR_FALSE); + nsCOMPtr docShellAsWin(do_QueryInterface(mSelectionDocShell)); + + PRInt32 x = NSToCoordRound(border.left * t2p); + PRInt32 y = NSToCoordRound(border.top * t2p); + PRInt32 cx = NSToCoordRound((aSize.width - border.right) * t2p); + PRInt32 cy = NSToCoordRound((aSize.height - border.bottom) * t2p); + NS_ENSURE_SUCCESS(docShellAsWin->InitWindow(nsnull, widget, (x >= 0) ? x : 0, + (y >= 0) ? y : 0, cx, cy), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(docShellAsWin->Create(), NS_ERROR_FAILURE); + + // move the view to the proper location + viewMan->MoveViewTo(view, origin.x, origin.y); + + mSelectionDocShell->SetDocLoaderObserver(mTempObserver); + + PRInt32 type; + GetType(&type); + if ((PR_FALSE==IsSingleLineTextControl()) || (NS_FORM_INPUT_PASSWORD == type)) { + docShellAsWin->SetVisibility(PR_TRUE); + } + return NS_OK; +} +#endif + +//nsresult DocumentViewerImpl::PrintSelection(nsIDeviceContextSpec * aDevSpec) +nsresult DocumentViewerImpl::GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc) +{ + //NS_ENSURE_ARG_POINTER(*aDevSpec); + NS_ENSURE_ARG_POINTER(aNewDoc); + + // create document + nsCOMPtr doc; + nsresult rv = NS_NewHTMLDocument(getter_AddRefs(doc)); + if (NS_FAILED(rv)) { return rv; } + if (!doc) { return NS_ERROR_NULL_POINTER; } + + nsCOMPtr nimgr; + rv = doc->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr nodeInfo; + nimgr->GetNodeInfo(nsHTMLAtoms::html, nsnull, kNameSpaceID_None, + *getter_AddRefs(nodeInfo)); + + // create document content + nsCOMPtr htmlElement; + nsCOMPtr headElement; + nsCOMPtr bodyElement; + // create the root + rv = NS_NewHTMLHtmlElement(getter_AddRefs(htmlElement), nodeInfo); + if (NS_FAILED(rv)) { return rv; } + if (!htmlElement) { return NS_ERROR_NULL_POINTER; } + // create the head + + nimgr->GetNodeInfo(NS_ConvertASCIItoUCS2("head"), nsnull, + kNameSpaceID_None, *getter_AddRefs(nodeInfo)); + + rv = NS_NewHTMLHeadElement(getter_AddRefs(headElement), nodeInfo); + if (NS_FAILED(rv)) { return rv; } + if (!headElement) { return NS_ERROR_NULL_POINTER; } + headElement->SetDocument(doc, PR_FALSE, PR_TRUE); + // create the body + + nimgr->GetNodeInfo(nsHTMLAtoms::body, nsnull, kNameSpaceID_None, + *getter_AddRefs(nodeInfo)); + + rv = NS_NewHTMLBodyElement(getter_AddRefs(bodyElement), nodeInfo); + if (NS_FAILED(rv)) { return rv; } + if (!bodyElement) { return NS_ERROR_NULL_POINTER; } + bodyElement->SetDocument(doc, PR_FALSE, PR_TRUE); + // put the head and body into the root + rv = htmlElement->AppendChildTo(headElement, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } + rv = htmlElement->AppendChildTo(bodyElement, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } + + // load the document into the docshell + nsCOMPtr domDoc = do_QueryInterface(doc); + if (!domDoc) { return NS_ERROR_NULL_POINTER; } + nsCOMPtr htmlDOMElement = do_QueryInterface(htmlElement); + if (!htmlDOMElement) { return NS_ERROR_NULL_POINTER; } + + //nsCOMPtr rootContent(do_QueryInterface(htmlElement)); + //doc->SetRootContent(rootContent); + + *aNewDoc = doc.get(); + NS_ADDREF(*aNewDoc); + + return rv; + +} + +PRBool +DocumentViewerImpl::IsThereASelection() +{ + // check here to see if there is a range selection + // so we know whether to turn on the "Selection" radio button + nsCOMPtr selection; + GetDocumentSelection(getter_AddRefs(selection)); + if (selection) { + PRInt32 count; + selection->GetRangeCount(&count); + if (count == 1) { + nsCOMPtr range; + if (NS_SUCCEEDED(selection->GetRangeAt(0, getter_AddRefs(range)))) { + // check to make sure it isn't an insertion selection + PRBool isCollapsed; + selection->GetIsCollapsed(&isCollapsed); + return !isCollapsed; + } + } + } + return PR_FALSE; +} /** --------------------------------------------------- * See documentation above in the nsIContentViewerfile class definition @@ -1543,9 +2260,15 @@ static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTOR NS_IMETHODIMP DocumentViewerImpl::Print(PRBool aSilent,FILE *aFile, nsIPrintListener *aPrintListener) { -nsCOMPtr webContainer; -nsCOMPtr factory; -PRInt32 width,height; + nsCOMPtr webContainer; + nsCOMPtr factory; + PRInt32 width,height; + + nsresult rv = NS_ERROR_FAILURE; + NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv); + if (NS_SUCCEEDED(rv) && printService) { + printService->SetPrintOptions(NS_PRINT_OPTIONS_ENABLE_SELECTION_RADIO, IsThereASelection()); + } nsComponentManager::CreateInstance(kDeviceContextSpecFactoryCID, nsnull, @@ -1566,11 +2289,14 @@ PRInt32 width,height; factory->CreateDeviceContextSpec(nsnull, devspec, aSilent); if (nsnull != devspec) { mPresContext->GetDeviceContext(getter_AddRefs(dx)); - nsresult rv = dx->GetDeviceContextFor(devspec, mPrintDC); + rv = dx->GetDeviceContextFor(devspec, mPrintDC); if (NS_SUCCEEDED(rv)) { NS_RELEASE(devspec); + nsCOMPtr printDoc; + printDoc = mDocument; + // Get the webshell for this documentviewer webContainer = do_QueryInterface(mContainer); if(webContainer) { @@ -1588,15 +2314,24 @@ PRInt32 width,height; mPrintDC->GetDeviceSurfaceDimensions(width,height); + // XXX - Hack Alert + // OK, so ther eis a selection, we will print the entire selection + // on one page and then crop the page. + // This means you can never print any selection that is longer than one page + // put it keeps it from page breaking in the middle of your print of the selection + if (IsThereASelection()) { + height = 0x0FFFFFFF; + } + mPrintPC->Init(mPrintDC); mPrintPC->SetContainer(webContainer); - CreateStyleSet(mDocument,&mPrintSS); + CreateStyleSet(printDoc,&mPrintSS); rv = NS_NewPresShell(&mPrintPS); if(NS_FAILED(rv)){ return rv; } - + rv = nsComponentManager::CreateInstance(kViewManagerCID, nsnull, NS_GET_IID(nsIViewManager),(void**)&mPrintVM); if(NS_FAILED(rv)) { return rv; @@ -1611,7 +2346,7 @@ PRInt32 width,height; if(NS_FAILED(rv)) { return rv; } - + nsRect tbounds = nsRect(0,0,width,height); rv = mPrintView->Init(mPrintVM,tbounds,nsnull); if(NS_FAILED(rv)) { @@ -1620,7 +2355,7 @@ PRInt32 width,height; // setup hierarchical relationship in view manager mPrintVM->SetRootView(mPrintView); - mPrintPS->Init(mDocument,mPrintPC,mPrintVM,mPrintSS); + mPrintPS->Init(printDoc,mPrintPC,mPrintVM,mPrintSS); nsCOMPtr imageGroup; mPrintPC->GetImageGroup(getter_AddRefs(imageGroup)); diff --git a/mozilla/gfx/idl/nsIPrintOptions.idl b/mozilla/gfx/idl/nsIPrintOptions.idl index 739fc991fcb..cc1bab88ce8 100644 --- a/mozilla/gfx/idl/nsIPrintOptions.idl +++ b/mozilla/gfx/idl/nsIPrintOptions.idl @@ -23,6 +23,44 @@ #include "nsISupports.idl" +%{ C++ +#include "nsMargin.h" +#include "nsFont.h" + + enum nsPrintRange { + ePrintRange_AllPages, // print all pages + ePrintRange_SpecifiedPageRange, // only print pages in the specified range + ePrintRange_Selection, // only print the selection + ePrintRange_FocusFrame // only print the frame with the current focus + }; + + /** + * Print Option Printing state bits. + */ + typedef PRUint32 nsPrintOptionsType; + +#define NS_PRINT_OPTIONS_PRINT_ODD_PAGES 0x00000001 +#define NS_PRINT_OPTIONS_PRINT_EVEN_PAGES 0x00000002 +#define NS_PRINT_OPTIONS_PRINT_DOC_TITLE 0x00000004 +#define NS_PRINT_OPTIONS_PRINT_DOC_LOCATION 0x00000008 +#define NS_PRINT_OPTIONS_PRINT_PAGE_NUMS 0x00000010 +#define NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL 0x00000020 +#define NS_PRINT_OPTIONS_PRINT_DATE_PRINTED 0x00000040 +#define NS_PRINT_OPTIONS_ENABLE_SELECTION_RADIO 0x00000080 + +// There are currently NOT supported +#define NS_PRINT_OPTIONS_PRINT_BEVEL_LINES 0x00000100 +#define NS_PRINT_OPTIONS_PRINT_BLACK_TEXT 0x00000200 +#define NS_PRINT_OPTIONS_PRINT_BLACK_LINES 0x00000400 +#define NS_PRINT_OPTIONS_PRINT_LAST_PAGE_FIRST 0x00000800 +#define NS_PRINT_OPTIONS_PRINT_BACKGROUNDS 0x00001000 + +// Justification Flags +#define NS_PRINT_JUSTIFY_LEFT 0x00000001 +#define NS_PRINT_JUSTIFY_CENTER 0x00000002 +#define NS_PRINT_JUSTIFY_RIGHT 0x00000004 + +%} /** * Simplified graphics interface for JS rendering. @@ -32,14 +70,107 @@ interface nsIPrintOptions : nsISupports { +%{C++ + // Set Default Font of Header and footer + NS_IMETHOD SetDefaultFont(const nsFont &aFont) = 0; + NS_IMETHOD SetFontNamePointSize(const nsString& aFontName, nscoord aPointSize) = 0; + + NS_IMETHOD GetDefaultFont(nsFont &aFont) = 0; + + + // non-scriptable helper method + NS_IMETHOD GetMargin(nsMargin& aMargin) = 0; +%} /** - * PageMargin. + * Set PageMargins */ void SetMargins(in PRInt32 aTop, in PRInt32 aLeft, in PRInt32 aRight, in PRInt32 aBottom); - + + /** + * Get PageMargins + */ void GetMargins(out PRInt32 aTop, out PRInt32 aLeft, out PRInt32 aRight, out PRInt32 aBottom); + + /** + * Show Native Print Options dialog, this may not be supported on all platforms + */ void ShowNativeDialog(); + /** + * Set Print Range + */ + void SetPrintRange(in PRInt32 aPrintRange); + + /** + * Get Print Range + */ + void GetPrintRange(out PRInt32 aPrintRange); + + /** + * Set Page Range + */ + void SetPageRange(in PRInt32 aStartPage, in PRInt32 aEndPage); + + /** + * Get Page Range + */ + void GetPageRange(out PRInt32 aStartPage, out PRInt32 aEndPage); + + /** + * Set PrintOptions + */ + void SetPrintOptions(in PRInt32 aType, in PRBool aTurnOnOff); + + /** + * Get PrintOptions + */ + void GetPrintOptions(in PRInt32 aType, out PRBool aTurnOnOff); + + /** + * Set PrintOptions Bit field + */ + void GetPrintOptionsBits(out PRInt32 aBits); + + /** + * Set Title field for Header + */ + void SetTitle(in wstring aTitle); + + /** + * Get Title field for Header + */ + void GetTitle(out wstring aTitle); + + /** + * Set URL field for Header + */ + void SetURL(in wstring aURL); + + /** + * Get URL field for Header + */ + void GetURL(out wstring aURL); + + /** + * Set Page Number Print Justification + */ + void SetPageNumJust(in PRInt32 aJust); + + /** + * Set Page Number Print Justification + */ + void GetPageNumJust(out PRInt32 aJust); + + /** + * Read Prefs + */ + void ReadPrefs(); + + /** + * Write Prefs + */ + void WritePrefs(); + }; diff --git a/mozilla/gfx/src/gtk/nsDeviceContextSpecG.cpp b/mozilla/gfx/src/gtk/nsDeviceContextSpecG.cpp index 558cd9de5aa..bceb667e2fe 100644 --- a/mozilla/gfx/src/gtk/nsDeviceContextSpecG.cpp +++ b/mozilla/gfx/src/gtk/nsDeviceContextSpecG.cpp @@ -24,6 +24,8 @@ #include "nsCOMPtr.h" #include "nsIServiceManager.h" +#include "nsIPrintOptions.h" +#include "nsGfxCIID.h" #include "nsIPref.h" #include "prenv.h" /* for PR_GetEnv */ @@ -36,6 +38,7 @@ static NS_DEFINE_IID( kAppShellServiceCID, NS_APPSHELL_SERVICE_CID ); static NS_DEFINE_CID(kDialogParamBlockCID, NS_DialogParamBlock_CID); +static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID); //#include "prmem.h" //#include "plstr.h" @@ -124,16 +127,30 @@ NS_IMPL_RELEASE(nsDeviceContextSpecGTK) */ NS_IMETHODIMP nsDeviceContextSpecGTK :: Init(PRBool aQuiet) { + nsresult rv = NS_ERROR_FAILURE; + NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv); + + // if there is a current selection then enable the "Selection" radio button + if (NS_SUCCEEDED(rv) && printService) { + PRBool isOn; + printService->GetPrintOptions(NS_PRINT_OPTIONS_ENABLE_SELECTION_RADIO, &isOn); + nsCOMPtr pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv) && pPrefs) { + (void) pPrefs->SetBoolPref("print.selection_radio_enabled", isOn); + } + } + char *path; PRBool reversed = PR_FALSE, color = PR_FALSE, landscape = PR_FALSE; - PRBool tofile = PR_FALSE; + PRBool tofile = PR_FALSE, allpagesRange = PR_TRUE, pageRange = PR_FALSE, selectionRange = PR_FALSE; PRInt32 paper_size = NS_LETTER_SIZE; - int ileft = 500, iright = 0, itop = 500, ibottom = 0; + PRInt32 fromPage = 1, toPage = 1; + int ileft = 500, iright = 500, itop = 500, ibottom = 500; char *command; char *printfile = nsnull; - nsresult rv = NS_OK; + rv = NS_OK; nsCOMPtr ioParamBlock; rv = nsComponentManager::CreateInstance(kDialogParamBlockCID, @@ -179,14 +196,58 @@ NS_IMETHODIMP nsDeviceContextSpecGTK :: Init(PRBool aQuiet) (void) pPrefs->GetBoolPref("print.print_landscape", &landscape); (void) pPrefs->GetIntPref("print.print_paper_size", &paper_size); (void) pPrefs->CopyCharPref("print.print_command", (char **) &command); - (void) pPrefs->GetIntPref("print.print_margin_top", &itop); - (void) pPrefs->GetIntPref("print.print_margin_left", &ileft); - (void) pPrefs->GetIntPref("print.print_margin_bottom", &ibottom); - (void) pPrefs->GetIntPref("print.print_margin_right", &iright); + + // the _js extention means these were set via script with the xp + // dialog as integers, int * 1000, meaning a 0.5 inches is 500 + // the "real" values are set into the prefs as strings + // the PrintOption object will save out these values as twips + // in the prefs with these names without the _js extention + (void) pPrefs->GetIntPref("print.print_margin_top_js", &itop); + (void) pPrefs->GetIntPref("print.print_margin_left_js", &ileft); + (void) pPrefs->GetIntPref("print.print_margin_bottom_js", &ibottom); + (void) pPrefs->GetIntPref("print.print_margin_right_js", &iright); + (void) pPrefs->CopyCharPref("print.print_file", (char **) &printfile); (void) pPrefs->GetBoolPref("print.print_tofile", &tofile); + + (void) pPrefs->GetBoolPref("print.print_allpagesrange", &allpagesRange); + (void) pPrefs->GetBoolPref("print.print_pagerange", &pageRange); + (void) pPrefs->GetBoolPref("print.print_selectionrange", &selectionRange); + (void) pPrefs->GetIntPref("print.print_frompage", &fromPage); + (void) pPrefs->GetIntPref("print.print_topage", &toPage); sprintf( mPrData.command, command ); sprintf( mPrData.path, printfile ); + + // fill the print options with the info from the dialog + if(printService) { + // convert the script values to twips + nsMargin margin; + margin.SizeTo(NS_INCHES_TO_TWIPS(float(ileft)/1000.0), + NS_INCHES_TO_TWIPS(float(itop)/1000.0), + NS_INCHES_TO_TWIPS(float(iright)/1000.0), + NS_INCHES_TO_TWIPS(float(ibottom)/1000.0)); + printService->SetMargins(margin.top, margin.left, margin.right, margin.bottom); +#ifdef DEBUG_rods + printf("margins: %d,%d,%d,%d\n", itop, ileft, ibottom, iright); + printf("margins: %d,%d,%d,%d (twips)\n", margin.top, margin.left, margin.bottom, margin.right); + printf("allpagesRange %d\n", allpagesRange); + printf("pageRange %d\n", pageRange); + printf("selectionRange %d\n", selectionRange); + printf("fromPage %d\n", fromPage); + printf("toPage %d\n", toPage); +#endif + if (selectionRange) { + printService->SetPrintRange(ePrintRange_Selection); + + } else if (pageRange) { + printService->SetPrintRange(ePrintRange_SpecifiedPageRange); + printService->SetPageRange(fromPage, toPage); + + } else { // (allpagesRange) + printService->SetPrintRange(ePrintRange_AllPages); + } + } + } else { #ifndef VMS sprintf( mPrData.command, "lpr" ); diff --git a/mozilla/gfx/src/nsPrintOptionsImpl.cpp b/mozilla/gfx/src/nsPrintOptionsImpl.cpp index 20fbaf72470..ed6f1d16d6b 100644 --- a/mozilla/gfx/src/nsPrintOptionsImpl.cpp +++ b/mozilla/gfx/src/nsPrintOptionsImpl.cpp @@ -21,18 +21,72 @@ */ #include "nsPrintOptionsImpl.h" +#include "nsCoord.h" +#include "nsUnitConversion.h" +// For Prefs +#include "nsIPref.h" +#include "nsIServiceManager.h" NS_IMPL_ISUPPORTS1(nsPrintOptions, nsIPrintOptions) +// Pref Constants +const char * kMarginTop = "print.print_margin_top"; +const char * kMarginLeft = "print.print_margin_left"; +const char * kMarginBottom = "print.print_margin_bottom"; +const char * kMarginRight = "print.print_margin_right"; + +// Prefs for Print Option +const char * kPrintEvenPages = "print.print_evenpages"; +const char * kPrintOddPages = "print.print_oddpages"; +const char * kPrintDocTitle = "print.print_doctitle"; +const char * kPrintDocLoc = "print.print_doclocation"; +const char * kPageNums = "print.print_pagenumbers"; +const char * kPageNumsJust = "print.print_pagenumjust"; +const char * kPrintPageTotals = "print.print_pagetotals"; +const char * kPrintDate = "print.print_date"; + +// There are currently NOT supported +//const char * kPrintBevelLines = "print.print_bevellines"; +//const char * kPrintBlackText = "print.print_blacktext"; +//const char * kPrintBlackLines = "print.print_blacklines"; +//const char * kPrintLastPageFirst = "print.print_lastpagefirst"; +//const char * kPrintBackgrounds = "print.print_backgrounds"; + +const char * kLeftJust = "left"; +const char * kCenterJust = "center"; +const char * kRightJust = "right"; + +#define form_properties "chrome://communicator/locale/printing.properties" + /** --------------------------------------------------- * See documentation in nsPrintOptionsImpl.h * @update 6/21/00 dwc */ -nsPrintOptions::nsPrintOptions() +nsPrintOptions::nsPrintOptions() : + mPrintRange(ePrintRange_AllPages), + mStartPageNum(0), + mEndPageNum(0), + mPrintOptions(0L) { NS_INIT_ISUPPORTS(); + /* member initializers and constructor code */ + nscoord halfInch = NS_INCHES_TO_TWIPS(0.5); + SetMargins(halfInch, halfInch, halfInch, halfInch); + + mPrintOptions = NS_PRINT_OPTIONS_PRINT_EVEN_PAGES | + NS_PRINT_OPTIONS_PRINT_ODD_PAGES | + NS_PRINT_OPTIONS_PRINT_DOC_LOCATION | + NS_PRINT_OPTIONS_PRINT_DOC_TITLE | + NS_PRINT_OPTIONS_PRINT_PAGE_NUMS | + NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL | + NS_PRINT_OPTIONS_PRINT_DATE_PRINTED; + + mDefaultFont = new nsFont("Times", NS_FONT_STYLE_NORMAL,NS_FONT_VARIANT_NORMAL, + NS_FONT_WEIGHT_NORMAL,0,NSIntPointsToTwips(10)); + + ReadPrefs(); } /** --------------------------------------------------- @@ -41,20 +95,79 @@ nsPrintOptions::nsPrintOptions() */ nsPrintOptions::~nsPrintOptions() { - /* destructor code */ + if (mDefaultFont != nsnull) { + delete mDefaultFont; + } +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::SetDefaultFont(const nsFont &aFont) +{ + if (mDefaultFont != nsnull) { + delete mDefaultFont; + } + mDefaultFont = new nsFont(aFont); + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::SetFontNamePointSize(const nsString& aFontName, nscoord aPointSize) +{ + if (mDefaultFont != nsnull && aFontName.Length() > 0 && aPointSize > 0) { + mDefaultFont->name = aFontName; + mDefaultFont->size = NSIntPointsToTwips(aPointSize); + } + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::GetDefaultFont(nsFont &aFont) +{ + aFont = *mDefaultFont; + return NS_OK; } /** --------------------------------------------------- * See documentation in nsPrintOptionsImpl.h * @update 6/21/00 dwc + * @update 1/12/01 rods */ NS_IMETHODIMP nsPrintOptions::SetMargins(PRInt32 aTop, PRInt32 aLeft, PRInt32 aRight, PRInt32 aBottom) { - mTopMargin = aTop; - mLeftMargin = aLeft; - mRightMargin = aRight; - mBottomMargin = aBottom; + mMargin.SizeTo(aLeft, aTop, aRight, aBottom); + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 6/21/00 dwc + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::GetMargins(PRInt32 *aTop, PRInt32 *aLeft, PRInt32 *aRight, PRInt32 *aBottom) +{ + NS_ENSURE_ARG_POINTER(aTop); + NS_ENSURE_ARG_POINTER(aLeft); + NS_ENSURE_ARG_POINTER(aRight); + NS_ENSURE_ARG_POINTER(aBottom); + + *aTop = mMargin.top; + *aLeft = mMargin.left; + *aRight = mMargin.right; + *aBottom = mMargin.bottom; return NS_OK; } @@ -64,13 +177,10 @@ nsPrintOptions::SetMargins(PRInt32 aTop, PRInt32 aLeft, PRInt32 aRight, PRInt32 * @update 6/21/00 dwc */ NS_IMETHODIMP -nsPrintOptions::GetMargins(PRInt32 *aTop, PRInt32 *aLeft, PRInt32 *aRight, PRInt32 *aBottom) +nsPrintOptions::GetMargin(nsMargin& aMargin) { - *aTop = mTopMargin; - *aLeft = mLeftMargin; - *aRight = mRightMargin; - *aBottom = mBottomMargin; - + aMargin = mMargin; + //aMargin.SizeTo(mLeftMargin, mTopMargin, mRightMargin, mBottomMargin); return NS_OK; } @@ -84,3 +194,329 @@ nsPrintOptions::ShowNativeDialog() return NS_OK; } + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::SetPrintRange(PRInt32 aPrintRange) +{ + mPrintRange = (nsPrintRange)aPrintRange; + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::GetPrintRange(PRInt32 *aPrintRange) +{ + NS_ENSURE_ARG_POINTER(aPrintRange); + + *aPrintRange = (PRInt32)mPrintRange; + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::SetPageRange(PRInt32 aStartPage, PRInt32 aEndPage) +{ + mStartPageNum = aStartPage; + mEndPageNum = aEndPage; + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::GetPageRange(PRInt32 *aStartPage, PRInt32 *aEndPage) +{ + NS_ENSURE_ARG_POINTER(aStartPage); + NS_ENSURE_ARG_POINTER(aEndPage); + *aStartPage = mStartPageNum; + *aEndPage = mEndPageNum; + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::SetPrintOptions(PRInt32 aType, PRBool aTurnOnOff) +{ + if (aTurnOnOff) { + mPrintOptions |= aType; + } else { + mPrintOptions &= ~aType; + } + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::GetPrintOptions(PRInt32 aType, PRBool *aTurnOnOff) +{ + NS_ENSURE_ARG_POINTER(aTurnOnOff); + *aTurnOnOff = mPrintOptions & aType; + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::GetPrintOptionsBits(PRInt32 *aBits) +{ + NS_ENSURE_ARG_POINTER(aBits); + *aBits = mPrintOptions; + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::SetTitle(const PRUnichar *aTitle) +{ + NS_ENSURE_ARG_POINTER(aTitle); + mTitle = aTitle; + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::GetTitle(PRUnichar **aTitle) +{ + NS_ENSURE_ARG_POINTER(aTitle); + *aTitle = mTitle.ToNewUnicode(); + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::SetURL(const PRUnichar *aURL) +{ + NS_ENSURE_ARG_POINTER(aURL); + mURL = aURL; + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::GetURL(PRUnichar **aURL) +{ + NS_ENSURE_ARG_POINTER(aURL); + *aURL = mURL.ToNewUnicode(); + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::SetPageNumJust(PRInt32 aJust) +{ + mPageNumJust = aJust; + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::GetPageNumJust(PRInt32 *aJust) +{ + NS_ENSURE_ARG_POINTER(aJust); + + *aJust = (PRInt32)mPageNumJust; + return NS_OK; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::ReadPrefs() +{ + nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID); + if (prefs) { + ReadInchesToTwipsPref(prefs, kMarginTop, mMargin.top); + ReadInchesToTwipsPref(prefs, kMarginLeft, mMargin.left); + ReadInchesToTwipsPref(prefs, kMarginBottom, mMargin.bottom); + ReadInchesToTwipsPref(prefs, kMarginRight, mMargin.right); + + ReadBitFieldPref(prefs, kPrintEvenPages, NS_PRINT_OPTIONS_PRINT_EVEN_PAGES); + ReadBitFieldPref(prefs, kPrintOddPages, NS_PRINT_OPTIONS_PRINT_ODD_PAGES); + ReadBitFieldPref(prefs, kPrintDocTitle, NS_PRINT_OPTIONS_PRINT_DOC_TITLE); + ReadBitFieldPref(prefs, kPrintDocLoc, NS_PRINT_OPTIONS_PRINT_DOC_LOCATION); + ReadBitFieldPref(prefs, kPageNums, NS_PRINT_OPTIONS_PRINT_PAGE_NUMS); + ReadBitFieldPref(prefs, kPrintPageTotals, NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL); + ReadBitFieldPref(prefs, kPrintDate, NS_PRINT_OPTIONS_PRINT_DATE_PRINTED); + + ReadJustification(prefs, kPageNumsJust, mPageNumJust, NS_PRINT_JUSTIFY_LEFT); + + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +/** --------------------------------------------------- + * See documentation in nsPrintOptionsImpl.h + * @update 1/12/01 rods + */ +NS_IMETHODIMP +nsPrintOptions::WritePrefs() +{ + nsCOMPtr prefs = do_GetService(NS_PREF_CONTRACTID); + if (prefs) { + WriteInchesFromTwipsPref(prefs, kMarginTop, mMargin.top); + WriteInchesFromTwipsPref(prefs, kMarginLeft, mMargin.left); + WriteInchesFromTwipsPref(prefs, kMarginBottom, mMargin.bottom); + WriteInchesFromTwipsPref(prefs, kMarginRight, mMargin.right); + + WriteBitFieldPref(prefs, kPrintEvenPages, NS_PRINT_OPTIONS_PRINT_EVEN_PAGES); + WriteBitFieldPref(prefs, kPrintOddPages, NS_PRINT_OPTIONS_PRINT_ODD_PAGES); + WriteBitFieldPref(prefs, kPrintDocTitle, NS_PRINT_OPTIONS_PRINT_DOC_TITLE); + WriteBitFieldPref(prefs, kPrintDocLoc, NS_PRINT_OPTIONS_PRINT_DOC_LOCATION); + WriteBitFieldPref(prefs, kPageNums, NS_PRINT_OPTIONS_PRINT_PAGE_NUMS); + WriteBitFieldPref(prefs, kPrintPageTotals, NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL); + WriteBitFieldPref(prefs, kPrintDate, NS_PRINT_OPTIONS_PRINT_DATE_PRINTED); + + WriteJustification(prefs, kPageNumsJust, mPageNumJust); + + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +//----------------------------------------------------- +//-- Protected Methods +//----------------------------------------------------- +void nsPrintOptions::ReadBitFieldPref(nsIPref * aPref, + const char * aPrefId, + PRInt32 anOption) +{ + PRBool b; + if (NS_SUCCEEDED(aPref->GetBoolPref(aPrefId, &b))) { + SetPrintOptions(anOption, b); + } +} + +//--------------------------------------------------- +void nsPrintOptions::WriteBitFieldPref(nsIPref * aPref, + const char * aPrefId, + PRInt32 anOption) +{ + PRBool b; + GetPrintOptions(anOption, &b); + aPref->SetBoolPref(aPrefId, b); +} + +//--------------------------------------------------- +void nsPrintOptions::ReadInchesToTwipsPref(nsIPref * aPref, + const char * aPrefId, + nscoord& aTwips) +{ + char * str = nsnull; + nsresult rv = aPref->CopyCharPref(aPrefId, &str); + if (NS_SUCCEEDED(rv) && str) { + nsAutoString justStr; + justStr.AssignWithConversion(str); + PRInt32 errCode; + float inches = justStr.ToFloat(&errCode); + if (NS_SUCCEEDED(errCode)) { + aTwips = NS_INCHES_TO_TWIPS(inches); + } else { + aTwips = 0; + } + nsMemory::Free(str); + } +} + +//--------------------------------------------------- +void nsPrintOptions::WriteInchesFromTwipsPref(nsIPref * aPref, + const char * aPrefId, + nscoord aTwips) +{ + double inches = NS_TWIPS_TO_INCHES(aTwips); + nsAutoString inchesStr; + inchesStr.AppendFloat(inches); + char * str = inchesStr.ToNewCString(); + if (str) { + aPref->SetCharPref(aPrefId, str); + } else { + aPref->SetCharPref(aPrefId, "0.5"); + } +} + +//--------------------------------------------------- +void nsPrintOptions::ReadJustification(nsIPref * aPref, + const char * aPrefId, + PRInt32& aJust, + PRInt32 aInitValue) +{ + aJust = aInitValue; + char * str = nsnull; + nsresult rv = aPref->CopyCharPref(aPrefId, &str); + if (NS_SUCCEEDED(rv) && str) { + nsAutoString justStr; + justStr.AssignWithConversion(str); + + if (justStr.EqualsWithConversion(kRightJust)) { + aJust = NS_PRINT_JUSTIFY_RIGHT; + + } else if (justStr.EqualsWithConversion(kCenterJust)) { + aJust = NS_PRINT_JUSTIFY_CENTER; + + } else { + aJust = NS_PRINT_JUSTIFY_LEFT; + } + nsMemory::Free(str); + } +} + +//--------------------------------------------------- +void nsPrintOptions::WriteJustification(nsIPref * aPref, + const char * aPrefId, + PRInt32 aJust) +{ + switch (aJust) { + case NS_PRINT_JUSTIFY_LEFT: + aPref->SetCharPref(aPrefId, kLeftJust); + break; + + case NS_PRINT_JUSTIFY_CENTER: + aPref->SetCharPref(aPrefId, kCenterJust); + break; + + case NS_PRINT_JUSTIFY_RIGHT: + aPref->SetCharPref(aPrefId, kRightJust); + break; + } //switch +} + diff --git a/mozilla/gfx/src/nsPrintOptionsImpl.h b/mozilla/gfx/src/nsPrintOptionsImpl.h index d5d96be7cda..7a9af306e86 100644 --- a/mozilla/gfx/src/nsPrintOptionsImpl.h +++ b/mozilla/gfx/src/nsPrintOptionsImpl.h @@ -25,6 +25,7 @@ #include "nsIPrintOptions.h" +class nsIPref; //***************************************************************************** //*** nsPrintOptions @@ -35,17 +36,39 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIPRINTOPTIONS + // C++ methods + NS_IMETHOD SetDefaultFont(const nsFont &aFont); + NS_IMETHOD SetFontNamePointSize(const nsString& aFontName, nscoord aPointSize); + + NS_IMETHOD GetDefaultFont(nsFont &aFont); + + // non-scriptable C++ helper method + NS_IMETHOD GetMargin(nsMargin& aMargin); + nsPrintOptions(); virtual ~nsPrintOptions(); +protected: + void ReadBitFieldPref(nsIPref * aPref, const char * aPrefId, PRInt32 anOption); + void WriteBitFieldPref(nsIPref * aPref, const char * aPrefId, PRInt32 anOption); + void ReadJustification(nsIPref * aPref, const char * aPrefId, PRInt32& aJust, PRInt32 aInitValue); + void WriteJustification(nsIPref * aPref, const char * aPrefId, PRInt32 aJust); + void ReadInchesToTwipsPref(nsIPref * aPref, const char * aPrefId, nscoord& aTwips); + void WriteInchesFromTwipsPref(nsIPref * aPref, const char * aPrefId, nscoord aTwips); // Members - PRInt32 mTopMargin; - PRInt32 mLeftMargin; - PRInt32 mRightMargin; - PRInt32 mBottomMargin; + nsMargin mMargin; + nsPrintRange mPrintRange; + PRInt32 mStartPageNum; // only used for ePrintRange_SpecifiedRange + PRInt32 mEndPageNum; + PRInt32 mPageNumJust; + PRInt32 mPrintOptions; + + nsFont* mDefaultFont; + nsString mTitle; + nsString mURL; }; diff --git a/mozilla/gfx/src/windows/nsDeviceContextSpecFactoryW.cpp b/mozilla/gfx/src/windows/nsDeviceContextSpecFactoryW.cpp index 6be1a20d3af..b0f139aedbd 100644 --- a/mozilla/gfx/src/windows/nsDeviceContextSpecFactoryW.cpp +++ b/mozilla/gfx/src/windows/nsDeviceContextSpecFactoryW.cpp @@ -26,6 +26,9 @@ #include #include "nsGfxCIID.h" #include "plstr.h" +#include "nsIServiceManager.h" + +#include "nsIPrintOptions.h" nsDeviceContextSpecFactoryWin :: nsDeviceContextSpecFactoryWin() { @@ -38,6 +41,7 @@ nsDeviceContextSpecFactoryWin :: ~nsDeviceContextSpecFactoryWin() static NS_DEFINE_IID(kIDeviceContextSpecIID, NS_IDEVICE_CONTEXT_SPEC_IID); static NS_DEFINE_IID(kDeviceContextSpecCID, NS_DEVICE_CONTEXT_SPEC_CID); +static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID); NS_IMPL_ISUPPORTS1(nsDeviceContextSpecFactoryWin, nsIDeviceContextSpecFactory) @@ -52,19 +56,30 @@ NS_IMETHODIMP nsDeviceContextSpecFactoryWin :: CreateDeviceContextSpec(nsIDevice nsIDeviceContextSpec *&aNewSpec, PRBool aQuiet) { - PRINTDLG prntdlg; nsresult rv = NS_ERROR_FAILURE; + NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv); + + PRINTDLG prntdlg; prntdlg.lStructSize = sizeof(prntdlg); prntdlg.hwndOwner = NULL; //XXX need to find a window here. MMP prntdlg.hDevMode = NULL; prntdlg.hDevNames = NULL; prntdlg.hDC = NULL; - prntdlg.Flags = PD_ALLPAGES | PD_RETURNIC | PD_NOSELECTION | PD_HIDEPRINTTOFILE; - prntdlg.nFromPage = 0; - prntdlg.nToPage = 0; + prntdlg.Flags = PD_ALLPAGES | PD_RETURNIC | PD_HIDEPRINTTOFILE; + + // if there is a current selection then enable the "Selection" radio button + if (printService) { + PRBool isOn; + printService->GetPrintOptions(NS_PRINT_OPTIONS_ENABLE_SELECTION_RADIO, &isOn); + if (!isOn) { + prntdlg.Flags |= PD_NOSELECTION; + } + } + prntdlg.nFromPage = 1; + prntdlg.nToPage = 1; prntdlg.nMinPage = 0; - prntdlg.nMaxPage = 0; + prntdlg.nMaxPage = 1000; prntdlg.nCopies = 1; prntdlg.hInstance = NULL; prntdlg.lCustData = 0; @@ -80,8 +95,6 @@ NS_IMETHODIMP nsDeviceContextSpecFactoryWin :: CreateDeviceContextSpec(nsIDevice prntdlg.Flags = PD_RETURNDEFAULT; } - - BOOL res = ::PrintDlg(&prntdlg); if (TRUE == res) @@ -95,10 +108,48 @@ NS_IMETHODIMP nsDeviceContextSpecFactoryWin :: CreateDeviceContextSpec(nsIDevice PL_strcpy(device, &(((char *)devnames)[devnames->wDeviceOffset])); PL_strcpy(driver, &(((char *)devnames)[devnames->wDriverOffset])); -#ifdef NS_DEBUG -printf("printer: driver %s, device %s\n", driver, device); +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + printf("printer: driver %s, device %s flags: %d\n", driver, device, prntdlg.Flags); #endif + // fill the print options with the info from the dialog + if(printService) { + + if (prntdlg.Flags & PD_SELECTION) { + printService->SetPrintRange(ePrintRange_Selection); + + } else if (prntdlg.Flags & PD_PAGENUMS) { + printService->SetPrintRange(ePrintRange_SpecifiedPageRange); + printService->SetPageRange(prntdlg.nFromPage, prntdlg.nToPage); + + } else { // (prntdlg.Flags & PD_ALLPAGES) + printService->SetPrintRange(ePrintRange_AllPages); + } + } + +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + PRBool printSelection = prntdlg.Flags & PD_SELECTION; + PRBool printAllPages = prntdlg.Flags & PD_ALLPAGES; + PRBool printNumPages = prntdlg.Flags & PD_PAGENUMS; + PRInt32 fromPageNum = 0; + PRInt32 toPageNum = 0; + + if (printNumPages) { + fromPageNum = prntdlg.nFromPage; + toPageNum = prntdlg.nToPage; + } + if (printSelection) { + printf("Printing the selection\n"); + + } else if (printAllPages) { + printf("Printing all the pages\n"); + + } else { + printf("Printing from page no. %d to %d\n", fromPageNum, toPageNum); + } +#endif + + nsIDeviceContextSpec *devspec = nsnull; nsComponentManager::CreateInstance(kDeviceContextSpecCID, nsnull, kIDeviceContextSpecIID, (void **)&devspec); diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index 7175ba23e12..071e8672d0a 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -10097,7 +10097,8 @@ GetAlternateTextFor(nsIContent* aContent, // If there's no "value" attribute either, then use the localized string // for "Submit" as the alternate text. if (NS_CONTENT_ATTR_NOT_THERE == rv) { - nsFormControlHelper::GetLocalizedString("Submit", aAltText); + nsFormControlHelper::GetLocalizedString(nsFormControlHelper::GetHTMLPropertiesFileName(), + "Submit", aAltText); } } } diff --git a/mozilla/layout/base/nsDocumentViewer.cpp b/mozilla/layout/base/nsDocumentViewer.cpp index d900d3b3abc..b337f40a507 100644 --- a/mozilla/layout/base/nsDocumentViewer.cpp +++ b/mozilla/layout/base/nsDocumentViewer.cpp @@ -87,6 +87,13 @@ #include "nsIEventQueueService.h" #include "nsIEventQueue.h" +// Print Options +#include "nsIPrintOptions.h" +#include "nsGfxCIID.h" +#include "nsIServiceManager.h" +static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID); +#include "nsHTMLAtoms.h" // XXX until atoms get factored into nsLayoutAtoms + //focus #include "nsIDOMEventReceiver.h" #include "nsIDOMFocusListener.h" @@ -248,12 +255,16 @@ private: const nsRect& aBounds); nsresult GetDocumentSelection(nsISelection **aSelection); + nsresult GetDocumentSelection(nsIPresShell * aPresShell, nsISelection **aSelection); nsresult FindFrameSetWithIID(nsIContent * aParentContent, const nsIID& aIID); + PRBool IsThereASelection(); // // The following three methods are used for printing... // void DocumentReadyForPrinting(); + //nsresult PrintSelection(nsIDeviceContextSpec * aDevSpec); + nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc); static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent); static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent); @@ -297,6 +308,8 @@ protected: nsIViewManager *mPrintVM; nsIView *mPrintView; FILE *mFilePointer; // a file where information can go to when printing + nsIDocument *mSelectionDoc; + nsIDocShell *mSelectionDocShell; nsCOMPtr mPrintListener; // An observer for printing... @@ -339,6 +352,7 @@ DocumentViewerImpl::DocumentViewerImpl() mEnableRendering = PR_TRUE; mFilePointer = nsnull; mPrintListener = nsnull; + mSelectionDoc = nsnull; } DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext) @@ -879,6 +893,386 @@ DocumentViewerImpl::FindFrameSetWithIID(nsIContent * aParentContent, const nsIID return NS_ERROR_FAILURE; } +//--------------------------------------------------------------- +//--------------------------------------------------------------- +//-- Debug helper routines +//--------------------------------------------------------------- +//--------------------------------------------------------------- +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + +/** --------------------------------------------------- + * Dumps Frames for Printing + */ +static void DumpFrames(FILE* out, + nsIPresContext* aPresContext, + nsIRenderingContext * aRendContext, + nsIFrame * aFrame, + PRInt32 aLevel) +{ + nsIFrame * child; + aFrame->FirstChild(aPresContext, nsnull, &child); + while (child != nsnull) { + for (PRInt32 i=0;iQueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) { + frameDebug->GetFrameName(tmp); + } + fputs(tmp, out); + nsFrameState state; + child->GetFrameState(&state); + PRBool isSelected; + if (NS_SUCCEEDED(child->IsVisibleForPainting(aPresContext, *aRendContext, PR_TRUE, &isSelected))) { + fprintf(out, " %p %s", child, isSelected?"VIS":"UVS"); + nsRect rect; + child->GetRect(rect); + fprintf(out, "[%d,%d,%d,%d] ", rect.x, rect.y, rect.width, rect.height); + nsIView * view; + child->GetView(aPresContext, &view); + fprintf(out, "v: %p ", view); + fprintf(out, "\n"); + DumpFrames(out, aPresContext, aRendContext, child, aLevel+1); + child->GetNextSibling(&child); + } + } +} + +/** --------------------------------------------------- + * Helper function needed for "DumpViews" + */ +static nsIPresShell* +GetPresShellFor(nsIDocShell* aDocShell) +{ + nsIPresShell* shell = nsnull; + if (nsnull != aDocShell) { + nsIContentViewer* cv = nsnull; + aDocShell->GetContentViewer(&cv); + if (nsnull != cv) { + nsIDocumentViewer* docv = nsnull; + cv->QueryInterface(NS_GET_IID(nsIDocumentViewer), (void**) &docv); + if (nsnull != docv) { + nsIPresContext* cx; + docv->GetPresContext(cx); + if (nsnull != cx) { + cx->GetShell(&shell); + NS_RELEASE(cx); + } + NS_RELEASE(docv); + } + NS_RELEASE(cv); + } + } + return shell; +} + +/** --------------------------------------------------- + * Dumps the Views from the DocShell + */ +static void +DumpViews(nsIDocShell* aDocShell, FILE* out) +{ + if (nsnull != aDocShell) { + fprintf(out, "docshell=%p \n", aDocShell); + nsIPresShell* shell = GetPresShellFor(aDocShell); + if (nsnull != shell) { + nsCOMPtr vm; + shell->GetViewManager(getter_AddRefs(vm)); + if (vm) { + nsIView* root; + vm->GetRootView(root); + if (nsnull != root) { + root->List(out); + } + } + NS_RELEASE(shell); + } + else { + fputs("null pres shell\n", out); + } + + // dump the views of the sub documents + PRInt32 i, n; + nsCOMPtr docShellAsNode(do_QueryInterface(aDocShell)); + docShellAsNode->GetChildCount(&n); + for (i = 0; i < n; i++) { + nsCOMPtr child; + docShellAsNode->GetChildAt(i, getter_AddRefs(child)); + nsCOMPtr childAsShell(do_QueryInterface(child)); + if (childAsShell) { + DumpViews(childAsShell, out); + } + } + } +} + +/** --------------------------------------------------- + * Dumps the Views and Frames + */ +void DumpLayoutData(nsIPresContext* aPresContext, + nsIDeviceContext * aDC, + nsIFrame * aRootFrame, + nsIWebShell * aWebShell) +{ + // Dump all the frames and view to a a file + FILE * fd = fopen("dump.txt", "w"); + if (fd) { + fprintf(fd, "--------------- Frames ----------------\n"); + nsCOMPtr renderingContext; + aDC->CreateRenderingContext(*getter_AddRefs(renderingContext)); + DumpFrames(fd, aPresContext, renderingContext, aRootFrame, 0); + fprintf(fd, "---------------------------------------\n\n"); + fprintf(fd, "--------------- Views From Root Frame----------------\n"); + nsIView * v; + aRootFrame->GetView(aPresContext, &v); + if (v) { + v->List(fd); + } else { + printf("View is null!\n"); + } + nsCOMPtr docShell(do_QueryInterface(aWebShell)); + if (docShell) { + fprintf(fd, "--------------- All Views ----------------\n"); + DumpViews(docShell, fd); + fprintf(fd, "---------------------------------------\n\n"); + } + fclose(fd); + } +} + +#endif +//--------------------------------------------------------------- +//--------------------------------------------------------------- +//-- End of debug helper routines +//--------------------------------------------------------------- +//--------------------------------------------------------------- + +/** --------------------------------------------------- + * Giving a child frame it searches "up" the tree until it + * finds a "Page" frame. + */ +static nsIFrame * GetPageFrame(nsIFrame * aFrame) +{ + nsIFrame * frame = aFrame; + while (frame != nsnull) { + nsCOMPtr type; + frame->GetFrameType(getter_AddRefs(type)); + if (type.get() == nsLayoutAtoms::pageFrame) { + return frame; + } + frame->GetParent(&frame); + } + return nsnull; +} + + +/** --------------------------------------------------- + * Find by checking content's tag type + */ +static nsIFrame * FindFrameByType(nsIPresContext* aPresContext, + nsIFrame * aParentFrame, + nsIAtom * aType, + nsRect& aRect, + nsRect& aChildRect) +{ + nsIFrame * child; + nsRect rect; + aParentFrame->GetRect(rect); + aRect.x += rect.x; + aRect.y += rect.y; + aParentFrame->FirstChild(aPresContext, nsnull, &child); + while (child != nsnull) { + nsCOMPtr content; + child->GetContent(getter_AddRefs(content)); + if (content) { + nsCOMPtr type; + content->GetTag(*getter_AddRefs(type)); + if (type.get() == aType) { + nsRect r; + child->GetRect(r); + aChildRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height); + aRect.x -= rect.x; + aRect.y -= rect.y; + return child; + } + } + nsIFrame * fndFrame = FindFrameByType(aPresContext, child, aType, aRect, aChildRect); + if (fndFrame != nsnull) { + return fndFrame; + } + child->GetNextSibling(&child); + } + aRect.x -= rect.x; + aRect.y -= rect.y; + return nsnull; +} + +/** --------------------------------------------------- + * Find by checking frames type + */ +static nsresult FindSelectionBounds(nsIPresContext* aPresContext, + nsIRenderingContext& aRC, + nsIFrame * aParentFrame, + nsRect& aRect, + nsIFrame *& aStartFrame, + nsRect& aStartRect, + nsIFrame *& aEndFrame, + nsRect& aEndRect) +{ + nsIFrame * child; + aParentFrame->FirstChild(aPresContext, nsnull, &child); + nsRect rect; + aParentFrame->GetRect(rect); + aRect.x += rect.x; + aRect.y += rect.y; + while (child != nsnull) { + nsFrameState state; + child->GetFrameState(&state); + // only leaf frames have this bit flipped + // then check the hard way + PRBool isSelected = (state & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + if (isSelected) { + if (NS_FAILED(child->IsVisibleForPainting(aPresContext, aRC, PR_TRUE, &isSelected))) { + return NS_ERROR_FAILURE; + } + } + + if (isSelected) { + nsRect r; + child->GetRect(r); + if (aStartFrame == nsnull) { + aStartFrame = child; + aStartRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height); + } else { + child->GetRect(r); + aEndFrame = child; + aEndRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height); + } + } + FindSelectionBounds(aPresContext, aRC, child, aRect, aStartFrame, aStartRect, aEndFrame, aEndRect); + child->GetNextSibling(&child); + } + aRect.x -= rect.x; + aRect.y -= rect.y; + return NS_OK; +} + +/** --------------------------------------------------- + * This method finds the starting and ending page numbers + * of the selection and also returns rect for each where + * the x,y of the rect is relative to the very top of the + * frame tree (absolutely positioned) + */ +static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, + nsIPresContext* aPresContext, + nsIRenderingContext& aRC, + nsISelection* aSelection, + nsIPageSequenceFrame* aPageSeqFrame, + nsIFrame** aStartFrame, + PRInt32& aStartPageNum, + nsRect& aStartRect, + nsIFrame** aEndFrame, + PRInt32& aEndPageNum, + nsRect& aEndRect) +{ + nsIFrame * seqFrame; + if (NS_FAILED(aPageSeqFrame->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + return NS_ERROR_FAILURE; + } + + nsIFrame * startFrame = nsnull; + nsIFrame * endFrame = nsnull; + nsRect rect; + seqFrame->GetRect(rect); + + // start out with the sequence frame and search the entire frame tree + // capturing the the starting and ending child frames of the selection + // and their rects + FindSelectionBounds(aPresContext, aRC, seqFrame, rect, startFrame, aStartRect, endFrame, aEndRect); + +#ifdef DEBUG_rods + printf("Start Frame: %p\n", startFrame); + printf("End Frame: %p\n", endFrame); +#endif + + // initial the page numbers here + // in case we don't find and frames + aStartPageNum = -1; + aEndPageNum = -1; + + nsIFrame * startPageFrame; + nsIFrame * endPageFrame; + + // check to make sure we found a starting frame + if (startFrame != nsnull) { + // Now search up the tree to find what page the + // start/ending selections frames are on + // + // Check to see if start should be same as end if + // the end frame comes back null + if (endFrame == nsnull) { + // XXX the "GetPageFrame" step could be integrated into + // the FindSelectionBounds step, but walking up to find + // the parent of a child frame isn't expensive and it makes + // FindSelectionBounds a little easier to understand + startPageFrame = GetPageFrame(startFrame); + endPageFrame = startPageFrame; + aEndRect = aStartRect; + } else { + startPageFrame = GetPageFrame(startFrame); + endPageFrame = GetPageFrame(endFrame); + } + } else { + return NS_ERROR_FAILURE; + } + +#ifdef DEBUG_rods + printf("Start Page: %p\n", startPageFrame); + printf("End Page: %p\n", endPageFrame); + + // dump all the pages and their pointers + { + PRInt32 pageNum = 1; + nsIFrame * child; + seqFrame->FirstChild(aPresContext, nsnull, &child); + while (child != nsnull) { + printf("Page: %d - %p\n", pageNum, child); + pageNum++; + child->GetNextSibling(&child); + } + } +#endif + + // Now that we have the page frames + // find out what the page numbers are for each frame + PRInt32 pageNum = 1; + nsIFrame * page; + seqFrame->FirstChild(aPresContext, nsnull, &page); + while (page != nsnull) { + if (page == startPageFrame) { + aStartPageNum = pageNum; + } + if (page == endPageFrame) { + aEndPageNum = pageNum; + } + pageNum++; + page->GetNextSibling(&page); + } + +#ifdef DEBUG_rods + printf("Start Page No: %d\n", aStartPageNum); + printf("End Page No: %d\n", aEndPageNum); +#endif + + *aStartFrame = startPageFrame; + *aEndFrame = endPageFrame; + + return NS_OK; +} + +//------------------------------------------------------- nsresult DocumentViewerImpl::PrintContent(nsIWebShell * aParent, nsIDeviceContext * aDContext) @@ -889,7 +1283,6 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, nsCOMPtr ss; nsCOMPtr vm; PRInt32 width, height; - nsIView *view; nsresult rv; PRInt32 count,i; nsCOMPtr viewer; @@ -922,7 +1315,10 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, nsCOMPtr doc; shell->GetDocument(getter_AddRefs(doc)); if (doc) { - nsCOMPtr rootContent = getter_AddRefs(mDocument->GetRootContent()); + if (mSelectionDoc) { + doc = mSelectionDoc; + } + nsCOMPtr rootContent = getter_AddRefs(doc->GetRootContent()); if (rootContent) { if (NS_SUCCEEDED(FindFrameSetWithIID(rootContent, NS_GET_IID(nsIDOMHTMLFrameSetElement)))) { doesContainFrameSet = PR_TRUE; @@ -955,6 +1351,16 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, NS_ENSURE_SUCCESS( aDContext->BeginDocument(), NS_ERROR_FAILURE ); aDContext->GetDeviceSurfaceDimensions(width, height); + // XXX - Hack Alert + // OK, so ther eis a selection, we will print the entire selection + // on one page and then crop the page. + // This means you can never print any selection that is longer than one page + // put it keeps it from page breaking in the middle of your print of the selection + // (see also nsSimplePageSequence.cpp) + if (IsThereASelection()) { + height = 0x0FFFFFFF; + } + nsCOMPtr cx; nsCOMPtr printcon; rv = NS_NewPrintContext(getter_AddRefs(printcon)); @@ -992,17 +1398,18 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, nsRect tbounds = nsRect(0, 0, width, height); // Create a child window of the parent that is our "root view/window" - rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&view); + nsIView* rootView; + rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&rootView); if (NS_FAILED(rv)) { return rv; } - rv = view->Init(vm, tbounds, nsnull); + rv = rootView->Init(vm, tbounds, nsnull); if (NS_FAILED(rv)) { return rv; } // Setup hierarchical relationship in view manager - vm->SetRootView(view); + vm->SetRootView(rootView); ps->Init(mDocument, cx, vm, ss); @@ -1018,10 +1425,30 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE); presShell->CaptureHistoryState(getter_AddRefs(layoutState),PR_TRUE); + ps->BeginObservingDocument(); //lay it out... ps->InitialReflow(width, height); + // Transfer Selection Ranges to the new Print PresShell + nsCOMPtr selection; + nsCOMPtr selectionPS; + GetDocumentSelection(getter_AddRefs(selection)); + if (selection) { + GetDocumentSelection(ps, getter_AddRefs(selectionPS)); + if (selectionPS) { + PRInt32 cnt; + selection->GetRangeCount(&cnt); + PRInt32 inx; + for (inx=0;inx range; + if (NS_SUCCEEDED(selection->GetRangeAt(inx, getter_AddRefs(range)))) { + selectionPS->AddRange(range); + } + } + } + } + // update the history from the old presentation shell nsCOMPtr fm; rv = ps->GetFrameManager(getter_AddRefs(fm)); @@ -1034,8 +1461,8 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, // Ask the page sequence frame to print all the pages nsIPageSequenceFrame* pageSequence; - nsPrintOptions options; + // ps->GetPageSequenceFrame(&pageSequence); NS_ASSERTION(nsnull != pageSequence, "no page sequence frame"); @@ -1051,7 +1478,97 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, } fclose(mFilePointer); } else { - pageSequence->Print(cx, options, nsnull); + nsIFrame* rootFrame; + ps->GetRootFrame(&rootFrame); + +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + DumpLayoutData(cx, aDContext, rootFrame, aParent); +#endif + + nsPrintRange printRangeType = ePrintRange_AllPages; + NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv); + if (NS_SUCCEEDED(rv) && printService) { + PRInt32 printType; + printService->GetPrintRange(&printType); + printRangeType = (nsPrintRange)printType; + + // get the document title + const nsString* docTitle = mDocument->GetDocumentTitle(); + PRUnichar * docStr = docTitle->ToNewUnicode(); + printService->SetTitle(docStr); + nsMemory::Free(docStr); + + // Get Document URL String + nsCOMPtr url(getter_AddRefs(mDocument->GetDocumentURL())); + char * urlCStr; + url->GetSpec(&urlCStr); + nsAutoString urlStr; + urlStr.AssignWithConversion(urlCStr); + PRUnichar * urlUStr = urlStr.ToNewUnicode(); + printService->SetURL(urlUStr); + nsMemory::Free(urlUStr); + nsMemory::Free(urlCStr); + + if (ePrintRange_Selection == printRangeType) { + cx->SetIsRenderingOnlySelection(PR_TRUE); + + // temporarily creating rendering context + // which is needed to dinf the selection frames + nsCOMPtr rc; + aDContext->CreateRenderingContext(*getter_AddRefs(rc)); + + // find the starting and ending page numbers + // via the selection + nsIFrame* startFrame; + nsIFrame* endFrame; + PRInt32 startPageNum; + PRInt32 endPageNum; + nsRect startRect; + nsRect endRect; + rv = GetPageRangeForSelection(ps, cx, *rc, selectionPS, pageSequence, + &startFrame, startPageNum, startRect, + &endFrame, endPageNum, endRect); + if (NS_SUCCEEDED(rv)) { + printService->SetPageRange(startPageNum, endPageNum); + if (startPageNum == endPageNum) { + nsIFrame * seqFrame; + if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + return NS_ERROR_FAILURE; + } + nsRect rect(0,0,0,0); + nsRect areaRect; + nsIFrame * areaFrame = FindFrameByType(cx, startFrame, nsHTMLAtoms::body, rect, areaRect); + if (areaFrame) { + areaRect.y = areaRect.y - startRect.y; + areaFrame->SetRect(cx, areaRect); + } + } + } + } + + nsIFrame * seqFrame; + if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + return NS_ERROR_FAILURE; + } + + nsRect srect; + seqFrame->GetRect(srect); + + nsRect r; + rootView->GetBounds(r); + r.height = srect.height; + rootView->SetBounds(r); + + rootFrame->GetRect(r); + r.height = srect.height; + rootFrame->SetRect(cx, r); + + pageSequence->Print(cx, printService, nsnull); + + } else { + // not sure what to do here! + return NS_ERROR_FAILURE; + } } aDContext->EndDocument(); @@ -1287,17 +1804,23 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, return rv; } -nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection) +nsresult DocumentViewerImpl::GetDocumentSelection(nsIPresShell * aPresShell, nsISelection **aSelection) { if (!aSelection) return NS_ERROR_NULL_POINTER; - if (!mPresShell) return NS_ERROR_NOT_INITIALIZED; + if (!aPresShell) return NS_ERROR_NULL_POINTER; nsCOMPtr selcon; - selcon = do_QueryInterface(mPresShell); + selcon = do_QueryInterface(aPresShell); if (selcon) return selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, aSelection); return NS_ERROR_FAILURE; } +nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection) +{ + if (!mPresShell) return NS_ERROR_NOT_INITIALIZED; + return GetDocumentSelection(mPresShell, aSelection); +} + NS_IMETHODIMP DocumentViewerImpl::CreateDocumentViewerUsing(nsIPresContext* aPresContext, nsIDocumentViewer*& aResult) @@ -1386,6 +1909,8 @@ void DocumentViewerImpl::DocumentReadyForPrinting() NS_RELEASE(mPrintVM); NS_RELEASE(mPrintSS); NS_RELEASE(mPrintDC); + NS_IF_RELEASE(mSelectionDoc); + } } @@ -1535,6 +2060,198 @@ DocumentViewerImpl::GetSaveable(PRBool *aSaveable) static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTORY_CID); +//------------------------------------------------------------------ +#include "nsINodeInfo.h" +#include "nsIDocument.h" +#include "nsHTMLAtoms.h" +#include "nsIHTMLContent.h" +#include "nsINameSpaceManager.h" +#include "nsIWebShell.h" + +static NS_DEFINE_IID(kWebShellCID, NS_WEB_SHELL_CID); +static NS_DEFINE_IID(kCViewCID, NS_VIEW_CID); +static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID); + +#if 0 +nsresult +DocumentViewerImpl::CreateDocShell(nsIPresContext* aPresContext, const nsSize& aSize) +{ + nsresult rv; + mSelectionDocShell = do_CreateInstance(kWebShellCID); + NS_ENSURE_TRUE(mSelectionDocShell, NS_ERROR_FAILURE); + + // pass along marginwidth and marginheight so sub document can use it + mSelectionDocShell->SetMarginWidth(0); + mSelectionDocShell->SetMarginHeight(0); + + /* our parent must be a docshell. we need to get our prefs from our parent */ + nsCOMPtr container; + aPresContext->GetContainer(getter_AddRefs(container)); + NS_ENSURE_TRUE(container, NS_ERROR_UNEXPECTED); + + nsCOMPtr outerShell = do_QueryInterface(container); + NS_ENSURE_TRUE(outerShell, NS_ERROR_UNEXPECTED); + + float t2p; + aPresContext->GetTwipsToPixels(&t2p); + nsCOMPtr presShell; + rv = aPresContext->GetShell(getter_AddRefs(presShell)); + if (NS_FAILED(rv)) { return rv; } + + // create, init, set the parent of the view + nsIView* view; + rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, NS_GET_IID(nsIView), + (void **)&view); + if (NS_FAILED(rv)) { return rv; } + + nsIView* parView; + nsPoint origin; + GetOffsetFromView(aPresContext, origin, &parView); + + nsRect viewBounds(origin.x, origin.y, aSize.width, aSize.height); +#ifdef NOISY + printf("%p view bounds: x=%d, y=%d, w=%d, h=%d\n", view, origin.x, origin.y, aSize.width, aSize.height); +#endif + + nsCOMPtr viewMan; + presShell->GetViewManager(getter_AddRefs(viewMan)); + rv = view->Init(viewMan, viewBounds, parView); + if (NS_FAILED(rv)) { return rv; } + viewMan->InsertChild(parView, view, 0); + rv = view->CreateWidget(kCChildCID); + if (NS_FAILED(rv)) { return rv; } + SetView(aPresContext, view); + + // if the visibility is hidden, reflect that in the view + const nsStyleDisplay* display; + GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display)); + if (!display->IsVisible()) { + view->SetVisibility(nsViewVisibility_kHide); + } + + const nsStyleSpacing* spacing; + GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing); + nsMargin border; + spacing->CalcBorderFor(this, border); + + nsCOMPtr widget; + view->GetWidget(*getter_AddRefs(widget)); + + mSelectionDocShell->SetAllowPlugins(PR_FALSE); + nsCOMPtr docShellAsWin(do_QueryInterface(mSelectionDocShell)); + + PRInt32 x = NSToCoordRound(border.left * t2p); + PRInt32 y = NSToCoordRound(border.top * t2p); + PRInt32 cx = NSToCoordRound((aSize.width - border.right) * t2p); + PRInt32 cy = NSToCoordRound((aSize.height - border.bottom) * t2p); + NS_ENSURE_SUCCESS(docShellAsWin->InitWindow(nsnull, widget, (x >= 0) ? x : 0, + (y >= 0) ? y : 0, cx, cy), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(docShellAsWin->Create(), NS_ERROR_FAILURE); + + // move the view to the proper location + viewMan->MoveViewTo(view, origin.x, origin.y); + + mSelectionDocShell->SetDocLoaderObserver(mTempObserver); + + PRInt32 type; + GetType(&type); + if ((PR_FALSE==IsSingleLineTextControl()) || (NS_FORM_INPUT_PASSWORD == type)) { + docShellAsWin->SetVisibility(PR_TRUE); + } + return NS_OK; +} +#endif + +//nsresult DocumentViewerImpl::PrintSelection(nsIDeviceContextSpec * aDevSpec) +nsresult DocumentViewerImpl::GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc) +{ + //NS_ENSURE_ARG_POINTER(*aDevSpec); + NS_ENSURE_ARG_POINTER(aNewDoc); + + // create document + nsCOMPtr doc; + nsresult rv = NS_NewHTMLDocument(getter_AddRefs(doc)); + if (NS_FAILED(rv)) { return rv; } + if (!doc) { return NS_ERROR_NULL_POINTER; } + + nsCOMPtr nimgr; + rv = doc->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr nodeInfo; + nimgr->GetNodeInfo(nsHTMLAtoms::html, nsnull, kNameSpaceID_None, + *getter_AddRefs(nodeInfo)); + + // create document content + nsCOMPtr htmlElement; + nsCOMPtr headElement; + nsCOMPtr bodyElement; + // create the root + rv = NS_NewHTMLHtmlElement(getter_AddRefs(htmlElement), nodeInfo); + if (NS_FAILED(rv)) { return rv; } + if (!htmlElement) { return NS_ERROR_NULL_POINTER; } + // create the head + + nimgr->GetNodeInfo(NS_ConvertASCIItoUCS2("head"), nsnull, + kNameSpaceID_None, *getter_AddRefs(nodeInfo)); + + rv = NS_NewHTMLHeadElement(getter_AddRefs(headElement), nodeInfo); + if (NS_FAILED(rv)) { return rv; } + if (!headElement) { return NS_ERROR_NULL_POINTER; } + headElement->SetDocument(doc, PR_FALSE, PR_TRUE); + // create the body + + nimgr->GetNodeInfo(nsHTMLAtoms::body, nsnull, kNameSpaceID_None, + *getter_AddRefs(nodeInfo)); + + rv = NS_NewHTMLBodyElement(getter_AddRefs(bodyElement), nodeInfo); + if (NS_FAILED(rv)) { return rv; } + if (!bodyElement) { return NS_ERROR_NULL_POINTER; } + bodyElement->SetDocument(doc, PR_FALSE, PR_TRUE); + // put the head and body into the root + rv = htmlElement->AppendChildTo(headElement, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } + rv = htmlElement->AppendChildTo(bodyElement, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } + + // load the document into the docshell + nsCOMPtr domDoc = do_QueryInterface(doc); + if (!domDoc) { return NS_ERROR_NULL_POINTER; } + nsCOMPtr htmlDOMElement = do_QueryInterface(htmlElement); + if (!htmlDOMElement) { return NS_ERROR_NULL_POINTER; } + + //nsCOMPtr rootContent(do_QueryInterface(htmlElement)); + //doc->SetRootContent(rootContent); + + *aNewDoc = doc.get(); + NS_ADDREF(*aNewDoc); + + return rv; + +} + +PRBool +DocumentViewerImpl::IsThereASelection() +{ + // check here to see if there is a range selection + // so we know whether to turn on the "Selection" radio button + nsCOMPtr selection; + GetDocumentSelection(getter_AddRefs(selection)); + if (selection) { + PRInt32 count; + selection->GetRangeCount(&count); + if (count == 1) { + nsCOMPtr range; + if (NS_SUCCEEDED(selection->GetRangeAt(0, getter_AddRefs(range)))) { + // check to make sure it isn't an insertion selection + PRBool isCollapsed; + selection->GetIsCollapsed(&isCollapsed); + return !isCollapsed; + } + } + } + return PR_FALSE; +} /** --------------------------------------------------- * See documentation above in the nsIContentViewerfile class definition @@ -1543,9 +2260,15 @@ static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTOR NS_IMETHODIMP DocumentViewerImpl::Print(PRBool aSilent,FILE *aFile, nsIPrintListener *aPrintListener) { -nsCOMPtr webContainer; -nsCOMPtr factory; -PRInt32 width,height; + nsCOMPtr webContainer; + nsCOMPtr factory; + PRInt32 width,height; + + nsresult rv = NS_ERROR_FAILURE; + NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv); + if (NS_SUCCEEDED(rv) && printService) { + printService->SetPrintOptions(NS_PRINT_OPTIONS_ENABLE_SELECTION_RADIO, IsThereASelection()); + } nsComponentManager::CreateInstance(kDeviceContextSpecFactoryCID, nsnull, @@ -1566,11 +2289,14 @@ PRInt32 width,height; factory->CreateDeviceContextSpec(nsnull, devspec, aSilent); if (nsnull != devspec) { mPresContext->GetDeviceContext(getter_AddRefs(dx)); - nsresult rv = dx->GetDeviceContextFor(devspec, mPrintDC); + rv = dx->GetDeviceContextFor(devspec, mPrintDC); if (NS_SUCCEEDED(rv)) { NS_RELEASE(devspec); + nsCOMPtr printDoc; + printDoc = mDocument; + // Get the webshell for this documentviewer webContainer = do_QueryInterface(mContainer); if(webContainer) { @@ -1588,15 +2314,24 @@ PRInt32 width,height; mPrintDC->GetDeviceSurfaceDimensions(width,height); + // XXX - Hack Alert + // OK, so ther eis a selection, we will print the entire selection + // on one page and then crop the page. + // This means you can never print any selection that is longer than one page + // put it keeps it from page breaking in the middle of your print of the selection + if (IsThereASelection()) { + height = 0x0FFFFFFF; + } + mPrintPC->Init(mPrintDC); mPrintPC->SetContainer(webContainer); - CreateStyleSet(mDocument,&mPrintSS); + CreateStyleSet(printDoc,&mPrintSS); rv = NS_NewPresShell(&mPrintPS); if(NS_FAILED(rv)){ return rv; } - + rv = nsComponentManager::CreateInstance(kViewManagerCID, nsnull, NS_GET_IID(nsIViewManager),(void**)&mPrintVM); if(NS_FAILED(rv)) { return rv; @@ -1611,7 +2346,7 @@ PRInt32 width,height; if(NS_FAILED(rv)) { return rv; } - + nsRect tbounds = nsRect(0,0,width,height); rv = mPrintView->Init(mPrintVM,tbounds,nsnull); if(NS_FAILED(rv)) { @@ -1620,7 +2355,7 @@ PRInt32 width,height; // setup hierarchical relationship in view manager mPrintVM->SetRootView(mPrintView); - mPrintPS->Init(mDocument,mPrintPC,mPrintVM,mPrintSS); + mPrintPS->Init(printDoc,mPrintPC,mPrintVM,mPrintSS); nsCOMPtr imageGroup; mPrintPC->GetImageGroup(getter_AddRefs(imageGroup)); diff --git a/mozilla/layout/base/nsPresContext.cpp b/mozilla/layout/base/nsPresContext.cpp index 8c87e648132..1b6f8a00a28 100644 --- a/mozilla/layout/base/nsPresContext.cpp +++ b/mozilla/layout/base/nsPresContext.cpp @@ -123,6 +123,7 @@ nsPresContext::nsPresContext() mDefaultBackgroundImageOffsetX = mDefaultBackgroundImageOffsetY = 0; mDefaultDirection = NS_STYLE_DIRECTION_LTR; mLanguageSpecificTransformType = eLanguageSpecificTransformType_Unknown; + mIsRenderingOnlySelection = PR_FALSE; } nsPresContext::~nsPresContext() @@ -1313,6 +1314,15 @@ nsPresContext::GetLanguageSpecificTransformType( return NS_OK; } +NS_IMETHODIMP +nsPresContext::IsRenderingOnlySelection(PRBool* aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + *aResult = mIsRenderingOnlySelection; + + return NS_OK; +} + #ifdef MOZ_REFLOW_PERF NS_IMETHODIMP nsPresContext::CountReflows(const char * aName, PRUint32 aType) diff --git a/mozilla/layout/base/nsPresContext.h b/mozilla/layout/base/nsPresContext.h index 996b8688301..5ee0effdbc7 100644 --- a/mozilla/layout/base/nsPresContext.h +++ b/mozilla/layout/base/nsPresContext.h @@ -357,6 +357,12 @@ public: NS_IMETHOD GetLanguageSpecificTransformType( nsLanguageSpecificTransformType* aType) = 0; + /** + * Render only Selection + */ + NS_IMETHOD SetIsRenderingOnlySelection(PRBool aResult) = 0; + NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0; + #ifdef MOZ_REFLOW_PERF NS_IMETHOD CountReflows(const char * aName, PRUint32 aType) = 0; #endif diff --git a/mozilla/layout/base/public/nsIFrame.h b/mozilla/layout/base/public/nsIFrame.h index e7580093633..82231a5ea8b 100644 --- a/mozilla/layout/base/public/nsIFrame.h +++ b/mozilla/layout/base/public/nsIFrame.h @@ -1092,6 +1092,19 @@ public: nsIFrame** aProviderFrame, nsContextProviderRelationship& aRelationship) = 0; + /** + * Determines whether a frame is visible for painting + * this takes into acount whether it is painting selection for printin + * @param aPresContext PresContext + * @param aRenderingContext PresContext + * @param aCheckVis indicates whether it should check for CSS visibility, + * PR_FALSE skips the check, PR_TRUE does the check + * @param aIsVisible return value + */ + NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext, + nsIRenderingContext& aRenderingContext, + PRBool aCheckVis, + PRBool* aIsVisible) = 0; private: NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; NS_IMETHOD_(nsrefcnt) Release(void) = 0; diff --git a/mozilla/layout/base/public/nsIPageSequenceFrame.h b/mozilla/layout/base/public/nsIPageSequenceFrame.h index 556fbbe705a..241c8f57a7c 100644 --- a/mozilla/layout/base/public/nsIPageSequenceFrame.h +++ b/mozilla/layout/base/public/nsIPageSequenceFrame.h @@ -26,6 +26,7 @@ #include "nsISupports.h" class nsIPresContext; +class nsIPrintOptions; // IID for the nsIPageSequenceFrame interface // a6cf90d2-15b3-11d2-932e-00805f8add32 @@ -91,27 +92,6 @@ public: //---------------------------------------------------------------------- -enum nsPrintRange { - ePrintRange_AllPages, // print all pages - ePrintRange_SpecifiedRange // only print pages in the specified range -}; - -/** - * Structure containing options for printing. - */ -struct nsPrintOptions { - nsPrintRange range; - PRInt32 startPage, endPage; // only used for ePrintRange_SpecifiedRange - PRPackedBool oddNumberedPages; // print the odd-numbered pages - PRPackedBool evenNumberedPages; // print the even-numbered pages - - nsPrintOptions() { - range = ePrintRange_AllPages; - startPage = endPage = 1; - oddNumberedPages = evenNumberedPages = PR_TRUE; - } -}; - /** * Interface for accessing special capabilities of the page sequence frame. * @@ -136,7 +116,7 @@ public: * @see nsIPrintStatusCallback#OnProgress() */ NS_IMETHOD Print(nsIPresContext* aPresContext, - const nsPrintOptions& aPrintOptions, + nsIPrintOptions* aPrintOptions, nsIPrintStatusCallback* aStatusCallback) = 0; private: diff --git a/mozilla/layout/base/public/nsIPresContext.h b/mozilla/layout/base/public/nsIPresContext.h index 996b8688301..5ee0effdbc7 100644 --- a/mozilla/layout/base/public/nsIPresContext.h +++ b/mozilla/layout/base/public/nsIPresContext.h @@ -357,6 +357,12 @@ public: NS_IMETHOD GetLanguageSpecificTransformType( nsLanguageSpecificTransformType* aType) = 0; + /** + * Render only Selection + */ + NS_IMETHOD SetIsRenderingOnlySelection(PRBool aResult) = 0; + NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0; + #ifdef MOZ_REFLOW_PERF NS_IMETHOD CountReflows(const char * aName, PRUint32 aType) = 0; #endif diff --git a/mozilla/layout/base/public/nsPresContext.h b/mozilla/layout/base/public/nsPresContext.h index 996b8688301..5ee0effdbc7 100644 --- a/mozilla/layout/base/public/nsPresContext.h +++ b/mozilla/layout/base/public/nsPresContext.h @@ -357,6 +357,12 @@ public: NS_IMETHOD GetLanguageSpecificTransformType( nsLanguageSpecificTransformType* aType) = 0; + /** + * Render only Selection + */ + NS_IMETHOD SetIsRenderingOnlySelection(PRBool aResult) = 0; + NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult) = 0; + #ifdef MOZ_REFLOW_PERF NS_IMETHOD CountReflows(const char * aName, PRUint32 aType) = 0; #endif diff --git a/mozilla/layout/base/src/nsDocumentViewer.cpp b/mozilla/layout/base/src/nsDocumentViewer.cpp index d900d3b3abc..b337f40a507 100644 --- a/mozilla/layout/base/src/nsDocumentViewer.cpp +++ b/mozilla/layout/base/src/nsDocumentViewer.cpp @@ -87,6 +87,13 @@ #include "nsIEventQueueService.h" #include "nsIEventQueue.h" +// Print Options +#include "nsIPrintOptions.h" +#include "nsGfxCIID.h" +#include "nsIServiceManager.h" +static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID); +#include "nsHTMLAtoms.h" // XXX until atoms get factored into nsLayoutAtoms + //focus #include "nsIDOMEventReceiver.h" #include "nsIDOMFocusListener.h" @@ -248,12 +255,16 @@ private: const nsRect& aBounds); nsresult GetDocumentSelection(nsISelection **aSelection); + nsresult GetDocumentSelection(nsIPresShell * aPresShell, nsISelection **aSelection); nsresult FindFrameSetWithIID(nsIContent * aParentContent, const nsIID& aIID); + PRBool IsThereASelection(); // // The following three methods are used for printing... // void DocumentReadyForPrinting(); + //nsresult PrintSelection(nsIDeviceContextSpec * aDevSpec); + nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc); static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent); static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent); @@ -297,6 +308,8 @@ protected: nsIViewManager *mPrintVM; nsIView *mPrintView; FILE *mFilePointer; // a file where information can go to when printing + nsIDocument *mSelectionDoc; + nsIDocShell *mSelectionDocShell; nsCOMPtr mPrintListener; // An observer for printing... @@ -339,6 +352,7 @@ DocumentViewerImpl::DocumentViewerImpl() mEnableRendering = PR_TRUE; mFilePointer = nsnull; mPrintListener = nsnull; + mSelectionDoc = nsnull; } DocumentViewerImpl::DocumentViewerImpl(nsIPresContext* aPresContext) @@ -879,6 +893,386 @@ DocumentViewerImpl::FindFrameSetWithIID(nsIContent * aParentContent, const nsIID return NS_ERROR_FAILURE; } +//--------------------------------------------------------------- +//--------------------------------------------------------------- +//-- Debug helper routines +//--------------------------------------------------------------- +//--------------------------------------------------------------- +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + +/** --------------------------------------------------- + * Dumps Frames for Printing + */ +static void DumpFrames(FILE* out, + nsIPresContext* aPresContext, + nsIRenderingContext * aRendContext, + nsIFrame * aFrame, + PRInt32 aLevel) +{ + nsIFrame * child; + aFrame->FirstChild(aPresContext, nsnull, &child); + while (child != nsnull) { + for (PRInt32 i=0;iQueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) { + frameDebug->GetFrameName(tmp); + } + fputs(tmp, out); + nsFrameState state; + child->GetFrameState(&state); + PRBool isSelected; + if (NS_SUCCEEDED(child->IsVisibleForPainting(aPresContext, *aRendContext, PR_TRUE, &isSelected))) { + fprintf(out, " %p %s", child, isSelected?"VIS":"UVS"); + nsRect rect; + child->GetRect(rect); + fprintf(out, "[%d,%d,%d,%d] ", rect.x, rect.y, rect.width, rect.height); + nsIView * view; + child->GetView(aPresContext, &view); + fprintf(out, "v: %p ", view); + fprintf(out, "\n"); + DumpFrames(out, aPresContext, aRendContext, child, aLevel+1); + child->GetNextSibling(&child); + } + } +} + +/** --------------------------------------------------- + * Helper function needed for "DumpViews" + */ +static nsIPresShell* +GetPresShellFor(nsIDocShell* aDocShell) +{ + nsIPresShell* shell = nsnull; + if (nsnull != aDocShell) { + nsIContentViewer* cv = nsnull; + aDocShell->GetContentViewer(&cv); + if (nsnull != cv) { + nsIDocumentViewer* docv = nsnull; + cv->QueryInterface(NS_GET_IID(nsIDocumentViewer), (void**) &docv); + if (nsnull != docv) { + nsIPresContext* cx; + docv->GetPresContext(cx); + if (nsnull != cx) { + cx->GetShell(&shell); + NS_RELEASE(cx); + } + NS_RELEASE(docv); + } + NS_RELEASE(cv); + } + } + return shell; +} + +/** --------------------------------------------------- + * Dumps the Views from the DocShell + */ +static void +DumpViews(nsIDocShell* aDocShell, FILE* out) +{ + if (nsnull != aDocShell) { + fprintf(out, "docshell=%p \n", aDocShell); + nsIPresShell* shell = GetPresShellFor(aDocShell); + if (nsnull != shell) { + nsCOMPtr vm; + shell->GetViewManager(getter_AddRefs(vm)); + if (vm) { + nsIView* root; + vm->GetRootView(root); + if (nsnull != root) { + root->List(out); + } + } + NS_RELEASE(shell); + } + else { + fputs("null pres shell\n", out); + } + + // dump the views of the sub documents + PRInt32 i, n; + nsCOMPtr docShellAsNode(do_QueryInterface(aDocShell)); + docShellAsNode->GetChildCount(&n); + for (i = 0; i < n; i++) { + nsCOMPtr child; + docShellAsNode->GetChildAt(i, getter_AddRefs(child)); + nsCOMPtr childAsShell(do_QueryInterface(child)); + if (childAsShell) { + DumpViews(childAsShell, out); + } + } + } +} + +/** --------------------------------------------------- + * Dumps the Views and Frames + */ +void DumpLayoutData(nsIPresContext* aPresContext, + nsIDeviceContext * aDC, + nsIFrame * aRootFrame, + nsIWebShell * aWebShell) +{ + // Dump all the frames and view to a a file + FILE * fd = fopen("dump.txt", "w"); + if (fd) { + fprintf(fd, "--------------- Frames ----------------\n"); + nsCOMPtr renderingContext; + aDC->CreateRenderingContext(*getter_AddRefs(renderingContext)); + DumpFrames(fd, aPresContext, renderingContext, aRootFrame, 0); + fprintf(fd, "---------------------------------------\n\n"); + fprintf(fd, "--------------- Views From Root Frame----------------\n"); + nsIView * v; + aRootFrame->GetView(aPresContext, &v); + if (v) { + v->List(fd); + } else { + printf("View is null!\n"); + } + nsCOMPtr docShell(do_QueryInterface(aWebShell)); + if (docShell) { + fprintf(fd, "--------------- All Views ----------------\n"); + DumpViews(docShell, fd); + fprintf(fd, "---------------------------------------\n\n"); + } + fclose(fd); + } +} + +#endif +//--------------------------------------------------------------- +//--------------------------------------------------------------- +//-- End of debug helper routines +//--------------------------------------------------------------- +//--------------------------------------------------------------- + +/** --------------------------------------------------- + * Giving a child frame it searches "up" the tree until it + * finds a "Page" frame. + */ +static nsIFrame * GetPageFrame(nsIFrame * aFrame) +{ + nsIFrame * frame = aFrame; + while (frame != nsnull) { + nsCOMPtr type; + frame->GetFrameType(getter_AddRefs(type)); + if (type.get() == nsLayoutAtoms::pageFrame) { + return frame; + } + frame->GetParent(&frame); + } + return nsnull; +} + + +/** --------------------------------------------------- + * Find by checking content's tag type + */ +static nsIFrame * FindFrameByType(nsIPresContext* aPresContext, + nsIFrame * aParentFrame, + nsIAtom * aType, + nsRect& aRect, + nsRect& aChildRect) +{ + nsIFrame * child; + nsRect rect; + aParentFrame->GetRect(rect); + aRect.x += rect.x; + aRect.y += rect.y; + aParentFrame->FirstChild(aPresContext, nsnull, &child); + while (child != nsnull) { + nsCOMPtr content; + child->GetContent(getter_AddRefs(content)); + if (content) { + nsCOMPtr type; + content->GetTag(*getter_AddRefs(type)); + if (type.get() == aType) { + nsRect r; + child->GetRect(r); + aChildRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height); + aRect.x -= rect.x; + aRect.y -= rect.y; + return child; + } + } + nsIFrame * fndFrame = FindFrameByType(aPresContext, child, aType, aRect, aChildRect); + if (fndFrame != nsnull) { + return fndFrame; + } + child->GetNextSibling(&child); + } + aRect.x -= rect.x; + aRect.y -= rect.y; + return nsnull; +} + +/** --------------------------------------------------- + * Find by checking frames type + */ +static nsresult FindSelectionBounds(nsIPresContext* aPresContext, + nsIRenderingContext& aRC, + nsIFrame * aParentFrame, + nsRect& aRect, + nsIFrame *& aStartFrame, + nsRect& aStartRect, + nsIFrame *& aEndFrame, + nsRect& aEndRect) +{ + nsIFrame * child; + aParentFrame->FirstChild(aPresContext, nsnull, &child); + nsRect rect; + aParentFrame->GetRect(rect); + aRect.x += rect.x; + aRect.y += rect.y; + while (child != nsnull) { + nsFrameState state; + child->GetFrameState(&state); + // only leaf frames have this bit flipped + // then check the hard way + PRBool isSelected = (state & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + if (isSelected) { + if (NS_FAILED(child->IsVisibleForPainting(aPresContext, aRC, PR_TRUE, &isSelected))) { + return NS_ERROR_FAILURE; + } + } + + if (isSelected) { + nsRect r; + child->GetRect(r); + if (aStartFrame == nsnull) { + aStartFrame = child; + aStartRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height); + } else { + child->GetRect(r); + aEndFrame = child; + aEndRect.SetRect(aRect.x + r.x, aRect.y + r.y, r.width, r.height); + } + } + FindSelectionBounds(aPresContext, aRC, child, aRect, aStartFrame, aStartRect, aEndFrame, aEndRect); + child->GetNextSibling(&child); + } + aRect.x -= rect.x; + aRect.y -= rect.y; + return NS_OK; +} + +/** --------------------------------------------------- + * This method finds the starting and ending page numbers + * of the selection and also returns rect for each where + * the x,y of the rect is relative to the very top of the + * frame tree (absolutely positioned) + */ +static nsresult GetPageRangeForSelection(nsIPresShell * aPresShell, + nsIPresContext* aPresContext, + nsIRenderingContext& aRC, + nsISelection* aSelection, + nsIPageSequenceFrame* aPageSeqFrame, + nsIFrame** aStartFrame, + PRInt32& aStartPageNum, + nsRect& aStartRect, + nsIFrame** aEndFrame, + PRInt32& aEndPageNum, + nsRect& aEndRect) +{ + nsIFrame * seqFrame; + if (NS_FAILED(aPageSeqFrame->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + return NS_ERROR_FAILURE; + } + + nsIFrame * startFrame = nsnull; + nsIFrame * endFrame = nsnull; + nsRect rect; + seqFrame->GetRect(rect); + + // start out with the sequence frame and search the entire frame tree + // capturing the the starting and ending child frames of the selection + // and their rects + FindSelectionBounds(aPresContext, aRC, seqFrame, rect, startFrame, aStartRect, endFrame, aEndRect); + +#ifdef DEBUG_rods + printf("Start Frame: %p\n", startFrame); + printf("End Frame: %p\n", endFrame); +#endif + + // initial the page numbers here + // in case we don't find and frames + aStartPageNum = -1; + aEndPageNum = -1; + + nsIFrame * startPageFrame; + nsIFrame * endPageFrame; + + // check to make sure we found a starting frame + if (startFrame != nsnull) { + // Now search up the tree to find what page the + // start/ending selections frames are on + // + // Check to see if start should be same as end if + // the end frame comes back null + if (endFrame == nsnull) { + // XXX the "GetPageFrame" step could be integrated into + // the FindSelectionBounds step, but walking up to find + // the parent of a child frame isn't expensive and it makes + // FindSelectionBounds a little easier to understand + startPageFrame = GetPageFrame(startFrame); + endPageFrame = startPageFrame; + aEndRect = aStartRect; + } else { + startPageFrame = GetPageFrame(startFrame); + endPageFrame = GetPageFrame(endFrame); + } + } else { + return NS_ERROR_FAILURE; + } + +#ifdef DEBUG_rods + printf("Start Page: %p\n", startPageFrame); + printf("End Page: %p\n", endPageFrame); + + // dump all the pages and their pointers + { + PRInt32 pageNum = 1; + nsIFrame * child; + seqFrame->FirstChild(aPresContext, nsnull, &child); + while (child != nsnull) { + printf("Page: %d - %p\n", pageNum, child); + pageNum++; + child->GetNextSibling(&child); + } + } +#endif + + // Now that we have the page frames + // find out what the page numbers are for each frame + PRInt32 pageNum = 1; + nsIFrame * page; + seqFrame->FirstChild(aPresContext, nsnull, &page); + while (page != nsnull) { + if (page == startPageFrame) { + aStartPageNum = pageNum; + } + if (page == endPageFrame) { + aEndPageNum = pageNum; + } + pageNum++; + page->GetNextSibling(&page); + } + +#ifdef DEBUG_rods + printf("Start Page No: %d\n", aStartPageNum); + printf("End Page No: %d\n", aEndPageNum); +#endif + + *aStartFrame = startPageFrame; + *aEndFrame = endPageFrame; + + return NS_OK; +} + +//------------------------------------------------------- nsresult DocumentViewerImpl::PrintContent(nsIWebShell * aParent, nsIDeviceContext * aDContext) @@ -889,7 +1283,6 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, nsCOMPtr ss; nsCOMPtr vm; PRInt32 width, height; - nsIView *view; nsresult rv; PRInt32 count,i; nsCOMPtr viewer; @@ -922,7 +1315,10 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, nsCOMPtr doc; shell->GetDocument(getter_AddRefs(doc)); if (doc) { - nsCOMPtr rootContent = getter_AddRefs(mDocument->GetRootContent()); + if (mSelectionDoc) { + doc = mSelectionDoc; + } + nsCOMPtr rootContent = getter_AddRefs(doc->GetRootContent()); if (rootContent) { if (NS_SUCCEEDED(FindFrameSetWithIID(rootContent, NS_GET_IID(nsIDOMHTMLFrameSetElement)))) { doesContainFrameSet = PR_TRUE; @@ -955,6 +1351,16 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, NS_ENSURE_SUCCESS( aDContext->BeginDocument(), NS_ERROR_FAILURE ); aDContext->GetDeviceSurfaceDimensions(width, height); + // XXX - Hack Alert + // OK, so ther eis a selection, we will print the entire selection + // on one page and then crop the page. + // This means you can never print any selection that is longer than one page + // put it keeps it from page breaking in the middle of your print of the selection + // (see also nsSimplePageSequence.cpp) + if (IsThereASelection()) { + height = 0x0FFFFFFF; + } + nsCOMPtr cx; nsCOMPtr printcon; rv = NS_NewPrintContext(getter_AddRefs(printcon)); @@ -992,17 +1398,18 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, nsRect tbounds = nsRect(0, 0, width, height); // Create a child window of the parent that is our "root view/window" - rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&view); + nsIView* rootView; + rv = nsComponentManager::CreateInstance(kViewCID, nsnull, NS_GET_IID(nsIView), (void **)&rootView); if (NS_FAILED(rv)) { return rv; } - rv = view->Init(vm, tbounds, nsnull); + rv = rootView->Init(vm, tbounds, nsnull); if (NS_FAILED(rv)) { return rv; } // Setup hierarchical relationship in view manager - vm->SetRootView(view); + vm->SetRootView(rootView); ps->Init(mDocument, cx, vm, ss); @@ -1018,10 +1425,30 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, NS_ENSURE_SUCCESS(GetPresShell(*(getter_AddRefs(presShell))), NS_ERROR_FAILURE); presShell->CaptureHistoryState(getter_AddRefs(layoutState),PR_TRUE); + ps->BeginObservingDocument(); //lay it out... ps->InitialReflow(width, height); + // Transfer Selection Ranges to the new Print PresShell + nsCOMPtr selection; + nsCOMPtr selectionPS; + GetDocumentSelection(getter_AddRefs(selection)); + if (selection) { + GetDocumentSelection(ps, getter_AddRefs(selectionPS)); + if (selectionPS) { + PRInt32 cnt; + selection->GetRangeCount(&cnt); + PRInt32 inx; + for (inx=0;inx range; + if (NS_SUCCEEDED(selection->GetRangeAt(inx, getter_AddRefs(range)))) { + selectionPS->AddRange(range); + } + } + } + } + // update the history from the old presentation shell nsCOMPtr fm; rv = ps->GetFrameManager(getter_AddRefs(fm)); @@ -1034,8 +1461,8 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, // Ask the page sequence frame to print all the pages nsIPageSequenceFrame* pageSequence; - nsPrintOptions options; + // ps->GetPageSequenceFrame(&pageSequence); NS_ASSERTION(nsnull != pageSequence, "no page sequence frame"); @@ -1051,7 +1478,97 @@ DocumentViewerImpl::PrintContent(nsIWebShell * aParent, } fclose(mFilePointer); } else { - pageSequence->Print(cx, options, nsnull); + nsIFrame* rootFrame; + ps->GetRootFrame(&rootFrame); + +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + DumpLayoutData(cx, aDContext, rootFrame, aParent); +#endif + + nsPrintRange printRangeType = ePrintRange_AllPages; + NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv); + if (NS_SUCCEEDED(rv) && printService) { + PRInt32 printType; + printService->GetPrintRange(&printType); + printRangeType = (nsPrintRange)printType; + + // get the document title + const nsString* docTitle = mDocument->GetDocumentTitle(); + PRUnichar * docStr = docTitle->ToNewUnicode(); + printService->SetTitle(docStr); + nsMemory::Free(docStr); + + // Get Document URL String + nsCOMPtr url(getter_AddRefs(mDocument->GetDocumentURL())); + char * urlCStr; + url->GetSpec(&urlCStr); + nsAutoString urlStr; + urlStr.AssignWithConversion(urlCStr); + PRUnichar * urlUStr = urlStr.ToNewUnicode(); + printService->SetURL(urlUStr); + nsMemory::Free(urlUStr); + nsMemory::Free(urlCStr); + + if (ePrintRange_Selection == printRangeType) { + cx->SetIsRenderingOnlySelection(PR_TRUE); + + // temporarily creating rendering context + // which is needed to dinf the selection frames + nsCOMPtr rc; + aDContext->CreateRenderingContext(*getter_AddRefs(rc)); + + // find the starting and ending page numbers + // via the selection + nsIFrame* startFrame; + nsIFrame* endFrame; + PRInt32 startPageNum; + PRInt32 endPageNum; + nsRect startRect; + nsRect endRect; + rv = GetPageRangeForSelection(ps, cx, *rc, selectionPS, pageSequence, + &startFrame, startPageNum, startRect, + &endFrame, endPageNum, endRect); + if (NS_SUCCEEDED(rv)) { + printService->SetPageRange(startPageNum, endPageNum); + if (startPageNum == endPageNum) { + nsIFrame * seqFrame; + if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + return NS_ERROR_FAILURE; + } + nsRect rect(0,0,0,0); + nsRect areaRect; + nsIFrame * areaFrame = FindFrameByType(cx, startFrame, nsHTMLAtoms::body, rect, areaRect); + if (areaFrame) { + areaRect.y = areaRect.y - startRect.y; + areaFrame->SetRect(cx, areaRect); + } + } + } + } + + nsIFrame * seqFrame; + if (NS_FAILED(pageSequence->QueryInterface(NS_GET_IID(nsIFrame), (void **)&seqFrame))) { + return NS_ERROR_FAILURE; + } + + nsRect srect; + seqFrame->GetRect(srect); + + nsRect r; + rootView->GetBounds(r); + r.height = srect.height; + rootView->SetBounds(r); + + rootFrame->GetRect(r); + r.height = srect.height; + rootFrame->SetRect(cx, r); + + pageSequence->Print(cx, printService, nsnull); + + } else { + // not sure what to do here! + return NS_ERROR_FAILURE; + } } aDContext->EndDocument(); @@ -1287,17 +1804,23 @@ DocumentViewerImpl::MakeWindow(nsIWidget* aParentWidget, return rv; } -nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection) +nsresult DocumentViewerImpl::GetDocumentSelection(nsIPresShell * aPresShell, nsISelection **aSelection) { if (!aSelection) return NS_ERROR_NULL_POINTER; - if (!mPresShell) return NS_ERROR_NOT_INITIALIZED; + if (!aPresShell) return NS_ERROR_NULL_POINTER; nsCOMPtr selcon; - selcon = do_QueryInterface(mPresShell); + selcon = do_QueryInterface(aPresShell); if (selcon) return selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, aSelection); return NS_ERROR_FAILURE; } +nsresult DocumentViewerImpl::GetDocumentSelection(nsISelection **aSelection) +{ + if (!mPresShell) return NS_ERROR_NOT_INITIALIZED; + return GetDocumentSelection(mPresShell, aSelection); +} + NS_IMETHODIMP DocumentViewerImpl::CreateDocumentViewerUsing(nsIPresContext* aPresContext, nsIDocumentViewer*& aResult) @@ -1386,6 +1909,8 @@ void DocumentViewerImpl::DocumentReadyForPrinting() NS_RELEASE(mPrintVM); NS_RELEASE(mPrintSS); NS_RELEASE(mPrintDC); + NS_IF_RELEASE(mSelectionDoc); + } } @@ -1535,6 +2060,198 @@ DocumentViewerImpl::GetSaveable(PRBool *aSaveable) static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTORY_CID); +//------------------------------------------------------------------ +#include "nsINodeInfo.h" +#include "nsIDocument.h" +#include "nsHTMLAtoms.h" +#include "nsIHTMLContent.h" +#include "nsINameSpaceManager.h" +#include "nsIWebShell.h" + +static NS_DEFINE_IID(kWebShellCID, NS_WEB_SHELL_CID); +static NS_DEFINE_IID(kCViewCID, NS_VIEW_CID); +static NS_DEFINE_IID(kCChildCID, NS_CHILD_CID); + +#if 0 +nsresult +DocumentViewerImpl::CreateDocShell(nsIPresContext* aPresContext, const nsSize& aSize) +{ + nsresult rv; + mSelectionDocShell = do_CreateInstance(kWebShellCID); + NS_ENSURE_TRUE(mSelectionDocShell, NS_ERROR_FAILURE); + + // pass along marginwidth and marginheight so sub document can use it + mSelectionDocShell->SetMarginWidth(0); + mSelectionDocShell->SetMarginHeight(0); + + /* our parent must be a docshell. we need to get our prefs from our parent */ + nsCOMPtr container; + aPresContext->GetContainer(getter_AddRefs(container)); + NS_ENSURE_TRUE(container, NS_ERROR_UNEXPECTED); + + nsCOMPtr outerShell = do_QueryInterface(container); + NS_ENSURE_TRUE(outerShell, NS_ERROR_UNEXPECTED); + + float t2p; + aPresContext->GetTwipsToPixels(&t2p); + nsCOMPtr presShell; + rv = aPresContext->GetShell(getter_AddRefs(presShell)); + if (NS_FAILED(rv)) { return rv; } + + // create, init, set the parent of the view + nsIView* view; + rv = nsComponentManager::CreateInstance(kCViewCID, nsnull, NS_GET_IID(nsIView), + (void **)&view); + if (NS_FAILED(rv)) { return rv; } + + nsIView* parView; + nsPoint origin; + GetOffsetFromView(aPresContext, origin, &parView); + + nsRect viewBounds(origin.x, origin.y, aSize.width, aSize.height); +#ifdef NOISY + printf("%p view bounds: x=%d, y=%d, w=%d, h=%d\n", view, origin.x, origin.y, aSize.width, aSize.height); +#endif + + nsCOMPtr viewMan; + presShell->GetViewManager(getter_AddRefs(viewMan)); + rv = view->Init(viewMan, viewBounds, parView); + if (NS_FAILED(rv)) { return rv; } + viewMan->InsertChild(parView, view, 0); + rv = view->CreateWidget(kCChildCID); + if (NS_FAILED(rv)) { return rv; } + SetView(aPresContext, view); + + // if the visibility is hidden, reflect that in the view + const nsStyleDisplay* display; + GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display)); + if (!display->IsVisible()) { + view->SetVisibility(nsViewVisibility_kHide); + } + + const nsStyleSpacing* spacing; + GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing); + nsMargin border; + spacing->CalcBorderFor(this, border); + + nsCOMPtr widget; + view->GetWidget(*getter_AddRefs(widget)); + + mSelectionDocShell->SetAllowPlugins(PR_FALSE); + nsCOMPtr docShellAsWin(do_QueryInterface(mSelectionDocShell)); + + PRInt32 x = NSToCoordRound(border.left * t2p); + PRInt32 y = NSToCoordRound(border.top * t2p); + PRInt32 cx = NSToCoordRound((aSize.width - border.right) * t2p); + PRInt32 cy = NSToCoordRound((aSize.height - border.bottom) * t2p); + NS_ENSURE_SUCCESS(docShellAsWin->InitWindow(nsnull, widget, (x >= 0) ? x : 0, + (y >= 0) ? y : 0, cx, cy), NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS(docShellAsWin->Create(), NS_ERROR_FAILURE); + + // move the view to the proper location + viewMan->MoveViewTo(view, origin.x, origin.y); + + mSelectionDocShell->SetDocLoaderObserver(mTempObserver); + + PRInt32 type; + GetType(&type); + if ((PR_FALSE==IsSingleLineTextControl()) || (NS_FORM_INPUT_PASSWORD == type)) { + docShellAsWin->SetVisibility(PR_TRUE); + } + return NS_OK; +} +#endif + +//nsresult DocumentViewerImpl::PrintSelection(nsIDeviceContextSpec * aDevSpec) +nsresult DocumentViewerImpl::GetSelectionDocument(nsIDeviceContextSpec * aDevSpec, nsIDocument ** aNewDoc) +{ + //NS_ENSURE_ARG_POINTER(*aDevSpec); + NS_ENSURE_ARG_POINTER(aNewDoc); + + // create document + nsCOMPtr doc; + nsresult rv = NS_NewHTMLDocument(getter_AddRefs(doc)); + if (NS_FAILED(rv)) { return rv; } + if (!doc) { return NS_ERROR_NULL_POINTER; } + + nsCOMPtr nimgr; + rv = doc->GetNodeInfoManager(*getter_AddRefs(nimgr)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr nodeInfo; + nimgr->GetNodeInfo(nsHTMLAtoms::html, nsnull, kNameSpaceID_None, + *getter_AddRefs(nodeInfo)); + + // create document content + nsCOMPtr htmlElement; + nsCOMPtr headElement; + nsCOMPtr bodyElement; + // create the root + rv = NS_NewHTMLHtmlElement(getter_AddRefs(htmlElement), nodeInfo); + if (NS_FAILED(rv)) { return rv; } + if (!htmlElement) { return NS_ERROR_NULL_POINTER; } + // create the head + + nimgr->GetNodeInfo(NS_ConvertASCIItoUCS2("head"), nsnull, + kNameSpaceID_None, *getter_AddRefs(nodeInfo)); + + rv = NS_NewHTMLHeadElement(getter_AddRefs(headElement), nodeInfo); + if (NS_FAILED(rv)) { return rv; } + if (!headElement) { return NS_ERROR_NULL_POINTER; } + headElement->SetDocument(doc, PR_FALSE, PR_TRUE); + // create the body + + nimgr->GetNodeInfo(nsHTMLAtoms::body, nsnull, kNameSpaceID_None, + *getter_AddRefs(nodeInfo)); + + rv = NS_NewHTMLBodyElement(getter_AddRefs(bodyElement), nodeInfo); + if (NS_FAILED(rv)) { return rv; } + if (!bodyElement) { return NS_ERROR_NULL_POINTER; } + bodyElement->SetDocument(doc, PR_FALSE, PR_TRUE); + // put the head and body into the root + rv = htmlElement->AppendChildTo(headElement, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } + rv = htmlElement->AppendChildTo(bodyElement, PR_FALSE); + if (NS_FAILED(rv)) { return rv; } + + // load the document into the docshell + nsCOMPtr domDoc = do_QueryInterface(doc); + if (!domDoc) { return NS_ERROR_NULL_POINTER; } + nsCOMPtr htmlDOMElement = do_QueryInterface(htmlElement); + if (!htmlDOMElement) { return NS_ERROR_NULL_POINTER; } + + //nsCOMPtr rootContent(do_QueryInterface(htmlElement)); + //doc->SetRootContent(rootContent); + + *aNewDoc = doc.get(); + NS_ADDREF(*aNewDoc); + + return rv; + +} + +PRBool +DocumentViewerImpl::IsThereASelection() +{ + // check here to see if there is a range selection + // so we know whether to turn on the "Selection" radio button + nsCOMPtr selection; + GetDocumentSelection(getter_AddRefs(selection)); + if (selection) { + PRInt32 count; + selection->GetRangeCount(&count); + if (count == 1) { + nsCOMPtr range; + if (NS_SUCCEEDED(selection->GetRangeAt(0, getter_AddRefs(range)))) { + // check to make sure it isn't an insertion selection + PRBool isCollapsed; + selection->GetIsCollapsed(&isCollapsed); + return !isCollapsed; + } + } + } + return PR_FALSE; +} /** --------------------------------------------------- * See documentation above in the nsIContentViewerfile class definition @@ -1543,9 +2260,15 @@ static NS_DEFINE_IID(kDeviceContextSpecFactoryCID, NS_DEVICE_CONTEXT_SPEC_FACTOR NS_IMETHODIMP DocumentViewerImpl::Print(PRBool aSilent,FILE *aFile, nsIPrintListener *aPrintListener) { -nsCOMPtr webContainer; -nsCOMPtr factory; -PRInt32 width,height; + nsCOMPtr webContainer; + nsCOMPtr factory; + PRInt32 width,height; + + nsresult rv = NS_ERROR_FAILURE; + NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv); + if (NS_SUCCEEDED(rv) && printService) { + printService->SetPrintOptions(NS_PRINT_OPTIONS_ENABLE_SELECTION_RADIO, IsThereASelection()); + } nsComponentManager::CreateInstance(kDeviceContextSpecFactoryCID, nsnull, @@ -1566,11 +2289,14 @@ PRInt32 width,height; factory->CreateDeviceContextSpec(nsnull, devspec, aSilent); if (nsnull != devspec) { mPresContext->GetDeviceContext(getter_AddRefs(dx)); - nsresult rv = dx->GetDeviceContextFor(devspec, mPrintDC); + rv = dx->GetDeviceContextFor(devspec, mPrintDC); if (NS_SUCCEEDED(rv)) { NS_RELEASE(devspec); + nsCOMPtr printDoc; + printDoc = mDocument; + // Get the webshell for this documentviewer webContainer = do_QueryInterface(mContainer); if(webContainer) { @@ -1588,15 +2314,24 @@ PRInt32 width,height; mPrintDC->GetDeviceSurfaceDimensions(width,height); + // XXX - Hack Alert + // OK, so ther eis a selection, we will print the entire selection + // on one page and then crop the page. + // This means you can never print any selection that is longer than one page + // put it keeps it from page breaking in the middle of your print of the selection + if (IsThereASelection()) { + height = 0x0FFFFFFF; + } + mPrintPC->Init(mPrintDC); mPrintPC->SetContainer(webContainer); - CreateStyleSet(mDocument,&mPrintSS); + CreateStyleSet(printDoc,&mPrintSS); rv = NS_NewPresShell(&mPrintPS); if(NS_FAILED(rv)){ return rv; } - + rv = nsComponentManager::CreateInstance(kViewManagerCID, nsnull, NS_GET_IID(nsIViewManager),(void**)&mPrintVM); if(NS_FAILED(rv)) { return rv; @@ -1611,7 +2346,7 @@ PRInt32 width,height; if(NS_FAILED(rv)) { return rv; } - + nsRect tbounds = nsRect(0,0,width,height); rv = mPrintView->Init(mPrintVM,tbounds,nsnull); if(NS_FAILED(rv)) { @@ -1620,7 +2355,7 @@ PRInt32 width,height; // setup hierarchical relationship in view manager mPrintVM->SetRootView(mPrintView); - mPrintPS->Init(mDocument,mPrintPC,mPrintVM,mPrintSS); + mPrintPS->Init(printDoc,mPrintPC,mPrintVM,mPrintSS); nsCOMPtr imageGroup; mPrintPC->GetImageGroup(getter_AddRefs(imageGroup)); diff --git a/mozilla/layout/base/src/nsPresContext.cpp b/mozilla/layout/base/src/nsPresContext.cpp index 8c87e648132..1b6f8a00a28 100644 --- a/mozilla/layout/base/src/nsPresContext.cpp +++ b/mozilla/layout/base/src/nsPresContext.cpp @@ -123,6 +123,7 @@ nsPresContext::nsPresContext() mDefaultBackgroundImageOffsetX = mDefaultBackgroundImageOffsetY = 0; mDefaultDirection = NS_STYLE_DIRECTION_LTR; mLanguageSpecificTransformType = eLanguageSpecificTransformType_Unknown; + mIsRenderingOnlySelection = PR_FALSE; } nsPresContext::~nsPresContext() @@ -1313,6 +1314,15 @@ nsPresContext::GetLanguageSpecificTransformType( return NS_OK; } +NS_IMETHODIMP +nsPresContext::IsRenderingOnlySelection(PRBool* aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + *aResult = mIsRenderingOnlySelection; + + return NS_OK; +} + #ifdef MOZ_REFLOW_PERF NS_IMETHODIMP nsPresContext::CountReflows(const char * aName, PRUint32 aType) diff --git a/mozilla/layout/base/src/nsPresContext.h b/mozilla/layout/base/src/nsPresContext.h index c1676e86ec8..793cb92b1e1 100644 --- a/mozilla/layout/base/src/nsPresContext.h +++ b/mozilla/layout/base/src/nsPresContext.h @@ -150,6 +150,9 @@ public: NS_IMETHOD GetLanguageSpecificTransformType( nsLanguageSpecificTransformType* aType); + NS_IMETHOD SetIsRenderingOnlySelection(PRBool aVal) { mIsRenderingOnlySelection = aVal; return NS_OK; } + NS_IMETHOD IsRenderingOnlySelection(PRBool* aResult); + #ifdef MOZ_REFLOW_PERF NS_IMETHOD CountReflows(const char * aName, PRUint32 aType); #endif @@ -205,7 +208,7 @@ protected: PRPackedBool mStopped; // loading stopped PRPackedBool mStopChrome; // should we stop chrome? PRUint8 mDefaultDirection; - + PRPackedBool mIsRenderingOnlySelection; #ifdef DEBUG PRBool mInitialized; #endif diff --git a/mozilla/layout/forms/nsComboboxControlFrame.cpp b/mozilla/layout/forms/nsComboboxControlFrame.cpp index 4d2f99a8475..8bf205a8c20 100644 --- a/mozilla/layout/forms/nsComboboxControlFrame.cpp +++ b/mozilla/layout/forms/nsComboboxControlFrame.cpp @@ -2473,6 +2473,10 @@ nsComboboxControlFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } #ifdef NOISY printf("%p paint layer %d at (%d, %d, %d, %d)\n", this, aWhichLayer, aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); diff --git a/mozilla/layout/forms/nsFieldSetFrame.cpp b/mozilla/layout/forms/nsFieldSetFrame.cpp index e60fb79664d..5e65b76b910 100644 --- a/mozilla/layout/forms/nsFieldSetFrame.cpp +++ b/mozilla/layout/forms/nsFieldSetFrame.cpp @@ -156,10 +156,9 @@ nsFieldSetFrame::Paint(nsIPresContext* aPresContext, { if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { // Paint our background and border - const nsStyleDisplay* disp = - (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); - - if (disp->IsVisible() && mRect.width && mRect.height) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && + isVisible && mRect.width && mRect.height) { PRIntn skipSides = GetSkipSides(); const nsStyleColor* color = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); diff --git a/mozilla/layout/forms/nsFileControlFrame.cpp b/mozilla/layout/forms/nsFileControlFrame.cpp index ad7cd74c4e2..d5b0e36bf78 100644 --- a/mozilla/layout/forms/nsFileControlFrame.cpp +++ b/mozilla/layout/forms/nsFileControlFrame.cpp @@ -269,7 +269,8 @@ nsFileControlFrame::MouseClick(nsIDOMEvent* aMouseEvent) // Get Loc title nsString title; - nsFormControlHelper::GetLocalizedString("FileUpload", title); + nsFormControlHelper::GetLocalizedString(nsFormControlHelper::GetHTMLPropertiesFileName(), + "FileUpload", title); nsCOMPtr filePicker = do_CreateInstance("@mozilla.org/filepicker;1"); if (!filePicker) @@ -658,6 +659,10 @@ nsFileControlFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); } diff --git a/mozilla/layout/forms/nsFormControlFrame.cpp b/mozilla/layout/forms/nsFormControlFrame.cpp index 00dd715ab88..002727c584f 100644 --- a/mozilla/layout/forms/nsFormControlFrame.cpp +++ b/mozilla/layout/forms/nsFormControlFrame.cpp @@ -402,6 +402,10 @@ nsFormControlFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } nsresult rv = nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); diff --git a/mozilla/layout/forms/nsFormControlHelper.cpp b/mozilla/layout/forms/nsFormControlHelper.cpp index d0bd9d6eb3e..08357e86d86 100644 --- a/mozilla/layout/forms/nsFormControlHelper.cpp +++ b/mozilla/layout/forms/nsFormControlHelper.cpp @@ -872,12 +872,10 @@ nsFormControlHelper::GetInputElementValue(nsIContent* aContent, nsString* aText, } //---------------------------------------------------------------------------------- -#define form_properties "chrome://communicator/locale/layout/HtmlForm.properties" - // Return localised string for resource string (e.g. "Submit" -> "Submit Query") // This code is derived from nsBookmarksService::Init() and cookie_Localize() nsresult -nsFormControlHelper::GetLocalizedString(char* aKey, nsString& oVal) +nsFormControlHelper::GetLocalizedString(const char * aPropFileName, const char* aKey, nsString& oVal) { nsresult rv; nsCOMPtr bundle; @@ -887,7 +885,7 @@ nsFormControlHelper::GetLocalizedString(char* aKey, nsString& oVal) NS_WITH_SERVICE(nsIIOService, pNetService, kIOServiceCID, &rv); if (NS_SUCCEEDED(rv) && pNetService) { nsCOMPtr uri; - rv = pNetService->NewURI(form_properties, nsnull, getter_AddRefs(uri)); + rv = pNetService->NewURI(aPropFileName, nsnull, getter_AddRefs(uri)); if (NS_SUCCEEDED(rv) && uri) { // Create bundle diff --git a/mozilla/layout/forms/nsFormControlHelper.h b/mozilla/layout/forms/nsFormControlHelper.h index d9c935deaf8..4e5f3fd3d48 100644 --- a/mozilla/layout/forms/nsFormControlHelper.h +++ b/mozilla/layout/forms/nsFormControlHelper.h @@ -44,6 +44,10 @@ class nsFormFrame; #define NS_STRING_TRUE NS_LITERAL_STRING("1") #define NS_STRING_FALSE NS_LITERAL_STRING("0") +// for localization +#define FORM_PROPERTIES "chrome://communicator/locale/layout/HtmlForm.properties" + + /** * Enumeration of possible mouse states used to detect mouse clicks */ @@ -174,7 +178,8 @@ public: static nsresult GetWrapPropertyEnum(nsIContent * aContent, nsHTMLTextWrap& aWrapProp); // Localization Helper - static nsresult GetLocalizedString(char* aKey, nsString& oVal); + static nsresult GetLocalizedString(const char * aPropFileName, const char* aKey, nsString& oVal); + static const char * GetHTMLPropertiesFileName() { return FORM_PROPERTIES; } static nsresult GetDisabled(nsIContent* aContent, PRBool* oIsDisabled); // diff --git a/mozilla/layout/forms/nsGfxButtonControlFrame.cpp b/mozilla/layout/forms/nsGfxButtonControlFrame.cpp index 93d4d73b070..082db493356 100644 --- a/mozilla/layout/forms/nsGfxButtonControlFrame.cpp +++ b/mozilla/layout/forms/nsGfxButtonControlFrame.cpp @@ -475,17 +475,18 @@ nsGfxButtonControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) NS_IMETHODIMP nsGfxButtonControlFrame::GetDefaultLabel(nsString& aString) { + const char * propname = nsFormControlHelper::GetHTMLPropertiesFileName(); nsresult rv = NS_OK; PRInt32 type; GetType(&type); if (IsReset(type)) { - rv = nsFormControlHelper::GetLocalizedString("Reset", aString); + rv = nsFormControlHelper::GetLocalizedString(propname, "Reset", aString); } else if (IsSubmit(type)) { - rv = nsFormControlHelper::GetLocalizedString("Submit", aString); + rv = nsFormControlHelper::GetLocalizedString(propname, "Submit", aString); } else if (IsBrowse(type)) { - rv = nsFormControlHelper::GetLocalizedString("Browse", aString); + rv = nsFormControlHelper::GetLocalizedString(propname, "Browse", aString); } else { aString.AssignWithConversion(" "); diff --git a/mozilla/layout/forms/nsGfxCheckboxControlFrame.cpp b/mozilla/layout/forms/nsGfxCheckboxControlFrame.cpp index a0034060f11..d641ca7ca9b 100644 --- a/mozilla/layout/forms/nsGfxCheckboxControlFrame.cpp +++ b/mozilla/layout/forms/nsGfxCheckboxControlFrame.cpp @@ -367,10 +367,10 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - const nsStyleDisplay* disp = (const nsStyleDisplay*) - mStyleContext->GetStyleData(eStyleStruct_Display); - if (!disp->IsVisible()) + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { return NS_OK; + } // Paint the background nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); diff --git a/mozilla/layout/forms/nsGfxRadioControlFrame.cpp b/mozilla/layout/forms/nsGfxRadioControlFrame.cpp index 742b5c84c05..8598a7a480e 100644 --- a/mozilla/layout/forms/nsGfxRadioControlFrame.cpp +++ b/mozilla/layout/forms/nsGfxRadioControlFrame.cpp @@ -314,11 +314,10 @@ nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - const nsStyleDisplay* disp = (const nsStyleDisplay*) - mStyleContext->GetStyleData(eStyleStruct_Display); - if (!disp->IsVisible()) - return NS_OK; - + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } // Paint the background nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); diff --git a/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp b/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp index 5fadcbc33b1..a64202530e4 100644 --- a/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/mozilla/layout/forms/nsHTMLButtonControlFrame.cpp @@ -475,14 +475,14 @@ nsHTMLButtonControlFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - const nsStyleDisplay* disp = (const nsStyleDisplay*) - mStyleContext->GetStyleData(eStyleStruct_Display); - if (disp->IsVisible()) - { - nsRect rect(0, 0, mRect.width, mRect.height); - mRenderer.PaintButton(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, rect); + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; } + nsRect rect(0, 0, mRect.width, mRect.height); + mRenderer.PaintButton(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, rect); + #if 0 // old way PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); @@ -498,10 +498,6 @@ nsHTMLButtonControlFrame::Paint(nsIPresContext* aPresContext, border.SizeTo(0, 0, 0, 0); spacing->CalcBorderFor(this, border); - nsRect rect; - GetRect(rect); - rect.x = 0; - rect.y = 0; rect.Deflate(border); aRenderingContext.PushState(); PRBool clipEmpty; diff --git a/mozilla/layout/forms/nsIsIndexFrame.cpp b/mozilla/layout/forms/nsIsIndexFrame.cpp index 17063c2447a..d90b95cd7c4 100644 --- a/mozilla/layout/forms/nsIsIndexFrame.cpp +++ b/mozilla/layout/forms/nsIsIndexFrame.cpp @@ -99,6 +99,19 @@ nsIsIndexFrame::~nsIsIndexFrame() } } +NS_IMETHODIMP +nsIsIndexFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } + return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); +} + NS_IMETHODIMP nsIsIndexFrame::UpdatePromptLabel() { @@ -125,7 +138,8 @@ nsIsIndexFrame::UpdatePromptLabel() // We can't make any assumption as to what the default would be // because the value is localized for non-english platforms, thus // it might not be the string "This is a searchable index. Enter search keywords: " - result = nsFormControlHelper::GetLocalizedString("IsIndexPrompt", prompt); + result = nsFormControlHelper::GetLocalizedString(nsFormControlHelper::GetHTMLPropertiesFileName(), + "IsIndexPrompt", prompt); } nsCOMPtr text = do_QueryInterface(mTextContent); result = text->SetText(prompt.GetUnicode(), prompt.Length(), PR_TRUE); diff --git a/mozilla/layout/forms/nsIsIndexFrame.h b/mozilla/layout/forms/nsIsIndexFrame.h index 37eb142bb5c..30278148b60 100644 --- a/mozilla/layout/forms/nsIsIndexFrame.h +++ b/mozilla/layout/forms/nsIsIndexFrame.h @@ -52,6 +52,11 @@ public: nsIsIndexFrame(); virtual ~nsIsIndexFrame(); + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + // XXX Hack so we can squirrel away the pres context pointer for the KeyPress method NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent, diff --git a/mozilla/layout/forms/nsLegendFrame.cpp b/mozilla/layout/forms/nsLegendFrame.cpp index 4c287c63516..6b069ff1c5b 100644 --- a/mozilla/layout/forms/nsLegendFrame.cpp +++ b/mozilla/layout/forms/nsLegendFrame.cpp @@ -104,6 +104,19 @@ nsLegendFrame::Reflow(nsIPresContext* aPresContext, } +NS_IMETHODIMP +nsLegendFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } + return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); +} + PRInt32 nsLegendFrame::GetAlign() { PRInt32 intValue = NS_STYLE_TEXT_ALIGN_LEFT; diff --git a/mozilla/layout/forms/nsLegendFrame.h b/mozilla/layout/forms/nsLegendFrame.h index 19101c463db..76d38bd88f7 100644 --- a/mozilla/layout/forms/nsLegendFrame.h +++ b/mozilla/layout/forms/nsLegendFrame.h @@ -52,6 +52,11 @@ public: NS_IMETHOD Destroy(nsIPresContext *aPresContext); + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + #ifdef NS_DEBUG NS_IMETHOD GetFrameName(nsString& aResult) const; #endif diff --git a/mozilla/layout/forms/nsListControlFrame.cpp b/mozilla/layout/forms/nsListControlFrame.cpp index 71e65069274..395ff7377c2 100644 --- a/mozilla/layout/forms/nsListControlFrame.cpp +++ b/mozilla/layout/forms/nsListControlFrame.cpp @@ -287,9 +287,55 @@ nsListControlFrame::Destroy(nsIPresContext *aPresContext) return nsScrollFrame::Destroy(aPresContext); } -//--------------------------------------------------------- -//NS_IMPL_ADDREF(nsListControlFrame) -//NS_IMPL_RELEASE(nsListControlFrame) +NS_IMETHODIMP +nsListControlFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + nsIStyleContext* sc = mStyleContext; + const nsStyleDisplay* disp = (const nsStyleDisplay*)sc->GetStyleData(eStyleStruct_Display); + if (!disp->IsVisible()) { + return PR_FALSE; + } + + // Start by assuming we are visible and need to be painted + PRBool isVisible = PR_TRUE; + + PRBool isPaginated; + aPresContext->IsPaginated(&isPaginated); + if (isPaginated) { + PRBool isRendingSelection;; + aPresContext->IsRenderingOnlySelection(&isRendingSelection); + if (isRendingSelection) { + // Check the quick way first + PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + // if we aren't selected in the mState we could be a container + // so check to see if we are in the selection range + if (!isSelected) { + nsCOMPtr shell; + aPresContext->GetShell(getter_AddRefs(shell)); + nsCOMPtr selcon; + selcon = do_QueryInterface(shell); + if (selcon) { + nsCOMPtr selection; + selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection)); + nsCOMPtr node(do_QueryInterface(mContent)); + selection->ContainsNode(node, PR_TRUE, &isVisible); + } else { + isVisible = PR_FALSE; + } + } + } + } + + if (isVisible) { + return nsScrollFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + } + + return NS_OK; + +} //--------------------------------------------------------- // Frames are not refcounted, no need to AddRef diff --git a/mozilla/layout/forms/nsListControlFrame.h b/mozilla/layout/forms/nsListControlFrame.h index b1c1ebc1732..6ca490ed711 100644 --- a/mozilla/layout/forms/nsListControlFrame.h +++ b/mozilla/layout/forms/nsListControlFrame.h @@ -193,6 +193,11 @@ public: NS_IMETHOD MoveTo(nsIPresContext* aPresContext, nscoord aX, nscoord aY); NS_IMETHOD Destroy(nsIPresContext *aPresContext); + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + // nsIFormControlFrame NS_IMETHOD GetType(PRInt32* aType) const; NS_IMETHOD GetName(nsString* aName); diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index 6ba65c8bb8a..669e6e8158c 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -6245,6 +6245,19 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, } #endif + // Check to see if we are an absolutely positioned block (div) + // then then check to see if we need to paint. + const nsStylePosition* postionStyle = (const nsStylePosition*) + mStyleContext->GetStyleData(eStyleStruct_Position); + if (NS_STYLE_POSITION_RELATIVE == postionStyle->mPosition || + NS_STYLE_POSITION_ABSOLUTE == postionStyle->mPosition || + NS_STYLE_POSITION_FIXED == postionStyle->mPosition) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } + } + const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index 6ba65c8bb8a..669e6e8158c 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -6245,6 +6245,19 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, } #endif + // Check to see if we are an absolutely positioned block (div) + // then then check to see if we need to paint. + const nsStylePosition* postionStyle = (const nsStylePosition*) + mStyleContext->GetStyleData(eStyleStruct_Position); + if (NS_STYLE_POSITION_RELATIVE == postionStyle->mPosition || + NS_STYLE_POSITION_ABSOLUTE == postionStyle->mPosition || + NS_STYLE_POSITION_FIXED == postionStyle->mPosition) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } + } + const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); diff --git a/mozilla/layout/generic/nsBlockReflowState.h b/mozilla/layout/generic/nsBlockReflowState.h index 6ba65c8bb8a..669e6e8158c 100644 --- a/mozilla/layout/generic/nsBlockReflowState.h +++ b/mozilla/layout/generic/nsBlockReflowState.h @@ -6245,6 +6245,19 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, } #endif + // Check to see if we are an absolutely positioned block (div) + // then then check to see if we need to paint. + const nsStylePosition* postionStyle = (const nsStylePosition*) + mStyleContext->GetStyleData(eStyleStruct_Position); + if (NS_STYLE_POSITION_RELATIVE == postionStyle->mPosition || + NS_STYLE_POSITION_ABSOLUTE == postionStyle->mPosition || + NS_STYLE_POSITION_FIXED == postionStyle->mPosition) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } + } + const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); diff --git a/mozilla/layout/generic/nsBulletFrame.cpp b/mozilla/layout/generic/nsBulletFrame.cpp index 6f8b48fa99e..099372f554e 100644 --- a/mozilla/layout/generic/nsBulletFrame.cpp +++ b/mozilla/layout/generic/nsBulletFrame.cpp @@ -107,6 +107,7 @@ nsBulletFrame::GetFrameType(nsIAtom** aType) const return NS_OK; } +#include "nsIDOMNode.h" NS_IMETHODIMP nsBulletFrame::Paint(nsIPresContext* aCX, nsIRenderingContext& aRenderingContext, @@ -117,10 +118,8 @@ nsBulletFrame::Paint(nsIPresContext* aCX, return NS_OK; } - const nsStyleDisplay* disp = - (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); - - if (disp->IsVisible()) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aCX, aRenderingContext, PR_TRUE, &isVisible)) && isVisible) { const nsStyleList* myList = (const nsStyleList*)mStyleContext->GetStyleData(eStyleStruct_List); PRUint8 listStyleType = myList->mListStyleType; diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index 96a79aba6ba..294d7003a5e 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -2308,6 +2308,58 @@ nsFrame::ParentDisablesSelection() const return PR_FALSE; } +NS_IMETHODIMP +nsFrame::IsVisibleForPainting(nsIPresContext * aPresContext, + nsIRenderingContext& aRenderingContext, + PRBool aCheckVis, + PRBool* aIsVisible) +{ + // first check to see if we are visible + if (aCheckVis) { + nsIStyleContext* sc = mStyleContext; + const nsStyleDisplay* disp = (const nsStyleDisplay*)sc->GetStyleData(eStyleStruct_Display); + if (!disp->IsVisible()) { + *aIsVisible = PR_FALSE; + return NS_OK; + } + } + + // Start by assuming we are visible and need to be painted + PRBool isVisible = PR_TRUE; + + // start by checking to see if we are paginated which probably means + // we are in print preview or printing + PRBool isPaginated; + aPresContext->IsPaginated(&isPaginated); + if (isPaginated) { + // now see if we are rendering selection only + PRBool isRendingSelection; + aPresContext->IsRenderingOnlySelection(&isRendingSelection); + if (isRendingSelection) { + // Check the quick way first (typically only leaf nodes) + PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + // if we aren't selected in the mState, + // we could be a container so check to see if we are in the selection range + // this is a expensive + if (!isSelected) { + nsCOMPtr shell; + aPresContext->GetShell(getter_AddRefs(shell)); + nsCOMPtr selcon(do_QueryInterface(shell)); + if (selcon) { + nsCOMPtr selection; + selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection)); + nsCOMPtr node(do_QueryInterface(mContent)); + selection->ContainsNode(node, PR_TRUE, &isVisible); + } else { + isVisible = PR_FALSE; + } + } + } + } + + *aIsVisible = isVisible; + return NS_OK; +} NS_IMETHODIMP diff --git a/mozilla/layout/generic/nsFrame.h b/mozilla/layout/generic/nsFrame.h index b0ce1c522b2..b2b26aa4c0c 100644 --- a/mozilla/layout/generic/nsFrame.h +++ b/mozilla/layout/generic/nsFrame.h @@ -278,6 +278,12 @@ public: nsIFrame** aProviderFrame, nsContextProviderRelationship& aRelationship); + // Check Style Visibility and mState for Selection (when printing) + NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext, + nsIRenderingContext& aRenderingContext, + PRBool aCheckVis, + PRBool* aIsVisible); + // nsIHTMLReflow NS_IMETHOD WillReflow(nsIPresContext* aPresContext); NS_IMETHOD Reflow(nsIPresContext* aPresContext, diff --git a/mozilla/layout/generic/nsHTMLFrame.cpp b/mozilla/layout/generic/nsHTMLFrame.cpp index 5332867867f..8ada64acd0c 100644 --- a/mozilla/layout/generic/nsHTMLFrame.cpp +++ b/mozilla/layout/generic/nsHTMLFrame.cpp @@ -20,7 +20,7 @@ * Contributor(s): */ #include "nsHTMLParts.h" -#include "nsContainerFrame.h" +#include "nsHTMLContainerFrame.h" #include "nsCSSRendering.h" #include "nsIDocument.h" #include "nsIReflowCommand.h" diff --git a/mozilla/layout/generic/nsIFrame.h b/mozilla/layout/generic/nsIFrame.h index e7580093633..82231a5ea8b 100644 --- a/mozilla/layout/generic/nsIFrame.h +++ b/mozilla/layout/generic/nsIFrame.h @@ -1092,6 +1092,19 @@ public: nsIFrame** aProviderFrame, nsContextProviderRelationship& aRelationship) = 0; + /** + * Determines whether a frame is visible for painting + * this takes into acount whether it is painting selection for printin + * @param aPresContext PresContext + * @param aRenderingContext PresContext + * @param aCheckVis indicates whether it should check for CSS visibility, + * PR_FALSE skips the check, PR_TRUE does the check + * @param aIsVisible return value + */ + NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext, + nsIRenderingContext& aRenderingContext, + PRBool aCheckVis, + PRBool* aIsVisible) = 0; private: NS_IMETHOD_(nsrefcnt) AddRef(void) = 0; NS_IMETHOD_(nsrefcnt) Release(void) = 0; diff --git a/mozilla/layout/generic/nsIPageSequenceFrame.h b/mozilla/layout/generic/nsIPageSequenceFrame.h index 556fbbe705a..241c8f57a7c 100644 --- a/mozilla/layout/generic/nsIPageSequenceFrame.h +++ b/mozilla/layout/generic/nsIPageSequenceFrame.h @@ -26,6 +26,7 @@ #include "nsISupports.h" class nsIPresContext; +class nsIPrintOptions; // IID for the nsIPageSequenceFrame interface // a6cf90d2-15b3-11d2-932e-00805f8add32 @@ -91,27 +92,6 @@ public: //---------------------------------------------------------------------- -enum nsPrintRange { - ePrintRange_AllPages, // print all pages - ePrintRange_SpecifiedRange // only print pages in the specified range -}; - -/** - * Structure containing options for printing. - */ -struct nsPrintOptions { - nsPrintRange range; - PRInt32 startPage, endPage; // only used for ePrintRange_SpecifiedRange - PRPackedBool oddNumberedPages; // print the odd-numbered pages - PRPackedBool evenNumberedPages; // print the even-numbered pages - - nsPrintOptions() { - range = ePrintRange_AllPages; - startPage = endPage = 1; - oddNumberedPages = evenNumberedPages = PR_TRUE; - } -}; - /** * Interface for accessing special capabilities of the page sequence frame. * @@ -136,7 +116,7 @@ public: * @see nsIPrintStatusCallback#OnProgress() */ NS_IMETHOD Print(nsIPresContext* aPresContext, - const nsPrintOptions& aPrintOptions, + nsIPrintOptions* aPrintOptions, nsIPrintStatusCallback* aStatusCallback) = 0; private: diff --git a/mozilla/layout/generic/nsImageFrame.cpp b/mozilla/layout/generic/nsImageFrame.cpp index aa58537a089..9e2b7b990ac 100644 --- a/mozilla/layout/generic/nsImageFrame.cpp +++ b/mozilla/layout/generic/nsImageFrame.cpp @@ -590,9 +590,9 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - const nsStyleDisplay* disp = (const nsStyleDisplay*) - mStyleContext->GetStyleData(eStyleStruct_Display); - if (disp->IsVisible() && mRect.width && mRect.height) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && + isVisible && mRect.width && mRect.height) { // First paint background and borders nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); diff --git a/mozilla/layout/generic/nsLeafFrame.cpp b/mozilla/layout/generic/nsLeafFrame.cpp index e6b21197498..7dd1cb5d20e 100644 --- a/mozilla/layout/generic/nsLeafFrame.cpp +++ b/mozilla/layout/generic/nsLeafFrame.cpp @@ -40,6 +40,12 @@ nsLeafFrame::Paint(nsIPresContext* aPresContext, nsFramePaintLayer aWhichLayer) { if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && + !isVisible) {// just checks selection painting + return NS_OK; // not visibility + } + const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); if (disp->IsVisibleOrCollapsed()) { diff --git a/mozilla/layout/generic/nsPageFrame.cpp b/mozilla/layout/generic/nsPageFrame.cpp index 22f87955a3f..1bab5ea65c2 100644 --- a/mozilla/layout/generic/nsPageFrame.cpp +++ b/mozilla/layout/generic/nsPageFrame.cpp @@ -31,6 +31,27 @@ #include "nsLayoutAtoms.h" #include "nsIStyleSet.h" #include "nsIPresShell.h" +#include "nsIDeviceContext.h" + +// for page number localization formatting +#include "nsTextFormatter.h" + +// DateTime Includes +#include "nsDateTimeFormatCID.h" +#include "nsIDateTimeFormat.h" +#include "nsIServiceManager.h" +#include "nsILocale.h" +#include "nsLocaleCID.h" +#include "nsILocaleService.h" + +static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID); +static NS_DEFINE_CID(kLocaleServiceCID, NS_LOCALESERVICE_CID); + +// Temporary +#include "nsIFontMetrics.h" + +// tstaic data members +PRUnichar * nsPageFrame::mPageNumFormat = nsnull; nsresult NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) @@ -47,10 +68,22 @@ NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } -nsPageFrame::nsPageFrame() +nsPageFrame::nsPageFrame() : + mHeadFootFont(nsnull) { } +nsPageFrame::~nsPageFrame() +{ + if (mHeadFootFont) + delete mHeadFootFont; + + if (mPageNumFormat) { + nsMemory::Free(mPageNumFormat); + mPageNumFormat = nsnull; + } +} + NS_METHOD nsPageFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, @@ -173,3 +206,253 @@ nsPageFrame::IsPercentageBase(PRBool& aBase) const aBase = PR_TRUE; return NS_OK; } + +//------------------------------------------------------------------------------ +nscoord nsPageFrame::GetXPosition(nsIRenderingContext& aRenderingContext, + const nsRect& aRect, + PRInt32 aJust, + const nsString& aStr) +{ + PRInt32 width; + aRenderingContext.GetWidth(aStr, width); + + nscoord x = aRect.x; + switch (aJust) { + case NS_PRINT_JUSTIFY_LEFT: + // do nothing, already set + break; + + case NS_PRINT_JUSTIFY_CENTER: + x += (aRect.width - width) / 2; + break; + + case NS_PRINT_JUSTIFY_RIGHT: + x += aRect.width - width; + break; + } // switch + + return x; +} + +//------------------------------------------------------------------------------ +// Draw a Header or footer text lrft,right or center justified +// @parm aRenderingContext - rendering content ot draw into +// @parm aHeaderFooter - indicates whether it is a header or footer +// @parm aJust - indicates the justification of the text +// @parm aStr - The string to be drawn +// @parm aRect - the rect of the page +// @parm aHeight - the height of the text +// @parm aUseHalfThePage - indicates whether the text should limited to the width +// of the entire page or just half the page +void +nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext, + nsIFrame * aFrame, + nsHeaderFooterEnum aHeaderFooter, + PRInt32 aJust, + const nsString& aStr, + const nsRect& aRect, + nscoord aHeight, + PRBool aUseHalfThePage) +{ + // first make sure we have a vaild string and that the height of the + // text will fit in the margin + if (aStr.Length() > 0 && + ((aHeaderFooter == eHeader && aHeight < mMargin.top) || + (aHeaderFooter == eFooter && aHeight < mMargin.bottom))) { + // measure the width of the text + nsString str = aStr; + PRInt32 width; + aRenderingContext.GetWidth(str, width); + PRBool addEllipse = PR_FALSE; + nscoord halfWidth = aRect.width; + if (aUseHalfThePage) { + halfWidth /= 2; + } + // trim the text and add the elipses if it won't fit + while (width >= halfWidth && str.Length() > 1) { + str.SetLength(str.Length()-1); + aRenderingContext.GetWidth(str, width); + addEllipse = PR_TRUE; + } + if (addEllipse && str.Length() > 3) { + str.SetLength(str.Length()-3); + str.AppendWithConversion("..."); + aRenderingContext.GetWidth(str, width); + } + + // cacl the x and y positions of the text + nsRect rect(aRect); + nscoord x = GetXPosition(aRenderingContext, rect, aJust, str); + nscoord y; + if (aHeaderFooter == eHeader) { + nscoord offset = ((mMargin.top - aHeight) / 2); + y = rect.y - offset - aHeight; + rect.Inflate(0, offset + aHeight); + } else { + nscoord offset = ((mMargin.bottom - aHeight) / 2); + y = rect.y + rect.height + offset; + rect.height += offset + aHeight; + } + + // set up new clip and draw the text + PRBool clipEmpty; + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(rect, nsClipCombine_kReplace, clipEmpty); + aRenderingContext.DrawString(str, x, y); + aRenderingContext.PopState(clipEmpty); + } +} + +//------------------------------------------------------------------------------ +NS_IMETHODIMP +nsPageFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + nsresult rv = nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + + if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { + // get the current margin + mPrintOptions->GetMargin(mMargin); + + nsRect rect(0,0,mRect.width, mRect.height); + +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + // XXX Paint a one-pixel border around the page so it's easy to see where + // each page begins and ends when we're + float p2t; + aPresContext->GetPixelsToTwips(&p2t); + rect.Deflate(NSToCoordRound(p2t), NSToCoordRound(p2t)); + aRenderingContext.SetColor(NS_RGB(0, 0, 0)); + //aRenderingContext.DrawRect(rect); + rect.Inflate(NSToCoordRound(p2t), NSToCoordRound(p2t)); + printf("SPSF::PaintChild -> Painting Frame %p Page No: %d\n", this, mPageNum); +#endif + // use the whole page + rect.width += mMargin.left + mMargin.right; + rect.x -= mMargin.left; + + aRenderingContext.SetFont(*mHeadFootFont); + aRenderingContext.SetColor(NS_RGB(0,0,0)); + + // Get the FontMetrics to determine width.height of strings + nsCOMPtr deviceContext; + aPresContext->GetDeviceContext(getter_AddRefs(deviceContext)); + NS_ASSERTION(deviceContext, "Couldn't get the device context"); + nsCOMPtr fontMet; + deviceContext->GetMetricsFor(*mHeadFootFont, *getter_AddRefs(fontMet)); + nscoord visibleHeight = 0; + if (fontMet) { + fontMet->GetHeight(visibleHeight); + } + + // get the print options bits so we can figure out all the + // the extra pieces of text that need to be drawn + PRInt32 printOptBits; + mPrintOptions->GetPrintOptionsBits(&printOptBits); + + // print page numbers + if (printOptBits & NS_PRINT_OPTIONS_PRINT_PAGE_NUMS && mPageNumFormat != nsnull) { + PRInt32 justify = NS_PRINT_JUSTIFY_LEFT; + mPrintOptions->GetPageNumJust(&justify); + + PRUnichar * valStr; + // print page number totals "x of x" + if (printOptBits & NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL) { + valStr = nsTextFormatter::smprintf(mPageNumFormat, mPageNum, mTotNumPages); + } else { + valStr = nsTextFormatter::smprintf(mPageNumFormat, mPageNum); + } + nsAutoString pageNoStr(valStr); + nsMemory::Free(valStr); + DrawHeaderFooter(aRenderingContext, this, eFooter, justify, pageNoStr, rect, visibleHeight); + } + + // print localized date + if (printOptBits & NS_PRINT_OPTIONS_PRINT_DATE_PRINTED) { + // Get Locale for Formating DateTime + nsCOMPtr locale; + NS_WITH_SERVICE(nsILocaleService, localeSvc, kLocaleServiceCID, &rv); + if (NS_SUCCEEDED(rv)) { + + rv = localeSvc->GetApplicationLocale(getter_AddRefs(locale)); + if (NS_SUCCEEDED(rv) && locale) { + nsCOMPtr dateTime; + rv = nsComponentManager::CreateInstance(kDateTimeFormatCID, + NULL, + NS_GET_IID(nsIDateTimeFormat), + (void**) getter_AddRefs(dateTime)); + + if (NS_SUCCEEDED(rv)) { + nsAutoString dateString; + time_t ltime; + time( <ime ); + rv = dateTime->FormatTMTime(locale, kDateFormatShort, kTimeFormatNoSeconds, localtime( <ime ), dateString); + if (NS_SUCCEEDED(rv)) { + DrawHeaderFooter(aRenderingContext, this, eFooter, NS_PRINT_JUSTIFY_RIGHT, dateString, rect, visibleHeight); + } + } + } + } + } + + + PRBool usingHalfThePage = (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_TITLE) && (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_LOCATION); + + // print document title + PRUnichar * title; + mPrintOptions->GetTitle(&title); // creates memory + if (title != nsnull && (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_TITLE)) { + DrawHeaderFooter(aRenderingContext, this, eHeader, NS_PRINT_JUSTIFY_LEFT, nsAutoString(title), rect, visibleHeight, usingHalfThePage); + nsMemory::Free(title); + } + + // print document URL + PRUnichar * url; + mPrintOptions->GetURL(&url); + if (title != url && (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_LOCATION)) { + DrawHeaderFooter(aRenderingContext, this, eHeader, NS_PRINT_JUSTIFY_RIGHT, nsAutoString(url), rect, visibleHeight, usingHalfThePage); + nsMemory::Free(url); + } + + } + + return rv; +} + +//------------------------------------------------------------------------------ +void +nsPageFrame::SetPrintOptions(nsIPrintOptions * aPrintOptions) +{ + NS_ASSERTION(aPrintOptions != nsnull, "Print Options can not be null!"); + + mPrintOptions = aPrintOptions; + // create a default font + mHeadFootFont = new nsFont("serif", NS_FONT_STYLE_NORMAL,NS_FONT_VARIANT_NORMAL, + NS_FONT_WEIGHT_NORMAL,0,NSIntPointsToTwips(10)); + // now get the default font form the print options + mPrintOptions->GetDefaultFont(*mHeadFootFont); +} + +//------------------------------------------------------------------------------ +void +nsPageFrame::SetPageNumInfo(PRInt32 aPageNumber, PRInt32 aTotalPages) +{ + mPageNum = aPageNumber; + mTotNumPages = aTotalPages; +} + + +//------------------------------------------------------------------------------ +void +nsPageFrame::SetPageNumberFormat(PRUnichar * aFormatStr) +{ + NS_ASSERTION(aFormatStr != nsnull, "Format string cannot be null!"); + + if (mPageNumFormat != nsnull) { + nsMemory::Free(mPageNumFormat); + } + mPageNumFormat = aFormatStr; +} + diff --git a/mozilla/layout/generic/nsPageFrame.h b/mozilla/layout/generic/nsPageFrame.h index 1403d842bd5..59d3bff2d24 100644 --- a/mozilla/layout/generic/nsPageFrame.h +++ b/mozilla/layout/generic/nsPageFrame.h @@ -22,17 +22,25 @@ #ifndef nsPageFrame_h___ #define nsPageFrame_h___ -#include "nsHTMLContainerFrame.h" +#include "nsContainerFrame.h" +#include "nsIPrintOptions.h" // Page frame class used by the simple page sequence frame class nsPageFrame : public nsContainerFrame { public: friend nsresult NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aResult); + // nsIFrame NS_IMETHOD Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aMaxSize, nsReflowStatus& aStatus); + + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + NS_IMETHOD IsPercentageBase(PRBool& aBase) const; /** @@ -47,8 +55,51 @@ public: NS_IMETHOD GetFrameName(nsString& aResult) const; #endif + ////////////////// + // For Printing + ////////////////// + + // Set the print options object into the page for printing + virtual void SetPrintOptions(nsIPrintOptions * aPrintOptions); + + // Tell the page which page number it is out of how many + virtual void SetPageNumInfo(PRInt32 aPageNumber, PRInt32 aTotalPages); + + // This is class is now responsible for freeing the memory + static void SetPageNumberFormat(PRUnichar * aFormatStr); + protected: nsPageFrame(); + virtual ~nsPageFrame(); + + typedef enum { + eHeader, + eFooter + } nsHeaderFooterEnum; + + nscoord GetXPosition(nsIRenderingContext& aRenderingContext, + const nsRect& aRect, + PRInt32 aJust, + const nsString& aStr); + + void DrawHeaderFooter(nsIRenderingContext& aRenderingContext, + nsIFrame * aFrame, + nsHeaderFooterEnum aHeaderFooter, + PRInt32 aJust, + const nsString& sStr, + const nsRect& aRect, + nscoord aHeight, + PRBool aUseHalfThePage = PR_TRUE); + + + nsCOMPtr mPrintOptions; + PRInt32 mPageNum; + PRInt32 mTotNumPages; + nsMargin mMargin; + nsFont * mHeadFootFont; + + static PRUnichar * mPageNumFormat; + }; #endif /* nsPageFrame_h___ */ diff --git a/mozilla/layout/generic/nsSimplePageSequence.cpp b/mozilla/layout/generic/nsSimplePageSequence.cpp index e6d9bbfc664..b7fc28298d3 100644 --- a/mozilla/layout/generic/nsSimplePageSequence.cpp +++ b/mozilla/layout/generic/nsSimplePageSequence.cpp @@ -31,6 +31,24 @@ #include "nsIViewManager.h" #include "nsIPresShell.h" #include "nsIStyleSet.h" +#include "nsIFontMetrics.h" +#include "nsIPrintOptions.h" +#include "nsPageFrame.h" + +#define OFFSET_NOT_SET -1 + +// This is for localization of the "x of n" pages string +// this class contains a helper method we need to get +// a string from a string bundle +#include "nsFormControlHelper.h" +#define PRINTING_PROPERTIES "chrome://communicator/locale/printing.properties" + +// Print Options +#include "nsIPrintOptions.h" +#include "nsGfxCIID.h" +#include "nsIServiceManager.h" +static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID); +// nsresult NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) @@ -47,7 +65,28 @@ NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } -nsSimplePageSequenceFrame::nsSimplePageSequenceFrame() +nsSimplePageSequenceFrame::nsSimplePageSequenceFrame() : + mIsPrintingSelection(PR_FALSE) +{ + mStartOffset = OFFSET_NOT_SET; + mEndOffset = OFFSET_NOT_SET; + + nscoord halfInch = NS_INCHES_TO_TWIPS(0.5); + mMargin.SizeTo(halfInch, halfInch, halfInch, halfInch); + + // XXX this code and the object data member "mIsPrintingSelection" is only needed + // for the hack for printing selection where we make the page the max size + nsresult rv; + NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv); + if (NS_SUCCEEDED(rv) && printService) { + PRInt32 printType; + printService->GetPrintRange(&printType); + mIsPrintingSelection = ePrintRange_Selection == nsPrintRange(printType); + } + +} + +nsSimplePageSequenceFrame::~nsSimplePageSequenceFrame() { } @@ -67,9 +106,6 @@ nsSimplePageSequenceFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr //---------------------------------------------------------------------- -// XXX Hack -#define PAGE_SPACING_TWIPS 100 - // Creates a continuing page frame nsresult nsSimplePageSequenceFrame::CreateContinuingPageFrame(nsIPresContext* aPresContext, @@ -110,12 +146,10 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext* aPresConte aReflowState.reflowCommand->GetNext(nextFrame); // Compute the y-offset of this page - for (nsIFrame* f = mFrames.FirstChild(); f != nextFrame; - f->GetNextSibling(&f)) { + for (nsIFrame* f = mFrames.FirstChild(); f != nextFrame; f->GetNextSibling(&f)) { nsSize size; - f->GetSize(size); - aY += size.height + PAGE_SPACING_TWIPS; + aY += size.height + mMargin.top + mMargin.bottom; } // Reflow the page @@ -131,7 +165,7 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext* aPresConte // Place and size the page. If the page is narrower than our max width, then // center it horizontally FinishReflowChild(nextFrame, aPresContext, kidSize, aX, aY, 0); - aY += kidSize.height + PAGE_SPACING_TWIPS; + aY += kidSize.height + mMargin.top + mMargin.bottom; // Check if the page is complete... nsIFrame* kidNextInFlow; @@ -174,7 +208,7 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext* aPresConte aY += childSize.height; // Leave a slight gap between the pages - aY += PAGE_SPACING_TWIPS; + aY += mMargin.top + mMargin.bottom; // Is the page complete? kidFrame->GetNextInFlow(&kidNextInFlow); @@ -216,15 +250,21 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, nsSize pageSize; aPresContext->GetPageWidth(&pageSize.width); aPresContext->GetPageHeight(&pageSize.height); - PRInt32 extra = aReflowState.availableWidth - 2 * PAGE_SPACING_TWIPS - pageSize.width; - nscoord x = PAGE_SPACING_TWIPS; - if (extra > 0) { - x += extra / 2; + // XXX - Hack Alert + // OK, so ther eis a selection, we will print the entire selection + // on one page and then crop the page. + // This means you can never print any selection that is longer than one page + // put it keeps it from page breaking in the middle of your print of the selection + // (see also nsDocumentViewer.cpp) + if (mIsPrintingSelection) { + pageSize.height = 0x0FFFFFFF; } + nscoord x = mMargin.left; + // Running y-offset for each page - nscoord y = PAGE_SPACING_TWIPS; + nscoord y = mMargin.top; // See if it's an incremental reflow command if (eReflowReason_Incremental == aReflowState.reason) { @@ -240,6 +280,10 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, pageSize, reflowReason); nsReflowStatus status; + kidReflowState.availableWidth = pageSize.width - mMargin.left - mMargin.right; + kidReflowState.availableHeight = pageSize.height - mMargin.top - mMargin.bottom; + kidReflowState.mComputedWidth = kidReflowState.availableWidth; + //kidReflowState.mComputedHeight = kidReflowState.availableHeight; // Place and size the page. If the page is narrower than our // max width then center it horizontally @@ -248,8 +292,16 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, FinishReflowChild(kidFrame, aPresContext, kidSize, x, y, 0); y += kidSize.height; + nsIView* view; + kidFrame->GetView(aPresContext, &view); + NS_ASSERTION(nsnull != view, "no page view"); + nsRect rect; + kidFrame->GetRect(rect); + nsRect viewRect; + view->GetBounds(viewRect); + // Leave a slight gap between the pages - y += PAGE_SPACING_TWIPS; + y += mMargin.top + mMargin.bottom; // Is the page complete? nsIFrame* kidNextInFlow; @@ -274,9 +326,9 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, } // Return our desired size - aDesiredSize.height = y; - aDesiredSize.width = 2*PAGE_SPACING_TWIPS + pageSize.width; - aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.height = y; + aDesiredSize.width = pageSize.width; + aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; NS_FRAME_TRACE_REFLOW_OUT("nsSimplePageSequeceFrame::Reflow", aStatus); @@ -293,53 +345,6 @@ nsSimplePageSequenceFrame::GetFrameName(nsString& aResult) const } #endif -NS_IMETHODIMP -nsSimplePageSequenceFrame::Paint(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer) -{ - if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { - // Paint a white background - aRenderingContext.SetColor(NS_RGB(255,255,255)); - aRenderingContext.FillRect(aDirtyRect); - // XXX Crop marks or hash marks would be nice. Use style info... - } - - return nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, - aWhichLayer); -} - -void -nsSimplePageSequenceFrame::PaintChild(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsIFrame* aFrame, - nsFramePaintLayer aWhichLayer) -{ - // Let the page paint - nsContainerFrame::PaintChild(aPresContext, aRenderingContext, - aDirtyRect, aFrame, aWhichLayer); - - if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { - // XXX Paint a one-pixel border around the page so it's easy to see where - // each page begins and ends when we're in print preview mode - nsRect pageBounds; - float p2t; - aPresContext->GetPixelsToTwips(&p2t); - - aRenderingContext.SetColor(NS_RGB(0, 0, 0)); - aFrame->GetRect(pageBounds); - pageBounds.Inflate(NSToCoordRound(p2t), NSToCoordRound(p2t)); - - // this paints a rectangle around the for the printer output, - // which sometimes appears, other times - // goes away. I have to look into this further or ask troy.. - // I took it out for the time being to fix some bugs -- dwc - //aRenderingContext.DrawRect(pageBounds); - } -} - //---------------------------------------------------------------------- // Helper function that sends the progress notification. Returns PR_TRUE @@ -361,15 +366,37 @@ SendStatusNotification(nsIPrintStatusCallback* aStatusCallback, NS_IMETHODIMP nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext, - const nsPrintOptions& aPrintOptions, + nsIPrintOptions* aPrintOptions, nsIPrintStatusCallback* aStatusCallback) { + NS_ENSURE_ARG_POINTER(aPresContext); + NS_ENSURE_ARG_POINTER(aPrintOptions); + + nsPrintRange printRangeType; + PRInt32 fromPageNum; + PRInt32 toPageNum; + PRInt32 marginL, marginR, marginT, marginB; + PRBool printEvenPages, printOddPages; + + PRInt32 printType; + aPrintOptions->GetPrintRange(&printType); + printRangeType = (nsPrintRange)printType; + aPrintOptions->GetPageRange(&fromPageNum, &toPageNum); + aPrintOptions->GetMargins(&marginT, &marginL, &marginR, &marginB); + mMargin.SizeTo(nscoord(marginL), nscoord(marginT), nscoord(marginR), nscoord(marginB)); + + aPrintOptions->GetPrintOptions(NS_PRINT_OPTIONS_PRINT_EVEN_PAGES, &printEvenPages); + aPrintOptions->GetPrintOptions(NS_PRINT_OPTIONS_PRINT_ODD_PAGES, &printOddPages); + + PRBool doingPageRange = ePrintRange_SpecifiedPageRange == printRangeType || + ePrintRange_Selection == printRangeType; + // If printing a range of pages make sure at least the starting page // number is valid PRInt32 totalPages = mFrames.GetLength(); - if (ePrintRange_SpecifiedRange == aPrintOptions.range) { - if (aPrintOptions.startPage > totalPages) { + if (doingPageRange) { + if (fromPageNum > totalPages) { return NS_ERROR_INVALID_ARG; } } @@ -383,29 +410,158 @@ nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext, presShell->GetViewManager(getter_AddRefs(vm)); nsresult rv = NS_OK; +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + { + nsIView * seqView; + GetView(aPresContext, &seqView); + nsRect rect; + GetRect(rect); + printf("Seq Frame: - %d,%d,%d,%d ", rect.x, rect.y, rect.width, rect.height); + printf("view: %p ", seqView); + nsRect viewRect; + if (seqView) { + seqView->GetBounds(viewRect); + printf(" %d,%d,%d,%d", viewRect.x, viewRect.y, viewRect.width, viewRect.height); + } + printf("\n"); + } + + { + PRInt32 pageNum = 1; + for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) { + nsIView* view; + page->GetView(aPresContext, &view); + NS_ASSERTION(nsnull != view, "no page view"); + nsRect rect; + page->GetRect(rect); + nsRect viewRect; + view->GetBounds(viewRect); + printf("Page: %d - %d,%d,%d,%d ", pageNum, rect.x, rect.y, rect.width, rect.height); + printf(" %d,%d,%d,%d\n", viewRect.x, viewRect.y, viewRect.width, viewRect.height); + pageNum++; + } + } + printf("***** Setting aPresContext %p is painting selection %d\n", aPresContext, ePrintRange_Selection == printRangeType); +#endif + + // Determine if we are rendering only the selection + aPresContext->SetIsRenderingOnlySelection(ePrintRange_Selection == printRangeType); + + + if (doingPageRange) { + // XXX because of the hack for making the selection all print on one page + // we must make sure that the page is sized correctly before printing. + PRInt32 width,height; + dc->GetDeviceSurfaceDimensions(width,height); + height -= mMargin.top + mMargin.bottom; + + PRInt32 pageNum = 1; + nscoord y = mMargin.top; + for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) { + nsIView* view; + page->GetView(aPresContext, &view); + NS_ASSERTION(nsnull != view, "no page view"); + if (pageNum < fromPageNum || pageNum > toPageNum) { + // XXX Doesn't seem like we need to do this + // because we ask only the pages we want to print + //view->SetVisibility(nsViewVisibility_kHide); + } else { + nsRect rect; + page->GetRect(rect); + rect.y = y; + rect.height = height; + page->SetRect(aPresContext, rect); + nsRect viewRect; + view->GetBounds(viewRect); + viewRect.y = y; + viewRect.height = height; + view->SetBounds(viewRect); + y += rect.height + mMargin.top + mMargin.bottom; + } + pageNum++; + } + + // adjust total number of pages + if (ePrintRange_Selection == printRangeType) { + totalPages = toPageNum - fromPageNum + 1; + } else { + totalPages = pageNum - 1; + } + } + + // XXX - This wouldn't have to be done each time + // but it isn't that expensive and this the best place + // to have access to a localized file properties file + // + // Note: because this is done here it makes a little bit harder + // to have UI for setting the header/footer font name and size + // + // Get default font name and size to be used for the headers and footers + nsAutoString fontName; + rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, "fontname", fontName); + if (NS_FAILED(rv)) { + fontName.AssignWithConversion("serif"); + } + + nsAutoString fontSizeStr; + nscoord pointSize = 10;; + rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, "fontsize", fontSizeStr); + if (NS_SUCCEEDED(rv)) { + PRInt32 errCode; + pointSize = fontSizeStr.ToInteger(&errCode); + if (NS_FAILED(errCode)) { + pointSize = 10; + } + } + aPrintOptions->SetFontNamePointSize(fontName, pointSize); + + // Now go get the Localized Page Formating String + PRBool doingPageTotals = PR_TRUE; + aPrintOptions->GetPrintOptions(NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL, &doingPageTotals); + + nsAutoString pageFormatStr; + rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, + doingPageTotals?"pageofpages":"pagenumber", + pageFormatStr); + if (NS_FAILED(rv)) { // back stop formatting + pageFormatStr.AssignWithConversion(doingPageTotals?"%ld of %ld":"%ld"); + } + // Sets the format into a static data memeber which will own the memory and free it + nsPageFrame::SetPageNumberFormat(pageFormatStr.ToNewUnicode()); + // Print each specified page - PRInt32 pageNum = 1; + // pageNum keeps track of the current page and what pages are printing + // + // printedPageNum keeps track of the current page number to be printed + // Note: When print al the pages or a page range the printed page shows the + // actual page number, when printing selection it prints the page number starting + // with the first page of the selection. For example if the user has a + // selection that starts on page 2 and ends on page 3, the page numbers when + // print are 1 and then two (which is different than printing a page range, where + // the page numbers would have been 2 and then 3) + PRInt32 pageNum = 1; + PRInt32 printedPageNum = 1; for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) { // See whether we should print this page PRBool printThisPage = PR_TRUE; // If printing a range of pages check whether the page number is in the // range of pages to print - if (ePrintRange_SpecifiedRange == aPrintOptions.range) { - if (pageNum < aPrintOptions.startPage) { + if (doingPageRange) { + if (pageNum < fromPageNum) { printThisPage = PR_FALSE; - } else if (pageNum > aPrintOptions.endPage) { + } else if (pageNum > toPageNum) { break; } } // Check for printing of odd and even pages if (pageNum & 0x1) { - if (!aPrintOptions.oddNumberedPages) { + if (!printOddPages) { printThisPage = PR_FALSE; // don't print odd numbered page } } else { - if (!aPrintOptions.evenNumberedPages) { + if (!printEvenPages) { printThisPage = PR_FALSE; // don't print even numbered page } } @@ -424,18 +580,37 @@ nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext, } break; } - + + // cast the frame to be a page frame + nsPageFrame * pf = NS_STATIC_CAST(nsPageFrame*, page); + if (pf != nsnull) { + pf->SetPrintOptions(aPrintOptions); + pf->SetPageNumInfo(printedPageNum, totalPages); + } + // Print the page nsIView* view; page->GetView(aPresContext, &view); + NS_ASSERTION(nsnull != view, "no page view"); - vm->Display(view); +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + { + char * fontname = fontName.ToNewCString(); + printf("SPSF::Paint -> FontName[%s] Point Size: %d\n", fontname, pointSize); + nsMemory::Free(fontname); + printf("SPSF::Paint -> PageNo: %d View: %p\n", pageNum, view); + } +#endif + vm->Display(view, mMargin.left, mMargin.top); + // this view was printed and since display set the origin // 0,0 there is a danger that this view can be printed again // If it is a sibling to another page/view. Setting the visibility // to hide will keep this page from printing again - dwc - view->SetVisibility(nsViewVisibility_kHide); + // + // XXX Doesn't seem like we need to do this anymore + //view->SetVisibility(nsViewVisibility_kHide); // Finish printing of the page if (!SendStatusNotification(aStatusCallback, pageNum, totalPages, @@ -452,9 +627,21 @@ nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext, } } - // Increment the page number + if (ePrintRange_Selection != printRangeType || + (ePrintRange_Selection == printRangeType && printThisPage)) { + printedPageNum++; + } + pageNum++; } return rv; } + +NS_IMETHODIMP +nsSimplePageSequenceFrame::SetOffsets(nscoord aStartOffset, nscoord aEndOffset) +{ + mStartOffset = aStartOffset; + mEndOffset = aEndOffset; + return NS_OK; +} diff --git a/mozilla/layout/generic/nsSimplePageSequence.h b/mozilla/layout/generic/nsSimplePageSequence.h index ff0f07c51ad..7683d77aa77 100644 --- a/mozilla/layout/generic/nsSimplePageSequence.h +++ b/mozilla/layout/generic/nsSimplePageSequence.h @@ -22,8 +22,9 @@ #ifndef nsSimplePageSequence_h___ #define nsSimplePageSequence_h___ -#include "nsHTMLContainerFrame.h" #include "nsIPageSequenceFrame.h" +#include "nsContainerFrame.h" +#include "nsIPrintOptions.h" // Simple page sequence frame class. Used when we're in paginated mode class nsSimplePageSequenceFrame : public nsContainerFrame, @@ -40,16 +41,12 @@ public: const nsHTMLReflowState& aMaxSize, nsReflowStatus& aStatus); - // nsIFrame - NS_IMETHOD Paint(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer); - // nsIPageSequenceFrame NS_IMETHOD Print(nsIPresContext* aPresContext, - const nsPrintOptions& aPrintOptions, + nsIPrintOptions* aPrintOptions, nsIPrintStatusCallback* aStatusCallback); + NS_IMETHOD SetOffsets(nscoord aStartOffset, nscoord aEndOffset); + NS_IMETHOD SetPageNo(PRInt32 aPageNo) { return NS_OK;} #ifdef DEBUG // Debugging @@ -58,11 +55,7 @@ public: protected: nsSimplePageSequenceFrame(); - virtual void PaintChild(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsIFrame* aFrame, - nsFramePaintLayer aWhichLayer); + virtual ~nsSimplePageSequenceFrame(); nsresult IncrementalReflow(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, @@ -73,9 +66,14 @@ protected: nsresult CreateContinuingPageFrame(nsIPresContext* aPresContext, nsIFrame* aPageFrame, nsIFrame** aContinuingFrame); - NS_IMETHOD_(nsrefcnt) AddRef(void) {return nsContainerFrame::AddRef();} NS_IMETHOD_(nsrefcnt) Release(void) {return nsContainerFrame::Release();} + + nscoord mStartOffset; + nscoord mEndOffset; + + nsMargin mMargin; + PRBool mIsPrintingSelection; }; #endif /* nsSimplePageSequence_h___ */ diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index ecf2f632c07..a9e67394413 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -427,6 +427,11 @@ public: PRInt32* outFrameContentOffset, nsIFrame* *outChildFrame); + NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext, + nsIRenderingContext& aRenderingContext, + PRBool aCheckVis, + PRBool* aIsVisible); + // nsIHTMLReflow NS_IMETHOD Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aMetrics, @@ -659,6 +664,19 @@ public: PRUnichar* aBuffer, PRInt32 aLength, nscoord aWidth); + PRBool IsTextInSelection(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext); + + nsresult GetTextInfoForPainting(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + nsIPresShell** aPresShell, + nsISelectionController** aSelectionController, + PRBool& aDisplayingSelection, + PRBool& aIsPaginated, + PRBool& aIsSelected, + PRInt16& aSelectionValue, + nsILineBreaker** aLineBreaker); + void PaintUnicodeText(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, nsIStyleContext* aStyleContext, @@ -805,6 +823,7 @@ public: nsTextFrame::TextStyle & CurrentStyle(); nscolor CurrentForeGroundColor(); PRBool CurrentBackGroundColor(nscolor &aColor); + PRBool IsBeforeOrAfter(); private: union { PRUnichar *mUniStr; @@ -1042,6 +1061,11 @@ DrawSelectionIterator::CurrentBackGroundColor(nscolor &aColor) return PR_FALSE; } +PRBool +DrawSelectionIterator::IsBeforeOrAfter() +{ + return mCurrentIdx != (PRUint32)mDetails->mStart; +} //END DRAWSELECTIONITERATOR!! @@ -1219,9 +1243,8 @@ nsTextFrame::Paint(nsIPresContext* aPresContext, return NS_OK; } nsIStyleContext* sc = mStyleContext; - const nsStyleDisplay* disp = (const nsStyleDisplay*) - sc->GetStyleData(eStyleStruct_Display); - if (disp->IsVisible()) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && isVisible) { TextStyle ts(aPresContext, aRenderingContext, mStyleContext); if (ts.mSmallCaps || (0 != ts.mWordSpacing) || (0 != ts.mLetterSpacing) || ts.mJustifying) { @@ -1261,6 +1284,7 @@ nsTextFrame::Paint(nsIPresContext* aPresContext, // Use char rendering routine PaintAsciiText(aPresContext, aRenderingContext, sc, ts, 0, 0); } + } } return NS_OK; @@ -1735,6 +1759,194 @@ nsTextFrame::GetContentAndOffsetsForSelection(nsIPresContext *aPresContext, nsIC return NS_OK; } +//--------------------------------------------------------- +nsresult nsTextFrame::GetTextInfoForPainting(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + nsIPresShell** aPresShell, + nsISelectionController** aSelectionController, + PRBool& aDisplayingSelection, + PRBool& aIsPaginated, + PRBool& aIsSelected, + PRInt16& aSelectionValue, + nsILineBreaker** aLineBreaker) +{ + NS_ENSURE_ARG_POINTER(aPresContext); + NS_ENSURE_ARG_POINTER(aPresShell); + NS_ENSURE_ARG_POINTER(aSelectionController); + NS_ENSURE_ARG_POINTER(aLineBreaker); + + //get the presshell + nsresult rv = aPresContext->GetShell(aPresShell); + if (NS_FAILED(rv) || (*aPresShell) == nsnull) + return NS_ERROR_FAILURE; + + //get the selection controller + rv = GetSelectionController(aPresContext, aSelectionController); + if (NS_FAILED(rv) || !(*aSelectionController)) + return NS_ERROR_FAILURE; + + aPresContext->IsPaginated(&aIsPaginated); + PRBool isRenderingOnlySelection; + aPresContext->IsRenderingOnlySelection(&isRenderingOnlySelection); + + (*aSelectionController)->GetDisplaySelection(&aSelectionValue); + //if greater than hidden then we display some kind of selection + aDisplayingSelection = (aSelectionValue > nsISelectionController::SELECTION_HIDDEN) || + (aIsPaginated && isRenderingOnlySelection); + + // Transform text from content into renderable form + // XXX If the text fragment is already Unicode and text text wasn't + // transformed when we formatted it, then there's no need to do all + // this and we should just render the text fragment directly. See + // PaintAsciiText()... + nsCOMPtr doc; + (*aPresShell)->GetDocument(getter_AddRefs(doc)); + if (!doc) + return NS_ERROR_FAILURE; + + doc->GetLineBreaker(aLineBreaker); + + nsFrameState frameState; + GetFrameState(&frameState); + aIsSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + + return NS_OK; +} + +PRBool +nsTextFrame::IsTextInSelection(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext) +{ + nsCOMPtr selCon; + nsCOMPtr shell; + PRBool displaySelection; + PRBool isPaginated; + PRBool isSelected; + PRInt16 selectionValue; + nsCOMPtr lb; + if (NS_FAILED(GetTextInfoForPainting(aPresContext, + aRenderingContext, + getter_AddRefs(shell), + getter_AddRefs(selCon), + displaySelection, + isPaginated, + isSelected, + selectionValue, + getter_AddRefs(lb)))) { + return PR_FALSE; + } + + // Make enough space to transform + nsAutoTextBuffer paintBuffer; + nsAutoIndexBuffer indexBuffer; + if (NS_FAILED(indexBuffer.GrowTo(mContentLength + 1))) { + return PR_FALSE; + } + TextStyle ts(aPresContext, aRenderingContext, mStyleContext); + + // Transform text from content into renderable form + // XXX If the text fragment is already Unicode and text text wasn't + // transformed when we formatted it, then there's no need to do all + // this and we should just render the text fragment directly. See + // PaintAsciiText()... + + nsTextTransformer tx(lb, nsnull, aPresContext); + PRInt32 textLength; + // no need to worry about justification, that's always on the slow path + PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength); + + PRInt32* ip = indexBuffer.mBuffer; + PRUnichar* text = paintBuffer.mBuffer; + + if (0 != textLength) { + + SelectionDetails *details = nsnull; + nsCOMPtr frameSelection; + //get the frameSelection from the selection controller + if (selCon) { + frameSelection = do_QueryInterface(selCon); //this MAY implement + } + nsresult rv = NS_OK; + //if that failed get it from the pres shell + if (!frameSelection) + rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); + + if (NS_SUCCEEDED(rv) && frameSelection){ + nsCOMPtr content; + PRInt32 offset; + PRInt32 length; + + rv = GetContentAndOffsetsForSelection(aPresContext,getter_AddRefs(content),&offset,&length); + if (NS_SUCCEEDED(rv) && content){ + rv = frameSelection->LookUpSelection(content, mContentOffset, + mContentLength , &details, PR_FALSE); + } + } + + //where are the selection points "really" + SelectionDetails *sdptr = details; + while (sdptr){ + sdptr->mStart = ip[sdptr->mStart] - mContentOffset; + sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset; + sdptr = sdptr->mNext; + } + //while we have substrings... + //PRBool drawn = PR_FALSE; + DrawSelectionIterator iter(details,text,(PRUint32)textLength, ts, nsISelectionController::SELECTION_NORMAL); + if (!iter.IsDone() && iter.First()) { + return PR_TRUE; + } + + sdptr = details; + if (details) { + while ((sdptr = details->mNext) != nsnull) { + delete details; + details = sdptr; + } + delete details; + } + } + return PR_FALSE; +} + +NS_IMETHODIMP +nsTextFrame::IsVisibleForPainting(nsIPresContext * aPresContext, + nsIRenderingContext& aRenderingContext, + PRBool aCheckVis, + PRBool* aIsVisible) +{ + if (aCheckVis) { + nsIStyleContext* sc = mStyleContext; + const nsStyleDisplay* disp = (const nsStyleDisplay*)sc->GetStyleData(eStyleStruct_Display); + if (!disp->IsVisible()) { + *aIsVisible = PR_FALSE; + return NS_OK; + } + } + + // Start by assuming we are visible and need to be painted + PRBool isVisible = PR_TRUE; + + PRBool isPaginated; + aPresContext->IsPaginated(&isPaginated); + if (isPaginated) { + PRBool isRendingSelection; + aPresContext->IsRenderingOnlySelection(&isRendingSelection); + if (isRendingSelection) { + // Check the quick way first + PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + if (isSelected) { + isVisible = IsTextInSelection(aPresContext, aRenderingContext); + } else { + isVisible = PR_FALSE; + } + } + } + + *aIsVisible = isVisible; + + return NS_OK; +} void nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, @@ -1743,22 +1955,24 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, TextStyle& aTextStyle, nscoord dx, nscoord dy) { - nsCOMPtr shell; -//get the presshell - nsresult rv = aPresContext->GetShell(getter_AddRefs(shell)); - if (NS_FAILED(rv) || !shell) - return; -//get the selection controller nsCOMPtr selCon; - rv = GetSelectionController(aPresContext, getter_AddRefs(selCon)); - if (NS_FAILED(rv) || !selCon) - return; - + nsCOMPtr shell; + PRBool displaySelection; + PRBool isPaginated; + PRBool isSelected; PRInt16 selectionValue; - selCon->GetDisplaySelection(&selectionValue); -//if greater than hidden then we display some kind of selection - PRBool displaySelection = selectionValue > nsISelectionController::SELECTION_HIDDEN; - + nsCOMPtr lb; + if (NS_FAILED(GetTextInfoForPainting(aPresContext, + aRenderingContext, + getter_AddRefs(shell), + getter_AddRefs(selCon), + displaySelection, + isPaginated, + isSelected, + selectionValue, + getter_AddRefs(lb)))) { + return; + } // Make enough space to transform nsAutoTextBuffer paintBuffer; nsAutoIndexBuffer indexBuffer; @@ -1774,12 +1988,7 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, // transformed when we formatted it, then there's no need to do all // this and we should just render the text fragment directly. See // PaintAsciiText()... - nsCOMPtr doc; - shell->GetDocument(getter_AddRefs(doc)); - if (!doc) - return; - nsCOMPtr lb; - doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(lb, nsnull, aPresContext); PRInt32 textLength; // no need to worry about justification, that's always on the slow path @@ -1788,10 +1997,6 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, PRInt32* ip = indexBuffer.mBuffer; PRUnichar* text = paintBuffer.mBuffer; - nsFrameState frameState; - PRBool isSelected; - GetFrameState(&frameState); - isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; if (0 != textLength) { @@ -1808,12 +2013,13 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, { //we draw according to selection rules SelectionDetails *details = nsnull; nsCOMPtr frameSelection; -//get the frameSelection from the selection controller - if (NS_SUCCEEDED(rv) && selCon) + //get the frameSelection from the selection controller + if (selCon) { frameSelection = do_QueryInterface(selCon); //this MAY implement } -//if that failed get it from the pres shell + //if that failed get it from the pres shell + nsresult rv = NS_OK; if (!frameSelection) rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); if (NS_SUCCEEDED(rv) && frameSelection){ @@ -1853,7 +2059,7 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING { - if (iter.CurrentBackGroundColor(currentBKColor)) + if (iter.CurrentBackGroundColor(currentBKColor) && !isPaginated) {//DRAW RECT HERE!!! aRenderingContext.SetColor(currentBKColor); aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height); @@ -1863,16 +2069,20 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, else newWidth =0; - - aRenderingContext.SetColor(currentFGColor); - aRenderingContext.DrawString(currenttext, currentlength, currentX, dy); + if (isPaginated && !iter.IsBeforeOrAfter()) { + aRenderingContext.SetColor(aTextStyle.mColor->mColor); + aRenderingContext.DrawString(currenttext, currentlength, currentX, dy); + } else if (!isPaginated) { + aRenderingContext.SetColor(currentFGColor); + aRenderingContext.DrawString(currenttext, currentlength, currentX, dy); + } currentX+=newWidth;//increment twips X start iter.Next(); } } - else + else if (!isPaginated) { aRenderingContext.SetColor(aTextStyle.mColor->mColor); aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy); @@ -2298,18 +2508,24 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext, TextStyle& aTextStyle, nscoord dx, nscoord dy) { - nsCOMPtr shell; - nsresult rv = aPresContext->GetShell(getter_AddRefs(shell)); - if (NS_FAILED(rv) || !shell) - return; nsCOMPtr selCon; - rv = GetSelectionController(aPresContext, getter_AddRefs(selCon)); - if (NS_FAILED(rv) || !selCon) - return; - + nsCOMPtr shell; + PRBool displaySelection; + PRBool isPaginated; + PRBool isSelected; PRInt16 selectionValue; - selCon->GetDisplaySelection(&selectionValue); - PRBool displaySelection = selectionValue > nsISelectionController::SELECTION_HIDDEN; + nsCOMPtr lb; + if (NS_FAILED(GetTextInfoForPainting(aPresContext, + aRenderingContext, + getter_AddRefs(shell), + getter_AddRefs(selCon), + displaySelection, + isPaginated, + isSelected, + selectionValue, + getter_AddRefs(lb)))) { + return; + } // Make enough space to transform @@ -2321,13 +2537,6 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext, nscoord width = mRect.width; PRInt32 textLength; - // Transform text from content into renderable form - nsCOMPtr doc; - shell->GetDocument(getter_AddRefs(doc)); - if (!doc) - return; - nsCOMPtr lb; - doc->GetLineBreaker(getter_AddRefs(lb)); nsTextTransformer tx(lb, nsnull, aPresContext); PRInt32 numSpaces; @@ -2337,10 +2546,7 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext, PRInt32* ip = indexBuffer.mBuffer; PRUnichar* text = paintBuffer.mBuffer; - nsFrameState frameState; - PRBool isSelected; - GetFrameState(&frameState); - isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + if (0 != textLength) { ComputeExtraJustificationSpacing(aRenderingContext, aTextStyle, text, textLength, numSpaces); if (!displaySelection || !isSelected) { @@ -2355,6 +2561,7 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext, SelectionDetails *details = nsnull; nsCOMPtr frameSelection; //get the frame selection + nsresult rv = NS_OK; frameSelection = do_QueryInterface(selCon); //this MAY implement if (!frameSelection)//if that failed get it from the presshell rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); @@ -2405,16 +2612,23 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext, else newWidth =0; - aRenderingContext.SetColor(currentFGColor); - RenderString(aRenderingContext,aStyleContext, aTextStyle, currenttext, - currentlength, currentX, dy, width, details); - //increment twips X start but remember to get ready for next draw by reducing current x by letter spacing amount + if (isPaginated && !iter.IsBeforeOrAfter()) { + aRenderingContext.SetColor(aTextStyle.mColor->mColor); + RenderString(aRenderingContext,aStyleContext, aTextStyle, currenttext, + currentlength, currentX, dy, width, details); + } else if (!isPaginated) { + aRenderingContext.SetColor(currentFGColor); + RenderString(aRenderingContext,aStyleContext, aTextStyle, currenttext, + currentlength, currentX, dy, width, details); + } + + //increment twips X start but remember to get ready for next draw by reducing current x by letter spacing amount currentX+=newWidth;// + aTextStyle.mLetterSpacing; iter.Next(); } } - else + else if (!isPaginated) { aRenderingContext.SetColor(aTextStyle.mColor->mColor); RenderString(aRenderingContext,aStyleContext, aTextStyle, text, @@ -2440,21 +2654,25 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext, nscoord dx, nscoord dy) { NS_PRECONDITION(0 == (TEXT_HAS_MULTIBYTE & mState), "text is multi-byte"); - nsCOMPtr shell; - nsresult rv = aPresContext->GetShell(getter_AddRefs(shell)); - if (NS_FAILED(rv) || !shell) - return; + nsCOMPtr selCon; - rv = GetSelectionController(aPresContext, getter_AddRefs(selCon)); - if (NS_FAILED(rv) || !selCon) - return; - + nsCOMPtr shell; + PRBool displaySelection; + PRBool isPaginated; + PRBool isSelected; PRInt16 selectionValue; - PRBool isSelected; - selCon->GetDisplaySelection(&selectionValue); - PRBool displaySelection = selectionValue > nsISelectionController::SELECTION_HIDDEN; - - isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + nsCOMPtr lb; + if (NS_FAILED(GetTextInfoForPainting(aPresContext, + aRenderingContext, + getter_AddRefs(shell), + getter_AddRefs(selCon), + displaySelection, + isPaginated, + isSelected, + selectionValue, + getter_AddRefs(lb)))) { + return; + } // Get the text fragment nsCOMPtr tc = do_QueryInterface(mContent); @@ -2475,13 +2693,6 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext, } } - // Construct a text transformer - nsCOMPtr doc; - shell->GetDocument(getter_AddRefs(doc)); - if (!doc) - return; - nsCOMPtr lb; - doc->GetLineBreaker(getter_AddRefs(lb)); nsTextTransformer tx(lb, nsnull, aPresContext); // See if we need to transform the text. If the text fragment is ascii and @@ -2557,6 +2768,7 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext, nsCOMPtr frameSelection; //get the frame selection frameSelection = do_QueryInterface(selCon); //this MAY implement + nsresult rv = NS_OK; if (!frameSelection)//if that failed get it from the presshell rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); if (NS_SUCCEEDED(rv) && frameSelection){ @@ -2593,7 +2805,7 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext, if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING { - if (iter.CurrentBackGroundColor(currentBKColor)) + if (iter.CurrentBackGroundColor(currentBKColor) && !isPaginated) {//DRAW RECT HERE!!! aRenderingContext.SetColor(currentBKColor); aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height); @@ -2602,16 +2814,21 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext, } else newWidth =0; - - aRenderingContext.SetColor(currentFGColor); - aRenderingContext.DrawString(currenttext, currentlength, currentX, dy); + + if (isPaginated && !iter.IsBeforeOrAfter()) { + aRenderingContext.SetColor(aTextStyle.mColor->mColor); + aRenderingContext.DrawString(currenttext, currentlength, currentX, dy); + } else if (!isPaginated) { + aRenderingContext.SetColor(currentFGColor); + aRenderingContext.DrawString(currenttext, currentlength, currentX, dy); + } currentX+=newWidth;//increment twips X start iter.Next(); } } - else + else if (!isPaginated) { aRenderingContext.SetColor(aTextStyle.mColor->mColor); aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy); @@ -4757,7 +4974,11 @@ nsTextFrame::List(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent) cons // Output the rect and state fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height); if (0 != mState) { - fprintf(out, " [state=%08x]", mState); + if (mState & NS_FRAME_SELECTED_CONTENT) { + fprintf(out, " [state=%08x] SELECTED", mState); + } else { + fprintf(out, " [state=%08x]", mState); + } } fprintf(out, " sc=%p<\n", mStyleContext); diff --git a/mozilla/layout/html/base/src/MANIFEST_PROPERTIES b/mozilla/layout/html/base/src/MANIFEST_PROPERTIES new file mode 100644 index 00000000000..81b63285283 --- /dev/null +++ b/mozilla/layout/html/base/src/MANIFEST_PROPERTIES @@ -0,0 +1 @@ +printing.properties diff --git a/mozilla/layout/html/base/src/Makefile.in b/mozilla/layout/html/base/src/Makefile.in index 7a37c29dc1e..26ee6cf88b7 100644 --- a/mozilla/layout/html/base/src/Makefile.in +++ b/mozilla/layout/html/base/src/Makefile.in @@ -106,6 +106,7 @@ INCLUDES += \ -I$(srcdir)/../../../xul/base/src \ -I$(srcdir)/../../../xul/content/src \ -I$(srcdir)/../../style/src \ + -I$(srcdir)/../../forms/src \ -I$(srcdir)/../../../base/src \ -I$(srcdir) \ $(NULL) diff --git a/mozilla/layout/html/base/src/jar.mn b/mozilla/layout/html/base/src/jar.mn new file mode 100644 index 00000000000..21722ef17cf --- /dev/null +++ b/mozilla/layout/html/base/src/jar.mn @@ -0,0 +1,3 @@ +en-US.jar: + locale/en-US/communicator/printing.properties + diff --git a/mozilla/layout/html/base/src/makefile.win b/mozilla/layout/html/base/src/makefile.win index 4df4bbbd6d9..d5616950b7c 100644 --- a/mozilla/layout/html/base/src/makefile.win +++ b/mozilla/layout/html/base/src/makefile.win @@ -123,6 +123,7 @@ CPP_OBJS= \ LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\js \ -I$(PUBLIC)\dom -I$(PUBLIC)\netlib -I$(PUBLIC)\unicharutil \ -I..\..\style\src \ + -I..\..\forms\src \ -I..\..\..\base\src -I$(PUBLIC)\plugin -I$(PUBLIC)\java \ -I$(PUBLIC)\pref \ -I$(PUBLIC)\lwbrk \ diff --git a/mozilla/layout/html/base/src/nsBlockFrame.cpp b/mozilla/layout/html/base/src/nsBlockFrame.cpp index 6ba65c8bb8a..669e6e8158c 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.cpp +++ b/mozilla/layout/html/base/src/nsBlockFrame.cpp @@ -6245,6 +6245,19 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, } #endif + // Check to see if we are an absolutely positioned block (div) + // then then check to see if we need to paint. + const nsStylePosition* postionStyle = (const nsStylePosition*) + mStyleContext->GetStyleData(eStyleStruct_Position); + if (NS_STYLE_POSITION_RELATIVE == postionStyle->mPosition || + NS_STYLE_POSITION_ABSOLUTE == postionStyle->mPosition || + NS_STYLE_POSITION_FIXED == postionStyle->mPosition) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } + } + const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.cpp b/mozilla/layout/html/base/src/nsBlockReflowState.cpp index 6ba65c8bb8a..669e6e8158c 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.cpp +++ b/mozilla/layout/html/base/src/nsBlockReflowState.cpp @@ -6245,6 +6245,19 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, } #endif + // Check to see if we are an absolutely positioned block (div) + // then then check to see if we need to paint. + const nsStylePosition* postionStyle = (const nsStylePosition*) + mStyleContext->GetStyleData(eStyleStruct_Position); + if (NS_STYLE_POSITION_RELATIVE == postionStyle->mPosition || + NS_STYLE_POSITION_ABSOLUTE == postionStyle->mPosition || + NS_STYLE_POSITION_FIXED == postionStyle->mPosition) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } + } + const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); diff --git a/mozilla/layout/html/base/src/nsBlockReflowState.h b/mozilla/layout/html/base/src/nsBlockReflowState.h index 6ba65c8bb8a..669e6e8158c 100644 --- a/mozilla/layout/html/base/src/nsBlockReflowState.h +++ b/mozilla/layout/html/base/src/nsBlockReflowState.h @@ -6245,6 +6245,19 @@ nsBlockFrame::Paint(nsIPresContext* aPresContext, } #endif + // Check to see if we are an absolutely positioned block (div) + // then then check to see if we need to paint. + const nsStylePosition* postionStyle = (const nsStylePosition*) + mStyleContext->GetStyleData(eStyleStruct_Position); + if (NS_STYLE_POSITION_RELATIVE == postionStyle->mPosition || + NS_STYLE_POSITION_ABSOLUTE == postionStyle->mPosition || + NS_STYLE_POSITION_FIXED == postionStyle->mPosition) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } + } + const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); diff --git a/mozilla/layout/html/base/src/nsBulletFrame.cpp b/mozilla/layout/html/base/src/nsBulletFrame.cpp index 6f8b48fa99e..099372f554e 100644 --- a/mozilla/layout/html/base/src/nsBulletFrame.cpp +++ b/mozilla/layout/html/base/src/nsBulletFrame.cpp @@ -107,6 +107,7 @@ nsBulletFrame::GetFrameType(nsIAtom** aType) const return NS_OK; } +#include "nsIDOMNode.h" NS_IMETHODIMP nsBulletFrame::Paint(nsIPresContext* aCX, nsIRenderingContext& aRenderingContext, @@ -117,10 +118,8 @@ nsBulletFrame::Paint(nsIPresContext* aCX, return NS_OK; } - const nsStyleDisplay* disp = - (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); - - if (disp->IsVisible()) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aCX, aRenderingContext, PR_TRUE, &isVisible)) && isVisible) { const nsStyleList* myList = (const nsStyleList*)mStyleContext->GetStyleData(eStyleStruct_List); PRUint8 listStyleType = myList->mListStyleType; diff --git a/mozilla/layout/html/base/src/nsFrame.cpp b/mozilla/layout/html/base/src/nsFrame.cpp index 96a79aba6ba..294d7003a5e 100644 --- a/mozilla/layout/html/base/src/nsFrame.cpp +++ b/mozilla/layout/html/base/src/nsFrame.cpp @@ -2308,6 +2308,58 @@ nsFrame::ParentDisablesSelection() const return PR_FALSE; } +NS_IMETHODIMP +nsFrame::IsVisibleForPainting(nsIPresContext * aPresContext, + nsIRenderingContext& aRenderingContext, + PRBool aCheckVis, + PRBool* aIsVisible) +{ + // first check to see if we are visible + if (aCheckVis) { + nsIStyleContext* sc = mStyleContext; + const nsStyleDisplay* disp = (const nsStyleDisplay*)sc->GetStyleData(eStyleStruct_Display); + if (!disp->IsVisible()) { + *aIsVisible = PR_FALSE; + return NS_OK; + } + } + + // Start by assuming we are visible and need to be painted + PRBool isVisible = PR_TRUE; + + // start by checking to see if we are paginated which probably means + // we are in print preview or printing + PRBool isPaginated; + aPresContext->IsPaginated(&isPaginated); + if (isPaginated) { + // now see if we are rendering selection only + PRBool isRendingSelection; + aPresContext->IsRenderingOnlySelection(&isRendingSelection); + if (isRendingSelection) { + // Check the quick way first (typically only leaf nodes) + PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + // if we aren't selected in the mState, + // we could be a container so check to see if we are in the selection range + // this is a expensive + if (!isSelected) { + nsCOMPtr shell; + aPresContext->GetShell(getter_AddRefs(shell)); + nsCOMPtr selcon(do_QueryInterface(shell)); + if (selcon) { + nsCOMPtr selection; + selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection)); + nsCOMPtr node(do_QueryInterface(mContent)); + selection->ContainsNode(node, PR_TRUE, &isVisible); + } else { + isVisible = PR_FALSE; + } + } + } + } + + *aIsVisible = isVisible; + return NS_OK; +} NS_IMETHODIMP diff --git a/mozilla/layout/html/base/src/nsFrame.h b/mozilla/layout/html/base/src/nsFrame.h index b0ce1c522b2..b2b26aa4c0c 100644 --- a/mozilla/layout/html/base/src/nsFrame.h +++ b/mozilla/layout/html/base/src/nsFrame.h @@ -278,6 +278,12 @@ public: nsIFrame** aProviderFrame, nsContextProviderRelationship& aRelationship); + // Check Style Visibility and mState for Selection (when printing) + NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext, + nsIRenderingContext& aRenderingContext, + PRBool aCheckVis, + PRBool* aIsVisible); + // nsIHTMLReflow NS_IMETHOD WillReflow(nsIPresContext* aPresContext); NS_IMETHOD Reflow(nsIPresContext* aPresContext, diff --git a/mozilla/layout/html/base/src/nsHTMLFrame.cpp b/mozilla/layout/html/base/src/nsHTMLFrame.cpp index 5332867867f..8ada64acd0c 100644 --- a/mozilla/layout/html/base/src/nsHTMLFrame.cpp +++ b/mozilla/layout/html/base/src/nsHTMLFrame.cpp @@ -20,7 +20,7 @@ * Contributor(s): */ #include "nsHTMLParts.h" -#include "nsContainerFrame.h" +#include "nsHTMLContainerFrame.h" #include "nsCSSRendering.h" #include "nsIDocument.h" #include "nsIReflowCommand.h" diff --git a/mozilla/layout/html/base/src/nsImageFrame.cpp b/mozilla/layout/html/base/src/nsImageFrame.cpp index aa58537a089..9e2b7b990ac 100644 --- a/mozilla/layout/html/base/src/nsImageFrame.cpp +++ b/mozilla/layout/html/base/src/nsImageFrame.cpp @@ -590,9 +590,9 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - const nsStyleDisplay* disp = (const nsStyleDisplay*) - mStyleContext->GetStyleData(eStyleStruct_Display); - if (disp->IsVisible() && mRect.width && mRect.height) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && + isVisible && mRect.width && mRect.height) { // First paint background and borders nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); diff --git a/mozilla/layout/html/base/src/nsLeafFrame.cpp b/mozilla/layout/html/base/src/nsLeafFrame.cpp index e6b21197498..7dd1cb5d20e 100644 --- a/mozilla/layout/html/base/src/nsLeafFrame.cpp +++ b/mozilla/layout/html/base/src/nsLeafFrame.cpp @@ -40,6 +40,12 @@ nsLeafFrame::Paint(nsIPresContext* aPresContext, nsFramePaintLayer aWhichLayer) { if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && + !isVisible) {// just checks selection painting + return NS_OK; // not visibility + } + const nsStyleDisplay* disp = (const nsStyleDisplay*) mStyleContext->GetStyleData(eStyleStruct_Display); if (disp->IsVisibleOrCollapsed()) { diff --git a/mozilla/layout/html/base/src/nsPageFrame.cpp b/mozilla/layout/html/base/src/nsPageFrame.cpp index 22f87955a3f..1bab5ea65c2 100644 --- a/mozilla/layout/html/base/src/nsPageFrame.cpp +++ b/mozilla/layout/html/base/src/nsPageFrame.cpp @@ -31,6 +31,27 @@ #include "nsLayoutAtoms.h" #include "nsIStyleSet.h" #include "nsIPresShell.h" +#include "nsIDeviceContext.h" + +// for page number localization formatting +#include "nsTextFormatter.h" + +// DateTime Includes +#include "nsDateTimeFormatCID.h" +#include "nsIDateTimeFormat.h" +#include "nsIServiceManager.h" +#include "nsILocale.h" +#include "nsLocaleCID.h" +#include "nsILocaleService.h" + +static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID); +static NS_DEFINE_CID(kLocaleServiceCID, NS_LOCALESERVICE_CID); + +// Temporary +#include "nsIFontMetrics.h" + +// tstaic data members +PRUnichar * nsPageFrame::mPageNumFormat = nsnull; nsresult NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) @@ -47,10 +68,22 @@ NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } -nsPageFrame::nsPageFrame() +nsPageFrame::nsPageFrame() : + mHeadFootFont(nsnull) { } +nsPageFrame::~nsPageFrame() +{ + if (mHeadFootFont) + delete mHeadFootFont; + + if (mPageNumFormat) { + nsMemory::Free(mPageNumFormat); + mPageNumFormat = nsnull; + } +} + NS_METHOD nsPageFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, @@ -173,3 +206,253 @@ nsPageFrame::IsPercentageBase(PRBool& aBase) const aBase = PR_TRUE; return NS_OK; } + +//------------------------------------------------------------------------------ +nscoord nsPageFrame::GetXPosition(nsIRenderingContext& aRenderingContext, + const nsRect& aRect, + PRInt32 aJust, + const nsString& aStr) +{ + PRInt32 width; + aRenderingContext.GetWidth(aStr, width); + + nscoord x = aRect.x; + switch (aJust) { + case NS_PRINT_JUSTIFY_LEFT: + // do nothing, already set + break; + + case NS_PRINT_JUSTIFY_CENTER: + x += (aRect.width - width) / 2; + break; + + case NS_PRINT_JUSTIFY_RIGHT: + x += aRect.width - width; + break; + } // switch + + return x; +} + +//------------------------------------------------------------------------------ +// Draw a Header or footer text lrft,right or center justified +// @parm aRenderingContext - rendering content ot draw into +// @parm aHeaderFooter - indicates whether it is a header or footer +// @parm aJust - indicates the justification of the text +// @parm aStr - The string to be drawn +// @parm aRect - the rect of the page +// @parm aHeight - the height of the text +// @parm aUseHalfThePage - indicates whether the text should limited to the width +// of the entire page or just half the page +void +nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext, + nsIFrame * aFrame, + nsHeaderFooterEnum aHeaderFooter, + PRInt32 aJust, + const nsString& aStr, + const nsRect& aRect, + nscoord aHeight, + PRBool aUseHalfThePage) +{ + // first make sure we have a vaild string and that the height of the + // text will fit in the margin + if (aStr.Length() > 0 && + ((aHeaderFooter == eHeader && aHeight < mMargin.top) || + (aHeaderFooter == eFooter && aHeight < mMargin.bottom))) { + // measure the width of the text + nsString str = aStr; + PRInt32 width; + aRenderingContext.GetWidth(str, width); + PRBool addEllipse = PR_FALSE; + nscoord halfWidth = aRect.width; + if (aUseHalfThePage) { + halfWidth /= 2; + } + // trim the text and add the elipses if it won't fit + while (width >= halfWidth && str.Length() > 1) { + str.SetLength(str.Length()-1); + aRenderingContext.GetWidth(str, width); + addEllipse = PR_TRUE; + } + if (addEllipse && str.Length() > 3) { + str.SetLength(str.Length()-3); + str.AppendWithConversion("..."); + aRenderingContext.GetWidth(str, width); + } + + // cacl the x and y positions of the text + nsRect rect(aRect); + nscoord x = GetXPosition(aRenderingContext, rect, aJust, str); + nscoord y; + if (aHeaderFooter == eHeader) { + nscoord offset = ((mMargin.top - aHeight) / 2); + y = rect.y - offset - aHeight; + rect.Inflate(0, offset + aHeight); + } else { + nscoord offset = ((mMargin.bottom - aHeight) / 2); + y = rect.y + rect.height + offset; + rect.height += offset + aHeight; + } + + // set up new clip and draw the text + PRBool clipEmpty; + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(rect, nsClipCombine_kReplace, clipEmpty); + aRenderingContext.DrawString(str, x, y); + aRenderingContext.PopState(clipEmpty); + } +} + +//------------------------------------------------------------------------------ +NS_IMETHODIMP +nsPageFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + nsresult rv = nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + + if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { + // get the current margin + mPrintOptions->GetMargin(mMargin); + + nsRect rect(0,0,mRect.width, mRect.height); + +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + // XXX Paint a one-pixel border around the page so it's easy to see where + // each page begins and ends when we're + float p2t; + aPresContext->GetPixelsToTwips(&p2t); + rect.Deflate(NSToCoordRound(p2t), NSToCoordRound(p2t)); + aRenderingContext.SetColor(NS_RGB(0, 0, 0)); + //aRenderingContext.DrawRect(rect); + rect.Inflate(NSToCoordRound(p2t), NSToCoordRound(p2t)); + printf("SPSF::PaintChild -> Painting Frame %p Page No: %d\n", this, mPageNum); +#endif + // use the whole page + rect.width += mMargin.left + mMargin.right; + rect.x -= mMargin.left; + + aRenderingContext.SetFont(*mHeadFootFont); + aRenderingContext.SetColor(NS_RGB(0,0,0)); + + // Get the FontMetrics to determine width.height of strings + nsCOMPtr deviceContext; + aPresContext->GetDeviceContext(getter_AddRefs(deviceContext)); + NS_ASSERTION(deviceContext, "Couldn't get the device context"); + nsCOMPtr fontMet; + deviceContext->GetMetricsFor(*mHeadFootFont, *getter_AddRefs(fontMet)); + nscoord visibleHeight = 0; + if (fontMet) { + fontMet->GetHeight(visibleHeight); + } + + // get the print options bits so we can figure out all the + // the extra pieces of text that need to be drawn + PRInt32 printOptBits; + mPrintOptions->GetPrintOptionsBits(&printOptBits); + + // print page numbers + if (printOptBits & NS_PRINT_OPTIONS_PRINT_PAGE_NUMS && mPageNumFormat != nsnull) { + PRInt32 justify = NS_PRINT_JUSTIFY_LEFT; + mPrintOptions->GetPageNumJust(&justify); + + PRUnichar * valStr; + // print page number totals "x of x" + if (printOptBits & NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL) { + valStr = nsTextFormatter::smprintf(mPageNumFormat, mPageNum, mTotNumPages); + } else { + valStr = nsTextFormatter::smprintf(mPageNumFormat, mPageNum); + } + nsAutoString pageNoStr(valStr); + nsMemory::Free(valStr); + DrawHeaderFooter(aRenderingContext, this, eFooter, justify, pageNoStr, rect, visibleHeight); + } + + // print localized date + if (printOptBits & NS_PRINT_OPTIONS_PRINT_DATE_PRINTED) { + // Get Locale for Formating DateTime + nsCOMPtr locale; + NS_WITH_SERVICE(nsILocaleService, localeSvc, kLocaleServiceCID, &rv); + if (NS_SUCCEEDED(rv)) { + + rv = localeSvc->GetApplicationLocale(getter_AddRefs(locale)); + if (NS_SUCCEEDED(rv) && locale) { + nsCOMPtr dateTime; + rv = nsComponentManager::CreateInstance(kDateTimeFormatCID, + NULL, + NS_GET_IID(nsIDateTimeFormat), + (void**) getter_AddRefs(dateTime)); + + if (NS_SUCCEEDED(rv)) { + nsAutoString dateString; + time_t ltime; + time( <ime ); + rv = dateTime->FormatTMTime(locale, kDateFormatShort, kTimeFormatNoSeconds, localtime( <ime ), dateString); + if (NS_SUCCEEDED(rv)) { + DrawHeaderFooter(aRenderingContext, this, eFooter, NS_PRINT_JUSTIFY_RIGHT, dateString, rect, visibleHeight); + } + } + } + } + } + + + PRBool usingHalfThePage = (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_TITLE) && (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_LOCATION); + + // print document title + PRUnichar * title; + mPrintOptions->GetTitle(&title); // creates memory + if (title != nsnull && (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_TITLE)) { + DrawHeaderFooter(aRenderingContext, this, eHeader, NS_PRINT_JUSTIFY_LEFT, nsAutoString(title), rect, visibleHeight, usingHalfThePage); + nsMemory::Free(title); + } + + // print document URL + PRUnichar * url; + mPrintOptions->GetURL(&url); + if (title != url && (printOptBits & NS_PRINT_OPTIONS_PRINT_DOC_LOCATION)) { + DrawHeaderFooter(aRenderingContext, this, eHeader, NS_PRINT_JUSTIFY_RIGHT, nsAutoString(url), rect, visibleHeight, usingHalfThePage); + nsMemory::Free(url); + } + + } + + return rv; +} + +//------------------------------------------------------------------------------ +void +nsPageFrame::SetPrintOptions(nsIPrintOptions * aPrintOptions) +{ + NS_ASSERTION(aPrintOptions != nsnull, "Print Options can not be null!"); + + mPrintOptions = aPrintOptions; + // create a default font + mHeadFootFont = new nsFont("serif", NS_FONT_STYLE_NORMAL,NS_FONT_VARIANT_NORMAL, + NS_FONT_WEIGHT_NORMAL,0,NSIntPointsToTwips(10)); + // now get the default font form the print options + mPrintOptions->GetDefaultFont(*mHeadFootFont); +} + +//------------------------------------------------------------------------------ +void +nsPageFrame::SetPageNumInfo(PRInt32 aPageNumber, PRInt32 aTotalPages) +{ + mPageNum = aPageNumber; + mTotNumPages = aTotalPages; +} + + +//------------------------------------------------------------------------------ +void +nsPageFrame::SetPageNumberFormat(PRUnichar * aFormatStr) +{ + NS_ASSERTION(aFormatStr != nsnull, "Format string cannot be null!"); + + if (mPageNumFormat != nsnull) { + nsMemory::Free(mPageNumFormat); + } + mPageNumFormat = aFormatStr; +} + diff --git a/mozilla/layout/html/base/src/nsPageFrame.h b/mozilla/layout/html/base/src/nsPageFrame.h index 1403d842bd5..59d3bff2d24 100644 --- a/mozilla/layout/html/base/src/nsPageFrame.h +++ b/mozilla/layout/html/base/src/nsPageFrame.h @@ -22,17 +22,25 @@ #ifndef nsPageFrame_h___ #define nsPageFrame_h___ -#include "nsHTMLContainerFrame.h" +#include "nsContainerFrame.h" +#include "nsIPrintOptions.h" // Page frame class used by the simple page sequence frame class nsPageFrame : public nsContainerFrame { public: friend nsresult NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aResult); + // nsIFrame NS_IMETHOD Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aMaxSize, nsReflowStatus& aStatus); + + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + NS_IMETHOD IsPercentageBase(PRBool& aBase) const; /** @@ -47,8 +55,51 @@ public: NS_IMETHOD GetFrameName(nsString& aResult) const; #endif + ////////////////// + // For Printing + ////////////////// + + // Set the print options object into the page for printing + virtual void SetPrintOptions(nsIPrintOptions * aPrintOptions); + + // Tell the page which page number it is out of how many + virtual void SetPageNumInfo(PRInt32 aPageNumber, PRInt32 aTotalPages); + + // This is class is now responsible for freeing the memory + static void SetPageNumberFormat(PRUnichar * aFormatStr); + protected: nsPageFrame(); + virtual ~nsPageFrame(); + + typedef enum { + eHeader, + eFooter + } nsHeaderFooterEnum; + + nscoord GetXPosition(nsIRenderingContext& aRenderingContext, + const nsRect& aRect, + PRInt32 aJust, + const nsString& aStr); + + void DrawHeaderFooter(nsIRenderingContext& aRenderingContext, + nsIFrame * aFrame, + nsHeaderFooterEnum aHeaderFooter, + PRInt32 aJust, + const nsString& sStr, + const nsRect& aRect, + nscoord aHeight, + PRBool aUseHalfThePage = PR_TRUE); + + + nsCOMPtr mPrintOptions; + PRInt32 mPageNum; + PRInt32 mTotNumPages; + nsMargin mMargin; + nsFont * mHeadFootFont; + + static PRUnichar * mPageNumFormat; + }; #endif /* nsPageFrame_h___ */ diff --git a/mozilla/layout/html/base/src/nsSimplePageSequence.cpp b/mozilla/layout/html/base/src/nsSimplePageSequence.cpp index e6d9bbfc664..b7fc28298d3 100644 --- a/mozilla/layout/html/base/src/nsSimplePageSequence.cpp +++ b/mozilla/layout/html/base/src/nsSimplePageSequence.cpp @@ -31,6 +31,24 @@ #include "nsIViewManager.h" #include "nsIPresShell.h" #include "nsIStyleSet.h" +#include "nsIFontMetrics.h" +#include "nsIPrintOptions.h" +#include "nsPageFrame.h" + +#define OFFSET_NOT_SET -1 + +// This is for localization of the "x of n" pages string +// this class contains a helper method we need to get +// a string from a string bundle +#include "nsFormControlHelper.h" +#define PRINTING_PROPERTIES "chrome://communicator/locale/printing.properties" + +// Print Options +#include "nsIPrintOptions.h" +#include "nsGfxCIID.h" +#include "nsIServiceManager.h" +static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID); +// nsresult NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) @@ -47,7 +65,28 @@ NS_NewSimplePageSequenceFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) return NS_OK; } -nsSimplePageSequenceFrame::nsSimplePageSequenceFrame() +nsSimplePageSequenceFrame::nsSimplePageSequenceFrame() : + mIsPrintingSelection(PR_FALSE) +{ + mStartOffset = OFFSET_NOT_SET; + mEndOffset = OFFSET_NOT_SET; + + nscoord halfInch = NS_INCHES_TO_TWIPS(0.5); + mMargin.SizeTo(halfInch, halfInch, halfInch, halfInch); + + // XXX this code and the object data member "mIsPrintingSelection" is only needed + // for the hack for printing selection where we make the page the max size + nsresult rv; + NS_WITH_SERVICE(nsIPrintOptions, printService, kPrintOptionsCID, &rv); + if (NS_SUCCEEDED(rv) && printService) { + PRInt32 printType; + printService->GetPrintRange(&printType); + mIsPrintingSelection = ePrintRange_Selection == nsPrintRange(printType); + } + +} + +nsSimplePageSequenceFrame::~nsSimplePageSequenceFrame() { } @@ -67,9 +106,6 @@ nsSimplePageSequenceFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr //---------------------------------------------------------------------- -// XXX Hack -#define PAGE_SPACING_TWIPS 100 - // Creates a continuing page frame nsresult nsSimplePageSequenceFrame::CreateContinuingPageFrame(nsIPresContext* aPresContext, @@ -110,12 +146,10 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext* aPresConte aReflowState.reflowCommand->GetNext(nextFrame); // Compute the y-offset of this page - for (nsIFrame* f = mFrames.FirstChild(); f != nextFrame; - f->GetNextSibling(&f)) { + for (nsIFrame* f = mFrames.FirstChild(); f != nextFrame; f->GetNextSibling(&f)) { nsSize size; - f->GetSize(size); - aY += size.height + PAGE_SPACING_TWIPS; + aY += size.height + mMargin.top + mMargin.bottom; } // Reflow the page @@ -131,7 +165,7 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext* aPresConte // Place and size the page. If the page is narrower than our max width, then // center it horizontally FinishReflowChild(nextFrame, aPresContext, kidSize, aX, aY, 0); - aY += kidSize.height + PAGE_SPACING_TWIPS; + aY += kidSize.height + mMargin.top + mMargin.bottom; // Check if the page is complete... nsIFrame* kidNextInFlow; @@ -174,7 +208,7 @@ nsSimplePageSequenceFrame::IncrementalReflow(nsIPresContext* aPresConte aY += childSize.height; // Leave a slight gap between the pages - aY += PAGE_SPACING_TWIPS; + aY += mMargin.top + mMargin.bottom; // Is the page complete? kidFrame->GetNextInFlow(&kidNextInFlow); @@ -216,15 +250,21 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, nsSize pageSize; aPresContext->GetPageWidth(&pageSize.width); aPresContext->GetPageHeight(&pageSize.height); - PRInt32 extra = aReflowState.availableWidth - 2 * PAGE_SPACING_TWIPS - pageSize.width; - nscoord x = PAGE_SPACING_TWIPS; - if (extra > 0) { - x += extra / 2; + // XXX - Hack Alert + // OK, so ther eis a selection, we will print the entire selection + // on one page and then crop the page. + // This means you can never print any selection that is longer than one page + // put it keeps it from page breaking in the middle of your print of the selection + // (see also nsDocumentViewer.cpp) + if (mIsPrintingSelection) { + pageSize.height = 0x0FFFFFFF; } + nscoord x = mMargin.left; + // Running y-offset for each page - nscoord y = PAGE_SPACING_TWIPS; + nscoord y = mMargin.top; // See if it's an incremental reflow command if (eReflowReason_Incremental == aReflowState.reason) { @@ -240,6 +280,10 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame, pageSize, reflowReason); nsReflowStatus status; + kidReflowState.availableWidth = pageSize.width - mMargin.left - mMargin.right; + kidReflowState.availableHeight = pageSize.height - mMargin.top - mMargin.bottom; + kidReflowState.mComputedWidth = kidReflowState.availableWidth; + //kidReflowState.mComputedHeight = kidReflowState.availableHeight; // Place and size the page. If the page is narrower than our // max width then center it horizontally @@ -248,8 +292,16 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, FinishReflowChild(kidFrame, aPresContext, kidSize, x, y, 0); y += kidSize.height; + nsIView* view; + kidFrame->GetView(aPresContext, &view); + NS_ASSERTION(nsnull != view, "no page view"); + nsRect rect; + kidFrame->GetRect(rect); + nsRect viewRect; + view->GetBounds(viewRect); + // Leave a slight gap between the pages - y += PAGE_SPACING_TWIPS; + y += mMargin.top + mMargin.bottom; // Is the page complete? nsIFrame* kidNextInFlow; @@ -274,9 +326,9 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, } // Return our desired size - aDesiredSize.height = y; - aDesiredSize.width = 2*PAGE_SPACING_TWIPS + pageSize.width; - aDesiredSize.ascent = aDesiredSize.height; + aDesiredSize.height = y; + aDesiredSize.width = pageSize.width; + aDesiredSize.ascent = aDesiredSize.height; aDesiredSize.descent = 0; NS_FRAME_TRACE_REFLOW_OUT("nsSimplePageSequeceFrame::Reflow", aStatus); @@ -293,53 +345,6 @@ nsSimplePageSequenceFrame::GetFrameName(nsString& aResult) const } #endif -NS_IMETHODIMP -nsSimplePageSequenceFrame::Paint(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer) -{ - if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { - // Paint a white background - aRenderingContext.SetColor(NS_RGB(255,255,255)); - aRenderingContext.FillRect(aDirtyRect); - // XXX Crop marks or hash marks would be nice. Use style info... - } - - return nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, - aWhichLayer); -} - -void -nsSimplePageSequenceFrame::PaintChild(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsIFrame* aFrame, - nsFramePaintLayer aWhichLayer) -{ - // Let the page paint - nsContainerFrame::PaintChild(aPresContext, aRenderingContext, - aDirtyRect, aFrame, aWhichLayer); - - if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { - // XXX Paint a one-pixel border around the page so it's easy to see where - // each page begins and ends when we're in print preview mode - nsRect pageBounds; - float p2t; - aPresContext->GetPixelsToTwips(&p2t); - - aRenderingContext.SetColor(NS_RGB(0, 0, 0)); - aFrame->GetRect(pageBounds); - pageBounds.Inflate(NSToCoordRound(p2t), NSToCoordRound(p2t)); - - // this paints a rectangle around the for the printer output, - // which sometimes appears, other times - // goes away. I have to look into this further or ask troy.. - // I took it out for the time being to fix some bugs -- dwc - //aRenderingContext.DrawRect(pageBounds); - } -} - //---------------------------------------------------------------------- // Helper function that sends the progress notification. Returns PR_TRUE @@ -361,15 +366,37 @@ SendStatusNotification(nsIPrintStatusCallback* aStatusCallback, NS_IMETHODIMP nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext, - const nsPrintOptions& aPrintOptions, + nsIPrintOptions* aPrintOptions, nsIPrintStatusCallback* aStatusCallback) { + NS_ENSURE_ARG_POINTER(aPresContext); + NS_ENSURE_ARG_POINTER(aPrintOptions); + + nsPrintRange printRangeType; + PRInt32 fromPageNum; + PRInt32 toPageNum; + PRInt32 marginL, marginR, marginT, marginB; + PRBool printEvenPages, printOddPages; + + PRInt32 printType; + aPrintOptions->GetPrintRange(&printType); + printRangeType = (nsPrintRange)printType; + aPrintOptions->GetPageRange(&fromPageNum, &toPageNum); + aPrintOptions->GetMargins(&marginT, &marginL, &marginR, &marginB); + mMargin.SizeTo(nscoord(marginL), nscoord(marginT), nscoord(marginR), nscoord(marginB)); + + aPrintOptions->GetPrintOptions(NS_PRINT_OPTIONS_PRINT_EVEN_PAGES, &printEvenPages); + aPrintOptions->GetPrintOptions(NS_PRINT_OPTIONS_PRINT_ODD_PAGES, &printOddPages); + + PRBool doingPageRange = ePrintRange_SpecifiedPageRange == printRangeType || + ePrintRange_Selection == printRangeType; + // If printing a range of pages make sure at least the starting page // number is valid PRInt32 totalPages = mFrames.GetLength(); - if (ePrintRange_SpecifiedRange == aPrintOptions.range) { - if (aPrintOptions.startPage > totalPages) { + if (doingPageRange) { + if (fromPageNum > totalPages) { return NS_ERROR_INVALID_ARG; } } @@ -383,29 +410,158 @@ nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext, presShell->GetViewManager(getter_AddRefs(vm)); nsresult rv = NS_OK; +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + { + nsIView * seqView; + GetView(aPresContext, &seqView); + nsRect rect; + GetRect(rect); + printf("Seq Frame: - %d,%d,%d,%d ", rect.x, rect.y, rect.width, rect.height); + printf("view: %p ", seqView); + nsRect viewRect; + if (seqView) { + seqView->GetBounds(viewRect); + printf(" %d,%d,%d,%d", viewRect.x, viewRect.y, viewRect.width, viewRect.height); + } + printf("\n"); + } + + { + PRInt32 pageNum = 1; + for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) { + nsIView* view; + page->GetView(aPresContext, &view); + NS_ASSERTION(nsnull != view, "no page view"); + nsRect rect; + page->GetRect(rect); + nsRect viewRect; + view->GetBounds(viewRect); + printf("Page: %d - %d,%d,%d,%d ", pageNum, rect.x, rect.y, rect.width, rect.height); + printf(" %d,%d,%d,%d\n", viewRect.x, viewRect.y, viewRect.width, viewRect.height); + pageNum++; + } + } + printf("***** Setting aPresContext %p is painting selection %d\n", aPresContext, ePrintRange_Selection == printRangeType); +#endif + + // Determine if we are rendering only the selection + aPresContext->SetIsRenderingOnlySelection(ePrintRange_Selection == printRangeType); + + + if (doingPageRange) { + // XXX because of the hack for making the selection all print on one page + // we must make sure that the page is sized correctly before printing. + PRInt32 width,height; + dc->GetDeviceSurfaceDimensions(width,height); + height -= mMargin.top + mMargin.bottom; + + PRInt32 pageNum = 1; + nscoord y = mMargin.top; + for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) { + nsIView* view; + page->GetView(aPresContext, &view); + NS_ASSERTION(nsnull != view, "no page view"); + if (pageNum < fromPageNum || pageNum > toPageNum) { + // XXX Doesn't seem like we need to do this + // because we ask only the pages we want to print + //view->SetVisibility(nsViewVisibility_kHide); + } else { + nsRect rect; + page->GetRect(rect); + rect.y = y; + rect.height = height; + page->SetRect(aPresContext, rect); + nsRect viewRect; + view->GetBounds(viewRect); + viewRect.y = y; + viewRect.height = height; + view->SetBounds(viewRect); + y += rect.height + mMargin.top + mMargin.bottom; + } + pageNum++; + } + + // adjust total number of pages + if (ePrintRange_Selection == printRangeType) { + totalPages = toPageNum - fromPageNum + 1; + } else { + totalPages = pageNum - 1; + } + } + + // XXX - This wouldn't have to be done each time + // but it isn't that expensive and this the best place + // to have access to a localized file properties file + // + // Note: because this is done here it makes a little bit harder + // to have UI for setting the header/footer font name and size + // + // Get default font name and size to be used for the headers and footers + nsAutoString fontName; + rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, "fontname", fontName); + if (NS_FAILED(rv)) { + fontName.AssignWithConversion("serif"); + } + + nsAutoString fontSizeStr; + nscoord pointSize = 10;; + rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, "fontsize", fontSizeStr); + if (NS_SUCCEEDED(rv)) { + PRInt32 errCode; + pointSize = fontSizeStr.ToInteger(&errCode); + if (NS_FAILED(errCode)) { + pointSize = 10; + } + } + aPrintOptions->SetFontNamePointSize(fontName, pointSize); + + // Now go get the Localized Page Formating String + PRBool doingPageTotals = PR_TRUE; + aPrintOptions->GetPrintOptions(NS_PRINT_OPTIONS_PRINT_PAGE_TOTAL, &doingPageTotals); + + nsAutoString pageFormatStr; + rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, + doingPageTotals?"pageofpages":"pagenumber", + pageFormatStr); + if (NS_FAILED(rv)) { // back stop formatting + pageFormatStr.AssignWithConversion(doingPageTotals?"%ld of %ld":"%ld"); + } + // Sets the format into a static data memeber which will own the memory and free it + nsPageFrame::SetPageNumberFormat(pageFormatStr.ToNewUnicode()); + // Print each specified page - PRInt32 pageNum = 1; + // pageNum keeps track of the current page and what pages are printing + // + // printedPageNum keeps track of the current page number to be printed + // Note: When print al the pages or a page range the printed page shows the + // actual page number, when printing selection it prints the page number starting + // with the first page of the selection. For example if the user has a + // selection that starts on page 2 and ends on page 3, the page numbers when + // print are 1 and then two (which is different than printing a page range, where + // the page numbers would have been 2 and then 3) + PRInt32 pageNum = 1; + PRInt32 printedPageNum = 1; for (nsIFrame* page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) { // See whether we should print this page PRBool printThisPage = PR_TRUE; // If printing a range of pages check whether the page number is in the // range of pages to print - if (ePrintRange_SpecifiedRange == aPrintOptions.range) { - if (pageNum < aPrintOptions.startPage) { + if (doingPageRange) { + if (pageNum < fromPageNum) { printThisPage = PR_FALSE; - } else if (pageNum > aPrintOptions.endPage) { + } else if (pageNum > toPageNum) { break; } } // Check for printing of odd and even pages if (pageNum & 0x1) { - if (!aPrintOptions.oddNumberedPages) { + if (!printOddPages) { printThisPage = PR_FALSE; // don't print odd numbered page } } else { - if (!aPrintOptions.evenNumberedPages) { + if (!printEvenPages) { printThisPage = PR_FALSE; // don't print even numbered page } } @@ -424,18 +580,37 @@ nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext, } break; } - + + // cast the frame to be a page frame + nsPageFrame * pf = NS_STATIC_CAST(nsPageFrame*, page); + if (pf != nsnull) { + pf->SetPrintOptions(aPrintOptions); + pf->SetPageNumInfo(printedPageNum, totalPages); + } + // Print the page nsIView* view; page->GetView(aPresContext, &view); + NS_ASSERTION(nsnull != view, "no page view"); - vm->Display(view); +#if defined(DEBUG_rods) || defined(DEBUG_dcone) + { + char * fontname = fontName.ToNewCString(); + printf("SPSF::Paint -> FontName[%s] Point Size: %d\n", fontname, pointSize); + nsMemory::Free(fontname); + printf("SPSF::Paint -> PageNo: %d View: %p\n", pageNum, view); + } +#endif + vm->Display(view, mMargin.left, mMargin.top); + // this view was printed and since display set the origin // 0,0 there is a danger that this view can be printed again // If it is a sibling to another page/view. Setting the visibility // to hide will keep this page from printing again - dwc - view->SetVisibility(nsViewVisibility_kHide); + // + // XXX Doesn't seem like we need to do this anymore + //view->SetVisibility(nsViewVisibility_kHide); // Finish printing of the page if (!SendStatusNotification(aStatusCallback, pageNum, totalPages, @@ -452,9 +627,21 @@ nsSimplePageSequenceFrame::Print(nsIPresContext* aPresContext, } } - // Increment the page number + if (ePrintRange_Selection != printRangeType || + (ePrintRange_Selection == printRangeType && printThisPage)) { + printedPageNum++; + } + pageNum++; } return rv; } + +NS_IMETHODIMP +nsSimplePageSequenceFrame::SetOffsets(nscoord aStartOffset, nscoord aEndOffset) +{ + mStartOffset = aStartOffset; + mEndOffset = aEndOffset; + return NS_OK; +} diff --git a/mozilla/layout/html/base/src/nsSimplePageSequence.h b/mozilla/layout/html/base/src/nsSimplePageSequence.h index ff0f07c51ad..7683d77aa77 100644 --- a/mozilla/layout/html/base/src/nsSimplePageSequence.h +++ b/mozilla/layout/html/base/src/nsSimplePageSequence.h @@ -22,8 +22,9 @@ #ifndef nsSimplePageSequence_h___ #define nsSimplePageSequence_h___ -#include "nsHTMLContainerFrame.h" #include "nsIPageSequenceFrame.h" +#include "nsContainerFrame.h" +#include "nsIPrintOptions.h" // Simple page sequence frame class. Used when we're in paginated mode class nsSimplePageSequenceFrame : public nsContainerFrame, @@ -40,16 +41,12 @@ public: const nsHTMLReflowState& aMaxSize, nsReflowStatus& aStatus); - // nsIFrame - NS_IMETHOD Paint(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsFramePaintLayer aWhichLayer); - // nsIPageSequenceFrame NS_IMETHOD Print(nsIPresContext* aPresContext, - const nsPrintOptions& aPrintOptions, + nsIPrintOptions* aPrintOptions, nsIPrintStatusCallback* aStatusCallback); + NS_IMETHOD SetOffsets(nscoord aStartOffset, nscoord aEndOffset); + NS_IMETHOD SetPageNo(PRInt32 aPageNo) { return NS_OK;} #ifdef DEBUG // Debugging @@ -58,11 +55,7 @@ public: protected: nsSimplePageSequenceFrame(); - virtual void PaintChild(nsIPresContext* aPresContext, - nsIRenderingContext& aRenderingContext, - const nsRect& aDirtyRect, - nsIFrame* aFrame, - nsFramePaintLayer aWhichLayer); + virtual ~nsSimplePageSequenceFrame(); nsresult IncrementalReflow(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, @@ -73,9 +66,14 @@ protected: nsresult CreateContinuingPageFrame(nsIPresContext* aPresContext, nsIFrame* aPageFrame, nsIFrame** aContinuingFrame); - NS_IMETHOD_(nsrefcnt) AddRef(void) {return nsContainerFrame::AddRef();} NS_IMETHOD_(nsrefcnt) Release(void) {return nsContainerFrame::Release();} + + nscoord mStartOffset; + nscoord mEndOffset; + + nsMargin mMargin; + PRBool mIsPrintingSelection; }; #endif /* nsSimplePageSequence_h___ */ diff --git a/mozilla/layout/html/base/src/nsTextFrame.cpp b/mozilla/layout/html/base/src/nsTextFrame.cpp index ecf2f632c07..a9e67394413 100644 --- a/mozilla/layout/html/base/src/nsTextFrame.cpp +++ b/mozilla/layout/html/base/src/nsTextFrame.cpp @@ -427,6 +427,11 @@ public: PRInt32* outFrameContentOffset, nsIFrame* *outChildFrame); + NS_IMETHOD IsVisibleForPainting(nsIPresContext * aPresContext, + nsIRenderingContext& aRenderingContext, + PRBool aCheckVis, + PRBool* aIsVisible); + // nsIHTMLReflow NS_IMETHOD Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aMetrics, @@ -659,6 +664,19 @@ public: PRUnichar* aBuffer, PRInt32 aLength, nscoord aWidth); + PRBool IsTextInSelection(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext); + + nsresult GetTextInfoForPainting(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + nsIPresShell** aPresShell, + nsISelectionController** aSelectionController, + PRBool& aDisplayingSelection, + PRBool& aIsPaginated, + PRBool& aIsSelected, + PRInt16& aSelectionValue, + nsILineBreaker** aLineBreaker); + void PaintUnicodeText(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, nsIStyleContext* aStyleContext, @@ -805,6 +823,7 @@ public: nsTextFrame::TextStyle & CurrentStyle(); nscolor CurrentForeGroundColor(); PRBool CurrentBackGroundColor(nscolor &aColor); + PRBool IsBeforeOrAfter(); private: union { PRUnichar *mUniStr; @@ -1042,6 +1061,11 @@ DrawSelectionIterator::CurrentBackGroundColor(nscolor &aColor) return PR_FALSE; } +PRBool +DrawSelectionIterator::IsBeforeOrAfter() +{ + return mCurrentIdx != (PRUint32)mDetails->mStart; +} //END DRAWSELECTIONITERATOR!! @@ -1219,9 +1243,8 @@ nsTextFrame::Paint(nsIPresContext* aPresContext, return NS_OK; } nsIStyleContext* sc = mStyleContext; - const nsStyleDisplay* disp = (const nsStyleDisplay*) - sc->GetStyleData(eStyleStruct_Display); - if (disp->IsVisible()) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && isVisible) { TextStyle ts(aPresContext, aRenderingContext, mStyleContext); if (ts.mSmallCaps || (0 != ts.mWordSpacing) || (0 != ts.mLetterSpacing) || ts.mJustifying) { @@ -1261,6 +1284,7 @@ nsTextFrame::Paint(nsIPresContext* aPresContext, // Use char rendering routine PaintAsciiText(aPresContext, aRenderingContext, sc, ts, 0, 0); } + } } return NS_OK; @@ -1735,6 +1759,194 @@ nsTextFrame::GetContentAndOffsetsForSelection(nsIPresContext *aPresContext, nsIC return NS_OK; } +//--------------------------------------------------------- +nsresult nsTextFrame::GetTextInfoForPainting(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + nsIPresShell** aPresShell, + nsISelectionController** aSelectionController, + PRBool& aDisplayingSelection, + PRBool& aIsPaginated, + PRBool& aIsSelected, + PRInt16& aSelectionValue, + nsILineBreaker** aLineBreaker) +{ + NS_ENSURE_ARG_POINTER(aPresContext); + NS_ENSURE_ARG_POINTER(aPresShell); + NS_ENSURE_ARG_POINTER(aSelectionController); + NS_ENSURE_ARG_POINTER(aLineBreaker); + + //get the presshell + nsresult rv = aPresContext->GetShell(aPresShell); + if (NS_FAILED(rv) || (*aPresShell) == nsnull) + return NS_ERROR_FAILURE; + + //get the selection controller + rv = GetSelectionController(aPresContext, aSelectionController); + if (NS_FAILED(rv) || !(*aSelectionController)) + return NS_ERROR_FAILURE; + + aPresContext->IsPaginated(&aIsPaginated); + PRBool isRenderingOnlySelection; + aPresContext->IsRenderingOnlySelection(&isRenderingOnlySelection); + + (*aSelectionController)->GetDisplaySelection(&aSelectionValue); + //if greater than hidden then we display some kind of selection + aDisplayingSelection = (aSelectionValue > nsISelectionController::SELECTION_HIDDEN) || + (aIsPaginated && isRenderingOnlySelection); + + // Transform text from content into renderable form + // XXX If the text fragment is already Unicode and text text wasn't + // transformed when we formatted it, then there's no need to do all + // this and we should just render the text fragment directly. See + // PaintAsciiText()... + nsCOMPtr doc; + (*aPresShell)->GetDocument(getter_AddRefs(doc)); + if (!doc) + return NS_ERROR_FAILURE; + + doc->GetLineBreaker(aLineBreaker); + + nsFrameState frameState; + GetFrameState(&frameState); + aIsSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + + return NS_OK; +} + +PRBool +nsTextFrame::IsTextInSelection(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext) +{ + nsCOMPtr selCon; + nsCOMPtr shell; + PRBool displaySelection; + PRBool isPaginated; + PRBool isSelected; + PRInt16 selectionValue; + nsCOMPtr lb; + if (NS_FAILED(GetTextInfoForPainting(aPresContext, + aRenderingContext, + getter_AddRefs(shell), + getter_AddRefs(selCon), + displaySelection, + isPaginated, + isSelected, + selectionValue, + getter_AddRefs(lb)))) { + return PR_FALSE; + } + + // Make enough space to transform + nsAutoTextBuffer paintBuffer; + nsAutoIndexBuffer indexBuffer; + if (NS_FAILED(indexBuffer.GrowTo(mContentLength + 1))) { + return PR_FALSE; + } + TextStyle ts(aPresContext, aRenderingContext, mStyleContext); + + // Transform text from content into renderable form + // XXX If the text fragment is already Unicode and text text wasn't + // transformed when we formatted it, then there's no need to do all + // this and we should just render the text fragment directly. See + // PaintAsciiText()... + + nsTextTransformer tx(lb, nsnull, aPresContext); + PRInt32 textLength; + // no need to worry about justification, that's always on the slow path + PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength); + + PRInt32* ip = indexBuffer.mBuffer; + PRUnichar* text = paintBuffer.mBuffer; + + if (0 != textLength) { + + SelectionDetails *details = nsnull; + nsCOMPtr frameSelection; + //get the frameSelection from the selection controller + if (selCon) { + frameSelection = do_QueryInterface(selCon); //this MAY implement + } + nsresult rv = NS_OK; + //if that failed get it from the pres shell + if (!frameSelection) + rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); + + if (NS_SUCCEEDED(rv) && frameSelection){ + nsCOMPtr content; + PRInt32 offset; + PRInt32 length; + + rv = GetContentAndOffsetsForSelection(aPresContext,getter_AddRefs(content),&offset,&length); + if (NS_SUCCEEDED(rv) && content){ + rv = frameSelection->LookUpSelection(content, mContentOffset, + mContentLength , &details, PR_FALSE); + } + } + + //where are the selection points "really" + SelectionDetails *sdptr = details; + while (sdptr){ + sdptr->mStart = ip[sdptr->mStart] - mContentOffset; + sdptr->mEnd = ip[sdptr->mEnd] - mContentOffset; + sdptr = sdptr->mNext; + } + //while we have substrings... + //PRBool drawn = PR_FALSE; + DrawSelectionIterator iter(details,text,(PRUint32)textLength, ts, nsISelectionController::SELECTION_NORMAL); + if (!iter.IsDone() && iter.First()) { + return PR_TRUE; + } + + sdptr = details; + if (details) { + while ((sdptr = details->mNext) != nsnull) { + delete details; + details = sdptr; + } + delete details; + } + } + return PR_FALSE; +} + +NS_IMETHODIMP +nsTextFrame::IsVisibleForPainting(nsIPresContext * aPresContext, + nsIRenderingContext& aRenderingContext, + PRBool aCheckVis, + PRBool* aIsVisible) +{ + if (aCheckVis) { + nsIStyleContext* sc = mStyleContext; + const nsStyleDisplay* disp = (const nsStyleDisplay*)sc->GetStyleData(eStyleStruct_Display); + if (!disp->IsVisible()) { + *aIsVisible = PR_FALSE; + return NS_OK; + } + } + + // Start by assuming we are visible and need to be painted + PRBool isVisible = PR_TRUE; + + PRBool isPaginated; + aPresContext->IsPaginated(&isPaginated); + if (isPaginated) { + PRBool isRendingSelection; + aPresContext->IsRenderingOnlySelection(&isRendingSelection); + if (isRendingSelection) { + // Check the quick way first + PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + if (isSelected) { + isVisible = IsTextInSelection(aPresContext, aRenderingContext); + } else { + isVisible = PR_FALSE; + } + } + } + + *aIsVisible = isVisible; + + return NS_OK; +} void nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, @@ -1743,22 +1955,24 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, TextStyle& aTextStyle, nscoord dx, nscoord dy) { - nsCOMPtr shell; -//get the presshell - nsresult rv = aPresContext->GetShell(getter_AddRefs(shell)); - if (NS_FAILED(rv) || !shell) - return; -//get the selection controller nsCOMPtr selCon; - rv = GetSelectionController(aPresContext, getter_AddRefs(selCon)); - if (NS_FAILED(rv) || !selCon) - return; - + nsCOMPtr shell; + PRBool displaySelection; + PRBool isPaginated; + PRBool isSelected; PRInt16 selectionValue; - selCon->GetDisplaySelection(&selectionValue); -//if greater than hidden then we display some kind of selection - PRBool displaySelection = selectionValue > nsISelectionController::SELECTION_HIDDEN; - + nsCOMPtr lb; + if (NS_FAILED(GetTextInfoForPainting(aPresContext, + aRenderingContext, + getter_AddRefs(shell), + getter_AddRefs(selCon), + displaySelection, + isPaginated, + isSelected, + selectionValue, + getter_AddRefs(lb)))) { + return; + } // Make enough space to transform nsAutoTextBuffer paintBuffer; nsAutoIndexBuffer indexBuffer; @@ -1774,12 +1988,7 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, // transformed when we formatted it, then there's no need to do all // this and we should just render the text fragment directly. See // PaintAsciiText()... - nsCOMPtr doc; - shell->GetDocument(getter_AddRefs(doc)); - if (!doc) - return; - nsCOMPtr lb; - doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(lb, nsnull, aPresContext); PRInt32 textLength; // no need to worry about justification, that's always on the slow path @@ -1788,10 +1997,6 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, PRInt32* ip = indexBuffer.mBuffer; PRUnichar* text = paintBuffer.mBuffer; - nsFrameState frameState; - PRBool isSelected; - GetFrameState(&frameState); - isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; if (0 != textLength) { @@ -1808,12 +2013,13 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, { //we draw according to selection rules SelectionDetails *details = nsnull; nsCOMPtr frameSelection; -//get the frameSelection from the selection controller - if (NS_SUCCEEDED(rv) && selCon) + //get the frameSelection from the selection controller + if (selCon) { frameSelection = do_QueryInterface(selCon); //this MAY implement } -//if that failed get it from the pres shell + //if that failed get it from the pres shell + nsresult rv = NS_OK; if (!frameSelection) rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); if (NS_SUCCEEDED(rv) && frameSelection){ @@ -1853,7 +2059,7 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING { - if (iter.CurrentBackGroundColor(currentBKColor)) + if (iter.CurrentBackGroundColor(currentBKColor) && !isPaginated) {//DRAW RECT HERE!!! aRenderingContext.SetColor(currentBKColor); aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height); @@ -1863,16 +2069,20 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext, else newWidth =0; - - aRenderingContext.SetColor(currentFGColor); - aRenderingContext.DrawString(currenttext, currentlength, currentX, dy); + if (isPaginated && !iter.IsBeforeOrAfter()) { + aRenderingContext.SetColor(aTextStyle.mColor->mColor); + aRenderingContext.DrawString(currenttext, currentlength, currentX, dy); + } else if (!isPaginated) { + aRenderingContext.SetColor(currentFGColor); + aRenderingContext.DrawString(currenttext, currentlength, currentX, dy); + } currentX+=newWidth;//increment twips X start iter.Next(); } } - else + else if (!isPaginated) { aRenderingContext.SetColor(aTextStyle.mColor->mColor); aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy); @@ -2298,18 +2508,24 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext, TextStyle& aTextStyle, nscoord dx, nscoord dy) { - nsCOMPtr shell; - nsresult rv = aPresContext->GetShell(getter_AddRefs(shell)); - if (NS_FAILED(rv) || !shell) - return; nsCOMPtr selCon; - rv = GetSelectionController(aPresContext, getter_AddRefs(selCon)); - if (NS_FAILED(rv) || !selCon) - return; - + nsCOMPtr shell; + PRBool displaySelection; + PRBool isPaginated; + PRBool isSelected; PRInt16 selectionValue; - selCon->GetDisplaySelection(&selectionValue); - PRBool displaySelection = selectionValue > nsISelectionController::SELECTION_HIDDEN; + nsCOMPtr lb; + if (NS_FAILED(GetTextInfoForPainting(aPresContext, + aRenderingContext, + getter_AddRefs(shell), + getter_AddRefs(selCon), + displaySelection, + isPaginated, + isSelected, + selectionValue, + getter_AddRefs(lb)))) { + return; + } // Make enough space to transform @@ -2321,13 +2537,6 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext, nscoord width = mRect.width; PRInt32 textLength; - // Transform text from content into renderable form - nsCOMPtr doc; - shell->GetDocument(getter_AddRefs(doc)); - if (!doc) - return; - nsCOMPtr lb; - doc->GetLineBreaker(getter_AddRefs(lb)); nsTextTransformer tx(lb, nsnull, aPresContext); PRInt32 numSpaces; @@ -2337,10 +2546,7 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext, PRInt32* ip = indexBuffer.mBuffer; PRUnichar* text = paintBuffer.mBuffer; - nsFrameState frameState; - PRBool isSelected; - GetFrameState(&frameState); - isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + if (0 != textLength) { ComputeExtraJustificationSpacing(aRenderingContext, aTextStyle, text, textLength, numSpaces); if (!displaySelection || !isSelected) { @@ -2355,6 +2561,7 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext, SelectionDetails *details = nsnull; nsCOMPtr frameSelection; //get the frame selection + nsresult rv = NS_OK; frameSelection = do_QueryInterface(selCon); //this MAY implement if (!frameSelection)//if that failed get it from the presshell rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); @@ -2405,16 +2612,23 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext, else newWidth =0; - aRenderingContext.SetColor(currentFGColor); - RenderString(aRenderingContext,aStyleContext, aTextStyle, currenttext, - currentlength, currentX, dy, width, details); - //increment twips X start but remember to get ready for next draw by reducing current x by letter spacing amount + if (isPaginated && !iter.IsBeforeOrAfter()) { + aRenderingContext.SetColor(aTextStyle.mColor->mColor); + RenderString(aRenderingContext,aStyleContext, aTextStyle, currenttext, + currentlength, currentX, dy, width, details); + } else if (!isPaginated) { + aRenderingContext.SetColor(currentFGColor); + RenderString(aRenderingContext,aStyleContext, aTextStyle, currenttext, + currentlength, currentX, dy, width, details); + } + + //increment twips X start but remember to get ready for next draw by reducing current x by letter spacing amount currentX+=newWidth;// + aTextStyle.mLetterSpacing; iter.Next(); } } - else + else if (!isPaginated) { aRenderingContext.SetColor(aTextStyle.mColor->mColor); RenderString(aRenderingContext,aStyleContext, aTextStyle, text, @@ -2440,21 +2654,25 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext, nscoord dx, nscoord dy) { NS_PRECONDITION(0 == (TEXT_HAS_MULTIBYTE & mState), "text is multi-byte"); - nsCOMPtr shell; - nsresult rv = aPresContext->GetShell(getter_AddRefs(shell)); - if (NS_FAILED(rv) || !shell) - return; + nsCOMPtr selCon; - rv = GetSelectionController(aPresContext, getter_AddRefs(selCon)); - if (NS_FAILED(rv) || !selCon) - return; - + nsCOMPtr shell; + PRBool displaySelection; + PRBool isPaginated; + PRBool isSelected; PRInt16 selectionValue; - PRBool isSelected; - selCon->GetDisplaySelection(&selectionValue); - PRBool displaySelection = selectionValue > nsISelectionController::SELECTION_HIDDEN; - - isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + nsCOMPtr lb; + if (NS_FAILED(GetTextInfoForPainting(aPresContext, + aRenderingContext, + getter_AddRefs(shell), + getter_AddRefs(selCon), + displaySelection, + isPaginated, + isSelected, + selectionValue, + getter_AddRefs(lb)))) { + return; + } // Get the text fragment nsCOMPtr tc = do_QueryInterface(mContent); @@ -2475,13 +2693,6 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext, } } - // Construct a text transformer - nsCOMPtr doc; - shell->GetDocument(getter_AddRefs(doc)); - if (!doc) - return; - nsCOMPtr lb; - doc->GetLineBreaker(getter_AddRefs(lb)); nsTextTransformer tx(lb, nsnull, aPresContext); // See if we need to transform the text. If the text fragment is ascii and @@ -2557,6 +2768,7 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext, nsCOMPtr frameSelection; //get the frame selection frameSelection = do_QueryInterface(selCon); //this MAY implement + nsresult rv = NS_OK; if (!frameSelection)//if that failed get it from the presshell rv = shell->GetFrameSelection(getter_AddRefs(frameSelection)); if (NS_SUCCEEDED(rv) && frameSelection){ @@ -2593,7 +2805,7 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext, if (NS_SUCCEEDED(aRenderingContext.GetWidth(currenttext, currentlength,newWidth)))//ADJUST FOR CHAR SPACING { - if (iter.CurrentBackGroundColor(currentBKColor)) + if (iter.CurrentBackGroundColor(currentBKColor) && !isPaginated) {//DRAW RECT HERE!!! aRenderingContext.SetColor(currentBKColor); aRenderingContext.FillRect(currentX, dy, newWidth, mRect.height); @@ -2602,16 +2814,21 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext, } else newWidth =0; - - aRenderingContext.SetColor(currentFGColor); - aRenderingContext.DrawString(currenttext, currentlength, currentX, dy); + + if (isPaginated && !iter.IsBeforeOrAfter()) { + aRenderingContext.SetColor(aTextStyle.mColor->mColor); + aRenderingContext.DrawString(currenttext, currentlength, currentX, dy); + } else if (!isPaginated) { + aRenderingContext.SetColor(currentFGColor); + aRenderingContext.DrawString(currenttext, currentlength, currentX, dy); + } currentX+=newWidth;//increment twips X start iter.Next(); } } - else + else if (!isPaginated) { aRenderingContext.SetColor(aTextStyle.mColor->mColor); aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy); @@ -4757,7 +4974,11 @@ nsTextFrame::List(nsIPresContext* aPresContext, FILE* out, PRInt32 aIndent) cons // Output the rect and state fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height); if (0 != mState) { - fprintf(out, " [state=%08x]", mState); + if (mState & NS_FRAME_SELECTED_CONTENT) { + fprintf(out, " [state=%08x] SELECTED", mState); + } else { + fprintf(out, " [state=%08x]", mState); + } } fprintf(out, " sc=%p<\n", mStyleContext); diff --git a/mozilla/layout/html/base/src/printing.properties b/mozilla/layout/html/base/src/printing.properties new file mode 100644 index 00000000000..f16f0e2715f --- /dev/null +++ b/mozilla/layout/html/base/src/printing.properties @@ -0,0 +1,42 @@ +# The contents of this file are subject to the Netscape Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/NPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): + +# Page number formating +## @page_number The current page number +#LOCALIZATION NOTE (pageofpages): Do not translate %ld in the following line. +# Place the word %ld where the page number and number of pages should be +# The first %ld will receive the the page number +pagenumber=%1$d + +# Page number formating +## @page_number The current page number +## @page_total The total number of pages +#LOCALIZATION NOTE (pageofpages): Do not translate %ld in the following line. +# Place the word %ld where the page number and number of pages should be +# The first %ld will receive the the page number +# the second %ld will receive the total number of pages +pageofpages=%1$d of %2$d + +# Print font +# The name of the font to be used to print the headers and footers +fontname=serif + +# Print font size +# The size of the font to be used to print the headers and footers +fontsize=10 diff --git a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp index 4d2f99a8475..8bf205a8c20 100644 --- a/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsComboboxControlFrame.cpp @@ -2473,6 +2473,10 @@ nsComboboxControlFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } #ifdef NOISY printf("%p paint layer %d at (%d, %d, %d, %d)\n", this, aWhichLayer, aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height); diff --git a/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp b/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp index e60fb79664d..5e65b76b910 100644 --- a/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp @@ -156,10 +156,9 @@ nsFieldSetFrame::Paint(nsIPresContext* aPresContext, { if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { // Paint our background and border - const nsStyleDisplay* disp = - (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); - - if (disp->IsVisible() && mRect.width && mRect.height) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && + isVisible && mRect.width && mRect.height) { PRIntn skipSides = GetSkipSides(); const nsStyleColor* color = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp index ad7cd74c4e2..d5b0e36bf78 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp @@ -269,7 +269,8 @@ nsFileControlFrame::MouseClick(nsIDOMEvent* aMouseEvent) // Get Loc title nsString title; - nsFormControlHelper::GetLocalizedString("FileUpload", title); + nsFormControlHelper::GetLocalizedString(nsFormControlHelper::GetHTMLPropertiesFileName(), + "FileUpload", title); nsCOMPtr filePicker = do_CreateInstance("@mozilla.org/filepicker;1"); if (!filePicker) @@ -658,6 +659,10 @@ nsFileControlFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); } diff --git a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp index 00dd715ab88..002727c584f 100644 --- a/mozilla/layout/html/forms/src/nsFormControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFormControlFrame.cpp @@ -402,6 +402,10 @@ nsFormControlFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } nsresult rv = nsLeafFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); diff --git a/mozilla/layout/html/forms/src/nsFormControlHelper.cpp b/mozilla/layout/html/forms/src/nsFormControlHelper.cpp index d0bd9d6eb3e..08357e86d86 100644 --- a/mozilla/layout/html/forms/src/nsFormControlHelper.cpp +++ b/mozilla/layout/html/forms/src/nsFormControlHelper.cpp @@ -872,12 +872,10 @@ nsFormControlHelper::GetInputElementValue(nsIContent* aContent, nsString* aText, } //---------------------------------------------------------------------------------- -#define form_properties "chrome://communicator/locale/layout/HtmlForm.properties" - // Return localised string for resource string (e.g. "Submit" -> "Submit Query") // This code is derived from nsBookmarksService::Init() and cookie_Localize() nsresult -nsFormControlHelper::GetLocalizedString(char* aKey, nsString& oVal) +nsFormControlHelper::GetLocalizedString(const char * aPropFileName, const char* aKey, nsString& oVal) { nsresult rv; nsCOMPtr bundle; @@ -887,7 +885,7 @@ nsFormControlHelper::GetLocalizedString(char* aKey, nsString& oVal) NS_WITH_SERVICE(nsIIOService, pNetService, kIOServiceCID, &rv); if (NS_SUCCEEDED(rv) && pNetService) { nsCOMPtr uri; - rv = pNetService->NewURI(form_properties, nsnull, getter_AddRefs(uri)); + rv = pNetService->NewURI(aPropFileName, nsnull, getter_AddRefs(uri)); if (NS_SUCCEEDED(rv) && uri) { // Create bundle diff --git a/mozilla/layout/html/forms/src/nsFormControlHelper.h b/mozilla/layout/html/forms/src/nsFormControlHelper.h index d9c935deaf8..4e5f3fd3d48 100644 --- a/mozilla/layout/html/forms/src/nsFormControlHelper.h +++ b/mozilla/layout/html/forms/src/nsFormControlHelper.h @@ -44,6 +44,10 @@ class nsFormFrame; #define NS_STRING_TRUE NS_LITERAL_STRING("1") #define NS_STRING_FALSE NS_LITERAL_STRING("0") +// for localization +#define FORM_PROPERTIES "chrome://communicator/locale/layout/HtmlForm.properties" + + /** * Enumeration of possible mouse states used to detect mouse clicks */ @@ -174,7 +178,8 @@ public: static nsresult GetWrapPropertyEnum(nsIContent * aContent, nsHTMLTextWrap& aWrapProp); // Localization Helper - static nsresult GetLocalizedString(char* aKey, nsString& oVal); + static nsresult GetLocalizedString(const char * aPropFileName, const char* aKey, nsString& oVal); + static const char * GetHTMLPropertiesFileName() { return FORM_PROPERTIES; } static nsresult GetDisabled(nsIContent* aContent, PRBool* oIsDisabled); // diff --git a/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp index 93d4d73b070..082db493356 100644 --- a/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxButtonControlFrame.cpp @@ -475,17 +475,18 @@ nsGfxButtonControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) NS_IMETHODIMP nsGfxButtonControlFrame::GetDefaultLabel(nsString& aString) { + const char * propname = nsFormControlHelper::GetHTMLPropertiesFileName(); nsresult rv = NS_OK; PRInt32 type; GetType(&type); if (IsReset(type)) { - rv = nsFormControlHelper::GetLocalizedString("Reset", aString); + rv = nsFormControlHelper::GetLocalizedString(propname, "Reset", aString); } else if (IsSubmit(type)) { - rv = nsFormControlHelper::GetLocalizedString("Submit", aString); + rv = nsFormControlHelper::GetLocalizedString(propname, "Submit", aString); } else if (IsBrowse(type)) { - rv = nsFormControlHelper::GetLocalizedString("Browse", aString); + rv = nsFormControlHelper::GetLocalizedString(propname, "Browse", aString); } else { aString.AssignWithConversion(" "); diff --git a/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp index a0034060f11..d641ca7ca9b 100644 --- a/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxCheckboxControlFrame.cpp @@ -367,10 +367,10 @@ nsGfxCheckboxControlFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - const nsStyleDisplay* disp = (const nsStyleDisplay*) - mStyleContext->GetStyleData(eStyleStruct_Display); - if (!disp->IsVisible()) + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { return NS_OK; + } // Paint the background nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); diff --git a/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.cpp b/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.cpp index 742b5c84c05..8598a7a480e 100644 --- a/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsGfxRadioControlFrame.cpp @@ -314,11 +314,10 @@ nsGfxRadioControlFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - const nsStyleDisplay* disp = (const nsStyleDisplay*) - mStyleContext->GetStyleData(eStyleStruct_Display); - if (!disp->IsVisible()) - return NS_OK; - + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } // Paint the background nsFormControlFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); diff --git a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp index fcfbbdccea5..2e3e2f36d94 100644 --- a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp +++ b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.cpp @@ -2014,6 +2014,19 @@ nsGfxTextControlFrame2::Reflow(nsIPresContext* aPresContext, return rv; } +NS_IMETHODIMP +nsGfxTextControlFrame2::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } + return nsStackFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); +} + NS_IMETHODIMP nsGfxTextControlFrame2::GetPrefSize(nsBoxLayoutState& aState, nsSize& aSize) diff --git a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.h b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.h index 9da3e3151f6..f9a697fbd16 100644 --- a/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.h +++ b/mozilla/layout/html/forms/src/nsGfxTextControlFrame2.h @@ -69,6 +69,11 @@ public: const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus); + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + NS_IMETHOD GetPrefSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize); NS_IMETHOD GetMinSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize); NS_IMETHOD GetMaxSize(nsBoxLayoutState& aBoxLayoutState, nsSize& aSize); diff --git a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp index 5fadcbc33b1..a64202530e4 100644 --- a/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsHTMLButtonControlFrame.cpp @@ -475,14 +475,14 @@ nsHTMLButtonControlFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { - const nsStyleDisplay* disp = (const nsStyleDisplay*) - mStyleContext->GetStyleData(eStyleStruct_Display); - if (disp->IsVisible()) - { - nsRect rect(0, 0, mRect.width, mRect.height); - mRenderer.PaintButton(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, rect); + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; } + nsRect rect(0, 0, mRect.width, mRect.height); + mRenderer.PaintButton(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, rect); + #if 0 // old way PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); @@ -498,10 +498,6 @@ nsHTMLButtonControlFrame::Paint(nsIPresContext* aPresContext, border.SizeTo(0, 0, 0, 0); spacing->CalcBorderFor(this, border); - nsRect rect; - GetRect(rect); - rect.x = 0; - rect.y = 0; rect.Deflate(border); aRenderingContext.PushState(); PRBool clipEmpty; diff --git a/mozilla/layout/html/forms/src/nsIsIndexFrame.cpp b/mozilla/layout/html/forms/src/nsIsIndexFrame.cpp index 17063c2447a..d90b95cd7c4 100644 --- a/mozilla/layout/html/forms/src/nsIsIndexFrame.cpp +++ b/mozilla/layout/html/forms/src/nsIsIndexFrame.cpp @@ -99,6 +99,19 @@ nsIsIndexFrame::~nsIsIndexFrame() } } +NS_IMETHODIMP +nsIsIndexFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } + return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); +} + NS_IMETHODIMP nsIsIndexFrame::UpdatePromptLabel() { @@ -125,7 +138,8 @@ nsIsIndexFrame::UpdatePromptLabel() // We can't make any assumption as to what the default would be // because the value is localized for non-english platforms, thus // it might not be the string "This is a searchable index. Enter search keywords: " - result = nsFormControlHelper::GetLocalizedString("IsIndexPrompt", prompt); + result = nsFormControlHelper::GetLocalizedString(nsFormControlHelper::GetHTMLPropertiesFileName(), + "IsIndexPrompt", prompt); } nsCOMPtr text = do_QueryInterface(mTextContent); result = text->SetText(prompt.GetUnicode(), prompt.Length(), PR_TRUE); diff --git a/mozilla/layout/html/forms/src/nsIsIndexFrame.h b/mozilla/layout/html/forms/src/nsIsIndexFrame.h index 37eb142bb5c..30278148b60 100644 --- a/mozilla/layout/html/forms/src/nsIsIndexFrame.h +++ b/mozilla/layout/html/forms/src/nsIsIndexFrame.h @@ -52,6 +52,11 @@ public: nsIsIndexFrame(); virtual ~nsIsIndexFrame(); + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + // XXX Hack so we can squirrel away the pres context pointer for the KeyPress method NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent, diff --git a/mozilla/layout/html/forms/src/nsLabelFrame.cpp b/mozilla/layout/html/forms/src/nsLabelFrame.cpp index 97be07115c5..2ba1f9b0d76 100644 --- a/mozilla/layout/html/forms/src/nsLabelFrame.cpp +++ b/mozilla/layout/html/forms/src/nsLabelFrame.cpp @@ -457,6 +457,10 @@ nsLabelFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } return nsHTMLContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); } diff --git a/mozilla/layout/html/forms/src/nsLegendFrame.cpp b/mozilla/layout/html/forms/src/nsLegendFrame.cpp index 4c287c63516..6b069ff1c5b 100644 --- a/mozilla/layout/html/forms/src/nsLegendFrame.cpp +++ b/mozilla/layout/html/forms/src/nsLegendFrame.cpp @@ -104,6 +104,19 @@ nsLegendFrame::Reflow(nsIPresContext* aPresContext, } +NS_IMETHODIMP +nsLegendFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_TRUE, &isVisible)) && !isVisible) { + return NS_OK; + } + return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); +} + PRInt32 nsLegendFrame::GetAlign() { PRInt32 intValue = NS_STYLE_TEXT_ALIGN_LEFT; diff --git a/mozilla/layout/html/forms/src/nsLegendFrame.h b/mozilla/layout/html/forms/src/nsLegendFrame.h index 19101c463db..76d38bd88f7 100644 --- a/mozilla/layout/html/forms/src/nsLegendFrame.h +++ b/mozilla/layout/html/forms/src/nsLegendFrame.h @@ -52,6 +52,11 @@ public: NS_IMETHOD Destroy(nsIPresContext *aPresContext); + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + #ifdef NS_DEBUG NS_IMETHOD GetFrameName(nsString& aResult) const; #endif diff --git a/mozilla/layout/html/forms/src/nsListControlFrame.cpp b/mozilla/layout/html/forms/src/nsListControlFrame.cpp index 71e65069274..395ff7377c2 100644 --- a/mozilla/layout/html/forms/src/nsListControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsListControlFrame.cpp @@ -287,9 +287,55 @@ nsListControlFrame::Destroy(nsIPresContext *aPresContext) return nsScrollFrame::Destroy(aPresContext); } -//--------------------------------------------------------- -//NS_IMPL_ADDREF(nsListControlFrame) -//NS_IMPL_RELEASE(nsListControlFrame) +NS_IMETHODIMP +nsListControlFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + nsIStyleContext* sc = mStyleContext; + const nsStyleDisplay* disp = (const nsStyleDisplay*)sc->GetStyleData(eStyleStruct_Display); + if (!disp->IsVisible()) { + return PR_FALSE; + } + + // Start by assuming we are visible and need to be painted + PRBool isVisible = PR_TRUE; + + PRBool isPaginated; + aPresContext->IsPaginated(&isPaginated); + if (isPaginated) { + PRBool isRendingSelection;; + aPresContext->IsRenderingOnlySelection(&isRendingSelection); + if (isRendingSelection) { + // Check the quick way first + PRBool isSelected = (mState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT; + // if we aren't selected in the mState we could be a container + // so check to see if we are in the selection range + if (!isSelected) { + nsCOMPtr shell; + aPresContext->GetShell(getter_AddRefs(shell)); + nsCOMPtr selcon; + selcon = do_QueryInterface(shell); + if (selcon) { + nsCOMPtr selection; + selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection)); + nsCOMPtr node(do_QueryInterface(mContent)); + selection->ContainsNode(node, PR_TRUE, &isVisible); + } else { + isVisible = PR_FALSE; + } + } + } + } + + if (isVisible) { + return nsScrollFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + } + + return NS_OK; + +} //--------------------------------------------------------- // Frames are not refcounted, no need to AddRef diff --git a/mozilla/layout/html/forms/src/nsListControlFrame.h b/mozilla/layout/html/forms/src/nsListControlFrame.h index b1c1ebc1732..6ca490ed711 100644 --- a/mozilla/layout/html/forms/src/nsListControlFrame.h +++ b/mozilla/layout/html/forms/src/nsListControlFrame.h @@ -193,6 +193,11 @@ public: NS_IMETHOD MoveTo(nsIPresContext* aPresContext, nscoord aX, nscoord aY); NS_IMETHOD Destroy(nsIPresContext *aPresContext); + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + // nsIFormControlFrame NS_IMETHOD GetType(PRInt32* aType) const; NS_IMETHOD GetName(nsString* aName); diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp index 7175ba23e12..071e8672d0a 100644 --- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -10097,7 +10097,8 @@ GetAlternateTextFor(nsIContent* aContent, // If there's no "value" attribute either, then use the localized string // for "Submit" as the alternate text. if (NS_CONTENT_ATTR_NOT_THERE == rv) { - nsFormControlHelper::GetLocalizedString("Submit", aAltText); + nsFormControlHelper::GetLocalizedString(nsFormControlHelper::GetHTMLPropertiesFileName(), + "Submit", aAltText); } } } diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp index ace4d55f06e..e38441b08c0 100644 --- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp @@ -247,6 +247,10 @@ NS_METHOD nsTableCellFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { + return NS_OK; + } const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); diff --git a/mozilla/layout/html/table/src/nsTableColFrame.cpp b/mozilla/layout/html/table/src/nsTableColFrame.cpp index 2b0905e7698..a12403a0bdc 100644 --- a/mozilla/layout/html/table/src/nsTableColFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableColFrame.cpp @@ -108,6 +108,10 @@ NS_METHOD nsTableColFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { + return NS_OK; + } if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { nsCompatibility mode; aPresContext->GetCompatibilityMode(&mode); diff --git a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp index 2d4e048e81d..29585338424 100644 --- a/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableColGroupFrame.cpp @@ -434,6 +434,10 @@ NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { + return NS_OK; + } if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { nsCompatibility mode; aPresContext->GetCompatibilityMode(&mode); diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp index d40351e0a58..1d70d304dc1 100644 --- a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp @@ -330,6 +330,10 @@ NS_METHOD nsTableOuterFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height); } #endif + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { + return NS_OK; + } // the remaining code was copied from nsContainerFrame::PaintChildren since // it only paints the primary child list diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp index b8cb53393d8..617417b7010 100644 --- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp @@ -513,6 +513,10 @@ NS_METHOD nsTableRowFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { + return NS_OK; + } nsresult rv; if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { nsCompatibility mode; diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp index 01f4d53da84..7a09a29740f 100644 --- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -205,6 +205,10 @@ NS_METHOD nsTableRowGroupFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { + return NS_OK; + } nsresult rv; if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { nsCompatibility mode; diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp index ace4d55f06e..e38441b08c0 100644 --- a/mozilla/layout/tables/nsTableCellFrame.cpp +++ b/mozilla/layout/tables/nsTableCellFrame.cpp @@ -247,6 +247,10 @@ NS_METHOD nsTableCellFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { + return NS_OK; + } const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); diff --git a/mozilla/layout/tables/nsTableColFrame.cpp b/mozilla/layout/tables/nsTableColFrame.cpp index 2b0905e7698..a12403a0bdc 100644 --- a/mozilla/layout/tables/nsTableColFrame.cpp +++ b/mozilla/layout/tables/nsTableColFrame.cpp @@ -108,6 +108,10 @@ NS_METHOD nsTableColFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { + return NS_OK; + } if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { nsCompatibility mode; aPresContext->GetCompatibilityMode(&mode); diff --git a/mozilla/layout/tables/nsTableColGroupFrame.cpp b/mozilla/layout/tables/nsTableColGroupFrame.cpp index 2d4e048e81d..29585338424 100644 --- a/mozilla/layout/tables/nsTableColGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableColGroupFrame.cpp @@ -434,6 +434,10 @@ NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { + return NS_OK; + } if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { nsCompatibility mode; aPresContext->GetCompatibilityMode(&mode); diff --git a/mozilla/layout/tables/nsTableOuterFrame.cpp b/mozilla/layout/tables/nsTableOuterFrame.cpp index d40351e0a58..1d70d304dc1 100644 --- a/mozilla/layout/tables/nsTableOuterFrame.cpp +++ b/mozilla/layout/tables/nsTableOuterFrame.cpp @@ -330,6 +330,10 @@ NS_METHOD nsTableOuterFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height); } #endif + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { + return NS_OK; + } // the remaining code was copied from nsContainerFrame::PaintChildren since // it only paints the primary child list diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp index b8cb53393d8..617417b7010 100644 --- a/mozilla/layout/tables/nsTableRowFrame.cpp +++ b/mozilla/layout/tables/nsTableRowFrame.cpp @@ -513,6 +513,10 @@ NS_METHOD nsTableRowFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { + return NS_OK; + } nsresult rv; if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { nsCompatibility mode; diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.cpp b/mozilla/layout/tables/nsTableRowGroupFrame.cpp index 01f4d53da84..7a09a29740f 100644 --- a/mozilla/layout/tables/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableRowGroupFrame.cpp @@ -205,6 +205,10 @@ NS_METHOD nsTableRowGroupFrame::Paint(nsIPresContext* aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { + PRBool isVisible; + if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { + return NS_OK; + } nsresult rv; if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { nsCompatibility mode; diff --git a/mozilla/view/public/nsIViewManager.h b/mozilla/view/public/nsIViewManager.h index dbdf1e6dc10..e79687ba5c8 100644 --- a/mozilla/view/public/nsIViewManager.h +++ b/mozilla/view/public/nsIViewManager.h @@ -434,7 +434,7 @@ public: /** * Display the specified view. Used when printing. */ - NS_IMETHOD Display(nsIView *aView) = 0; + NS_IMETHOD Display(nsIView *aView, nscoord aX, nscoord aY) = 0; /** * Add a listener to the view manager's composite listener list. diff --git a/mozilla/view/src/nsViewManager.cpp b/mozilla/view/src/nsViewManager.cpp index 049bb78aadf..f0ee0f5a18c 100644 --- a/mozilla/view/src/nsViewManager.cpp +++ b/mozilla/view/src/nsViewManager.cpp @@ -2905,51 +2905,47 @@ NS_IMETHODIMP nsViewManager::GetRootScrollableView(nsIScrollableView **aScrollab return NS_OK; } -NS_IMETHODIMP nsViewManager::Display(nsIView* aView) +NS_IMETHODIMP nsViewManager::Display(nsIView* aView, nscoord aX, nscoord aY) { - nsIRenderingContext *localcx = nsnull; - nsRect trect; + nsIRenderingContext *localcx = nsnull; + nsRect trect; - if (PR_FALSE == mRefreshEnabled) - return NS_OK; + if (PR_FALSE == mRefreshEnabled) + return NS_OK; - NS_ASSERTION(!(PR_TRUE == mPainting), "recursive painting not permitted"); + NS_ASSERTION(!(PR_TRUE == mPainting), "recursive painting not permitted"); - mPainting = PR_TRUE; + mPainting = PR_TRUE; - mContext->CreateRenderingContext(localcx); + mContext->CreateRenderingContext(localcx); - //couldn't get rendering context. this is ok if at startup - if (nsnull == localcx) - { - mPainting = PR_FALSE; - return NS_ERROR_FAILURE; - } + //couldn't get rendering context. this is ok if at startup + if (nsnull == localcx) + { + mPainting = PR_FALSE; + return NS_ERROR_FAILURE; + } - aView->GetBounds(trect); - nscoord x = trect.x, y = trect.y; + aView->GetBounds(trect); + nscoord x = trect.x, y = trect.y; - // XXX Temporarily reset the position to (0, 0), that way when we paint - // we won't end up translating incorrectly - aView->SetPosition(0, 0); + localcx->Translate(aX, aY); - PRBool result; + PRBool result; - trect.x = trect.y = 0; - localcx->SetClipRect(trect, nsClipCombine_kReplace, result); + trect.x = trect.y = 0; + localcx->SetClipRect(trect, nsClipCombine_kReplace, result); - // Paint the view. The clipping rect was set above set don't clip again. - //aView->Paint(*localcx, trect, NS_VIEW_FLAG_CLIP_SET, result); + // Paint the view. The clipping rect was set above set don't clip again. + //aView->Paint(*localcx, trect, NS_VIEW_FLAG_CLIP_SET, result); RenderViews(aView,*localcx,trect,result); - // XXX Reset the view's origin - aView->SetPosition(x, y); + NS_RELEASE(localcx); - NS_RELEASE(localcx); + mPainting = PR_FALSE; - mPainting = PR_FALSE; + return NS_OK; - return NS_OK; } NS_IMETHODIMP nsViewManager::AddCompositeListener(nsICompositeListener* aListener) diff --git a/mozilla/view/src/nsViewManager.h b/mozilla/view/src/nsViewManager.h index 6026a4b3cb6..1c17de8031c 100644 --- a/mozilla/view/src/nsViewManager.h +++ b/mozilla/view/src/nsViewManager.h @@ -148,7 +148,7 @@ public: nsDrawingSurface GetDrawingSurface(nsIRenderingContext &aContext, nsRect& aBounds); - NS_IMETHOD Display(nsIView *aView); + NS_IMETHOD Display(nsIView *aView, nscoord aX, nscoord aY); NS_IMETHOD AddCompositeListener(nsICompositeListener *aListener); NS_IMETHOD RemoveCompositeListener(nsICompositeListener *aListener); diff --git a/mozilla/view/src/nsViewManager2.cpp b/mozilla/view/src/nsViewManager2.cpp index 21aea336327..71e87d3e7d9 100755 --- a/mozilla/view/src/nsViewManager2.cpp +++ b/mozilla/view/src/nsViewManager2.cpp @@ -2368,51 +2368,46 @@ NS_IMETHODIMP nsViewManager2::GetRootScrollableView(nsIScrollableView **aScrolla return NS_OK; } -NS_IMETHODIMP nsViewManager2::Display(nsIView* aView) +NS_IMETHODIMP nsViewManager2::Display(nsIView* aView, nscoord aX, nscoord aY) { - nsIRenderingContext *localcx = nsnull; - nsRect trect; + nsIRenderingContext *localcx = nsnull; + nsRect trect; - if (PR_FALSE == mRefreshEnabled) - return NS_OK; + if (PR_FALSE == mRefreshEnabled) + return NS_OK; - NS_ASSERTION(!(PR_TRUE == mPainting), "recursive painting not permitted"); + NS_ASSERTION(!(PR_TRUE == mPainting), "recursive painting not permitted"); - mPainting = PR_TRUE; + mPainting = PR_TRUE; - mContext->CreateRenderingContext(localcx); + mContext->CreateRenderingContext(localcx); - //couldn't get rendering context. this is ok if at startup - if (nsnull == localcx) - { - mPainting = PR_FALSE; - return NS_ERROR_FAILURE; - } + //couldn't get rendering context. this is ok if at startup + if (nsnull == localcx) + { + mPainting = PR_FALSE; + return NS_ERROR_FAILURE; + } - aView->GetBounds(trect); - nscoord x = trect.x, y = trect.y; + aView->GetBounds(trect); + nscoord x = trect.x, y = trect.y; - // XXX Temporarily reset the position to (0, 0), that way when we paint - // we won't end up translating incorrectly - aView->SetPosition(0, 0); + localcx->Translate(aX, aY); - PRBool result; + PRBool result; - trect.x = trect.y = 0; - localcx->SetClipRect(trect, nsClipCombine_kReplace, result); + trect.x = trect.y = 0; + localcx->SetClipRect(trect, nsClipCombine_kReplace, result); - // Paint the view. The clipping rect was set above set don't clip again. - //aView->Paint(*localcx, trect, NS_VIEW_FLAG_CLIP_SET, result); + // Paint the view. The clipping rect was set above set don't clip again. + //aView->Paint(*localcx, trect, NS_VIEW_FLAG_CLIP_SET, result); RenderViews(aView,*localcx,trect,result); - // XXX Reset the view's origin - aView->SetPosition(x, y); + NS_RELEASE(localcx); - NS_RELEASE(localcx); + mPainting = PR_FALSE; - mPainting = PR_FALSE; - - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsViewManager2::AddCompositeListener(nsICompositeListener* aListener) diff --git a/mozilla/view/src/nsViewManager2.h b/mozilla/view/src/nsViewManager2.h index 69372fdf67a..105883e370a 100755 --- a/mozilla/view/src/nsViewManager2.h +++ b/mozilla/view/src/nsViewManager2.h @@ -146,7 +146,7 @@ public: nsDrawingSurface GetDrawingSurface(nsIRenderingContext &aContext, nsRect& aBounds); - NS_IMETHOD Display(nsIView *aView); + NS_IMETHOD Display(nsIView *aView, nscoord aX, nscoord aY); NS_IMETHOD AddCompositeListener(nsICompositeListener *aListener); NS_IMETHOD RemoveCompositeListener(nsICompositeListener *aListener); diff --git a/mozilla/xpfe/global/resources/content/unix/printdialog.js b/mozilla/xpfe/global/resources/content/unix/printdialog.js index 17cf17644d3..79ccb4c5bbd 100644 --- a/mozilla/xpfe/global/resources/content/unix/printdialog.js +++ b/mozilla/xpfe/global/resources/content/unix/printdialog.js @@ -54,6 +54,14 @@ function initDialog() dialog.legalRadio = document.getElementById("legalRadio"); dialog.exectiveRadio = document.getElementById("exectiveRadio"); + dialog.allpagesRadio = document.getElementById("allpagesRadio"); + dialog.rangeRadio = document.getElementById("rangeRadio"); + dialog.selectionRadio = document.getElementById("selectionRadio"); + dialog.frompageInput = document.getElementById("frompageInput"); + dialog.frompageLabel = document.getElementById("frompageLabel"); + dialog.topageInput = document.getElementById("topageInput"); + dialog.topageLabel = document.getElementById("topageLabel"); + dialog.topInput = document.getElementById("topInput"); dialog.bottomInput = document.getElementById("bottomInput"); dialog.leftInput = document.getElementById("leftInput"); @@ -99,6 +107,21 @@ function doPrintToFile( value ) } } +function doPrintRange( value ) +{ + if ( value == true) { + dialog.frompageInput.removeAttribute("disabled"); + dialog.frompageLabel.removeAttribute("disabled"); + dialog.topageInput.removeAttribute("disabled"); + dialog.topageLabel.removeAttribute("disabled"); + } else { + dialog.frompageInput.setAttribute("disabled","true" ); + dialog.frompageLabel.setAttribute("disabled","true" ); + dialog.topageInput.setAttribute("disabled","true" ); + dialog.topageLabel.setAttribute("disabled","true" ); + } +} + function loadDialog() { var print_tofile = false; @@ -112,6 +135,7 @@ function loadDialog() var print_margin_right = 500; var print_command = default_command; var print_file = default_file; + var print_selection_radio_enabled = false; try { prefs = Components.classes["@mozilla.org/preferences;1"]; @@ -127,12 +151,19 @@ function loadDialog() try { print_reversed = prefs.GetBoolPref("print.print_reversed"); } catch(e) { } try { print_color = prefs.GetBoolPref("print.print_color"); } catch(e) { } try { print_paper_size = prefs.GetIntPref("print.print_paper_size"); } catch(e) { } - try { print_margin_top = prefs.GetIntPref("print.print_margin_top"); } catch(e) { } - try { print_margin_left = prefs.GetIntPref("print.print_margin_left"); } catch(e) { } - try { print_margin_bottom = prefs.GetIntPref("print.print_margin_bottom"); } catch(e) { } - try { print_margin_right = prefs.GetIntPref("print.print_margin_right"); } catch(e) { } + // + // margins are set/get with the _js extention because we aren't converting them to twips + // the are multiplied by a 1000, i.e. 0.5 inches equals 500 + // + try { print_margin_top = prefs.GetIntPref("print.print_margin_top_js"); } catch(e) { } + try { print_margin_left = prefs.GetIntPref("print.print_margin_left_js"); } catch(e) { } + try { print_margin_bottom = prefs.GetIntPref("print.print_margin_bottom_js"); } catch(e) { } + try { print_margin_right = prefs.GetIntPref("print.print_margin_right_js"); } catch(e) { } + try { print_command = prefs.CopyCharPref("print.print_command"); } catch(e) { } try { print_file = prefs.CopyCharPref("print.print_file"); } catch(e) { } + try { print_tofile = prefs.GetBoolPref("print.print_tofile"); } catch(e) { } + try { print_selection_radio_enabled = prefs.GetBoolPref("print.selection_radio_enabled"); } catch(e) { } } if ( print_tofile == true) { @@ -165,6 +196,17 @@ function loadDialog() dialog.a4Radio.checked = true; } + dialog.allpagesRadio.checked = true; + if ( print_selection_radio_enabled == true) { + dialog.selectionRadio.removeAttribute("disabled"); + } else { + dialog.selectionRadio.setAttribute("disabled","true" ); + } + doPrintRange(dialog.rangeRadio.checked); + dialog.frompageInput.value = 1; + dialog.topageInput.value = 1; + + // convert back to inches dialog.topInput.value = print_margin_top * 0.001; dialog.bottomInput.value = print_margin_bottom * 0.001; dialog.leftInput.value = print_margin_left * 0.001; @@ -236,13 +278,21 @@ function onOK() } prefs.SetIntPref("print.print_paper_size", print_paper_size); - prefs.SetIntPref("print.print_margin_top", dialog.topInput.value * 1000); - prefs.SetIntPref("print.print_margin_left", dialog.leftInput.value * 1000); - prefs.SetIntPref("print.print_margin_bottom", dialog.bottomInput.value *1000); - prefs.SetIntPref("print.print_margin_right", dialog.rightInput.value * 1000); + // save these out so they can be picked up by the device spec + prefs.SetIntPref("print.print_margin_top_js", dialog.topInput.value * 1000); + prefs.SetIntPref("print.print_margin_left_js", dialog.leftInput.value * 1000); + prefs.SetIntPref("print.print_margin_bottom_js", dialog.bottomInput.value *1000); + prefs.SetIntPref("print.print_margin_right_js", dialog.rightInput.value * 1000); prefs.SetCharPref("print.print_command", dialog.cmdInput.value); prefs.SetCharPref("print.print_file", dialog.fileInput.value); + + prefs.SetBoolPref("print.print_allpagesrange", dialog.allpagesRadio.checked); + prefs.SetBoolPref("print.print_pagerange", dialog.rangeRadio.checked); + prefs.SetBoolPref("print.print_selectionrange", dialog.selectionRadio.checked); + prefs.SetIntPref("print.print_frompage", dialog.frompageInput.value); + prefs.SetIntPref("print.print_topage", dialog.topageInput.value); + } if (param) { diff --git a/mozilla/xpfe/global/resources/content/unix/printdialog.xul b/mozilla/xpfe/global/resources/content/unix/printdialog.xul index 7a553d7d307..a304ab8f7e2 100644 --- a/mozilla/xpfe/global/resources/content/unix/printdialog.xul +++ b/mozilla/xpfe/global/resources/content/unix/printdialog.xul @@ -87,22 +87,36 @@ Contributor(s): Masaki Katakai + + + + + + + + + + + + + + - - + + - + - + - + diff --git a/mozilla/xpfe/global/resources/locale/en-US/unix/printdialog.dtd b/mozilla/xpfe/global/resources/locale/en-US/unix/printdialog.dtd index 08660bab19b..e17c2be781c 100644 --- a/mozilla/xpfe/global/resources/locale/en-US/unix/printdialog.dtd +++ b/mozilla/xpfe/global/resources/locale/en-US/unix/printdialog.dtd @@ -28,6 +28,13 @@ + + + + + + +