1 /******************************************************************************
2  *
3  * Project:  OpenCPN
4  * Purpose:  About Dialog
5  * Author:   David Register
6  *
7  ***************************************************************************
8  *   Copyright (C) 2010 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  *
27  *
28  */
29 
30 #include "wx/wxprec.h"
31 
32 #ifndef WX_PRECOMP
33     #include <wx/wx.h>
34 #endif
35 
36 #include <wx/textfile.h>
37 #include <wx/ffile.h>
38 #include <wx/clipbrd.h>
39 #include <wx/html/htmlwin.h>
40 #include <wx/tokenzr.h>
41 #include <config.h>
42 
43 #include "about.h"
44 #include "chart1.h"
45 #include "chcanv.h"
46 #include "styles.h"
47 #include "OCPNPlatform.h"
48 #include "FontMgr.h"
49 #include "navutil.h"
50 #ifdef __OCPN__ANDROID__
51   #include "androidUTIL.h"
52 #endif
53 
54 extern OCPNPlatform *g_Platform;
55 extern MyFrame *gFrame;
56 extern ocpnStyle::StyleManager* g_StyleManager;
57 extern about *g_pAboutDlgLegacy;
58 extern bool g_bresponsive;
59 
60 wxString OpenCPNVersion =  wxString::Format( wxT("\n      Version %s"), VERSION_FULL);
61 
62 
63 const wxString AboutText =
64     wxT("<br>OpenCPN<br>")
65     wxT("(c) 2000-2019 The OpenCPN Authors<br><br>");
66 
67 const wxString OpenCPNInfo =
68     wxT("<br><br>")
69     wxT("OpenCPN is a Free Software project, built by sailors. ")
70     wxT("It is freely available to download and distribute ")
71     wxT("without charge at opencpn.org.<br><br>")
72     wxT("If you use OpenCPN, please consider contributing ")
73     wxT("or donating funds to the project.<br><br>")
74     wxT("For more information, visit http://opencpn.org<br><br>");
75 
76 const wxString OpenCPNInfoAlt =
77     wxT("<br><br>")
78     wxT("OpenCPN is a Free Software project, built by sailors.")
79     wxT("The complete source code and many other resources ")
80     wxT("are freely available for your download and use, ")
81     wxT("subject to applicable License agreements.")
82     wxT("<br><br>")
83     wxT("For more information, visit http://opencpn.org<br><br>");
84 
85 
86 const wxString AuthorText =
87     wxT("   David S Register\n")
88     wxT("      OpenCPN Lead Developer\n\n")
89     wxT("    Pavel Kalian\n")
90     wxT("      Packaging and PlugIn development\n\n")
91     wxT("    Sean D'Epagnier\n")
92     wxT("      OpenGL Architecture\n\n")
93     wxT("    J.P. Joubert\n")
94     wxT("      GRIB PlugIn enhancements\n\n")
95     wxT("    Thomas Höckne\n")
96     wxT("      Documentation and Wiki support\n\n")
97     wxT("    Didier Gautheron\n")
98     wxT("      App debugging and optimization\n\n")
99     wxT("    Wiets Wilken\n")
100     wxT("      Extended vector Icon implementation\n\n")
101     wxT("    Gene Seybold\n")
102     wxT("      Extended vector Icon design\n\n")
103     wxT("    Caesar Schinas\n")
104     wxT("      User Interface and OS X improvements\n\n")
105     wxT("    Jesper Weissglas\n")
106     wxT("      Vector Chart Rendering\n\n")
107     wxT("    Jean-Eudes Onfray\n")
108     wxT("      Dashboard and Dialog enhancements\n\n")
109     wxT("    Kathleen Boswell\n")
110     wxT("      Icon design\n\n")
111     wxT("    Flavius Bindea\n")
112     wxT("      CM93 Offset and AIS enhancements\n\n")
113     wxT("    Gunther Pilz\n")
114     wxT("      Windows Installer enhancements\n\n")
115     wxT("    Alan Bleasby\n")
116     wxT("      Garmin jeeps module\n\n")
117     wxT("    Piotr Carlson\n")
118     wxT("      General usability enhancements\n\n")
119     wxT("    Anders Lund\n")
120     wxT("      RouteManagerDialog\n\n")
121     wxT("    Gordon Mau\n")
122     wxT("      OpenCPN Documentation\n\n")
123     wxT("    Tim Francis\n")
124     wxT("      OpenCPN Documentation\n\n")
125     wxT("    Mark A Sikes\n")
126     wxT("      OpenCPN CoDeveloper\n\n")
127     wxT("    Thomas Haller\n")
128     wxT("      GPX Import/Export Implementation\n\n")
129     wxT("    Will Kamp\n")
130     wxT("      Toolbar Icon design\n\n")
131     wxT("    Richard Smith\n")
132     wxT("      OpenCPN CoDeveloper, MacOSX\n\n")
133     wxT("    David Herring\n")
134     wxT("      OpenCPN CoDeveloper, MacOSX\n\n")
135     wxT("    Philip Lange\n")
136     wxT("      OpenCPN Documentation\n\n")
137     wxT("    Ron Kuris\n")
138     wxT("      wxWidgets Support\n\n")
139     wxT("    Julian Smart, Robert Roebling et al\n")
140     wxT("      wxWidgets Authors\n\n")
141     wxT("    Sylvain Duclos\n")
142     wxT("      S52 Presentation Library code\n\n")
143     wxT("    Manish P. Pagey\n")
144     wxT("      Serial Port Library\n\n")
145     wxT("    David Flater\n")
146     wxT("      XTIDE tide and current code\n\n")
147     wxT("    Frank Warmerdam\n")
148     wxT("      GDAL Class Library\n\n")
149     wxT("    Mike Higgins\n")
150     wxT("      BSB Chart Format Detail\n\n")
151     wxT("    Samuel R. Blackburn\n")
152     wxT("      NMEA0183 Class Library\n\n")
153     wxT("    Atul Narkhede\n")
154     wxT("      Polygon Graphics utilities\n\n")
155     wxT("    Jan C. Depner\n")
156     wxT("      WVS Chart Library\n\n")
157     wxT("    Stuart Cunningham, et al\n")
158     wxT("      BSB Chart Georeferencing Algorithms\n\n")
159     wxT("    John F. Waers\n")
160     wxT("      UTM Conversion Algorithms\n\n")
161     wxT("    Carsten Tschach\n")
162     wxT("      UTM Conversion Algorithms\n\n")
163     wxT("    Ed Williams\n")
164     wxT("      Great Circle Formulary\n\n")
165     wxT("    Philippe Bekaert\n")
166     wxT("      CIE->RGB Color Conversion Matrix\n\n")
167     wxT("    Robert Lipe\n")
168     wxT("      Garmin USB GPS Interface\n");
169 
IMPLEMENT_DYNAMIC_CLASS(about,wxDialog)170 IMPLEMENT_DYNAMIC_CLASS( about, wxDialog )
171 
172 BEGIN_EVENT_TABLE( about, wxDialog )
173     EVT_BUTTON( xID_OK, about::OnXidOkClick )
174     EVT_BUTTON( ID_DONATE, about::OnDonateClick)
175     EVT_BUTTON( ID_COPYINI, about::OnCopyClick)
176     EVT_BUTTON( ID_COPYLOG, about::OnCopyClick)
177     EVT_CLOSE( about::OnClose )
178 END_EVENT_TABLE()
179 
180 about::about( void ) :
181     m_DataLocn( wxEmptyString ),
182     m_parent( NULL ),
183     m_btips_loaded ( FALSE )
184 {
185     pAboutHTMLCtl = NULL;
186     pLicenseHTMLCtl = NULL;
187     pAuthorHTMLCtl = NULL;
188     m_blicensePageSet = false;
189 
190 }
191 
about(wxWindow * parent,wxString Data_Locn,wxWindowID id,const wxString & caption,const wxPoint & pos,const wxSize & size,long style)192 about::about( wxWindow* parent,wxString Data_Locn, wxWindowID id, const wxString& caption,
193                   const wxPoint& pos, const wxSize& size, long style) :
194     m_DataLocn( Data_Locn ),
195     m_parent( parent ),
196     m_btips_loaded ( FALSE )
197 {
198     pAboutHTMLCtl = NULL;
199     pLicenseHTMLCtl = NULL;
200     pAuthorHTMLCtl = NULL;
201     m_blicensePageSet = false;
202 
203   Create(parent, id, caption, pos, size, style);
204 }
205 
206 
Create(wxWindow * parent,wxWindowID id,const wxString & caption,const wxPoint & pos,const wxSize & size,long style)207 bool about::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos,
208         const wxSize& size, long style )
209 {
210     m_parent = parent;
211 #ifdef __WXOSX__
212     style |= wxSTAY_ON_TOP;
213 #endif
214 
215     SetExtraStyle( GetExtraStyle() | wxWS_EX_BLOCK_EVENTS );
216     wxDialog::Create( parent, id, caption, pos, size, style );
217     wxFont *qFont = GetOCPNScaledFont(_("Dialog"));
218     SetFont( *qFont );
219 
220     m_displaySize = g_Platform->getDisplaySize();
221     CreateControls();
222     Populate();
223 
224     RecalculateSize();
225 
226     return TRUE;
227 }
228 
SetColorScheme(void)229 void about::SetColorScheme( void )
230 {
231     DimeControl( this );
232     wxColor bg = GetBackgroundColour();
233     if(pAboutHTMLCtl) pAboutHTMLCtl->SetBackgroundColour( bg );
234     if(pLicenseHTMLCtl)pLicenseHTMLCtl->SetBackgroundColour( bg );
235     if(pAuthorHTMLCtl)pAuthorHTMLCtl->SetBackgroundColour( bg );
236 
237 
238     // This looks like non-sense, but is needed for __WXGTK__
239     // to get colours to propagate down the control's family tree.
240     SetBackgroundColour( bg );
241 
242 #ifdef __WXQT__
243     // wxQT has some trouble clearing the background of HTML window...
244     wxBitmap tbm( GetSize().x, GetSize().y, -1 );
245     wxMemoryDC tdc( tbm );
246     tdc.SetBackground( bg );
247     tdc.Clear();
248     if(pAboutHTMLCtl)pAboutHTMLCtl->SetBackgroundImage(tbm);
249     if(pLicenseHTMLCtl)pLicenseHTMLCtl->SetBackgroundImage(tbm);
250     if(pAuthorHTMLCtl)pAuthorHTMLCtl->SetBackgroundImage(tbm);
251 #endif
252 
253 }
254 
Populate(void)255 void about::Populate( void )
256 {
257 
258     wxColor bg = GetBackgroundColour();
259     wxColor fg = wxColour( 0, 0, 0 );
260 
261     // The HTML Header
262     wxString aboutText =
263         wxString::Format(
264             _T( "<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
265             bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green() );
266 
267     wxFont *dFont = FontMgr::Get().GetFont( _("Dialog") );
268 
269     // Do weird font size calculation
270     int points = dFont->GetPointSize();
271 #ifndef __WXOSX__
272     ++points;
273 #endif
274     int sizes[7];
275     for ( int i = -2; i < 5; i++ ) {
276         sizes[i+2] = points + i + ( i > 0 ? i : 0 );
277     }
278     wxString face = dFont->GetFaceName();
279     pAboutHTMLCtl->SetFonts( face, face, sizes );
280 
281     if( wxFONTSTYLE_ITALIC == dFont->GetStyle() )
282         aboutText.Append( _T("<i>") );
283 
284 #ifdef __OCPN__ANDROID__
285     wxString msg;
286     msg.Printf( _T(" [%d]"), androidGetVersionCode() );
287     wxString OpenCPNVersionAndroid = _T("OpenCPN for Android Version ") + androidGetVersionName() + msg;
288 
289     aboutText.Append( AboutText + OpenCPNVersionAndroid  + OpenCPNInfoAlt );
290 #else
291     aboutText.Append( AboutText + OpenCPNVersion + OpenCPNInfo );
292 #endif
293 
294     // Show where the log file is going to be placed
295     wxString log_string = _T("Logfile location: ") + g_Platform->GetLogFileName();
296     log_string.Replace(_T("/"), _T("/ "));      // allow line breaks, in a cheap way...
297 
298     aboutText.Append( log_string );
299 
300     // Show where the config file is going to be placed
301     wxString config_string = _T("<br><br>Config file location: ") + g_Platform->GetConfigFileName();
302     config_string.Replace(_T("/"), _T("/ "));      // allow line breaks, in a cheap way...
303     aboutText.Append( config_string );
304 
305     if(wxFONTSTYLE_ITALIC == dFont->GetStyle())
306         aboutText.Append( _T("</i>") );
307 
308     // The HTML Footer
309     aboutText.Append( _T("</font></body></html>") );
310 
311     pAboutHTMLCtl->SetPage( aboutText );
312 
313     ///Authors page
314     // The HTML Header
315     wxString authorText =
316     wxString::Format(
317         _T( "<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
318                      bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green() );
319 
320     pAuthorHTMLCtl->SetFonts( face, face, sizes );
321 
322 
323     wxString authorFixText = AuthorText;
324     authorFixText.Replace(_T("\n"), _T("<br>"));
325     authorText.Append( authorFixText );
326 
327     // The HTML Footer
328     authorText.Append( _T("</font></body></html>") );
329 
330     pAuthorHTMLCtl->SetPage( authorFixText );
331 
332     ///License page
333     // Deferred....
334 #if 0
335     // The HTML Header
336     wxString licenseText =
337     wxString::Format(
338         _T( "<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
339             bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green() );
340 
341     pLicenseHTMLCtl->SetFonts( face, face, sizes );
342 
343     wxTextFile license_filea( m_DataLocn + _T("license.txt") );
344     if ( license_filea.Open() ) {
345         for ( wxString str = license_filea.GetFirstLine(); !license_filea.Eof() ; str = license_filea.GetNextLine() )
346             licenseText.Append( str + _T("<br>") );
347         license_filea.Close();
348     } else {
349         wxLogMessage( _T("Could not open License file: ") + m_DataLocn );
350     }
351 
352     wxString suppLicense = g_Platform->GetSupplementalLicenseString();
353 
354     wxStringTokenizer st(suppLicense, _T("\n"), wxTOKEN_DEFAULT);
355     while( st.HasMoreTokens() )
356     {
357         wxString s1 = st.GetNextToken();
358         licenseText.Append( s1 + _T("<br>") );
359     }
360 
361         // The HTML Footer
362     licenseText.Append( _T("</font></body></html>") );
363 
364     pLicenseHTMLCtl->SetPage( licenseText );
365 #endif
366 
367     SetColorScheme();
368 }
369 
RecalculateSize(void)370 void about::RecalculateSize( void )
371 {
372     //  Make an estimate of the dialog size, without scrollbars showing
373 
374     wxSize esize;
375     esize.x = GetCharWidth() * 110;
376     esize.y = GetCharHeight() * 44;
377 
378     wxSize dsize = GetParent()->GetSize();
379     esize.y = wxMin(esize.y, dsize.y - (0 * GetCharHeight()));
380     esize.x = wxMin(esize.x, dsize.x - (0 * GetCharHeight()));
381     SetClientSize(esize);
382 
383     wxSize fsize = GetSize();
384     fsize.y = wxMin(fsize.y, dsize.y - (0 * GetCharHeight()));
385     fsize.x = wxMin(fsize.x, dsize.x - (0 * GetCharHeight()));
386 
387     SetSize(fsize);
388 
389     Centre();
390 }
391 
392 
CreateControls(void)393 void about::CreateControls( void )
394 {
395     //  Set the nominal vertical size of the embedded controls
396 
397     wxBoxSizer* mainSizer = new wxBoxSizer( wxVERTICAL );
398     SetSizer( mainSizer );
399     wxStaticText *pST1 = new wxStaticText( this, -1,
400         _("The Open Source Chart Plotter/Navigator"), wxDefaultPosition,
401         wxSize( -1, 50 /* 500, 30 */ ), wxALIGN_CENTRE /* | wxALIGN_CENTER_VERTICAL */ );
402 
403     wxFont *qFont = GetOCPNScaledFont(_("Dialog"));
404 
405     wxFont *headerFont = FontMgr::Get().FindOrCreateFont( 14, wxFONTFAMILY_DEFAULT,
406                                                           qFont->GetStyle(), wxFONTWEIGHT_BOLD, false,
407                                                           qFont->GetFaceName() );
408     pST1->SetFont( *headerFont );
409     mainSizer->Add( pST1, 0, wxALL | wxEXPAND, 8 );
410 
411     bool orient =  m_displaySize.x < m_displaySize.y;
412 #ifndef __OCPN__ANDROID__
413     wxBoxSizer *buttonSizer = new wxBoxSizer( orient ? wxVERTICAL : wxHORIZONTAL );
414     mainSizer->Add( buttonSizer, 0, wxALL, 0 );
415 
416     wxButton* donateButton = new wxBitmapButton( this, ID_DONATE,
417             g_StyleManager->GetCurrentStyle()->GetIcon( _T("donate") ),
418             wxDefaultPosition, wxDefaultSize, 0 );
419 
420     buttonSizer->Add( new wxButton( this, ID_COPYLOG, _("Copy Log File to Clipboard") ), 1, wxALL | wxEXPAND, 3 );
421     buttonSizer->Add( new wxButton( this, ID_COPYINI, _("Copy Settings File to Clipboard") ), 1, wxALL | wxEXPAND, 3 );
422     buttonSizer->Add( donateButton, 1, wxALL | (buttonSizer->GetOrientation() == wxHORIZONTAL ? wxALIGN_RIGHT : 0), 3 );
423 #endif
424 
425     //  Main Notebook
426     pNotebook = new wxNotebook( this, ID_NOTEBOOK_HELP, wxDefaultPosition, wxSize( -1, -1 ), wxNB_TOP );
427 
428     pNotebook->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, wxNotebookEventHandler(about::OnNBPageChange), NULL,   this);
429 
430     pNotebook->InheritAttributes();
431     mainSizer->Add( pNotebook, 1, (orient ? wxALIGN_CENTER_VERTICAL : 0) | wxEXPAND | wxALL, 5 );
432 
433     //  About Panel
434     itemPanelAbout = new wxPanel( pNotebook, -1, wxDefaultPosition, wxDefaultSize,
435             wxSUNKEN_BORDER | wxTAB_TRAVERSAL );
436     itemPanelAbout->InheritAttributes();
437     pNotebook->AddPage( itemPanelAbout, _("About"), TRUE /* Default page */ );
438 
439     pAboutHTMLCtl = new wxHtmlWindow( itemPanelAbout, wxID_ANY, wxDefaultPosition, wxDefaultSize,
440                                 wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
441     pAboutHTMLCtl->SetBorders( 5 );
442     wxBoxSizer* aboutSizer = new wxBoxSizer( wxVERTICAL );
443     aboutSizer->Add( pAboutHTMLCtl, 1, wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5 );
444     itemPanelAbout->SetSizer( aboutSizer );
445 
446     //  Authors Panel
447 
448     itemPanelAuthors = new wxPanel( pNotebook, -1, wxDefaultPosition, wxDefaultSize,
449                                 wxSUNKEN_BORDER | wxTAB_TRAVERSAL );
450     itemPanelAuthors->InheritAttributes();
451     pNotebook->AddPage( itemPanelAuthors, _("Authors") );
452 
453     pAuthorHTMLCtl = new wxHtmlWindow( itemPanelAuthors, wxID_ANY, wxDefaultPosition, wxDefaultSize,
454                                     wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
455     pAuthorHTMLCtl->SetBorders( 5 );
456     wxBoxSizer* authorSizer = new wxBoxSizer( wxVERTICAL );
457     authorSizer->Add( pAuthorHTMLCtl, 1, wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5 );
458     itemPanelAuthors->SetSizer( authorSizer );
459 
460     //  License Panel
461     itemPanelLicense = new wxPanel( pNotebook, -1, wxDefaultPosition, wxDefaultSize,
462             wxSUNKEN_BORDER | wxTAB_TRAVERSAL );
463     itemPanelLicense->InheritAttributes();
464     pNotebook->AddPage( itemPanelLicense, _("License") );
465 
466     pLicenseHTMLCtl = new wxHtmlWindow( itemPanelLicense, wxID_ANY, wxDefaultPosition, wxDefaultSize,
467                                       wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
468     pLicenseHTMLCtl->SetBorders( 5 );
469     wxBoxSizer* licenseSizer = new wxBoxSizer( wxVERTICAL );
470     licenseSizer->Add( pLicenseHTMLCtl, 1, wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5 );
471     itemPanelLicense->SetSizer( licenseSizer );
472 
473     //  Help Panel
474     itemPanelTips = new wxPanel( pNotebook, -1, wxDefaultPosition, wxDefaultSize,
475             wxSUNKEN_BORDER | wxTAB_TRAVERSAL );
476     itemPanelTips->InheritAttributes();
477     pNotebook->AddPage( itemPanelTips, _("Help") );
478 
479     wxBoxSizer* helpSizer = new wxBoxSizer( wxVERTICAL );
480     itemPanelTips->SetSizer( helpSizer );
481 
482     //  Close Button
483     wxButton* closeButton = new wxButton( this, xID_OK, _("Close"), wxDefaultPosition,
484             wxDefaultSize, 0 );
485     closeButton->SetDefault();
486     closeButton->InheritAttributes();
487     mainSizer->Add( closeButton, 0, wxALIGN_RIGHT | wxALL, 5 );
488 }
489 
490 
OnNBPageChange(wxNotebookEvent & event)491 void about::OnNBPageChange(wxNotebookEvent& event)
492 {
493     unsigned int i  = event.GetSelection();
494 
495     if( i == 3 ){
496         g_Platform->LaunchLocalHelp();
497         pNotebook->ChangeSelection(0);
498     }
499 
500     else if((i == 2) && !m_blicensePageSet){          // license
501 
502         wxColor bg = GetBackgroundColour();
503         wxColor fg = wxColour( 0, 0, 0 );
504         wxFont *dFont = FontMgr::Get().GetFont( _("Dialog") );
505 
506         // Do weird font size calculation
507         int points = dFont->GetPointSize();
508         #ifndef __WXOSX__
509         ++points;
510         #endif
511         int sizes[7];
512         for ( int i = -2; i < 5; i++ ) {
513             sizes[i+2] = points + i + ( i > 0 ? i : 0 );
514         }
515         wxString face = dFont->GetFaceName();
516 
517     ///License page
518         g_Platform->ShowBusySpinner();
519 
520     // The HTML Header
521         wxString licenseText =
522         wxString::Format(
523             _T( "<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
524                      bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green() );
525 
526         pLicenseHTMLCtl->SetFonts( face, face, sizes );
527 
528         wxTextFile license_filea( m_DataLocn + _T("license.txt") );
529         if ( license_filea.Open() ) {
530             for ( wxString str = license_filea.GetFirstLine(); !license_filea.Eof() ; str = license_filea.GetNextLine() )
531                 licenseText.Append( str + _T("<br>") );
532             license_filea.Close();
533         } else {
534             wxLogMessage( _T("Could not open License file: ") + m_DataLocn );
535         }
536 
537         wxString suppLicense = g_Platform->GetSupplementalLicenseString();
538 
539         wxStringTokenizer st(suppLicense, _T("\n"), wxTOKEN_DEFAULT);
540         while( st.HasMoreTokens() )
541         {
542             wxString s1 = st.GetNextToken();
543             licenseText.Append( s1 + _T("<br>") );
544         }
545 
546         // The HTML Footer
547         licenseText.Append( _T("</font></body></html>") );
548 
549         pLicenseHTMLCtl->SetPage( licenseText );
550 
551         g_Platform->HideBusySpinner();
552 
553         SetColorScheme();
554         m_blicensePageSet = true;
555     }
556 }
557 
OnXidOkClick(wxCommandEvent & event)558 void about::OnXidOkClick( wxCommandEvent& event )
559 {
560   Close();
561 }
562 
OnClose(wxCloseEvent & event)563 void about::OnClose( wxCloseEvent& event )
564 {
565     #ifdef __WXGTK__
566     gFrame->Raise();
567     #endif
568     Destroy();
569     g_pAboutDlgLegacy = NULL;
570 }
571 
OnDonateClick(wxCommandEvent & event)572 void about::OnDonateClick( wxCommandEvent& event )
573 {
574       wxLaunchDefaultBrowser(_T("https://sourceforge.net/donate/index.php?group_id=180842"));
575 }
576 
OnCopyClick(wxCommandEvent & event)577 void about::OnCopyClick( wxCommandEvent& event )
578 {
579     wxString filename = event.GetId() == ID_COPYLOG ?
580         g_Platform->GetLogFileName() : g_Platform->GetConfigFileName();
581 
582     wxFFile file( filename );
583 
584     if( !file.IsOpened() ) {
585         wxLogMessage( _T("Failed to open file for Copy to Clipboard.") );
586         return;
587     }
588 
589     wxString fileContent;
590     char buf[1024];
591     while( ! file.Eof() ) {
592         int c = file.Read( &buf, 1024 );
593         if( c ) fileContent += wxString( buf, wxConvUTF8, c );
594     }
595 
596     file.Close();
597     int length = fileContent.Length();
598 
599     if( event.GetId() == ID_COPYLOG ) {
600         wxString lastLogs = fileContent;
601         int pos = lastLogs.Find( _T("________") );
602         while( pos != wxNOT_FOUND && lastLogs.Length() > 65000 ) {
603             lastLogs = lastLogs.Right(lastLogs.Length() - pos - 8);
604             pos = lastLogs.Find( _T("________") );
605         }
606         fileContent = lastLogs;
607     }
608 
609     ::wxBeginBusyCursor();
610     if( wxTheClipboard->Open() ) {
611         if( !wxTheClipboard->SetData( new wxTextDataObject( fileContent ) ) )
612             wxLogMessage( _T("wxTheClipboard->Open() failed.") );
613         wxTheClipboard->Close();
614     } else {
615         wxLogMessage( _T("wxTheClipboard->Open() failed.") );
616     }
617     ::wxEndBusyCursor();
618 }
619 
620