OpenCPN Partial API docs
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>
27 using 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 
63 enum { PRINT_POSITION, PRINT_DISTANCE, PRINT_BEARING, PRINT_TIME, PRINT_SPEED };
64 
65 // Global print data, to remember settings during the session
66 extern wxPrintData* g_printData;
67 // Global page setup data
68 extern wxPageSetupData* g_pageSetupData;
69 
70 MyTrackPrintout::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 
134 void 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 
142 void 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 
175 bool 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 
188 void 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 
238 IMPLEMENT_DYNAMIC_CLASS(TrackPrintSelection, wxDialog)
239 BEGIN_EVENT_TABLE(TrackPrintSelection, wxDialog)
240 EVT_BUTTON(ID_TRACKPRINT_SELECTION_CANCEL,
241  TrackPrintSelection::OnTrackpropCancelClick)
242 EVT_BUTTON(ID_TRACKPRINT_SELECTION_OK, TrackPrintSelection::OnTrackpropOkClick)
243 END_EVENT_TABLE()
245 
246 TrackPrintSelection::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 
260 TrackPrintSelection::~TrackPrintSelection() {}
261 
266 bool 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 
277  CreateControls();
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 
368 void TrackPrintSelection::SetColorScheme(ColorScheme cs) { DimeControl(this); }
369 
370 /*
371  * Should we show tooltips?
372  */
373 
374 bool TrackPrintSelection::ShowToolTips() { return TRUE; }
375 
376 void TrackPrintSelection::SetDialogTitle(const wxString& title) {
377  SetTitle(title);
378 }
379 
380 void TrackPrintSelection::OnTrackpropCancelClick(wxCommandEvent& event) {
381  Close(); // Hide();
382  event.Skip();
383 }
384 
385 void 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:78
General purpose GUI support.