audacia/src/widgets/ErrorDialog.cpp

443 lines
13 KiB
C++
Raw Normal View History

/**********************************************************************
Audacity: A Digital Audio Editor
ErrorDialog.cpp
Jimmy Johnson
Leland Lucius
*******************************************************************//**
\class ErrorDialog
Gives an Error message with an option for help.
*//********************************************************************/
#include "../Audacity.h"
#include <wx/button.h>
#include <wx/icon.h>
#include <wx/dialog.h>
#include <wx/intl.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/utils.h>
#include <wx/html/htmlwin.h>
#include <wx/settings.h>
#include <wx/statusbr.h>
#include "LinkingHtmlWindow.h"
#include "../Theme.h"
#include "../AllThemeResources.h"
#include "../ShuttleGui.h"
#include "../HelpText.h"
#include "../Internat.h"
#include "../Project.h"
#include "../Prefs.h"
#include "ErrorDialog.h"
class ErrorDialog : public wxDialog
{
public:
// constructors and destructors
ErrorDialog(wxWindow *parent,
const wxString & dlogTitle,
const wxString & message,
const wxString & helpURL,
const bool Close = true, const bool modal = true);
virtual ~ErrorDialog(){}
private:
wxString dhelpURL;
bool dClose;
bool dModal;
void OnOk( wxCommandEvent &event );
void OnHelp( wxCommandEvent &event );
DECLARE_EVENT_TABLE()
};
// special case for alias missing dialog because we keep track of if it exists.
class AliasedFileMissingDialog : public ErrorDialog
{
public:
AliasedFileMissingDialog(AudacityProject *parent,
const wxString & dlogTitle,
const wxString & message,
const wxString & helpURL,
const bool Close = true, const bool modal = true);
virtual ~AliasedFileMissingDialog();
};
BEGIN_EVENT_TABLE(ErrorDialog, wxDialog)
EVT_BUTTON( wxID_OK, ErrorDialog::OnOk)
EVT_BUTTON( wxID_HELP, ErrorDialog::OnHelp)
END_EVENT_TABLE()
AliasedFileMissingDialog::AliasedFileMissingDialog(AudacityProject *parent,
const wxString & dlogTitle,
const wxString & message,
const wxString & helpURL,
const bool Close, const bool modal):
ErrorDialog(parent, dlogTitle, message, helpURL, Close, modal)
{
parent->SetMissingAliasFileDialog(this);
}
AliasedFileMissingDialog::~AliasedFileMissingDialog()
{
((AudacityProject*)GetParent())->SetMissingAliasFileDialog(NULL);
}
ErrorDialog::ErrorDialog(
wxWindow *parent,
const wxString & dlogTitle,
const wxString & message,
const wxString & helpURL,
const bool Close, const bool modal):
wxDialog(parent, (wxWindowID)-1, dlogTitle)
{
long buttonMask;
// only add the help button if we have a URL
buttonMask = (helpURL == wxT("")) ? eOkButton : (eHelpButton | eOkButton);
dhelpURL = helpURL;
dClose = Close;
dModal = modal;
ShuttleGui S(this, eIsCreating);
S.StartVerticalLay();
{
S.SetBorder( 20 );
S.AddFixedText( message );
S.SetBorder( 2 );
S.AddStandardButtons( buttonMask );
}
S.EndVerticalLay();
Layout();
Fit();
SetMinSize(GetSize());
Center();
#if 0
// Original non ShuttleGui based code.
// Layout did not look good on Windows.
wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *vSizer = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *hSizer = new wxBoxSizer(wxHORIZONTAL);
wxStaticText *statText = new wxStaticText(this, -1, message);
mainSizer->Add(statText, 0, wxALIGN_LEFT|wxALL, 5);
wxButton *help = new wxButton(this, wxID_HELP, _("Help"));
hSizer->Add(help, 0, wxALIGN_LEFT|wxALL, 5);
wxButton *ok = new wxButton(this, wxID_OK, _("OK"));
ok->SetDefault();
ok->SetFocus();
hSizer->Add(ok, 0, wxALIGN_RIGHT|wxALL, 5);
vSizer->Add(hSizer, 0, wxALIGN_CENTER|wxALL, 5);
mainSizer->Add(vSizer, 0, wxALL, 15 );
SetAutoLayout(true);
SetSizer(mainSizer);
mainSizer->Fit(this);
mainSizer->SetSizeHints(this);
#endif
}
void ErrorDialog::OnOk(wxCommandEvent &event)
{
if (dModal)
EndModal(true);
else
Destroy();
}
// Helper class to make browser "simulate" a modal dialog
class HtmlTextHelpDialog : public BrowserFrame
{
public:
HtmlTextHelpDialog() : BrowserFrame()
{
MakeModal( true );
}
virtual ~HtmlTextHelpDialog()
{
MakeModal( false );
// On Windows, for some odd reason, the Audacity window will be sent to
// the back. So, make sure that doesn't happen.
GetParent()->Raise();
}
};
void ShowHtmlText(wxWindow *pParent,
const wxString &Title,
const wxString &HtmlText,
bool bIsFile = false, bool bModal = false)
{
LinkingHtmlWindow *html;
BrowserFrame * pWnd;
if( bModal )
pWnd = new HtmlTextHelpDialog();
else
pWnd = new BrowserFrame();
pWnd->Create(pParent, wxID_ANY, Title, wxDefaultPosition, wxDefaultSize,
#if defined(__WXMAC__)
// On OSX, the html frame can go behind the help dialog and if the help
// html frame is modal, you can't get back to it. Pressing escape gets
// you out of this, but it's just easier to add the wxSTAY_ON_TOP flag
// to prevent it from falling behind the dialog. Not the perfect solution
// but acceptable in this case.
wxSTAY_ON_TOP |
#endif
wxDEFAULT_FRAME_STYLE);
ShuttleGui S( pWnd, eIsCreating );
S.SetStyle( wxNO_BORDER | wxTAB_TRAVERSAL );
wxPanel *pPan = S.Prop(true).StartPanel();
{
S.StartHorizontalLay( wxEXPAND, false );
{
wxButton * pWndBackwards = S.Id( wxID_BACKWARD ).AddButton( _("<") );
wxButton * pWndForwards = S.Id( wxID_FORWARD ).AddButton( _(">") );
pWndForwards->Enable( false );
pWndBackwards->Enable( false );
#if wxUSE_TOOLTIPS
pWndForwards->SetToolTip( _("Forwards" ));
pWndBackwards->SetToolTip( _("Backwards" ));
#endif
}
S.EndHorizontalLay();
html = new LinkingHtmlWindow(pPan, wxID_ANY,
wxDefaultPosition,
bIsFile ? wxSize(500, 400) : wxSize(480, 240),
wxHW_SCROLLBAR_AUTO | wxSUNKEN_BORDER);
html->SetRelatedFrame( pWnd, wxT("Help: %s") );
if( bIsFile )
html->LoadFile( HtmlText );
else
html->SetPage( HtmlText);
S.Prop(1).AddWindow( html, wxEXPAND );
S.Id( wxID_CANCEL ).AddButton( _("Close") )->SetDefault();
}
S.EndPanel();
// -- START of ICON stuff -----
// If this section (providing an icon) causes compilation errors on linux, comment it out for now.
// it will just mean that the icon is missing. Works OK on Windows.
#ifdef __WXMSW__
wxIcon ic(wxICON(AudacityLogo));
#else
wxIcon ic;
ic.CopyFromBitmap(theTheme.Bitmap(bmpAudacityLogo48x48));
#endif
pWnd->SetIcon( ic );
// -- END of ICON stuff -----
pWnd->mpHtml = html;
pWnd->SetBackgroundColour( wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
pWnd->CreateStatusBar();
pWnd->Centre();
pWnd->Layout();
pWnd->Fit();
pWnd->SetSizeHints(pWnd->GetSize());
pWnd->Show( true );
html->SetRelatedStatusBar( 0 );
html->SetFocus();
return;
}
void ErrorDialog::OnHelp(wxCommandEvent &event)
{
if( dhelpURL.StartsWith(wxT("innerlink:")) )
{
ShowHtmlText(
this,
TitleText(dhelpURL.Mid( 10 ) ),
HelpText( dhelpURL.Mid( 10 )),
false,
true );
return;
}
OpenInDefaultBrowser( dhelpURL );
if(dClose)
EndModal(true);
}
void ShowErrorDialog(wxWindow *parent,
const wxString &dlogTitle,
const wxString &message,
const wxString &helpURL,
const bool Close)
{
ErrorDialog dlog(parent, dlogTitle, message, helpURL, Close);
dlog.CentreOnParent();
dlog.ShowModal();
}
void ShowModelessErrorDialog(wxWindow *parent,
const wxString &dlogTitle,
const wxString &message,
const wxString &helpURL,
const bool Close)
{
ErrorDialog *dlog = new ErrorDialog(parent, dlogTitle, message, helpURL, Close, false);
dlog->CentreOnParent();
dlog->Show();
// ANSWER-ME: Vigilant Sentry flags this method as not deleting dlog, so a mem leak.
// ANSWER-ME: This is unused. Delete it or are there plans for it?
}
void ShowAliasMissingDialog(AudacityProject *parent,
const wxString &dlogTitle,
const wxString &message,
const wxString &helpURL,
const bool Close)
{
ErrorDialog *dlog = new AliasedFileMissingDialog(parent, dlogTitle, message, helpURL, Close, false);
// Don't center because in many cases (effect, export, etc) there will be a progress bar in the center that blocks this.
// instead put it just above or on the top of the project.
wxPoint point;
point.x = 0;
point.y = parent ? parent->GetPosition().y - 200 : 100;
if (point.y < 100)
point.y = 100;
dlog->SetPosition(point);
dlog->CentreOnParent(wxHORIZONTAL);
dlog->Show();
// ANSWER-ME: Vigilant Sentry flags this method as not deleting dlog, so a mem leak.
// ANSWER-ME: Why is this modeless? Shouldn't it require user action before proceeding?
}
/// Mostly we use this so that we have the code for resizability
/// in one place. Other considerations like screen readers are also
/// handled by having the code in one place.
void ShowInfoDialog( wxWindow *parent,
const wxString &dlogTitle,
const wxString &shortMsg,
const wxString &message,
const int xSize, const int ySize)
{
wxDialog dlog(parent, wxID_ANY,
dlogTitle,
wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX /*| wxDEFAULT_FRAME_STYLE */);
ShuttleGui S(&dlog, eIsCreating);
S.StartVerticalLay(1);
{
S.AddTitle( shortMsg);
S.SetStyle( wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH | wxTE_RICH2 |
wxTE_AUTO_URL | wxTE_NOHIDESEL | wxHSCROLL );
S.AddTextWindow(message);
}
S.SetBorder( 0 );
S.StartHorizontalLay(wxALIGN_CENTER|wxALIGN_BOTTOM, 0);
S.AddStandardButtons(eOkButton);
S.EndHorizontalLay();
// Next three lines add a tiny dragger.
wxStatusBar * pBar = new wxStatusBar( &dlog );
pBar->SetSize( 18, 38);
S.AddWindow( pBar, wxALIGN_BOTTOM|wxALIGN_RIGHT );
S.EndVerticalLay();
// Smallest size is half default size. Seems reasonable.
dlog.SetMinSize( wxSize(xSize/2, ySize/2) );
dlog.SetSize( wxSize(xSize, ySize) );
dlog.Center();
dlog.ShowModal();
}
void ShowHelpDialog(wxWindow *parent,
const wxString &localFileName,
const wxString &remoteURL)
{
AudacityProject * pProj = GetActiveProject();
wxString HelpMode = wxT("Local");
if( pProj )
{
HelpMode = pProj->mHelpPref;
// these next lines are for legacy cfg files (pre 2.0) where we had different modes
if( (HelpMode == wxT("Standard")) || (HelpMode == wxT("InBrowser")) )
{
HelpMode = wxT("Local");
pProj->mHelpPref = HelpMode;
gPrefs->Write(wxT("/GUI/Help"), HelpMode);
gPrefs->Flush();
}
}
if( localFileName.Contains(wxT("Quick_Help")) )
// 'Quick_Help' is installed locally
OpenInDefaultBrowser( localFileName );
else if( (HelpMode == wxT("FromInternet")) && !remoteURL.IsEmpty() )
{
// Always go to remote URL. Use External browser.
OpenInDefaultBrowser( remoteURL );
}
else if( !wxFileExists( localFileName ))
{
// If you give an empty remote URL, you should have already ensured
// that the file exists!
wxASSERT( !remoteURL.IsEmpty() );
// I can't find it'.
// Use Built-in browser to suggest you use the remote url.
//use the remote link
wxString Text = HelpText( wxT("remotehelp") );
Text.Replace( wxT("*URL*"), remoteURL );
ShowHtmlText( parent, _("Help on the Internet"), Text );
}
else if( HelpMode == wxT("Local") )
{
// Local file, External browser
OpenInDefaultBrowser( wxString(wxT("file:"))+localFileName );
}
else
{
// Local file, Built-in browser
ShowHtmlText( parent, wxT(""), localFileName, true );
}
}
// Indentation settings for Vim and Emacs and unique identifier for Arch, a
// version control system. Please do not modify past this point.
//
// Local Variables:
// c-basic-offset: 3
// indent-tabs-mode: nil
// End:
//
// vim: et sts=3 sw=3
// arch-tag: b84d77e0-4375-43f0-868e-3130e18c14c8