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 S.AddVariableText(XO(
140 "Click \"Send\" to submit the report to Audacity. This information is collected anonymously."))
141 ->SetFont(textFont);
142
143 S.AddSpace(0, 6);
144
145 /* i18n-hint: %s will be replaced with "our Privacy Policy" */
146 AccessibleLinksFormatter privacyPolicy(
147 XO("See %s for more info."));
148
149 privacyPolicy.FormatLink(
150 /* i18n-hint: Title of hyperlink to the privacy policy. This is an object of "See". */
151 wxT("%s"),
152 XO("our Privacy Policy"),
153 "https://www.audacityteam.org/about/desktop-privacy-notice/");
154
155 privacyPolicy.Populate(S);
156 }
157 S.EndVerticalLay();
158 }
159 S.EndHorizontalLay();
160
161 S.AddSpace(0, 6);
162
163 S.StartHorizontalLay(wxEXPAND, 0);
164 {
165 auto pane = safenew wxCollapsiblePane(
166 S.GetParent(), wxID_ANY, XO("Problem details").Translation());
167
168 S.Style(wxEXPAND | wxALIGN_LEFT);
169 S.Prop(1);
170 S.AddWindow(pane);
171
172 ShuttleGui SI(pane->GetPane(), eIsCreating);
173
174 SI.StartVerticalLay();
175 {
176 SI.Style(
177 wxTE_RICH | wxTE_READONLY | wxTE_MULTILINE | wxTE_DONTWRAP)
178 .MinSize(wxSize(0, 152))
179 .Name(XO("Problem details"))
180 .AddTextBox({}, mReport->GetReportPreview(), 0);
181
183 {
184 SI.AddSpace(0, 20);
185
186 SI.AddVariableText(XO("Comments"))->SetFont(textFont);
187
188 SI.AddSpace(0, 6);
189
190 mCommentsControl = SI.Style(wxTE_MULTILINE)
191 .MinSize(wxSize(0, 76))
192 .Name(XO("Comments"))
193 .AddTextBox({}, {}, 0);
194
195 mCommentsControl->SetMaxLength(MaxUserCommentLength);
196 }
197 }
198 SI.EndVerticalLay();
199 }
200 S.EndHorizontalLay();
201
202 S.AddSpace(0, 20);
203
204 S.StartHorizontalLay(wxEXPAND);
205 {
206 if (!mHelpUrl.empty())
207 {
208 wxBitmapButton* helpButton =
209 S.Id(wxID_HELP).AddBitmapButton(theTheme.Bitmap(bmpHelpIcon));
210 // For screen readers
211 helpButton->SetToolTip(XO("Help").Translation());
212 helpButton->SetLabel(XO("Help").Translation());
213 }
214
215 S.AddSpace(0, 0, 1);
216
217 S.Id(wxID_NO).AddButton(XC("&Don't send", "crash reporter button"));
218
219 S.AddSpace(13, 0);
220
221 S.Id(wxID_YES).AddButton(XC("&Send", "crash reporter button"));
222 }
223 S.EndHorizontalLay();
224
225 S.AddSpace(0, 20);
226 }
227 S.EndVerticalLay();
228
229 S.AddSpace(28, 0);
230 }
231 S.EndHorizontalLay();
232
233 S.SetBorder(2);
234
235 Layout();
236 GetSizer()->Fit(this);
237 SetMinSize(GetSize());
238 Center();
239}
240
242{
243}
244
245void ErrorReportDialog::OnSend(wxCommandEvent& event)
246{
247 Disable();
248
249 if (mCommentsControl != nullptr)
250 mReport->AddUserComment(audacity::ToUTF8(mCommentsControl->GetValue()));
251
252 mReport->Send(
253 [this](int code, std::string body) {
254 CallAfter([this]() {
255 EndModal(true);
256 });
257 });
258}
259
260void ErrorReportDialog::OnDontSend(wxCommandEvent& event)
261{
262 EndModal(true);
263}
264
265void ErrorReportDialog::OnHelp(wxCommandEvent& event)
266{
267 const auto &helpUrl = mHelpUrl.GET();
268 if (helpUrl.StartsWith(wxT("innerlink:")))
269 {
271 this, TitleText(helpUrl.Mid(10)), HelpText(helpUrl.Mid(10)), false,
272 true);
273 return;
274 }
275
276 HelpSystem::ShowHelp(this, mHelpUrl, false);
277}
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:237
static void ShowHtmlText(wxWindow *pParent, const TranslatableString &Title, const wxString &HtmlText, bool bIsFile=false, bool bModal=false)
Definition: HelpSystem.cpp:125
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:38
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.