OpenCPN Partial API docs
Loading...
Searching...
No Matches
trackprintout.cpp
1/***************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose: OpenCPN Route printout
5 * Author: Pavel Saviankou, Sean D'Epagnier
6 *
7 ***************************************************************************
8 * Copyright (C) 2017 by David S. Register *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24 **************************************************************************/
25
26#include <iostream>
27using namespace std;
28
29#include <wx/wxprec.h>
30
31#ifndef WX_PRECOMP
32#include <wx/wx.h>
33#endif // precompiled headers
34
35#include <wx/print.h>
36#include <wx/printdlg.h>
37#include <wx/artprov.h>
38#include <wx/stdpaths.h>
39#include <wx/intl.h>
40#include <wx/listctrl.h>
41#include <wx/aui/aui.h>
42#include <wx/dialog.h>
43#include <wx/progdlg.h>
44#include <wx/brush.h>
45#include <wx/colour.h>
46
47#include <wx/dialog.h>
48#include "dychart.h"
49#include "ocpn_frame.h"
50
51#ifdef __WXMSW__
52#include <stdlib.h>
53#include <math.h>
54#include <time.h>
55#include <psapi.h>
56#endif
57
58#include "trackprintout.h"
59#include "printtable.h"
60#include "track.h"
61#include "gui_lib.h"
62
63enum { PRINT_POSITION, PRINT_DISTANCE, PRINT_BEARING, PRINT_TIME, PRINT_SPEED };
64
65// Global print data, to remember settings during the session
66extern wxPrintData* g_printData;
67// Global page setup data
68extern wxPageSetupData* g_pageSetupData;
69
70MyTrackPrintout::MyTrackPrintout(std::vector<bool> _toPrintOut, Track* track,
71 OCPNTrackListCtrl* lcPoints,
72 const wxString& title)
73 : MyPrintout(title), myTrack(track), toPrintOut(_toPrintOut) {
74 // Let's have at least some device units margin
75 marginX = 100;
76 marginY = 100;
77
78 // Offset text from the edge of the cell (Needed on Linux)
79 textOffsetX = 5;
80 textOffsetY = 8;
81
82 table.StartFillHeader();
83 // setup widths for columns
84
85 table << (const char*)wxString(_("Leg")).mb_str();
86
87 if (toPrintOut[PRINT_POSITION]) {
88 table << (const char*)wxString(_("Position")).mb_str();
89 }
90 if (toPrintOut[PRINT_BEARING]) {
91 table << (const char*)wxString(_("Course")).mb_str();
92 }
93 if (toPrintOut[PRINT_DISTANCE]) {
94 table << (const char*)wxString(_("Distance")).mb_str();
95 }
96 if (toPrintOut[PRINT_TIME]) {
97 table << (const char*)wxString(_("Time")).mb_str();
98 }
99 if (toPrintOut[PRINT_SPEED]) {
100 table << (const char*)wxString(_("Speed")).mb_str();
101 }
102
103 table.StartFillWidths();
104
105 table << 20; // "Leg" column
106 // setup widths for columns
107 if (toPrintOut[PRINT_POSITION]) table << 80;
108 if (toPrintOut[PRINT_BEARING]) table << 40;
109 if (toPrintOut[PRINT_DISTANCE]) table << 40;
110 if (toPrintOut[PRINT_TIME]) table << 60;
111 if (toPrintOut[PRINT_SPEED]) table << 40;
112
113 table.StartFillData();
114 for (int n = 0; n <= myTrack->GetnPoints(); n++) {
115 table << lcPoints->OnGetItemText(n, 0); // leg
116
117 if (toPrintOut[PRINT_POSITION]) {
118 // lat + lon
119 wxString pos = lcPoints->OnGetItemText(n, 3) + _T(" ") +
120 lcPoints->OnGetItemText(n, 4);
121 table << pos;
122 }
123 if (toPrintOut[PRINT_BEARING])
124 table << lcPoints->OnGetItemText(n, 2); // bearing
125 if (toPrintOut[PRINT_DISTANCE])
126 table << lcPoints->OnGetItemText(n, 1); // distance
127 if (toPrintOut[PRINT_TIME]) table << lcPoints->OnGetItemText(n, 5); // time
128 if (toPrintOut[PRINT_SPEED])
129 table << lcPoints->OnGetItemText(n, 6); // speed
130 table << "\n";
131 }
132}
133
134void MyTrackPrintout::GetPageInfo(int* minPage, int* maxPage, int* selPageFrom,
135 int* selPageTo) {
136 *minPage = 1;
137 *maxPage = numberOfPages;
138 *selPageFrom = 1;
139 *selPageTo = numberOfPages;
140}
141
142void MyTrackPrintout::OnPreparePrinting() {
143 pageToPrint = 1;
144 wxDC* dc = GetDC();
145 wxFont trackPrintFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
146 wxFONTWEIGHT_NORMAL);
147 dc->SetFont(trackPrintFont);
148
149 // Get the size of the DC in pixels
150 int w, h;
151 dc->GetSize(&w, &h);
152
153 // We don't know before hand what size the Print DC will be, in pixels. Varies
154 // by host. So, if the dc size is greater than 1000 pixels, we scale
155 // accordinly.
156
157 int maxX = wxMin(w, 1000);
158 int maxY = wxMin(h, 1000);
159
160 // Calculate a suitable scaling factor
161 double scaleX = (double)(w / maxX);
162 double scaleY = (double)(h / maxY);
163
164 // Use x or y scaling factor, whichever fits on the DC
165 double actualScale = wxMin(scaleX, scaleY);
166
167 // Set the scale and origin
168 dc->SetUserScale(actualScale, actualScale);
169 dc->SetDeviceOrigin((long)marginX, (long)marginY);
170
171 table.AdjustCells(dc, marginX, marginY);
172 numberOfPages = table.GetNumberPages();
173}
174
175bool MyTrackPrintout::OnPrintPage(int page) {
176 wxDC* dc = GetDC();
177 if (dc) {
178 if (page <= numberOfPages) {
179 pageToPrint = page;
180 DrawPage(dc);
181 return true;
182 } else
183 return false;
184 } else
185 return false;
186}
187
188void MyTrackPrintout::DrawPage(wxDC* dc) {
189 wxFont trackPrintFont_bold(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
190 wxFONTWEIGHT_BOLD);
191 dc->SetFont(trackPrintFont_bold);
192 wxBrush brush(wxColour(255, 255, 255), wxBRUSHSTYLE_TRANSPARENT);
193 dc->SetBrush(brush);
194
195 int header_textOffsetX = 2;
196 int header_textOffsetY = 2;
197
198 dc->DrawText(myTrack->GetName(), 150, 20);
199
200 int currentX = marginX;
201 int currentY = marginY;
202 vector<PrintCell>& header_content = table.GetHeader();
203 for (size_t j = 0; j < header_content.size(); j++) {
204 PrintCell& cell = header_content[j];
205 dc->DrawRectangle(currentX, currentY, cell.GetWidth(), cell.GetHeight());
206 dc->DrawText(cell.GetText(), currentX + header_textOffsetX,
207 currentY + header_textOffsetY);
208 currentX += cell.GetWidth();
209 }
210
211 wxFont trackPrintFont_normal(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
212 wxFONTWEIGHT_NORMAL);
213 dc->SetFont(trackPrintFont_normal);
214
215 vector<vector<PrintCell> >& cells = table.GetContent();
216 currentY = marginY + table.GetHeaderHeight();
217 int currentHeight = 0;
218 for (size_t i = 0; i < cells.size(); i++) {
219 vector<PrintCell>& content_row = cells[i];
220 currentX = marginX;
221 for (size_t j = 0; j < content_row.size(); j++) {
222 PrintCell& cell = content_row[j];
223 if (cell.GetPage() == pageToPrint) {
224 wxRect r(currentX, currentY, cell.GetWidth(), cell.GetHeight());
225 dc->DrawRectangle(r);
226 r.Offset(textOffsetX, textOffsetY);
227 dc->DrawLabel(cell.GetText(), r);
228 currentX += cell.GetWidth();
229 currentHeight = cell.GetHeight();
230 }
231 }
232 currentY += currentHeight;
233 }
234}
235
236// ---------- TrackPrintSelection dialof implementation
237
238IMPLEMENT_DYNAMIC_CLASS(TrackPrintSelection, wxDialog)
239BEGIN_EVENT_TABLE(TrackPrintSelection, wxDialog)
240EVT_BUTTON(ID_TRACKPRINT_SELECTION_CANCEL,
241 TrackPrintSelection::OnTrackpropCancelClick)
242EVT_BUTTON(ID_TRACKPRINT_SELECTION_OK, TrackPrintSelection::OnTrackpropOkClick)
243END_EVENT_TABLE()
245
246TrackPrintSelection::TrackPrintSelection(wxWindow* parent, Track* _track,
247 OCPNTrackListCtrl* lcPoints,
248 wxWindowID id, const wxString& caption,
249 const wxPoint& pos, const wxSize& size,
250 long style) {
251 track = _track;
252 m_lcPoints = lcPoints;
253
254 long wstyle = style;
255
256 Create(parent, id, caption, pos, size, wstyle);
257 Centre();
258}
259
260TrackPrintSelection::~TrackPrintSelection() {}
261
266bool TrackPrintSelection::Create(wxWindow* parent, wxWindowID id,
267 const wxString& caption, const wxPoint& pos,
268 const wxSize& size, long style) {
269 SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
270
271#ifdef __WXOSX__
272 style |= wxSTAY_ON_TOP;
273#endif
274
275 wxDialog::Create(parent, id, _("Print Track Selection"), pos, size, style);
276
278
279 return TRUE;
280}
281
287 TrackPrintSelection* itemDialog1 = this;
288 wxStaticBox* itemStaticBoxSizer3Static =
289 new wxStaticBox(itemDialog1, wxID_ANY, _("Elements to print..."));
290 wxStaticBoxSizer* itemBoxSizer1 =
291 new wxStaticBoxSizer(itemStaticBoxSizer3Static, wxVERTICAL);
292 itemDialog1->SetSizer(itemBoxSizer1);
293
294 wxFlexGridSizer* fgSizer2;
295 fgSizer2 = new wxFlexGridSizer(5, 2, 0, 0);
296
297 m_checkBoxPosition =
298 new wxCheckBox(itemDialog1, wxID_ANY, _("Position"), wxDefaultPosition,
299 wxDefaultSize, wxALIGN_LEFT);
300 m_checkBoxPosition->SetValue(true);
301 fgSizer2->Add(m_checkBoxPosition, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
302 wxStaticText* label2 =
303 new wxStaticText(itemDialog1, wxID_ANY, _("Show Waypoint position."),
304 wxDefaultPosition, wxDefaultSize);
305 fgSizer2->Add(label2, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
306
307 m_checkBoxCourse =
308 new wxCheckBox(itemDialog1, wxID_ANY, _("Course"), wxDefaultPosition,
309 wxDefaultSize, wxALIGN_LEFT);
310 m_checkBoxCourse->SetValue(true);
311 fgSizer2->Add(m_checkBoxCourse, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
312 wxStaticText* label3 =
313 new wxStaticText(itemDialog1, wxID_ANY,
314 _("Show course from each Waypoint to the next one. "),
315 wxDefaultPosition, wxDefaultSize);
316 fgSizer2->Add(label3, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
317
318 m_checkBoxDistance =
319 new wxCheckBox(itemDialog1, wxID_ANY, _("Distance"), wxDefaultPosition,
320 wxDefaultSize, wxALIGN_LEFT);
321 m_checkBoxDistance->SetValue(true);
322 fgSizer2->Add(m_checkBoxDistance, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
323 wxStaticText* label4 =
324 new wxStaticText(itemDialog1, wxID_ANY,
325 _("Show Distance from each Waypoint to the next one."),
326 wxDefaultPosition, wxDefaultSize);
327 fgSizer2->Add(label4, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
328
329 m_checkBoxTime =
330 new wxCheckBox(itemDialog1, wxID_ANY, _("Time"), wxDefaultPosition,
331 wxDefaultSize, wxALIGN_LEFT);
332 m_checkBoxTime->SetValue(true);
333 fgSizer2->Add(m_checkBoxTime, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
334 wxStaticText* label5 = new wxStaticText(
335 itemDialog1, wxID_ANY, _("Show Time."), wxDefaultPosition, wxDefaultSize);
336 fgSizer2->Add(label5, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
337
338 m_checkBoxSpeed =
339 new wxCheckBox(itemDialog1, wxID_ANY, _("Speed"), wxDefaultPosition,
340 wxDefaultSize, wxALIGN_LEFT);
341 m_checkBoxSpeed->SetValue(true);
342 fgSizer2->Add(m_checkBoxSpeed, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
343 wxStaticText* label6 =
344 new wxStaticText(itemDialog1, wxID_ANY, _("Show Speed."),
345 wxDefaultPosition, wxDefaultSize);
346 fgSizer2->Add(label6, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
347
348 itemBoxSizer1->Add(fgSizer2, 5, wxEXPAND, 5);
349
350 wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
351 itemBoxSizer1->Add(itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5);
352
353 m_CancelButton =
354 new wxButton(itemDialog1, ID_TRACKPRINT_SELECTION_CANCEL, _("Cancel"),
355 wxDefaultPosition, wxDefaultSize, 0);
356 itemBoxSizer16->Add(m_CancelButton, 0,
357 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
358
359 m_OKButton = new wxButton(itemDialog1, ID_TRACKPRINT_SELECTION_OK, _("OK"),
360 wxDefaultPosition, wxDefaultSize, 0);
361 itemBoxSizer16->Add(m_OKButton, 0,
362 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
363 m_OKButton->SetDefault();
364
365 SetColorScheme((ColorScheme)0);
366}
367
368void TrackPrintSelection::SetColorScheme(ColorScheme cs) { DimeControl(this); }
369
370/*
371 * Should we show tooltips?
372 */
373
374bool TrackPrintSelection::ShowToolTips() { return TRUE; }
375
376void TrackPrintSelection::SetDialogTitle(const wxString& title) {
377 SetTitle(title);
378}
379
380void TrackPrintSelection::OnTrackpropCancelClick(wxCommandEvent& event) {
381 Close(); // Hide();
382 event.Skip();
383}
384
385void TrackPrintSelection::OnTrackpropOkClick(wxCommandEvent& event) {
386 std::vector<bool> toPrintOut;
387 toPrintOut.push_back(m_checkBoxPosition->GetValue());
388 toPrintOut.push_back(m_checkBoxCourse->GetValue());
389 toPrintOut.push_back(m_checkBoxDistance->GetValue());
390 toPrintOut.push_back(m_checkBoxTime->GetValue());
391 toPrintOut.push_back(m_checkBoxSpeed->GetValue());
392
393 if (NULL == g_printData) {
394 g_printData = new wxPrintData;
395 g_printData->SetOrientation(wxPORTRAIT);
396 g_pageSetupData = new wxPageSetupDialogData;
397 }
398
399 MyTrackPrintout* mytrackprintout1 =
400 new MyTrackPrintout(toPrintOut, track, m_lcPoints, _("Track Print"));
401
402 wxPrintDialogData printDialogData(*g_printData);
403 printDialogData.EnablePageNumbers(true);
404
405 wxPrinter printer(&printDialogData);
406 if (!printer.Print(this, mytrackprintout1, true)) {
407 if (wxPrinter::GetLastError() == wxPRINTER_ERROR) {
408 OCPNMessageBox(NULL,
409 _("There was a problem printing.\nPerhaps your current "
410 "printer is not set correctly?"),
411 _T( "OpenCPN" ), wxOK);
412 }
413 }
414
415 Close(); // Hide();
416 event.Skip();
417}
This class takes multilined string and modifies it to fit into given width for given device.
Definition: printtable.h:113
bool Create(wxWindow *parent, wxWindowID id=SYMBOL_TRACKPRINT_SELECTION_IDNAME, const wxString &caption=SYMBOL_TRACKPRINT_SELECTION_TITLE, const wxPoint &pos=SYMBOL_TRACKPRINT_SELECTION_POSITION, const wxSize &size=SYMBOL_TRACKPRINT_SELECTION_SIZE, long style=SYMBOL_TRACKPRINT_SELECTION_STYLE)
Definition: track.h:79