36#include <wx/textfile.h>
38#include <wx/clipbrd.h>
39#include <wx/html/htmlwin.h>
40#include <wx/tokenzr.h>
47#include "OCPNPlatform.h"
50#ifdef __OCPN__ANDROID__
51#include "androidUTIL.h"
53#include "ocpn_frame.h"
58extern about* g_pAboutDlgLegacy;
59extern bool g_bresponsive;
61wxString OpenCPNVersion =
62 wxString::Format(wxT(
"\n Version %s"), VERSION_FULL);
68const wxString AboutText =
69 wxT(
"<br>OpenCPN<br>")
70 wxT("(c) 2000-2021 The OpenCPN Authors<br><br>");
72const wxString OpenCPNInfo =
74 wxT("OpenCPN is a Free Software project, built by sailors. ")
75 wxT("It is freely available to download and distribute ")
76 wxT("without charge at opencpn.org.<br><br>")
77 wxT("If you use OpenCPN, please consider contributing ")
78 wxT("or donating funds to the project.<br><br>")
79 wxT("For more information, visit http:
81const wxString OpenCPNInfoAlt =
83 wxT("OpenCPN is a Free Software project, built by sailors.")
84 wxT("The complete source code and many other resources ")
85 wxT("are freely available for your download and use, ")
86 wxT("subject to applicable License agreements.")
88 wxT("For more information, visit http:
91const wxString AuthorText =
92 wxT(" David S Register\n")
93 wxT(" OpenCPN Lead Developer\n\n")
94 wxT(" Pavel Kalian\n")
95 wxT(" Packaging and PlugIn development\n\n")
96 wxT(" Håkan Svensson\n")
97 wxT(" Comms and
Plugin integration\n\n")
98 wxT(" Rick Gleason\n")
99 wxT("
Plugin adaptation and maintenance\n\n")
100 wxT(" Sean D'Epagnier\n")
101 wxT(" OpenGL Architecture\n\n")
102 wxT(" J.P. Joubert\n")
103 wxT(" GRIB PlugIn enhancements\n\n")
104 wxT(" Thomas Höckne\n")
105 wxT(" Documentation and Wiki support\n\n")
106 wxT(" Didier Gautheron\n")
107 wxT(" App debugging and optimization\n\n")
108 wxT(" Wiets Wilken\n")
109 wxT(" Extended vector Icon implementation\n\n")
110 wxT(" Gene Seybold\n")
111 wxT(" Extended vector Icon design\n\n")
112 wxT(" Caesar Schinas\n")
113 wxT(" User Interface and OS X improvements\n\n")
114 wxT(" Jesper Weissglas\n")
115 wxT(" Vector Chart Rendering\n\n")
116 wxT(" Jean-Eudes Onfray\n")
117 wxT(" Dashboard and Dialog enhancements\n\n")
118 wxT(" Kathleen Boswell\n")
119 wxT(" Icon design\n\n")
120 wxT(" Flavius Bindea\n")
121 wxT(" CM93 Offset and AIS enhancements\n\n")
122 wxT(" Gunther Pilz\n")
123 wxT(" Windows Installer enhancements\n\n")
124 wxT(" Alan Bleasby\n")
125 wxT(" Garmin jeeps module\n\n")
126 wxT(" Piotr Carlson\n")
127 wxT(" General usability enhancements\n\n")
128 wxT(" Anders Lund\n")
131 wxT(" OpenCPN Documentation\n\n")
132 wxT(" Tim Francis\n")
133 wxT(" OpenCPN Documentation\n\n")
134 wxT(" Mark A Sikes\n")
135 wxT(" OpenCPN CoDeveloper\n\n")
136 wxT(" Thomas Haller\n")
137 wxT(" GPX Import/Export Implementation\n\n")
139 wxT(" Toolbar Icon design\n\n")
140 wxT(" Richard Smith\n")
141 wxT(" OpenCPN CoDeveloper, MacOSX\n\n")
142 wxT(" David Herring\n")
143 wxT(" OpenCPN CoDeveloper, MacOSX\n\n")
144 wxT(" Philip Lange\n")
145 wxT(" OpenCPN Documentation\n\n")
147 wxT(" wxWidgets Support\n\n")
148 wxT(" Julian Smart, Robert Roebling et al\n")
149 wxT(" wxWidgets Authors\n\n")
150 wxT(" Sylvain Duclos\n")
151 wxT(" S52 Presentation Library code\n\n")
152 wxT(" Manish P. Pagey\n")
153 wxT(" Serial Port Library\n\n")
154 wxT(" David Flater\n")
155 wxT(" XTIDE tide and current code\n\n")
156 wxT(" Frank Warmerdam\n")
157 wxT(" GDAL Class Library\n\n")
158 wxT(" Mike Higgins\n")
159 wxT(" BSB Chart Format Detail\n\n")
160 wxT(" Samuel R. Blackburn\n")
161 wxT(" NMEA0183 Class Library\n\n")
162 wxT(" Atul Narkhede\n")
163 wxT(" Polygon Graphics utilities\n\n")
164 wxT(" Jan C. Depner\n")
165 wxT(" WVS Chart Library\n\n")
166 wxT(" Stuart Cunningham, et al\n")
167 wxT(" BSB Chart Georeferencing Algorithms\n\n")
168 wxT(" John F. Waers\n")
169 wxT(" UTM Conversion Algorithms\n\n")
170 wxT(" Carsten Tschach\n")
171 wxT(" UTM Conversion Algorithms\n\n")
172 wxT(" Ed Williams\n")
173 wxT(" Great Circle Formulary\n\n")
174 wxT(" Philippe Bekaert\n")
175 wxT(" CIE->RGB Color Conversion Matrix\n\n")
176 wxT(" Robert Lipe\n")
177 wxT(" Garmin USB GPS Interface\n");
181IMPLEMENT_DYNAMIC_CLASS(
about, wxDialog)
183BEGIN_EVENT_TABLE(
about, wxDialog)
184EVT_BUTTON(xID_OK,
about::OnXidOkClick)
185EVT_BUTTON(ID_DONATE,
about::OnDonateClick)
186EVT_BUTTON(ID_COPYINI,
about::OnCopyClick)
187EVT_BUTTON(ID_COPYLOG,
about::OnCopyClick)
188EVT_CLOSE(
about::OnClose)
192 : m_DataLocn(wxEmptyString), m_parent(NULL), m_btips_loaded(FALSE) {
193 pAboutHTMLCtl = NULL;
194 pLicenseHTMLCtl = NULL;
195 pAuthorHTMLCtl = NULL;
196 m_blicensePageSet =
false;
199about::about(wxWindow* parent, wxString Data_Locn, wxWindowID
id,
200 const wxString& caption,
const wxPoint& pos,
const wxSize& size,
202 : m_DataLocn(Data_Locn), m_parent(parent), m_btips_loaded(FALSE) {
203 pAboutHTMLCtl = NULL;
204 pLicenseHTMLCtl = NULL;
205 pAuthorHTMLCtl = NULL;
206 m_blicensePageSet =
false;
208 Create(parent,
id, caption, pos, size, style);
211bool about::Create(wxWindow* parent, wxWindowID
id,
const wxString& caption,
212 const wxPoint& pos,
const wxSize& size,
long style) {
215 style |= wxSTAY_ON_TOP;
218 SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
219 wxDialog::Create(parent,
id, caption, pos, size, style);
220 wxFont* qFont = GetOCPNScaledFont(_(
"Dialog"));
223 m_displaySize = g_Platform->getDisplaySize();
232void about::SetColorScheme(
void) {
234 wxColor bg = GetBackgroundColour();
235 if (pAboutHTMLCtl) pAboutHTMLCtl->SetBackgroundColour(bg);
236 if (pLicenseHTMLCtl) pLicenseHTMLCtl->SetBackgroundColour(bg);
237 if (pAuthorHTMLCtl) pAuthorHTMLCtl->SetBackgroundColour(bg);
241 SetBackgroundColour(bg);
245 wxBitmap tbm(GetSize().x, GetSize().y, -1);
247 tdc.SetBackground(bg);
249 if (pAboutHTMLCtl) pAboutHTMLCtl->SetBackgroundImage(tbm);
250 if (pLicenseHTMLCtl) pLicenseHTMLCtl->SetBackgroundImage(tbm);
251 if (pAuthorHTMLCtl) pAuthorHTMLCtl->SetBackgroundImage(tbm);
255void about::Populate(
void) {
256 wxColor bg = GetBackgroundColour();
257 wxColor fg = wxColour(0, 0, 0);
260 wxString aboutText = wxString::Format(
261 _T(
"<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
262 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green());
264 wxFont* dFont = FontMgr::Get().GetFont(_(
"Dialog"));
267 int points = dFont->GetPointSize();
272 for (
int i = -2; i < 5; i++) {
273 sizes[i + 2] = points + i + (i > 0 ? i : 0);
275 wxString face = dFont->GetFaceName();
276 pAboutHTMLCtl->SetFonts(face, face, sizes);
278 if (wxFONTSTYLE_ITALIC == dFont->GetStyle()) aboutText.Append(_T(
"<i>"));
280#ifdef __OCPN__ANDROID__
282 msg.Printf(_T(
" [%d]"), androidGetVersionCode());
283 wxString OpenCPNVersionAndroid =
284 _T(
"OpenCPN for Android Version ") + androidGetVersionName() + msg;
286 aboutText.Append(AboutText + OpenCPNVersionAndroid + OpenCPNInfoAlt);
288 aboutText.Append(AboutText + OpenCPNVersion + OpenCPNInfo);
292 wxString log_string = _T(
"Logfile location: ") + g_Platform->GetLogFileName();
293 log_string.Replace(_T(
"/"),
296 aboutText.Append(log_string);
299 wxString config_string =
300 _T(
"<br><br>Config file location: ") + g_Platform->GetConfigFileName();
301 config_string.Replace(_T(
"/"),
303 aboutText.Append(config_string);
305 if (wxFONTSTYLE_ITALIC == dFont->GetStyle()) aboutText.Append(_T(
"</i>"));
308 aboutText.Append(_T(
"</font></body></html>"));
310 pAboutHTMLCtl->SetPage(aboutText);
314 wxString authorText = wxString::Format(
315 _T(
"<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
316 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green());
318 pAuthorHTMLCtl->SetFonts(face, face, sizes);
320 wxString authorFixText = AuthorText;
321 authorFixText.Replace(_T(
"\n"), _T(
"<br>"));
322 authorText.Append(authorFixText);
325 authorText.Append(_T(
"</font></body></html>"));
327 pAuthorHTMLCtl->SetPage(authorFixText);
333 wxString licenseText =
335 _T(
"<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
336 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green() );
338 pLicenseHTMLCtl->SetFonts( face, face, sizes );
340 wxTextFile license_filea( m_DataLocn + _T(
"license.txt") );
341 if ( license_filea.Open() ) {
342 for ( wxString str = license_filea.GetFirstLine(); !license_filea.Eof() ; str = license_filea.GetNextLine() )
343 licenseText.Append( str + _T(
"<br>") );
344 license_filea.Close();
346 wxLogMessage( _T(
"Could not open License file: ") + m_DataLocn );
349 wxString suppLicense = g_Platform->GetSupplementalLicenseString();
351 wxStringTokenizer st(suppLicense, _T(
"\n"), wxTOKEN_DEFAULT);
352 while( st.HasMoreTokens() )
354 wxString s1 = st.GetNextToken();
355 licenseText.Append( s1 + _T(
"<br>") );
359 licenseText.Append( _T(
"</font></body></html>") );
361 pLicenseHTMLCtl->SetPage( licenseText );
367void about::RecalculateSize(
void) {
371 esize.x = GetCharWidth() * 110;
372 esize.y = GetCharHeight() * 44;
374 wxSize dsize = GetParent()->GetSize();
375 esize.y = wxMin(esize.y, dsize.y - (0 * GetCharHeight()));
376 esize.x = wxMin(esize.x, dsize.x - (0 * GetCharHeight()));
377 SetClientSize(esize);
379 wxSize fsize = GetSize();
380 fsize.y = wxMin(fsize.y, dsize.y - (0 * GetCharHeight()));
381 fsize.x = wxMin(fsize.x, dsize.x - (0 * GetCharHeight()));
388void about::CreateControls(
void) {
391 wxBoxSizer* mainSizer =
new wxBoxSizer(wxVERTICAL);
394 new wxStaticText(
this, -1, _(
"The Open Source Chart Plotter/Navigator"),
395 wxDefaultPosition, wxSize(-1, 50 ),
398 wxFont* qFont = GetOCPNScaledFont(_(
"Dialog"));
400 wxFont* headerFont = FontMgr::Get().FindOrCreateFont(
401 14, wxFONTFAMILY_DEFAULT, qFont->GetStyle(), wxFONTWEIGHT_BOLD,
false,
402 qFont->GetFaceName());
403 pST1->SetFont(*headerFont);
404 mainSizer->Add(pST1, 0, wxALL | wxEXPAND, 8);
406 bool orient = m_displaySize.x < m_displaySize.y;
407#ifndef __OCPN__ANDROID__
408 wxBoxSizer* buttonSizer =
new wxBoxSizer(orient ? wxVERTICAL : wxHORIZONTAL);
409 mainSizer->Add(buttonSizer, 0, wxALL, 0);
411 wxButton* donateButton =
new wxBitmapButton(
412 this, ID_DONATE, g_StyleManager->GetCurrentStyle()->GetIcon(_T(
"donate")),
413 wxDefaultPosition, wxDefaultSize, 0);
416 new wxButton(
this, ID_COPYLOG, _(
"Copy Log File to Clipboard")), 1,
417 wxALL | wxEXPAND, 3);
419 new wxButton(
this, ID_COPYINI, _(
"Copy Settings File to Clipboard")), 1,
420 wxALL | wxEXPAND, 3);
424 (buttonSizer->GetOrientation() == wxHORIZONTAL ? wxALIGN_RIGHT : 0),
429 pNotebook =
new wxNotebook(
this, ID_NOTEBOOK_HELP, wxDefaultPosition,
430 wxSize(-1, -1), wxNB_TOP);
432 pNotebook->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
433 wxNotebookEventHandler(about::OnNBPageChange), NULL,
this);
435 pNotebook->InheritAttributes();
436 mainSizer->Add(pNotebook, 1,
437 (orient ? wxALIGN_CENTER_VERTICAL : 0) | wxEXPAND | wxALL, 5);
440 itemPanelAbout =
new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
441 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
442 itemPanelAbout->InheritAttributes();
443 pNotebook->AddPage(itemPanelAbout, _(
"About"), TRUE );
446 new wxHtmlWindow(itemPanelAbout, wxID_ANY, wxDefaultPosition,
447 wxDefaultSize, wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
448 pAboutHTMLCtl->SetBorders(5);
449 wxBoxSizer* aboutSizer =
new wxBoxSizer(wxVERTICAL);
450 aboutSizer->Add(pAboutHTMLCtl, 1,
451 wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5);
452 itemPanelAbout->SetSizer(aboutSizer);
457 new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
458 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
459 itemPanelAuthors->InheritAttributes();
460 pNotebook->AddPage(itemPanelAuthors, _(
"Authors"));
463 new wxHtmlWindow(itemPanelAuthors, wxID_ANY, wxDefaultPosition,
464 wxDefaultSize, wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
465 pAuthorHTMLCtl->SetBorders(5);
466 wxBoxSizer* authorSizer =
new wxBoxSizer(wxVERTICAL);
467 authorSizer->Add(pAuthorHTMLCtl, 1,
468 wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5);
469 itemPanelAuthors->SetSizer(authorSizer);
473 new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
474 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
475 itemPanelLicense->InheritAttributes();
476 pNotebook->AddPage(itemPanelLicense, _(
"License"));
479 new wxHtmlWindow(itemPanelLicense, wxID_ANY, wxDefaultPosition,
480 wxDefaultSize, wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
481 pLicenseHTMLCtl->SetBorders(5);
482 wxBoxSizer* licenseSizer =
new wxBoxSizer(wxVERTICAL);
483 licenseSizer->Add(pLicenseHTMLCtl, 1,
484 wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5);
485 itemPanelLicense->SetSizer(licenseSizer);
488 itemPanelTips =
new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
489 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
490 itemPanelTips->InheritAttributes();
491 pNotebook->AddPage(itemPanelTips, _(
"Help"));
493 wxBoxSizer* helpSizer =
new wxBoxSizer(wxVERTICAL);
494 itemPanelTips->SetSizer(helpSizer);
497 wxButton* closeButton =
new wxButton(
this, xID_OK, _(
"Close"),
498 wxDefaultPosition, wxDefaultSize, 0);
499 closeButton->SetDefault();
500 closeButton->InheritAttributes();
501 mainSizer->Add(closeButton, 0, wxALIGN_RIGHT | wxALL, 5);
504void about::OnNBPageChange(wxNotebookEvent& event) {
505 unsigned int i =
event.GetSelection();
508 g_Platform->LaunchLocalHelp();
509 pNotebook->ChangeSelection(0);
512 else if ((i == 2) && !m_blicensePageSet) {
514 wxColor bg = GetBackgroundColour();
515 wxColor fg = wxColour(0, 0, 0);
516 wxFont* dFont = FontMgr::Get().GetFont(_(
"Dialog"));
519 int points = dFont->GetPointSize();
524 for (
int i = -2; i < 5; i++) {
525 sizes[i + 2] = points + i + (i > 0 ? i : 0);
527 wxString face = dFont->GetFaceName();
530 g_Platform->ShowBusySpinner();
533 wxString licenseText = wxString::Format(
534 _T(
"<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
535 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green());
537 pLicenseHTMLCtl->SetFonts(face, face, sizes);
539 wxTextFile license_filea(m_DataLocn + _T(
"license.txt"));
540 if (license_filea.Open()) {
541 for (wxString str = license_filea.GetFirstLine(); !license_filea.Eof();
542 str = license_filea.GetNextLine())
543 licenseText.Append(str + _T(
"<br>"));
544 license_filea.Close();
546 wxLogMessage(_T(
"Could not open License file: ") + m_DataLocn);
549 wxString suppLicense = g_Platform->GetSupplementalLicenseString();
551 wxStringTokenizer st(suppLicense, _T(
"\n"), wxTOKEN_DEFAULT);
552 while (st.HasMoreTokens()) {
553 wxString s1 = st.GetNextToken();
554 licenseText.Append(s1 + _T(
"<br>"));
558 licenseText.Append(_T(
"</font></body></html>"));
560 pLicenseHTMLCtl->SetPage(licenseText);
562 g_Platform->HideBusySpinner();
565 m_blicensePageSet =
true;
569void about::OnXidOkClick(wxCommandEvent& event) { Close(); }
571void about::OnClose(wxCloseEvent& event) {
576 g_pAboutDlgLegacy = NULL;
579void about::OnDonateClick(wxCommandEvent& event) {
580 wxLaunchDefaultBrowser(
581 _T(
"https://sourceforge.net/donate/index.php?group_id=180842"));
584void about::OnCopyClick(wxCommandEvent& event) {
585 wxString filename =
event.GetId() == ID_COPYLOG
586 ? g_Platform->GetLogFileName()
587 : g_Platform->GetConfigFileName();
589 wxFFile file(filename);
591 if (!file.IsOpened()) {
592 wxLogMessage(_T(
"Failed to open file for Copy to Clipboard."));
596 wxString fileContent;
598 while (!file.Eof()) {
599 int c = file.Read(&buf, 1024);
600 if (c) fileContent += wxString(buf, wxConvUTF8, c);
604 int length = fileContent.Length();
606 if (event.GetId() == ID_COPYLOG) {
607 wxString lastLogs = fileContent;
608 int pos = lastLogs.Find(_T(
"________"));
609 while (pos != wxNOT_FOUND && lastLogs.Length() > 65000) {
610 lastLogs = lastLogs.Right(lastLogs.Length() - pos - 8);
611 pos = lastLogs.Find(_T(
"________"));
613 fileContent = lastLogs;
616 ::wxBeginBusyCursor();
617 if (wxTheClipboard->Open()) {
618 if (!wxTheClipboard->SetData(
new wxTextDataObject(fileContent)))
619 wxLogMessage(_T(
"wxTheClipboard->Open() failed."));
620 wxTheClipboard->Close();
622 wxLogMessage(_T(
"wxTheClipboard->Open() failed."));
Plugin ABI encapsulation.