Audacity 3.2.0
HelpSystem.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 HelpSystem.cpp
6
7 Jimmy Johnson
8 Leland Lucius
9 Richard Ash
10
11 was merged with LinkingHtmlWindow.h
12
13 Vaughan Johnson
14 Dominic Mazzoni
15
16 utility fn and
17 descendant of HtmlWindow that opens links in the user's
18 default browser
19
20*//********************************************************************/
21
22
23#include "HelpSystem.h"
24
25#include <wx/setup.h> // for wxUSE_* macros
26#include <wx/button.h>
27#include <wx/frame.h>
28#include <wx/icon.h>
29#include <wx/dialog.h>
30#include <wx/intl.h>
31#include <wx/log.h>
32#include <wx/sizer.h>
33#include <wx/stattext.h>
34#include <wx/textctrl.h>
35#include <wx/utils.h>
36#include <wx/html/htmlwin.h>
37#include <wx/settings.h>
38#include <wx/statusbr.h>
39#include <wx/regex.h>
40
41#include "FileNames.h"
42#include "AllThemeResources.h"
43#include "../ShuttleGui.h"
44#include "Theme.h"
45#include "../HelpText.h"
46#include "Prefs.h"
47#include "wxFileNameWrapper.h"
48#include "../prefs/GUIPrefs.h"
49
50#ifdef USE_ALPHA_MANUAL
51const wxString HelpSystem::HelpHostname = wxT("alphamanual.audacityteam.org");
52const wxString HelpSystem::HelpServerHomeDir = wxT("/man/");
53const wxString HelpSystem::HelpServerManDir = wxT("/man/");
54#else
55const wxString HelpSystem::HelpHostname = wxT("manual.audacityteam.org");
56const wxString HelpSystem::HelpServerHomeDir = wxT("/");
57const wxString HelpSystem::HelpServerManDir = wxT("/man/");
58#endif
59const wxString HelpSystem::LocalHelpManDir = wxT("/man/");
60
61namespace {
62
63// Helper class to make browser "simulate" a modal dialog
65{
66public:
67 HtmlTextHelpDialog(wxWindow *pParent, const TranslatableString &title)
68 : BrowserDialog{ pParent, title }
69 {
70#if !wxCHECK_VERSION(3, 0, 0)
71 MakeModal( true );
72#endif
73 }
75 {
76#if !wxCHECK_VERSION(3, 0, 0)
77 MakeModal( false );
78#endif
79 // On Windows, for some odd reason, the Audacity window will be sent to
80 // the back. So, make sure that doesn't happen.
81 GetParent()->Raise();
82 }
83};
84
85}
86
90void HelpSystem::ShowInfoDialog( wxWindow *parent,
91 const TranslatableString &dlogTitle,
92 const TranslatableString &shortMsg,
93 const wxString &message,
94 const int xSize, const int ySize)
95{
96 wxDialogWrapper dlog(parent, wxID_ANY,
97 dlogTitle,
98 wxDefaultPosition, wxDefaultSize,
99 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX /*| wxDEFAULT_FRAME_STYLE */);
100
101 dlog.SetName();
102 ShuttleGui S(&dlog, eIsCreating);
103
104 S.StartVerticalLay(1);
105 {
106 S.AddTitle( shortMsg );
107 S.Style( wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH | wxTE_RICH2 |
108 wxTE_AUTO_URL | wxTE_NOHIDESEL | wxHSCROLL )
109 .AddTextWindow(message);
110
111 S.SetBorder( 0 );
112 S.StartHorizontalLay(wxALIGN_CENTER_HORIZONTAL, 0);
113 S.AddStandardButtons(eOkButton);
114 S.EndHorizontalLay();
115 }
116 S.EndVerticalLay();
117
118 // Smallest size is half default size. Seems reasonable.
119 dlog.SetMinSize( wxSize(xSize/2, ySize/2) );
120 dlog.SetSize( wxSize(xSize, ySize) );
121 dlog.Center();
122 dlog.ShowModal();
123}
124
125void HelpSystem::ShowHtmlText(wxWindow *pParent,
126 const TranslatableString &Title,
127 const wxString &HtmlText,
128 bool bIsFile,
129 bool bModal)
130{
131 LinkingHtmlWindow *html;
132
133 wxASSERT(pParent); // to justify safenew
134 // JKC: ANSWER-ME: Why do we create a fake 'frame' and then put a BrowserDialog
135 // inside it, rather than have a variant of the BrowserDialog that is a
136 // frame??
137 // Bug 1412 seems to be related to the extra frame.
138 auto pFrame = safenew wxFrame {
139 pParent, wxID_ANY, Title.Translation(), wxDefaultPosition, wxDefaultSize,
140#if defined(__WXMAC__)
141 // On OSX, the html frame can go behind the help dialog and if the help
142 // html frame is modal, you can't get back to it. Pressing escape gets
143 // you out of this, but it's just easier to add the wxSTAY_ON_TOP flag
144 // to prevent it from falling behind the dialog. Not the perfect solution
145 // but acceptable in this case.
146 wxSTAY_ON_TOP |
147#endif
148 wxDEFAULT_FRAME_STYLE
149 };
150
151 BrowserDialog * pWnd;
152 if( bModal )
153 pWnd = safenew HtmlTextHelpDialog{ pFrame, Title };
154 else
155 pWnd = safenew BrowserDialog{ pFrame, Title };
156
157 // Bug 1412 workaround for 'extra window'. Hide the 'fake' window.
158 pFrame->SetTransparent(0);
159 ShuttleGui S( pWnd, eIsCreating );
160
161 S.Style( wxNO_BORDER | wxTAB_TRAVERSAL )
162 .Prop(true)
163 .StartPanel();
164 {
165 S.StartHorizontalLay( wxEXPAND, false );
166 {
167 S.Id( wxID_BACKWARD )
168 .Disable()
169#if wxUSE_TOOLTIPS
170 .ToolTip( XO("Backwards" ) )
171#endif
172 /* i18n-hint arrowhead meaning backward movement */
173 .AddButton( XXO("<") );
174 S.Id( wxID_FORWARD )
175 .Disable()
176#if wxUSE_TOOLTIPS
177 .ToolTip( XO("Forwards" ) )
178#endif
179 /* i18n-hint arrowhead meaning forward movement */
180 .AddButton( XXO(">") );
181 }
182 S.EndHorizontalLay();
183
184 html = safenew LinkingHtmlWindow(S.GetParent(), wxID_ANY,
185 wxDefaultPosition,
186 bIsFile ? wxSize(500, 400) : wxSize(480, 240),
187 wxHW_SCROLLBAR_AUTO | wxSUNKEN_BORDER);
188
189 html->SetRelatedFrame( pFrame, wxT("Help: %s") );
190 if( bIsFile )
191 html->LoadFile( HtmlText );
192 else
193 html->SetPage( HtmlText);
194
195 S.Prop(1).Focus().Position( wxEXPAND )
196 .AddWindow( html );
197
198 S.Id( wxID_CANCEL ).AddButton( XXO("Close"), wxALIGN_CENTER, true );
199 }
200 S.EndPanel();
201
202 // -- START of ICON stuff -----
203 // If this section (providing an icon) causes compilation errors on linux, comment it out for now.
204 // it will just mean that the icon is missing. Works OK on Windows.
205 #ifdef __WXMSW__
206 wxIcon ic{ wxICON(AudacityLogo) };
207 #else
208 wxIcon ic{};
209 ic.CopyFromBitmap(theTheme.Bitmap(bmpAudacityLogo48x48));
210 #endif
211 pFrame->SetIcon( ic );
212 // -- END of ICON stuff -----
213
214
215 pWnd->mpHtml = html;
216 pWnd->SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
217
218 pFrame->CreateStatusBar();
219 pFrame->Centre();
220 pFrame->Layout();
221 pFrame->SetSizeHints(pWnd->GetSize());
222
223 pFrame->SetName(Title.Translation());
224 if (bModal)
225 pWnd->ShowModal();
226 else {
227 pWnd->Show(true);
228 pFrame->Show(true);
229 }
230
231 html->SetRelatedStatusBar( 0 );
232
233 return;
234}
235
236// Shows help in browser, or possibly in own dialog.
237void HelpSystem::ShowHelp(wxWindow *parent,
238 const FilePath &localFileName,
239 const URLString &remoteURL,
240 bool bModal,
241 bool alwaysDefaultBrowser)
242{
243 wxASSERT(parent); // to justify safenew
244 wxString HelpMode = wxT("Local");
245
246// DA: Default for DA is manual from internet.
247#ifdef EXPERIMENTAL_DA
248 gPrefs->Read(wxT("/GUI/Help"), &HelpMode, wxT("FromInternet") );
249#else
250 gPrefs->Read(wxT("/GUI/Help"), &HelpMode, wxT("Local") );
251#endif
252
253 {
254 // these next lines are for legacy cfg files (pre 2.0) where we had different modes
255 if( (HelpMode == wxT("Standard")) || (HelpMode == wxT("InBrowser")) )
256 {
257 HelpMode = GUIManualLocation.Default().Internal();
258 GUIManualLocation.Write(HelpMode);
259 gPrefs->Flush();
260 }
261 }
262
263 // Anchors (URLs with a '#' in them) are not supported by many OSs for local file names
264 // See, for example, https://groups.google.com/forum/#!topic/wx-users/pC0uOZJalRQ
265 // Problems have been reported on Win, Mac and some versions of Linux.
266 // So we set HelpMode to use the internet if an anchor is found.
267 if (localFileName.Find('#', true) != wxNOT_FOUND)
268 HelpMode = wxT("FromInternet");
269 // Until a solution is found for this, the next few lines are irrelevant.
270
271 // Obtain the local file system file name, without the anchor if present.
272 wxString localfile;
273 if (localFileName.Find('#', true) != wxNOT_FOUND)
274 localfile = localFileName.BeforeLast('#');
275 else
276 localfile = localFileName;
277
278 if( (HelpMode == wxT("FromInternet")) && !remoteURL.empty() )
279 {
280 // Always go to remote URL. Use External browser.
281 OpenInDefaultBrowser( remoteURL );
282 }
283 else if( localfile.empty() || !wxFileExists( localfile ))
284 {
285 // If you give an empty remote URL, you should have already ensured
286 // that the file exists!
287 wxASSERT( !remoteURL.empty() );
288 // I can't find it'.
289 // Use Built-in browser to suggest you use the remote url.
290 wxString Text = HelpText( wxT("remotehelp") );
291 Text.Replace( wxT("*URL*"), remoteURL.GET() );
292 // Always make the 'help on the internet' dialog modal.
293 // Fixes Bug 1411.
294 ShowHtmlText( parent, XO("Help on the Internet"), Text, false, true );
295 }
296 else if( HelpMode == wxT("Local") || alwaysDefaultBrowser)
297 {
298 // Local file, External browser
299 OpenInDefaultBrowser( L"file:" + localFileName );
300 }
301 else
302 {
303 // Local file, Built-in browser
304 ShowHtmlText( parent, {}, localFileName, true, bModal );
305 }
306}
307
308void HelpSystem::ShowHelp(wxWindow *parent,
309 const ManualPageID &PageName,
310 bool bModal)
311{
314 const wxString ReleaseSuffix = L".html";
315
316 FilePath localHelpPage;
317 wxString webHelpPath;
318 wxString webHelpPage;
319 wxString releasePageName;
320 wxString anchor; // optional part of URL after (and including) the '#'
321 const auto &PageNameStr = PageName.GET();
322 if (PageNameStr.Find('#', true) != wxNOT_FOUND)
323 { // need to split anchor off into separate variable
324 releasePageName = PageNameStr.BeforeLast('#');
325 anchor = wxT("#") + PageNameStr.AfterLast('#');
326 }
327 else
328 {
329 releasePageName = PageName.GET();
330 anchor = wxT("");
331 }
332 // The wiki pages are transformed to static HTML by
333 // scripts/mw2html_audacity/mw2html.py
334 // The name is first transformed to lower case, then all
335 // 'special characters' are replaced by underscores. Spaces are
336 // transformed to "+".
337 //
338 // The transformations are handled in mw2html by first applying
339 // 'urllib.parse.quote_plus' (escape chars that are not in "always safe" list)
340 // then replacing escape characters (%xx) with underscores,
341 // and finally removing duplicate / redundant underscores.
342 //
343 // The front page and 'quick_help' are treated as special cases and placed in
344 // the root of the help directory rather than the "/man/" sub-directory.
345 if (releasePageName == L"Main_Page")
346 {
347 releasePageName = L"index" + ReleaseSuffix + anchor;
348 localHelpPage = wxFileName(FileNames::HtmlHelpDir(), releasePageName).GetFullPath();
349 webHelpPath = L"https://" + HelpSystem::HelpHostname + HelpSystem::HelpServerHomeDir;
350 }
351 else if (releasePageName == L"Quick_Help")
352 {
353// DA: No bundled help, by default, and different quick-help URL.
354#ifdef EXPERIMENTAL_DA
355 releasePageName = L"video" + ReleaseSuffix + anchor;
356 localHelpPage = wxFileName(FileNames::HtmlHelpDir(), releasePageName).GetFullPath();
357 webHelpPath = L"http://www.darkaudacity.com/";
358#else
359 releasePageName = L"quick_help" + ReleaseSuffix + anchor;
360 localHelpPage = wxFileName(FileNames::HtmlHelpDir(), releasePageName).GetFullPath();
361 webHelpPath = L"https://" + HelpSystem::HelpHostname + HelpSystem::HelpServerHomeDir;
362#endif
363 }
364 // not a page name, but rather a full path (e.g. to wiki)
365 // in which case do not do any substitutions.
366 else if (releasePageName.StartsWith( "http" ) )
367 {
368 localHelpPage = "";
369 releasePageName += anchor;
370 // webHelpPath remains empty
371 }
372 else
373 {
374 // Handle all other pages.
375 // Change to lower case.
376 releasePageName = releasePageName.Lower();
377 wxRegEx re;
378 // replace 'special characters' with underscores.
379 // RFC 2396 defines the characters a-z, A-Z, 0-9 and ".-_" as "always safe"
380 // mw2html also replaces "-" with "_" so replace that too.
381
382 // If PageName contains a %xx code, mw2html will transform it:
383 // '%xx' => '%25xx' => '_'
384 re.Compile(wxT("%.."));
385 re.ReplaceAll(&releasePageName, (wxT("_")));
386 // Now replace all other 'not-safe' characters.
387 re.Compile(wxT("[^[:alnum:] . [:space:]]"));
388 re.ReplaceAll(&releasePageName, (wxT("_")));
389 // Replace spaces with "+"
390 releasePageName.Replace(wxT(" "), wxT("+"), true);
391 // Reduce multiple underscores to single underscores
392 re.Compile(wxT("__+"));
393 re.ReplaceAll(&releasePageName, (wxT("_")));
394 // Replace "_." with "."
395 releasePageName.Replace(wxT("_."), wxT("."), true);
396 // Concatenate file name with file extension and anchor.
397 releasePageName = releasePageName + ReleaseSuffix + anchor;
398 // Other than index and quick_help, all local pages are in subdirectory 'LocalHelpManDir'.
399 localHelpPage = wxFileName(FileNames::HtmlHelpDir() + LocalHelpManDir, releasePageName).GetFullPath();
400 // Other than index and quick_help, all on-line pages are in subdirectory 'HelpServerManDir'.
401 webHelpPath = L"https://" + HelpSystem::HelpHostname + HelpSystem::HelpServerManDir;
402 }
403
404#ifdef USE_ALPHA_MANUAL
405 webHelpPage = webHelpPath + PageName.GET();
406#else
407 webHelpPage = webHelpPath + releasePageName;
408#endif
409
410 wxLogMessage(wxT("Help button pressed: PageName %s, releasePageName %s"),
411 PageName.GET(), releasePageName);
412 wxLogMessage(wxT("webHelpPage %s, localHelpPage %s"),
413 webHelpPage, localHelpPage);
414
415 wxASSERT(parent); // to justify safenew
416
418 parent,
419 localHelpPage,
420 webHelpPage,
421 bModal
422 );
423}
424
425// For compilers that support precompilation, includes "wx/wx.h".
426#include <wx/wxprec.h>
427
428#include <wx/mimetype.h>
429#include <wx/filename.h>
430#include <wx/uri.h>
431
432BEGIN_EVENT_TABLE(BrowserDialog, wxDialogWrapper)
436 EVT_KEY_DOWN(BrowserDialog::OnKeyDown)
438
439
441 : wxDialogWrapper{ pParent, ID, title, wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER /*| wxMAXIMIZE_BOX */ }
442{
443 int width, height;
444 const int minWidth = 400;
445 const int minHeight = 250;
446
447 gPrefs->Read(wxT("/GUI/BrowserWidth"), &width, minWidth);
448 gPrefs->Read(wxT("/GUI/BrowserHeight"), &height, minHeight);
449
450 if (width < minWidth || width > wxSystemSettings::GetMetric(wxSYS_SCREEN_X))
451 width = minWidth;
452 if (height < minHeight || height > wxSystemSettings::GetMetric(wxSYS_SCREEN_Y))
453 height = minHeight;
454
455 SetMinSize(wxSize(minWidth, minHeight));
456 SetSize(wxDefaultPosition.x, wxDefaultPosition.y, width, height, wxSIZE_AUTO);
457}
458
459void BrowserDialog::OnForward(wxCommandEvent & WXUNUSED(event))
460{
461 mpHtml->HistoryForward();
463}
464
465void BrowserDialog::OnBackward(wxCommandEvent & WXUNUSED(event))
466{
467 mpHtml->HistoryBack();
469}
470
471void BrowserDialog::OnClose(wxCommandEvent & WXUNUSED(event))
472{
473 if (IsModal() && !mDismissed)
474 {
475 mDismissed = true;
476 EndModal(wxID_CANCEL);
477 }
478 auto parent = GetParent();
479
480 gPrefs->Write(wxT("/GUI/BrowserWidth"), GetSize().GetX());
481 gPrefs->Write(wxT("/GUI/BrowserHeight"), GetSize().GetY());
482 gPrefs->Flush();
483
484#ifdef __WXMAC__
485 auto grandparent = GetParent()->GetParent();
486#endif
487
488 parent->Destroy();
489
490#ifdef __WXMAC__
491 if(grandparent && grandparent->IsShown()) {
492 grandparent->Raise();
493 }
494#endif
495}
496
497void BrowserDialog::OnKeyDown(wxKeyEvent & event)
498{
499 bool bSkip = true;
500 if (event.GetKeyCode() == WXK_ESCAPE)
501 {
502 bSkip = false;
503 Close(false);
504 }
505 event.Skip(bSkip);
506}
507
508
510{
511 wxWindow * pWnd;
512 if( (pWnd = FindWindowById( wxID_BACKWARD, this )) != NULL )
513 {
514 pWnd->Enable(mpHtml->HistoryCanBack());
515 }
516 if( (pWnd = FindWindowById( wxID_FORWARD, this )) != NULL )
517 {
518 pWnd->Enable(mpHtml->HistoryCanForward());
519 }
520}
521
523{
524 wxURI uri(link.GET());
525 wxLaunchDefaultBrowser(uri.BuildURI());
526}
527
528LinkingHtmlWindow::LinkingHtmlWindow(wxWindow *parent, wxWindowID id /*= -1*/,
529 const wxPoint& pos /*= wxDefaultPosition*/,
530 const wxSize& size /*= wxDefaultSize*/,
531 long style /*= wxHW_SCROLLBAR_AUTO*/) :
532 HtmlWindow(parent, id, pos, size, style)
533{
534}
535
536void LinkingHtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& link)
537{
538 wxString href = link.GetHref();
539
540 if( href.StartsWith( wxT("innerlink:help:")))
541 {
542 HelpSystem::ShowHelp(this, ManualPageID{ href.Mid( 15 ) }, true );
543 return;
544 }
545 else if( href.StartsWith(wxT("innerlink:")) )
546 {
547 wxString FileName =
548 wxFileName( FileNames::HtmlHelpDir(), href.Mid( 10 ) + wxT(".htm") ).GetFullPath();
549 if( wxFileExists( FileName ) )
550 {
551 HelpSystem::ShowHelp(this, FileName, wxEmptyString, false);
552 return;
553 }
554 else
555 {
556 SetPage( HelpText( href.Mid( 10 )));
557 wxGetTopLevelParent(this)->SetLabel( TitleText( href.Mid( 10 )).Translation() );
558 }
559 }
560 else if( href.StartsWith(wxT("mailto:")) || href.StartsWith(wxT("file:")) )
561 {
562 OpenInDefaultBrowser( link.GetHref() );
563 return;
564 }
565 else if( !href.StartsWith( wxT("http:")) && !href.StartsWith( wxT("https:")) )
566 {
567 HtmlWindow::OnLinkClicked( link );
568 }
569 else
570 {
571 OpenInDefaultBrowser(link.GetHref());
572 return;
573 }
574 wxFrame * pFrame = GetRelatedFrame();
575 if( !pFrame )
576 return;
577 wxWindow * pWnd = pFrame->FindWindow(BrowserDialog::ID);
578 if( !pWnd )
579 return;
580 BrowserDialog * pDlg = wxDynamicCast( pWnd , BrowserDialog );
581 if( !pDlg )
582 return;
583 pDlg->UpdateButtons();
584}
END_EVENT_TABLE()
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
ChoiceSetting GUIManualLocation
Definition: GUIPrefs.cpp:130
void OpenInDefaultBrowser(const URLString &link)
Definition: HelpSystem.cpp:522
TranslatableString TitleText(const wxString &Key)
Definition: HelpText.cpp:151
wxString HelpText(const wxString &Key)
Definition: HelpText.cpp:360
#define XXO(s)
Definition: Internat.h:44
#define XO(s)
Definition: Internat.h:31
#define safenew
Definition: MemoryX.h:10
static const auto title
FileConfig * gPrefs
Definition: Prefs.cpp:71
wxString FilePath
Definition: Project.h:20
@ eIsCreating
Definition: ShuttleGui.h:39
@ eOkButton
Definition: ShuttleGui.h:597
THEME_API Theme theTheme
Definition: Theme.cpp:82
#define S(N)
Definition: ToChars.cpp:64
int id
Adds some event handling to an HtmlWindow.
Definition: HelpSystem.h:140
void UpdateButtons()
Definition: HelpSystem.cpp:509
void OnClose(wxCommandEvent &event)
Definition: HelpSystem.cpp:471
void OnKeyDown(wxKeyEvent &event)
Definition: HelpSystem.cpp:497
void OnBackward(wxCommandEvent &event)
Definition: HelpSystem.cpp:465
HtmlWindow * mpHtml
Definition: HelpSystem.h:154
void OnForward(wxCommandEvent &event)
Definition: HelpSystem.cpp:459
bool Write(const wxString &value)
Definition: Prefs.cpp:390
const EnumValueSymbol & Default() const
Definition: Prefs.cpp:346
const wxString & Internal() const
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:237
static const wxString LocalHelpManDir
Definition: HelpSystem.h:111
static void ShowInfoDialog(wxWindow *parent, const TranslatableString &dlogTitle, const TranslatableString &shortMsg, const wxString &message, const int xSize, const int ySize)
Displays cuttable information in a text ctrl, with an OK button.
Definition: HelpSystem.cpp:90
static const wxString HelpHostname
Definition: HelpSystem.h:96
static const wxString HelpServerHomeDir
Definition: HelpSystem.h:101
static const wxString HelpServerManDir
Definition: HelpSystem.h:106
static void ShowHtmlText(wxWindow *pParent, const TranslatableString &Title, const wxString &HtmlText, bool bIsFile=false, bool bModal=false)
Definition: HelpSystem.cpp:125
HtmlWindow Class.
Definition: HtmlWindow.h:37
bool empty() const
Definition: Identifier.h:61
const wxString & GET() const
Explicit conversion to wxString, meant to be ugly-looking and demanding of a comment why it's correct...
Definition: Identifier.h:66
An HtmlWindow that handles linked clicked - usually the link will go to our own local copy of the man...
Definition: HelpSystem.h:126
LinkingHtmlWindow(wxWindow *parent, wxWindowID id=-1, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxHW_SCROLLBAR_AUTO)
Definition: HelpSystem.cpp:528
void OnLinkClicked(const wxHtmlLinkInfo &link) override
Definition: HelpSystem.cpp:536
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:628
Template generates different TaggedIdentifier classes that don't interconvert implicitly.
Definition: Identifier.h:113
wxBitmap & Bitmap(int iIndex)
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
HtmlTextHelpDialog(wxWindow *pParent, const TranslatableString &title)
Definition: HelpSystem.cpp:67
void SetName(const TranslatableString &title)
FILES_API FilePath HtmlHelpDir()