Audacity 3.2.0
HelpMenus.cpp
Go to the documentation of this file.
1
2#include <wx/app.h>
3#include <wx/bmpbuttn.h>
4#include <wx/textctrl.h>
5#include <wx/frame.h>
6
7#include "../AboutDialog.h"
8#include "AllThemeResources.h"
9#include "AudioIO.h"
10#include "../CommonCommandFlags.h"
11#include "../CrashReport.h" // for HAS_CRASH_REPORT
12#include "FileNames.h"
13#include "HelpText.h"
14#include "../HelpUtilities.h"
15#include "LogWindow.h"
16#include "../Menus.h"
17#include "Prefs.h"
18#include "Project.h"
19#include "../ProjectSelectionManager.h"
20#include "../ProjectWindows.h"
21#include "SelectFile.h"
22#include "ShuttleGui.h"
23#include "../SplashDialog.h"
24#include "SyncLock.h"
25#include "Theme.h"
26#include "../commands/CommandContext.h"
27#include "../commands/CommandManager.h"
28#include "../prefs/PrefsDialog.h"
29#include "AudacityMessageBox.h"
30#include "HelpSystem.h"
31
33
34#if defined(HAVE_UPDATES_CHECK)
36#endif
37
38// private helper classes and functions
39namespace
40{
41
50{
51public:
52 using PrefSetter = std::function< void() > ;
53
54 QuickFixDialog(wxWindow * pParent, AudacityProject &project);
55 void Populate();
56 void PopulateOrExchange(ShuttleGui & S);
57 void AddStuck( ShuttleGui & S, bool & bBool,
58 const PrefSetter &prefSetter,
59 const TranslatableString &Prompt, const ManualPageID &Help );
60
61 void OnOk(wxCommandEvent &event);
62 void OnCancel(wxCommandEvent &event);
63 void OnHelp(const ManualPageID &Str);
64 void OnFix(const PrefSetter &setter, wxWindowID id);
65
67
68 int mItem;
72 DECLARE_EVENT_TABLE()
73};
74
75
76#define FixButtonID 7001
77#define HelpButtonID 7011
78
79BEGIN_EVENT_TABLE(QuickFixDialog, wxDialogWrapper)
80 EVT_BUTTON(wxID_OK, QuickFixDialog::OnOk)
81 EVT_BUTTON(wxID_CANCEL, QuickFixDialog::OnCancel)
83
84QuickFixDialog::QuickFixDialog(wxWindow * pParent, AudacityProject &project) :
85 wxDialogWrapper(pParent, wxID_ANY, XO("Do you have these problems?"),
86 wxDefaultPosition, wxDefaultSize,
87 wxDEFAULT_DIALOG_STYLE )
88 , mProject{ project }
89{
90 const long SNAP_OFF = 0;
91
92 mbSyncLocked = SyncLockTracks.Read();
93 mbInSnapTo = gPrefs->Read(wxT("/SnapTo"), SNAP_OFF) !=0;
94 mbSoundActivated = SoundActivatedRecord.Read();
95
97 PopulateOrExchange(S);
98
99 Fit();
100 auto sz = GetSize();
101 SetMinSize( sz );
102 SetMaxSize( sz );
103
104 // The close button has the cancel id and acts exactly the same as cancel.
105 wxButton * pWin = (wxButton*)FindWindowById( wxID_CANCEL );
106 if( pWin )
107 pWin->SetFocus( );
108 Center();
109}
110
111void QuickFixDialog::AddStuck( ShuttleGui & S, bool & bBool,
112 const PrefSetter &prefSetter,
113 const TranslatableString &Prompt, const ManualPageID &Help )
114{
115 mItem++;
116 wxWindowID id = FixButtonID + mItem;
117 if( !bBool)
118 return;
119
120 S
121 .AddFixedText( Prompt );
122
123 S
124 .Id( id )
125 .AddButton( XXO("Fix") )
126 ->Bind( wxEVT_BUTTON, [this, prefSetter, id](wxCommandEvent&){
127 OnFix( prefSetter, id );
128 } );
129
130 {
131 // Replace standard Help button with smaller icon button.
132 // bs->AddButton(safenew wxButton(parent, wxID_HELP));
133 auto b = safenew wxBitmapButton(S.GetParent(), HelpButtonID+mItem, theTheme.Bitmap( bmpHelpIcon ));
134 b->SetToolTip( _("Help") );
135 b->SetLabel(_("Help")); // for screen readers
136 b->Bind( wxEVT_BUTTON, [this, Help](const wxCommandEvent&){
137 OnHelp( Help );
138 } );
139 S.AddWindow( b );
140 }
141}
142
143void QuickFixDialog::PopulateOrExchange(ShuttleGui & S)
144{
145
146 S.StartVerticalLay(1);
147 S.StartStatic( XO("Quick Fixes"));
148
149 // These aren't all possible modes one can be stuck in, but they are some of them.
150 bool bStuckInMode = mbSyncLocked || mbInSnapTo || mbSoundActivated;
151
152 if( !bStuckInMode ){
153 SetLabel(XO("Nothing to do"));
154 S.AddFixedText(XO("No quick, easily fixed problems were found"));
155 }
156 else {
157 S.StartMultiColumn(3, wxALIGN_CENTER);
158 {
159 mItem = -1;
160
161 auto defaultAction =
162 [](AudacityProject *pProject, BoolSetting &setting){ return
163 [pProject, &setting]{
164 setting.Reset();
165 gPrefs->Flush();
166 // This is overkill (aka slow), as all preferences are
167 // reloaded and all
168 // toolbars recreated.
169 // Overkill probably doesn't matter, as this command is
170 // infrequently used.
171 DoReloadPreferences( *pProject );
172 };
173 };
174
175 // Use # in the URLs to ensure we go to the online version of help.
176 // Local help may well not be installed.
177 auto pProject = &mProject;
178 AddStuck( S, mbSyncLocked,
179 defaultAction( pProject, SyncLockTracks ),
180 XO("Clocks on the Tracks"), "Quick_Fix#sync_lock" );
181 AddStuck( S, mbInSnapTo,
182 [pProject] {
183 gPrefs->Write( "/SnapTo", 0 );
184 gPrefs->Flush();
185 // Sadly SnapTo has to be handled specially,
186 // as it is not part of the standard
187 // preference dialogs.
189 },
190 XO("Can't select precisely"), "Quick_Fix#snap_to" );
191 AddStuck( S, mbSoundActivated,
192 defaultAction( pProject, SoundActivatedRecord ),
193 XO("Recording stops and starts"),
194 "Quick_Fix#sound_activated_recording" );
195 }
196 S.EndMultiColumn();
197 }
198 S.EndStatic();
199
200 S.StartHorizontalLay(wxALIGN_CENTER_HORIZONTAL, 0);
201 S.AddStandardButtons(eCloseButton + (bStuckInMode ? 0 : eHelpButton));
202 S.EndHorizontalLay();
203
204 S.EndVerticalLay();
205
206 wxButton * pBtn = (wxButton*)FindWindowById( wxID_HELP );
207 if( pBtn )
208 pBtn->Bind( wxEVT_BUTTON, [this]( const wxCommandEvent & ){
209 OnHelp( "Quick_Fix#" );
210 } );
211}
212
213void QuickFixDialog::OnOk(wxCommandEvent &event)
214{
215 (void)event;// Compiler food
216 EndModal(wxID_OK);
217}
218
219void QuickFixDialog::OnCancel(wxCommandEvent &event)
220{
221 (void)event;// Compiler food
222 EndModal(wxID_CANCEL);
223}
224
225void QuickFixDialog::OnHelp(const ManualPageID &Str)
226{
227 HelpSystem::ShowHelp(this, Str, true);
228}
229
230void QuickFixDialog::OnFix(const PrefSetter &setter, wxWindowID id)
231{
232 if ( setter )
233 setter();
234
235 // Change the label after doing the fix, as the fix may take a second or two.
236 auto pBtn = FindWindow(id);
237 if( pBtn )
238 pBtn->SetLabel( _("Fixed") );
239
240 // The close button has the cancel id and acts exactly the same as cancel.
241 wxButton * pWin = (wxButton*)FindWindowById( wxID_CANCEL );
242 if( pWin )
243 pWin->SetFocus( );
244}
245
246}
247
248namespace {
249
250// Menu handler functions
251
252void OnQuickFix(const CommandContext &context)
253{
254 auto &project = context.project;
255 QuickFixDialog dlg( &GetProjectFrame( project ), project );
256 dlg.ShowModal();
257}
258
259void OnQuickHelp(const CommandContext &context)
260{
261 auto &project = context.project;
263 &GetProjectFrame( project ),
264 L"Quick_Help");
265}
266
267void OnManual(const CommandContext &context)
268{
269 auto &project = context.project;
271 &GetProjectFrame( project ),
272 L"Main_Page");
273}
274
276{
277 auto &project = context.project;
278 auto gAudioIO = AudioIOBase::Get();
279 wxString info = gAudioIO->GetDeviceInfo();
280 ShowDiagnostics( project, info,
281 XO("Audio Device Info"), wxT("deviceinfo.txt") );
282}
283
284void OnShowLog( const CommandContext &context )
285{
287}
288
289#if defined(HAS_CRASH_REPORT)
290void OnCrashReport(const CommandContext &WXUNUSED(context) )
291{
292// Change to "1" to test a real crash
293#if 0
294 char *p = 0;
295 *p = 1234;
296#endif
297 CrashReport::Generate(wxDebugReport::Context_Current);
298}
299#endif
300
301#ifdef IS_ALPHA
302void OnSegfault(const CommandContext &)
303{
304 unsigned *p = nullptr;
305 *p = 0xDEADBEEF;
306}
307
308void OnException(const CommandContext &)
309{
310 // Throw an exception that can be caught only as (...)
311 // The intent is to exercise detection of unhandled exceptions by the
312 // crash reporter
313 struct Unique{};
314 throw Unique{};
315}
316
317void OnAssertion(const CommandContext &)
318{
319 // We don't use assert() much directly, but Breakpad does detect it
320 // This may crash the program only in debug builds
321 // See also wxSetAssertHandler, and wxApp::OnAssertFailure()
322 assert(false);
323}
324#endif
325
326void OnMenuTree(const CommandContext &context)
327{
328 auto &project = context.project;
329
330 using namespace MenuTable;
331 struct MyVisitor : ToolbarMenuVisitor
332 {
334
335 enum : unsigned { TAB = 3 };
336 void DoBeginGroup( GroupItem &item, const Path& ) override
337 {
338 if ( dynamic_cast<MenuItem*>( &item ) ) {
339 Indent();
340 // using GET for alpha only diagnostic tool
341 info += item.name.GET();
342 Return();
343 indentation = wxString{ ' ', TAB * ++level };
344 }
345 }
346
347 void DoEndGroup( GroupItem &item, const Path& ) override
348 {
349 if ( dynamic_cast<MenuItem*>( &item ) )
350 indentation = wxString{ ' ', TAB * --level };
351 }
352
353 void DoVisit( SingleItem &item, const Path& ) override
354 {
355 // using GET for alpha only diagnostic tool
356 Indent();
357 info += item.name.GET();
358 Return();
359 }
360
361 void DoSeparator() override
362 {
363 static const wxString separatorName{ '=', 20 };
364 Indent();
365 info += separatorName;
366 Return();
367 }
368
369 void Indent() { info += indentation; }
370 void Return() { info += '\n'; }
371
372 unsigned level{};
373 wxString indentation;
374 wxString info;
375 } visitor{ project };
376
377 MenuManager::Visit( visitor );
378
379 ShowDiagnostics( project, visitor.info,
380 Verbatim("Menu Tree"), wxT("menutree.txt"), true );
381}
382
384{
386}
387
388#if defined(HAVE_UPDATES_CHECK)
389void OnCheckForUpdates(const CommandContext &WXUNUSED(context))
390{
392}
393#endif
394
395void OnAbout(const CommandContext &context)
396{
397#ifdef __WXMAC__
398 // Modeless dialog, consistent with other Mac applications
399 // Simulate the application Exit menu item
400 wxCommandEvent evt{ wxEVT_MENU, wxID_ABOUT };
401 wxTheApp->AddPendingEvent( evt );
402#else
403 auto &project = context.project;
404 auto &window = GetProjectFrame( project );
405
406 // Windows and Linux still modal.
407 AboutDialog dlog( &window );
408 dlog.ShowModal();
409#endif
410}
411
412#if 0
413// Legacy handlers, not used as of version 2.3.0
414
415// Only does the update checks if it's an ALPHA build and not disabled by
416// preferences.
417void MayCheckForUpdates(AudacityProject &project)
418{
419#ifdef IS_ALPHA
420 OnCheckForUpdates(project);
421#endif
422}
423
424void OnHelpWelcome(const CommandContext &context)
425{
427}
428
429#endif
430
431// Menu definitions
432
433using namespace MenuTable;
435{
436 static BaseItemSharedPtr menu{
437 Menu( wxT("Help"), XXO("&Help"),
438 Section( "Basic",
439 // QuickFix menu item not in Audacity 2.3.1 whilst we discuss further.
440 #ifdef EXPERIMENTAL_DA
441 // DA: Has QuickFix menu item.
442 Command( wxT("QuickFix"), XXO("&Quick Fix..."), OnQuickFix,
444 // DA: 'Getting Started' rather than 'Quick Help'.
445 Command( wxT("QuickHelp"), XXO("&Getting Started"), OnQuickHelp,
447 // DA: Emphasise it is the Audacity Manual (No separate DA manual).
448 Command( wxT("Manual"), XXO("Audacity &Manual"), OnManual,
450
451 #else
452 Command( wxT("QuickHelp"), XXO("&Quick Help..."), OnQuickHelp,
454 Command( wxT("Manual"), XXO("&Manual..."), OnManual,
456 #endif
457 ),
458
459 #ifdef __WXMAC__
460 Items
461 #else
462 Section
463 #endif
464 ( "Other",
465 Menu( wxT("Diagnostics"), XXO("&Diagnostics"),
466 Command( wxT("DeviceInfo"), XXO("Au&dio Device Info..."),
469 Command( wxT("Log"), XXO("Show &Log..."), OnShowLog,
471 #if defined(HAS_CRASH_REPORT)
472 Command( wxT("CrashReport"), XXO("&Generate Support Data..."),
473 OnCrashReport, AlwaysEnabledFlag )
474 #endif
475
476 #ifdef IS_ALPHA
477 ,
478 // alpha-only items don't need to internationalize, so use
479 // Verbatim for labels
480
481 Command( wxT("RaiseSegfault"), Verbatim("Test segfault report"),
482 OnSegfault, AlwaysEnabledFlag ),
483
484 Command( wxT("ThrowException"), Verbatim("Test exception report"),
485 OnException, AlwaysEnabledFlag ),
486
487 Command( wxT("ViolateAssertion"), Verbatim("Test assertion report"),
488 OnAssertion, AlwaysEnabledFlag ),
489
490 // Menu explorer. Perhaps this should become a macro command
491 Command( wxT("MenuTree"), Verbatim("Menu Tree..."),
494
495 Command(
496 wxT("FrameStatistics"), Verbatim("Frame Statistics..."),
499 #endif
500 )
501 ),
502
503 Section( "Extra",
504 // DA: Does not fully support update checking.
505 #if !defined(EXPERIMENTAL_DA) && defined(HAVE_UPDATES_CHECK)
506 Command( wxT("Updates"), XXO("&Check for Updates..."),
507 OnCheckForUpdates,
509 #endif
510 Command( wxT("About"), XXO("&About Audacity"), OnAbout,
512 )
513 ) };
514 return menu;
515}
516
518 wxT(""),
519 Shared( HelpMenu() )
520};
521
522}
wxT("CloseDown"))
BoolSetting SoundActivatedRecord
Definition: AudioIO.cpp:3333
AttachedItem sAttachment1
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:34
const ReservedCommandFlag & AudioIONotBusyFlag()
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define HelpButtonID
Definition: HelpMenus.cpp:77
#define FixButtonID
Definition: HelpMenus.cpp:76
void ShowDiagnostics(AudacityProject &project, const wxString &info, const TranslatableString &description, const wxString &defaultPath, bool fixedWidth)
#define _(s)
Definition: Internat.h:73
#define safenew
Definition: MemoryX.h:10
FileConfig * gPrefs
Definition: Prefs.cpp:70
void DoReloadPreferences(AudacityProject &project)
@ SNAP_OFF
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
@ eIsCreating
Definition: ShuttleGui.h:37
@ eCloseButton
Definition: ShuttleGui.h:604
@ eHelpButton
Definition: ShuttleGui.h:598
BoolSetting SyncLockTracks
Definition: SyncLock.cpp:172
THEME_API Theme theTheme
Definition: Theme.cpp:82
#define S(N)
Definition: ToChars.cpp:64
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
Declare a class that handles managing of updates.
The AboutDialog shows the program version and developer credits.
Definition: AboutDialog.h:32
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static AudioIOBase * Get()
Definition: AudioIOBase.cpp:91
This specialization of Setting for bool adds a Toggle method to negate the saved value.
Definition: Prefs.h:339
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:143
static void Show(bool show)
Shows the dialog.
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:233
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
static void Show(bool show=true)
Show or hide the unique logging window; create it on demand the first time it is shown.
Definition: LogWindow.cpp:61
static void Visit(ToolbarMenuVisitor &visitor)
Definition: Menus.cpp:441
void AS_SetSnapTo(int snap) override
static ProjectSelectionManager & Get(AudacityProject &project)
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:200
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:625
static void DoHelpWelcome(AudacityProject &project)
wxBitmap & Bitmap(int iIndex)
Holds a msgid for the translation catalog; may also bind format arguments.
void GetUpdates(bool ignoreNetworkErrors, bool configurableNotification)
static UpdateManager & GetInstance()
Class which makes a dialog for displaying quick fixes to common issues.
Definition: HelpMenus.cpp:50
std::unique_ptr< MenuItem > Menu(const Identifier &internalName, const TranslatableString &title, Args &&... args)
std::unique_ptr< MenuPart > Section(const Identifier &internalName, Args &&... args)
std::unique_ptr< MenuItems > Items(const Identifier &internalName, Args &&... args)
std::unique_ptr< CommandItem > Command(const CommandID &name, const TranslatableString &label_in, void(Handler::*pmf)(const CommandContext &), CommandFlag flags, const CommandManager::Options &options={}, CommandHandlerFinder finder=FinderScope::DefaultFinder())
std::shared_ptr< BaseItem > BaseItemSharedPtr
Definition: Registry.h:72
void OnMenuTree(const CommandContext &context)
Definition: HelpMenus.cpp:326
void OnAudioDeviceInfo(const CommandContext &context)
Definition: HelpMenus.cpp:275
void OnQuickFix(const CommandContext &context)
Definition: HelpMenus.cpp:252
void OnQuickHelp(const CommandContext &context)
Definition: HelpMenus.cpp:259
void OnShowLog(const CommandContext &context)
Definition: HelpMenus.cpp:284
void OnFrameStatistics(const CommandContext &)
Definition: HelpMenus.cpp:383
void OnAbout(const CommandContext &context)
Definition: HelpMenus.cpp:395
void OnManual(const CommandContext &context)
Definition: HelpMenus.cpp:267
virtual void DoBeginGroup(Registry::GroupItem &item, const Path &path)
Definition: Menus.cpp:167
virtual void DoEndGroup(Registry::GroupItem &item, const Path &path)
Definition: Menus.cpp:171
virtual void DoSeparator()
Definition: Menus.cpp:179
virtual void DoVisit(Registry::SingleItem &item, const Path &path)
Definition: Menus.cpp:175
const Identifier name
Definition: Registry.h:67
ToolbarMenuVisitor(AudacityProject &p)