Audacity 3.2.0
wxWidgetsBasicUI.cpp
Go to the documentation of this file.
1/*!********************************************************************
2
3Audacity: A Digital Audio Editor
4
5@file wxWidgetsBasicUI.cpp
6
7Paul Licameli
8
9**********************************************************************/
10#include "wxWidgetsBasicUI.h"
12#include "MemoryX.h" // for Destroy_ptr
13#include "widgets/ErrorDialog.h"
14#ifdef HAS_SENTRY_REPORTING
16#endif
18#include "ProgressDialog.h"
19#include "MultiDialog.h"
20#include <wx/app.h>
21#include <wx/progdlg.h>
22#include <wx/windowptr.h>
23#include <wx/utils.h>
24
25using namespace BasicUI;
26
28
30{
31 wxTheApp->CallAfter(action);
32}
33
35{
36 wxTheApp->Yield();
37}
38
40 const BasicUI::WindowPlacement &placement,
41 const TranslatableString &dlogTitle,
42 const TranslatableString &message,
43 const ManualPageID &helpPage,
44 const BasicUI::ErrorDialogOptions &options)
45{
46 using namespace BasicUI;
47 bool modal = true;
48 auto parent = wxWidgetsWindowPlacement::GetParent(placement);
49 switch (options.type) {
50 case ErrorDialogType::ModalErrorReport: {
51#ifdef HAS_SENTRY_REPORTING
52 ErrorReportDialog dlog(parent, dlogTitle, message, helpPage,
53 options.log, modal);
54
55 dlog.CentreOnParent();
56 dlog.ShowModal();
57 return;
58#else
59 break;
60#endif
61 }
62 case ErrorDialogType::ModelessError: {
63 if (!parent)
64 parent = wxTheApp->GetTopWindow();
65 // To be nonmodal, either it needs a parent, to avoid leaks, or it must
66 // guarantee eventual deletion of itself. There might be no top window
67 // on MacOS. Let's just force it to be modal in that case.
68 if (parent)
69 modal = false;
70 break;
71 }
72 default:
73 break;
74 }
75 auto pDlog = Destroy_ptr<ErrorDialog>( safenew ErrorDialog{ parent,
76 dlogTitle, message, helpPage, options.log,
77 options.modalHelp, modal } );
78 pDlog->CentreOnParent();
79 if (modal)
80 pDlog->ShowModal();
81 else {
82 pDlog->Show();
83 pDlog.release(); // not a memory leak, because it has a parent
84 }
85}
86
89 const TranslatableString &message,
90 MessageBoxOptions options)
91{
92 // Compute the style argument to pass to wxWidgets
93 long style = 0;
94 switch (options.iconStyle) {
95 case Icon::Warning :
96 style = wxICON_WARNING;
97 break;
98 case Icon::Error :
99 style = wxICON_ERROR;
100 break;
101 case Icon::Question :
102 style = wxICON_QUESTION;
103 break;
104 case Icon::Information :
105 style = wxICON_INFORMATION;
106 break;
107 default:
108 break;
109 }
110 switch (options.buttonStyle) {
111 case Button::Ok :
112 style |= wxOK;
113 break;
114 case Button::YesNo :
115 style |= wxYES_NO;
116 break;
117 default:
118 break;
119 }
120 if (!options.yesOrOkDefaultButton && options.buttonStyle == Button::YesNo)
121 style |= wxNO_DEFAULT;
122 if (options.cancelButton)
123 style |= wxCANCEL;
124 if (options.centered)
125 style |= wxCENTER;
126
127 // Preserving the default style AudacityMessageBox had,
128 // when none of the above were explicitly specified
129 if (!style)
130 style = wxOK | wxCENTRE;
131
132 // This calls through to ::wxMessageBox:
133 auto wxResult =
134 ::AudacityMessageBox(message, options.caption, style,
135 options.parent
137 : nullptr);
138 // This switch exhausts all possibilities for the return from::wxMessageBox.
139 // see utilscmn.cpp in wxWidgets.
140 // Remap to our toolkit-neutral enumeration.
141 switch (wxResult) {
142 case wxYES:
143 return MessageBoxResult::Yes;
144 case wxNO:
145 return MessageBoxResult::No;
146 case wxOK:
147 return MessageBoxResult::Ok;
148 case wxCANCEL:
149 return MessageBoxResult::Cancel;
150 case wxHELP:
151 // should not happen, because we don't ever pass wxHELP
152 default:
153 wxASSERT(false);
154 return MessageBoxResult::None;
155 }
156}
157
158std::unique_ptr<BasicUI::ProgressDialog>
160 const TranslatableString &message,
161 unsigned flags,
162 const TranslatableString &remainingLabelText)
163{
164 unsigned options = 0;
165 if (!(flags & ProgressShowStop))
166 options |= pdlgHideStopButton;
167 if (!(flags & ProgressShowCancel))
168 options |= pdlgHideCancelButton;
169 if ((flags & ProgressHideTime))
170 options |= pdlgHideElapsedTime;
171 if ((flags & ProgressConfirmStopOrCancel))
172 options |= pdlgConfirmStopCancel;
173 // Usually wxWindow objects should not be managed by std::unique_ptr
174 // See https://docs.wxwidgets.org/3.0/overview_windowdeletion.html
175 // But on macOS the use of wxWindowPtr for the progress dialog sometimes
176 // causes hangs.
177 return std::make_unique<::ProgressDialog>(
178 title, message, options, remainingLabelText);
179}
180
181namespace {
182struct MyGenericProgress : wxGenericProgressDialog, GenericProgressDialog {
184 const TranslatableString &message,
185 wxWindow *parent = nullptr)
186 : wxGenericProgressDialog{
187 title.Translation(), message.Translation(),
188 300000, // range
189 parent,
190 wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_SMOOTH
191 }
192 {}
193 ~MyGenericProgress() override = default;
194 void Pulse() override { wxGenericProgressDialog::Pulse(); }
195};
196}
197
198std::unique_ptr<GenericProgressDialog>
200 const BasicUI::WindowPlacement &placement,
202 const TranslatableString &message)
203{
204 return std::make_unique<MyGenericProgress>(
205 title, message, wxWidgetsWindowPlacement::GetParent(placement));
206}
207
210 const TranslatableStrings &buttons,
211 const ManualPageID &helpPage,
212 const TranslatableString &boxMsg, bool log)
213{
214 return ::ShowMultiDialog(message, title, buttons, helpPage, boxMsg, log);
215}
216
218{
219 return wxLaunchDefaultBrowser(url);
220}
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
#define safenew
Definition: MemoryX.h:10
std::unique_ptr< T, Destroyer< T > > Destroy_ptr
a convenience for using Destroyer
Definition: MemoryX.h:162
int ShowMultiDialog(const TranslatableString &message, const TranslatableString &title, const TranslatableStrings &buttons, const ManualPageID &helpPage, const TranslatableString &boxMsg, bool log)
static const auto title
@ pdlgConfirmStopCancel
@ pdlgHideStopButton
@ pdlgHideElapsedTime
@ pdlgHideCancelButton
std::vector< TranslatableString > TranslatableStrings
Abstraction of a progress dialog with undefined time-to-completion estimate.
Definition: BasicUI.h:176
Subclasses may hold information such as a parent window pointer for a dialog.
Definition: BasicUI.h:29
Gives an Error message with an option for help.
Definition: ErrorDialog.h:26
A dialog, that has "Send", "Don't send" and help buttons.
Holds a msgid for the translation catalog; may also bind format arguments.
void DoCallAfter(const BasicUI::Action &action) override
bool DoOpenInDefaultBrowser(const wxString &url) override
BasicUI::MessageBoxResult DoMessageBox(const TranslatableString &message, BasicUI::MessageBoxOptions options) override
int DoMultiDialog(const TranslatableString &message, const TranslatableString &title, const TranslatableStrings &buttons, const ManualPageID &helpPage, const TranslatableString &boxMsg, bool log) override
~wxWidgetsBasicUI() override
std::unique_ptr< BasicUI::GenericProgressDialog > DoMakeGenericProgress(const BasicUI::WindowPlacement &placement, const TranslatableString &title, const TranslatableString &message) override
std::unique_ptr< BasicUI::ProgressDialog > DoMakeProgress(const TranslatableString &title, const TranslatableString &message, unsigned flags, const TranslatableString &remainingLabelText) override
void DoYield() override
void DoShowErrorDialog(const BasicUI::WindowPlacement &placement, const TranslatableString &dlogTitle, const TranslatableString &message, const ManualPageID &helpPage, const BasicUI::ErrorDialogOptions &options) override
@ ProgressHideTime
Definition: BasicUI.h:140
@ ProgressShowCancel
Definition: BasicUI.h:139
@ ProgressConfirmStopOrCancel
Definition: BasicUI.h:141
@ ProgressShowStop
Definition: BasicUI.h:138
std::function< void()> Action
Definition: BasicUI.h:24
MessageBoxResult
Definition: BasicUI.h:129
Options for variations of error dialogs; the default is for modal dialogs.
Definition: BasicUI.h:49
ErrorDialogType type
Type of help dialog.
Definition: BasicUI.h:67
std::wstring log
Optional extra logging information to be shown.
Definition: BasicUI.h:71
bool modalHelp
Whether the secondary help dialog with more information should be modal.
Definition: BasicUI.h:69
TranslatableString caption
Definition: BasicUI.h:121
WindowPlacement * parent
Definition: BasicUI.h:120
void Pulse() override
Give some visual indication of progress. Call only on the main thread.
MyGenericProgress(const TranslatableString &title, const TranslatableString &message, wxWindow *parent=nullptr)
static wxWindow * GetParent(const WindowPlacement &placement)
Retrieve the pointer to window, if placement is of this type; else null.
Implementation of BasicUI using wxWidgets.