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