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 "model/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
238BEGIN_EVENT_TABLE(TrackPrintSelection, wxDialog)
239EVT_BUTTON(ID_TRACKPRINT_SELECTION_CANCEL,
240 TrackPrintSelection::OnTrackpropCancelClick)
241EVT_BUTTON(ID_TRACKPRINT_SELECTION_OK, TrackPrintSelection::OnTrackpropOkClick)
242END_EVENT_TABLE()
244
245TrackPrintSelection::TrackPrintSelection(wxWindow* parent, Track* _track,
246 OCPNTrackListCtrl* lcPoints,
247 wxWindowID id, const wxString& caption,
248 const wxPoint& pos, const wxSize& size,
249 long style) {
250 track = _track;
251 m_lcPoints = lcPoints;
252
253 long wstyle = style;
254
255 Create(parent, id, caption, pos, size, wstyle);
256 Centre();
257}
258
259TrackPrintSelection::~TrackPrintSelection() {}
260
265bool TrackPrintSelection::Create(wxWindow* parent, wxWindowID id,
266 const wxString& caption, const wxPoint& pos,
267 const wxSize& size, long style) {
268 SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
269
270#ifdef __WXOSX__
271 style |= wxSTAY_ON_TOP;
272#endif
273
274 wxDialog::Create(parent, id, _("Print Track Selection"), pos, size, style);
275
277
278 return TRUE;
279}
280
286 TrackPrintSelection* itemDialog1 = this;
287 wxStaticBox* itemStaticBoxSizer3Static =
288 new wxStaticBox(itemDialog1, wxID_ANY, _("Elements to print..."));
289 wxStaticBoxSizer* itemBoxSizer1 =
290 new wxStaticBoxSizer(itemStaticBoxSizer3Static, wxVERTICAL);
291 itemDialog1->SetSizer(itemBoxSizer1);
292
293 wxFlexGridSizer* fgSizer2;
294 fgSizer2 = new wxFlexGridSizer(5, 2, 0, 0);
295
296 m_checkBoxPosition =
297 new wxCheckBox(itemDialog1, wxID_ANY, _("Position"), wxDefaultPosition,
298 wxDefaultSize, wxALIGN_LEFT);
299 m_checkBoxPosition->SetValue(true);
300 fgSizer2->Add(m_checkBoxPosition, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
301 wxStaticText* label2 =
302 new wxStaticText(itemDialog1, wxID_ANY, _("Show Waypoint position."),
303 wxDefaultPosition, wxDefaultSize);
304 fgSizer2->Add(label2, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
305
306 m_checkBoxCourse =
307 new wxCheckBox(itemDialog1, wxID_ANY, _("Course"), wxDefaultPosition,
308 wxDefaultSize, wxALIGN_LEFT);
309 m_checkBoxCourse->SetValue(true);
310 fgSizer2->Add(m_checkBoxCourse, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
311 wxStaticText* label3 =
312 new wxStaticText(itemDialog1, wxID_ANY,
313 _("Show course from each Waypoint to the next one. "),
314 wxDefaultPosition, wxDefaultSize);
315 fgSizer2->Add(label3, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
316
317 m_checkBoxDistance =
318 new wxCheckBox(itemDialog1, wxID_ANY, _("Distance"), wxDefaultPosition,
319 wxDefaultSize, wxALIGN_LEFT);
320 m_checkBoxDistance->SetValue(true);
321 fgSizer2->Add(m_checkBoxDistance, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
322 wxStaticText* label4 =
323 new wxStaticText(itemDialog1, wxID_ANY,
324 _("Show Distance from each Waypoint to the next one."),
325 wxDefaultPosition, wxDefaultSize);
326 fgSizer2->Add(label4, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
327
328 m_checkBoxTime =
329 new wxCheckBox(itemDialog1, wxID_ANY, _("Time"), wxDefaultPosition,
330 wxDefaultSize, wxALIGN_LEFT);
331 m_checkBoxTime->SetValue(true);
332 fgSizer2->Add(m_checkBoxTime, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
333 wxStaticText* label5 = new wxStaticText(
334 itemDialog1, wxID_ANY, _("Show Time."), wxDefaultPosition, wxDefaultSize);
335 fgSizer2->Add(label5, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
336
337 m_checkBoxSpeed =
338 new wxCheckBox(itemDialog1, wxID_ANY, _("Speed"), wxDefaultPosition,
339 wxDefaultSize, wxALIGN_LEFT);
340 m_checkBoxSpeed->SetValue(true);
341 fgSizer2->Add(m_checkBoxSpeed, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
342 wxStaticText* label6 =
343 new wxStaticText(itemDialog1, wxID_ANY, _("Show Speed."),
344 wxDefaultPosition, wxDefaultSize);
345 fgSizer2->Add(label6, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
346
347 itemBoxSizer1->Add(fgSizer2, 5, wxEXPAND, 5);
348
349 wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
350 itemBoxSizer1->Add(itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5);
351
352 m_CancelButton =
353 new wxButton(itemDialog1, ID_TRACKPRINT_SELECTION_CANCEL, _("Cancel"),
354 wxDefaultPosition, wxDefaultSize, 0);
355 itemBoxSizer16->Add(m_CancelButton, 0,
356 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
357
358 m_OKButton = new wxButton(itemDialog1, ID_TRACKPRINT_SELECTION_OK, _("OK"),
359 wxDefaultPosition, wxDefaultSize, 0);
360 itemBoxSizer16->Add(m_OKButton, 0,
361 wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 5);
362 m_OKButton->SetDefault();
363
364 SetColorScheme((ColorScheme)0);
365}
366
367void TrackPrintSelection::SetColorScheme(ColorScheme cs) { DimeControl(this); }
368
369/*
370 * Should we show tooltips?
371 */
372
373bool TrackPrintSelection::ShowToolTips() { return TRUE; }
374
375void TrackPrintSelection::SetDialogTitle(const wxString& title) {
376 SetTitle(title);
377}
378
379void TrackPrintSelection::OnTrackpropCancelClick(wxCommandEvent& event) {
380 Close(); // Hide();
381 event.Skip();
382}
383
384void TrackPrintSelection::OnTrackpropOkClick(wxCommandEvent& event) {
385 std::vector<bool> toPrintOut;
386 toPrintOut.push_back(m_checkBoxPosition->GetValue());
387 toPrintOut.push_back(m_checkBoxCourse->GetValue());
388 toPrintOut.push_back(m_checkBoxDistance->GetValue());
389 toPrintOut.push_back(m_checkBoxTime->GetValue());
390 toPrintOut.push_back(m_checkBoxSpeed->GetValue());
391
392 if (NULL == g_printData) {
393 g_printData = new wxPrintData;
394 g_printData->SetOrientation(wxPORTRAIT);
395 g_pageSetupData = new wxPageSetupDialogData;
396 }
397
398 MyTrackPrintout* mytrackprintout1 =
399 new MyTrackPrintout(toPrintOut, track, m_lcPoints, _("Track Print"));
400
401 wxPrintDialogData printDialogData(*g_printData);
402 printDialogData.EnablePageNumbers(true);
403
404 wxPrinter printer(&printDialogData);
405 if (!printer.Print(this, mytrackprintout1, true)) {
406 if (wxPrinter::GetLastError() == wxPRINTER_ERROR) {
407 OCPNMessageBox(NULL,
408 _("There was a problem printing.\nPerhaps your current "
409 "printer is not set correctly?"),
410 _T( "OpenCPN" ), wxOK);
411 }
412 }
413
414 Close(); // Hide();
415 event.Skip();
416}
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)
Represents a track, which is a series of connected track points.
Definition track.h:78
General purpose GUI support.