--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/richtext/richtextprint.h
+// Purpose: Rich text printing classes
+// Author: Julian Smart
+// Created: 2006-10-23
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_RICHTEXTPRINT_H_
+#define _WX_RICHTEXTPRINT_H_
+
+#include "wx/defs.h"
+
+#if wxUSE_RICHTEXT & wxUSE_PRINTING_ARCHITECTURE
+
+#include "wx/richtext/richtextbuffer.h"
+
+#include "wx/print.h"
+#include "wx/printdlg.h"
+
+#define wxRICHTEXT_PRINT_MAX_PAGES 99999
+
+// Header/footer page identifiers
+enum wxRichTextOddEvenPage {
+ wxRICHTEXT_PAGE_ODD,
+ wxRICHTEXT_PAGE_EVEN,
+ wxRICHTEXT_PAGE_ALL,
+};
+
+// Header/footer text locations
+enum wxRichTextPageLocation {
+ wxRICHTEXT_PAGE_LEFT,
+ wxRICHTEXT_PAGE_CENTRE,
+ wxRICHTEXT_PAGE_RIGHT
+};
+
+/*!
+ * Header/footer data
+ */
+
+class WXDLLIMPEXP_RICHTEXT wxRichTextHeaderFooterData: public wxObject
+{
+public:
+ wxRichTextHeaderFooterData() { Init(); }
+ wxRichTextHeaderFooterData(const wxRichTextHeaderFooterData& data) { Copy(data); }
+
+ /// Initialise
+ void Init() { m_headerMargin = 20; m_footerMargin = 20; m_showOnFirstPage = true; }
+
+ /// Copy
+ void Copy(const wxRichTextHeaderFooterData& data);
+
+ /// Assignment
+ void operator= (const wxRichTextHeaderFooterData& data) { Copy(data); }
+
+ /// Set/get header text, e.g. wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT
+ void SetHeaderText(const wxString& text, wxRichTextOddEvenPage page = wxRICHTEXT_PAGE_ALL, wxRichTextPageLocation location = wxRICHTEXT_PAGE_CENTRE);
+ wxString GetHeaderText(wxRichTextOddEvenPage page = wxRICHTEXT_PAGE_EVEN, wxRichTextPageLocation location = wxRICHTEXT_PAGE_CENTRE) const;
+
+ /// Set/get footer text, e.g. wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT
+ void SetFooterText(const wxString& text, wxRichTextOddEvenPage page = wxRICHTEXT_PAGE_ALL, wxRichTextPageLocation location = wxRICHTEXT_PAGE_CENTRE);
+ wxString GetFooterText(wxRichTextOddEvenPage page = wxRICHTEXT_PAGE_EVEN, wxRichTextPageLocation location = wxRICHTEXT_PAGE_CENTRE) const;
+
+ /// Set/get text
+ void SetText(const wxString& text, int headerFooter, wxRichTextOddEvenPage page, wxRichTextPageLocation location);
+ wxString GetText(int headerFooter, wxRichTextOddEvenPage page, wxRichTextPageLocation location) const;
+
+ /// Set/get margins between text and header or footer, in tenths of a millimeter
+ void SetMargins(int headerMargin, int footerMargin) { m_headerMargin = headerMargin; m_footerMargin = footerMargin; }
+ int GetHeaderMargin() const { return m_headerMargin; }
+ int GetFooterMargin() const { return m_footerMargin; }
+
+ /// Set/get whether to show header or footer on first page
+ void SetShowOnFirstPage(bool showOnFirstPage) { m_showOnFirstPage = showOnFirstPage; }
+ bool GetShowOnFirstPage() const { return m_showOnFirstPage; }
+
+ /// Clear all text
+ void Clear();
+
+ /// Set/get font
+ void SetFont(const wxFont& font) { m_font = font; }
+ const wxFont& GetFont() const { return m_font; }
+
+ /// Set/get colour
+ void SetTextColour(const wxColour& col) { m_colour = col; }
+ const wxColour& GetTextColour() const { return m_colour; }
+
+ DECLARE_CLASS(wxRichTextHeaderFooterData)
+
+private:
+
+ // Strings for left, centre, right, top, bottom, odd, even
+ wxString m_text[12];
+ wxFont m_font;
+ wxColour m_colour;
+ int m_headerMargin;
+ int m_footerMargin;
+ bool m_showOnFirstPage;
+};
+
+/*!
+ * wxRichTextPrintout
+ */
+
+class WXDLLIMPEXP_RICHTEXT wxRichTextPrintout : public wxPrintout
+{
+public:
+ wxRichTextPrintout(const wxString& title = wxT("Printout"));
+ virtual ~wxRichTextPrintout();
+
+ /// The buffer to print
+ void SetRichTextBuffer(wxRichTextBuffer* buffer) { m_richTextBuffer = buffer; }
+ wxRichTextBuffer* GetRichTextBuffer() const { return m_richTextBuffer; }
+
+ /// Set/get header/footer data
+ void SetHeaderFooterData(const wxRichTextHeaderFooterData& data) { m_headerFooterData = data; }
+ const wxRichTextHeaderFooterData& GetHeaderFooterData() const { return m_headerFooterData; }
+
+ /// Sets margins in 10ths of millimetre. Defaults to 1 inch for margins.
+ void SetMargins(int top = 252, int bottom = 252, int left = 252, int right = 252);
+
+ /// Calculate scaling and rectangles, setting the device context scaling
+ void CalculateScaling(wxDC* dc, wxRect& textRect, wxRect& headerRect, wxRect& footerRect);
+
+ // wxPrintout virtual functions
+ virtual bool OnPrintPage(int page);
+ virtual bool HasPage(int page);
+ virtual void GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo);
+ virtual bool OnBeginDocument(int startPage, int endPage);
+ virtual void OnPreparePrinting();
+
+private:
+
+ /// Renders one page into dc
+ void RenderPage(wxDC *dc, int page);
+
+ /// Substitute keywords
+ static bool SubstituteKeywords(wxString& str, const wxString& title, int pageNum, int pageCount);
+
+private:
+
+ wxRichTextBuffer* m_richTextBuffer;
+ int m_numPages;
+ wxArrayInt m_pageBreaksStart;
+ wxArrayInt m_pageBreaksEnd;
+ int m_marginLeft, m_marginTop, m_marginRight, m_marginBottom;
+
+ wxRichTextHeaderFooterData m_headerFooterData;
+
+ DECLARE_NO_COPY_CLASS(wxRichTextPrintout)
+};
+
+/*
+ *! wxRichTextPrinting
+ * A simple interface to perform wxRichTextBuffer printing.
+ */
+
+class WXDLLIMPEXP_RICHTEXT wxRichTextPrinting : public wxObject
+{
+public:
+ wxRichTextPrinting(const wxString& name = wxT("Printing"), wxWindow *parentWindow = NULL);
+ virtual ~wxRichTextPrinting();
+
+ /// Preview the file or buffer
+ bool PreviewFile(const wxString& richTextFile);
+ bool PreviewBuffer(const wxRichTextBuffer& buffer);
+
+ /// Print the file or buffer
+ bool PrintFile(const wxString& richTextFile);
+ bool PrintBuffer(const wxRichTextBuffer& buffer);
+
+ /// Shows page setup dialog
+ void PageSetup();
+
+ /// Set/get header/footer data
+ void SetHeaderFooterData(const wxRichTextHeaderFooterData& data) { m_headerFooterData = data; }
+ const wxRichTextHeaderFooterData& GetHeaderFooterData() const { return m_headerFooterData; }
+
+ /// Set/get header text, e.g. wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT
+ void SetHeaderText(const wxString& text, wxRichTextOddEvenPage page = wxRICHTEXT_PAGE_ALL, wxRichTextPageLocation location = wxRICHTEXT_PAGE_CENTRE);
+ wxString GetHeaderText(wxRichTextOddEvenPage page = wxRICHTEXT_PAGE_EVEN, wxRichTextPageLocation location = wxRICHTEXT_PAGE_CENTRE) const;
+
+ /// Set/get footer text, e.g. wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT
+ void SetFooterText(const wxString& text, wxRichTextOddEvenPage page = wxRICHTEXT_PAGE_ALL, wxRichTextPageLocation location = wxRICHTEXT_PAGE_CENTRE);
+ wxString GetFooterText(wxRichTextOddEvenPage page = wxRICHTEXT_PAGE_EVEN, wxRichTextPageLocation location = wxRICHTEXT_PAGE_CENTRE) const;
+
+ /// Show header/footer on first page, or not
+ bool SetShowOnFirstPage(bool show) { m_headerFooterData.SetShowOnFirstPage(show); }
+
+ /// Get print and page setup data
+ wxPrintData *GetPrintData();
+ wxPageSetupDialogData *GetPageSetupData() { return m_pageSetupData; }
+
+ /// Set the rich text buffer pointer, deleting the existing object if present
+ void SetRichTextBufferPreview(wxRichTextBuffer* buf);
+ wxRichTextBuffer* GetRichTextBufferPreview() const { return m_richTextBufferPreview; }
+
+ void SetRichTextBufferPrinting(wxRichTextBuffer* buf);
+ wxRichTextBuffer* GetRichTextBufferPrinting() const { return m_richTextBufferPrinting; }
+
+ /// Set/get the parent window
+ void SetParentWindow(wxWindow* parent) { m_parentWindow = parent; }
+ wxWindow* GetParentWindow() const { return m_parentWindow; }
+
+ /// Set/get the title
+ void SetTitle(const wxString& title) { m_title = title; }
+ const wxString& GetTitle() const { return m_title; }
+
+ /// Set/get the preview rect
+ void SetPreviewRect(const wxRect& rect) { m_previewRect = rect; }
+ const wxRect& GetPreviewRect() const { return m_previewRect; }
+
+protected:
+ virtual wxRichTextPrintout *CreatePrintout();
+ virtual bool DoPreview(wxRichTextPrintout *printout1, wxRichTextPrintout *printout2);
+ virtual bool DoPrint(wxRichTextPrintout *printout);
+
+private:
+ wxPrintData* m_printData;
+ wxPageSetupDialogData* m_pageSetupData;
+
+ wxRichTextHeaderFooterData m_headerFooterData;
+ wxString m_title;
+ wxWindow* m_parentWindow;
+ wxRichTextBuffer* m_richTextBufferPreview;
+ wxRichTextBuffer* m_richTextBufferPrinting;
+ wxRect m_previewRect;
+
+ DECLARE_NO_COPY_CLASS(wxRichTextPrinting)
+};
+
+#endif // wxUSE_RICHTEXT & wxUSE_PRINTING_ARCHITECTURE
+
+#endif // _WX_RICHTEXTPRINT_H_
+
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: src/richtext/richtextprint.cpp
+// Purpose: Rich text printing classes
+// Author: Julian Smart
+// Created: 2006-10-24
+// RCS-ID: $Id$
+// Copyright: (c) Julian Smart
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// For compilers that support precompilation, includes "wx/wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#if wxUSE_RICHTEXT && wxUSE_PRINTING_ARCHITECTURE && wxUSE_STREAMS
+
+#ifndef WX_PRECOMP
+ #include "wx/log.h"
+ #include "wx/intl.h"
+ #include "wx/dc.h"
+ #include "wx/settings.h"
+ #include "wx/msgdlg.h"
+#endif
+
+#include "wx/datetime.h"
+#include "wx/print.h"
+#include "wx/printdlg.h"
+#include "wx/richtext/richtextprint.h"
+#include "wx/wfstream.h"
+
+/*!
+ * wxRichTextPrintout
+ */
+
+wxRichTextPrintout::wxRichTextPrintout(const wxString& title) : wxPrintout(title)
+{
+ m_numPages = wxRICHTEXT_PRINT_MAX_PAGES;
+
+ SetMargins(); // to default values
+}
+
+wxRichTextPrintout::~wxRichTextPrintout()
+{
+}
+
+void wxRichTextPrintout::OnPreparePrinting()
+{
+ wxBusyCursor wait;
+
+ m_numPages = 0;
+
+ m_pageBreaksStart.Clear();
+ m_pageBreaksEnd.Clear();
+
+ int lastStartPos = 0;
+
+ wxRect rect, headerRect, footerRect;
+
+ /// Sets the DC scaling and returns important page rectangles
+ CalculateScaling(GetDC(), rect, headerRect, footerRect);
+
+ if (GetRichTextBuffer())
+ {
+ GetRichTextBuffer()->Invalidate(wxRICHTEXT_ALL);
+
+ GetRichTextBuffer()->Layout(*GetDC(), rect, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT);
+
+ // Now calculate the page breaks
+
+ int yOffset = 0;
+
+ wxRichTextLine* lastLine = NULL;
+
+ wxRichTextObjectList::compatibility_iterator node = GetRichTextBuffer()->GetChildren().GetFirst();
+ while (node)
+ {
+ // child is a paragraph
+ wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph);
+ wxASSERT (child != NULL);
+
+ wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst();
+ while (node2)
+ {
+ wxRichTextLine* line = node2->GetData();
+
+ // Set the line to the page-adjusted position
+ line->SetPosition(wxPoint(line->GetPosition().x, line->GetPosition().y - yOffset));
+
+ int lineY = child->GetPosition().y + line->GetPosition().y;
+
+ if ((lineY + line->GetSize().y) > rect.GetBottom())
+ {
+ // New page starting at this line
+ int newY = rect.y;
+
+ // We increase the offset by the difference between new and old positions
+
+ int increaseOffsetBy = lineY - newY;
+ yOffset += increaseOffsetBy;
+
+ line->SetPosition(wxPoint(line->GetPosition().x, newY - child->GetPosition().y));
+
+ if (!lastLine)
+ lastLine = line;
+
+ m_pageBreaksStart.Add(lastStartPos);
+ m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd());
+
+ lastStartPos = line->GetAbsoluteRange().GetStart();
+
+ m_numPages ++;
+ }
+
+ lastLine = line;
+
+ node2 = node2->GetNext();
+ }
+
+ node = node->GetNext();
+ }
+
+ // Closing page break
+ if (m_pageBreaksStart.GetCount() > 0 && (m_pageBreaksEnd[m_pageBreaksEnd.GetCount()-1] < (GetRichTextBuffer()->GetRange().GetEnd()-1)))
+ {
+ m_pageBreaksStart.Add(lastStartPos);
+ m_pageBreaksEnd.Add(GetRichTextBuffer()->GetRange().GetEnd());
+ m_numPages ++;
+ }
+ }
+}
+
+bool wxRichTextPrintout::OnBeginDocument(int startPage, int endPage)
+{
+ if (!wxPrintout::OnBeginDocument(startPage, endPage)) return false;
+
+ return true;
+}
+
+bool wxRichTextPrintout::OnPrintPage(int page)
+{
+ wxDC *dc = GetDC();
+ if (dc)
+ {
+ if (HasPage(page))
+ RenderPage(dc, page);
+ return true;
+ }
+ else return false;
+}
+
+void wxRichTextPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
+{
+ *minPage = 1;
+ *maxPage = m_numPages;
+ *selPageFrom = 1;
+ *selPageTo = m_numPages;
+}
+
+bool wxRichTextPrintout::HasPage(int pageNum)
+{
+ return pageNum > 0 && pageNum <= m_numPages;
+}
+
+void wxRichTextPrintout::RenderPage(wxDC *dc, int page)
+{
+ if (!GetRichTextBuffer())
+ return;
+
+ wxBusyCursor wait;
+
+ wxRect textRect, headerRect, footerRect;
+
+ /// Sets the DC scaling and returns important page rectangles
+ CalculateScaling(dc, textRect, headerRect, footerRect);
+
+ if (page > 1 || m_headerFooterData.GetShowOnFirstPage())
+ {
+ if (m_headerFooterData.GetFont().Ok())
+ dc->SetFont(m_headerFooterData.GetFont());
+ else
+ dc->SetFont(*wxNORMAL_FONT);
+ if (m_headerFooterData.GetTextColour().Ok())
+ dc->SetTextForeground(m_headerFooterData.GetTextColour());
+ else
+ dc->SetTextForeground(*wxBLACK);
+ dc->SetBackgroundMode(wxTRANSPARENT);
+
+ // Draw header, if any
+ wxRichTextOddEvenPage oddEven = ((page % 2) == 1) ? wxRICHTEXT_PAGE_ODD : wxRICHTEXT_PAGE_EVEN;
+
+ wxString headerTextCentre = m_headerFooterData.GetHeaderText(oddEven, wxRICHTEXT_PAGE_CENTRE);
+ wxString headerTextLeft = m_headerFooterData.GetHeaderText(oddEven, wxRICHTEXT_PAGE_LEFT);
+ wxString headerTextRight = m_headerFooterData.GetHeaderText(oddEven, wxRICHTEXT_PAGE_RIGHT);
+
+ if (!headerTextLeft.IsEmpty())
+ {
+ SubstituteKeywords(headerTextLeft, GetTitle(), page, m_numPages);
+
+ //int tx, ty;
+ //dc->GetTextExtent(headerTextLeft, & tx, & ty);
+
+ int x = headerRect.GetLeft();
+ int y = headerRect.GetX();
+ dc->DrawText(headerTextLeft, x, y);
+ }
+ if (!headerTextCentre.IsEmpty())
+ {
+ SubstituteKeywords(headerTextCentre, GetTitle(), page, m_numPages);
+
+ int tx, ty;
+ dc->GetTextExtent(headerTextCentre, & tx, & ty);
+
+ int x = headerRect.GetWidth()/2 - tx/2 + headerRect.GetLeft();
+ int y = headerRect.GetY();
+ dc->DrawText(headerTextCentre, x, y);
+ }
+ if (!headerTextRight.IsEmpty())
+ {
+ SubstituteKeywords(headerTextRight, GetTitle(), page, m_numPages);
+
+ int tx, ty;
+ dc->GetTextExtent(headerTextRight, & tx, & ty);
+
+ int x = headerRect.GetRight() - tx;
+ int y = headerRect.GetY();
+ dc->DrawText(headerTextRight, x, y);
+ }
+
+ // Draw footer, if any
+ wxString footerTextCentre = m_headerFooterData.GetFooterText(oddEven, wxRICHTEXT_PAGE_CENTRE);
+ wxString footerTextLeft = m_headerFooterData.GetFooterText(oddEven, wxRICHTEXT_PAGE_LEFT);
+ wxString footerTextRight = m_headerFooterData.GetFooterText(oddEven, wxRICHTEXT_PAGE_RIGHT);
+
+ if (!footerTextLeft.IsEmpty())
+ {
+ SubstituteKeywords(footerTextLeft, GetTitle(), page, m_numPages);
+
+ int tx, ty;
+ dc->GetTextExtent(footerTextLeft, & tx, & ty);
+
+ int x = footerRect.GetLeft();
+ int y = footerRect.GetBottom() - ty;
+ dc->DrawText(footerTextLeft, x, y);
+ }
+ if (!footerTextCentre.IsEmpty())
+ {
+ SubstituteKeywords(footerTextCentre, GetTitle(), page, m_numPages);
+
+ int tx, ty;
+ dc->GetTextExtent(footerTextCentre, & tx, & ty);
+
+ int x = footerRect.GetWidth()/2 - tx/2 + footerRect.GetLeft();
+ int y = footerRect.GetBottom() - ty;
+ dc->DrawText(footerTextCentre, x, y);
+ }
+ if (!footerTextRight.IsEmpty())
+ {
+ SubstituteKeywords(footerTextRight, GetTitle(), page, m_numPages);
+
+ int tx, ty;
+ dc->GetTextExtent(footerTextRight, & tx, & ty);
+
+ int x = footerRect.GetRight() - tx;
+ int y = footerRect.GetBottom() - ty;
+ dc->DrawText(footerTextRight, x, y);
+ }
+ }
+
+ wxRichTextRange rangeToDraw(m_pageBreaksStart[page-1], m_pageBreaksEnd[page-1]);
+
+ GetRichTextBuffer()->Draw(*dc, rangeToDraw, wxRichTextRange(-1,-1), textRect, 0 /* descent */, wxRICHTEXT_DRAW_IGNORE_CACHE /* flags */);
+}
+
+void wxRichTextPrintout::SetMargins(int top, int bottom, int left, int right)
+{
+ m_marginTop = top;
+ m_marginBottom = bottom;
+ m_marginLeft = left;
+ m_marginRight = right;
+}
+
+/// Calculate scaling and rectangles, setting the device context scaling
+void wxRichTextPrintout::CalculateScaling(wxDC* dc, wxRect& textRect, wxRect& headerRect, wxRect& footerRect)
+{
+ // Get the logical pixels per inch of screen and printer
+ int ppiScreenX, ppiScreenY;
+ GetPPIScreen(&ppiScreenX, &ppiScreenY);
+ int ppiPrinterX, ppiPrinterY;
+ GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
+
+ // This scales the DC so that the printout roughly represents the
+ // the screen scaling.
+ float scale = (float)((float)ppiPrinterX/(float)ppiScreenX);
+
+ // Now we have to check in case our real page size is reduced
+ // (e.g. because we're drawing to a print preview memory DC)
+ int pageWidth, pageHeight;
+ int w, h;
+ dc->GetSize(&w, &h);
+ GetPageSizePixels(&pageWidth, &pageHeight);
+
+ // If printer pageWidth == current DC width, then this doesn't
+ // change. But w might be the preview bitmap width, so scale down.
+ float previewScale = (float)(w/(float)pageWidth);
+ float overallScale = scale * previewScale;
+
+ // The dimensions used for indentation etc. have to be unscaled
+ // during printing to be correct when scaling is applied.
+ if (!IsPreview())
+ m_richTextBuffer->SetScale(scale);
+
+ // Calculate margins
+ int marginLeft = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_marginLeft);
+ int marginTop = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_marginTop);
+ int marginRight = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_marginRight);
+ int marginBottom = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_marginBottom);
+
+ // Header and footer margins
+ int headerMargin = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_headerFooterData.GetHeaderMargin());
+ int footerMargin = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_headerFooterData.GetFooterMargin());
+
+ dc->SetUserScale(overallScale, overallScale);
+
+ wxRect rect(marginLeft/scale, marginTop/scale,
+ (pageWidth - marginLeft - marginRight)/scale, (pageHeight - marginTop - marginBottom)/scale);
+
+ headerRect = wxRect(0, 0, 0, 0);
+
+ if (!m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT).IsEmpty() ||
+ !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_CENTRE).IsEmpty() ||
+ !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_RIGHT).IsEmpty() ||
+
+ !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_LEFT).IsEmpty() ||
+ !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_CENTRE).IsEmpty() ||
+ !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_RIGHT).IsEmpty())
+ {
+ if (m_headerFooterData.GetFont().Ok())
+ dc->SetFont(m_headerFooterData.GetFont());
+ else
+ dc->SetFont(*wxNORMAL_FONT);
+
+ int charHeight = dc->GetCharHeight();
+
+ int headerHeight = charHeight + headerMargin/scale;
+
+ headerRect = wxRect(rect.x, rect.y, rect.width, headerHeight);
+
+ rect.y += headerHeight;
+ rect.height -= headerHeight;
+ }
+
+ footerRect = wxRect(0, 0, 0, 0);
+
+ if (!m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT).IsEmpty() ||
+ !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_CENTRE).IsEmpty() ||
+ !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_RIGHT).IsEmpty() ||
+
+ !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_LEFT).IsEmpty() ||
+ !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_CENTRE).IsEmpty() ||
+ !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_RIGHT).IsEmpty())
+ {
+ if (m_headerFooterData.GetFont().Ok())
+ dc->SetFont(m_headerFooterData.GetFont());
+ else
+ dc->SetFont(*wxNORMAL_FONT);
+
+ int charHeight = dc->GetCharHeight();
+
+ int footerHeight = charHeight + footerMargin/scale;
+
+ footerRect = wxRect(rect.x, rect.y + rect.height, rect.width, footerHeight);
+
+ rect.height -= footerHeight;
+ }
+
+ textRect = rect;
+}
+
+bool wxRichTextPrintout::SubstituteKeywords(wxString& str, const wxString& title, int pageNum, int pageCount)
+{
+ wxString num;
+
+ num.Printf(wxT("%i"), pageNum);
+ str.Replace(wxT("@PAGENUM@"), num);
+
+ num.Printf(wxT("%lu"), (unsigned long) pageCount);
+ str.Replace(wxT("@PAGESCNT@"), num);
+
+ wxDateTime now = wxDateTime::Now();
+
+ str.Replace(wxT("@DATE@"), now.FormatDate());
+ str.Replace(wxT("@TIME@"), now.FormatTime());
+
+ str.Replace(wxT("@TITLE@"), title);
+
+ return true;
+}
+
+/*!
+ * wxRichTextPrinting
+ */
+
+wxRichTextPrinting::wxRichTextPrinting(const wxString& name, wxWindow *parentWindow)
+{
+ m_richTextBufferPrinting = NULL;
+ m_richTextBufferPreview = NULL;
+
+ m_parentWindow = parentWindow;
+ m_title = name;
+ m_printData = NULL;
+
+ m_previewRect = wxRect(wxPoint(100, 100), wxSize(800, 800));
+
+ m_pageSetupData = new wxPageSetupDialogData;
+ m_pageSetupData->EnableMargins(true);
+ m_pageSetupData->SetMarginTopLeft(wxPoint(25, 25));
+ m_pageSetupData->SetMarginBottomRight(wxPoint(25, 25));
+}
+
+wxRichTextPrinting::~wxRichTextPrinting()
+{
+ delete m_printData;
+ delete m_pageSetupData;
+ delete m_richTextBufferPrinting;
+ delete m_richTextBufferPreview;
+}
+
+wxPrintData *wxRichTextPrinting::GetPrintData()
+{
+ if (m_printData == NULL)
+ m_printData = new wxPrintData();
+ return m_printData;
+}
+
+/// Set the rich text buffer pointer, deleting the existing object if present
+void wxRichTextPrinting::SetRichTextBufferPrinting(wxRichTextBuffer* buf)
+{
+ if (m_richTextBufferPrinting)
+ {
+ delete m_richTextBufferPrinting;
+ m_richTextBufferPrinting = NULL;
+ }
+ m_richTextBufferPrinting = buf;
+}
+
+void wxRichTextPrinting::SetRichTextBufferPreview(wxRichTextBuffer* buf)
+{
+ if (m_richTextBufferPreview)
+ {
+ delete m_richTextBufferPreview;
+ m_richTextBufferPreview = NULL;
+ }
+ m_richTextBufferPreview = buf;
+}
+
+bool wxRichTextPrinting::PreviewFile(const wxString& richTextFile)
+{
+ SetRichTextBufferPreview(new wxRichTextBuffer);
+
+ if (!m_richTextBufferPreview->LoadFile(richTextFile))
+ {
+ SetRichTextBufferPreview(NULL);
+ return false;
+ }
+ else
+ SetRichTextBufferPrinting(new wxRichTextBuffer(*m_richTextBufferPreview));
+
+ wxRichTextPrintout *p1 = CreatePrintout();
+ p1->SetRichTextBuffer(m_richTextBufferPreview);
+
+ wxRichTextPrintout *p2 = CreatePrintout();
+ p2->SetRichTextBuffer(m_richTextBufferPrinting);
+ return DoPreview(p1, p2);
+}
+
+bool wxRichTextPrinting::PreviewBuffer(const wxRichTextBuffer& buffer)
+{
+ SetRichTextBufferPreview(new wxRichTextBuffer(buffer));
+ SetRichTextBufferPrinting(new wxRichTextBuffer(buffer));
+
+ wxRichTextPrintout *p1 = CreatePrintout();
+ p1->SetRichTextBuffer(m_richTextBufferPreview);
+
+ wxRichTextPrintout *p2 = CreatePrintout();
+ p2->SetRichTextBuffer(m_richTextBufferPrinting);
+
+ return DoPreview(p1, p2);
+}
+
+bool wxRichTextPrinting::PrintFile(const wxString& richTextFile)
+{
+ SetRichTextBufferPrinting(new wxRichTextBuffer);
+
+ if (!m_richTextBufferPrinting->LoadFile(richTextFile))
+ {
+ SetRichTextBufferPrinting(NULL);
+ return false;
+ }
+
+ wxRichTextPrintout *p = CreatePrintout();
+ p->SetRichTextBuffer(m_richTextBufferPrinting);
+
+ bool ret = DoPrint(p);
+ delete p;
+ return ret;
+}
+
+bool wxRichTextPrinting::PrintBuffer(const wxRichTextBuffer& buffer)
+{
+ SetRichTextBufferPrinting(new wxRichTextBuffer(buffer));
+
+ wxRichTextPrintout *p = CreatePrintout();
+ p->SetRichTextBuffer(m_richTextBufferPrinting);
+
+ bool ret = DoPrint(p);
+ delete p;
+ return ret;
+}
+
+bool wxRichTextPrinting::DoPreview(wxRichTextPrintout *printout1, wxRichTextPrintout *printout2)
+{
+ // Pass two printout objects: for preview, and possible printing.
+ wxPrintDialogData printDialogData(*GetPrintData());
+ wxPrintPreview *preview = new wxPrintPreview(printout1, printout2, &printDialogData);
+ if (!preview->Ok())
+ {
+ delete preview;
+ return false;
+ }
+
+ wxPreviewFrame *frame = new wxPreviewFrame(preview, m_parentWindow,
+ m_title + _(" Preview"),
+ m_previewRect.GetPosition(), m_previewRect.GetSize());
+ frame->Centre(wxBOTH);
+ frame->Initialize();
+ frame->Show(true);
+ return true;
+}
+
+bool wxRichTextPrinting::DoPrint(wxRichTextPrintout *printout)
+{
+ wxPrintDialogData printDialogData(*GetPrintData());
+ wxPrinter printer(&printDialogData);
+
+ if (!printer.Print(m_parentWindow, printout, true))
+ {
+ return false;
+ }
+
+ (*GetPrintData()) = printer.GetPrintDialogData().GetPrintData();
+ return true;
+}
+
+void wxRichTextPrinting::PageSetup()
+{
+ if (!GetPrintData()->Ok())
+ {
+ wxLogError(_("There was a problem during page setup: you may need to set a default printer."));
+ return;
+ }
+
+ m_pageSetupData->SetPrintData(*GetPrintData());
+ wxPageSetupDialog pageSetupDialog(m_parentWindow, m_pageSetupData);
+
+ if (pageSetupDialog.ShowModal() == wxID_OK)
+ {
+ (*GetPrintData()) = pageSetupDialog.GetPageSetupData().GetPrintData();
+ (*m_pageSetupData) = pageSetupDialog.GetPageSetupData();
+ }
+}
+
+wxRichTextPrintout *wxRichTextPrinting::CreatePrintout()
+{
+ wxRichTextPrintout *p = new wxRichTextPrintout(m_title);
+
+ p->SetHeaderFooterData(GetHeaderFooterData());
+ p->SetMargins(10*m_pageSetupData->GetMarginTopLeft().y,
+ 10*m_pageSetupData->GetMarginBottomRight().y,
+ 10*m_pageSetupData->GetMarginTopLeft().x,
+ 10*m_pageSetupData->GetMarginBottomRight().x);
+
+ return p;
+}
+
+/// Set/get header text, e.g. wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT
+void wxRichTextPrinting::SetHeaderText(const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location)
+{
+ m_headerFooterData.SetHeaderText(text, page, location);
+}
+
+wxString wxRichTextPrinting::GetHeaderText(wxRichTextOddEvenPage page, wxRichTextPageLocation location) const
+{
+ return m_headerFooterData.GetHeaderText(page, location);
+}
+
+/// Set/get footer text, e.g. wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT
+void wxRichTextPrinting::SetFooterText(const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location)
+{
+ m_headerFooterData.SetFooterText(text, page, location);
+}
+
+wxString wxRichTextPrinting::GetFooterText(wxRichTextOddEvenPage page, wxRichTextPageLocation location) const
+{
+ return m_headerFooterData.GetFooterText(page, location);
+}
+
+/*!
+ * Header/footer data
+ */
+
+IMPLEMENT_CLASS(wxRichTextHeaderFooterData, wxObject)
+
+/// Copy
+void wxRichTextHeaderFooterData::Copy(const wxRichTextHeaderFooterData& data)
+{
+ int i;
+ for (i = 0; i < 12; i++)
+ m_text[i] = data.m_text[i];
+ m_font = data.m_font;
+ m_colour = data.m_colour;
+ m_headerMargin = data.m_headerMargin;
+ m_footerMargin = data.m_footerMargin;
+ m_showOnFirstPage = data.m_showOnFirstPage;
+}
+
+/// Set/get text
+void wxRichTextHeaderFooterData::SetText(const wxString& text, int headerFooter, wxRichTextOddEvenPage page, wxRichTextPageLocation location)
+{
+ int idx = headerFooter + (2 * (int) page) + (4 * (int) location);
+ wxASSERT( idx >= 0 && idx < 12 );
+
+ if (idx >= 0 && idx < 12)
+ m_text[idx] = text;
+}
+
+wxString wxRichTextHeaderFooterData::GetText(int headerFooter, wxRichTextOddEvenPage page, wxRichTextPageLocation location) const
+{
+ int idx = headerFooter + (2 * (int) page) + (4 * (int) location);
+ wxASSERT( idx >= 0 && idx < 12 );
+
+ if (idx >= 0 && idx < 12)
+ return m_text[idx];
+ else
+ return wxEmptyString;
+}
+
+/// Set/get header text, e.g. wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT
+void wxRichTextHeaderFooterData::SetHeaderText(const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location)
+{
+ if (page == wxRICHTEXT_PAGE_ALL)
+ {
+ SetText(text, 0, wxRICHTEXT_PAGE_ODD, location);
+ SetText(text, 0, wxRICHTEXT_PAGE_EVEN, location);
+ }
+ else
+ SetText(text, 0, page, location);
+}
+
+wxString wxRichTextHeaderFooterData::GetHeaderText(wxRichTextOddEvenPage page, wxRichTextPageLocation location) const
+{
+ return GetText(0, page, location);
+}
+
+/// Set/get footer text, e.g. wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT
+void wxRichTextHeaderFooterData::SetFooterText(const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location)
+{
+ if (page == wxRICHTEXT_PAGE_ALL)
+ {
+ SetText(text, 1, wxRICHTEXT_PAGE_ODD, location);
+ SetText(text, 1, wxRICHTEXT_PAGE_EVEN, location);
+ }
+ else
+ SetText(text, 1, page, location);
+}
+
+wxString wxRichTextHeaderFooterData::GetFooterText(wxRichTextOddEvenPage page, wxRichTextPageLocation location) const
+{
+ return GetText(1, page, location);
+}
+
+/// Clear all text
+void wxRichTextHeaderFooterData::Clear()
+{
+ int i;
+ for (i = 0; i < 12; i++)
+ m_text[i] = wxEmptyString;
+}
+
+#endif // wxUSE_RICHTEXT & wxUSE_PRINTING_ARCHITECTURE
+