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