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 
40 namespace
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
45 int 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 
59 constexpr int MaxUserCommentLength = 2000;
60 constexpr bool ErrorReportDialogHasUserComment = false;
61 
62 BEGIN_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 
86  ShuttleGui S(this, eIsCreating);
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 
182  if constexpr (ErrorReportDialogHasUserComment)
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 
245 void 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 
260 void ErrorReportDialog::OnDontSend(wxCommandEvent& event)
261 {
262  EndModal(true);
263 }
264 
265 void 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 }
EVT_BUTTON
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
eIsCreating
@ eIsCreating
Definition: ShuttleGui.h:39
SentryReport.h
Declare a class to report errors to Sentry.
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1185
S
#define S(N)
Definition: ToChars.cpp:64
HelpSystem.h
ErrorReportDialog
A dialog, that has "Send", "Don't send" and help buttons.
Definition: ErrorReportDialog.h:36
AllThemeResources.h
ThemeBase::Bitmap
wxBitmap & Bitmap(int iIndex)
ShuttleGui::AddSpace
wxSizerItem * AddSpace(int width, int height, int prop=0)
Definition: ShuttleGui.cpp:2460
ShuttleGui::MinSize
ShuttleGui & MinSize()
Definition: ShuttleGui.h:732
XO
#define XO(s)
Definition: Internat.h:31
XC
#define XC(s, c)
Definition: Internat.h:37
BasicUI::CallAfter
void CallAfter(Action action)
Schedule an action to be done later, and in the main thread.
Definition: BasicUI.cpp:38
ErrorReportDialog::mCommentsControl
wxTextCtrl * mCommentsControl
Definition: ErrorReportDialog.h:55
ErrorReportDialog::OnSend
void OnSend(wxCommandEvent &event)
Definition: ErrorReportDialog.cpp:245
HelpSystem::ShowHelp
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:237
ErrorReportDialog.h
ErrorReportDialog::mHelpUrl
ManualPageID mHelpUrl
Definition: ErrorReportDialog.h:53
ShuttleGui::Style
ShuttleGui & Style(long iStyle)
Definition: ShuttleGui.h:726
HelpText.h
HelpSystem::ShowHtmlText
static void ShowHtmlText(wxWindow *pParent, const TranslatableString &Title, const wxString &HtmlText, bool bIsFile=false, bool bModal=false)
Definition: HelpSystem.cpp:125
ShuttleGuiBase::AddTextBox
wxTextCtrl * AddTextBox(const TranslatableString &Caption, const wxString &Value, const int nChars)
Definition: ShuttleGui.cpp:639
ShuttleGuiBase::EndVerticalLay
void EndVerticalLay()
Definition: ShuttleGui.cpp:1204
ErrorReportDialog::mReport
std::unique_ptr< audacity::sentry::Report > mReport
Definition: ErrorReportDialog.h:51
Theme.h
ShuttleGui.h
theTheme
THEME_API Theme theTheme
Definition: Theme.cpp:82
Identifier::GET
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
ShuttleGui::Name
ShuttleGui & Name(const TranslatableString &name)
Definition: ShuttleGui.h:663
wxDialogWrapper
Definition: wxPanelWrapper.h:81
TaggedIdentifier< ManualPageIDTag >
MaxUserCommentLength
constexpr int MaxUserCommentLength
Definition: ErrorReportDialog.cpp:59
audacity::sentry::Exception::Create
static Exception Create(std::string type, AnonymizedMessage value)
Create a new exception.
Definition: SentryReport.cpp:224
ErrorReportDialog::~ErrorReportDialog
~ErrorReportDialog()
Definition: ErrorReportDialog.cpp:241
Prefs.h
anonymous_namespace{ErrorReportDialog.cpp}::GetCollapsiblePaneBorder
int GetCollapsiblePaneBorder(wxWindow *root)
Definition: ErrorReportDialog.cpp:45
audacity::sentry::Exception
A DTO for the Sentry Exception interface.
Definition: SentryReport.h:31
CodeConversions.h
Declare functions to preform UTF-8 to std::wstring conversions.
ShuttleGuiBase::AddVariableText
wxStaticText * AddVariableText(const TranslatableString &Str, bool bCenter=false, int PositionFlags=0, int wrapWidth=0)
Definition: ShuttleGui.cpp:464
HelpText
AUDACITY_DLL_API wxString HelpText(const wxString &Key)
safenew
#define safenew
Definition: MemoryX.h:10
audacity::ToUTF8
std::string ToUTF8(const std::wstring &wstr)
Definition: CodeConversions.cpp:19
TitleText
AUDACITY_DLL_API TranslatableString TitleText(const wxString &Key)
END_EVENT_TABLE
END_EVENT_TABLE()
audacity::sentry::Exception::AddData
Exception & AddData(std::string key, AnonymizedMessage value)
Add a payload to the exception.
Definition: SentryReport.cpp:238
ErrorReportDialog::OnHelp
void OnHelp(wxCommandEvent &event)
Definition: ErrorReportDialog.cpp:265
ErrorReportDialogHasUserComment
constexpr bool ErrorReportDialogHasUserComment
Definition: ErrorReportDialog.cpp:60
ShuttleGui
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:631
ErrorReportDialog::OnDontSend
void OnDontSend(wxCommandEvent &event)
Definition: ErrorReportDialog.cpp:260