diff --git a/mozilla/gfx/idl/nsIPrintOptions.idl b/mozilla/gfx/idl/nsIPrintOptions.idl index c2f38143831..5636f8afde3 100644 --- a/mozilla/gfx/idl/nsIPrintOptions.idl +++ b/mozilla/gfx/idl/nsIPrintOptions.idl @@ -63,12 +63,7 @@ interface nsIPrintOptions : nsISupports /* Print Option Flags for Bit Field*/ const long kOptPrintOddPages = 0x00000001; const long kOptPrintEvenPages = 0x00000002; - const long kOptPrintDocTitle = 0x00000004; - const long kOptPrintDocLoc = 0x00000008; - const long kOptPrintPageNums = 0x00000010; - const long kOptPrintPageTotal = 0x00000020; - const long kOptPrintDatePrinted = 0x00000040; - const long kPrintOptionsEnableSelectionRB = 0x00000080; + const long kPrintOptionsEnableSelectionRB = 0x00000004; /* Print Range Enums */ const long kRangeAllPages = 0; @@ -151,10 +146,18 @@ interface nsIPrintOptions : nsISupports attribute double marginRight; attribute short printRange; - attribute short pageNumJust; + attribute wstring title; attribute wstring docURL; + attribute wstring headerStrLeft; + attribute wstring headerStrCenter; + attribute wstring headerStrRight; + + attribute wstring footerStrLeft; + attribute wstring footerStrCenter; + attribute wstring footerStrRight; + attribute short howToEnableFrameUI; attribute short printFrameType; attribute boolean isCancelled; diff --git a/mozilla/gfx/src/nsPrintOptionsImpl.cpp b/mozilla/gfx/src/nsPrintOptionsImpl.cpp index 1899e4d2e66..1f19d7257e8 100644 --- a/mozilla/gfx/src/nsPrintOptionsImpl.cpp +++ b/mozilla/gfx/src/nsPrintOptionsImpl.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * @@ -16,7 +16,7 @@ * * The Initial Developer of the Original Code is * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 + * Portions created by the Initial Developer are Copyright (C) 2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): @@ -77,12 +77,12 @@ const char * kMarginRight = "print.print_margin_right"; // Prefs for Print Options 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"; +const char * kPrintHeaderStr1 = "print.print_headerleft"; +const char * kPrintHeaderStr2 = "print.print_headercenter"; +const char * kPrintHeaderStr3 = "print.print_headerright"; +const char * kPrintFooterStr1 = "print.print_footerleft"; +const char * kPrintFooterStr2 = "print.print_footercenter"; +const char * kPrintFooterStr3 = "print.print_footerright"; // Additional Prefs const char * kPrintReversed = "print.print_reversed"; @@ -105,7 +105,7 @@ const char * kLeftJust = "left"; const char * kCenterJust = "center"; const char * kRightJust = "right"; -#define form_properties "chrome://communicator/locale/printing.properties" +nsFont* nsPrintOptions::mDefaultFont = nsnull; /** --------------------------------------------------- * See documentation in nsPrintOptionsImpl.h @@ -123,7 +123,6 @@ nsPrintOptions::nsPrintOptions() : mPrintToFile(PR_FALSE), mPrintFrameType(kFramesAsIs), mHowToEnableFrameUI(kFrameEnableNone), - mPageNumJust(kJustLeft), mIsCancelled(PR_FALSE), mPrintPageDelay(500), mPrintSilent(PR_FALSE) @@ -134,18 +133,21 @@ nsPrintOptions::nsPrintOptions() : nscoord halfInch = NS_INCHES_TO_TWIPS(0.5); mMargin.SizeTo(halfInch, halfInch, halfInch, halfInch); - mPrintOptions = kOptPrintOddPages | - kOptPrintEvenPages | - kOptPrintDocTitle | - kOptPrintDocLoc | - kOptPrintPageNums | - kOptPrintPageTotal | - kOptPrintDatePrinted; + mPrintOptions = kOptPrintOddPages | kOptPrintEvenPages; - mDefaultFont = new nsFont("Times", NS_FONT_STYLE_NORMAL,NS_FONT_VARIANT_NORMAL, - NS_FONT_WEIGHT_NORMAL,0,NSIntPointsToTwips(10)); + if (mDefaultFont == nsnull) { + mDefaultFont = new nsFont("Times", NS_FONT_STYLE_NORMAL,NS_FONT_VARIANT_NORMAL, + NS_FONT_WEIGHT_NORMAL,0,NSIntPointsToTwips(10)); + } + + mHeaderStrs[0].AssignWithConversion("&T"); + mHeaderStrs[2].AssignWithConversion("&U"); + + mFooterStrs[0].AssignWithConversion("&P"); // Use &P (Page Num Only) or &PT (Page Num of Page Total) + mFooterStrs[2].AssignWithConversion("&D"); ReadPrefs(); + } /** --------------------------------------------------- @@ -156,6 +158,7 @@ nsPrintOptions::~nsPrintOptions() { if (mDefaultFont != nsnull) { delete mDefaultFont; + mDefaultFont = nsnull; } } @@ -288,13 +291,13 @@ nsPrintOptions::ReadPrefs() ReadBitFieldPref(prefs, kPrintEvenPages, kOptPrintEvenPages); ReadBitFieldPref(prefs, kPrintOddPages, kOptPrintOddPages); - ReadBitFieldPref(prefs, kPrintDocTitle, kOptPrintDocTitle); - ReadBitFieldPref(prefs, kPrintDocLoc, kOptPrintDocLoc); - ReadBitFieldPref(prefs, kPageNums, kOptPrintPageNums); - ReadBitFieldPref(prefs, kPrintPageTotals, kOptPrintPageTotal); - ReadBitFieldPref(prefs, kPrintDate, kOptPrintDatePrinted); - ReadJustification(prefs, kPageNumsJust, mPageNumJust, kJustLeft); + ReadPrefString(prefs, kPrintHeaderStr1, mHeaderStrs[0]); + ReadPrefString(prefs, kPrintHeaderStr2, mHeaderStrs[1]); + ReadPrefString(prefs, kPrintHeaderStr3, mHeaderStrs[2]); + ReadPrefString(prefs, kPrintFooterStr1, mFooterStrs[0]); + ReadPrefString(prefs, kPrintFooterStr2, mFooterStrs[1]); + ReadPrefString(prefs, kPrintFooterStr3, mFooterStrs[2]); // Read Additional XP Prefs prefs->GetBoolPref(kPrintReversed, &mPrintReversed); @@ -327,13 +330,13 @@ nsPrintOptions::WritePrefs() WriteBitFieldPref(prefs, kPrintEvenPages, kOptPrintEvenPages); WriteBitFieldPref(prefs, kPrintOddPages, kOptPrintOddPages); - WriteBitFieldPref(prefs, kPrintDocTitle, kOptPrintDocTitle); - WriteBitFieldPref(prefs, kPrintDocLoc, kOptPrintDocLoc); - WriteBitFieldPref(prefs, kPageNums, kOptPrintPageNums); - WriteBitFieldPref(prefs, kPrintPageTotals, kOptPrintPageTotal); - WriteBitFieldPref(prefs, kPrintDate, kOptPrintDatePrinted); - WriteJustification(prefs, kPageNumsJust, mPageNumJust); + WritePrefString(prefs, kPrintHeaderStr1, mHeaderStrs[0]); + WritePrefString(prefs, kPrintHeaderStr2, mHeaderStrs[1]); + WritePrefString(prefs, kPrintHeaderStr3, mHeaderStrs[2]); + WritePrefString(prefs, kPrintFooterStr1, mFooterStrs[0]); + WritePrefString(prefs, kPrintFooterStr2, mFooterStrs[1]); + WritePrefString(prefs, kPrintFooterStr3, mFooterStrs[2]); // Write Additional XP Prefs prefs->SetBoolPref(kPrintReversed, mPrintReversed); @@ -544,19 +547,6 @@ NS_IMETHODIMP nsPrintOptions::SetPrintRange(PRInt16 aPrintRange) return NS_OK; } -/* attribute long pageNumJust; */ -NS_IMETHODIMP nsPrintOptions::GetPageNumJust(PRInt16 *aPageNumJust) -{ - NS_ENSURE_ARG_POINTER(aPageNumJust); - *aPageNumJust = mPageNumJust; - return NS_OK; -} -NS_IMETHODIMP nsPrintOptions::SetPageNumJust(PRInt16 aPageNumJust) -{ - mPageNumJust = aPageNumJust; - return NS_OK; -} - /* attribute wstring docTitle; */ NS_IMETHODIMP nsPrintOptions::GetTitle(PRUnichar * *aTitle) { @@ -585,6 +575,114 @@ NS_IMETHODIMP nsPrintOptions::SetDocURL(const PRUnichar * aDocURL) return NS_OK; } +/* attribute wstring docTitle; */ +nsresult +nsPrintOptions::GetMarginStrs(PRUnichar * *aTitle, + nsHeaderFooterEnum aType, + PRInt16 aJust) +{ + NS_ENSURE_ARG_POINTER(aTitle); + *aTitle = nsnull; + if (aType == eHeader) { + switch (aJust) { + case kJustLeft: *aTitle = mHeaderStrs[0].ToNewUnicode();break; + case kJustCenter: *aTitle = mHeaderStrs[1].ToNewUnicode();break; + case kJustRight: *aTitle = mHeaderStrs[2].ToNewUnicode();break; + } //switch + } else { + switch (aJust) { + case kJustLeft: *aTitle = mFooterStrs[0].ToNewUnicode();break; + case kJustCenter: *aTitle = mFooterStrs[1].ToNewUnicode();break; + case kJustRight: *aTitle = mFooterStrs[2].ToNewUnicode();break; + } //switch + } + return NS_OK; +} + +nsresult +nsPrintOptions::SetMarginStrs(const PRUnichar * aTitle, + nsHeaderFooterEnum aType, + PRInt16 aJust) +{ + NS_ENSURE_ARG_POINTER(aTitle); + if (aType == eHeader) { + switch (aJust) { + case kJustLeft: mHeaderStrs[0] = aTitle;break; + case kJustCenter: mHeaderStrs[1] = aTitle;break; + case kJustRight: mHeaderStrs[2] = aTitle;break; + } //switch + } else { + switch (aJust) { + case kJustLeft: mFooterStrs[0] = aTitle;break; + case kJustCenter: mFooterStrs[1] = aTitle;break; + case kJustRight: mFooterStrs[2] = aTitle;break; + } //switch + } + return NS_OK; +} + +/* attribute wstring Header String Left */ +NS_IMETHODIMP nsPrintOptions::GetHeaderStrLeft(PRUnichar * *aTitle) +{ + return GetMarginStrs(aTitle, eHeader, kJustLeft); +} +NS_IMETHODIMP nsPrintOptions::SetHeaderStrLeft(const PRUnichar * aTitle) +{ + return SetMarginStrs(aTitle, eHeader, kJustLeft); +} + +/* attribute wstring Header String Center */ +NS_IMETHODIMP nsPrintOptions::GetHeaderStrCenter(PRUnichar * *aTitle) +{ + return GetMarginStrs(aTitle, eHeader, kJustCenter); +} +NS_IMETHODIMP nsPrintOptions::SetHeaderStrCenter(const PRUnichar * aTitle) +{ + return SetMarginStrs(aTitle, eHeader, kJustCenter); +} + +/* attribute wstring Header String Right */ +NS_IMETHODIMP nsPrintOptions::GetHeaderStrRight(PRUnichar * *aTitle) +{ + return GetMarginStrs(aTitle, eHeader, kJustRight); +} +NS_IMETHODIMP nsPrintOptions::SetHeaderStrRight(const PRUnichar * aTitle) +{ + return SetMarginStrs(aTitle, eHeader, kJustRight); +} + + +/* attribute wstring Footer String Left */ +NS_IMETHODIMP nsPrintOptions::GetFooterStrLeft(PRUnichar * *aTitle) +{ + return GetMarginStrs(aTitle, eFooter, kJustLeft); +} +NS_IMETHODIMP nsPrintOptions::SetFooterStrLeft(const PRUnichar * aTitle) +{ + return SetMarginStrs(aTitle, eFooter, kJustLeft); +} + +/* attribute wstring Footer String Center */ +NS_IMETHODIMP nsPrintOptions::GetFooterStrCenter(PRUnichar * *aTitle) +{ + return GetMarginStrs(aTitle, eFooter, kJustCenter); +} +NS_IMETHODIMP nsPrintOptions::SetFooterStrCenter(const PRUnichar * aTitle) +{ + return SetMarginStrs(aTitle, eFooter, kJustCenter); +} + +/* attribute wstring Footer String Right */ +NS_IMETHODIMP nsPrintOptions::GetFooterStrRight(PRUnichar * *aTitle) +{ + return GetMarginStrs(aTitle, eFooter, kJustRight); +} +NS_IMETHODIMP nsPrintOptions::SetFooterStrRight(const PRUnichar * aTitle) +{ + return SetMarginStrs(aTitle, eFooter, kJustRight); +} + + /* attribute boolean isPrintFrame; */ NS_IMETHODIMP nsPrintOptions::GetHowToEnableFrameUI(PRInt16 *aHowToEnableFrameUI) { diff --git a/mozilla/gfx/src/nsPrintOptionsImpl.h b/mozilla/gfx/src/nsPrintOptionsImpl.h index 4bbed4a04d9..151e13b527e 100644 --- a/mozilla/gfx/src/nsPrintOptionsImpl.h +++ b/mozilla/gfx/src/nsPrintOptionsImpl.h @@ -50,6 +50,14 @@ protected: nsresult ReadPrefString(nsIPref * aPref, const char * aPrefId, nsString& aString); nsresult WritePrefString(nsIPref * aPref, const char * aPrefId, nsString& aString); + typedef enum { + eHeader, + eFooter + } nsHeaderFooterEnum; + + nsresult GetMarginStrs(PRUnichar * *aTitle, nsHeaderFooterEnum aType, PRInt16 aJust); + nsresult SetMarginStrs(const PRUnichar * aTitle, nsHeaderFooterEnum aType, PRInt16 aJust); + // Members nsMargin mMargin; PRInt32 mPrintOptions; @@ -58,7 +66,6 @@ protected: PRInt16 mPrintRange; PRInt32 mStartPageNum; // only used for ePrintRange_SpecifiedRange PRInt32 mEndPageNum; - PRInt16 mPageNumJust; PRInt16 mPrintFrameType; PRBool mHowToEnableFrameUI; @@ -66,9 +73,11 @@ protected: PRBool mPrintSilent; PRInt32 mPrintPageDelay; - nsFont* mDefaultFont; nsString mTitle; nsString mURL; + nsString mPageNumberFormat; + nsString mHeaderStrs[3]; + nsString mFooterStrs[3]; PRBool mPrintReversed; PRBool mPrintInColor; // a false means grayscale @@ -78,6 +87,7 @@ protected: PRBool mPrintToFile; nsString mToFileName; + static nsFont* mDefaultFont; }; diff --git a/mozilla/layout/generic/nsPageFrame.cpp b/mozilla/layout/generic/nsPageFrame.cpp index f011f41daa9..5a4fe37a4ca 100644 --- a/mozilla/layout/generic/nsPageFrame.cpp +++ b/mozilla/layout/generic/nsPageFrame.cpp @@ -36,22 +36,20 @@ // 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 +// Print Options +#include "nsIPrintOptions.h" +#include "nsGfxCIID.h" +#include "nsIServiceManager.h" +static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID); + +// static data members +PRUnichar * nsPageFrame::mDateTimeStr = nsnull; +nsFont * nsPageFrame::mHeadFootFont = nsnull; PRUnichar * nsPageFrame::mPageNumFormat = nsnull; +PRUnichar * nsPageFrame::mPageNumAndTotalsFormat = nsnull; #if defined(DEBUG_rods) || defined(DEBUG_dcone) #define DEBUG_PRINTING @@ -87,7 +85,6 @@ NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) } nsPageFrame::nsPageFrame() : - mHeadFootFont(nsnull), mSupressHF(PR_FALSE), mClipRect(-1, -1, -1, -1) @@ -95,17 +92,38 @@ nsPageFrame::nsPageFrame() : #ifdef NS_DEBUG mDebugFD = stdout; #endif + nsresult rv; + mPrintOptions = do_GetService(kPrintOptionsCID, &rv); + + if (mHeadFootFont == nsnull) { + 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); } nsPageFrame::~nsPageFrame() { - if (mHeadFootFont) + if (mHeadFootFont != nsnull) { delete mHeadFootFont; + mHeadFootFont = nsnull; + } + + if (mDateTimeStr) { + nsMemory::Free(mDateTimeStr); + mDateTimeStr = nsnull; + } if (mPageNumFormat) { nsMemory::Free(mPageNumFormat); mPageNumFormat = nsnull; } + + if (mPageNumAndTotalsFormat) { + nsMemory::Free(mPageNumAndTotalsFormat); + mPageNumAndTotalsFormat = nsnull; + } } NS_METHOD nsPageFrame::Reflow(nsIPresContext* aPresContext, @@ -235,6 +253,116 @@ nsPageFrame::IsPercentageBase(PRBool& aBase) const return NS_OK; } +//------------------------------------------------------------------------------ +// helper function for converting from char * to unichar +static PRUnichar * +GetUStr(const char * aCStr) +{ + nsAutoString str; + str.AssignWithConversion(aCStr); + return str.ToNewUnicode(); +} + +// replace the & with the value, but if the value is empty +// set the string to zero length +static void +SubstValueForCode(nsString& aStr, const PRUnichar * aUKey, const PRUnichar * aUStr) +{ + nsAutoString str; + str = aUStr; + if (str.Length() == 0) { + aStr.SetLength(0); + } else { + aStr.ReplaceSubstring(aUKey, aUStr); + } +} +// done with static helper functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +void +nsPageFrame::ProcessSpecialCodes(const nsString& aStr, nsString& aNewStr) +{ + + aNewStr = aStr; + + // Search to see if the &D code is in the string + // then subst in the current date/time + PRUnichar * kDate = GetUStr("&D"); + if (kDate != nsnull) { + if (aStr.Find(kDate) > -1) { + if (mDateTimeStr != nsnull) { + aNewStr.ReplaceSubstring(kDate, mDateTimeStr); + } else { + nsAutoString empty; + PRUnichar * uEmpty = empty.ToNewUnicode(); + aNewStr.ReplaceSubstring(kDate, uEmpty); + nsMemory::Free(uEmpty); + } + nsMemory::Free(kDate); + return; + } + nsMemory::Free(kDate); + } + + // NOTE: Must search for &PT before searching for &P + // + // Search to see if the "page number and page" total code are in the string + // and replace the page number and page total code with the actual values + PRUnichar * kPage = GetUStr("&PT"); + if (kPage != nsnull) { + if (aStr.Find(kPage) > -1) { + PRUnichar * uStr = nsTextFormatter::smprintf(mPageNumAndTotalsFormat, mPageNum, mTotNumPages); + aNewStr.ReplaceSubstring(kPage, uStr); + nsMemory::Free(uStr); + nsMemory::Free(kPage); + return; + } + nsMemory::Free(kPage); + } + + // Search to see if the page number code is in the string + // and replace the page number code with the actual values + kPage = GetUStr("&P"); + if (kPage != nsnull) { + if (aStr.Find(kPage) > -1) { + PRUnichar * uStr = nsTextFormatter::smprintf(mPageNumFormat, mPageNum); + aNewStr.ReplaceSubstring(kPage, uStr); + nsMemory::Free(uStr); + nsMemory::Free(kPage); + return; + } + nsMemory::Free(kPage); + } + + PRUnichar * kTitle = GetUStr("&T"); + if (kTitle != nsnull) { + if (aStr.Find(kTitle) > -1) { + PRUnichar * uTitle; + mPrintOptions->GetTitle(&uTitle); // creates memory + SubstValueForCode(aNewStr, kTitle, uTitle); + nsMemory::Free(uTitle); + nsMemory::Free(kTitle); + return; + } + nsMemory::Free(kTitle); + } + + PRUnichar * kDocURL = GetUStr("&U"); + if (kDocURL != nsnull) { + if (aStr.Find(kDocURL) > -1) { + PRUnichar * uDocURL; + mPrintOptions->GetDocURL(&uDocURL); // creates memory + SubstValueForCode(aNewStr, kDocURL, uDocURL); + nsMemory::Free(uDocURL); + nsMemory::Free(kDocURL); + return; + } + nsMemory::Free(kDocURL); + } +} + + //------------------------------------------------------------------------------ nscoord nsPageFrame::GetXPosition(nsIRenderingContext& aRenderingContext, const nsRect& aRect, @@ -273,6 +401,45 @@ nscoord nsPageFrame::GetXPosition(nsIRenderingContext& aRenderingContext, // @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& aStr1, + const nsString& aStr2, + const nsString& aStr3, + const nsRect& aRect, + nscoord aHeight) +{ + PRInt32 numStrs = 0; + if (!aStr1.IsEmpty()) numStrs++; + if (!aStr2.IsEmpty()) numStrs++; + if (!aStr3.IsEmpty()) numStrs++; + + nscoord strSpace = aRect.width / numStrs; + if (numStrs == 0) return; + + if (!aStr1.IsEmpty()) { + DrawHeaderFooter(aRenderingContext, aFrame, aHeaderFooter, nsIPrintOptions::kJustLeft, aStr1, aRect, aHeight, strSpace); + } + if (!aStr2.IsEmpty()) { + DrawHeaderFooter(aRenderingContext, aFrame, aHeaderFooter, nsIPrintOptions::kJustCenter, aStr2, aRect, aHeight, strSpace); + } + if (!aStr3.IsEmpty()) { + DrawHeaderFooter(aRenderingContext, aFrame, aHeaderFooter, nsIPrintOptions::kJustRight, aStr3, aRect, aHeight, strSpace); + } +} + +//------------------------------------------------------------------------------ +// 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 aWidth - available width for any one of the strings +void nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext, nsIFrame * aFrame, nsHeaderFooterEnum aHeaderFooter, @@ -280,7 +447,7 @@ nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext, const nsString& aStr, const nsRect& aRect, nscoord aHeight, - PRBool aUseHalfThePage) + nscoord aWidth) { // first make sure we have a vaild string and that the height of the @@ -289,16 +456,15 @@ nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext, ((aHeaderFooter == eHeader && aHeight < mMargin.top) || (aHeaderFooter == eFooter && aHeight < mMargin.bottom))) { // measure the width of the text - nsString str = aStr; + nsAutoString str; + ProcessSpecialCodes(aStr, str); + 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) { + while (width >= aWidth && str.Length() > 1) { str.SetLength(str.Length()-1); aRenderingContext.GetWidth(str, width); addEllipse = PR_TRUE; @@ -347,8 +513,7 @@ nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext, PRINT_DEBUG_MSG2(" HF: %s ", aHeaderFooter==eHeader?"Header":"Footer"); PRINT_DEBUG_MSG2(" JST: %s ", justStr); PRINT_DEBUG_MSG3(" x,y: %d,%d", x, y); - PRINT_DEBUG_MSG2(" Hgt: %d ", aHeight); - PRINT_DEBUG_MSG2(" Half: %s\n", aUseHalfThePage?"Yes":"No"); + PRINT_DEBUG_MSG2(" Hgt: %d \n", aHeight); #endif } } @@ -362,6 +527,9 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, PRUint32 aFlags) { aRenderingContext.PushState(); + aRenderingContext.SetColor(NS_RGB(255,255,255)); + + nsRect rect; PRBool clipEmpty; if (mClipRect.width != -1 || mClipRect.height != -1) { #ifdef DEBUG_PRINTING @@ -372,6 +540,16 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, mClipRect.x = 0; mClipRect.y = 0; aRenderingContext.SetClipRect(mClipRect, nsClipCombine_kReplace, clipEmpty); + rect = mClipRect; + } else { + rect = mRect; + } + + if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { + aRenderingContext.SetColor(NS_RGB(255,255,255)); + rect.x = 0; + rect.y = 0; + aRenderingContext.FillRect(rect); } nsresult rv = nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); @@ -388,7 +566,7 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, // get the current margin mPrintOptions->GetMarginInTwips(mMargin); - nsRect rect(0,0,mRect.width, mRect.height); + 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 @@ -401,10 +579,11 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, rect.Inflate(NSToCoordRound(p2t), NSToCoordRound(p2t)); fprintf(mDebugFD, "PageFr::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)); @@ -419,76 +598,25 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, 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 document headers and footers + PRUnichar * headers[3]; + mPrintOptions->GetHeaderStrLeft(&headers[0]); // creates memory + mPrintOptions->GetHeaderStrCenter(&headers[1]); // creates memory + mPrintOptions->GetHeaderStrRight(&headers[2]); // creates memory + DrawHeaderFooter(aRenderingContext, this, eHeader, nsIPrintOptions::kJustLeft, + nsAutoString(headers[0]), nsAutoString(headers[1]), nsAutoString(headers[2]), + rect, visibleHeight); + PRInt32 i; + for (i=0;i<3;i++) nsMemory::Free(headers[i]); - // print page numbers - if (printOptBits & nsIPrintOptions::kOptPrintPageNums && mPageNumFormat != nsnull) { - PRInt16 justify = nsIPrintOptions::kJustLeft; - mPrintOptions->GetPageNumJust(&justify); - - PRUnichar * valStr; - // print page number totals "x of x" - if (printOptBits & nsIPrintOptions::kOptPrintPageTotal) { - 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 & nsIPrintOptions::kOptPrintDatePrinted) { - // Get Locale for Formating DateTime - nsCOMPtr locale; - nsCOMPtr localeSvc = - do_GetService(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->FormatTime(locale, kDateFormatShort, kTimeFormatNoSeconds, ltime, dateString); - if (NS_SUCCEEDED(rv)) { - DrawHeaderFooter(aRenderingContext, this, eFooter, nsIPrintOptions::kJustRight, dateString, rect, visibleHeight); - } - } - } - } - } - - - PRBool usingHalfThePage = (printOptBits & nsIPrintOptions::kOptPrintDocTitle) && - (printOptBits & nsIPrintOptions::kOptPrintDocLoc); - - // print document title - PRUnichar * title; - mPrintOptions->GetTitle(&title); // creates memory - if (title != nsnull && (printOptBits & nsIPrintOptions::kOptPrintDocTitle)) { - DrawHeaderFooter(aRenderingContext, this, eHeader, nsIPrintOptions::kJustLeft, nsAutoString(title), rect, visibleHeight, usingHalfThePage); - nsMemory::Free(title); - } - - // print document URL - PRUnichar * url; - mPrintOptions->GetDocURL(&url); - if ((nsnull != url) && (printOptBits & nsIPrintOptions::kOptPrintDocLoc)) { - DrawHeaderFooter(aRenderingContext, this, eHeader, nsIPrintOptions::kJustRight, nsAutoString(url), rect, visibleHeight, usingHalfThePage); - nsMemory::Free(url); - } + PRUnichar * footers[3]; + mPrintOptions->GetFooterStrLeft(&footers[0]); // creates memory + mPrintOptions->GetFooterStrCenter(&footers[1]); // creates memory + mPrintOptions->GetFooterStrRight(&footers[2]); // creates memory + DrawHeaderFooter(aRenderingContext, this, eFooter, nsIPrintOptions::kJustRight, + nsAutoString(footers[0]), nsAutoString(footers[1]), nsAutoString(footers[2]), + rect, visibleHeight); + for (i=0;i<3;i++) nsMemory::Free(footers[i]); } @@ -521,12 +649,31 @@ nsPageFrame::SetPageNumInfo(PRInt32 aPageNumber, PRInt32 aTotalPages) //------------------------------------------------------------------------------ void -nsPageFrame::SetPageNumberFormat(PRUnichar * aFormatStr) +nsPageFrame::SetPageNumberFormat(PRUnichar * aFormatStr, PRBool aForPageNumOnly) { NS_ASSERTION(aFormatStr != nsnull, "Format string cannot be null!"); - if (mPageNumFormat != nsnull) { - nsMemory::Free(mPageNumFormat); + if (aForPageNumOnly) { + if (mPageNumFormat != nsnull) { + nsMemory::Free(mPageNumFormat); + } + mPageNumFormat = aFormatStr; + } else { + if (mPageNumAndTotalsFormat != nsnull) { + nsMemory::Free(mPageNumAndTotalsFormat); + } + mPageNumAndTotalsFormat = aFormatStr; } - mPageNumFormat = aFormatStr; +} + +//------------------------------------------------------------------------------ +void +nsPageFrame::SetDateTimeStr(PRUnichar * aDateTimeStr) +{ + NS_ASSERTION(aDateTimeStr != nsnull, "DateTime string cannot be null!"); + + if (mDateTimeStr != nsnull) { + nsMemory::Free(mDateTimeStr); + } + mDateTimeStr = aDateTimeStr; } diff --git a/mozilla/layout/generic/nsPageFrame.h b/mozilla/layout/generic/nsPageFrame.h index 9f5be457fa7..8e19aaaf442 100644 --- a/mozilla/layout/generic/nsPageFrame.h +++ b/mozilla/layout/generic/nsPageFrame.h @@ -71,8 +71,10 @@ public: virtual void SuppressHeadersAndFooters(PRBool aDoSup) { mSupressHF = aDoSup; } virtual void SetClipRect(nsRect* aClipRect) { mClipRect = *aClipRect; } + static void SetDateTimeStr(PRUnichar * aDateTimeStr); + // This is class is now responsible for freeing the memory - static void SetPageNumberFormat(PRUnichar * aFormatStr); + static void SetPageNumberFormat(PRUnichar * aFormatStr, PRBool aForPageNumOnly); protected: nsPageFrame(); @@ -95,19 +97,32 @@ protected: const nsString& sStr, const nsRect& aRect, nscoord aHeight, - PRBool aUseHalfThePage = PR_TRUE); + nscoord aWidth); + void DrawHeaderFooter(nsIRenderingContext& aRenderingContext, + nsIFrame * aFrame, + nsHeaderFooterEnum aHeaderFooter, + PRInt32 aJust, + const nsString& aStr1, + const nsString& aStr2, + const nsString& aStr3, + const nsRect& aRect, + nscoord aHeight); + + void ProcessSpecialCodes(const nsString& aStr, nsString& aNewStr); nsCOMPtr mPrintOptions; PRInt32 mPageNum; PRInt32 mTotNumPages; nsMargin mMargin; - nsFont * mHeadFootFont; PRPackedBool mSupressHF; nsRect mClipRect; + static PRUnichar * mDateTimeStr; + static nsFont * mHeadFootFont; static PRUnichar * mPageNumFormat; + static PRUnichar * mPageNumAndTotalsFormat; }; diff --git a/mozilla/layout/generic/nsSimplePageSequence.cpp b/mozilla/layout/generic/nsSimplePageSequence.cpp index efa5d4f5b25..c295f0ccb15 100644 --- a/mozilla/layout/generic/nsSimplePageSequence.cpp +++ b/mozilla/layout/generic/nsSimplePageSequence.cpp @@ -35,6 +35,16 @@ #include "nsIPrintOptions.h" #include "nsPageFrame.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); + #define OFFSET_NOT_SET -1 // This is for localization of the "x of n" pages string @@ -364,6 +374,7 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, kidReflowState.mComputedWidth = kidReflowState.availableWidth; //kidReflowState.mComputedHeight = kidReflowState.availableHeight; + PRINT_DEBUG_MSG3("AV W: %d H: %d\n", kidReflowState.availableWidth, kidReflowState.availableHeight); // Place and size the page. If the page is narrower than our // max width then center it horizontally @@ -403,6 +414,49 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, // Get the next page kidFrame->GetNextSibling(&kidFrame); } + + // Get Total Page Count + nsIFrame* page; + PRInt32 pageTot = 0; + for (page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) { + pageTot++; + } + + // Set Page Number Info + PRInt32 pageNum = 1; + for (page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) { + nsPageFrame * pf = NS_STATIC_CAST(nsPageFrame*, page); + if (pf != nsnull) { + //pf->SetPrintOptions(aPrintOptions); + pf->SetPageNumInfo(pageNum, pageTot); + } + pageNum++; + } + + // Create current Date/Time String + nsresult rv; + nsCOMPtr locale; + nsCOMPtr localeSvc = do_GetService(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 ); + if (NS_SUCCEEDED(dateTime->FormatTime(locale, kDateFormatShort, kTimeFormatNoSeconds, ltime, dateString))) { + PRUnichar * uStr = dateString.ToNewUnicode(); + nsPageFrame::SetDateTimeStr(uStr); // nsPageFrame will own memory + } + } + } + } + } // Return our desired size @@ -501,6 +555,30 @@ nsSimplePageSequenceFrame::GetPrintRange(PRInt32* aFromPage, PRInt32* aToPage) return NS_OK; } +// Helper Function +void +nsSimplePageSequenceFrame::SetPageNumberFormat(const char* aPropName, const char* aDefPropVal, PRBool aPageNumOnly) +{ + // Doing this here so we only have to go get these formats once + nsAutoString pageNumberFormat; + // Now go get the Localized Page Formating String + nsAutoString propName; + propName.AssignWithConversion(aPropName); + PRUnichar* uPropName = propName.ToNewUnicode(); + if (uPropName != nsnull) { + nsresult rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, uPropName, pageNumberFormat); + if (NS_FAILED(rv)) { // back stop formatting + pageNumberFormat.AssignWithConversion(aDefPropVal); + } + nsMemory::Free(uPropName); + } + // Sets the format into a static data memeber which will own the memory and free it + PRUnichar* uStr = pageNumberFormat.ToNewUnicode(); + if (uStr != nsnull) { + nsPageFrame::SetPageNumberFormat(uStr, aPageNumOnly); // nsPageFrame will own the memory + } + +} NS_IMETHODIMP nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext, @@ -649,19 +727,9 @@ nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext, } aPrintOptions->SetFontNamePointSize(fontName, pointSize); - // Now go get the Localized Page Formating String - PRBool doingPageTotals = PR_TRUE; - aPrintOptions->GetPrintOptions(nsIPrintOptions::kOptPrintPageTotal, &doingPageTotals); - - nsAutoString pageFormatStr; - rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, - doingPageTotals? NS_LITERAL_STRING("pageofpages").get():NS_LITERAL_STRING("pagenumber").get(), - 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()); + // Doing this here so we only have to go get these formats once + SetPageNumberFormat("pagenumber", "%1$d", PR_TRUE); + SetPageNumberFormat("pageofpages", "%1$d of %2$d", PR_FALSE); mPageNum = 1; mPrintedPageNum = 1; @@ -870,3 +938,29 @@ nsSimplePageSequenceFrame::SetDebugFD(FILE* aFD) return NS_OK; } #endif + +//------------------------------------------------------------------------------ +NS_IMETHODIMP +nsSimplePageSequenceFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + aRenderingContext.PushState(); + aRenderingContext.SetColor(NS_RGB(255,255,255)); + + + if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { + nsRect rect = mRect; + aRenderingContext.SetColor(NS_RGB(255,255,255)); + rect.x = 0; + rect.y = 0; + aRenderingContext.FillRect(rect); + } + + nsresult rv = nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + + PRBool clipEmpty; + aRenderingContext.PopState(clipEmpty); + return rv; +} diff --git a/mozilla/layout/generic/nsSimplePageSequence.h b/mozilla/layout/generic/nsSimplePageSequence.h index b4988dd4ba1..703a160f10c 100644 --- a/mozilla/layout/generic/nsSimplePageSequence.h +++ b/mozilla/layout/generic/nsSimplePageSequence.h @@ -41,6 +41,11 @@ public: const nsHTMLReflowState& aMaxSize, nsReflowStatus& aStatus); + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + // nsIPageSequenceFrame NS_IMETHOD Print(nsIPresContext* aPresContext, nsIPrintOptions* aPrintOptions, @@ -85,6 +90,9 @@ protected: nsresult CreateContinuingPageFrame(nsIPresContext* aPresContext, nsIFrame* aPageFrame, nsIFrame** aContinuingFrame); + + void SetPageNumberFormat(const char* aPropName, const char* aDefPropVal, PRBool aPageNumOnly); + NS_IMETHOD_(nsrefcnt) AddRef(void) {return nsContainerFrame::AddRef();} NS_IMETHOD_(nsrefcnt) Release(void) {return nsContainerFrame::Release();} diff --git a/mozilla/layout/html/base/src/nsPageFrame.cpp b/mozilla/layout/html/base/src/nsPageFrame.cpp index f011f41daa9..5a4fe37a4ca 100644 --- a/mozilla/layout/html/base/src/nsPageFrame.cpp +++ b/mozilla/layout/html/base/src/nsPageFrame.cpp @@ -36,22 +36,20 @@ // 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 +// Print Options +#include "nsIPrintOptions.h" +#include "nsGfxCIID.h" +#include "nsIServiceManager.h" +static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID); + +// static data members +PRUnichar * nsPageFrame::mDateTimeStr = nsnull; +nsFont * nsPageFrame::mHeadFootFont = nsnull; PRUnichar * nsPageFrame::mPageNumFormat = nsnull; +PRUnichar * nsPageFrame::mPageNumAndTotalsFormat = nsnull; #if defined(DEBUG_rods) || defined(DEBUG_dcone) #define DEBUG_PRINTING @@ -87,7 +85,6 @@ NS_NewPageFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) } nsPageFrame::nsPageFrame() : - mHeadFootFont(nsnull), mSupressHF(PR_FALSE), mClipRect(-1, -1, -1, -1) @@ -95,17 +92,38 @@ nsPageFrame::nsPageFrame() : #ifdef NS_DEBUG mDebugFD = stdout; #endif + nsresult rv; + mPrintOptions = do_GetService(kPrintOptionsCID, &rv); + + if (mHeadFootFont == nsnull) { + 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); } nsPageFrame::~nsPageFrame() { - if (mHeadFootFont) + if (mHeadFootFont != nsnull) { delete mHeadFootFont; + mHeadFootFont = nsnull; + } + + if (mDateTimeStr) { + nsMemory::Free(mDateTimeStr); + mDateTimeStr = nsnull; + } if (mPageNumFormat) { nsMemory::Free(mPageNumFormat); mPageNumFormat = nsnull; } + + if (mPageNumAndTotalsFormat) { + nsMemory::Free(mPageNumAndTotalsFormat); + mPageNumAndTotalsFormat = nsnull; + } } NS_METHOD nsPageFrame::Reflow(nsIPresContext* aPresContext, @@ -235,6 +253,116 @@ nsPageFrame::IsPercentageBase(PRBool& aBase) const return NS_OK; } +//------------------------------------------------------------------------------ +// helper function for converting from char * to unichar +static PRUnichar * +GetUStr(const char * aCStr) +{ + nsAutoString str; + str.AssignWithConversion(aCStr); + return str.ToNewUnicode(); +} + +// replace the & with the value, but if the value is empty +// set the string to zero length +static void +SubstValueForCode(nsString& aStr, const PRUnichar * aUKey, const PRUnichar * aUStr) +{ + nsAutoString str; + str = aUStr; + if (str.Length() == 0) { + aStr.SetLength(0); + } else { + aStr.ReplaceSubstring(aUKey, aUStr); + } +} +// done with static helper functions +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +void +nsPageFrame::ProcessSpecialCodes(const nsString& aStr, nsString& aNewStr) +{ + + aNewStr = aStr; + + // Search to see if the &D code is in the string + // then subst in the current date/time + PRUnichar * kDate = GetUStr("&D"); + if (kDate != nsnull) { + if (aStr.Find(kDate) > -1) { + if (mDateTimeStr != nsnull) { + aNewStr.ReplaceSubstring(kDate, mDateTimeStr); + } else { + nsAutoString empty; + PRUnichar * uEmpty = empty.ToNewUnicode(); + aNewStr.ReplaceSubstring(kDate, uEmpty); + nsMemory::Free(uEmpty); + } + nsMemory::Free(kDate); + return; + } + nsMemory::Free(kDate); + } + + // NOTE: Must search for &PT before searching for &P + // + // Search to see if the "page number and page" total code are in the string + // and replace the page number and page total code with the actual values + PRUnichar * kPage = GetUStr("&PT"); + if (kPage != nsnull) { + if (aStr.Find(kPage) > -1) { + PRUnichar * uStr = nsTextFormatter::smprintf(mPageNumAndTotalsFormat, mPageNum, mTotNumPages); + aNewStr.ReplaceSubstring(kPage, uStr); + nsMemory::Free(uStr); + nsMemory::Free(kPage); + return; + } + nsMemory::Free(kPage); + } + + // Search to see if the page number code is in the string + // and replace the page number code with the actual values + kPage = GetUStr("&P"); + if (kPage != nsnull) { + if (aStr.Find(kPage) > -1) { + PRUnichar * uStr = nsTextFormatter::smprintf(mPageNumFormat, mPageNum); + aNewStr.ReplaceSubstring(kPage, uStr); + nsMemory::Free(uStr); + nsMemory::Free(kPage); + return; + } + nsMemory::Free(kPage); + } + + PRUnichar * kTitle = GetUStr("&T"); + if (kTitle != nsnull) { + if (aStr.Find(kTitle) > -1) { + PRUnichar * uTitle; + mPrintOptions->GetTitle(&uTitle); // creates memory + SubstValueForCode(aNewStr, kTitle, uTitle); + nsMemory::Free(uTitle); + nsMemory::Free(kTitle); + return; + } + nsMemory::Free(kTitle); + } + + PRUnichar * kDocURL = GetUStr("&U"); + if (kDocURL != nsnull) { + if (aStr.Find(kDocURL) > -1) { + PRUnichar * uDocURL; + mPrintOptions->GetDocURL(&uDocURL); // creates memory + SubstValueForCode(aNewStr, kDocURL, uDocURL); + nsMemory::Free(uDocURL); + nsMemory::Free(kDocURL); + return; + } + nsMemory::Free(kDocURL); + } +} + + //------------------------------------------------------------------------------ nscoord nsPageFrame::GetXPosition(nsIRenderingContext& aRenderingContext, const nsRect& aRect, @@ -273,6 +401,45 @@ nscoord nsPageFrame::GetXPosition(nsIRenderingContext& aRenderingContext, // @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& aStr1, + const nsString& aStr2, + const nsString& aStr3, + const nsRect& aRect, + nscoord aHeight) +{ + PRInt32 numStrs = 0; + if (!aStr1.IsEmpty()) numStrs++; + if (!aStr2.IsEmpty()) numStrs++; + if (!aStr3.IsEmpty()) numStrs++; + + nscoord strSpace = aRect.width / numStrs; + if (numStrs == 0) return; + + if (!aStr1.IsEmpty()) { + DrawHeaderFooter(aRenderingContext, aFrame, aHeaderFooter, nsIPrintOptions::kJustLeft, aStr1, aRect, aHeight, strSpace); + } + if (!aStr2.IsEmpty()) { + DrawHeaderFooter(aRenderingContext, aFrame, aHeaderFooter, nsIPrintOptions::kJustCenter, aStr2, aRect, aHeight, strSpace); + } + if (!aStr3.IsEmpty()) { + DrawHeaderFooter(aRenderingContext, aFrame, aHeaderFooter, nsIPrintOptions::kJustRight, aStr3, aRect, aHeight, strSpace); + } +} + +//------------------------------------------------------------------------------ +// 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 aWidth - available width for any one of the strings +void nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext, nsIFrame * aFrame, nsHeaderFooterEnum aHeaderFooter, @@ -280,7 +447,7 @@ nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext, const nsString& aStr, const nsRect& aRect, nscoord aHeight, - PRBool aUseHalfThePage) + nscoord aWidth) { // first make sure we have a vaild string and that the height of the @@ -289,16 +456,15 @@ nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext, ((aHeaderFooter == eHeader && aHeight < mMargin.top) || (aHeaderFooter == eFooter && aHeight < mMargin.bottom))) { // measure the width of the text - nsString str = aStr; + nsAutoString str; + ProcessSpecialCodes(aStr, str); + 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) { + while (width >= aWidth && str.Length() > 1) { str.SetLength(str.Length()-1); aRenderingContext.GetWidth(str, width); addEllipse = PR_TRUE; @@ -347,8 +513,7 @@ nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext, PRINT_DEBUG_MSG2(" HF: %s ", aHeaderFooter==eHeader?"Header":"Footer"); PRINT_DEBUG_MSG2(" JST: %s ", justStr); PRINT_DEBUG_MSG3(" x,y: %d,%d", x, y); - PRINT_DEBUG_MSG2(" Hgt: %d ", aHeight); - PRINT_DEBUG_MSG2(" Half: %s\n", aUseHalfThePage?"Yes":"No"); + PRINT_DEBUG_MSG2(" Hgt: %d \n", aHeight); #endif } } @@ -362,6 +527,9 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, PRUint32 aFlags) { aRenderingContext.PushState(); + aRenderingContext.SetColor(NS_RGB(255,255,255)); + + nsRect rect; PRBool clipEmpty; if (mClipRect.width != -1 || mClipRect.height != -1) { #ifdef DEBUG_PRINTING @@ -372,6 +540,16 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, mClipRect.x = 0; mClipRect.y = 0; aRenderingContext.SetClipRect(mClipRect, nsClipCombine_kReplace, clipEmpty); + rect = mClipRect; + } else { + rect = mRect; + } + + if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { + aRenderingContext.SetColor(NS_RGB(255,255,255)); + rect.x = 0; + rect.y = 0; + aRenderingContext.FillRect(rect); } nsresult rv = nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); @@ -388,7 +566,7 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, // get the current margin mPrintOptions->GetMarginInTwips(mMargin); - nsRect rect(0,0,mRect.width, mRect.height); + 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 @@ -401,10 +579,11 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, rect.Inflate(NSToCoordRound(p2t), NSToCoordRound(p2t)); fprintf(mDebugFD, "PageFr::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)); @@ -419,76 +598,25 @@ nsPageFrame::Paint(nsIPresContext* aPresContext, 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 document headers and footers + PRUnichar * headers[3]; + mPrintOptions->GetHeaderStrLeft(&headers[0]); // creates memory + mPrintOptions->GetHeaderStrCenter(&headers[1]); // creates memory + mPrintOptions->GetHeaderStrRight(&headers[2]); // creates memory + DrawHeaderFooter(aRenderingContext, this, eHeader, nsIPrintOptions::kJustLeft, + nsAutoString(headers[0]), nsAutoString(headers[1]), nsAutoString(headers[2]), + rect, visibleHeight); + PRInt32 i; + for (i=0;i<3;i++) nsMemory::Free(headers[i]); - // print page numbers - if (printOptBits & nsIPrintOptions::kOptPrintPageNums && mPageNumFormat != nsnull) { - PRInt16 justify = nsIPrintOptions::kJustLeft; - mPrintOptions->GetPageNumJust(&justify); - - PRUnichar * valStr; - // print page number totals "x of x" - if (printOptBits & nsIPrintOptions::kOptPrintPageTotal) { - 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 & nsIPrintOptions::kOptPrintDatePrinted) { - // Get Locale for Formating DateTime - nsCOMPtr locale; - nsCOMPtr localeSvc = - do_GetService(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->FormatTime(locale, kDateFormatShort, kTimeFormatNoSeconds, ltime, dateString); - if (NS_SUCCEEDED(rv)) { - DrawHeaderFooter(aRenderingContext, this, eFooter, nsIPrintOptions::kJustRight, dateString, rect, visibleHeight); - } - } - } - } - } - - - PRBool usingHalfThePage = (printOptBits & nsIPrintOptions::kOptPrintDocTitle) && - (printOptBits & nsIPrintOptions::kOptPrintDocLoc); - - // print document title - PRUnichar * title; - mPrintOptions->GetTitle(&title); // creates memory - if (title != nsnull && (printOptBits & nsIPrintOptions::kOptPrintDocTitle)) { - DrawHeaderFooter(aRenderingContext, this, eHeader, nsIPrintOptions::kJustLeft, nsAutoString(title), rect, visibleHeight, usingHalfThePage); - nsMemory::Free(title); - } - - // print document URL - PRUnichar * url; - mPrintOptions->GetDocURL(&url); - if ((nsnull != url) && (printOptBits & nsIPrintOptions::kOptPrintDocLoc)) { - DrawHeaderFooter(aRenderingContext, this, eHeader, nsIPrintOptions::kJustRight, nsAutoString(url), rect, visibleHeight, usingHalfThePage); - nsMemory::Free(url); - } + PRUnichar * footers[3]; + mPrintOptions->GetFooterStrLeft(&footers[0]); // creates memory + mPrintOptions->GetFooterStrCenter(&footers[1]); // creates memory + mPrintOptions->GetFooterStrRight(&footers[2]); // creates memory + DrawHeaderFooter(aRenderingContext, this, eFooter, nsIPrintOptions::kJustRight, + nsAutoString(footers[0]), nsAutoString(footers[1]), nsAutoString(footers[2]), + rect, visibleHeight); + for (i=0;i<3;i++) nsMemory::Free(footers[i]); } @@ -521,12 +649,31 @@ nsPageFrame::SetPageNumInfo(PRInt32 aPageNumber, PRInt32 aTotalPages) //------------------------------------------------------------------------------ void -nsPageFrame::SetPageNumberFormat(PRUnichar * aFormatStr) +nsPageFrame::SetPageNumberFormat(PRUnichar * aFormatStr, PRBool aForPageNumOnly) { NS_ASSERTION(aFormatStr != nsnull, "Format string cannot be null!"); - if (mPageNumFormat != nsnull) { - nsMemory::Free(mPageNumFormat); + if (aForPageNumOnly) { + if (mPageNumFormat != nsnull) { + nsMemory::Free(mPageNumFormat); + } + mPageNumFormat = aFormatStr; + } else { + if (mPageNumAndTotalsFormat != nsnull) { + nsMemory::Free(mPageNumAndTotalsFormat); + } + mPageNumAndTotalsFormat = aFormatStr; } - mPageNumFormat = aFormatStr; +} + +//------------------------------------------------------------------------------ +void +nsPageFrame::SetDateTimeStr(PRUnichar * aDateTimeStr) +{ + NS_ASSERTION(aDateTimeStr != nsnull, "DateTime string cannot be null!"); + + if (mDateTimeStr != nsnull) { + nsMemory::Free(mDateTimeStr); + } + mDateTimeStr = aDateTimeStr; } diff --git a/mozilla/layout/html/base/src/nsPageFrame.h b/mozilla/layout/html/base/src/nsPageFrame.h index 9f5be457fa7..8e19aaaf442 100644 --- a/mozilla/layout/html/base/src/nsPageFrame.h +++ b/mozilla/layout/html/base/src/nsPageFrame.h @@ -71,8 +71,10 @@ public: virtual void SuppressHeadersAndFooters(PRBool aDoSup) { mSupressHF = aDoSup; } virtual void SetClipRect(nsRect* aClipRect) { mClipRect = *aClipRect; } + static void SetDateTimeStr(PRUnichar * aDateTimeStr); + // This is class is now responsible for freeing the memory - static void SetPageNumberFormat(PRUnichar * aFormatStr); + static void SetPageNumberFormat(PRUnichar * aFormatStr, PRBool aForPageNumOnly); protected: nsPageFrame(); @@ -95,19 +97,32 @@ protected: const nsString& sStr, const nsRect& aRect, nscoord aHeight, - PRBool aUseHalfThePage = PR_TRUE); + nscoord aWidth); + void DrawHeaderFooter(nsIRenderingContext& aRenderingContext, + nsIFrame * aFrame, + nsHeaderFooterEnum aHeaderFooter, + PRInt32 aJust, + const nsString& aStr1, + const nsString& aStr2, + const nsString& aStr3, + const nsRect& aRect, + nscoord aHeight); + + void ProcessSpecialCodes(const nsString& aStr, nsString& aNewStr); nsCOMPtr mPrintOptions; PRInt32 mPageNum; PRInt32 mTotNumPages; nsMargin mMargin; - nsFont * mHeadFootFont; PRPackedBool mSupressHF; nsRect mClipRect; + static PRUnichar * mDateTimeStr; + static nsFont * mHeadFootFont; static PRUnichar * mPageNumFormat; + static PRUnichar * mPageNumAndTotalsFormat; }; diff --git a/mozilla/layout/html/base/src/nsSimplePageSequence.cpp b/mozilla/layout/html/base/src/nsSimplePageSequence.cpp index efa5d4f5b25..c295f0ccb15 100644 --- a/mozilla/layout/html/base/src/nsSimplePageSequence.cpp +++ b/mozilla/layout/html/base/src/nsSimplePageSequence.cpp @@ -35,6 +35,16 @@ #include "nsIPrintOptions.h" #include "nsPageFrame.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); + #define OFFSET_NOT_SET -1 // This is for localization of the "x of n" pages string @@ -364,6 +374,7 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, kidReflowState.mComputedWidth = kidReflowState.availableWidth; //kidReflowState.mComputedHeight = kidReflowState.availableHeight; + PRINT_DEBUG_MSG3("AV W: %d H: %d\n", kidReflowState.availableWidth, kidReflowState.availableHeight); // Place and size the page. If the page is narrower than our // max width then center it horizontally @@ -403,6 +414,49 @@ nsSimplePageSequenceFrame::Reflow(nsIPresContext* aPresContext, // Get the next page kidFrame->GetNextSibling(&kidFrame); } + + // Get Total Page Count + nsIFrame* page; + PRInt32 pageTot = 0; + for (page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) { + pageTot++; + } + + // Set Page Number Info + PRInt32 pageNum = 1; + for (page = mFrames.FirstChild(); nsnull != page; page->GetNextSibling(&page)) { + nsPageFrame * pf = NS_STATIC_CAST(nsPageFrame*, page); + if (pf != nsnull) { + //pf->SetPrintOptions(aPrintOptions); + pf->SetPageNumInfo(pageNum, pageTot); + } + pageNum++; + } + + // Create current Date/Time String + nsresult rv; + nsCOMPtr locale; + nsCOMPtr localeSvc = do_GetService(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 ); + if (NS_SUCCEEDED(dateTime->FormatTime(locale, kDateFormatShort, kTimeFormatNoSeconds, ltime, dateString))) { + PRUnichar * uStr = dateString.ToNewUnicode(); + nsPageFrame::SetDateTimeStr(uStr); // nsPageFrame will own memory + } + } + } + } + } // Return our desired size @@ -501,6 +555,30 @@ nsSimplePageSequenceFrame::GetPrintRange(PRInt32* aFromPage, PRInt32* aToPage) return NS_OK; } +// Helper Function +void +nsSimplePageSequenceFrame::SetPageNumberFormat(const char* aPropName, const char* aDefPropVal, PRBool aPageNumOnly) +{ + // Doing this here so we only have to go get these formats once + nsAutoString pageNumberFormat; + // Now go get the Localized Page Formating String + nsAutoString propName; + propName.AssignWithConversion(aPropName); + PRUnichar* uPropName = propName.ToNewUnicode(); + if (uPropName != nsnull) { + nsresult rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, uPropName, pageNumberFormat); + if (NS_FAILED(rv)) { // back stop formatting + pageNumberFormat.AssignWithConversion(aDefPropVal); + } + nsMemory::Free(uPropName); + } + // Sets the format into a static data memeber which will own the memory and free it + PRUnichar* uStr = pageNumberFormat.ToNewUnicode(); + if (uStr != nsnull) { + nsPageFrame::SetPageNumberFormat(uStr, aPageNumOnly); // nsPageFrame will own the memory + } + +} NS_IMETHODIMP nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext, @@ -649,19 +727,9 @@ nsSimplePageSequenceFrame::StartPrint(nsIPresContext* aPresContext, } aPrintOptions->SetFontNamePointSize(fontName, pointSize); - // Now go get the Localized Page Formating String - PRBool doingPageTotals = PR_TRUE; - aPrintOptions->GetPrintOptions(nsIPrintOptions::kOptPrintPageTotal, &doingPageTotals); - - nsAutoString pageFormatStr; - rv = nsFormControlHelper::GetLocalizedString(PRINTING_PROPERTIES, - doingPageTotals? NS_LITERAL_STRING("pageofpages").get():NS_LITERAL_STRING("pagenumber").get(), - 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()); + // Doing this here so we only have to go get these formats once + SetPageNumberFormat("pagenumber", "%1$d", PR_TRUE); + SetPageNumberFormat("pageofpages", "%1$d of %2$d", PR_FALSE); mPageNum = 1; mPrintedPageNum = 1; @@ -870,3 +938,29 @@ nsSimplePageSequenceFrame::SetDebugFD(FILE* aFD) return NS_OK; } #endif + +//------------------------------------------------------------------------------ +NS_IMETHODIMP +nsSimplePageSequenceFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + aRenderingContext.PushState(); + aRenderingContext.SetColor(NS_RGB(255,255,255)); + + + if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { + nsRect rect = mRect; + aRenderingContext.SetColor(NS_RGB(255,255,255)); + rect.x = 0; + rect.y = 0; + aRenderingContext.FillRect(rect); + } + + nsresult rv = nsContainerFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + + PRBool clipEmpty; + aRenderingContext.PopState(clipEmpty); + return rv; +} diff --git a/mozilla/layout/html/base/src/nsSimplePageSequence.h b/mozilla/layout/html/base/src/nsSimplePageSequence.h index b4988dd4ba1..703a160f10c 100644 --- a/mozilla/layout/html/base/src/nsSimplePageSequence.h +++ b/mozilla/layout/html/base/src/nsSimplePageSequence.h @@ -41,6 +41,11 @@ public: const nsHTMLReflowState& aMaxSize, nsReflowStatus& aStatus); + NS_IMETHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + // nsIPageSequenceFrame NS_IMETHOD Print(nsIPresContext* aPresContext, nsIPrintOptions* aPrintOptions, @@ -85,6 +90,9 @@ protected: nsresult CreateContinuingPageFrame(nsIPresContext* aPresContext, nsIFrame* aPageFrame, nsIFrame** aContinuingFrame); + + void SetPageNumberFormat(const char* aPropName, const char* aDefPropVal, PRBool aPageNumOnly); + NS_IMETHOD_(nsrefcnt) AddRef(void) {return nsContainerFrame::AddRef();} NS_IMETHOD_(nsrefcnt) Release(void) {return nsContainerFrame::Release();}