]> git.saurik.com Git - wxWidgets.git/blob - src/generic/choicdgg.cpp
deselect the current selection when the user clicks outside of any item
[wxWidgets.git] / src / generic / choicdgg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/choicdgg.cpp
3 // Purpose: Choice dialogs
4 // Author: Julian Smart
5 // Modified by: 03.11.00: VZ to add wxArrayString and multiple sel functions
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) wxWidgets team
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #if wxUSE_CHOICEDLG
28
29 #ifndef WX_PRECOMP
30 #include <stdio.h>
31 #include "wx/utils.h"
32 #include "wx/dialog.h"
33 #include "wx/button.h"
34 #include "wx/listbox.h"
35 #include "wx/checklst.h"
36 #include "wx/stattext.h"
37 #include "wx/intl.h"
38 #include "wx/sizer.h"
39 #include "wx/arrstr.h"
40 #endif
41
42 #include "wx/statline.h"
43 #include "wx/generic/choicdgg.h"
44
45 // ----------------------------------------------------------------------------
46 // constants
47 // ----------------------------------------------------------------------------
48
49 #define wxID_LISTBOX 3000
50
51 // ---------------------------------------------------------------------------
52 // macros
53 // ---------------------------------------------------------------------------
54
55 /* Macro for avoiding #ifdefs when value have to be different depending on size of
56 device we display on - take it from something like wxDesktopPolicy in the future
57 */
58
59 #if defined(__SMARTPHONE__)
60 #define wxLARGESMALL(large,small) small
61 #else
62 #define wxLARGESMALL(large,small) large
63 #endif
64
65 // ----------------------------------------------------------------------------
66 // private functions
67 // ----------------------------------------------------------------------------
68
69 // convert wxArrayString into a wxString[] which must be delete[]d by caller
70 static int ConvertWXArrayToC(const wxArrayString& aChoices, wxString **choices);
71
72 // ============================================================================
73 // implementation
74 // ============================================================================
75
76 // ----------------------------------------------------------------------------
77 // helpers
78 // ----------------------------------------------------------------------------
79
80 int ConvertWXArrayToC(const wxArrayString& aChoices, wxString **choices)
81 {
82 int n = aChoices.GetCount();
83 *choices = new wxString[n];
84
85 for ( int i = 0; i < n; i++ )
86 {
87 (*choices)[i] = aChoices[i];
88 }
89
90 return n;
91 }
92
93 // ----------------------------------------------------------------------------
94 // wrapper functions
95 // ----------------------------------------------------------------------------
96
97 wxString wxGetSingleChoice( const wxString& message,
98 const wxString& caption,
99 int n, const wxString *choices,
100 wxWindow *parent,
101 int WXUNUSED(x), int WXUNUSED(y),
102 bool WXUNUSED(centre),
103 int WXUNUSED(width), int WXUNUSED(height) )
104 {
105 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
106 wxString choice;
107 if ( dialog.ShowModal() == wxID_OK )
108 choice = dialog.GetStringSelection();
109
110 return choice;
111 }
112
113 wxString wxGetSingleChoice( const wxString& message,
114 const wxString& caption,
115 const wxArrayString& aChoices,
116 wxWindow *parent,
117 int x, int y,
118 bool centre,
119 int width, int height)
120 {
121 wxString *choices;
122 int n = ConvertWXArrayToC(aChoices, &choices);
123 wxString res = wxGetSingleChoice(message, caption, n, choices, parent,
124 x, y, centre, width, height);
125 delete [] choices;
126
127 return res;
128 }
129
130 int wxGetSingleChoiceIndex( const wxString& message,
131 const wxString& caption,
132 int n, const wxString *choices,
133 wxWindow *parent,
134 int WXUNUSED(x), int WXUNUSED(y),
135 bool WXUNUSED(centre),
136 int WXUNUSED(width), int WXUNUSED(height) )
137 {
138 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
139 int choice;
140 if ( dialog.ShowModal() == wxID_OK )
141 choice = dialog.GetSelection();
142 else
143 choice = -1;
144
145 return choice;
146 }
147
148 int wxGetSingleChoiceIndex( const wxString& message,
149 const wxString& caption,
150 const wxArrayString& aChoices,
151 wxWindow *parent,
152 int x, int y,
153 bool centre,
154 int width, int height)
155 {
156 wxString *choices;
157 int n = ConvertWXArrayToC(aChoices, &choices);
158 int res = wxGetSingleChoiceIndex(message, caption, n, choices, parent,
159 x, y, centre, width, height);
160 delete [] choices;
161
162 return res;
163 }
164
165 void *wxGetSingleChoiceData( const wxString& message,
166 const wxString& caption,
167 int n, const wxString *choices,
168 void **client_data,
169 wxWindow *parent,
170 int WXUNUSED(x), int WXUNUSED(y),
171 bool WXUNUSED(centre),
172 int WXUNUSED(width), int WXUNUSED(height) )
173 {
174 wxSingleChoiceDialog dialog(parent, message, caption, n, choices,
175 (char **)client_data);
176 void *data;
177 if ( dialog.ShowModal() == wxID_OK )
178 data = dialog.GetSelectionClientData();
179 else
180 data = NULL;
181
182 return data;
183 }
184
185 void *wxGetSingleChoiceData( const wxString& message,
186 const wxString& caption,
187 const wxArrayString& aChoices,
188 void **client_data,
189 wxWindow *parent,
190 int x, int y,
191 bool centre,
192 int width, int height)
193 {
194 wxString *choices;
195 int n = ConvertWXArrayToC(aChoices, &choices);
196 void *res = wxGetSingleChoiceData(message, caption, n, choices,
197 client_data, parent,
198 x, y, centre, width, height);
199 delete [] choices;
200
201 return res;
202 }
203
204 size_t wxGetMultipleChoices(wxArrayInt& selections,
205 const wxString& message,
206 const wxString& caption,
207 int n, const wxString *choices,
208 wxWindow *parent,
209 int WXUNUSED(x), int WXUNUSED(y),
210 bool WXUNUSED(centre),
211 int WXUNUSED(width), int WXUNUSED(height))
212 {
213 wxMultiChoiceDialog dialog(parent, message, caption, n, choices);
214
215 // call this even if selections array is empty and this then (correctly)
216 // deselects the first item which is selected by default
217 dialog.SetSelections(selections);
218
219 if ( dialog.ShowModal() == wxID_OK )
220 selections = dialog.GetSelections();
221 else
222 selections.Empty();
223
224 return selections.GetCount();
225 }
226
227 size_t wxGetMultipleChoices(wxArrayInt& selections,
228 const wxString& message,
229 const wxString& caption,
230 const wxArrayString& aChoices,
231 wxWindow *parent,
232 int x, int y,
233 bool centre,
234 int width, int height)
235 {
236 wxString *choices;
237 int n = ConvertWXArrayToC(aChoices, &choices);
238 size_t res = wxGetMultipleChoices(selections, message, caption,
239 n, choices, parent,
240 x, y, centre, width, height);
241 delete [] choices;
242
243 return res;
244 }
245
246 // ----------------------------------------------------------------------------
247 // wxAnyChoiceDialog
248 // ----------------------------------------------------------------------------
249
250 bool wxAnyChoiceDialog::Create(wxWindow *parent,
251 const wxString& message,
252 const wxString& caption,
253 int n, const wxString *choices,
254 long styleDlg,
255 const wxPoint& pos,
256 long styleLbox)
257 {
258 #if defined(__SMARTPHONE__) || defined(__POCKETPC__)
259 styleDlg &= ~wxBORDER_MASK;
260 styleDlg &= ~wxRESIZE_BORDER;
261 styleDlg &= ~wxCAPTION;
262 #endif
263 #ifdef __WXMAC__
264 if ( !wxDialog::Create(parent, wxID_ANY, caption, pos, wxDefaultSize, styleDlg & (~wxCANCEL) ) )
265 return false;
266 #else
267 if ( !wxDialog::Create(parent, wxID_ANY, caption, pos, wxDefaultSize, styleDlg) )
268 return false;
269 #endif
270
271 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
272
273 // 1) text message
274 #ifdef __WXMAC__
275 // align text and list at least on mac
276 topsizer->Add( CreateTextSizer( message ), 0, wxALL, wxLARGESMALL(15,0) );
277 #else
278 topsizer->Add( CreateTextSizer( message ), 0, wxALL, wxLARGESMALL(10,0) );
279 #endif
280 // 2) list box
281 m_listbox = CreateList(n,choices,styleLbox);
282
283 if ( n > 0 )
284 m_listbox->SetSelection(0);
285
286 topsizer->Add( m_listbox, 1, wxEXPAND|wxLEFT|wxRIGHT, wxLARGESMALL(15,0) );
287
288 // 3) buttons if any
289 wxSizer *buttonSizer = CreateButtonSizer( styleDlg & ButtonSizerFlags , true, wxLARGESMALL(10,0) );
290 if(buttonSizer->GetChildren().GetCount() > 0 )
291 {
292 topsizer->Add( buttonSizer, 0, wxEXPAND | wxALL, wxLARGESMALL(10,0) );
293 }
294 else
295 {
296 topsizer->AddSpacer( wxLARGESMALL(15,0) );
297 delete buttonSizer;
298 }
299
300 SetSizer( topsizer );
301
302 #if !defined(__SMARTPHONE__) && !defined(__POCKETPC__)
303 topsizer->SetSizeHints( this );
304 topsizer->Fit( this );
305
306 if ( styleDlg & wxCENTRE )
307 Centre(wxBOTH);
308 #endif
309
310 m_listbox->SetFocus();
311
312 return true;
313 }
314
315 bool wxAnyChoiceDialog::Create(wxWindow *parent,
316 const wxString& message,
317 const wxString& caption,
318 const wxArrayString& choices,
319 long styleDlg,
320 const wxPoint& pos,
321 long styleLbox)
322 {
323 wxCArrayString chs(choices);
324 return Create(parent, message, caption, chs.GetCount(), chs.GetStrings(),
325 styleDlg, pos, styleLbox);
326 }
327
328 wxListBoxBase *wxAnyChoiceDialog::CreateList(int n, const wxString *choices, long styleLbox)
329 {
330 return new wxListBox( this, wxID_LISTBOX,
331 wxDefaultPosition, wxDefaultSize,
332 n, choices,
333 styleLbox );
334 }
335
336 // ----------------------------------------------------------------------------
337 // wxSingleChoiceDialog
338 // ----------------------------------------------------------------------------
339
340 BEGIN_EVENT_TABLE(wxSingleChoiceDialog, wxDialog)
341 EVT_BUTTON(wxID_OK, wxSingleChoiceDialog::OnOK)
342 #ifndef __SMARTPHONE__
343 EVT_LISTBOX_DCLICK(wxID_LISTBOX, wxSingleChoiceDialog::OnListBoxDClick)
344 #endif
345 #ifdef __WXWINCE__
346 EVT_JOY_BUTTON_DOWN(wxSingleChoiceDialog::OnJoystickButtonDown)
347 #endif
348 END_EVENT_TABLE()
349
350 IMPLEMENT_DYNAMIC_CLASS(wxSingleChoiceDialog, wxDialog)
351
352 wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
353 const wxString& message,
354 const wxString& caption,
355 int n,
356 const wxString *choices,
357 char **clientData,
358 long style,
359 const wxPoint& WXUNUSED(pos))
360 {
361 Create(parent, message, caption, n, choices, clientData, style);
362 }
363
364 wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
365 const wxString& message,
366 const wxString& caption,
367 const wxArrayString& choices,
368 char **clientData,
369 long style,
370 const wxPoint& WXUNUSED(pos))
371 {
372 Create(parent, message, caption, choices, clientData, style);
373 }
374
375 bool wxSingleChoiceDialog::Create( wxWindow *parent,
376 const wxString& message,
377 const wxString& caption,
378 int n,
379 const wxString *choices,
380 char **clientData,
381 long style,
382 const wxPoint& pos )
383 {
384 if ( !wxAnyChoiceDialog::Create(parent, message, caption,
385 n, choices,
386 style, pos) )
387 return false;
388
389 m_selection = n > 0 ? 0 : -1;
390
391 if (clientData)
392 {
393 for (int i = 0; i < n; i++)
394 m_listbox->SetClientData(i, clientData[i]);
395 }
396
397 return true;
398 }
399
400 bool wxSingleChoiceDialog::Create( wxWindow *parent,
401 const wxString& message,
402 const wxString& caption,
403 const wxArrayString& choices,
404 char **clientData,
405 long style,
406 const wxPoint& pos )
407 {
408 wxCArrayString chs(choices);
409 return Create( parent, message, caption, chs.GetCount(), chs.GetStrings(),
410 clientData, style, pos );
411 }
412
413 // Set the selection
414 void wxSingleChoiceDialog::SetSelection(int sel)
415 {
416 m_listbox->SetSelection(sel);
417 m_selection = sel;
418 }
419
420 void wxSingleChoiceDialog::OnOK(wxCommandEvent& WXUNUSED(event))
421 {
422 DoChoice();
423 }
424
425 #ifndef __SMARTPHONE__
426 void wxSingleChoiceDialog::OnListBoxDClick(wxCommandEvent& WXUNUSED(event))
427 {
428 DoChoice();
429 }
430 #endif
431
432 #ifdef __WXWINCE__
433 void wxSingleChoiceDialog::OnJoystickButtonDown(wxJoystickEvent& WXUNUSED(event))
434 {
435 DoChoice();
436 }
437 #endif
438
439 void wxSingleChoiceDialog::DoChoice()
440 {
441 m_selection = m_listbox->GetSelection();
442 m_stringSelection = m_listbox->GetStringSelection();
443
444 if ( m_listbox->HasClientUntypedData() )
445 SetClientData(m_listbox->GetClientData(m_selection));
446
447 EndModal(wxID_OK);
448 }
449
450 // ----------------------------------------------------------------------------
451 // wxMultiChoiceDialog
452 // ----------------------------------------------------------------------------
453
454 IMPLEMENT_DYNAMIC_CLASS(wxMultiChoiceDialog, wxDialog)
455
456 bool wxMultiChoiceDialog::Create( wxWindow *parent,
457 const wxString& message,
458 const wxString& caption,
459 int n,
460 const wxString *choices,
461 long style,
462 const wxPoint& pos )
463 {
464 if ( !wxAnyChoiceDialog::Create(parent, message, caption,
465 n, choices,
466 style, pos,
467 wxLB_ALWAYS_SB | wxLB_EXTENDED) )
468 return false;
469
470 return true;
471 }
472
473 bool wxMultiChoiceDialog::Create( wxWindow *parent,
474 const wxString& message,
475 const wxString& caption,
476 const wxArrayString& choices,
477 long style,
478 const wxPoint& pos )
479 {
480 wxCArrayString chs(choices);
481 return Create( parent, message, caption, chs.GetCount(),
482 chs.GetStrings(), style, pos );
483 }
484
485 void wxMultiChoiceDialog::SetSelections(const wxArrayInt& selections)
486 {
487 // first clear all currently selected items
488 size_t n,
489 count = m_listbox->GetCount();
490 for ( n = 0; n < count; ++n )
491 {
492 m_listbox->Deselect(n);
493 }
494
495 // now select the ones which should be selected
496 count = selections.GetCount();
497 for ( n = 0; n < count; n++ )
498 {
499 m_listbox->Select(selections[n]);
500 }
501 }
502
503 bool wxMultiChoiceDialog::TransferDataFromWindow()
504 {
505 m_selections.Empty();
506 size_t count = m_listbox->GetCount();
507 for ( size_t n = 0; n < count; n++ )
508 {
509 if ( m_listbox->IsSelected(n) )
510 m_selections.Add(n);
511 }
512
513 return true;
514 }
515
516 #if wxUSE_CHECKLISTBOX
517
518 wxListBoxBase *wxMultiChoiceDialog::CreateList(int n, const wxString *choices, long styleLbox)
519 {
520 return new wxCheckListBox( this, wxID_LISTBOX,
521 wxDefaultPosition, wxDefaultSize,
522 n, choices,
523 styleLbox );
524 }
525
526 #endif // wxUSE_CHECKLISTBOX
527
528 #endif // wxUSE_CHOICEDLG