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