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 "ProjectSnap.h"
20#include "../ProjectSelectionManager.h"
21#include "../ProjectWindows.h"
22#include "SelectFile.h"
23#include "ShuttleGui.h"
24#include "../SplashDialog.h"
25#include "SyncLock.h"
26#include "Theme.h"
27#include "../commands/CommandContext.h"
28#include "../commands/CommandManager.h"
29#include "../prefs/PrefsDialog.h"
30#include "AudacityMessageBox.h"
31#include "HelpSystem.h"
32
34
35#if defined(HAVE_UPDATES_CHECK)
37#endif
38
39// private helper classes and functions
40namespace
41{
42
51{
52public:
53 using PrefSetter = std::function< void() > ;
54
55 QuickFixDialog(wxWindow * pParent, AudacityProject &project);
56 void Populate();
57 void PopulateOrExchange(ShuttleGui & S);
58 void AddStuck( ShuttleGui & S, bool & bBool,
59 const PrefSetter &prefSetter,
60 const TranslatableString &Prompt, const ManualPageID &Help );
61
62 void OnOk(wxCommandEvent &event);
63 void OnCancel(wxCommandEvent &event);
64 void OnHelp(const ManualPageID &Str);
65 void OnFix(const PrefSetter &setter, wxWindowID id);
66
68
69 int mItem;
73 DECLARE_EVENT_TABLE()
74};
75
76
77#define FixButtonID 7001
78#define HelpButtonID 7011
79
80BEGIN_EVENT_TABLE(QuickFixDialog, wxDialogWrapper)
81 EVT_BUTTON(wxID_OK, QuickFixDialog::OnOk)
82 EVT_BUTTON(wxID_CANCEL, QuickFixDialog::OnCancel)
84
86 wxDialogWrapper(pParent, wxID_ANY, XO("Do you have these problems?"),
87 wxDefaultPosition, wxDefaultSize,
88 wxDEFAULT_DIALOG_STYLE )
89 , mProject{ project }
90{
91 mbSyncLocked = SyncLockTracks.Read();
92 mbInSnapTo = ProjectSnap(project).GetSnapMode() != SnapMode::SNAP_OFF; gPrefs->Read(wxT("/SnapTo"));
93 mbSoundActivated = SoundActivatedRecord.Read();
94
96 PopulateOrExchange(S);
97
98 Fit();
99 auto sz = GetSize();
100 SetMinSize( sz );
101 SetMaxSize( sz );
102
103 // The close button has the cancel id and acts exactly the same as cancel.
104 wxButton * pWin = (wxButton*)FindWindowById( wxID_CANCEL );
105 if( pWin )
106 pWin->SetFocus( );
107 Center();
108}
109
110void QuickFixDialog::AddStuck( ShuttleGui & S, bool & bBool,
111 const PrefSetter &prefSetter,
112 const TranslatableString &Prompt, const ManualPageID &Help )
113{
114 mItem++;
115 wxWindowID id = FixButtonID + mItem;
116 if( !bBool)
117 return;
118
119 S
120 .AddFixedText( Prompt );
121
122 S
123 .Id( id )
124 .AddButton( XXO("Fix") )
125 ->Bind( wxEVT_BUTTON, [this, prefSetter, id](wxCommandEvent&){
126 OnFix( prefSetter, id );
127 } );
128
129 {
130 // Replace standard Help button with smaller icon button.
131 // bs->AddButton(safenew wxButton(parent, wxID_HELP));
132 auto b = safenew wxBitmapButton(S.GetParent(), HelpButtonID+mItem, theTheme.Bitmap( bmpHelpIcon ));
133 b->SetToolTip( _("Help") );
134 b->SetLabel(_("Help")); // for screen readers
135 b->Bind( wxEVT_BUTTON, [this, Help](const wxCommandEvent&){
136 OnHelp( Help );
137 } );
138 S.AddWindow( b );
139 }
140}
141
142void QuickFixDialog::PopulateOrExchange(ShuttleGui & S)
143{
144
145 S.StartVerticalLay(1);
146 S.StartStatic( XO("Quick Fixes"));
147
148 // These aren't all possible modes one can be stuck in, but they are some of them.
149 bool bStuckInMode = mbSyncLocked || mbInSnapTo || mbSoundActivated;
150
151 if( !bStuckInMode ){
152 SetLabel(XO("Nothing to do"));
153 S.AddFixedText(XO("No quick, easily fixed problems were found"));
154 }
155 else {
156 S.StartMultiColumn(3, wxALIGN_CENTER);
157 {
158 mItem = -1;
159
160 auto defaultAction =
161 [](AudacityProject *pProject, BoolSetting &setting){ return
162 [pProject, &setting]{
163 setting.Reset();
164 gPrefs->Flush();
165 // This is overkill (aka slow), as all preferences are
166 // reloaded and all
167 // toolbars recreated.
168 // Overkill probably doesn't matter, as this command is
169 // infrequently used.
170 DoReloadPreferences( *pProject );
171 };
172 };
173
174 // Use # in the URLs to ensure we go to the online version of help.
175 // Local help may well not be installed.
176 auto pProject = &mProject;
177 AddStuck( S, mbSyncLocked,
178 defaultAction( pProject, SyncLockTracks ),
179 XO("Clocks on the Tracks"), "Quick_Fix#sync_lock" );
180 AddStuck( S, mbInSnapTo,
181 [pProject] {
182 // Sadly SnapTo has to be handled specially,
183 // as it is not part of the standard
184 // preference dialogs.
186 },
187 XO("Can't select precisely"), "Quick_Fix#snap_to" );
188 AddStuck( S, mbSoundActivated,
189 defaultAction( pProject, SoundActivatedRecord ),
190 XO("Recording stops and starts"),
191 "Quick_Fix#sound_activated_recording" );
192 }
193 S.EndMultiColumn();
194 }
195 S.EndStatic();
196
197 S.StartHorizontalLay(wxALIGN_CENTER_HORIZONTAL, 0);
198 S.AddStandardButtons(eCloseButton + (bStuckInMode ? 0 : eHelpButton));
199 S.EndHorizontalLay();
200
201 S.EndVerticalLay();
202
203 wxButton * pBtn = (wxButton*)FindWindowById( wxID_HELP );
204 if( pBtn )
205 pBtn->Bind( wxEVT_BUTTON, [this]( const wxCommandEvent & ){
206 OnHelp( "Quick_Fix#" );
207 } );
208}
209
210void QuickFixDialog::OnOk(wxCommandEvent &event)
211{
212 (void)event;// Compiler food
213 EndModal(wxID_OK);
214}
215
216void QuickFixDialog::OnCancel(wxCommandEvent &event)
217{
218 (void)event;// Compiler food
219 EndModal(wxID_CANCEL);
220}
221
222void QuickFixDialog::OnHelp(const ManualPageID &Str)
223{
224 HelpSystem::ShowHelp(this, Str, true);
225}
226
227void QuickFixDialog::OnFix(const PrefSetter &setter, wxWindowID id)
228{
229 if ( setter )
230 setter();
231
232 // Change the label after doing the fix, as the fix may take a second or two.
233 auto pBtn = FindWindow(id);
234 if( pBtn )
235 pBtn->SetLabel( _("Fixed") );
236
237 // The close button has the cancel id and acts exactly the same as cancel.
238 wxButton * pWin = (wxButton*)FindWindowById( wxID_CANCEL );
239 if( pWin )
240 pWin->SetFocus( );
241}
242
243}
244
245namespace {
246
247// Menu handler functions
248
249void OnQuickFix(const CommandContext &context)
250{
251 auto &project = context.project;
253 dlg.ShowModal();
254}
255
256void OnQuickHelp(const CommandContext &context)
257{
258 auto &project = context.project;
261 L"Quick_Help");
262}
263
264void OnManual(const CommandContext &context)
265{
266 auto &project = context.project;
269 L"Main_Page");
270}
271
273{
274 auto &project = context.project;
275 auto gAudioIO = AudioIOBase::Get();
276 wxString info = gAudioIO->GetDeviceInfo();
278 XO("Audio Device Info"), wxT("deviceinfo.txt") );
279}
280
281void OnShowLog( const CommandContext &context )
282{
284}
285
286#if defined(HAS_CRASH_REPORT)
287void OnCrashReport(const CommandContext &WXUNUSED(context) )
288{
289// Change to "1" to test a real crash
290#if 0
291 char *p = 0;
292 *p = 1234;
293#endif
294 CrashReport::Generate(wxDebugReport::Context_Current);
295}
296#endif
297
298#ifdef IS_ALPHA
299void OnSegfault(const CommandContext &)
300{
301 unsigned *p = nullptr;
302 *p = 0xDEADBEEF;
303}
304
305void OnException(const CommandContext &)
306{
307 // Throw an exception that can be caught only as (...)
308 // The intent is to exercise detection of unhandled exceptions by the
309 // crash reporter
310 struct Unique{};
311 throw Unique{};
312}
313
314void OnAssertion(const CommandContext &)
315{
316 // We don't use assert() much directly, but Breakpad does detect it
317 // This may crash the program only in debug builds
318 // See also wxSetAssertHandler, and wxApp::OnAssertFailure()
319 assert(false);
320}
321#endif
322
323void OnMenuTree(const CommandContext &context)
324{
325 auto &project = context.project;
326
327 using namespace MenuTable;
328 struct MyVisitor : ProjectMenuVisitor
329 {
331
332 enum : unsigned { TAB = 3 };
333 void DoBeginGroup( GroupItemBase &item, const Path& ) override
334 {
335 if ( dynamic_cast<MenuItem*>( &item ) ) {
336 Indent();
337 // using GET for alpha only diagnostic tool
338 info += item.name.GET();
339 Return();
340 indentation = wxString{ ' ', TAB * ++level };
341 }
342 }
343
344 void DoEndGroup( GroupItemBase &item, const Path& ) override
345 {
346 if ( dynamic_cast<MenuItem*>( &item ) )
347 indentation = wxString{ ' ', TAB * --level };
348 }
349
350 void DoVisit( SingleItem &item, const Path& ) override
351 {
352 // using GET for alpha only diagnostic tool
353 Indent();
354 info += item.name.GET();
355 Return();
356 }
357
358 void DoSeparator() override
359 {
360 static const wxString separatorName{ '=', 20 };
361 Indent();
362 info += separatorName;
363 Return();
364 }
365
366 void Indent() { info += indentation; }
367 void Return() { info += '\n'; }
368
369 unsigned level{};
370 wxString indentation;
371 wxString info;
372 } visitor{ project };
373
374 MenuManager::Visit( visitor );
375
376 ShowDiagnostics( project, visitor.info,
377 Verbatim("Menu Tree"), wxT("menutree.txt"), true );
378}
379
381{
383}
384
385#if defined(HAVE_UPDATES_CHECK)
386void OnCheckForUpdates(const CommandContext &WXUNUSED(context))
387{
389}
390#endif
391
392void OnAbout(const CommandContext &context)
393{
394#ifdef __WXMAC__
395 // Modeless dialog, consistent with other Mac applications
396 // Simulate the application Exit menu item
397 wxCommandEvent evt{ wxEVT_MENU, wxID_ABOUT };
398 wxTheApp->AddPendingEvent( evt );
399#else
400 auto &project = context.project;
401 auto &window = GetProjectFrame( project );
402
403 // Windows and Linux still modal.
404 AboutDialog dlog( &window );
405 dlog.ShowModal();
406#endif
407}
408
409#if 0
410// Legacy handlers, not used as of version 2.3.0
411
412// Only does the update checks if it's an ALPHA build and not disabled by
413// preferences.
414void MayCheckForUpdates(AudacityProject &project)
415{
416#ifdef IS_ALPHA
417 OnCheckForUpdates(project);
418#endif
419}
420
421void OnHelpWelcome(const CommandContext &context)
422{
424}
425
426#endif
427
428// Menu definitions
429
430using namespace MenuTable;
432{
433 static BaseItemSharedPtr menu{
434 Menu( wxT("Help"), XXO("&Help"),
435 Section( "Basic",
436 // QuickFix menu item not in Audacity 2.3.1 whilst we discuss further.
437 #ifdef EXPERIMENTAL_DA
438 // DA: Has QuickFix menu item.
439 Command( wxT("QuickFix"), XXO("&Quick Fix..."), OnQuickFix,
441 // DA: 'Getting Started' rather than 'Quick Help'.
442 Command( wxT("QuickHelp"), XXO("&Getting Started"), OnQuickHelp,
444 // DA: Emphasise it is the Audacity Manual (No separate DA manual).
445 Command( wxT("Manual"), XXO("Audacity &Manual"), OnManual,
447
448 #else
449 Command( wxT("QuickHelp"), XXO("&Quick Help..."), OnQuickHelp,
451 Command( wxT("Manual"), XXO("&Manual..."), OnManual,
453 #endif
454 ),
455
456 #ifdef __WXMAC__
457 Items
458 #else
459 Section
460 #endif
461 ( "Other",
462 Menu( wxT("Diagnostics"), XXO("&Diagnostics"),
463 Command( wxT("DeviceInfo"), XXO("Au&dio Device Info..."),
466 Command( wxT("Log"), XXO("Show &Log..."), OnShowLog,
468 #if defined(HAS_CRASH_REPORT)
469 Command( wxT("CrashReport"), XXO("&Generate Support Data..."),
470 OnCrashReport, AlwaysEnabledFlag )
471 #endif
472
473 #ifdef IS_ALPHA
474 ,
475 // alpha-only items don't need to internationalize, so use
476 // Verbatim for labels
477
478 Command( wxT("RaiseSegfault"), Verbatim("Test segfault report"),
479 OnSegfault, AlwaysEnabledFlag ),
480
481 Command( wxT("ThrowException"), Verbatim("Test exception report"),
482 OnException, AlwaysEnabledFlag ),
483
484 Command( wxT("ViolateAssertion"), Verbatim("Test assertion report"),
485 OnAssertion, AlwaysEnabledFlag ),
486
487 // Menu explorer. Perhaps this should become a macro command
488 Command( wxT("MenuTree"), Verbatim("Menu Tree..."),
491
492 Command(
493 wxT("FrameStatistics"), Verbatim("Frame Statistics..."),
496 #endif
497 )
498 ),
499
500 Section( "Extra",
501 // DA: Does not fully support update checking.
502 #if !defined(EXPERIMENTAL_DA) && defined(HAVE_UPDATES_CHECK)
503 Command( wxT("Updates"), XXO("&Check for Updates..."),
504 OnCheckForUpdates,
506 #endif
507 Command( wxT("About"), XXO("&About Audacity"), OnAbout,
509 )
510 ) };
511 return menu;
512}
513
515 wxT(""),
517};
518
519}
wxT("CloseDown"))
BoolSetting SoundActivatedRecord
Definition: AudioIO.cpp:3305
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:78
#define FixButtonID
Definition: HelpMenus.cpp:77
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
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
void DoReloadPreferences(AudacityProject &project)
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:609
@ eHelpButton
Definition: ShuttleGui.h:603
BoolSetting SyncLockTracks
Definition: SyncLock.cpp:173
const auto project
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:93
This specialization of Setting for bool adds a Toggle method to negate the saved value.
Definition: Prefs.h:344
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
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
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(ProjectMenuVisitor &visitor)
Definition: Menus.cpp:434
Project snapping settings.
Definition: ProjectSnap.h:29
void SetSnapMode(SnapMode mode)
Definition: ProjectSnap.cpp:41
static ProjectSnap & Get(AudacityProject &project)
Definition: ProjectSnap.cpp:27
SnapMode GetSnapMode() const
Definition: ProjectSnap.cpp:54
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:205
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:630
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:51
virtual bool Flush() noexcept=0
virtual bool Read(const wxString &key, bool *value) const =0
constexpr auto Section
constexpr auto Menu
Items will appear in a main toolbar menu or in a sub-menu.
constexpr auto Items
constexpr auto Command
std::unique_ptr< detail::IndirectItem< Item > > Indirect(const std::shared_ptr< Item > &ptr)
A convenience function.
Definition: Registry.h:113
std::shared_ptr< BaseItem > BaseItemSharedPtr
Definition: Registry.h:78
void OnMenuTree(const CommandContext &context)
Definition: HelpMenus.cpp:323
void OnAudioDeviceInfo(const CommandContext &context)
Definition: HelpMenus.cpp:272
void OnQuickFix(const CommandContext &context)
Definition: HelpMenus.cpp:249
void OnQuickHelp(const CommandContext &context)
Definition: HelpMenus.cpp:256
void OnShowLog(const CommandContext &context)
Definition: HelpMenus.cpp:281
void OnFrameStatistics(const CommandContext &)
Definition: HelpMenus.cpp:380
void OnAbout(const CommandContext &context)
Definition: HelpMenus.cpp:392
void OnManual(const CommandContext &context)
Definition: HelpMenus.cpp:264
virtual void DoSeparator()
Definition: Menus.cpp:185
virtual void DoBeginGroup(Registry::GroupItemBase &item, const Path &path)
Groups of type MenuItems are excluded from this callback.
Definition: Menus.cpp:173
virtual void DoVisit(Registry::SingleItem &item, const Path &path)
Definition: Menus.cpp:181
virtual void DoEndGroup(Registry::GroupItemBase &item, const Path &path)
Groups of type MenuItems are excluded from this callback.
Definition: Menus.cpp:177
ProjectMenuVisitor(AudacityProject &p)
Common abstract base class for items that group other items.
Definition: Registry.h:170
Common abstract base class for items that are not groups.
Definition: Registry.h:162