/[pcsx2_0.9.7]/trunk/pcsx2/gui/Dialogs/ConfirmationDialogs.cpp
ViewVC logotype

Contents of /trunk/pcsx2/gui/Dialogs/ConfirmationDialogs.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 1 month ago) by william
File size: 8943 byte(s)
re-commit (had local access denied errors when committing)
1 /* PCSX2 - PS2 Emulator for PCs
2 * Copyright (C) 2002-2010 PCSX2 Dev Team
3 *
4 * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5 * of the GNU Lesser General Public License as published by the Free Software Found-
6 * ation, either version 3 of the License, or (at your option) any later version.
7 *
8 * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10 * PURPOSE. See the GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License along with PCSX2.
13 * If not, see <http://www.gnu.org/licenses/>.
14 */
15
16 #include "PrecompiledHeader.h"
17 #include "System.h"
18 #include "App.h"
19
20 #include "ModalPopups.h"
21 #include "Utilities/StringHelpers.h"
22
23 using namespace pxSizerFlags;
24
25 bool MsgButtons::Allows( wxWindowID id ) const
26 {
27 switch( id )
28 {
29 case wxID_OK: return HasOK();
30 case wxID_CANCEL: return HasCancel();
31 case wxID_APPLY: return HasApply();
32 case wxID_YES: return HasYes();
33 case wxID_NO: return HasNo();
34 case wxID_YESTOALL: return HasYes() && AllowsToAll();
35 case wxID_NOTOALL: return HasNo() && AllowsToAll();
36
37 case wxID_ABORT: return HasAbort();
38 case wxID_RETRY: return HasRetry();
39
40 // [TODO] : maybe add in an Ignore All?
41 case wxID_IGNORE: return HasIgnore();
42
43 case wxID_RESET: return HasReset();
44 case wxID_CLOSE: return HasClose();
45 }
46
47 if (id <= wxID_LOWEST)
48 return HasCustom();
49
50 return false;
51 }
52
53 static wxString ResultToString( int result, const MsgButtons& buttons )
54 {
55 switch( result )
56 {
57 case wxID_OK: return L"ok";
58 case wxID_CANCEL: return L"cancel";
59 case wxID_APPLY: return L"apply";
60 case wxID_YES: return L"yes";
61 case wxID_NO: return L"no";
62 case wxID_YESTOALL: return L"yestoall";
63 case wxID_NOTOALL: return L"notoall";
64
65 case wxID_ABORT: return L"abort";
66 case wxID_RETRY: return L"retry";
67
68 // [TODO] : maybe add in an Ignore All?
69 case wxID_IGNORE: return L"ignore";
70
71 case wxID_RESET: return L"reset";
72 case wxID_CLOSE: return L"close";
73 }
74
75 if (result <= wxID_LOWEST)
76 return buttons.GetCustomLabelId();
77
78 return wxEmptyString;
79 }
80
81 static wxWindowID ParseThatResult( const wxString& src, const MsgButtons& validTypes )
82 {
83 if( !pxAssert( !src.IsEmpty() ) ) return wxID_ANY;
84
85 static const wxWindowID retvals[] =
86 {
87 wxID_OK, wxID_CANCEL, wxID_APPLY,
88 wxID_YES, wxID_NO,
89 wxID_YESTOALL, wxID_NOTOALL,
90
91 wxID_ABORT, wxID_RETRY, wxID_IGNORE,
92
93 wxID_RESET,
94 wxID_ANY,
95 };
96
97 for( uint i=0; i<ArraySize( retvals ); ++i )
98 {
99 if( (validTypes.Allows( retvals[i] )) && (src == ResultToString(retvals[i], validTypes)) )
100 return retvals[i];
101 }
102
103 return wxID_NONE;
104 }
105
106 static bool pxTrySetFocus( wxWindow& parent, wxWindowID id )
107 {
108 if( wxWindow* found = parent.FindWindowById( id ) )
109 {
110 found->SetFocus();
111 return true;
112 }
113
114 return false;
115 }
116
117 static bool pxTrySetFocus( wxWindow* parent, wxWindowID id )
118 {
119 if( parent == NULL ) return false;
120 pxTrySetFocus( *parent, id );
121 }
122
123 void MsgButtons::SetBestFocus( wxWindow& dialog ) const
124 {
125 if( HasOK() && pxTrySetFocus( dialog, wxID_OK ) ) return;
126 if( HasNo() && pxTrySetFocus( dialog, wxID_NO ) ) return;
127 if( HasClose() && pxTrySetFocus( dialog, wxID_CLOSE ) ) return;
128 if( HasRetry() && pxTrySetFocus( dialog, wxID_RETRY ) ) return;
129
130 // Other confirmational types of buttons must be explicitly focused by the user or
131 // by an implementing dialog. We won't do it here implicitly because accidental
132 // "on focus" typed keys could invoke really unwanted actions.
133
134 // (typically close/ok/retry/etc. aren't so bad that accidental clicking does terrible things)
135 }
136
137 void MsgButtons::SetBestFocus( wxWindow* dialog ) const
138 {
139 if( dialog == NULL ) return;
140 SetBestFocus( *dialog );
141 }
142
143
144 wxWindowID pxIssueConfirmation( wxDialogWithHelpers& confirmDlg, const MsgButtons& buttons )
145 {
146 if( confirmDlg.GetMinWidth() <= 0 ) confirmDlg.SetMinWidth( 400 );
147
148 confirmDlg += new ModalButtonPanel( &confirmDlg, buttons ) | pxCenter.Border( wxTOP, 8 );
149 buttons.SetBestFocus( confirmDlg );
150 return confirmDlg.ShowModal();
151 }
152
153
154 wxWindowID pxIssueConfirmation( wxDialogWithHelpers& confirmDlg, const MsgButtons& buttons, const wxString& disablerKey )
155 {
156 wxConfigBase* cfg = GetAppConfig();
157
158 if( cfg != NULL )
159 {
160 cfg->SetPath( L"/PopupDisablers" );
161 bool recdef = cfg->IsRecordingDefaults();
162 cfg->SetRecordDefaults( false );
163
164 wxString result = cfg->Read( disablerKey, L"enabled" );
165
166 cfg->SetRecordDefaults( recdef );
167 cfg->SetPath( L"/" );
168
169 result.MakeLower();
170 wxArrayString split;
171 SplitString( split, result, L"," );
172
173 // if only one param (no comma!?) then assume the entry is invalid and force a
174 // re-display of the dialog.
175
176 if( split.Count() > 1 )
177 {
178 result = split[0];
179 if( result == L"disabled" || result == L"off" || result == L"no" )
180 {
181 int result = ParseThatResult( split[1], buttons );
182 if( result != wxID_ANY ) return result;
183 }
184 }
185 }
186
187 pxCheckBox* DisablerCtrl = NULL;
188 if( cfg != NULL )
189 {
190 // Add an option that allows the user to disable this popup from showing again.
191 // (and if the config hasn't been initialized yet, then assume the dialog as non-disablable)
192
193 DisablerCtrl = new pxCheckBox(&confirmDlg, _("Do not show this dialog again."));
194
195 confirmDlg += 8;
196 confirmDlg += DisablerCtrl | wxSF.Centre();
197
198 if( buttons != MsgButtons().OK() )
199 pxSetToolTip(DisablerCtrl, _("Disables this popup and whatever response you select here will be automatically used from now on."));
200 else
201 pxSetToolTip(DisablerCtrl, _("The popup will not be shown again. This setting can be undone from the settings panels."));
202
203 }
204
205 int modalResult = pxIssueConfirmation( confirmDlg, buttons );
206
207 if( cfg != NULL )
208 {
209 wxString cfgResult = ResultToString( modalResult, buttons );
210 if( DisablerCtrl->IsChecked() && !cfgResult.IsEmpty() )
211 {
212 cfg->SetPath( L"/PopupDisablers" );
213 cfg->Write( disablerKey, L"disabled," + cfgResult );
214 cfg->SetPath( L"/" );
215 cfg->Flush();
216 }
217 }
218 return modalResult;
219 }
220
221 ModalButtonPanel::ModalButtonPanel( wxWindow* parent, const MsgButtons& buttons )
222 : wxPanelWithHelpers( parent, wxHORIZONTAL )
223 {
224 // Populate the Button Sizer.
225 // We prefer this over the built-in wxWidgets ButtonSizer stuff used for other types of
226 // dialogs because we offer more button types, and we don't want the MSW default behavior
227 // of right-justified buttons.
228
229 if( buttons.HasCustom() )
230 AddCustomButton( pxID_CUSTOM, buttons.GetCustomLabel() );
231
232 // Order of wxID_RESET and custom button have been picked fairly arbitrarily, since there's
233 // no standard governing those.
234
235 #ifdef __WXGTK__
236 // GTK+ / Linux inverts OK/CANCEL order -- cancel / no first, OK / Yes later. >_<
237 if( buttons.HasCancel() )
238 AddActionButton( wxID_CANCEL );
239
240 if( buttons.HasNo() )
241 {
242 AddActionButton( wxID_NO );
243 if( buttons.AllowsToAll() ) AddActionButton( wxID_NOTOALL );
244 }
245
246 if( buttons.HasIgnore() )
247 AddCustomButton( wxID_IGNORE, _("Ignore") );
248
249 if( buttons.HasOK() || buttons.HasYes() ) // Extra space between Affirm and Cancel Actions
250 GetSizer()->Add(0, 0, 1, wxEXPAND, 0);
251 #endif
252
253 if( buttons.HasOK() )
254 AddActionButton( wxID_OK );
255
256 if( buttons.HasYes() )
257 {
258 AddActionButton( wxID_YES );
259 if( buttons.AllowsToAll() )
260 AddActionButton( wxID_YESTOALL );
261 }
262
263 #ifdef __WXGTK__
264 if( buttons.HasRetry() )
265 AddActionButton( wxID_RETRY );
266
267 if( buttons.HasAbort() )
268 AddActionButton( wxID_ABORT );
269 #else
270 if( buttons.HasAbort() )
271 AddActionButton( wxID_ABORT );
272
273 if( buttons.HasRetry() )
274 AddActionButton( wxID_RETRY );
275 #endif
276
277 if( buttons.HasReset() )
278 AddCustomButton( wxID_RESET, _("Reset") );
279
280 if( buttons.HasClose() )
281 AddActionButton( wxID_CLOSE );
282
283 #ifndef __WXGTK__
284 if( buttons.HasNo() )
285 {
286 AddActionButton( wxID_NO );
287 if( buttons.AllowsToAll() )
288 AddActionButton( wxID_NOTOALL );
289 }
290
291 if( buttons.HasIgnore() )
292 AddCustomButton( wxID_IGNORE, _("Ignore") );
293
294 if( buttons.HasCancel() )
295 AddActionButton( wxID_CANCEL );
296 #endif
297 }
298
299 void ModalButtonPanel::OnActionButtonClicked( wxCommandEvent& evt )
300 {
301 evt.Skip();
302 wxWindow* toplevel = wxGetTopLevelParent( this );
303 if( wxDialog* dialog = wxDynamicCast( toplevel, wxDialog ) )
304 dialog->EndModal( evt.GetId() );
305 }
306
307 void ModalButtonPanel::AddCustomButton( wxWindowID id, const wxString& label )
308 {
309 *this += new wxButton( this, id, label ) | StdButton().Proportion(6);
310 Connect( id, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ModalButtonPanel::OnActionButtonClicked ) );
311 }
312
313 // This is for buttons that are defined internally by wxWidgets, such as wxID_CANCEL, wxID_ABORT, etc.
314 // wxWidgets will assign the labels and stuff for us. :D
315 void ModalButtonPanel::AddActionButton( wxWindowID id )
316 {
317 *this += new wxButton( this, id ) | StdButton().Proportion(6);
318 Connect( id, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ModalButtonPanel::OnActionButtonClicked ) );
319 }
320

  ViewVC Help
Powered by ViewVC 1.1.22