33#include <wx/clipbrd.h>
35#include <wx/html/htmlwin.h>
36#include <wx/textfile.h>
37#include <wx/tokenzr.h>
50#include "std_filesystem.h"
54#include "androidUTIL.h"
62static wxString OpenCPNVersion(
"\n Version ");
66static const wxString AboutText =
68 "(c) 2000-2024 The OpenCPN Authors<br><br>";
70static const wxString OpenCPNInfo =
72 "OpenCPN is a Free Software project, built by sailors. "
73 "It is freely available to download and distribute "
74 "without charge at opencpn.org.<br><br>"
75 "If you use OpenCPN, please consider contributing "
76 "or donating funds to the project.<br><br>"
77 "For more information, visit http://opencpn.org<br><br>";
79static const wxString OpenCPNInfoAlt =
81 "OpenCPN is a Free Software project, built by sailors."
82 "The complete source code and many other resources "
83 "are freely available for your download and use, "
84 "subject to applicable License agreements."
86 "For more information, visit http://opencpn.org<br><br>";
90BEGIN_EVENT_TABLE(
About, wxDialog)
91EVT_BUTTON(xID_OK, About::OnXidOkClick)
92EVT_BUTTON(ID_DONATE, About::OnDonateClick)
93EVT_BUTTON(ID_COPYINI, About::OnCopyClick)
94EVT_BUTTON(ID_COPYLOG, About::OnCopyClick)
95EVT_CLOSE(About::OnClose)
99 : m_DataLocn(wxEmptyString), m_parent(NULL), m_btips_loaded(FALSE) {
100 pAboutHTMLCtl = NULL;
101 pLicenseHTMLCtl = NULL;
102 pAuthorHTMLCtl = NULL;
103 m_blicensePageSet =
false;
106About::About(wxWindow* parent, wxString Data_Locn,
107 std::function<
void()> launch_local_help, wxWindowID
id,
108 const wxString& caption,
const wxPoint& pos,
const wxSize& size,
110 : m_DataLocn(Data_Locn),
112 m_launch_local_help(launch_local_help),
113 m_btips_loaded(FALSE) {
114 pAboutHTMLCtl = NULL;
115 pLicenseHTMLCtl = NULL;
116 pAuthorHTMLCtl = NULL;
117 m_blicensePageSet =
false;
119 if (strlen(DEBIAN_PPA_VERSION))
120 OpenCPNVersion += wxString(DEBIAN_PPA_VERSION);
122 OpenCPNVersion += wxString(PACKAGE_VERSION);
124 Create(parent,
id, caption, pos, size, style);
127bool About::Create(wxWindow* parent, wxWindowID
id,
const wxString& caption,
128 const wxPoint& pos,
const wxSize& size,
long style) {
131 style |= wxSTAY_ON_TOP;
134 SetExtraStyle(GetExtraStyle() | wxWS_EX_BLOCK_EVENTS);
135 wxDialog::Create(parent,
id, caption, pos, size, style);
148void About::SetColorScheme() {
150 wxColor bg = GetBackgroundColour();
151 if (pAboutHTMLCtl) pAboutHTMLCtl->SetBackgroundColour(bg);
152 if (pLicenseHTMLCtl) pLicenseHTMLCtl->SetBackgroundColour(bg);
153 if (pAuthorHTMLCtl) pAuthorHTMLCtl->SetBackgroundColour(bg);
157 SetBackgroundColour(bg);
161 wxBitmap tbm(GetSize().x, GetSize().y, -1);
163 tdc.SetBackground(bg);
165 if (pAboutHTMLCtl) pAboutHTMLCtl->SetBackgroundImage(tbm);
166 if (pLicenseHTMLCtl) pLicenseHTMLCtl->SetBackgroundImage(tbm);
167 if (pAuthorHTMLCtl) pAuthorHTMLCtl->SetBackgroundImage(tbm);
171void About::Populate() {
172 wxColor bg = GetBackgroundColour();
173 wxColor fg = wxColour(0, 0, 0);
176 wxString aboutText = wxString::Format(
177 "<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>", bg.Red(),
178 bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green());
180 wxFont* dFont = FontMgr::Get().
GetFont(_(
"Dialog"));
183 int points = dFont->GetPointSize();
188 for (
int i = -2; i < 5; i++) {
189 sizes[i + 2] = points + i + (i > 0 ? i : 0);
191 wxString face = dFont->GetFaceName();
192 pAboutHTMLCtl->SetFonts(face, face, sizes);
194 if (wxFONTSTYLE_ITALIC == dFont->GetStyle()) aboutText.Append(
"<i>");
198 msg.Printf(
" [%d]", androidGetVersionCode());
199 wxString OpenCPNVersionAndroid =
200 "OpenCPN for Android Version " + androidGetVersionName() + msg;
202 aboutText.Append(AboutText + OpenCPNVersionAndroid + OpenCPNInfoAlt);
204 aboutText.Append(AboutText + OpenCPNVersion + OpenCPNInfo);
208 wxString log_string =
"Logfile location: " +
g_BasePlatform->GetLogFileName();
209 log_string.Replace(
"/",
"/ ");
211 aboutText.Append(log_string);
214 wxString config_string =
215 "<br><br>Config file location: " +
g_BasePlatform->GetConfigFileName();
216 config_string.Replace(
"/",
"/ ");
217 aboutText.Append(config_string);
219 if (wxFONTSTYLE_ITALIC == dFont->GetStyle()) aboutText.Append(
"</i>");
222 aboutText.Append(
"</font></body></html>");
224 pAboutHTMLCtl->SetPage(aboutText);
229 fs::path data_path(
g_BasePlatform->GetSharedDataDir().ToStdString());
230 std::ifstream istream(data_path /
"Authors.html");
231 std::stringstream ss;
232 ss << istream.rdbuf();
233 pAuthorHTMLCtl->SetPage(ss.str());
239 wxString licenseText =
241 "<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>",
242 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green() );
244 pLicenseHTMLCtl->SetFonts( face, face, sizes );
246 wxTextFile license_filea( m_DataLocn +
"license.txt" );
247 if ( license_filea.Open() ) {
248 for ( wxString str = license_filea.GetFirstLine(); !license_filea.Eof() ; str = license_filea.GetNextLine() )
249 licenseText.Append( str +
"<br>" );
250 license_filea.Close();
252 wxLogMessage(
"Could not open License file: " + m_DataLocn );
257 wxStringTokenizer st(suppLicense,
"\n", wxTOKEN_DEFAULT);
258 while( st.HasMoreTokens() )
260 wxString s1 = st.GetNextToken();
261 licenseText.Append( s1 +
"<br>" );
265 licenseText.Append(
"</font></body></html>" );
267 pLicenseHTMLCtl->SetPage( licenseText );
273void About::RecalculateSize() {
277 esize.x = GetCharWidth() * 110;
278 esize.y = GetCharHeight() * 44;
280 wxSize dsize = GetParent()->GetSize();
281 esize.y = wxMin(esize.y, dsize.y - (0 * GetCharHeight()));
282 esize.x = wxMin(esize.x, dsize.x - (0 * GetCharHeight()));
283 SetClientSize(esize);
285 wxSize fsize = GetSize();
286 fsize.y = wxMin(fsize.y, dsize.y - (0 * GetCharHeight()));
287 fsize.x = wxMin(fsize.x, dsize.x - (0 * GetCharHeight()));
294void About::CreateControls() {
297 wxBoxSizer* mainSizer =
new wxBoxSizer(wxVERTICAL);
300 new wxStaticText(
this, -1, _(
"The Open Source Chart Plotter/Navigator"),
301 wxDefaultPosition, wxSize(-1, 50 ),
307 14, wxFONTFAMILY_DEFAULT, qFont->GetStyle(), wxFONTWEIGHT_BOLD,
false,
308 qFont->GetFaceName());
309 pST1->SetFont(*headerFont);
310 mainSizer->Add(pST1, 0, wxALL | wxEXPAND, 8);
312 bool orient = m_displaySize.x < m_displaySize.y;
314 wxBoxSizer* buttonSizer =
new wxBoxSizer(orient ? wxVERTICAL : wxHORIZONTAL);
315 mainSizer->Add(buttonSizer, 0, wxALL, 0);
317 wxButton* donateButton =
new wxBitmapButton(
318 this, ID_DONATE, g_StyleManager->GetCurrentStyle()->GetIcon(
"donate"),
319 wxDefaultPosition, wxDefaultSize, 0);
322 new wxButton(
this, ID_COPYLOG, _(
"Copy Log File to Clipboard")), 1,
323 wxALL | wxEXPAND, 3);
325 new wxButton(
this, ID_COPYINI, _(
"Copy Settings File to Clipboard")), 1,
326 wxALL | wxEXPAND, 3);
330 (buttonSizer->GetOrientation() == wxHORIZONTAL ? wxALIGN_RIGHT : 0),
335 pNotebook =
new wxNotebook(
this, ID_NOTEBOOK_HELP, wxDefaultPosition,
336 wxSize(-1, -1), wxNB_TOP);
338 pNotebook->Connect(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
339 wxNotebookEventHandler(About::OnNBPageChange), NULL,
this);
341 pNotebook->InheritAttributes();
342 mainSizer->Add(pNotebook, 1,
343 (orient ? wxALIGN_CENTER_VERTICAL : 0) | wxEXPAND | wxALL, 5);
346 itemPanelAbout =
new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
347 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
348 itemPanelAbout->InheritAttributes();
349 pNotebook->AddPage(itemPanelAbout, _(
"About"), TRUE );
352 new wxHtmlWindow(itemPanelAbout, wxID_ANY, wxDefaultPosition,
353 wxDefaultSize, wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
354 pAboutHTMLCtl->SetBorders(5);
355 wxBoxSizer* aboutSizer =
new wxBoxSizer(wxVERTICAL);
356 aboutSizer->Add(pAboutHTMLCtl, 1,
357 wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5);
358 itemPanelAbout->SetSizer(aboutSizer);
363 new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
364 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
365 itemPanelAuthors->InheritAttributes();
366 pNotebook->AddPage(itemPanelAuthors, _(
"Authors"));
369 new wxHtmlWindow(itemPanelAuthors, wxID_ANY, wxDefaultPosition,
370 wxDefaultSize, wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
371 pAuthorHTMLCtl->SetBorders(5);
372 wxBoxSizer* authorSizer =
new wxBoxSizer(wxVERTICAL);
373 authorSizer->Add(pAuthorHTMLCtl, 1,
374 wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5);
375 itemPanelAuthors->SetSizer(authorSizer);
379 new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
380 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
381 itemPanelLicense->InheritAttributes();
382 pNotebook->AddPage(itemPanelLicense, _(
"License"));
385 new wxHtmlWindow(itemPanelLicense, wxID_ANY, wxDefaultPosition,
386 wxDefaultSize, wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION);
387 pLicenseHTMLCtl->SetBorders(5);
388 wxBoxSizer* licenseSizer =
new wxBoxSizer(wxVERTICAL);
389 licenseSizer->Add(pLicenseHTMLCtl, 1,
390 wxALIGN_CENTER_HORIZONTAL | wxEXPAND | wxALL, 5);
391 itemPanelLicense->SetSizer(licenseSizer);
394 itemPanelTips =
new wxPanel(pNotebook, -1, wxDefaultPosition, wxDefaultSize,
395 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
396 itemPanelTips->InheritAttributes();
397 pNotebook->AddPage(itemPanelTips, _(
"Help"));
399 wxBoxSizer* helpSizer =
new wxBoxSizer(wxVERTICAL);
400 itemPanelTips->SetSizer(helpSizer);
403 wxButton* closeButton =
new wxButton(
this, xID_OK, _(
"Close"),
404 wxDefaultPosition, wxDefaultSize, 0);
405 closeButton->SetDefault();
406 closeButton->InheritAttributes();
407 mainSizer->Add(closeButton, 0, wxALIGN_RIGHT | wxALL, 5);
410void About::OnNBPageChange(wxNotebookEvent& event) {
411 unsigned int i =
event.GetSelection();
414 m_launch_local_help();
415 pNotebook->ChangeSelection(0);
418 else if ((i == 2) && !m_blicensePageSet) {
420 wxColor bg = GetBackgroundColour();
421 wxColor fg = wxColour(0, 0, 0);
422 wxFont* dFont = FontMgr::Get().
GetFont(_(
"Dialog"));
425 int points = dFont->GetPointSize();
430 for (
int j = -2; j < 5; j++) {
431 sizes[j + 2] = points + j + (j > 0 ? j : 0);
433 wxString face = dFont->GetFaceName();
439 wxString licenseText = wxString::Format(
440 "<html><body bgcolor=#%02x%02x%02x><font color=#%02x%02x%02x>",
441 bg.Red(), bg.Blue(), bg.Green(), fg.Red(), fg.Blue(), fg.Green());
443 pLicenseHTMLCtl->SetFonts(face, face, sizes);
445 wxTextFile license_filea(m_DataLocn +
"license.txt");
446 if (license_filea.Open()) {
447 for (wxString str = license_filea.GetFirstLine(); !license_filea.Eof();
448 str = license_filea.GetNextLine())
449 licenseText.Append(str +
"<br>");
450 license_filea.Close();
452 wxLogMessage(
"Could not open License file: " + m_DataLocn);
457 wxStringTokenizer st(suppLicense,
"\n", wxTOKEN_DEFAULT);
458 while (st.HasMoreTokens()) {
459 wxString s1 = st.GetNextToken();
460 licenseText.Append(s1 +
"<br>");
464 licenseText.Append(
"</font></body></html>");
466 pLicenseHTMLCtl->SetPage(licenseText);
471 m_blicensePageSet =
true;
475void About::OnXidOkClick(wxCommandEvent& event) { Close(); }
477void About::OnClose(wxCloseEvent& event) {
479 wxTheApp->GetTopWindow()->Raise();
485void About::OnDonateClick(wxCommandEvent& event) {
486 wxLaunchDefaultBrowser(
487 "https://sourceforge.net/donate/index.php?group_id=180842");
490void About::OnCopyClick(wxCommandEvent& event) {
491 wxString filename =
event.GetId() == ID_COPYLOG
495 wxFFile file(filename);
497 if (!file.IsOpened()) {
498 wxLogMessage(
"Failed to open file for Copy to Clipboard.");
502 wxString fileContent;
504 while (!file.Eof()) {
505 int c = file.Read(&buf, 1024);
506 if (c) fileContent += wxString(buf, wxConvUTF8, c);
510 int length = fileContent.Length();
512 if (event.GetId() == ID_COPYLOG) {
513 wxString lastLogs = fileContent;
514 int pos = lastLogs.Find(
"________");
515 while (pos != wxNOT_FOUND && lastLogs.Length() > 65000) {
516 lastLogs = lastLogs.Right(lastLogs.Length() - pos - 8);
517 pos = lastLogs.Find(
"________");
519 fileContent = lastLogs;
522 ::wxBeginBusyCursor();
523 if (wxTheClipboard->Open()) {
524 if (!wxTheClipboard->SetData(
new wxTextDataObject(fileContent)))
525 wxLogMessage(
"wxTheClipboard->Open() failed.");
526 wxTheClipboard->Close();
528 wxLogMessage(
"wxTheClipboard->Open() failed.");
AboutFrameImpl * g_pAboutDlg
Global instance.
About * g_pAboutDlgLegacy
Global instance.
About * g_pAboutDlgLegacy
Global instance.
Generic Chart canvas base.
Extends AboutFrame, providing implementation for various event handlers and additional methods.
The OpenCPN About dialog displaying information including version, authors, license,...
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)
Get a font object for a UI element.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.