OpenCPN Partial API docs
Loading...
Searching...
No Matches
routeprintout.cpp
1/***************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose: OpenCPN Route printout
5 * Author: Pavel Saviankou
6 *
7 ***************************************************************************
8 * Copyright (C) 2012 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
28#include <wx/wxprec.h>
29
30#ifndef WX_PRECOMP
31#include <wx/wx.h>
32#endif // precompiled headers
33#ifdef __WXMSW__
34//#include "c:\\Program Files\\visual leak detector\\include\\vld.h"
35#endif
36
37#include <wx/print.h>
38#include <wx/printdlg.h>
39#include <wx/artprov.h>
40#include <wx/stdpaths.h>
41#include <wx/intl.h>
42#include <wx/listctrl.h>
43#include <wx/aui/aui.h>
44#include <wx/dialog.h>
45#include <wx/progdlg.h>
46#include <wx/brush.h>
47#include <wx/colour.h>
48
49#include <wx/dialog.h>
50
51#include "navutil.h"
52#include "dychart.h"
53
54#ifdef __WXMSW__
55#include <stdlib.h>
56#include <math.h>
57#include <time.h>
58#include <psapi.h>
59#endif
60
61#ifndef __WXMSW__
62#include <signal.h>
63#include <setjmp.h>
64#endif
65#include "routeprintout.h"
66
67#include "printtable.h"
68#include "wx28compat.h"
69#include "track.h"
70#include "route.h"
71#include "gui_lib.h"
72#include "navutil_base.h"
73
74#define PRINT_WP_NAME 0
75#define PRINT_WP_POSITION 1
76#define PRINT_WP_COURSE 2
77#define PRINT_WP_DISTANCE 3
78#define PRINT_WP_DESCRIPTION 4
79
80using namespace std;
81
82// Global print data, to remember settings during the session
83extern wxPrintData* g_printData;
84// Global page setup data
85extern wxPageSetupData* g_pageSetupData;
86
87MyRoutePrintout::MyRoutePrintout(std::vector<bool> _toPrintOut, Route* route,
88 const wxString& title)
89 : MyPrintout(title), myRoute(route), toPrintOut(_toPrintOut) {
90 // Let's have at least some device units margin
91 marginX = 100;
92 marginY = 100;
93
94 // Offset text from the edge of the cell (Needed on Linux)
95 textOffsetX = 5;
96 textOffsetY = 8;
97
98 table.StartFillHeader();
99 // setup widths for columns
100
101 table << _("Leg");
102
103 if (toPrintOut[PRINT_WP_NAME]) {
104 table << _("To Waypoint");
105 }
106 if (toPrintOut[PRINT_WP_POSITION]) {
107 table << _("Position");
108 }
109 if (toPrintOut[PRINT_WP_COURSE]) {
110 table << _("Course");
111 }
112 if (toPrintOut[PRINT_WP_DISTANCE]) {
113 table << _("Distance");
114 }
115 if (toPrintOut[PRINT_WP_DESCRIPTION]) {
116 table << _("Description");
117 }
118
119 table.StartFillWidths();
120
121 table << 20; // "Leg" column
122
123 // setup widths for columns
124 if (toPrintOut[PRINT_WP_NAME]) {
125 table << 40;
126 }
127 if (toPrintOut[PRINT_WP_POSITION]) {
128 table << 40;
129 }
130 if (toPrintOut[PRINT_WP_COURSE]) {
131 table << 40;
132 }
133 if (toPrintOut[PRINT_WP_DISTANCE]) {
134 table << 80;
135 }
136 if (toPrintOut[PRINT_WP_DESCRIPTION]) {
137 table << 100;
138 }
139
140 table.StartFillData();
141
142 for (int n = 1; n <= myRoute->GetnPoints(); n++) {
143 RoutePoint* point = myRoute->GetPoint(n);
144
145 RoutePoint* pointm1 = NULL;
146 if (n - 1 >= 0) pointm1 = myRoute->GetPoint(n - 1);
147
148 if (NULL == point) continue;
149
150 wxString leg = _T("---");
151 if (n > 1) leg.Printf(_T("%d"), n - 1);
152
153 string cell(leg.mb_str());
154
155 table << cell;
156
157 if (toPrintOut[PRINT_WP_NAME]) {
158 string cell(point->GetName().mb_str());
159 table << cell;
160 }
161 if (toPrintOut[PRINT_WP_POSITION]) {
162 wxString point_position = toSDMM(1, point->m_lat, false) + _T( "\n" ) +
163 toSDMM(2, point->m_lon, false);
164 string cell(point_position.mb_str());
165 table << cell;
166 }
167 if (toPrintOut[PRINT_WP_COURSE]) {
168 wxString point_course = "---";
169 if (pointm1) {
170 point_course = formatAngle(point->GetCourse());
171 }
172 table << point_course;
173 }
174 if (toPrintOut[PRINT_WP_DISTANCE]) {
175 wxString point_distance = _T("---");
176 if (n > 1)
177 point_distance.Printf(_T("%6.2f" + getUsrDistanceUnit()),
178 toUsrDistance(point->GetDistance()));
179 table << point_distance;
180 }
181 if (toPrintOut[PRINT_WP_DESCRIPTION]) {
182 table << point->GetDescription();
183 }
184 table << "\n";
185 }
186}
187
188void MyRoutePrintout::GetPageInfo(int* minPage, int* maxPage, int* selPageFrom,
189 int* selPageTo) {
190 *minPage = 1;
191 *maxPage = numberOfPages;
192 *selPageFrom = 1;
193 *selPageTo = numberOfPages;
194}
195
196void MyRoutePrintout::OnPreparePrinting() {
197 pageToPrint = 1;
198 wxDC* dc = GetDC();
199 wxFont routePrintFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
200 wxFONTWEIGHT_NORMAL);
201 dc->SetFont(routePrintFont);
202
203 // Get the size of the DC in pixels
204 int w, h;
205 dc->GetSize(&w, &h);
206
207 // We don't know before hand what size the Print DC will be, in pixels. Varies
208 // by host. So, if the dc size is greater than 1000 pixels, we scale
209 // accordinly.
210
211 int maxX = wxMin(w, 1000);
212 int maxY = wxMin(h, 1000);
213
214 // Calculate a suitable scaling factor
215 double scaleX = (double)(w / maxX);
216 double scaleY = (double)(h / maxY);
217
218 // Use x or y scaling factor, whichever fits on the DC
219 double actualScale = wxMin(scaleX, scaleY);
220
221 // Set the scale and origin
222 dc->SetUserScale(actualScale, actualScale);
223 dc->SetDeviceOrigin((long)marginX, (long)marginY);
224
225 table.AdjustCells(dc, marginX, marginY);
226 numberOfPages = table.GetNumberPages();
227}
228
229bool MyRoutePrintout::OnPrintPage(int page) {
230 wxDC* dc = GetDC();
231 if (dc) {
232 if (page <= numberOfPages) {
233 pageToPrint = page;
234 DrawPage(dc);
235 return true;
236 } else
237 return false;
238 } else
239 return false;
240}
241
242void MyRoutePrintout::DrawPage(wxDC* dc) {
243 wxFont routePrintFont_bold(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
244 wxFONTWEIGHT_BOLD);
245 dc->SetFont(routePrintFont_bold);
246 wxBrush brush(wxColour(255, 255, 255), wxBRUSHSTYLE_TRANSPARENT);
247 dc->SetBrush(brush);
248
249 int header_textOffsetX = 2;
250 int header_textOffsetY = 2;
251
252 dc->DrawText(myRoute->m_RouteNameString, 150, 20);
253
254 int currentX = marginX;
255 int currentY = marginY;
256 vector<PrintCell>& header_content = table.GetHeader();
257 for (size_t j = 0; j < header_content.size(); j++) {
258 PrintCell& cell = header_content[j];
259 dc->DrawRectangle(currentX, currentY, cell.GetWidth(), cell.GetHeight());
260 dc->DrawText(cell.GetText(), currentX + header_textOffsetX,
261 currentY + header_textOffsetY);
262 currentX += cell.GetWidth();
263 }
264
265 wxFont routePrintFont_normal(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
266 wxFONTWEIGHT_NORMAL);
267 dc->SetFont(routePrintFont_normal);
268
269 vector<vector<PrintCell> >& cells = table.GetContent();
270 currentY = marginY + table.GetHeaderHeight();
271 int currentHeight = 0;
272 for (size_t i = 0; i < cells.size(); i++) {
273 vector<PrintCell>& content_row = cells[i];
274 currentX = marginX;
275 for (size_t j = 0; j < content_row.size(); j++) {
276 PrintCell& cell = content_row[j];
277 if (cell.GetPage() == pageToPrint) {
278 wxRect r(currentX, currentY, cell.GetWidth(), cell.GetHeight());
279 dc->DrawRectangle(r);
280 r.Offset(textOffsetX, textOffsetY);
281 dc->DrawLabel(cell.GetText(), r);
282 currentX += cell.GetWidth();
283 currentHeight = cell.GetHeight();
284 }
285 }
286 currentY += currentHeight;
287 }
288}
289
290// ---------- RoutePrintSelection dialof implementation
291
296IMPLEMENT_DYNAMIC_CLASS(RoutePrintSelection, wxDialog)
301BEGIN_EVENT_TABLE(RoutePrintSelection, wxDialog)
302EVT_BUTTON(ID_ROUTEPRINT_SELECTION_CANCEL,
303 RoutePrintSelection::OnRoutepropCancelClick)
304EVT_BUTTON(ID_ROUTEPRINT_SELECTION_OK, RoutePrintSelection::OnRoutepropOkClick)
305END_EVENT_TABLE()
306
307
312
313RoutePrintSelection::RoutePrintSelection(wxWindow* parent, Route* _route,
314 wxWindowID id, const wxString& caption,
315 const wxPoint& pos, const wxSize& size,
316 long style) {
317 route = _route;
318
319 long wstyle = style;
320
321 Create(parent, id, caption, pos, size, wstyle);
322 Centre();
323}
324
325RoutePrintSelection::~RoutePrintSelection() {}
326
331bool RoutePrintSelection::Create(wxWindow* parent, wxWindowID id,
332 const wxString& caption, const wxPoint& pos,
333 const wxSize& size, long style) {
334 SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
335
336#ifdef __WXOSX__
337 style |= wxSTAY_ON_TOP;
338#endif
339
340 wxDialog::Create(parent, id, _("Print Route Selection"), pos, size, style);
341
343
344 return TRUE;
345}
346
352 RoutePrintSelection* itemDialog1 = this;
353
354 wxStaticBox* itemStaticBoxSizer3Static =
355 new wxStaticBox(itemDialog1, wxID_ANY, _("Elements to print..."));
356
357 wxStaticBoxSizer* itemBoxSizer1 =
358 new wxStaticBoxSizer(itemStaticBoxSizer3Static, wxVERTICAL);
359 itemDialog1->SetSizer(itemBoxSizer1);
360
361 wxFlexGridSizer* fgSizer2;
362 fgSizer2 = new wxFlexGridSizer(5, 2, 0, 0);
363
364 m_checkBoxWPName =
365 new wxCheckBox(itemDialog1, wxID_ANY, _("Name"), wxDefaultPosition,
366 wxDefaultSize, wxALIGN_LEFT);
367 m_checkBoxWPName->SetValue(true);
368 fgSizer2->Add(m_checkBoxWPName, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
369
370 wxStaticText* label1 =
371 new wxStaticText(itemDialog1, wxID_ANY, _("Show Waypoint name."),
372 wxDefaultPosition, wxDefaultSize);
373 fgSizer2->Add(label1, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
374
375 m_checkBoxWPPosition =
376 new wxCheckBox(itemDialog1, wxID_ANY, _("Position"), wxDefaultPosition,
377 wxDefaultSize, wxALIGN_LEFT);
378 m_checkBoxWPPosition->SetValue(true);
379 fgSizer2->Add(m_checkBoxWPPosition, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
380 wxStaticText* label2 =
381 new wxStaticText(itemDialog1, wxID_ANY, _("Show Waypoint position."),
382 wxDefaultPosition, wxDefaultSize);
383 fgSizer2->Add(label2, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
384
385 m_checkBoxWPCourse =
386 new wxCheckBox(itemDialog1, wxID_ANY, _("Course"), wxDefaultPosition,
387 wxDefaultSize, wxALIGN_LEFT);
388 m_checkBoxWPCourse->SetValue(true);
389 fgSizer2->Add(m_checkBoxWPCourse, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
390 wxStaticText* label3 =
391 new wxStaticText(itemDialog1, wxID_ANY,
392 _("Show course from each Waypoint to the next one. "),
393 wxDefaultPosition, wxDefaultSize);
394 fgSizer2->Add(label3, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
395
396 m_checkBoxWPDistanceToNext =
397 new wxCheckBox(itemDialog1, wxID_ANY, _("Distance"), wxDefaultPosition,
398 wxDefaultSize, wxALIGN_LEFT);
399 m_checkBoxWPDistanceToNext->SetValue(true);
400 fgSizer2->Add(m_checkBoxWPDistanceToNext, 0, wxALL | wxALIGN_CENTER_VERTICAL,
401 5);
402 wxStaticText* label4 =
403 new wxStaticText(itemDialog1, wxID_ANY,
404 _("Show Distance from each Waypoint to the next one."),
405 wxDefaultPosition, wxDefaultSize);
406 fgSizer2->Add(label4, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
407
408 m_checkBoxWPDescription =
409 new wxCheckBox(itemDialog1, wxID_ANY, _("Description"), wxDefaultPosition,
410 wxDefaultSize, wxALIGN_LEFT);
411 m_checkBoxWPDescription->SetValue(true);
412 fgSizer2->Add(m_checkBoxWPDescription, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5);
413 wxStaticText* label5 =
414 new wxStaticText(itemDialog1, wxID_ANY, _("Show Waypoint description."),
415 wxDefaultPosition, wxDefaultSize);
416 fgSizer2->Add(label5, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5);
417
418 itemBoxSizer1->Add(fgSizer2, 5, wxEXPAND, 5);
419
420 wxBoxSizer* itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
421 itemBoxSizer1->Add(itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5);
422
423 m_CancelButton =
424 new wxButton(itemDialog1, ID_ROUTEPRINT_SELECTION_CANCEL, _("Cancel"),
425 wxDefaultPosition, wxDefaultSize, 0);
426 itemBoxSizer16->Add(m_CancelButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
427
428 m_OKButton = new wxButton(itemDialog1, ID_ROUTEPRINT_SELECTION_OK, _("OK"),
429 wxDefaultPosition, wxDefaultSize, 0);
430 itemBoxSizer16->Add(m_OKButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
431 m_OKButton->SetDefault();
432
433 SetColorScheme((ColorScheme)0);
434}
435
436void RoutePrintSelection::SetColorScheme(ColorScheme cs) { DimeControl(this); }
437
438/*
439 * Should we show tooltips?
440 */
441
442bool RoutePrintSelection::ShowToolTips() { return TRUE; }
443
444void RoutePrintSelection::SetDialogTitle(const wxString& title) {
445 SetTitle(title);
446}
447
448void RoutePrintSelection::OnRoutepropCancelClick(wxCommandEvent& event) {
449 Close(); // Hide();
450 event.Skip();
451}
452
453void RoutePrintSelection::OnRoutepropOkClick(wxCommandEvent& event) {
454 std::vector<bool> toPrintOut;
455 toPrintOut.push_back(m_checkBoxWPName->GetValue());
456 toPrintOut.push_back(m_checkBoxWPPosition->GetValue());
457 toPrintOut.push_back(m_checkBoxWPCourse->GetValue());
458 toPrintOut.push_back(m_checkBoxWPDistanceToNext->GetValue());
459 toPrintOut.push_back(m_checkBoxWPDescription->GetValue());
460
461 if (NULL == g_printData) {
462 g_printData = new wxPrintData;
463 g_printData->SetOrientation(wxPORTRAIT);
464 g_pageSetupData = new wxPageSetupDialogData;
465 }
466
467 MyRoutePrintout* myrouteprintout1 =
468 new MyRoutePrintout(toPrintOut, route, _("Route Print"));
469
470 wxPrintDialogData printDialogData(*g_printData);
471 printDialogData.EnablePageNumbers(true);
472
473 wxPrinter printer(&printDialogData);
474 if (!printer.Print(this, myrouteprintout1, true)) {
475 if (wxPrinter::GetLastError() == wxPRINTER_ERROR) {
476 OCPNMessageBox(NULL,
477 _("There was a problem printing.\nPerhaps your current "
478 "printer is not set correctly?"),
479 _T( "OpenCPN" ), wxOK);
480 }
481 }
482
483 Close();
484 event.Skip();
485}
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_ROUTEPRINT_SELECTION_IDNAME, const wxString &caption=SYMBOL_ROUTEPRINT_SELECTION_TITLE, const wxPoint &pos=SYMBOL_ROUTEPRINT_SELECTION_POSITION, const wxSize &size=SYMBOL_ROUTEPRINT_SELECTION_SIZE, long style=SYMBOL_ROUTEPRINT_SELECTION_STYLE)
Definition: route.h:70