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
48 #include <wx/dialog.h>
49 #include "dychart.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
62 enum {PRINT_POSITION, PRINT_DISTANCE, PRINT_BEARING, PRINT_TIME, PRINT_SPEED};
63
64 // Global print data, to remember settings during the session
65 extern wxPrintData* g_printData;
66 // Global page setup data
67 extern wxPageSetupData* g_pageSetupData;
68
MyTrackPrintout(std::vector<bool> _toPrintOut,Track * track,OCPNTrackListCtrl * lcPoints,const wxString & title)69 MyTrackPrintout::MyTrackPrintout( std::vector<bool> _toPrintOut,
70 Track* track,
71 OCPNTrackListCtrl *lcPoints,
72 const wxString &title
73 ) : MyPrintout( title ),
74 myTrack( track ),
75 toPrintOut( _toPrintOut )
76 {
77 // Let's have at least some device units margin
78 marginX = 100;
79 marginY = 100;
80
81 // Offset text from the edge of the cell (Needed on Linux)
82 textOffsetX = 5;
83 textOffsetY = 8;
84
85 table.StartFillHeader();
86 // setup widths for columns
87
88 table << (const char *)wxString(_("Leg")).mb_str();
89
90 if ( toPrintOut[ PRINT_POSITION ] ) {
91 table << (const char *)wxString(_("Position")).mb_str();
92 }
93 if ( toPrintOut[ PRINT_BEARING ] ) {
94 table << (const char *)wxString(_("Course")).mb_str();
95 }
96 if ( toPrintOut[ PRINT_DISTANCE ] ) {
97 table << (const char *)wxString(_("Distance")).mb_str();
98 }
99 if ( toPrintOut[ PRINT_TIME ] ) {
100 table << (const char *)wxString(_("Time")).mb_str();
101 }
102 if ( toPrintOut[ PRINT_SPEED ] ) {
103 table << (const char *)wxString(_("Speed")).mb_str();
104 }
105
106 table.StartFillWidths();
107
108 table << 20; // "Leg" column
109 // setup widths for columns
110 if ( toPrintOut[ PRINT_POSITION ] )
111 table << 80;
112 if ( toPrintOut[ PRINT_BEARING ] )
113 table << 40;
114 if ( toPrintOut[ PRINT_DISTANCE ] )
115 table << 40;
116 if ( toPrintOut[ PRINT_TIME ] )
117 table << 60;
118 if ( toPrintOut[ PRINT_SPEED ] )
119 table << 40;
120
121 table.StartFillData();
122 for ( int n = 0; n <= myTrack->GetnPoints(); n++ ) {
123 table << lcPoints->OnGetItemText(n, 0); // leg
124
125 if ( toPrintOut[ PRINT_POSITION ] ) {
126 // lat + lon
127 wxString pos = lcPoints->OnGetItemText(n, 3) + _T(" ") + lcPoints->OnGetItemText(n, 4);
128 table << pos;
129 }
130 if ( toPrintOut[ PRINT_BEARING ] )
131 table << lcPoints->OnGetItemText(n, 2); // bearing
132 if ( toPrintOut[ PRINT_DISTANCE ] )
133 table << lcPoints->OnGetItemText(n, 1); // distance
134 if ( toPrintOut[ PRINT_TIME ] )
135 table << lcPoints->OnGetItemText(n, 5); // time
136 if ( toPrintOut[ PRINT_SPEED ] )
137 table << lcPoints->OnGetItemText(n, 6); // speed
138 table << "\n";
139 }
140 }
141
142
GetPageInfo(int * minPage,int * maxPage,int * selPageFrom,int * selPageTo)143 void MyTrackPrintout::GetPageInfo( int* minPage, int* maxPage, int* selPageFrom, int* selPageTo )
144 {
145 *minPage = 1;
146 *maxPage = numberOfPages;
147 *selPageFrom = 1;
148 *selPageTo = numberOfPages;
149 }
150
151
OnPreparePrinting()152 void MyTrackPrintout::OnPreparePrinting()
153 {
154 pageToPrint = 1;
155 wxDC* dc = GetDC();
156 wxFont trackPrintFont( 10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL );
157 dc->SetFont( trackPrintFont );
158
159 // Get the size of the DC in pixels
160 int w, h;
161 dc->GetSize( &w, &h );
162
163 // We don't know before hand what size the Print DC will be, in pixels. Varies by host.
164 // So, if the dc size is greater than 1000 pixels, we scale accordinly.
165
166 int maxX = wxMin(w, 1000);
167 int maxY = wxMin(h, 1000);
168
169 // Calculate a suitable scaling factor
170 double scaleX = ( double )( w / maxX );
171 double scaleY = ( double )( h / maxY );
172
173 // Use x or y scaling factor, whichever fits on the DC
174 double actualScale = wxMin( scaleX, scaleY );
175
176 // Set the scale and origin
177 dc->SetUserScale( actualScale, actualScale );
178 dc->SetDeviceOrigin( ( long )marginX, ( long )marginY );
179
180 table.AdjustCells( dc, marginX, marginY );
181 numberOfPages = table.GetNumberPages();
182 }
183
184
OnPrintPage(int page)185 bool MyTrackPrintout::OnPrintPage( int page )
186 {
187 wxDC* dc = GetDC();
188 if( dc ) {
189 if( page <= numberOfPages ){
190 pageToPrint = page;
191 DrawPage( dc );
192 return true;
193 }
194 else
195 return false;
196 } else
197 return false;
198
199 }
200
DrawPage(wxDC * dc)201 void MyTrackPrintout::DrawPage( wxDC* dc )
202 {
203
204
205 wxFont trackPrintFont_bold( 10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD );
206 dc->SetFont( trackPrintFont_bold );
207 wxBrush brush( wxColour(255,255,255), wxBRUSHSTYLE_TRANSPARENT );
208 dc->SetBrush( brush );
209
210 int header_textOffsetX = 2;
211 int header_textOffsetY = 2;
212
213 dc->DrawText( myTrack->GetName(), 150, 20 );
214
215 int currentX = marginX;
216 int currentY = marginY;
217 vector< PrintCell >& header_content = table.GetHeader();
218 for ( size_t j = 0; j < header_content.size(); j++ ) {
219 PrintCell& cell = header_content[ j ];
220 dc->DrawRectangle( currentX, currentY, cell.GetWidth(), cell.GetHeight() );
221 dc->DrawText( cell.GetText(), currentX +header_textOffsetX, currentY + header_textOffsetY );
222 currentX += cell.GetWidth();
223 }
224
225 wxFont trackPrintFont_normal( 10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL );
226 dc->SetFont( trackPrintFont_normal );
227
228 vector< vector < PrintCell > > & cells = table.GetContent();
229 currentY = marginY + table.GetHeaderHeight();
230 int currentHeight = 0;
231 for ( size_t i = 0; i < cells.size(); i++ ) {
232 vector< PrintCell >& content_row = cells[ i ];
233 currentX = marginX;
234 for ( size_t j = 0; j < content_row.size(); j++ ) {
235 PrintCell& cell = content_row[ j ];
236 if ( cell.GetPage() == pageToPrint ) {
237 wxRect r( currentX, currentY, cell.GetWidth(), cell.GetHeight() );
238 dc->DrawRectangle( r );
239 r.Offset( textOffsetX, textOffsetY );
240 dc->DrawLabel(cell.GetText(), r);
241 currentX += cell.GetWidth();
242 currentHeight = cell.GetHeight();
243 }
244 }
245 currentY += currentHeight;
246 }
247 }
248
249
250 // ---------- TrackPrintSelection dialof implementation
251
IMPLEMENT_DYNAMIC_CLASS(TrackPrintSelection,wxDialog)252 IMPLEMENT_DYNAMIC_CLASS( TrackPrintSelection, wxDialog )
253 BEGIN_EVENT_TABLE( TrackPrintSelection, wxDialog )
254 EVT_BUTTON( ID_TRACKPRINT_SELECTION_CANCEL, TrackPrintSelection::OnTrackpropCancelClick )
255 EVT_BUTTON( ID_TRACKPRINT_SELECTION_OK, TrackPrintSelection::OnTrackpropOkClick )
256 END_EVENT_TABLE()
257 TrackPrintSelection::TrackPrintSelection()
258 {
259 }
260
TrackPrintSelection(wxWindow * parent,Track * _track,OCPNTrackListCtrl * lcPoints,wxWindowID id,const wxString & caption,const wxPoint & pos,const wxSize & size,long style)261 TrackPrintSelection::TrackPrintSelection( wxWindow* parent,
262 Track* _track,
263 OCPNTrackListCtrl *lcPoints,
264 wxWindowID id,
265 const wxString& caption,
266 const wxPoint& pos,
267 const wxSize& size,
268 long style )
269 {
270 track = _track;
271 m_lcPoints = lcPoints;
272
273 long wstyle = style;
274
275 Create( parent, id, caption, pos, size, wstyle );
276 Centre();
277 }
278
279
~TrackPrintSelection()280 TrackPrintSelection::~TrackPrintSelection()
281 {
282 }
283
284
285 /*!
286 * TrackProp creator
287 */
288
Create(wxWindow * parent,wxWindowID id,const wxString & caption,const wxPoint & pos,const wxSize & size,long style)289 bool TrackPrintSelection::Create( wxWindow* parent, wxWindowID id, const wxString& caption,
290 const wxPoint& pos, const wxSize& size, long style )
291 {
292 SetExtraStyle( GetExtraStyle() | wxWS_EX_BLOCK_EVENTS );
293
294 #ifdef __WXOSX__
295 style |= wxSTAY_ON_TOP;
296 #endif
297
298 wxDialog::Create( parent, id, _("Print Track Selection"), pos, size, style );
299
300 CreateControls();
301
302 return TRUE;
303 }
304
305
306 /*!
307 * Control creation for TrackProp
308 */
309
CreateControls()310 void TrackPrintSelection::CreateControls()
311 {
312 TrackPrintSelection* itemDialog1 = this;
313 wxStaticBox* itemStaticBoxSizer3Static = new wxStaticBox( itemDialog1, wxID_ANY,
314 _( "Elements to print..." ) );
315 wxStaticBoxSizer* itemBoxSizer1 = new wxStaticBoxSizer( itemStaticBoxSizer3Static, wxVERTICAL );
316 itemDialog1->SetSizer( itemBoxSizer1 );
317
318 wxFlexGridSizer* fgSizer2;
319 fgSizer2 = new wxFlexGridSizer( 5, 2, 0, 0 );
320
321 m_checkBoxPosition = new wxCheckBox( itemDialog1, wxID_ANY, _( "Position" ),
322 wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
323 m_checkBoxPosition->SetValue( true );
324 fgSizer2->Add( m_checkBoxPosition, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
325 wxStaticText* label2 = new wxStaticText( itemDialog1, wxID_ANY, _( "Show Waypoint position." ), wxDefaultPosition, wxDefaultSize );
326 fgSizer2->Add( label2, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
327
328 m_checkBoxCourse = new wxCheckBox( itemDialog1, wxID_ANY, _( "Course" ),
329 wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
330 m_checkBoxCourse->SetValue( true );
331 fgSizer2->Add( m_checkBoxCourse, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
332 wxStaticText* label3 = new wxStaticText( itemDialog1, wxID_ANY, _( "Show course from each Waypoint to the next one. " ), wxDefaultPosition, wxDefaultSize );
333 fgSizer2->Add( label3, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
334
335 m_checkBoxDistance = new wxCheckBox( itemDialog1, wxID_ANY, _( "Distance" ),
336 wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
337 m_checkBoxDistance->SetValue( true );
338 fgSizer2->Add( m_checkBoxDistance, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
339 wxStaticText* label4 = new wxStaticText( itemDialog1, wxID_ANY, _( "Show Distance from each Waypoint to the next one." ), wxDefaultPosition, wxDefaultSize );
340 fgSizer2->Add( label4, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
341
342 m_checkBoxTime = new wxCheckBox( itemDialog1, wxID_ANY, _( "Time" ),
343 wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
344 m_checkBoxTime->SetValue( true );
345 fgSizer2->Add( m_checkBoxTime, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
346 wxStaticText* label5 = new wxStaticText( itemDialog1, wxID_ANY, _( "Show Time." ), wxDefaultPosition, wxDefaultSize );
347 fgSizer2->Add( label5, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
348
349 m_checkBoxSpeed = new wxCheckBox( itemDialog1, wxID_ANY, _( "Speed" ),
350 wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT );
351 m_checkBoxSpeed->SetValue( true );
352 fgSizer2->Add( m_checkBoxSpeed, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
353 wxStaticText* label6 = new wxStaticText( itemDialog1, wxID_ANY, _( "Show Speed." ), wxDefaultPosition, wxDefaultSize );
354 fgSizer2->Add( label6, 1, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
355
356 itemBoxSizer1->Add( fgSizer2, 5, wxEXPAND, 5 );
357
358 wxBoxSizer* itemBoxSizer16 = new wxBoxSizer( wxHORIZONTAL );
359 itemBoxSizer1->Add( itemBoxSizer16, 0, wxALIGN_RIGHT | wxALL, 5 );
360
361 m_CancelButton = new wxButton( itemDialog1, ID_TRACKPRINT_SELECTION_CANCEL, _( "Cancel" ), wxDefaultPosition,
362 wxDefaultSize, 0 );
363 itemBoxSizer16->Add( m_CancelButton, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
364
365 m_OKButton = new wxButton( itemDialog1, ID_TRACKPRINT_SELECTION_OK, _( "OK" ), wxDefaultPosition,
366 wxDefaultSize, 0 );
367 itemBoxSizer16->Add( m_OKButton, 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL | wxALL, 5 );
368 m_OKButton->SetDefault();
369
370 SetColorScheme( ( ColorScheme )0 );
371 }
372
373
SetColorScheme(ColorScheme cs)374 void TrackPrintSelection::SetColorScheme( ColorScheme cs )
375 {
376 DimeControl( this );
377 }
378
379
380 /*
381 * Should we show tooltips?
382 */
383
ShowToolTips()384 bool TrackPrintSelection::ShowToolTips()
385 {
386 return TRUE;
387 }
388
389
SetDialogTitle(const wxString & title)390 void TrackPrintSelection::SetDialogTitle(const wxString & title)
391 {
392 SetTitle( title );
393 }
394
395
OnTrackpropCancelClick(wxCommandEvent & event)396 void TrackPrintSelection::OnTrackpropCancelClick( wxCommandEvent& event )
397 {
398 Close(); //Hide();
399 event.Skip();
400 }
401
402
OnTrackpropOkClick(wxCommandEvent & event)403 void TrackPrintSelection::OnTrackpropOkClick( wxCommandEvent& event )
404 {
405 std::vector<bool> toPrintOut;
406 toPrintOut.push_back( m_checkBoxPosition->GetValue() );
407 toPrintOut.push_back( m_checkBoxCourse->GetValue() );
408 toPrintOut.push_back( m_checkBoxDistance->GetValue() );
409 toPrintOut.push_back( m_checkBoxTime->GetValue() );
410 toPrintOut.push_back( m_checkBoxSpeed->GetValue() );
411
412
413 if ( NULL == g_printData ) {
414 g_printData = new wxPrintData;
415 g_printData->SetOrientation( wxPORTRAIT );
416 g_pageSetupData = new wxPageSetupDialogData;
417 }
418
419 MyTrackPrintout* mytrackprintout1 = new MyTrackPrintout( toPrintOut, track, m_lcPoints, _( "Track Print" ) );
420
421 wxPrintDialogData printDialogData( *g_printData );
422 printDialogData.EnablePageNumbers( true );
423
424 wxPrinter printer( &printDialogData );
425 if ( !printer.Print( this, mytrackprintout1, true ) ) {
426 if ( wxPrinter::GetLastError() == wxPRINTER_ERROR ) {
427 OCPNMessageBox(
428 NULL,
429 _( "There was a problem printing.\nPerhaps your current printer is not set correctly?" ),
430 _T( "OpenCPN" ), wxOK );
431 }
432 }
433
434 Close(); //Hide();
435 event.Skip();
436 }
437