replace wxGetMultipleChoices() with wxGetSelectedChoices() which allows to distinguis...
[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/settings.h"
44 #include "wx/generic/choicdgg.h"
45
46 // ----------------------------------------------------------------------------
47 // constants
48 // ----------------------------------------------------------------------------
49
50 #define wxID_LISTBOX 3000
51
52 // ----------------------------------------------------------------------------
53 // private functions
54 // ----------------------------------------------------------------------------
55
56 // convert wxArrayString into a wxString[] which must be delete[]d by caller
57 static int ConvertWXArrayToC(const wxArrayString& aChoices, wxString **choices);
58
59 // ============================================================================
60 // implementation
61 // ============================================================================
62
63 // ----------------------------------------------------------------------------
64 // helpers
65 // ----------------------------------------------------------------------------
66
67 int ConvertWXArrayToC(const wxArrayString& aChoices, wxString **choices)
68 {
69 int n = aChoices.GetCount();
70 *choices = new wxString[n];
71
72 for ( int i = 0; i < n; i++ )
73 {
74 (*choices)[i] = aChoices[i];
75 }
76
77 return n;
78 }
79
80 // ----------------------------------------------------------------------------
81 // wrapper functions
82 // ----------------------------------------------------------------------------
83
84 wxString wxGetSingleChoice( const wxString& message,
85 const wxString& caption,
86 int n, const wxString *choices,
87 wxWindow *parent,
88 int WXUNUSED(x), int WXUNUSED(y),
89 bool WXUNUSED(centre),
90 int WXUNUSED(width), int WXUNUSED(height) )
91 {
92 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
93 wxString choice;
94 if ( dialog.ShowModal() == wxID_OK )
95 choice = dialog.GetStringSelection();
96
97 return choice;
98 }
99
100 wxString wxGetSingleChoice( const wxString& message,
101 const wxString& caption,
102 const wxArrayString& aChoices,
103 wxWindow *parent,
104 int x, int y,
105 bool centre,
106 int width, int height)
107 {
108 wxString *choices;
109 int n = ConvertWXArrayToC(aChoices, &choices);
110 wxString res = wxGetSingleChoice(message, caption, n, choices, parent,
111 x, y, centre, width, height);
112 delete [] choices;
113
114 return res;
115 }
116
117 int wxGetSingleChoiceIndex( const wxString& message,
118 const wxString& caption,
119 int n, const wxString *choices,
120 wxWindow *parent,
121 int WXUNUSED(x), int WXUNUSED(y),
122 bool WXUNUSED(centre),
123 int WXUNUSED(width), int WXUNUSED(height) )
124 {
125 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
126 int choice;
127 if ( dialog.ShowModal() == wxID_OK )
128 choice = dialog.GetSelection();
129 else
130 choice = -1;
131
132 return choice;
133 }
134
135 int wxGetSingleChoiceIndex( const wxString& message,
136 const wxString& caption,
137 const wxArrayString& aChoices,
138 wxWindow *parent,
139 int x, int y,
140 bool centre,
141 int width, int height)
142 {
143 wxString *choices;
144 int n = ConvertWXArrayToC(aChoices, &choices);
145 int res = wxGetSingleChoiceIndex(message, caption, n, choices, parent,
146 x, y, centre, width, height);
147 delete [] choices;
148
149 return res;
150 }
151
152 void *wxGetSingleChoiceData( const wxString& message,
153 const wxString& caption,
154 int n, const wxString *choices,
155 void **client_data,
156 wxWindow *parent,
157 int WXUNUSED(x), int WXUNUSED(y),
158 bool WXUNUSED(centre),
159 int WXUNUSED(width), int WXUNUSED(height) )
160 {
161 wxSingleChoiceDialog dialog(parent, message, caption, n, choices,
162 (char **)client_data);
163 void *data;
164 if ( dialog.ShowModal() == wxID_OK )
165 data = dialog.GetSelectionClientData();
166 else
167 data = NULL;
168
169 return data;
170 }
171
172 void *wxGetSingleChoiceData( const wxString& message,
173 const wxString& caption,
174 const wxArrayString& aChoices,
175 void **client_data,
176 wxWindow *parent,
177 int x, int y,
178 bool centre,
179 int width, int height)
180 {
181 wxString *choices;
182 int n = ConvertWXArrayToC(aChoices, &choices);
183 void *res = wxGetSingleChoiceData(message, caption, n, choices,
184 client_data, parent,
185 x, y, centre, width, height);
186 delete [] choices;
187
188 return res;
189 }
190
191 int wxGetSelectedChoices(wxArrayInt& selections,
192 const wxString& message,
193 const wxString& caption,
194 int n, const wxString *choices,
195 wxWindow *parent,
196 int WXUNUSED(x), int WXUNUSED(y),
197 bool WXUNUSED(centre),
198 int WXUNUSED(width), int WXUNUSED(height))
199 {
200 wxMultiChoiceDialog dialog(parent, message, caption, n, choices);
201
202 // call this even if selections array is empty and this then (correctly)
203 // deselects the first item which is selected by default
204 dialog.SetSelections(selections);
205
206 if ( dialog.ShowModal() != wxID_OK )
207 {
208 // NB: intentionally do not clear the selections array here, the caller
209 // might want to preserve its original contents if the dialog was
210 // cancelled
211 return -1;
212 }
213
214 selections = dialog.GetSelections();
215 return selections.GetCount();
216 }
217
218 int wxGetSelectedChoices(wxArrayInt& selections,
219 const wxString& message,
220 const wxString& caption,
221 const wxArrayString& aChoices,
222 wxWindow *parent,
223 int x, int y,
224 bool centre,
225 int width, int height)
226 {
227 wxString *choices;
228 int n = ConvertWXArrayToC(aChoices, &choices);
229 int res = wxGetSelectedChoices(selections, message, caption,
230 n, choices, parent,
231 x, y, centre, width, height);
232 delete [] choices;
233
234 return res;
235 }
236
237 #if WXWIN_COMPATIBILITY_2_8
238 size_t wxGetMultipleChoices(wxArrayInt& selections,
239 const wxString& message,
240 const wxString& caption,
241 int n, const wxString *choices,
242 wxWindow *parent,
243 int x, int y,
244 bool centre,
245 int width, int height)
246 {
247 int rc = wxGetSelectedChoices(selections, message, caption,
248 n, choices,
249 parent, x, y, centre, width, height);
250 if ( rc == -1 )
251 {
252 selections.clear();
253 return 0;
254 }
255
256 return rc;
257 }
258
259 size_t wxGetMultipleChoices(wxArrayInt& selections,
260 const wxString& message,
261 const wxString& caption,
262 const wxArrayString& aChoices,
263 wxWindow *parent,
264 int x, int y,
265 bool centre,
266 int width, int height)
267 {
268 int rc = wxGetSelectedChoices(selections, message, caption,
269 aChoices,
270 parent, x, y, centre, width, height);
271 if ( rc == -1 )
272 {
273 selections.clear();
274 return 0;
275 }
276
277 return rc;
278 }
279 #endif // WXWIN_COMPATIBILITY_2_8
280
281 // ----------------------------------------------------------------------------
282 // wxAnyChoiceDialog
283 // ----------------------------------------------------------------------------
284
285 bool wxAnyChoiceDialog::Create(wxWindow *parent,
286 const wxString& message,
287 const wxString& caption,
288 int n, const wxString *choices,
289 long styleDlg,
290 const wxPoint& pos,
291 long styleLbox)
292 {
293 #ifdef __WXMAC__
294 // FIXME: why??
295 if ( !wxDialog::Create(parent, wxID_ANY, caption, pos, wxDefaultSize, styleDlg & (~wxCANCEL) ) )
296 return false;
297 #else
298 if ( !wxDialog::Create(parent, wxID_ANY, caption, pos, wxDefaultSize, styleDlg) )
299 return false;
300 #endif
301
302 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
303
304 // 1) text message
305 topsizer->
306 Add(CreateTextSizer(message), wxSizerFlags().Expand().TripleBorder());
307
308 // 2) list box
309 m_listbox = CreateList(n, choices, styleLbox);
310
311 if ( n > 0 )
312 m_listbox->SetSelection(0);
313
314 topsizer->
315 Add(m_listbox, wxSizerFlags().Expand().Proportion(1).TripleBorder(wxLEFT | wxRIGHT));
316
317 // 3) buttons if any
318 wxSizer *
319 buttonSizer = CreateSeparatedButtonSizer(styleDlg & ButtonSizerFlags);
320 if ( buttonSizer )
321 {
322 topsizer->Add(buttonSizer, wxSizerFlags().Expand().DoubleBorder());
323 }
324
325 SetSizer( topsizer );
326
327 topsizer->SetSizeHints( this );
328 topsizer->Fit( this );
329
330 if ( styleDlg & wxCENTRE )
331 Centre(wxBOTH);
332
333 m_listbox->SetFocus();
334
335 return true;
336 }
337
338 bool wxAnyChoiceDialog::Create(wxWindow *parent,
339 const wxString& message,
340 const wxString& caption,
341 const wxArrayString& choices,
342 long styleDlg,
343 const wxPoint& pos,
344 long styleLbox)
345 {
346 wxCArrayString chs(choices);
347 return Create(parent, message, caption, chs.GetCount(), chs.GetStrings(),
348 styleDlg, pos, styleLbox);
349 }
350
351 wxListBoxBase *wxAnyChoiceDialog::CreateList(int n, const wxString *choices, long styleLbox)
352 {
353 return new wxListBox( this, wxID_LISTBOX,
354 wxDefaultPosition, wxDefaultSize,
355 n, choices,
356 styleLbox );
357 }
358
359 // ----------------------------------------------------------------------------
360 // wxSingleChoiceDialog
361 // ----------------------------------------------------------------------------
362
363 BEGIN_EVENT_TABLE(wxSingleChoiceDialog, wxDialog)
364 EVT_BUTTON(wxID_OK, wxSingleChoiceDialog::OnOK)
365 #ifndef __SMARTPHONE__
366 EVT_LISTBOX_DCLICK(wxID_LISTBOX, wxSingleChoiceDialog::OnListBoxDClick)
367 #endif
368 #ifdef __WXWINCE__
369 EVT_JOY_BUTTON_DOWN(wxSingleChoiceDialog::OnJoystickButtonDown)
370 #endif
371 END_EVENT_TABLE()
372
373 IMPLEMENT_DYNAMIC_CLASS(wxSingleChoiceDialog, wxDialog)
374
375 wxSingleChoiceDialog::wxSingleChoiceDialog(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& WXUNUSED(pos))
383 {
384 Create(parent, message, caption, n, choices, clientData, style);
385 }
386
387 wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
388 const wxString& message,
389 const wxString& caption,
390 const wxArrayString& choices,
391 char **clientData,
392 long style,
393 const wxPoint& WXUNUSED(pos))
394 {
395 Create(parent, message, caption, choices, clientData, style);
396 }
397
398 bool wxSingleChoiceDialog::Create( wxWindow *parent,
399 const wxString& message,
400 const wxString& caption,
401 int n,
402 const wxString *choices,
403 char **clientData,
404 long style,
405 const wxPoint& pos )
406 {
407 if ( !wxAnyChoiceDialog::Create(parent, message, caption,
408 n, choices,
409 style, pos) )
410 return false;
411
412 m_selection = n > 0 ? 0 : -1;
413
414 if (clientData)
415 {
416 for (int i = 0; i < n; i++)
417 m_listbox->SetClientData(i, clientData[i]);
418 }
419
420 return true;
421 }
422
423 bool wxSingleChoiceDialog::Create( wxWindow *parent,
424 const wxString& message,
425 const wxString& caption,
426 const wxArrayString& choices,
427 char **clientData,
428 long style,
429 const wxPoint& pos )
430 {
431 wxCArrayString chs(choices);
432 return Create( parent, message, caption, chs.GetCount(), chs.GetStrings(),
433 clientData, style, pos );
434 }
435
436 // Set the selection
437 void wxSingleChoiceDialog::SetSelection(int sel)
438 {
439 m_listbox->SetSelection(sel);
440 m_selection = sel;
441 }
442
443 void wxSingleChoiceDialog::OnOK(wxCommandEvent& WXUNUSED(event))
444 {
445 DoChoice();
446 }
447
448 #ifndef __SMARTPHONE__
449 void wxSingleChoiceDialog::OnListBoxDClick(wxCommandEvent& WXUNUSED(event))
450 {
451 DoChoice();
452 }
453 #endif
454
455 #ifdef __WXWINCE__
456 void wxSingleChoiceDialog::OnJoystickButtonDown(wxJoystickEvent& WXUNUSED(event))
457 {
458 DoChoice();
459 }
460 #endif
461
462 void wxSingleChoiceDialog::DoChoice()
463 {
464 m_selection = m_listbox->GetSelection();
465 m_stringSelection = m_listbox->GetStringSelection();
466
467 if ( m_listbox->HasClientUntypedData() )
468 SetClientData(m_listbox->GetClientData(m_selection));
469
470 EndModal(wxID_OK);
471 }
472
473 // ----------------------------------------------------------------------------
474 // wxMultiChoiceDialog
475 // ----------------------------------------------------------------------------
476
477 IMPLEMENT_DYNAMIC_CLASS(wxMultiChoiceDialog, wxDialog)
478
479 bool wxMultiChoiceDialog::Create( wxWindow *parent,
480 const wxString& message,
481 const wxString& caption,
482 int n,
483 const wxString *choices,
484 long style,
485 const wxPoint& pos )
486 {
487 long styleLbox;
488 #if wxUSE_CHECKLISTBOX
489 styleLbox = wxLB_ALWAYS_SB;
490 #else
491 styleLbox = wxLB_ALWAYS_SB | wxLB_EXTENDED;
492 #endif
493
494 if ( !wxAnyChoiceDialog::Create(parent, message, caption,
495 n, choices,
496 style, pos,
497 styleLbox) )
498 return false;
499
500 return true;
501 }
502
503 bool wxMultiChoiceDialog::Create( wxWindow *parent,
504 const wxString& message,
505 const wxString& caption,
506 const wxArrayString& choices,
507 long style,
508 const wxPoint& pos )
509 {
510 wxCArrayString chs(choices);
511 return Create( parent, message, caption, chs.GetCount(),
512 chs.GetStrings(), style, pos );
513 }
514
515 void wxMultiChoiceDialog::SetSelections(const wxArrayInt& selections)
516 {
517 #if wxUSE_CHECKLISTBOX
518 wxCheckListBox* checkListBox = wxDynamicCast(m_listbox, wxCheckListBox);
519 if (checkListBox)
520 {
521 // first clear all currently selected items
522 size_t n,
523 count = checkListBox->GetCount();
524 for ( n = 0; n < count; ++n )
525 {
526 if (checkListBox->IsChecked(n))
527 checkListBox->Check(n, false);
528 }
529
530 // now select the ones which should be selected
531 count = selections.GetCount();
532 for ( n = 0; n < count; n++ )
533 {
534 checkListBox->Check(selections[n]);
535 }
536
537 return;
538 }
539 #endif
540
541 // first clear all currently selected items
542 size_t n,
543 count = m_listbox->GetCount();
544 for ( n = 0; n < count; ++n )
545 {
546 m_listbox->Deselect(n);
547 }
548
549 // now select the ones which should be selected
550 count = selections.GetCount();
551 for ( n = 0; n < count; n++ )
552 {
553 m_listbox->Select(selections[n]);
554 }
555 }
556
557 bool wxMultiChoiceDialog::TransferDataFromWindow()
558 {
559 m_selections.Empty();
560
561 #if wxUSE_CHECKLISTBOX
562 wxCheckListBox* checkListBox = wxDynamicCast(m_listbox, wxCheckListBox);
563 if (checkListBox)
564 {
565 size_t count = checkListBox->GetCount();
566 for ( size_t n = 0; n < count; n++ )
567 {
568 if ( checkListBox->IsChecked(n) )
569 m_selections.Add(n);
570 }
571 return true;
572 }
573 #endif
574
575 size_t count = m_listbox->GetCount();
576 for ( size_t n = 0; n < count; n++ )
577 {
578 if ( m_listbox->IsSelected(n) )
579 m_selections.Add(n);
580 }
581
582 return true;
583 }
584
585 #if wxUSE_CHECKLISTBOX
586
587 wxListBoxBase *wxMultiChoiceDialog::CreateList(int n, const wxString *choices, long styleLbox)
588 {
589 return new wxCheckListBox( this, wxID_LISTBOX,
590 wxDefaultPosition, wxDefaultSize,
591 n, choices,
592 styleLbox );
593 }
594
595 #endif // wxUSE_CHECKLISTBOX
596
597 #endif // wxUSE_CHOICEDLG