]> git.saurik.com Git - wxWidgets.git/blame - src/richtext/richtextprint.cpp
Add wxAnyScrollHelperBase to reduce code duplication in wxVarScrollHelperBase.
[wxWidgets.git] / src / richtext / richtextprint.cpp
CommitLineData
44219ff0
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/richtext/richtextprint.cpp
3// Purpose: Rich text printing classes
4// Author: Julian Smart
5// Created: 2006-10-24
44219ff0
JS
6// Copyright: (c) Julian Smart
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10// For compilers that support precompilation, includes "wx/wx.h".
11#include "wx/wxprec.h"
12
13#ifdef __BORLANDC__
14 #pragma hdrstop
15#endif
16
17#if wxUSE_RICHTEXT && wxUSE_PRINTING_ARCHITECTURE && wxUSE_STREAMS
18
19#ifndef WX_PRECOMP
20 #include "wx/log.h"
21 #include "wx/intl.h"
22 #include "wx/dc.h"
23 #include "wx/settings.h"
24 #include "wx/msgdlg.h"
25#endif
26
27#include "wx/datetime.h"
28#include "wx/print.h"
29#include "wx/printdlg.h"
30#include "wx/richtext/richtextprint.h"
31#include "wx/wfstream.h"
32
33/*!
34 * wxRichTextPrintout
35 */
36
37wxRichTextPrintout::wxRichTextPrintout(const wxString& title) : wxPrintout(title)
38{
39 m_numPages = wxRICHTEXT_PRINT_MAX_PAGES;
40
41 SetMargins(); // to default values
42}
43
44wxRichTextPrintout::~wxRichTextPrintout()
45{
46}
47
48void wxRichTextPrintout::OnPreparePrinting()
49{
50 wxBusyCursor wait;
51
f1b18eba 52 m_numPages = 1;
44219ff0
JS
53
54 m_pageBreaksStart.Clear();
55 m_pageBreaksEnd.Clear();
603f702b 56 m_pageYOffsets.Clear();
03647350 57
44219ff0 58 int lastStartPos = 0;
03647350 59
44219ff0
JS
60 wxRect rect, headerRect, footerRect;
61
62 /// Sets the DC scaling and returns important page rectangles
63 CalculateScaling(GetDC(), rect, headerRect, footerRect);
64
65 if (GetRichTextBuffer())
66 {
67 GetRichTextBuffer()->Invalidate(wxRICHTEXT_ALL);
68
8db2e3ef
JS
69 wxRichTextDrawingContext context(GetRichTextBuffer());
70 GetRichTextBuffer()->Layout(*GetDC(), context, rect, rect, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT);
03647350 71
44219ff0 72 // Now calculate the page breaks
03647350 73
44219ff0 74 int yOffset = 0;
03647350 75
44219ff0 76 wxRichTextLine* lastLine = NULL;
03647350 77
44219ff0
JS
78 wxRichTextObjectList::compatibility_iterator node = GetRichTextBuffer()->GetChildren().GetFirst();
79 while (node)
80 {
81 // child is a paragraph
82 wxRichTextParagraph* child = wxDynamicCast(node->GetData(), wxRichTextParagraph);
83 wxASSERT (child != NULL);
603f702b 84 if (child)
44219ff0 85 {
603f702b
JS
86 wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst();
87 while (node2)
88 {
89 wxRichTextLine* line = node2->GetData();
ea160b2e 90
603f702b
JS
91 int lineY = child->GetPosition().y + line->GetPosition().y - yOffset;
92 bool hasHardPageBreak = ((node2 == child->GetLines().GetFirst()) && child->GetAttributes().HasPageBreak());
44219ff0 93
603f702b
JS
94 // Break the page if either we're going off the bottom, or this paragraph specifies
95 // an explicit page break
03647350 96
603f702b
JS
97 if (((lineY + line->GetSize().y) > rect.GetBottom()) || hasHardPageBreak)
98 {
b5a1cc93
JS
99 // Only if we're not at the start of the document, and
100 // even then, only if either it's a hard break or if the object
101 // can fit in a whole page (otherwise there's no point in making
102 // the rest of this page blank).
103 if (lastLine && (hasHardPageBreak || (line->GetSize().y <= rect.GetHeight())))
104 {
105 // New page starting at this line
106 int newY = rect.y;
e58471c7 107
b5a1cc93 108 // We increase the offset by the difference between new and old positions
e58471c7 109
b5a1cc93
JS
110 int increaseOffsetBy = lineY - newY;
111 yOffset += increaseOffsetBy;
e58471c7 112
b5a1cc93
JS
113 m_pageBreaksStart.Add(lastStartPos);
114 m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd());
115 m_pageYOffsets.Add(yOffset);
e58471c7 116
b5a1cc93
JS
117 lastStartPos = line->GetAbsoluteRange().GetStart();
118 m_numPages ++;
119 }
44219ff0 120
44219ff0 121 lastLine = line;
03647350 122
603f702b
JS
123 // Now create page breaks for the rest of the line, if it's larger than the page height
124 int contentLeft = line->GetSize().y - rect.GetHeight();
125 while (contentLeft >= 0)
126 {
127 yOffset += rect.GetHeight();
128 contentLeft -= rect.GetHeight();
bb7bbd12 129
603f702b
JS
130 m_pageBreaksStart.Add(lastStartPos);
131 m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd());
132 m_pageYOffsets.Add(yOffset);
b5a1cc93
JS
133
134 m_numPages ++;
bb7bbd12 135 }
603f702b
JS
136 }
137
138 lastLine = line;
139
140 node2 = node2->GetNext();
44219ff0 141 }
44219ff0
JS
142 }
143
144 node = node->GetNext();
145 }
146
147 // Closing page break
e58471c7
JS
148 m_pageBreaksStart.Add(lastStartPos);
149 m_pageBreaksEnd.Add(GetRichTextBuffer()->GetOwnRange().GetEnd());
150 m_pageYOffsets.Add(yOffset);
44219ff0
JS
151 }
152}
153
154bool wxRichTextPrintout::OnBeginDocument(int startPage, int endPage)
155{
156 if (!wxPrintout::OnBeginDocument(startPage, endPage)) return false;
157
158 return true;
159}
160
161bool wxRichTextPrintout::OnPrintPage(int page)
162{
163 wxDC *dc = GetDC();
164 if (dc)
165 {
166 if (HasPage(page))
167 RenderPage(dc, page);
168 return true;
169 }
170 else return false;
171}
172
173void wxRichTextPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
174{
175 *minPage = 1;
176 *maxPage = m_numPages;
177 *selPageFrom = 1;
178 *selPageTo = m_numPages;
179}
180
181bool wxRichTextPrintout::HasPage(int pageNum)
182{
183 return pageNum > 0 && pageNum <= m_numPages;
184}
185
186void wxRichTextPrintout::RenderPage(wxDC *dc, int page)
187{
188 if (!GetRichTextBuffer())
189 return;
190
191 wxBusyCursor wait;
03647350 192
44219ff0
JS
193 wxRect textRect, headerRect, footerRect;
194
195 /// Sets the DC scaling and returns important page rectangles
196 CalculateScaling(dc, textRect, headerRect, footerRect);
197
198 if (page > 1 || m_headerFooterData.GetShowOnFirstPage())
199 {
a1b806b9 200 if (m_headerFooterData.GetFont().IsOk())
44219ff0
JS
201 dc->SetFont(m_headerFooterData.GetFont());
202 else
203 dc->SetFont(*wxNORMAL_FONT);
a1b806b9 204 if (m_headerFooterData.GetTextColour().IsOk())
44219ff0
JS
205 dc->SetTextForeground(m_headerFooterData.GetTextColour());
206 else
207 dc->SetTextForeground(*wxBLACK);
04ee05f9 208 dc->SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
44219ff0 209
03647350 210 // Draw header, if any
44219ff0
JS
211 wxRichTextOddEvenPage oddEven = ((page % 2) == 1) ? wxRICHTEXT_PAGE_ODD : wxRICHTEXT_PAGE_EVEN;
212
213 wxString headerTextCentre = m_headerFooterData.GetHeaderText(oddEven, wxRICHTEXT_PAGE_CENTRE);
214 wxString headerTextLeft = m_headerFooterData.GetHeaderText(oddEven, wxRICHTEXT_PAGE_LEFT);
215 wxString headerTextRight = m_headerFooterData.GetHeaderText(oddEven, wxRICHTEXT_PAGE_RIGHT);
216
217 if (!headerTextLeft.IsEmpty())
218 {
219 SubstituteKeywords(headerTextLeft, GetTitle(), page, m_numPages);
220
221 //int tx, ty;
222 //dc->GetTextExtent(headerTextLeft, & tx, & ty);
03647350 223
44219ff0
JS
224 int x = headerRect.GetLeft();
225 int y = headerRect.GetX();
226 dc->DrawText(headerTextLeft, x, y);
227 }
228 if (!headerTextCentre.IsEmpty())
229 {
230 SubstituteKeywords(headerTextCentre, GetTitle(), page, m_numPages);
231
232 int tx, ty;
233 dc->GetTextExtent(headerTextCentre, & tx, & ty);
234
235 int x = headerRect.GetWidth()/2 - tx/2 + headerRect.GetLeft();
236 int y = headerRect.GetY();
237 dc->DrawText(headerTextCentre, x, y);
238 }
239 if (!headerTextRight.IsEmpty())
240 {
241 SubstituteKeywords(headerTextRight, GetTitle(), page, m_numPages);
242
243 int tx, ty;
244 dc->GetTextExtent(headerTextRight, & tx, & ty);
245
246 int x = headerRect.GetRight() - tx;
247 int y = headerRect.GetY();
248 dc->DrawText(headerTextRight, x, y);
249 }
250
03647350 251 // Draw footer, if any
44219ff0
JS
252 wxString footerTextCentre = m_headerFooterData.GetFooterText(oddEven, wxRICHTEXT_PAGE_CENTRE);
253 wxString footerTextLeft = m_headerFooterData.GetFooterText(oddEven, wxRICHTEXT_PAGE_LEFT);
254 wxString footerTextRight = m_headerFooterData.GetFooterText(oddEven, wxRICHTEXT_PAGE_RIGHT);
255
256 if (!footerTextLeft.IsEmpty())
257 {
258 SubstituteKeywords(footerTextLeft, GetTitle(), page, m_numPages);
259
260 int tx, ty;
261 dc->GetTextExtent(footerTextLeft, & tx, & ty);
262
263 int x = footerRect.GetLeft();
264 int y = footerRect.GetBottom() - ty;
265 dc->DrawText(footerTextLeft, x, y);
266 }
267 if (!footerTextCentre.IsEmpty())
268 {
269 SubstituteKeywords(footerTextCentre, GetTitle(), page, m_numPages);
270
271 int tx, ty;
272 dc->GetTextExtent(footerTextCentre, & tx, & ty);
273
274 int x = footerRect.GetWidth()/2 - tx/2 + footerRect.GetLeft();
275 int y = footerRect.GetBottom() - ty;
276 dc->DrawText(footerTextCentre, x, y);
277 }
278 if (!footerTextRight.IsEmpty())
279 {
280 SubstituteKeywords(footerTextRight, GetTitle(), page, m_numPages);
281
282 int tx, ty;
283 dc->GetTextExtent(footerTextRight, & tx, & ty);
284
285 int x = footerRect.GetRight() - tx;
286 int y = footerRect.GetBottom() - ty;
287 dc->DrawText(footerTextRight, x, y);
288 }
03647350 289 }
44219ff0
JS
290
291 wxRichTextRange rangeToDraw(m_pageBreaksStart[page-1], m_pageBreaksEnd[page-1]);
bb7bbd12 292
603f702b
JS
293 wxPoint oldOrigin = dc->GetLogicalOrigin();
294 double scaleX, scaleY;
295 dc->GetUserScale(& scaleX, & scaleY);
296
297 int yOffset = 0;
298 if (page > 1)
299 yOffset = m_pageYOffsets[page-2];
bb7bbd12 300
603f702b
JS
301 if (yOffset != oldOrigin.y)
302 dc->SetLogicalOrigin(oldOrigin.x, oldOrigin.y + yOffset);
303
304 dc->SetClippingRegion(wxRect(textRect.x, textRect.y + yOffset, textRect.width, textRect.height));
305
8db2e3ef
JS
306 wxRichTextDrawingContext context(GetRichTextBuffer());
307 GetRichTextBuffer()->Draw(*dc, context, rangeToDraw, wxRichTextSelection(), textRect, 0 /* descent */, wxRICHTEXT_DRAW_IGNORE_CACHE|wxRICHTEXT_DRAW_PRINT /* flags */);
603f702b
JS
308
309 dc->DestroyClippingRegion();
44219ff0 310
603f702b
JS
311 if (yOffset != oldOrigin.y)
312 dc->SetLogicalOrigin(oldOrigin.x, oldOrigin.y);
44219ff0
JS
313}
314
315void wxRichTextPrintout::SetMargins(int top, int bottom, int left, int right)
316{
317 m_marginTop = top;
318 m_marginBottom = bottom;
319 m_marginLeft = left;
320 m_marginRight = right;
321}
322
323/// Calculate scaling and rectangles, setting the device context scaling
324void wxRichTextPrintout::CalculateScaling(wxDC* dc, wxRect& textRect, wxRect& headerRect, wxRect& footerRect)
325{
326 // Get the logical pixels per inch of screen and printer
327 int ppiScreenX, ppiScreenY;
328 GetPPIScreen(&ppiScreenX, &ppiScreenY);
329 int ppiPrinterX, ppiPrinterY;
330 GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
331
332 // This scales the DC so that the printout roughly represents the
333 // the screen scaling.
334 float scale = (float)((float)ppiPrinterX/(float)ppiScreenX);
335
336 // Now we have to check in case our real page size is reduced
337 // (e.g. because we're drawing to a print preview memory DC)
338 int pageWidth, pageHeight;
339 int w, h;
340 dc->GetSize(&w, &h);
341 GetPageSizePixels(&pageWidth, &pageHeight);
03647350 342
44219ff0
JS
343 // If printer pageWidth == current DC width, then this doesn't
344 // change. But w might be the preview bitmap width, so scale down.
345 float previewScale = (float)(w/(float)pageWidth);
346 float overallScale = scale * previewScale;
347
348 // The dimensions used for indentation etc. have to be unscaled
349 // during printing to be correct when scaling is applied.
ed98f424
JS
350 // Also, correct the conversions in wxRTC using DC instead of print DC.
351 m_richTextBuffer->SetScale(scale * float(dc->GetPPI().x)/float(ppiPrinterX));
03647350 352
44219ff0
JS
353 // Calculate margins
354 int marginLeft = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_marginLeft);
355 int marginTop = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_marginTop);
356 int marginRight = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_marginRight);
357 int marginBottom = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_marginBottom);
03647350 358
44219ff0
JS
359 // Header and footer margins
360 int headerMargin = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_headerFooterData.GetHeaderMargin());
361 int footerMargin = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_headerFooterData.GetFooterMargin());
03647350 362
44219ff0
JS
363 dc->SetUserScale(overallScale, overallScale);
364
2786b623
JS
365 wxRect rect((int) (marginLeft/scale), (int) (marginTop/scale),
366 (int) ((pageWidth - marginLeft - marginRight)/scale), (int)((pageHeight - marginTop - marginBottom)/scale));
03647350 367
44219ff0
JS
368 headerRect = wxRect(0, 0, 0, 0);
369
370 if (!m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT).IsEmpty() ||
371 !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_CENTRE).IsEmpty() ||
372 !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_RIGHT).IsEmpty() ||
373
374 !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_LEFT).IsEmpty() ||
375 !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_CENTRE).IsEmpty() ||
376 !m_headerFooterData.GetHeaderText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_RIGHT).IsEmpty())
377 {
a1b806b9 378 if (m_headerFooterData.GetFont().IsOk())
44219ff0
JS
379 dc->SetFont(m_headerFooterData.GetFont());
380 else
381 dc->SetFont(*wxNORMAL_FONT);
03647350 382
44219ff0 383 int charHeight = dc->GetCharHeight();
03647350 384
2786b623 385 int headerHeight = (int) (charHeight + headerMargin/scale);
44219ff0
JS
386
387 headerRect = wxRect(rect.x, rect.y, rect.width, headerHeight);
388
389 rect.y += headerHeight;
03647350 390 rect.height -= headerHeight;
44219ff0
JS
391 }
392
393 footerRect = wxRect(0, 0, 0, 0);
394
395 if (!m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT).IsEmpty() ||
396 !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_CENTRE).IsEmpty() ||
397 !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_RIGHT).IsEmpty() ||
398
399 !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_LEFT).IsEmpty() ||
400 !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_CENTRE).IsEmpty() ||
401 !m_headerFooterData.GetFooterText(wxRICHTEXT_PAGE_EVEN, wxRICHTEXT_PAGE_RIGHT).IsEmpty())
402 {
a1b806b9 403 if (m_headerFooterData.GetFont().IsOk())
44219ff0
JS
404 dc->SetFont(m_headerFooterData.GetFont());
405 else
406 dc->SetFont(*wxNORMAL_FONT);
03647350 407
44219ff0 408 int charHeight = dc->GetCharHeight();
03647350 409
2786b623 410 int footerHeight = (int) (charHeight + footerMargin/scale);
44219ff0
JS
411
412 footerRect = wxRect(rect.x, rect.y + rect.height, rect.width, footerHeight);
413
03647350 414 rect.height -= footerHeight;
44219ff0
JS
415 }
416
417 textRect = rect;
418}
419
420bool wxRichTextPrintout::SubstituteKeywords(wxString& str, const wxString& title, int pageNum, int pageCount)
421{
422 wxString num;
423
424 num.Printf(wxT("%i"), pageNum);
425 str.Replace(wxT("@PAGENUM@"), num);
426
427 num.Printf(wxT("%lu"), (unsigned long) pageCount);
428 str.Replace(wxT("@PAGESCNT@"), num);
429
430 wxDateTime now = wxDateTime::Now();
431
432 str.Replace(wxT("@DATE@"), now.FormatDate());
433 str.Replace(wxT("@TIME@"), now.FormatTime());
434
435 str.Replace(wxT("@TITLE@"), title);
436
437 return true;
438}
439
440/*!
441 * wxRichTextPrinting
442 */
443
444wxRichTextPrinting::wxRichTextPrinting(const wxString& name, wxWindow *parentWindow)
445{
446 m_richTextBufferPrinting = NULL;
447 m_richTextBufferPreview = NULL;
448
449 m_parentWindow = parentWindow;
450 m_title = name;
451 m_printData = NULL;
03647350 452
44219ff0
JS
453 m_previewRect = wxRect(wxPoint(100, 100), wxSize(800, 800));
454
455 m_pageSetupData = new wxPageSetupDialogData;
456 m_pageSetupData->EnableMargins(true);
457 m_pageSetupData->SetMarginTopLeft(wxPoint(25, 25));
458 m_pageSetupData->SetMarginBottomRight(wxPoint(25, 25));
459}
460
461wxRichTextPrinting::~wxRichTextPrinting()
462{
463 delete m_printData;
464 delete m_pageSetupData;
465 delete m_richTextBufferPrinting;
466 delete m_richTextBufferPreview;
467}
468
469wxPrintData *wxRichTextPrinting::GetPrintData()
470{
471 if (m_printData == NULL)
472 m_printData = new wxPrintData();
473 return m_printData;
474}
475
5c0a71a2
JS
476/// Set print and page setup data
477void wxRichTextPrinting::SetPrintData(const wxPrintData& printData)
478{
479 (*GetPrintData()) = printData;
480}
481
7193abfb 482void wxRichTextPrinting::SetPageSetupData(const wxPageSetupDialogData& pageSetupData)
5c0a71a2
JS
483{
484 (*GetPageSetupData()) = pageSetupData;
485}
486
44219ff0
JS
487/// Set the rich text buffer pointer, deleting the existing object if present
488void wxRichTextPrinting::SetRichTextBufferPrinting(wxRichTextBuffer* buf)
489{
490 if (m_richTextBufferPrinting)
491 {
492 delete m_richTextBufferPrinting;
493 m_richTextBufferPrinting = NULL;
494 }
495 m_richTextBufferPrinting = buf;
496}
497
498void wxRichTextPrinting::SetRichTextBufferPreview(wxRichTextBuffer* buf)
499{
500 if (m_richTextBufferPreview)
501 {
502 delete m_richTextBufferPreview;
503 m_richTextBufferPreview = NULL;
504 }
505 m_richTextBufferPreview = buf;
506}
507
7e81e3a7 508#if wxUSE_FFILE && wxUSE_STREAMS
44219ff0
JS
509bool wxRichTextPrinting::PreviewFile(const wxString& richTextFile)
510{
511 SetRichTextBufferPreview(new wxRichTextBuffer);
512
513 if (!m_richTextBufferPreview->LoadFile(richTextFile))
514 {
515 SetRichTextBufferPreview(NULL);
516 return false;
517 }
518 else
519 SetRichTextBufferPrinting(new wxRichTextBuffer(*m_richTextBufferPreview));
03647350 520
44219ff0
JS
521 wxRichTextPrintout *p1 = CreatePrintout();
522 p1->SetRichTextBuffer(m_richTextBufferPreview);
523
524 wxRichTextPrintout *p2 = CreatePrintout();
525 p2->SetRichTextBuffer(m_richTextBufferPrinting);
526 return DoPreview(p1, p2);
527}
7e81e3a7 528#endif // wxUSE_FFILE && wxUSE_STREAMS
44219ff0
JS
529
530bool wxRichTextPrinting::PreviewBuffer(const wxRichTextBuffer& buffer)
531{
532 SetRichTextBufferPreview(new wxRichTextBuffer(buffer));
533 SetRichTextBufferPrinting(new wxRichTextBuffer(buffer));
534
535 wxRichTextPrintout *p1 = CreatePrintout();
536 p1->SetRichTextBuffer(m_richTextBufferPreview);
03647350 537
44219ff0
JS
538 wxRichTextPrintout *p2 = CreatePrintout();
539 p2->SetRichTextBuffer(m_richTextBufferPrinting);
540
541 return DoPreview(p1, p2);
542}
543
7e81e3a7 544#if wxUSE_FFILE && wxUSE_STREAMS
148d83b5 545bool wxRichTextPrinting::PrintFile(const wxString& richTextFile, bool showPrintDialog)
44219ff0
JS
546{
547 SetRichTextBufferPrinting(new wxRichTextBuffer);
548
549 if (!m_richTextBufferPrinting->LoadFile(richTextFile))
550 {
551 SetRichTextBufferPrinting(NULL);
552 return false;
553 }
554
555 wxRichTextPrintout *p = CreatePrintout();
556 p->SetRichTextBuffer(m_richTextBufferPrinting);
557
148d83b5 558 bool ret = DoPrint(p, showPrintDialog);
44219ff0
JS
559 delete p;
560 return ret;
561}
7e81e3a7 562#endif // wxUSE_FFILE && wxUSE_STREAMS
44219ff0 563
148d83b5 564bool wxRichTextPrinting::PrintBuffer(const wxRichTextBuffer& buffer, bool showPrintDialog)
44219ff0
JS
565{
566 SetRichTextBufferPrinting(new wxRichTextBuffer(buffer));
567
568 wxRichTextPrintout *p = CreatePrintout();
569 p->SetRichTextBuffer(m_richTextBufferPrinting);
570
148d83b5 571 bool ret = DoPrint(p, showPrintDialog);
44219ff0
JS
572 delete p;
573 return ret;
574}
575
576bool wxRichTextPrinting::DoPreview(wxRichTextPrintout *printout1, wxRichTextPrintout *printout2)
577{
578 // Pass two printout objects: for preview, and possible printing.
579 wxPrintDialogData printDialogData(*GetPrintData());
580 wxPrintPreview *preview = new wxPrintPreview(printout1, printout2, &printDialogData);
a1b806b9 581 if (!preview->IsOk())
44219ff0
JS
582 {
583 delete preview;
584 return false;
585 }
586
587 wxPreviewFrame *frame = new wxPreviewFrame(preview, m_parentWindow,
588 m_title + _(" Preview"),
589 m_previewRect.GetPosition(), m_previewRect.GetSize());
590 frame->Centre(wxBOTH);
591 frame->Initialize();
592 frame->Show(true);
593 return true;
594}
595
148d83b5 596bool wxRichTextPrinting::DoPrint(wxRichTextPrintout *printout, bool showPrintDialog)
44219ff0
JS
597{
598 wxPrintDialogData printDialogData(*GetPrintData());
599 wxPrinter printer(&printDialogData);
600
148d83b5 601 if (!printer.Print(m_parentWindow, printout, showPrintDialog))
44219ff0
JS
602 {
603 return false;
604 }
605
606 (*GetPrintData()) = printer.GetPrintDialogData().GetPrintData();
607 return true;
608}
609
610void wxRichTextPrinting::PageSetup()
611{
a1b806b9 612 if (!GetPrintData()->IsOk())
44219ff0
JS
613 {
614 wxLogError(_("There was a problem during page setup: you may need to set a default printer."));
615 return;
616 }
617
618 m_pageSetupData->SetPrintData(*GetPrintData());
619 wxPageSetupDialog pageSetupDialog(m_parentWindow, m_pageSetupData);
620
621 if (pageSetupDialog.ShowModal() == wxID_OK)
622 {
623 (*GetPrintData()) = pageSetupDialog.GetPageSetupData().GetPrintData();
624 (*m_pageSetupData) = pageSetupDialog.GetPageSetupData();
625 }
626}
627
628wxRichTextPrintout *wxRichTextPrinting::CreatePrintout()
629{
630 wxRichTextPrintout *p = new wxRichTextPrintout(m_title);
631
632 p->SetHeaderFooterData(GetHeaderFooterData());
633 p->SetMargins(10*m_pageSetupData->GetMarginTopLeft().y,
634 10*m_pageSetupData->GetMarginBottomRight().y,
635 10*m_pageSetupData->GetMarginTopLeft().x,
636 10*m_pageSetupData->GetMarginBottomRight().x);
637
638 return p;
639}
640
641/// Set/get header text, e.g. wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT
642void wxRichTextPrinting::SetHeaderText(const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location)
643{
644 m_headerFooterData.SetHeaderText(text, page, location);
645}
646
647wxString wxRichTextPrinting::GetHeaderText(wxRichTextOddEvenPage page, wxRichTextPageLocation location) const
648{
649 return m_headerFooterData.GetHeaderText(page, location);
650}
651
652/// Set/get footer text, e.g. wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT
653void wxRichTextPrinting::SetFooterText(const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location)
654{
655 m_headerFooterData.SetFooterText(text, page, location);
656}
657
658wxString wxRichTextPrinting::GetFooterText(wxRichTextOddEvenPage page, wxRichTextPageLocation location) const
659{
660 return m_headerFooterData.GetFooterText(page, location);
661}
662
663/*!
664 * Header/footer data
665 */
666
667IMPLEMENT_CLASS(wxRichTextHeaderFooterData, wxObject)
668
669/// Copy
670void wxRichTextHeaderFooterData::Copy(const wxRichTextHeaderFooterData& data)
671{
672 int i;
673 for (i = 0; i < 12; i++)
674 m_text[i] = data.m_text[i];
675 m_font = data.m_font;
676 m_colour = data.m_colour;
677 m_headerMargin = data.m_headerMargin;
678 m_footerMargin = data.m_footerMargin;
679 m_showOnFirstPage = data.m_showOnFirstPage;
680}
681
682/// Set/get text
683void wxRichTextHeaderFooterData::SetText(const wxString& text, int headerFooter, wxRichTextOddEvenPage page, wxRichTextPageLocation location)
684{
685 int idx = headerFooter + (2 * (int) page) + (4 * (int) location);
686 wxASSERT( idx >= 0 && idx < 12 );
687
688 if (idx >= 0 && idx < 12)
689 m_text[idx] = text;
690}
691
692wxString wxRichTextHeaderFooterData::GetText(int headerFooter, wxRichTextOddEvenPage page, wxRichTextPageLocation location) const
693{
694 int idx = headerFooter + (2 * (int) page) + (4 * (int) location);
695 wxASSERT( idx >= 0 && idx < 12 );
696
697 if (idx >= 0 && idx < 12)
698 return m_text[idx];
699 else
700 return wxEmptyString;
701}
702
703/// Set/get header text, e.g. wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT
704void wxRichTextHeaderFooterData::SetHeaderText(const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location)
705{
706 if (page == wxRICHTEXT_PAGE_ALL)
707 {
708 SetText(text, 0, wxRICHTEXT_PAGE_ODD, location);
709 SetText(text, 0, wxRICHTEXT_PAGE_EVEN, location);
710 }
711 else
712 SetText(text, 0, page, location);
713}
714
715wxString wxRichTextHeaderFooterData::GetHeaderText(wxRichTextOddEvenPage page, wxRichTextPageLocation location) const
716{
717 return GetText(0, page, location);
718}
719
720/// Set/get footer text, e.g. wxRICHTEXT_PAGE_ODD, wxRICHTEXT_PAGE_LEFT
721void wxRichTextHeaderFooterData::SetFooterText(const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location)
722{
723 if (page == wxRICHTEXT_PAGE_ALL)
724 {
725 SetText(text, 1, wxRICHTEXT_PAGE_ODD, location);
726 SetText(text, 1, wxRICHTEXT_PAGE_EVEN, location);
727 }
728 else
729 SetText(text, 1, page, location);
730}
731
732wxString wxRichTextHeaderFooterData::GetFooterText(wxRichTextOddEvenPage page, wxRichTextPageLocation location) const
733{
734 return GetText(1, page, location);
735}
736
737/// Clear all text
738void wxRichTextHeaderFooterData::Clear()
739{
740 int i;
741 for (i = 0; i < 12; i++)
742 m_text[i] = wxEmptyString;
743}
744
745#endif // wxUSE_RICHTEXT & wxUSE_PRINTING_ARCHITECTURE
746