1 /*
2 * This file is part of the Code::Blocks IDE and licensed under the GNU Lesser General Public License, version 3
3 * http://www.gnu.org/licenses/lgpl-3.0.html
4 *
5 * $Revision: 9426 $
6 * $Id: cbeditorprintout.cpp 9426 2013-11-02 19:42:20Z alpha0010 $
7 * $HeadURL: svn://svn.code.sf.net/p/codeblocks/code/branches/release-20.xx/src/sdk/cbeditorprintout.cpp $
8 */
9
10 #include "sdk_precomp.h"
11
12 #ifndef CB_PRECOMP
13 #include <wx/dc.h>
14
15 #include "manager.h"
16 #include "logmanager.h"
17 #include "cbeditor.h"
18 #endif
19 #include "cbstyledtextctrl.h"
20
21 #include "cbeditorprintout.h"
22 #include "printing_types.h"
23 #include <wx/paper.h>
24
cbEditorPrintout(const wxString & title,cbStyledTextCtrl * control,bool selectionOnly)25 cbEditorPrintout::cbEditorPrintout(const wxString& title, cbStyledTextCtrl* control, bool selectionOnly)
26 : wxPrintout(title),
27 m_TextControl(control)
28 {
29 // ctor
30 m_SelStart = 0;
31 m_SelEnd = control->GetLength();
32 if (selectionOnly && !control->GetSelectedText().IsEmpty())
33 {
34 m_SelStart = control->GetSelectionStart();
35 m_SelEnd = control->GetSelectionEnd();
36 }
37 m_pPageSelStart = new wxArrayInt;
38 }
39
~cbEditorPrintout()40 cbEditorPrintout::~cbEditorPrintout()
41 {
42 // dtor
43 delete m_pPageSelStart;
44 m_pPageSelStart = nullptr;
45 }
46
OnPrintPage(int page)47 bool cbEditorPrintout::OnPrintPage(int page)
48 {
49 wxDC *dc = GetDC();
50 if (dc)
51 {
52 // scale DC
53 ScaleDC(dc);
54
55 // print selected page
56 int maxpage = m_pPageSelStart->GetCount();
57 if (page && page<maxpage)
58 m_printed = (*m_pPageSelStart)[page-1];
59 else
60 {
61 Manager::Get()->GetLogManager()->DebugLog(F(_T("OnPrintPage ERROR: page = %d , maxpage = %d"), page, maxpage));
62 return false;
63 }
64
65 //Manager::Get()->GetLogManager()->DebugLog(_T("OnPrintPage: page %d , m_printed %d"), page, m_printed);
66 m_printed = m_TextControl->FormatRange (1, m_printed, m_SelEnd,
67 dc, dc, m_printRect, m_pageRect);
68 return true;
69 }
70 return false;
71 }
72
HasPage(cb_unused int page)73 bool cbEditorPrintout::HasPage(cb_unused int page)
74 {
75 return (m_printed < m_SelEnd);
76 }
77
GetPageInfo(int * minPage,int * maxPage,int * selPageFrom,int * selPageTo)78 void cbEditorPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
79 {
80 // initialize values
81 *minPage = 0;
82 *maxPage = 0;
83 *selPageFrom = 0;
84 *selPageTo = 0;
85 // get print page information and convert to printer pixels
86 wxSize ppiScr;
87 GetPPIScreen (&ppiScr.x, &ppiScr.y);
88 if (ppiScr.x == 0 || ppiScr.y == 0)
89 {
90 // guess
91 ppiScr.x = 96;
92 ppiScr.y = 96;
93 }
94
95 wxPrintData* ppd = &(g_printer->GetPrintDialogData().GetPrintData());
96 // We cannot use GetSize from wxPrintData, because it always returns -1 for page.x and page.y,
97 wxPrintPaperDatabase paperDB;
98 paperDB.CreateDatabase();
99 wxSize page=paperDB.GetSize(ppd->GetPaperId());
100 if(ppd->GetOrientation() == wxLANDSCAPE )
101 {
102 int temp = page.x;
103 page.x = page.y;
104 page.y = temp;
105 }
106
107 // We have to divide through 254 instead of 25.4, because GetSize() of paperDB returns tenth of millimeters
108 page.x = static_cast<int> (page.x * ppiScr.x / 254);
109 page.y = static_cast<int> (page.y * ppiScr.y / 254);
110 m_pageRect = wxRect (0,
111 0,
112 page.x,
113 page.y);
114 // get margins information and convert to printer pixels
115 int top = 15; // default 25
116 int bottom = 15; // default 25
117 int left = 20; // default 20
118 int right = 15; // default 20
119 // TODO (Tiwag#1#): get margins from PageSetup Dialog
120 // wxPoint (top, left) = g_pageSetupData->GetMarginTopLeft();
121 // wxPoint (bottom, right) = g_pageSetupData->GetMarginBottomRight();
122 top = static_cast<int> (top * ppiScr.y / 25.4);
123 bottom = static_cast<int> (bottom * ppiScr.y / 25.4);
124 left = static_cast<int> (left * ppiScr.x / 25.4);
125 right = static_cast<int> (right * ppiScr.x / 25.4);
126 m_printRect = wxRect (left,
127 top,
128 page.x - (left + right),
129 page.y - (top + bottom));
130
131 // wxWidgets 2.4.2, have some printing-related bugs.
132 // one of them is that that GetDC always returns 0 in GetPageInfo.
133 // this means we can't count the pages...
134 wxDC *dc = GetDC();
135 if (dc)
136 {
137 ScaleDC(dc);
138
139 // count pages and save SelStart value of each page
140 m_pPageSelStart->Clear();
141 m_pPageSelStart->Add(m_SelStart);
142 m_printed = m_SelStart;
143 while (HasPage(*maxPage))
144 {
145 //Manager::Get()->GetLogManager()->DebugLog(_T("CountPages: PageCount %d , m_printed %d"), m_pPageSelStart->GetCount(), m_printed);
146 m_printed = m_TextControl->FormatRange (0, m_printed, m_SelEnd,
147 dc, dc, m_printRect, m_pageRect);
148 m_pPageSelStart->Add(m_printed);
149 *maxPage += 1;
150 }
151 }
152 else
153 *maxPage = 32000; // use a fictitious high number
154
155 if (*maxPage > 0)
156 *minPage = 1;
157 *selPageFrom = *minPage;
158 *selPageTo = *maxPage;
159 m_printed = m_SelStart;
160 }
161
OnBeginDocument(int startPage,int endPage)162 bool cbEditorPrintout::OnBeginDocument(int startPage, int endPage)
163 {
164 bool result = wxPrintout::OnBeginDocument(startPage, endPage);
165 // FIXME (Tiwag#1#): when the first time a printout is initiated
166 // and you request a page to print which is out of bounds of available pages
167 // it is not recognized by the above check, don't know how to fix this better
168 int maxpage = m_pPageSelStart->GetCount();
169 if( startPage > maxpage || endPage > maxpage )
170 {
171 Manager::Get()->GetLogManager()->DebugLog(F(_T("OnBeginDocument ERROR: startPage %d , endPage %d , maxpage %d "), startPage, endPage, maxpage));
172 return false;
173 }
174 return result;
175 }
176
ScaleDC(wxDC * dc)177 bool cbEditorPrintout::ScaleDC(wxDC *dc)
178 {
179 if (!dc)
180 return false;
181 // get printer and screen sizing values
182 wxSize ppiScr;
183 GetPPIScreen (&ppiScr.x, &ppiScr.y);
184 if (ppiScr.x == 0)
185 { // most possible guess 96 dpi
186 ppiScr.x = 96;
187 ppiScr.y = 96;
188 }
189 wxSize ppiPrt;
190 GetPPIPrinter (&ppiPrt.x, &ppiPrt.y);
191 if (ppiPrt.x == 0)
192 { // scaling factor to 1
193 ppiPrt.x = ppiScr.x;
194 ppiPrt.y = ppiScr.y;
195 }
196 wxSize dcSize = dc->GetSize();
197 wxSize pageSize;
198 GetPageSizePixels (&pageSize.x, &pageSize.y);
199 // set user scale
200 float scale_x = (float)(ppiPrt.x * dcSize.x) /
201 (float)(ppiScr.x * pageSize.x);
202 float scale_y = (float)(ppiPrt.y * dcSize.y) /
203 (float)(ppiScr.y * pageSize.y);
204 dc->SetUserScale (scale_x, scale_y);
205 return true;
206 }
207