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"
57extern about* g_pAboutDlgLegacy;
58extern bool g_bresponsive;
60wxString OpenCPNVersion(
"\n Version ");
66const wxString AboutText =
67 wxT(
"<br>OpenCPN<br>")
68 wxT("(c) 2000-2024 The OpenCPN Authors<br><br>");
70const wxString OpenCPNInfo =
72 wxT("OpenCPN is a Free Software project, built by sailors. ")
73 wxT("It is freely available to download and distribute ")
74 wxT("without charge at opencpn.org.<br><br>")
75 wxT("If you use OpenCPN, please consider contributing ")
76 wxT("or donating funds to the project.<br><br>")
77 wxT("For more information, visit http:
79const wxString OpenCPNInfoAlt =
81 wxT("OpenCPN is a Free Software project, built by sailors.")
82 wxT("The complete source code and many other resources ")
83 wxT("are freely available for your download and use, ")
84 wxT("subject to applicable License agreements.")
86 wxT("For more information, visit http:
89const wxString AuthorText =
90 wxT(" David S Register\n")
91 wxT(" OpenCPN Lead Developer\n\n")
92 wxT(" Pavel Kalian\n")
93 wxT(" Packaging and PlugIn development\n\n")
94 wxT(" Håkan Svensson\n")
95 wxT(" Comms and
Plugin integration\n\n")
96 wxT(" Rick Gleason\n")
97 wxT("
Plugin adaptation and maintenance\n\n")
98 wxT(" Sean D'Epagnier\n")
99 wxT(" OpenGL Architecture\n\n")
100 wxT(" J.P. Joubert\n")
101 wxT(" GRIB PlugIn enhancements\n\n")
102 wxT(" Thomas Höckne\n")
103 wxT(" Documentation and Wiki support\n\n")
104 wxT(" Didier Gautheron\n")
105 wxT(" App debugging and optimization\n\n")
106 wxT(" Wiets Wilken\n")
107 wxT(" Extended vector Icon implementation\n\n")
108 wxT(" Gene Seybold\n")
109 wxT(" Extended vector Icon design\n\n")
110 wxT(" Caesar Schinas\n")
111 wxT(" User Interface and OS X improvements\n\n")
112 wxT(" Jesper Weissglas\n")
113 wxT(" Vector
Chart Rendering\n\n")
114 wxT(" Jean-Eudes Onfray\n")
115 wxT(" Dashboard and Dialog enhancements\n\n")
116 wxT(" Kathleen Boswell\n")
117 wxT(" Icon design\n\n")
118 wxT(" Flavius Bindea\n")
119 wxT(" CM93 Offset and AIS enhancements\n\n")
120 wxT(" Gunther Pilz\n")
121 wxT(" Windows Installer enhancements\n\n")
122 wxT(" Alan Bleasby\n")
123 wxT(" Garmin jeeps module\n\n")
124 wxT(" Piotr Carlson\n")
125 wxT(" General usability enhancements\n\n")
126 wxT(" Anders Lund\n")
129 wxT(" OpenCPN Documentation\n\n")
130 wxT(" Tim Francis\n")
131 wxT(" OpenCPN Documentation\n\n")
132 wxT(" Mark A Sikes\n")
133 wxT(" OpenCPN CoDeveloper\n\n")
134 wxT(" Thomas Haller\n")
135 wxT(" GPX Import/Export Implementation\n\n")
137 wxT(" Toolbar Icon design\n\n")
138 wxT(" Richard Smith\n")
139 wxT(" OpenCPN CoDeveloper, MacOSX\n\n")
140 wxT(" David Herring\n")
141 wxT(" OpenCPN CoDeveloper, MacOSX\n\n")
142 wxT(" Philip Lange\n")
143 wxT(" OpenCPN Documentation\n\n")
145 wxT(" wxWidgets Support\n\n")
146 wxT(" Julian Smart, Robert Roebling et al\n")
147 wxT(" wxWidgets Authors\n\n")
148 wxT(" Sylvain Duclos\n")
149 wxT(" S52 Presentation Library code\n\n")
150 wxT(" Manish P. Pagey\n")
151 wxT(" Serial Port Library\n\n")
152 wxT(" David Flater\n")
153 wxT(" XTIDE tide and current code\n\n")
154 wxT(" Frank Warmerdam\n")
155 wxT(" GDAL Class Library\n\n")
156 wxT(" Mike Higgins\n")
157 wxT(" BSB
Chart Format Detail\n\n")
158 wxT(" Samuel R. Blackburn\n")
159 wxT(" NMEA0183 Class Library\n\n")
160 wxT(" Atul Narkhede\n")
161 wxT(" Polygon Graphics utilities\n\n")
162 wxT(" Jan C. Depner\n")
163 wxT(" WVS
Chart Library\n\n")
164 wxT(" Stuart Cunningham, et al\n")
165 wxT(" BSB
Chart Georeferencing Algorithms\n\n")
166 wxT(" John F. Waers\n")
167 wxT(" UTM Conversion Algorithms\n\n")
168 wxT(" Carsten Tschach\n")
169 wxT(" UTM Conversion Algorithms\n\n")
170 wxT(" Ed Williams\n")
171 wxT(" Great Circle Formulary\n\n")
172 wxT(" Philippe Bekaert\n")
173 wxT(" CIE->RGB Color Conversion Matrix\n\n")
174 wxT(" Robert Lipe\n")
175 wxT(" Garmin USB GPS Interface\n");
179BEGIN_EVENT_TABLE(
about, wxDialog)
180EVT_BUTTON(xID_OK,
about::OnXidOkClick)
181EVT_BUTTON(ID_DONATE,
about::OnDonateClick)
182EVT_BUTTON(ID_COPYINI,
about::OnCopyClick)
183EVT_BUTTON(ID_COPYLOG,
about::OnCopyClick)
184EVT_CLOSE(
about::OnClose)
188 : m_DataLocn(wxEmptyString), m_parent(NULL), m_btips_loaded(FALSE) {
189 pAboutHTMLCtl = NULL;
190 pLicenseHTMLCtl = NULL;
191 pAuthorHTMLCtl = NULL;
192 m_blicensePageSet =
false;
195about::about(wxWindow* parent, wxString Data_Locn, wxWindowID
id,
196 const wxString& caption,
const wxPoint& pos,
const wxSize& size,
198 : m_DataLocn(Data_Locn), m_parent(parent), m_btips_loaded(FALSE) {
199 pAboutHTMLCtl = NULL;
200 pLicenseHTMLCtl = NULL;
201 pAuthorHTMLCtl = NULL;
202 m_blicensePageSet =
false;
204 if (strlen(DEBIAN_PPA_VERSION))
205 OpenCPNVersion += wxString(DEBIAN_PPA_VERSION);
207 OpenCPNVersion += wxString(PACKAGE_VERSION);
209 Create(parent,
id, caption, pos, size, style);
212bool about::Create(wxWindow* parent, wxWindowID
id,
const wxString& caption,
213 const wxPoint& pos,
const wxSize& size,
long style) {
216 style |= wxSTAY_ON_TOP;
219 SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
220 wxDialog::Create(parent,
id, caption, pos, size, style);
233void about::SetColorScheme(
void) {
235 wxColor bg = GetBackgroundColour();
236 if (pAboutHTMLCtl) pAboutHTMLCtl->SetBackgroundColour(bg);
237 if (pLicenseHTMLCtl) pLicenseHTMLCtl->SetBackgroundColour(bg);
238 if (pAuthorHTMLCtl) pAuthorHTMLCtl->SetBackgroundColour(bg);
242 SetBackgroundColour(bg);
246 wxBitmap tbm(GetSize().x, GetSize().y, -1);
248 tdc.SetBackground(bg);
250 if (pAboutHTMLCtl) pAboutHTMLCtl->SetBackgroundImage(tbm);
251 if (pLicenseHTMLCtl) pLicenseHTMLCtl->SetBackgroundImage(tbm);
252 if (pAuthorHTMLCtl) pAuthorHTMLCtl->SetBackgroundImage(tbm);
256void about::Populate(
void) {
257 wxColor bg = GetBackgroundColour();
258 wxColor fg = wxColour(0, 0, 0);
261 wxString aboutText = wxString::Format(
262 _T(
"<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
263 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green());
265 wxFont* dFont = FontMgr::Get().
GetFont(_(
"Dialog"));
268 int points = dFont->GetPointSize();
273 for (
int i = -2; i < 5; i++) {
274 sizes[i + 2] = points + i + (i > 0 ? i : 0);
276 wxString face = dFont->GetFaceName();
277 pAboutHTMLCtl->SetFonts(face, face, sizes);
279 if (wxFONTSTYLE_ITALIC == dFont->GetStyle()) aboutText.Append(_T(
"<i>"));
281#ifdef __OCPN__ANDROID__
283 msg.Printf(_T(
" [%d]"), androidGetVersionCode());
284 wxString OpenCPNVersionAndroid =
285 _T(
"OpenCPN for Android Version ") + androidGetVersionName() + msg;
287 aboutText.Append(AboutText + OpenCPNVersionAndroid + OpenCPNInfoAlt);
289 aboutText.Append(AboutText + OpenCPNVersion + OpenCPNInfo);
293 wxString log_string = _T(
"Logfile location: ") + g_Platform->GetLogFileName();
294 log_string.Replace(_T(
"/"),
297 aboutText.Append(log_string);
300 wxString config_string =
301 _T(
"<br><br>Config file location: ") + g_Platform->GetConfigFileName();
302 config_string.Replace(_T(
"/"),
304 aboutText.Append(config_string);
306 if (wxFONTSTYLE_ITALIC == dFont->GetStyle()) aboutText.Append(_T(
"</i>"));
309 aboutText.Append(_T(
"</font></body></html>"));
311 pAboutHTMLCtl->SetPage(aboutText);
315 wxString authorText = wxString::Format(
316 _T(
"<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
317 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green());
319 pAuthorHTMLCtl->SetFonts(face, face, sizes);
321 wxString authorFixText = AuthorText;
322 authorFixText.Replace(_T(
"\n"), _T(
"<br>"));
323 authorText.Append(authorFixText);
326 authorText.Append(_T(
"</font></body></html>"));
328 pAuthorHTMLCtl->SetPage(authorFixText);
334 wxString licenseText =
336 _T(
"<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
337 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green() );
339 pLicenseHTMLCtl->SetFonts( face, face, sizes );
341 wxTextFile license_filea( m_DataLocn + _T(
"license.txt") );
342 if ( license_filea.Open() ) {
343 for ( wxString str = license_filea.GetFirstLine(); !license_filea.Eof() ; str = license_filea.GetNextLine() )
344 licenseText.Append( str + _T(
"<br>") );
345 license_filea.Close();
347 wxLogMessage( _T(
"Could not open License file: ") + m_DataLocn );
350 wxString suppLicense = g_Platform->GetSupplementalLicenseString();
352 wxStringTokenizer st(suppLicense, _T(
"\n"), wxTOKEN_DEFAULT);
353 while( st.HasMoreTokens() )
355 wxString s1 = st.GetNextToken();
356 licenseText.Append( s1 + _T(
"<br>") );
360 licenseText.Append( _T(
"</font></body></html>") );
362 pLicenseHTMLCtl->SetPage( licenseText );
368void about::RecalculateSize(
void) {
372 esize.x = GetCharWidth() * 110;
373 esize.y = GetCharHeight() * 44;
375 wxSize dsize = GetParent()->GetSize();
376 esize.y = wxMin(esize.y, dsize.y - (0 * GetCharHeight()));
377 esize.x = wxMin(esize.x, dsize.x - (0 * GetCharHeight()));
378 SetClientSize(esize);
380 wxSize fsize = GetSize();
381 fsize.y = wxMin(fsize.y, dsize.y - (0 * GetCharHeight()));
382 fsize.x = wxMin(fsize.x, dsize.x - (0 * GetCharHeight()));
389void about::CreateControls(
void) {
392 wxBoxSizer* mainSizer =
new wxBoxSizer(wxVERTICAL);
395 new wxStaticText(
this, -1, _(
"The Open Source Chart Plotter/Navigator"),
396 wxDefaultPosition, wxSize(-1, 50 ),
402 14, wxFONTFAMILY_DEFAULT, qFont->GetStyle(), wxFONTWEIGHT_BOLD,
false,
403 qFont->GetFaceName());
404 pST1->SetFont(*headerFont);
405 mainSizer->Add(pST1, 0, wxALL | wxEXPAND, 8);
407 bool orient = m_displaySize.x < m_displaySize.y;
408#ifndef __OCPN__ANDROID__
409 wxBoxSizer* buttonSizer =
new wxBoxSizer(orient ? wxVERTICAL : wxHORIZONTAL);
410 mainSizer->Add(buttonSizer, 0, wxALL, 0);
412 wxButton* donateButton =
new wxBitmapButton(
413 this, ID_DONATE, g_StyleManager->GetCurrentStyle()->GetIcon(_T(
"donate")),
414 wxDefaultPosition, wxDefaultSize, 0);
417 new wxButton(
this, ID_COPYLOG, _(
"Copy Log File to Clipboard")), 1,
418 wxALL | wxEXPAND, 3);
420 new wxButton(
this, ID_COPYINI, _(
"Copy Settings File to Clipboard")), 1,
421 wxALL | wxEXPAND, 3);
425 (buttonSizer->GetOrientation() == wxHORIZONTAL ? wxALIGN_RIGHT : 0),
430 pNotebook =
new wxNotebook(
this, ID_NOTEBOOK_HELP, wxDefaultPosition,
431 wxSize(-1, -1), wxNB_TOP);
433 pNotebook->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
434 wxNotebookEventHandler(about::OnNBPageChange), NULL,
this);
436 pNotebook->InheritAttributes();
437 mainSizer->Add(pNotebook, 1,
438 (orient ? wxALIGN_CENTER_VERTICAL : 0) | wxEXPAND | wxALL, 5);
441 itemPanelAbout =
new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
442 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
443 itemPanelAbout->InheritAttributes();
444 pNotebook->AddPage(itemPanelAbout, _(
"About"), TRUE );
447 new wxHtmlWindow(itemPanelAbout, wxID_ANY, wxDefaultPosition,
448 wxDefaultSize, wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
449 pAboutHTMLCtl->SetBorders(5);
450 wxBoxSizer* aboutSizer =
new wxBoxSizer(wxVERTICAL);
451 aboutSizer->Add(pAboutHTMLCtl, 1,
452 wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5);
453 itemPanelAbout->SetSizer(aboutSizer);
458 new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
459 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
460 itemPanelAuthors->InheritAttributes();
461 pNotebook->AddPage(itemPanelAuthors, _(
"Authors"));
464 new wxHtmlWindow(itemPanelAuthors, wxID_ANY, wxDefaultPosition,
465 wxDefaultSize, wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
466 pAuthorHTMLCtl->SetBorders(5);
467 wxBoxSizer* authorSizer =
new wxBoxSizer(wxVERTICAL);
468 authorSizer->Add(pAuthorHTMLCtl, 1,
469 wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5);
470 itemPanelAuthors->SetSizer(authorSizer);
474 new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
475 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
476 itemPanelLicense->InheritAttributes();
477 pNotebook->AddPage(itemPanelLicense, _(
"License"));
480 new wxHtmlWindow(itemPanelLicense, wxID_ANY, wxDefaultPosition,
481 wxDefaultSize, wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
482 pLicenseHTMLCtl->SetBorders(5);
483 wxBoxSizer* licenseSizer =
new wxBoxSizer(wxVERTICAL);
484 licenseSizer->Add(pLicenseHTMLCtl, 1,
485 wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5);
486 itemPanelLicense->SetSizer(licenseSizer);
489 itemPanelTips =
new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
490 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
491 itemPanelTips->InheritAttributes();
492 pNotebook->AddPage(itemPanelTips, _(
"Help"));
494 wxBoxSizer* helpSizer =
new wxBoxSizer(wxVERTICAL);
495 itemPanelTips->SetSizer(helpSizer);
498 wxButton* closeButton =
new wxButton(
this, xID_OK, _(
"Close"),
499 wxDefaultPosition, wxDefaultSize, 0);
500 closeButton->SetDefault();
501 closeButton->InheritAttributes();
502 mainSizer->Add(closeButton, 0, wxALIGN_RIGHT | wxALL, 5);
505void about::OnNBPageChange(wxNotebookEvent& event) {
506 unsigned int i =
event.GetSelection();
509 g_Platform->LaunchLocalHelp();
510 pNotebook->ChangeSelection(0);
513 else if ((i == 2) && !m_blicensePageSet) {
515 wxColor bg = GetBackgroundColour();
516 wxColor fg = wxColour(0, 0, 0);
517 wxFont* dFont = FontMgr::Get().
GetFont(_(
"Dialog"));
520 int points = dFont->GetPointSize();
525 for (
int i = -2; i < 5; i++) {
526 sizes[i + 2] = points + i + (i > 0 ? i : 0);
528 wxString face = dFont->GetFaceName();
531 g_Platform->ShowBusySpinner();
534 wxString licenseText = wxString::Format(
535 _T(
"<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
536 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green());
538 pLicenseHTMLCtl->SetFonts(face, face, sizes);
540 wxTextFile license_filea(m_DataLocn + _T(
"license.txt"));
541 if (license_filea.Open()) {
542 for (wxString str = license_filea.GetFirstLine(); !license_filea.Eof();
543 str = license_filea.GetNextLine())
544 licenseText.Append(str + _T(
"<br>"));
545 license_filea.Close();
547 wxLogMessage(_T(
"Could not open License file: ") + m_DataLocn);
550 wxString suppLicense = g_Platform->GetSupplementalLicenseString();
552 wxStringTokenizer st(suppLicense, _T(
"\n"), wxTOKEN_DEFAULT);
553 while (st.HasMoreTokens()) {
554 wxString s1 = st.GetNextToken();
555 licenseText.Append(s1 + _T(
"<br>"));
559 licenseText.Append(_T(
"</font></body></html>"));
561 pLicenseHTMLCtl->SetPage(licenseText);
563 g_Platform->HideBusySpinner();
566 m_blicensePageSet =
true;
570void about::OnXidOkClick(wxCommandEvent& event) { Close(); }
572void about::OnClose(wxCloseEvent& event) {
574 wxTheApp->GetTopWindow()->Raise();
577 g_pAboutDlgLegacy = NULL;
580void about::OnDonateClick(wxCommandEvent& event) {
581 wxLaunchDefaultBrowser(
582 _T(
"https://sourceforge.net/donate/index.php?group_id=180842"));
585void about::OnCopyClick(wxCommandEvent& event) {
586 wxString filename =
event.GetId() == ID_COPYLOG
587 ? g_Platform->GetLogFileName()
588 : g_Platform->GetConfigFileName();
590 wxFFile file(filename);
592 if (!file.IsOpened()) {
593 wxLogMessage(_T(
"Failed to open file for Copy to Clipboard."));
597 wxString fileContent;
599 while (!file.Eof()) {
600 int c = file.Read(&buf, 1024);
601 if (c) fileContent += wxString(buf, wxConvUTF8, c);
605 int length = fileContent.Length();
607 if (event.GetId() == ID_COPYLOG) {
608 wxString lastLogs = fileContent;
609 int pos = lastLogs.Find(_T(
"________"));
610 while (pos != wxNOT_FOUND && lastLogs.Length() > 65000) {
611 lastLogs = lastLogs.Right(lastLogs.Length() - pos - 8);
612 pos = lastLogs.Find(_T(
"________"));
614 fileContent = lastLogs;
617 ::wxBeginBusyCursor();
618 if (wxTheClipboard->Open()) {
619 if (!wxTheClipboard->SetData(
new wxTextDataObject(fileContent)))
620 wxLogMessage(_T(
"wxTheClipboard->Open() failed."));
621 wxTheClipboard->Close();
623 wxLogMessage(_T(
"wxTheClipboard->Open() failed."));
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Gets a font object for a UI element.
Plugin ABI encapsulation.
Represents the About dialog for OpenCPN.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.