1 /**********************************************************************
2 
3    Audacity: A Digital Audio Editor
4    Audacity(R) is copyright (c) 1999-2010 Audacity Team.
5    License: GPL v2.  See License.txt.
6 
7    MultiDialog.h
8 
9    Monty
10    Vaughan Johnson
11 
12 *******************************************************************//**
13 
14 \class MultiDialog
15 \brief A multi purpose dialog, mainly used to show lists of orphaned or
16 damaged block files.  It is a good alternative to having a dialog pop up
17 for each problem encountered, since there can be many orphans.
18 
19 *//*******************************************************************/
20 
21 
22 #include "MultiDialog.h"
23 
24 #include "../ShuttleGui.h"
25 
26 #include <wx/app.h>
27 #include <wx/button.h>
28 #include <wx/dialog.h>
29 #include <wx/intl.h>
30 #include <wx/icon.h>
31 #include <wx/sizer.h>
32 #include <wx/stattext.h>
33 #include <wx/statbmp.h>
34 #include <wx/artprov.h>
35 #include <wx/radiobox.h>
36 #include <wx/bmpbuttn.h>
37 
38 
39 #include "wxPanelWrapper.h"
40 #include "../LogWindow.h"
41 #include "Theme.h"
42 #include "AllThemeResources.h"
43 #include "../widgets/HelpSystem.h"
44 
45 class MultiDialog final : public wxDialogWrapper
46 {
47 public:
48    MultiDialog(wxWindow * pParent,
49                const TranslatableString &message,
50                const TranslatableString &title,
51                const TranslatableStrings &buttons,
52                const wxString &helpPage,
53                const TranslatableString &boxMsg, bool log);
~MultiDialog()54    ~MultiDialog() {};
55 
56 private:
57    void OnOK( wxCommandEvent &event );
58    void OnShowLog(wxCommandEvent& event);
59    void OnHelp(wxCommandEvent& event);
60 
61    wxRadioBox* mRadioBox;
62    ManualPageID mHelpPage;
63 
64    DECLARE_EVENT_TABLE()
65 };
66 
67 #define ID_SHOW_LOG_BUTTON 3333
68 
BEGIN_EVENT_TABLE(MultiDialog,wxDialogWrapper)69 BEGIN_EVENT_TABLE(MultiDialog, wxDialogWrapper)
70    EVT_BUTTON( wxID_OK, MultiDialog::OnOK )
71    EVT_BUTTON(ID_SHOW_LOG_BUTTON, MultiDialog::OnShowLog)
72    EVT_BUTTON(wxID_HELP, MultiDialog::OnHelp)
73 END_EVENT_TABLE()
74 
75 MultiDialog::MultiDialog(wxWindow * pParent,
76                          const TranslatableString &message,
77                          const TranslatableString &title,
78                          const TranslatableStrings &buttons,
79                          const wxString &helpPage,
80                          const TranslatableString &boxMsg,
81                          bool log
82    )
83    : wxDialogWrapper(pParent, wxID_ANY, title,
84                wxDefaultPosition, wxDefaultSize,
85                wxCAPTION), // not wxDEFAULT_DIALOG_STYLE because we don't want wxCLOSE_BOX and wxSYSTEM_MENU
86     mHelpPage( helpPage)
87 {
88    SetName();
89 
90    ShuttleGui S{ this, eIsCreating };
91    {
92       S.SetBorder( 5 );
93       S.StartVerticalLay( 0 );
94       {
95          S.StartHorizontalLay(wxALIGN_LEFT | wxALL, 0);
96          {
97             S.SetBorder( 0 );
98             wxBitmap bitmap = wxArtProvider::GetIcon(wxART_WARNING,
99                wxART_MESSAGE_BOX);
100             auto icon = safenew wxStaticBitmap(S.GetParent(), -1, bitmap);
101             S
102                .Position( wxCENTER )
103                .AddWindow( icon );
104 
105             S.SetBorder( 15 );
106             S.Prop(1).AddVariableText( message, false, wxCENTER | wxLEFT );
107          }
108          S.EndHorizontalLay();
109 
110          const auto buttonLabels = transform_container<wxArrayStringEx>(
111             buttons, std::mem_fn( &TranslatableString::Translation ) );
112 
113          const auto count = buttons.size();
114 
115          const auto boxStr = boxMsg.Translation();
116 
117          S.SetBorder( 5 );
118 
119          mRadioBox = safenew wxRadioBox(S.GetParent(), -1,
120             boxStr,
121             wxDefaultPosition, wxDefaultSize,
122             count, count ? &buttonLabels[0] : nullptr,
123             1, wxRA_SPECIFY_COLS);
124          mRadioBox->SetSelection(0);
125          S.Prop( 1 )
126             .Name( boxMsg )
127             .Position(wxEXPAND | wxALL)
128             .AddWindow( mRadioBox );
129 
130 
131          S.StartHorizontalLay(wxALIGN_CENTER | wxALL, 0);
132          {
133             if (log)
134             {
135                S
136                   .Id(ID_SHOW_LOG_BUTTON)
137                   .AddButton(
138                      XXO("Show Log for Details"), wxALIGN_LEFT | wxALL,
139                      // set default to encourage user to look at files.
140                      true);
141 
142                S.AddSpace(40, 0);
143             }
144 
145             auto pButton = S.Id(wxID_OK)
146                .AddButton(XXO("OK"), wxALIGN_CENTER, !log);
147 
148             if (!mHelpPage.empty()) {
149                auto pHelpBtn = S.Id(wxID_HELP)
150                   .AddBitmapButton(theTheme.Bitmap(bmpHelpIcon), wxALIGN_CENTER, false);
151                pHelpBtn->SetToolTip(XO("Help").Translation());
152                pHelpBtn->SetLabel(XO("Help").Translation());       // for screen readers
153             }
154          }
155          S.EndHorizontalLay();
156       }
157       S.EndVerticalLay();
158    }
159 
160    SetAutoLayout(true);
161    GetSizer()->Fit(this);
162    GetSizer()->SetSizeHints(this);
163 }
164 
OnOK(wxCommandEvent & WXUNUSED (event))165 void MultiDialog::OnOK(wxCommandEvent & WXUNUSED(event))
166 {
167    EndModal(mRadioBox->GetSelection());
168 }
169 
OnShowLog(wxCommandEvent & WXUNUSED (event))170 void MultiDialog::OnShowLog(wxCommandEvent & WXUNUSED(event))
171 {
172    LogWindow::Show();
173 }
174 
OnHelp(wxCommandEvent & WXUNUSED (event))175 void MultiDialog::OnHelp(wxCommandEvent & WXUNUSED(event))
176 {
177    HelpSystem::ShowHelp(FindWindow(wxID_HELP), mHelpPage, true);
178 }
179 
ShowMultiDialog(const TranslatableString & message,const TranslatableString & title,const TranslatableStrings & buttons,const wxString & helpPage,const TranslatableString & boxMsg,bool log)180 int ShowMultiDialog(const TranslatableString &message,
181    const TranslatableString &title,
182    const TranslatableStrings &buttons,
183    const wxString &helpPage,
184    const TranslatableString &boxMsg, bool log)
185 {
186    wxWindow * pParent = wxTheApp->GetTopWindow();
187 
188    // We want a parent we can display over, so don't make it a parent if top
189    // window is a STAY_ON_TOP.
190    if (pParent) {
191       if ((pParent->GetWindowStyle() & wxSTAY_ON_TOP) == wxSTAY_ON_TOP)
192          pParent = NULL;
193    }
194    MultiDialog dlog(pParent,
195       message, title, buttons, helpPage, boxMsg, log);
196    // If dialog does not have a parent, cannot be centred on it.
197    if (pParent != NULL)
198       dlog.CentreOnParent();
199    else {
200       dlog.CenterOnScreen();
201       // and after centring move the dialog left by the size of the dialog.
202       // Likely to help if we have the splash screen visible, or if
203       // we're spanning two equally sized monitors.
204       // Unlikely to make things worse.
205       wxSize Size = dlog.GetSize();
206       Size.SetHeight( 10 );
207       wxPoint Pos = dlog.GetPosition() -Size;
208       dlog.Move(Pos);
209    }
210    return dlog.ShowModal();
211 }
212 
DefaultMultiDialogMessage()213 const TranslatableString &DefaultMultiDialogMessage()
214 {
215    static auto result = XO("Please select an action");
216    return result;
217 }
218