30 #include <wx/wxprec.h>
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"
58 extern about* g_pAboutDlgLegacy;
59 extern bool g_bresponsive;
61 wxString OpenCPNVersion(
"\n Version ");
67 const wxString AboutText =
68 wxT(
"<br>OpenCPN<br>")
69 wxT("(c) 2000-2023 The OpenCPN Authors<br><br>");
71 const 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:
80 const 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:
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")
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");
180 IMPLEMENT_DYNAMIC_CLASS(
about, wxDialog)
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)
191 : m_DataLocn(wxEmptyString), m_parent(NULL), m_btips_loaded(FALSE) {
192 pAboutHTMLCtl = NULL;
193 pLicenseHTMLCtl = NULL;
194 pAuthorHTMLCtl = NULL;
195 m_blicensePageSet =
false;
198 about::about(wxWindow* parent, wxString Data_Locn, wxWindowID
id,
199 const wxString& caption,
const wxPoint& pos,
const wxSize& size,
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;
207 if(strlen(DEBIAN_PPA_VERSION))
208 OpenCPNVersion += wxString(DEBIAN_PPA_VERSION);
210 OpenCPNVersion += wxString(PACKAGE_VERSION);
212 Create(parent,
id, caption, pos, size, style);
215 bool about::Create(wxWindow* parent, wxWindowID
id,
const wxString& caption,
216 const wxPoint& pos,
const wxSize& size,
long style) {
219 style |= wxSTAY_ON_TOP;
222 SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
223 wxDialog::Create(parent,
id, caption, pos, size, style);
224 wxFont* qFont = GetOCPNScaledFont(_(
"Dialog"));
227 m_displaySize = g_Platform->getDisplaySize();
236 void about::SetColorScheme(
void) {
238 wxColor bg = GetBackgroundColour();
239 if (pAboutHTMLCtl) pAboutHTMLCtl->SetBackgroundColour(bg);
240 if (pLicenseHTMLCtl) pLicenseHTMLCtl->SetBackgroundColour(bg);
241 if (pAuthorHTMLCtl) pAuthorHTMLCtl->SetBackgroundColour(bg);
245 SetBackgroundColour(bg);
249 wxBitmap tbm(GetSize().x, GetSize().y, -1);
251 tdc.SetBackground(bg);
253 if (pAboutHTMLCtl) pAboutHTMLCtl->SetBackgroundImage(tbm);
254 if (pLicenseHTMLCtl) pLicenseHTMLCtl->SetBackgroundImage(tbm);
255 if (pAuthorHTMLCtl) pAuthorHTMLCtl->SetBackgroundImage(tbm);
259 void about::Populate(
void) {
260 wxColor bg = GetBackgroundColour();
261 wxColor fg = wxColour(0, 0, 0);
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());
268 wxFont* dFont = FontMgr::Get().GetFont(_(
"Dialog"));
271 int points = dFont->GetPointSize();
276 for (
int i = -2; i < 5; i++) {
277 sizes[i + 2] = points + i + (i > 0 ? i : 0);
279 wxString face = dFont->GetFaceName();
280 pAboutHTMLCtl->SetFonts(face, face, sizes);
282 if (wxFONTSTYLE_ITALIC == dFont->GetStyle()) aboutText.Append(_T(
"<i>"));
284 #ifdef __OCPN__ANDROID__
286 msg.Printf(_T(
" [%d]"), androidGetVersionCode());
287 wxString OpenCPNVersionAndroid =
288 _T(
"OpenCPN for Android Version ") + androidGetVersionName() + msg;
290 aboutText.Append(AboutText + OpenCPNVersionAndroid + OpenCPNInfoAlt);
292 aboutText.Append(AboutText + OpenCPNVersion + OpenCPNInfo);
296 wxString log_string = _T(
"Logfile location: ") + g_Platform->GetLogFileName();
297 log_string.Replace(_T(
"/"),
300 aboutText.Append(log_string);
303 wxString config_string =
304 _T(
"<br><br>Config file location: ") + g_Platform->GetConfigFileName();
305 config_string.Replace(_T(
"/"),
307 aboutText.Append(config_string);
309 if (wxFONTSTYLE_ITALIC == dFont->GetStyle()) aboutText.Append(_T(
"</i>"));
312 aboutText.Append(_T(
"</font></body></html>"));
314 pAboutHTMLCtl->SetPage(aboutText);
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());
322 pAuthorHTMLCtl->SetFonts(face, face, sizes);
324 wxString authorFixText = AuthorText;
325 authorFixText.Replace(_T(
"\n"), _T(
"<br>"));
326 authorText.Append(authorFixText);
329 authorText.Append(_T(
"</font></body></html>"));
331 pAuthorHTMLCtl->SetPage(authorFixText);
337 wxString licenseText =
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() );
342 pLicenseHTMLCtl->SetFonts( face, face, sizes );
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();
350 wxLogMessage( _T(
"Could not open License file: ") + m_DataLocn );
353 wxString suppLicense = g_Platform->GetSupplementalLicenseString();
355 wxStringTokenizer st(suppLicense, _T(
"\n"), wxTOKEN_DEFAULT);
356 while( st.HasMoreTokens() )
358 wxString s1 = st.GetNextToken();
359 licenseText.Append( s1 + _T(
"<br>") );
363 licenseText.Append( _T(
"</font></body></html>") );
365 pLicenseHTMLCtl->SetPage( licenseText );
371 void about::RecalculateSize(
void) {
375 esize.x = GetCharWidth() * 110;
376 esize.y = GetCharHeight() * 44;
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);
383 wxSize fsize = GetSize();
384 fsize.y = wxMin(fsize.y, dsize.y - (0 * GetCharHeight()));
385 fsize.x = wxMin(fsize.x, dsize.x - (0 * GetCharHeight()));
392 void about::CreateControls(
void) {
395 wxBoxSizer* mainSizer =
new wxBoxSizer(wxVERTICAL);
398 new wxStaticText(
this, -1, _(
"The Open Source Chart Plotter/Navigator"),
399 wxDefaultPosition, wxSize(-1, 50 ),
402 wxFont* qFont = GetOCPNScaledFont(_(
"Dialog"));
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);
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);
415 wxButton* donateButton =
new wxBitmapButton(
416 this, ID_DONATE, g_StyleManager->GetCurrentStyle()->GetIcon(_T(
"donate")),
417 wxDefaultPosition, wxDefaultSize, 0);
420 new wxButton(
this, ID_COPYLOG, _(
"Copy Log File to Clipboard")), 1,
421 wxALL | wxEXPAND, 3);
423 new wxButton(
this, ID_COPYINI, _(
"Copy Settings File to Clipboard")), 1,
424 wxALL | wxEXPAND, 3);
428 (buttonSizer->GetOrientation() == wxHORIZONTAL ? wxALIGN_RIGHT : 0),
433 pNotebook =
new wxNotebook(
this, ID_NOTEBOOK_HELP, wxDefaultPosition,
434 wxSize(-1, -1), wxNB_TOP);
436 pNotebook->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
437 wxNotebookEventHandler(about::OnNBPageChange), NULL,
this);
439 pNotebook->InheritAttributes();
440 mainSizer->Add(pNotebook, 1,
441 (orient ? wxALIGN_CENTER_VERTICAL : 0) | wxEXPAND | wxALL, 5);
444 itemPanelAbout =
new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
445 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
446 itemPanelAbout->InheritAttributes();
447 pNotebook->AddPage(itemPanelAbout, _(
"About"), TRUE );
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);
461 new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
462 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
463 itemPanelAuthors->InheritAttributes();
464 pNotebook->AddPage(itemPanelAuthors, _(
"Authors"));
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);
477 new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
478 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
479 itemPanelLicense->InheritAttributes();
480 pNotebook->AddPage(itemPanelLicense, _(
"License"));
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);
492 itemPanelTips =
new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
493 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
494 itemPanelTips->InheritAttributes();
495 pNotebook->AddPage(itemPanelTips, _(
"Help"));
497 wxBoxSizer* helpSizer =
new wxBoxSizer(wxVERTICAL);
498 itemPanelTips->SetSizer(helpSizer);
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);
508 void about::OnNBPageChange(wxNotebookEvent& event) {
509 unsigned int i =
event.GetSelection();
512 g_Platform->LaunchLocalHelp();
513 pNotebook->ChangeSelection(0);
516 else if ((i == 2) && !m_blicensePageSet) {
518 wxColor bg = GetBackgroundColour();
519 wxColor fg = wxColour(0, 0, 0);
520 wxFont* dFont = FontMgr::Get().GetFont(_(
"Dialog"));
523 int points = dFont->GetPointSize();
528 for (
int i = -2; i < 5; i++) {
529 sizes[i + 2] = points + i + (i > 0 ? i : 0);
531 wxString face = dFont->GetFaceName();
534 g_Platform->ShowBusySpinner();
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());
541 pLicenseHTMLCtl->SetFonts(face, face, sizes);
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();
550 wxLogMessage(_T(
"Could not open License file: ") + m_DataLocn);
553 wxString suppLicense = g_Platform->GetSupplementalLicenseString();
555 wxStringTokenizer st(suppLicense, _T(
"\n"), wxTOKEN_DEFAULT);
556 while (st.HasMoreTokens()) {
557 wxString s1 = st.GetNextToken();
558 licenseText.Append(s1 + _T(
"<br>"));
562 licenseText.Append(_T(
"</font></body></html>"));
564 pLicenseHTMLCtl->SetPage(licenseText);
566 g_Platform->HideBusySpinner();
569 m_blicensePageSet =
true;
573 void about::OnXidOkClick(wxCommandEvent& event) { Close(); }
575 void about::OnClose(wxCloseEvent& event) {
580 g_pAboutDlgLegacy = NULL;
583 void about::OnDonateClick(wxCommandEvent& event) {
584 wxLaunchDefaultBrowser(
585 _T(
"https://sourceforge.net/donate/index.php?group_id=180842"));
588 void about::OnCopyClick(wxCommandEvent& event) {
589 wxString filename =
event.GetId() == ID_COPYLOG
590 ? g_Platform->GetLogFileName()
591 : g_Platform->GetConfigFileName();
593 wxFFile file(filename);
595 if (!file.IsOpened()) {
596 wxLogMessage(_T(
"Failed to open file for Copy to Clipboard."));
600 wxString fileContent;
602 while (!file.Eof()) {
603 int c = file.Read(&buf, 1024);
604 if (c) fileContent += wxString(buf, wxConvUTF8, c);
608 int length = fileContent.Length();
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(
"________"));
617 fileContent = lastLogs;
620 ::wxBeginBusyCursor();
621 if (wxTheClipboard->Open()) {
622 if (!wxTheClipboard->SetData(
new wxTextDataObject(fileContent)))
623 wxLogMessage(_T(
"wxTheClipboard->Open() failed."));
624 wxTheClipboard->Close();
626 wxLogMessage(_T(
"wxTheClipboard->Open() failed."));
Plugin ABI encapsulation.
General purpose GUI support.