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