/********************************************************************** 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 #include #include #include #include #include #include #include #include #include #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