Audacity 3.2.0
ErrorReportDialog.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 ErrorReportDialog.cpp
6
7 Dmitry Vedenko
8
9**********************************************************************/
10
11#include "ErrorReportDialog.h"
12
13#include <wx/app.h>
14#include <wx/artprov.h>
15#include <wx/button.h>
16#include <wx/collpane.h>
17#include <wx/dialog.h>
18#include <wx/html/htmlwin.h>
19#include <wx/icon.h>
20#include <wx/intl.h>
21#include <wx/settings.h>
22#include <wx/sizer.h>
23#include <wx/statbmp.h>
24#include <wx/stattext.h>
25#include <wx/statusbr.h>
26#include <wx/textctrl.h>
27#include <wx/bmpbuttn.h>
28
30#include "AllThemeResources.h"
31#include "Theme.h"
32#include "HelpText.h"
33#include "Prefs.h"
34#include "ShuttleGui.h"
35#include "HelpSystem.h"
36
37#include "SentryReport.h"
38#include "CodeConversions.h"
39
40namespace
41{
42// wxWidgets set an inaccessible border for the wxCollapsiblePane
43// which makes layout of the dialog even more difficult.
44// This code was copied from the wxWidgets 3.1.3 collpaneg.cpp
45int GetCollapsiblePaneBorder(wxWindow* root)
46{
47#if defined(__WXMAC__)
48 (void)root;
49 return 6;
50#elif defined(__WXMSW__)
51 return root->ConvertDialogToPixels(wxSize(2, 0)).x;
52#else
53 (void)root;
54 return 5;
55#endif
56}
57}
58
59constexpr int MaxUserCommentLength = 2000;
60constexpr bool ErrorReportDialogHasUserComment = false;
61
62BEGIN_EVENT_TABLE(ErrorReportDialog, wxDialogWrapper)
67
69 wxWindow* parent, const TranslatableString& dlogTitle,
70 const TranslatableString& message, const ManualPageID& helpUrl,
71 const wxString& log, const bool modal)
73 parent, wxID_ANY, dlogTitle, wxDefaultPosition, wxDefaultSize,
74 wxDEFAULT_DIALOG_STYLE)
75 , mHelpUrl(helpUrl)
76 , mIsModal(modal)
77{
79 audacity::ToUTF8(dlogTitle.Debug()),message.Debug());
80
81 if (!log.empty())
82 ex.AddData("log", log);
83
84 mReport = std::make_unique<audacity::sentry::Report> (ex);
85
87
88 const wxFont headingFont = wxFont(wxFontInfo(12).Bold());
89 const wxFont textFont = wxFont(wxFontInfo(10));
90
91 const int CollapsibleBorderSize = GetCollapsiblePaneBorder(this);
92
93 S.SetBorder(0);
94
95 S.StartHorizontalLay(wxEXPAND, 0);
96 {
97 S.AddSpace(40 - CollapsibleBorderSize, 0);
98
99 S.StartVerticalLay(wxEXPAND, 0);
100 {
101 S.AddSpace(0, 32);
102
103 S.StartHorizontalLay(wxEXPAND, 0);
104 {
105 S.AddSpace(CollapsibleBorderSize);
106
107 S.StartVerticalLay(wxEXPAND, 0);
108 {
109 S.StartHorizontalLay(wxEXPAND, 1);
110 {
111 S.StartVerticalLay(0);
112 {
113 wxBitmap bitmap = wxArtProvider::GetBitmap(
114 wxART_WARNING, wxART_MESSAGE_BOX, wxSize(24, 24));
115
116 S.Prop(0).AddWindow(
117 safenew wxStaticBitmap(S.GetParent(), -1, bitmap));
118
119 S.AddSpace(0, 0, 1);
120 }
121 S.EndVerticalLay();
122
123 S.AddSpace(10, 0);
124
125 S.StartVerticalLay(0);
126 {
127 S.AddSpace(0, 7);
128
129 S.Prop(1)
130 .AddVariableText(message, false, 0, 560)
131 ->SetFont(headingFont);
132 }
133 S.EndVerticalLay();
134 }
135 S.EndHorizontalLay();
136
137 S.AddSpace(0, 20);
138
139 /* i18n-hint: %s is replaced with "here" */
140 AccessibleLinksFormatter errorpage(
141 XO("More information about this error may be available %s."));
142
143 errorpage.FormatLink(
144 /* i18n-hint: Title of hyperlink to audacityteam.org/errors. */
145 wxT("%s"),
146 XO("here"),
147 "https://audacityteam.org/errors");
148 errorpage.Populate(S);
149
150 S.AddSpace(0, 12);
151 S.AddVariableText(XO(
152 "Would you like to send a report to help us fix this issue?"))
153 ->SetFont(textFont);
154
155 S.AddSpace(0, 6);
156
157 /* i18n-hint: %s will be replaced with "our Privacy Policy" */
158 AccessibleLinksFormatter privacyPolicy(
159 XO("All reports are anonymous. See %s for more info."));
160
161 privacyPolicy.FormatLink(
162 /* i18n-hint: Title of hyperlink to the privacy policy. This is an object of "See". */
163 wxT("%s"),
164 XO("our Privacy Policy"),
165 "https://www.audacityteam.org/about/desktop-privacy-notice/");
166
167 privacyPolicy.Populate(S);
168 }
169 S.EndVerticalLay();
170 }
171 S.EndHorizontalLay();
172
173 S.AddSpace(0, 6);
174
175 S.StartHorizontalLay(wxEXPAND, 0);
176 {
177 auto pane = safenew wxCollapsiblePane(
178 S.GetParent(), wxID_ANY, XO("Problem details").Translation());
179
180 S.Style(wxEXPAND | wxALIGN_LEFT);
181 S.Prop(1);
182 S.AddWindow(pane);
183
184 ShuttleGui SI(pane->GetPane(), eIsCreating);
185
186 SI.StartVerticalLay();
187 {
188 SI.Style(
189 wxTE_RICH | wxTE_READONLY | wxTE_MULTILINE | wxTE_DONTWRAP)
190 .MinSize(wxSize(0, 152))
191 .Name(XO("Problem details"))
192 .AddTextBox({}, mReport->GetReportPreview(), 0);
193
195 {
196 SI.AddSpace(0, 20);
197
198 SI.AddVariableText(XO("Comments"))->SetFont(textFont);
199
200 SI.AddSpace(0, 6);
201
202 mCommentsControl = SI.Style(wxTE_MULTILINE)
203 .MinSize(wxSize(0, 76))
204 .Name(XO("Comments"))
205 .AddTextBox({}, {}, 0);
206
207 mCommentsControl->SetMaxLength(MaxUserCommentLength);
208 }
209 }
210 SI.EndVerticalLay();
211 }
212 S.EndHorizontalLay();
213
214 S.AddSpace(0, 20);
215
216 S.StartHorizontalLay(wxEXPAND);
217 {
218 if (!mHelpUrl.empty())
219 {
220 wxBitmapButton* helpButton =
221 S.Id(wxID_HELP).AddBitmapButton(theTheme.Bitmap(bmpHelpIcon));
222 // For screen readers
223 helpButton->SetToolTip(XO("Help").Translation());
224 helpButton->SetLabel(XO("Help").Translation());
225 }
226
227 S.AddSpace(0, 0, 1);
228
229 S.Id(wxID_NO).AddButton(XC("&Don't send", "crash reporter button"));
230
231 S.AddSpace(13, 0);
232
233 S.Id(wxID_YES).AddButton(XC("&Send", "crash reporter button"));
234 }
235 S.EndHorizontalLay();
236
237 S.AddSpace(0, 20);
238 }
239 S.EndVerticalLay();
240
241 S.AddSpace(28, 0);
242 }
243 S.EndHorizontalLay();
244
245 S.SetBorder(2);
246
247 Layout();
248 GetSizer()->Fit(this);
249 SetMinSize(GetSize());
250 Center();
251}
252
254{
255}
256
257void ErrorReportDialog::OnSend(wxCommandEvent& event)
258{
259 Disable();
260
261 if (mCommentsControl != nullptr)
262 mReport->AddUserComment(audacity::ToUTF8(mCommentsControl->GetValue()));
263
264 mReport->Send(
265 [this](int code, std::string body) {
266 CallAfter([this]() {
267 EndModal(true);
268 });
269 });
270}
271
272void ErrorReportDialog::OnDontSend(wxCommandEvent& event)
273{
274 EndModal(true);
275}
276
277void ErrorReportDialog::OnHelp(wxCommandEvent& event)
278{
279 const auto &helpUrl = mHelpUrl.GET();
280 if (helpUrl.StartsWith(wxT("innerlink:")))
281 {
283 this, TitleText(helpUrl.Mid(10)), HelpText(helpUrl.Mid(10)), false,
284 true);
285 return;
286 }
287
288 HelpSystem::ShowHelp(this, mHelpUrl, false);
289}
wxT("CloseDown"))
END_EVENT_TABLE()
Declare functions to perform UTF-8 to std::wstring conversions.
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
constexpr bool ErrorReportDialogHasUserComment
constexpr int MaxUserCommentLength
TranslatableString TitleText(const wxString &Key)
Definition: HelpText.cpp:151
wxString HelpText(const wxString &Key)
Definition: HelpText.cpp:360
#define XO(s)
Definition: Internat.h:31
#define XC(s, c)
Definition: Internat.h:37
#define safenew
Definition: MemoryX.h:10
Declare a class to report errors to Sentry.
@ eIsCreating
Definition: ShuttleGui.h:39
THEME_API Theme theTheme
Definition: Theme.cpp:82
#define S(N)
Definition: ToChars.cpp:64
A dialog, that has "Send", "Don't send" and help buttons.
void OnSend(wxCommandEvent &event)
wxTextCtrl * mCommentsControl
ManualPageID mHelpUrl
void OnDontSend(wxCommandEvent &event)
std::unique_ptr< audacity::sentry::Report > mReport
void OnHelp(wxCommandEvent &event)
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:239
static void ShowHtmlText(wxWindow *pParent, const TranslatableString &Title, const wxString &HtmlText, bool bIsFile=false, bool bModal=false)
Definition: HelpSystem.cpp:127
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
void EndVerticalLay()
wxTextCtrl * AddTextBox(const TranslatableString &Caption, const wxString &Value, const int nChars)
Definition: ShuttleGui.cpp:639
void StartVerticalLay(int iProp=1)
wxStaticText * AddVariableText(const TranslatableString &Str, bool bCenter=false, int PositionFlags=0, int wrapWidth=0)
Definition: ShuttleGui.cpp:464
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:628
wxSizerItem * AddSpace(int width, int height, int prop=0)
ShuttleGui & MinSize()
Definition: ShuttleGui.h:729
ShuttleGui & Name(const TranslatableString &name)
Definition: ShuttleGui.h:660
ShuttleGui & Style(long iStyle)
Definition: ShuttleGui.h:723
wxBitmap & Bitmap(int iIndex)
Holds a msgid for the translation catalog; may also bind format arguments.
void CallAfter(Action action)
Schedule an action to be done later, and in the main thread.
Definition: BasicUI.cpp:206
std::string ToUTF8(const std::wstring &wstr)
A DTO for the Sentry Exception interface.
Definition: SentryReport.h:31
Exception & AddData(std::string key, AnonymizedMessage value)
Add a payload to the exception.
static Exception Create(std::string type, AnonymizedMessage value)
Create a new exception.