]> git.saurik.com Git - wxWidgets.git/blob - src/richtext/richtextprint.cpp
follow up parent chain to properly support modal dialog parents, see #15383
[wxWidgets.git] / src / richtext / richtextprint.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/richtext/richtextprint.cpp
3 // Purpose: Rich text printing classes
4 // Author: Julian Smart
5 // Created: 2006-10-24
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
37 wxRichTextPrintout::wxRichTextPrintout(const wxString& title) : wxPrintout(title)
38 {
39 m_numPages = wxRICHTEXT_PRINT_MAX_PAGES;
40
41 SetMargins(); // to default values
42 }
43
44 wxRichTextPrintout::~wxRichTextPrintout()
45 {
46 }
47
48 void wxRichTextPrintout::OnPreparePrinting()
49 {
50 wxBusyCursor wait;
51
52 m_numPages = 1;
53
54 m_pageBreaksStart.Clear();
55 m_pageBreaksEnd.Clear();
56 m_pageYOffsets.Clear();
57
58 int lastStartPos = 0;
59
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
69 wxRichTextDrawingContext context(GetRichTextBuffer());
70 GetRichTextBuffer()->Layout(*GetDC(), context, rect, rect, wxRICHTEXT_FIXED_WIDTH|wxRICHTEXT_VARIABLE_HEIGHT);
71
72 // Now calculate the page breaks
73
74 int yOffset = 0;
75
76 wxRichTextLine* lastLine = NULL;
77
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);
84 if (child)
85 {
86 wxRichTextLineList::compatibility_iterator node2 = child->GetLines().GetFirst();
87 while (node2)
88 {
89 wxRichTextLine* line = node2->GetData();
90
91 int lineY = child->GetPosition().y + line->GetPosition().y - yOffset;
92 bool hasHardPageBreak = ((node2 == child->GetLines().GetFirst()) && child->GetAttributes().HasPageBreak());
93
94 // Break the page if either we're going off the bottom, or this paragraph specifies
95 // an explicit page break
96
97 if (((lineY + line->GetSize().y) > rect.GetBottom()) || hasHardPageBreak)
98 {
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;
107
108 // We increase the offset by the difference between new and old positions
109
110 int increaseOffsetBy = lineY - newY;
111 yOffset += increaseOffsetBy;
112
113 m_pageBreaksStart.Add(lastStartPos);
114 m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd());
115 m_pageYOffsets.Add(yOffset);
116
117 lastStartPos = line->GetAbsoluteRange().GetStart();
118 m_numPages ++;
119 }
120
121 lastLine = line;
122
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();
129
130 m_pageBreaksStart.Add(lastStartPos);
131 m_pageBreaksEnd.Add(lastLine->GetAbsoluteRange().GetEnd());
132 m_pageYOffsets.Add(yOffset);
133
134 m_numPages ++;
135 }
136 }
137
138 lastLine = line;
139
140 node2 = node2->GetNext();
141 }
142 }
143
144 node = node->GetNext();
145 }
146
147 // Closing page break
148 m_pageBreaksStart.Add(lastStartPos);
149 m_pageBreaksEnd.Add(GetRichTextBuffer()->GetOwnRange().GetEnd());
150 m_pageYOffsets.Add(yOffset);
151 }
152 }
153
154 bool wxRichTextPrintout::OnBeginDocument(int startPage, int endPage)
155 {
156 if (!wxPrintout::OnBeginDocument(startPage, endPage)) return false;
157
158 return true;
159 }
160
161 bool 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
173 void 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
181 bool wxRichTextPrintout::HasPage(int pageNum)
182 {
183 return pageNum > 0 && pageNum <= m_numPages;
184 }
185
186 void wxRichTextPrintout::RenderPage(wxDC *dc, int page)
187 {
188 if (!GetRichTextBuffer())
189 return;
190
191 wxBusyCursor wait;
192
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 {
200 if (m_headerFooterData.GetFont().IsOk())
201 dc->SetFont(m_headerFooterData.GetFont());
202 else
203 dc->SetFont(*wxNORMAL_FONT);
204 if (m_headerFooterData.GetTextColour().IsOk())
205 dc->SetTextForeground(m_headerFooterData.GetTextColour());
206 else
207 dc->SetTextForeground(*wxBLACK);
208 dc->SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
209
210 // Draw header, if any
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);
223
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
251 // Draw footer, if any
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 }
289 }
290
291 wxRichTextRange rangeToDraw(m_pageBreaksStart[page-1], m_pageBreaksEnd[page-1]);
292
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];
300
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
306 wxRichTextDrawingContext context(GetRichTextBuffer());
307 GetRichTextBuffer()->Draw(*dc, context, rangeToDraw, wxRichTextSelection(), textRect, 0 /* descent */, wxRICHTEXT_DRAW_IGNORE_CACHE|wxRICHTEXT_DRAW_PRINT /* flags */);
308
309 dc->DestroyClippingRegion();
310
311 if (yOffset != oldOrigin.y)
312 dc->SetLogicalOrigin(oldOrigin.x, oldOrigin.y);
313 }
314
315 void 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
324 void 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);
342
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.
350 // Also, correct the conversions in wxRTC using DC instead of print DC.
351 m_richTextBuffer->SetScale(scale * float(dc->GetPPI().x)/float(ppiPrinterX));
352
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);
358
359 // Header and footer margins
360 int headerMargin = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_headerFooterData.GetHeaderMargin());
361 int footerMargin = wxRichTextObject::ConvertTenthsMMToPixels(ppiPrinterX, m_headerFooterData.GetFooterMargin());
362
363 dc->SetUserScale(overallScale, overallScale);
364
365 wxRect rect((int) (marginLeft/scale), (int) (marginTop/scale),
366 (int) ((pageWidth - marginLeft - marginRight)/scale), (int)((pageHeight - marginTop - marginBottom)/scale));
367
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 {
378 if (m_headerFooterData.GetFont().IsOk())
379 dc->SetFont(m_headerFooterData.GetFont());
380 else
381 dc->SetFont(*wxNORMAL_FONT);
382
383 int charHeight = dc->GetCharHeight();
384
385 int headerHeight = (int) (charHeight + headerMargin/scale);
386
387 headerRect = wxRect(rect.x, rect.y, rect.width, headerHeight);
388
389 rect.y += headerHeight;
390 rect.height -= headerHeight;
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 {
403 if (m_headerFooterData.GetFont().IsOk())
404 dc->SetFont(m_headerFooterData.GetFont());
405 else
406 dc->SetFont(*wxNORMAL_FONT);
407
408 int charHeight = dc->GetCharHeight();
409
410 int footerHeight = (int) (charHeight + footerMargin/scale);
411
412 footerRect = wxRect(rect.x, rect.y + rect.height, rect.width, footerHeight);
413
414 rect.height -= footerHeight;
415 }
416
417 textRect = rect;
418 }
419
420 bool 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
444 wxRichTextPrinting::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;
452
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
461 wxRichTextPrinting::~wxRichTextPrinting()
462 {
463 delete m_printData;
464 delete m_pageSetupData;
465 delete m_richTextBufferPrinting;
466 delete m_richTextBufferPreview;
467 }
468
469 wxPrintData *wxRichTextPrinting::GetPrintData()
470 {
471 if (m_printData == NULL)
472 m_printData = new wxPrintData();
473 return m_printData;
474 }
475
476 /// Set print and page setup data
477 void wxRichTextPrinting::SetPrintData(const wxPrintData& printData)
478 {
479 (*GetPrintData()) = printData;
480 }
481
482 void wxRichTextPrinting::SetPageSetupData(const wxPageSetupDialogData& pageSetupData)
483 {
484 (*GetPageSetupData()) = pageSetupData;
485 }
486
487 /// Set the rich text buffer pointer, deleting the existing object if present
488 void 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
498 void 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
508 #if wxUSE_FFILE && wxUSE_STREAMS
509 bool 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));
520
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 }
528 #endif // wxUSE_FFILE && wxUSE_STREAMS
529
530 bool 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);
537
538 wxRichTextPrintout *p2 = CreatePrintout();
539 p2->SetRichTextBuffer(m_richTextBufferPrinting);
540
541 return DoPreview(p1, p2);
542 }
543
544 #if wxUSE_FFILE && wxUSE_STREAMS
545 bool wxRichTextPrinting::PrintFile(const wxString& richTextFile, bool showPrintDialog)
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
558 bool ret = DoPrint(p, showPrintDialog);
559 delete p;
560 return ret;
561 }
562 #endif // wxUSE_FFILE && wxUSE_STREAMS
563
564 bool wxRichTextPrinting::PrintBuffer(const wxRichTextBuffer& buffer, bool showPrintDialog)
565 {
566 SetRichTextBufferPrinting(new wxRichTextBuffer(buffer));
567
568 wxRichTextPrintout *p = CreatePrintout();
569 p->SetRichTextBuffer(m_richTextBufferPrinting);
570
571 bool ret = DoPrint(p, showPrintDialog);
572 delete p;
573 return ret;
574 }
575
576 bool 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);
581 if (!preview->IsOk())
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
596 bool wxRichTextPrinting::DoPrint(wxRichTextPrintout *printout, bool showPrintDialog)
597 {
598 wxPrintDialogData printDialogData(*GetPrintData());
599 wxPrinter printer(&printDialogData);
600
601 if (!printer.Print(m_parentWindow, printout, showPrintDialog))
602 {
603 return false;
604 }
605
606 (*GetPrintData()) = printer.GetPrintDialogData().GetPrintData();
607 return true;
608 }
609
610 void wxRichTextPrinting::PageSetup()
611 {
612 if (!GetPrintData()->IsOk())
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
628 wxRichTextPrintout *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
642 void wxRichTextPrinting::SetHeaderText(const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location)
643 {
644 m_headerFooterData.SetHeaderText(text, page, location);
645 }
646
647 wxString 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
653 void wxRichTextPrinting::SetFooterText(const wxString& text, wxRichTextOddEvenPage page, wxRichTextPageLocation location)
654 {
655 m_headerFooterData.SetFooterText(text, page, location);
656 }
657
658 wxString wxRichTextPrinting::GetFooterText(wxRichTextOddEvenPage page, wxRichTextPageLocation location) const
659 {
660 return m_headerFooterData.GetFooterText(page, location);
661 }
662
663 /*!
664 * Header/footer data
665 */
666
667 IMPLEMENT_CLASS(wxRichTextHeaderFooterData, wxObject)
668
669 /// Copy
670 void 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
683 void 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
692 wxString 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
704 void 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
715 wxString 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
721 void 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
732 wxString wxRichTextHeaderFooterData::GetFooterText(wxRichTextOddEvenPage page, wxRichTextPageLocation location) const
733 {
734 return GetText(1, page, location);
735 }
736
737 /// Clear all text
738 void 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