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