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(
"\n Version ");
67const wxString AboutText =
68 wxT(
"<br>OpenCPN<br>")
69 wxT("(c) 2000-2024 The OpenCPN Authors<br><br>");
71const wxString OpenCPNInfo =
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:
80const wxString OpenCPNInfoAlt =
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.")
87 wxT("For more information, visit http:
90const 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")
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")
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")
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");
180BEGIN_EVENT_TABLE(
about, wxDialog)
181EVT_BUTTON(xID_OK,
about::OnXidOkClick)
182EVT_BUTTON(ID_DONATE,
about::OnDonateClick)
183EVT_BUTTON(ID_COPYINI,
about::OnCopyClick)
184EVT_BUTTON(ID_COPYLOG,
about::OnCopyClick)
185EVT_CLOSE(
about::OnClose)
189 : m_DataLocn(wxEmptyString), m_parent(NULL), m_btips_loaded(FALSE) {
190 pAboutHTMLCtl = NULL;
191 pLicenseHTMLCtl = NULL;
192 pAuthorHTMLCtl = NULL;
193 m_blicensePageSet =
false;
196about::about(wxWindow* parent, wxString Data_Locn, wxWindowID
id,
197 const wxString& caption,
const wxPoint& pos,
const wxSize& size,
199 : m_DataLocn(Data_Locn), m_parent(parent), m_btips_loaded(FALSE) {
200 pAboutHTMLCtl = NULL;
201 pLicenseHTMLCtl = NULL;
202 pAuthorHTMLCtl = NULL;
203 m_blicensePageSet =
false;
205 if (strlen(DEBIAN_PPA_VERSION))
206 OpenCPNVersion += wxString(DEBIAN_PPA_VERSION);
208 OpenCPNVersion += wxString(PACKAGE_VERSION);
210 Create(parent,
id, caption, pos, size, style);
213bool about::Create(wxWindow* parent, wxWindowID
id,
const wxString& caption,
214 const wxPoint& pos,
const wxSize& size,
long style) {
217 style |= wxSTAY_ON_TOP;
220 SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
221 wxDialog::Create(parent,
id, caption, pos, size, style);
234void about::SetColorScheme(
void) {
236 wxColor bg = GetBackgroundColour();
237 if (pAboutHTMLCtl) pAboutHTMLCtl->SetBackgroundColour(bg);
238 if (pLicenseHTMLCtl) pLicenseHTMLCtl->SetBackgroundColour(bg);
239 if (pAuthorHTMLCtl) pAuthorHTMLCtl->SetBackgroundColour(bg);
243 SetBackgroundColour(bg);
247 wxBitmap tbm(GetSize().x, GetSize().y, -1);
249 tdc.SetBackground(bg);
251 if (pAboutHTMLCtl) pAboutHTMLCtl->SetBackgroundImage(tbm);
252 if (pLicenseHTMLCtl) pLicenseHTMLCtl->SetBackgroundImage(tbm);
253 if (pAuthorHTMLCtl) pAuthorHTMLCtl->SetBackgroundImage(tbm);
257void about::Populate(
void) {
258 wxColor bg = GetBackgroundColour();
259 wxColor fg = wxColour(0, 0, 0);
262 wxString aboutText = wxString::Format(
263 _T(
"<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
264 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green());
266 wxFont* dFont = FontMgr::Get().
GetFont(_(
"Dialog"));
269 int points = dFont->GetPointSize();
274 for (
int i = -2; i < 5; i++) {
275 sizes[i + 2] = points + i + (i > 0 ? i : 0);
277 wxString face = dFont->GetFaceName();
278 pAboutHTMLCtl->SetFonts(face, face, sizes);
280 if (wxFONTSTYLE_ITALIC == dFont->GetStyle()) aboutText.Append(_T(
"<i>"));
282#ifdef __OCPN__ANDROID__
284 msg.Printf(_T(
" [%d]"), androidGetVersionCode());
285 wxString OpenCPNVersionAndroid =
286 _T(
"OpenCPN for Android Version ") + androidGetVersionName() + msg;
288 aboutText.Append(AboutText + OpenCPNVersionAndroid + OpenCPNInfoAlt);
290 aboutText.Append(AboutText + OpenCPNVersion + OpenCPNInfo);
294 wxString log_string = _T(
"Logfile location: ") + g_Platform->GetLogFileName();
295 log_string.Replace(_T(
"/"),
298 aboutText.Append(log_string);
301 wxString config_string =
302 _T(
"<br><br>Config file location: ") + g_Platform->GetConfigFileName();
303 config_string.Replace(_T(
"/"),
305 aboutText.Append(config_string);
307 if (wxFONTSTYLE_ITALIC == dFont->GetStyle()) aboutText.Append(_T(
"</i>"));
310 aboutText.Append(_T(
"</font></body></html>"));
312 pAboutHTMLCtl->SetPage(aboutText);
316 wxString authorText = 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());
320 pAuthorHTMLCtl->SetFonts(face, face, sizes);
322 wxString authorFixText = AuthorText;
323 authorFixText.Replace(_T(
"\n"), _T(
"<br>"));
324 authorText.Append(authorFixText);
327 authorText.Append(_T(
"</font></body></html>"));
329 pAuthorHTMLCtl->SetPage(authorFixText);
335 wxString licenseText =
337 _T(
"<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
338 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green() );
340 pLicenseHTMLCtl->SetFonts( face, face, sizes );
342 wxTextFile license_filea( m_DataLocn + _T(
"license.txt") );
343 if ( license_filea.Open() ) {
344 for ( wxString str = license_filea.GetFirstLine(); !license_filea.Eof() ; str = license_filea.GetNextLine() )
345 licenseText.Append( str + _T(
"<br>") );
346 license_filea.Close();
348 wxLogMessage( _T(
"Could not open License file: ") + m_DataLocn );
351 wxString suppLicense = g_Platform->GetSupplementalLicenseString();
353 wxStringTokenizer st(suppLicense, _T(
"\n"), wxTOKEN_DEFAULT);
354 while( st.HasMoreTokens() )
356 wxString s1 = st.GetNextToken();
357 licenseText.Append( s1 + _T(
"<br>") );
361 licenseText.Append( _T(
"</font></body></html>") );
363 pLicenseHTMLCtl->SetPage( licenseText );
369void about::RecalculateSize(
void) {
373 esize.x = GetCharWidth() * 110;
374 esize.y = GetCharHeight() * 44;
376 wxSize dsize = GetParent()->GetSize();
377 esize.y = wxMin(esize.y, dsize.y - (0 * GetCharHeight()));
378 esize.x = wxMin(esize.x, dsize.x - (0 * GetCharHeight()));
379 SetClientSize(esize);
381 wxSize fsize = GetSize();
382 fsize.y = wxMin(fsize.y, dsize.y - (0 * GetCharHeight()));
383 fsize.x = wxMin(fsize.x, dsize.x - (0 * GetCharHeight()));
390void about::CreateControls(
void) {
393 wxBoxSizer* mainSizer =
new wxBoxSizer(wxVERTICAL);
396 new wxStaticText(
this, -1, _(
"The Open Source Chart Plotter/Navigator"),
397 wxDefaultPosition, wxSize(-1, 50 ),
403 14, wxFONTFAMILY_DEFAULT, qFont->GetStyle(), wxFONTWEIGHT_BOLD,
false,
404 qFont->GetFaceName());
405 pST1->SetFont(*headerFont);
406 mainSizer->Add(pST1, 0, wxALL | wxEXPAND, 8);
408 bool orient = m_displaySize.x < m_displaySize.y;
409#ifndef __OCPN__ANDROID__
410 wxBoxSizer* buttonSizer =
new wxBoxSizer(orient ? wxVERTICAL : wxHORIZONTAL);
411 mainSizer->Add(buttonSizer, 0, wxALL, 0);
413 wxButton* donateButton =
new wxBitmapButton(
414 this, ID_DONATE, g_StyleManager->GetCurrentStyle()->GetIcon(_T(
"donate")),
415 wxDefaultPosition, wxDefaultSize, 0);
418 new wxButton(
this, ID_COPYLOG, _(
"Copy Log File to Clipboard")), 1,
419 wxALL | wxEXPAND, 3);
421 new wxButton(
this, ID_COPYINI, _(
"Copy Settings File to Clipboard")), 1,
422 wxALL | wxEXPAND, 3);
426 (buttonSizer->GetOrientation() == wxHORIZONTAL ? wxALIGN_RIGHT : 0),
431 pNotebook =
new wxNotebook(
this, ID_NOTEBOOK_HELP, wxDefaultPosition,
432 wxSize(-1, -1), wxNB_TOP);
434 pNotebook->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
435 wxNotebookEventHandler(about::OnNBPageChange), NULL,
this);
437 pNotebook->InheritAttributes();
438 mainSizer->Add(pNotebook, 1,
439 (orient ? wxALIGN_CENTER_VERTICAL : 0) | wxEXPAND | wxALL, 5);
442 itemPanelAbout =
new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
443 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
444 itemPanelAbout->InheritAttributes();
445 pNotebook->AddPage(itemPanelAbout, _(
"About"), TRUE );
448 new wxHtmlWindow(itemPanelAbout, wxID_ANY, wxDefaultPosition,
449 wxDefaultSize, wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
450 pAboutHTMLCtl->SetBorders(5);
451 wxBoxSizer* aboutSizer =
new wxBoxSizer(wxVERTICAL);
452 aboutSizer->Add(pAboutHTMLCtl, 1,
453 wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5);
454 itemPanelAbout->SetSizer(aboutSizer);
459 new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
460 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
461 itemPanelAuthors->InheritAttributes();
462 pNotebook->AddPage(itemPanelAuthors, _(
"Authors"));
465 new wxHtmlWindow(itemPanelAuthors, wxID_ANY, wxDefaultPosition,
466 wxDefaultSize, wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
467 pAuthorHTMLCtl->SetBorders(5);
468 wxBoxSizer* authorSizer =
new wxBoxSizer(wxVERTICAL);
469 authorSizer->Add(pAuthorHTMLCtl, 1,
470 wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5);
471 itemPanelAuthors->SetSizer(authorSizer);
475 new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
476 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
477 itemPanelLicense->InheritAttributes();
478 pNotebook->AddPage(itemPanelLicense, _(
"License"));
481 new wxHtmlWindow(itemPanelLicense, wxID_ANY, wxDefaultPosition,
482 wxDefaultSize, wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
483 pLicenseHTMLCtl->SetBorders(5);
484 wxBoxSizer* licenseSizer =
new wxBoxSizer(wxVERTICAL);
485 licenseSizer->Add(pLicenseHTMLCtl, 1,
486 wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5);
487 itemPanelLicense->SetSizer(licenseSizer);
490 itemPanelTips =
new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
491 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
492 itemPanelTips->InheritAttributes();
493 pNotebook->AddPage(itemPanelTips, _(
"Help"));
495 wxBoxSizer* helpSizer =
new wxBoxSizer(wxVERTICAL);
496 itemPanelTips->SetSizer(helpSizer);
499 wxButton* closeButton =
new wxButton(
this, xID_OK, _(
"Close"),
500 wxDefaultPosition, wxDefaultSize, 0);
501 closeButton->SetDefault();
502 closeButton->InheritAttributes();
503 mainSizer->Add(closeButton, 0, wxALIGN_RIGHT | wxALL, 5);
506void about::OnNBPageChange(wxNotebookEvent& event) {
507 unsigned int i =
event.GetSelection();
510 g_Platform->LaunchLocalHelp();
511 pNotebook->ChangeSelection(0);
514 else if ((i == 2) && !m_blicensePageSet) {
516 wxColor bg = GetBackgroundColour();
517 wxColor fg = wxColour(0, 0, 0);
518 wxFont* dFont = FontMgr::Get().
GetFont(_(
"Dialog"));
521 int points = dFont->GetPointSize();
526 for (
int i = -2; i < 5; i++) {
527 sizes[i + 2] = points + i + (i > 0 ? i : 0);
529 wxString face = dFont->GetFaceName();
532 g_Platform->ShowBusySpinner();
535 wxString licenseText = wxString::Format(
536 _T(
"<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>" ),
537 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green());
539 pLicenseHTMLCtl->SetFonts(face, face, sizes);
541 wxTextFile license_filea(m_DataLocn + _T(
"license.txt"));
542 if (license_filea.Open()) {
543 for (wxString str = license_filea.GetFirstLine(); !license_filea.Eof();
544 str = license_filea.GetNextLine())
545 licenseText.Append(str + _T(
"<br>"));
546 license_filea.Close();
548 wxLogMessage(_T(
"Could not open License file: ") + m_DataLocn);
551 wxString suppLicense = g_Platform->GetSupplementalLicenseString();
553 wxStringTokenizer st(suppLicense, _T(
"\n"), wxTOKEN_DEFAULT);
554 while (st.HasMoreTokens()) {
555 wxString s1 = st.GetNextToken();
556 licenseText.Append(s1 + _T(
"<br>"));
560 licenseText.Append(_T(
"</font></body></html>"));
562 pLicenseHTMLCtl->SetPage(licenseText);
564 g_Platform->HideBusySpinner();
567 m_blicensePageSet =
true;
571void about::OnXidOkClick(wxCommandEvent& event) { Close(); }
573void about::OnClose(wxCloseEvent& event) {
578 g_pAboutDlgLegacy = NULL;
581void about::OnDonateClick(wxCommandEvent& event) {
582 wxLaunchDefaultBrowser(
583 _T(
"https://sourceforge.net/donate/index.php?group_id=180842"));
586void about::OnCopyClick(wxCommandEvent& event) {
587 wxString filename =
event.GetId() == ID_COPYLOG
588 ? g_Platform->GetLogFileName()
589 : g_Platform->GetConfigFileName();
591 wxFFile file(filename);
593 if (!file.IsOpened()) {
594 wxLogMessage(_T(
"Failed to open file for Copy to Clipboard."));
598 wxString fileContent;
600 while (!file.Eof()) {
601 int c = file.Read(&buf, 1024);
602 if (c) fileContent += wxString(buf, wxConvUTF8, c);
606 int length = fileContent.Length();
608 if (event.GetId() == ID_COPYLOG) {
609 wxString lastLogs = fileContent;
610 int pos = lastLogs.Find(_T(
"________"));
611 while (pos != wxNOT_FOUND && lastLogs.Length() > 65000) {
612 lastLogs = lastLogs.Right(lastLogs.Length() - pos - 8);
613 pos = lastLogs.Find(_T(
"________"));
615 fileContent = lastLogs;
618 ::wxBeginBusyCursor();
619 if (wxTheClipboard->Open()) {
620 if (!wxTheClipboard->SetData(
new wxTextDataObject(fileContent)))
621 wxLogMessage(_T(
"wxTheClipboard->Open() failed."));
622 wxTheClipboard->Close();
624 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.