From bbb9ca14a2c32fe3f82503a023b14b0b9988769c Mon Sep 17 00:00:00 2001 From: Dmitry Vedenko Date: Mon, 7 Jun 2021 19:15:17 +0300 Subject: [PATCH] Adds ErrorReportDialog and ShowExceptionDialog --- src/CMakeLists.txt | 4 + src/widgets/ErrorDialog.cpp | 16 +++ src/widgets/ErrorDialog.h | 7 + src/widgets/ErrorReportDialog.cpp | 217 ++++++++++++++++++++++++++++++ src/widgets/ErrorReportDialog.h | 69 ++++++++++ 5 files changed, 313 insertions(+) create mode 100644 src/widgets/ErrorReportDialog.cpp create mode 100644 src/widgets/ErrorReportDialog.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 415dd040d..b480ff53f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -956,6 +956,10 @@ list( APPEND SOURCES widgets/ReadOnlyText.h widgets/Ruler.cpp widgets/Ruler.h + $<$: + widgets/ErrorReportDialog.cpp + widgets/ErrorReportDialog.h + > widgets/Warning.cpp widgets/Warning.h widgets/WindowAccessible.cpp diff --git a/src/widgets/ErrorDialog.cpp b/src/widgets/ErrorDialog.cpp index e34f1cd4e..ac0473571 100644 --- a/src/widgets/ErrorDialog.cpp +++ b/src/widgets/ErrorDialog.cpp @@ -38,6 +38,10 @@ #include "../Prefs.h" #include "HelpSystem.h" +#ifdef HAS_SENTRY_REPORTING +# include "ErrorReportDialog.h" +#endif + BEGIN_EVENT_TABLE(ErrorDialog, wxDialogWrapper) EVT_COLLAPSIBLEPANE_CHANGED( wxID_ANY, ErrorDialog::OnPane ) EVT_BUTTON( wxID_OK, ErrorDialog::OnOk) @@ -158,6 +162,18 @@ void ShowErrorDialog(wxWindow *parent, } +void ShowExceptionDialog( + wxWindow* parent, const TranslatableString& dlogTitle, + const TranslatableString& message, const wxString& helpPage, bool Close, + const wxString& log) +{ +#ifndef HAS_SENTRY_REPORTING + ShowErrorDialog(parent, dlogTitle, message, helpPage, Close, log); +#else + ShowErrorReportDialog(parent, dlogTitle, message, helpPage, log); +#endif // !HAS_SENTRY_REPORTING +} + // unused. void ShowModelessErrorDialog(wxWindow *parent, const TranslatableString &dlogTitle, diff --git a/src/widgets/ErrorDialog.h b/src/widgets/ErrorDialog.h index d40f985d3..af3ac4fab 100644 --- a/src/widgets/ErrorDialog.h +++ b/src/widgets/ErrorDialog.h @@ -54,6 +54,13 @@ void ShowErrorDialog(wxWindow *parent, bool Close = true, const wxString &log = {}); +/// Displays an error dialog, possibly allowing to send error report. +AUDACITY_DLL_API +void ShowExceptionDialog( + wxWindow* parent, const TranslatableString& dlogTitle, + const TranslatableString& message, const wxString& helpPage, + bool Close = true, const wxString& log = {}); + /// Displays a modeless error dialog with a button that offers help void ShowModelessErrorDialog(wxWindow *parent, const TranslatableString &dlogTitle, diff --git a/src/widgets/ErrorReportDialog.cpp b/src/widgets/ErrorReportDialog.cpp new file mode 100644 index 000000000..ce81cd976 --- /dev/null +++ b/src/widgets/ErrorReportDialog.cpp @@ -0,0 +1,217 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + ErrorReportDialog.cpp + + Dmitry Vedenko + +**********************************************************************/ + +#include "ErrorReportDialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AllThemeResources.h" +#include "Theme.h" +#include "HelpText.h" +#include "Prefs.h" +#include "ShuttleGui.h" +#include "HelpSystem.h" + +#include "SentryReport.h" +#include "CodeConversions.h" + +constexpr int MaxUserCommentLength = 2000; + +BEGIN_EVENT_TABLE(ErrorReportDialog, wxDialogWrapper) + EVT_BUTTON(wxID_YES, ErrorReportDialog::OnSend) + EVT_BUTTON(wxID_NO, ErrorReportDialog::OnDontSend) + EVT_BUTTON(wxID_HELP, ErrorReportDialog::OnHelp) +END_EVENT_TABLE() + +ErrorReportDialog::ErrorReportDialog( + wxWindow* parent, const TranslatableString& dlogTitle, + const TranslatableString& message, const wxString& helpUrl, + const wxString& log, const bool modal) + : wxDialogWrapper( + parent, wxID_ANY, dlogTitle, wxDefaultPosition, wxDefaultSize, + wxDEFAULT_DIALOG_STYLE) + , mHelpUrl(helpUrl) + , mIsModal(modal) +{ + audacity::sentry::Exception ex = audacity::sentry::Exception::Create( + audacity::ToUTF8(dlogTitle.Debug()),message.Debug()); + + if (!log.empty()) + ex.AddData("log", log); + + mReport = std::make_unique (ex); + + ShuttleGui S(this, eIsCreating); + + const wxFont headingFont = wxFont(wxFontInfo(12).Bold()); + const wxFont textFont = wxFont(wxFontInfo(10)); + + S.SetBorder(0); + + S.StartHorizontalLay(wxEXPAND, 0); + { + S.AddSpace(40, 0); + S.StartVerticalLay(wxEXPAND, 0); + { + S.AddSpace(0, 32); + + S.StartHorizontalLay(wxEXPAND, 1); + { + S.StartVerticalLay(0); + { + wxBitmap bitmap = wxArtProvider::GetBitmap( + wxART_WARNING, wxART_MESSAGE_BOX, wxSize(24, 24)); + + S.Prop(0).AddWindow( + safenew wxStaticBitmap(S.GetParent(), -1, bitmap)); + + S.AddSpace(0, 0, 1); + } + S.EndVerticalLay(); + + S.AddSpace(10, 0); + + S.StartVerticalLay(0); + { + S.AddSpace(0, 7); + + S.Prop(1) + .AddVariableText(message, false, 0, 560) + ->SetFont(headingFont); + } + S.EndVerticalLay(); + } + S.EndHorizontalLay(); + + S.AddSpace(0, 20); + + S.AddVariableText(XO( + "Click \"Send\" to submit report to Audacity. This information is collected anonymously.")) + ->SetFont(textFont); + + S.AddSpace(0, 20); + + S.AddVariableText(XO("Problem details"))->SetFont(textFont); + + S.AddSpace(0, 6); + + S.Style(wxTE_RICH | wxTE_READONLY | wxTE_MULTILINE | wxTE_DONTWRAP).MinSize(wxSize(0,152)) + .AddTextBox({}, mReport->GetReportPreview(), 0); + + S.AddSpace(0, 20); + + S.AddVariableText(XO("Comments"))->SetFont(textFont); + + S.AddSpace(0, 6); + + mCommentsControl = S.Style(wxTE_MULTILINE) + .MinSize(wxSize(0, 76)).AddTextBox({}, {}, 0); + + mCommentsControl->SetMaxLength(MaxUserCommentLength); + + S.AddSpace(0, 20); + + S.StartHorizontalLay(wxEXPAND); + { + if (!mHelpUrl.empty()) + { + wxBitmapButton* helpButton = + S.Id(wxID_HELP).AddBitmapButton(theTheme.Bitmap(bmpHelpIcon)); + // For screen readers + helpButton->SetToolTip(XO("Help").Translation()); + helpButton->SetLabel(XO("Help").Translation()); + } + + S.AddSpace(0, 0, 1); + + S.Id(wxID_NO).AddButton(XO("Don't send")); + + S.AddSpace(13, 0); + + S.Id(wxID_YES).AddButton(XO("Send")); + } + S.EndHorizontalLay(); + + S.AddSpace(0, 20); + } + S.EndVerticalLay(); + + S.AddSpace(28, 0); + } + S.EndHorizontalLay(); + + S.SetBorder(2); + + Layout(); + GetSizer()->Fit(this); + SetMinSize(GetSize()); + Center(); +} + +ErrorReportDialog::~ErrorReportDialog() +{ +} + +void ErrorReportDialog::OnSend(wxCommandEvent& event) +{ + Disable(); + + mReport->AddUserComment(audacity::ToUTF8(mCommentsControl->GetValue())); + + mReport->Send( + [this](int code, std::string body) { + CallAfter([this]() { + EndModal(true); + }); + }); +} + +void ErrorReportDialog::OnDontSend(wxCommandEvent& event) +{ + EndModal(true); +} + +void ErrorReportDialog::OnHelp(wxCommandEvent& event) +{ + if (mHelpUrl.StartsWith(wxT("innerlink:"))) + { + HelpSystem::ShowHtmlText( + this, TitleText(mHelpUrl.Mid(10)), HelpText(mHelpUrl.Mid(10)), false, + true); + return; + } + + HelpSystem::ShowHelp(this, mHelpUrl, false); +} + +void ShowErrorReportDialog( + wxWindow* parent, const TranslatableString& dlogTitle, + const TranslatableString& message, const wxString& helpPage, + const wxString& log) +{ + ErrorReportDialog dlog(parent, dlogTitle, message, helpPage, log); + + dlog.CentreOnParent(); + dlog.ShowModal(); +} diff --git a/src/widgets/ErrorReportDialog.h b/src/widgets/ErrorReportDialog.h new file mode 100644 index 000000000..ecc2d83b3 --- /dev/null +++ b/src/widgets/ErrorReportDialog.h @@ -0,0 +1,69 @@ +/********************************************************************** + + Audacity: A Digital Audio Editor + + ErrorReportDialog.h + + Dmitry Vedenko + +**********************************************************************/ + +#ifndef __AUDACITY_SENTRYERRORDIALOG__ +#define __AUDACITY_SENTRYERRORDIALOG__ + +#include + +#include +#include + +#include "wxPanelWrapper.h" // to inherit + +namespace audacity +{ +namespace sentry +{ +class Report; +} +} + +class wxTextCtrl; + +//! A dialog, that has "Send", "Don't send" and help buttons. +/*! This dialog is used in place of error dialogs for Audacity errors + when Sentry reporting is enabled. +*/ +class ErrorReportDialog final : public wxDialogWrapper +{ +public: + ErrorReportDialog( + wxWindow* parent, const TranslatableString& dlogTitle, + const TranslatableString& message, const wxString& helpUrl, + const wxString& log, const bool modal = true); + + ~ErrorReportDialog(); + +private: + void OnSend(wxCommandEvent& event); + void OnDontSend(wxCommandEvent& event); + + void OnHelp(wxCommandEvent& event); + + std::unique_ptr mReport; + + wxString mHelpUrl; + + wxTextCtrl* mCommentsControl; + + bool mIsModal; + + DECLARE_EVENT_TABLE() +}; + +/// Displays an error dialog that allows to send the error report +AUDACITY_DLL_API +void ShowErrorReportDialog( + wxWindow* parent, const TranslatableString& dlogTitle, + const TranslatableString& message, const wxString& helpPage = {}, + const wxString& log = {}); + +#endif // __AUDACITY_SENTRYERRORDIALOG__