]> git.saurik.com Git - wxWidgets.git/blob - src/generic/choicdgg.cpp
adapting new osx modifier handling, fixes #14377
[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 int initialSelection)
92 {
93 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
94
95 dialog.SetSelection(initialSelection);
96
97 wxString choice;
98 if ( dialog.ShowModal() == wxID_OK )
99 choice = dialog.GetStringSelection();
100
101 return choice;
102 }
103
104 wxString wxGetSingleChoice( const wxString& message,
105 const wxString& caption,
106 const wxArrayString& aChoices,
107 wxWindow *parent,
108 int x, int y,
109 bool centre,
110 int width, int height,
111 int initialSelection)
112 {
113 wxString *choices;
114 int n = ConvertWXArrayToC(aChoices, &choices);
115 wxString res = wxGetSingleChoice(message, caption, n, choices, parent,
116 x, y, centre, width, height,
117 initialSelection);
118 delete [] choices;
119
120 return res;
121 }
122
123 wxString wxGetSingleChoice( const wxString& message,
124 const wxString& caption,
125 const wxArrayString& choices,
126 int initialSelection,
127 wxWindow *parent)
128 {
129 return wxGetSingleChoice(message, caption, choices, parent,
130 wxDefaultCoord, wxDefaultCoord,
131 true, wxCHOICE_WIDTH, wxCHOICE_HEIGHT,
132 initialSelection);
133 }
134
135 wxString wxGetSingleChoice( const wxString& message,
136 const wxString& caption,
137 int n, const wxString *choices,
138 int initialSelection,
139 wxWindow *parent)
140 {
141 return wxGetSingleChoice(message, caption, n, choices, parent,
142 wxDefaultCoord, wxDefaultCoord,
143 true, wxCHOICE_WIDTH, wxCHOICE_HEIGHT,
144 initialSelection);
145 }
146
147 int wxGetSingleChoiceIndex( const wxString& message,
148 const wxString& caption,
149 int n, const wxString *choices,
150 wxWindow *parent,
151 int WXUNUSED(x), int WXUNUSED(y),
152 bool WXUNUSED(centre),
153 int WXUNUSED(width), int WXUNUSED(height),
154 int initialSelection)
155 {
156 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
157
158 dialog.SetSelection(initialSelection);
159
160 int choice;
161 if ( dialog.ShowModal() == wxID_OK )
162 choice = dialog.GetSelection();
163 else
164 choice = -1;
165
166 return choice;
167 }
168
169 int wxGetSingleChoiceIndex( const wxString& message,
170 const wxString& caption,
171 const wxArrayString& aChoices,
172 wxWindow *parent,
173 int x, int y,
174 bool centre,
175 int width, int height,
176 int initialSelection)
177 {
178 wxString *choices;
179 int n = ConvertWXArrayToC(aChoices, &choices);
180 int res = wxGetSingleChoiceIndex(message, caption, n, choices, parent,
181 x, y, centre, width, height,
182 initialSelection);
183 delete [] choices;
184
185 return res;
186 }
187
188 int wxGetSingleChoiceIndex( const wxString& message,
189 const wxString& caption,
190 const wxArrayString& choices,
191 int initialSelection,
192 wxWindow *parent)
193 {
194 return wxGetSingleChoiceIndex(message, caption, choices, parent,
195 wxDefaultCoord, wxDefaultCoord,
196 true, wxCHOICE_WIDTH, wxCHOICE_HEIGHT,
197 initialSelection);
198 }
199
200
201 int wxGetSingleChoiceIndex( const wxString& message,
202 const wxString& caption,
203 int n, const wxString *choices,
204 int initialSelection,
205 wxWindow *parent)
206 {
207 return wxGetSingleChoiceIndex(message, caption, n, choices, parent,
208 wxDefaultCoord, wxDefaultCoord,
209 true, wxCHOICE_WIDTH, wxCHOICE_HEIGHT,
210 initialSelection);
211 }
212
213
214 void *wxGetSingleChoiceData( const wxString& message,
215 const wxString& caption,
216 int n, const wxString *choices,
217 void **client_data,
218 wxWindow *parent,
219 int WXUNUSED(x), int WXUNUSED(y),
220 bool WXUNUSED(centre),
221 int WXUNUSED(width), int WXUNUSED(height),
222 int initialSelection)
223 {
224 wxSingleChoiceDialog dialog(parent, message, caption, n, choices,
225 client_data);
226
227 dialog.SetSelection(initialSelection);
228
229 void *data;
230 if ( dialog.ShowModal() == wxID_OK )
231 data = dialog.GetSelectionData();
232 else
233 data = NULL;
234
235 return data;
236 }
237
238 void *wxGetSingleChoiceData( const wxString& message,
239 const wxString& caption,
240 const wxArrayString& aChoices,
241 void **client_data,
242 wxWindow *parent,
243 int x, int y,
244 bool centre,
245 int width, int height,
246 int initialSelection)
247 {
248 wxString *choices;
249 int n = ConvertWXArrayToC(aChoices, &choices);
250 void *res = wxGetSingleChoiceData(message, caption, n, choices,
251 client_data, parent,
252 x, y, centre, width, height,
253 initialSelection);
254 delete [] choices;
255
256 return res;
257 }
258
259 void* wxGetSingleChoiceData( const wxString& message,
260 const wxString& caption,
261 const wxArrayString& choices,
262 void **client_data,
263 int initialSelection,
264 wxWindow *parent)
265 {
266 return wxGetSingleChoiceData(message, caption, choices,
267 client_data, parent,
268 wxDefaultCoord, wxDefaultCoord,
269 true, wxCHOICE_WIDTH, wxCHOICE_HEIGHT,
270 initialSelection);
271 }
272
273 void* wxGetSingleChoiceData( const wxString& message,
274 const wxString& caption,
275 int n, const wxString *choices,
276 void **client_data,
277 int initialSelection,
278 wxWindow *parent)
279 {
280 return wxGetSingleChoiceData(message, caption, n, choices,
281 client_data, parent,
282 wxDefaultCoord, wxDefaultCoord,
283 true, wxCHOICE_WIDTH, wxCHOICE_HEIGHT,
284 initialSelection);
285 }
286
287
288 int wxGetSelectedChoices(wxArrayInt& selections,
289 const wxString& message,
290 const wxString& caption,
291 int n, const wxString *choices,
292 wxWindow *parent,
293 int WXUNUSED(x), int WXUNUSED(y),
294 bool WXUNUSED(centre),
295 int WXUNUSED(width), int WXUNUSED(height))
296 {
297 wxMultiChoiceDialog dialog(parent, message, caption, n, choices);
298
299 // call this even if selections array is empty and this then (correctly)
300 // deselects the first item which is selected by default
301 dialog.SetSelections(selections);
302
303 if ( dialog.ShowModal() != wxID_OK )
304 {
305 // NB: intentionally do not clear the selections array here, the caller
306 // might want to preserve its original contents if the dialog was
307 // cancelled
308 return -1;
309 }
310
311 selections = dialog.GetSelections();
312 return selections.GetCount();
313 }
314
315 int wxGetSelectedChoices(wxArrayInt& selections,
316 const wxString& message,
317 const wxString& caption,
318 const wxArrayString& aChoices,
319 wxWindow *parent,
320 int x, int y,
321 bool centre,
322 int width, int height)
323 {
324 wxString *choices;
325 int n = ConvertWXArrayToC(aChoices, &choices);
326 int res = wxGetSelectedChoices(selections, message, caption,
327 n, choices, parent,
328 x, y, centre, width, height);
329 delete [] choices;
330
331 return res;
332 }
333
334 #if WXWIN_COMPATIBILITY_2_8
335 size_t wxGetMultipleChoices(wxArrayInt& selections,
336 const wxString& message,
337 const wxString& caption,
338 int n, const wxString *choices,
339 wxWindow *parent,
340 int x, int y,
341 bool centre,
342 int width, int height)
343 {
344 int rc = wxGetSelectedChoices(selections, message, caption,
345 n, choices,
346 parent, x, y, centre, width, height);
347 if ( rc == -1 )
348 {
349 selections.clear();
350 return 0;
351 }
352
353 return rc;
354 }
355
356 size_t wxGetMultipleChoices(wxArrayInt& selections,
357 const wxString& message,
358 const wxString& caption,
359 const wxArrayString& aChoices,
360 wxWindow *parent,
361 int x, int y,
362 bool centre,
363 int width, int height)
364 {
365 int rc = wxGetSelectedChoices(selections, message, caption,
366 aChoices,
367 parent, x, y, centre, width, height);
368 if ( rc == -1 )
369 {
370 selections.clear();
371 return 0;
372 }
373
374 return rc;
375 }
376 #endif // WXWIN_COMPATIBILITY_2_8
377
378 // ----------------------------------------------------------------------------
379 // wxAnyChoiceDialog
380 // ----------------------------------------------------------------------------
381
382 bool wxAnyChoiceDialog::Create(wxWindow *parent,
383 const wxString& message,
384 const wxString& caption,
385 int n, const wxString *choices,
386 long styleDlg,
387 const wxPoint& pos,
388 long styleLbox)
389 {
390 // extract the buttons styles from the dialog one and remove them from it
391 const long styleBtns = styleDlg & (wxOK | wxCANCEL);
392 styleDlg &= ~styleBtns;
393
394 if ( !wxDialog::Create(parent, wxID_ANY, caption, pos, wxDefaultSize, styleDlg) )
395 return false;
396
397 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
398
399 // 1) text message
400 topsizer->
401 Add(CreateTextSizer(message), wxSizerFlags().Expand().TripleBorder());
402
403 // 2) list box
404 m_listbox = CreateList(n, choices, styleLbox);
405
406 if ( n > 0 )
407 m_listbox->SetSelection(0);
408
409 topsizer->
410 Add(m_listbox, wxSizerFlags().Expand().Proportion(1).TripleBorder(wxLEFT | wxRIGHT));
411
412 // 3) buttons if any
413 wxSizer *
414 buttonSizer = CreateSeparatedButtonSizer(styleBtns);
415 if ( buttonSizer )
416 {
417 topsizer->Add(buttonSizer, wxSizerFlags().Expand().DoubleBorder());
418 }
419
420 SetSizer( topsizer );
421
422 topsizer->SetSizeHints( this );
423 topsizer->Fit( this );
424
425 if ( styleDlg & wxCENTRE )
426 Centre(wxBOTH);
427
428 m_listbox->SetFocus();
429
430 return true;
431 }
432
433 bool wxAnyChoiceDialog::Create(wxWindow *parent,
434 const wxString& message,
435 const wxString& caption,
436 const wxArrayString& choices,
437 long styleDlg,
438 const wxPoint& pos,
439 long styleLbox)
440 {
441 wxCArrayString chs(choices);
442 return Create(parent, message, caption, chs.GetCount(), chs.GetStrings(),
443 styleDlg, pos, styleLbox);
444 }
445
446 wxListBoxBase *wxAnyChoiceDialog::CreateList(int n, const wxString *choices, long styleLbox)
447 {
448 return new wxListBox( this, wxID_LISTBOX,
449 wxDefaultPosition, wxDefaultSize,
450 n, choices,
451 styleLbox );
452 }
453
454 // ----------------------------------------------------------------------------
455 // wxSingleChoiceDialog
456 // ----------------------------------------------------------------------------
457
458 BEGIN_EVENT_TABLE(wxSingleChoiceDialog, wxDialog)
459 EVT_BUTTON(wxID_OK, wxSingleChoiceDialog::OnOK)
460 #ifndef __SMARTPHONE__
461 EVT_LISTBOX_DCLICK(wxID_LISTBOX, wxSingleChoiceDialog::OnListBoxDClick)
462 #endif
463 #ifdef __WXWINCE__
464 EVT_JOY_BUTTON_DOWN(wxSingleChoiceDialog::OnJoystickButtonDown)
465 #endif
466 END_EVENT_TABLE()
467
468 IMPLEMENT_DYNAMIC_CLASS(wxSingleChoiceDialog, wxDialog)
469
470 bool wxSingleChoiceDialog::Create( wxWindow *parent,
471 const wxString& message,
472 const wxString& caption,
473 int n,
474 const wxString *choices,
475 void **clientData,
476 long style,
477 const wxPoint& pos )
478 {
479 if ( !wxAnyChoiceDialog::Create(parent, message, caption,
480 n, choices,
481 style, pos) )
482 return false;
483
484 m_selection = n > 0 ? 0 : -1;
485
486 if (clientData)
487 {
488 for (int i = 0; i < n; i++)
489 m_listbox->SetClientData(i, clientData[i]);
490 }
491
492 return true;
493 }
494
495 bool wxSingleChoiceDialog::Create( wxWindow *parent,
496 const wxString& message,
497 const wxString& caption,
498 const wxArrayString& choices,
499 void **clientData,
500 long style,
501 const wxPoint& pos )
502 {
503 wxCArrayString chs(choices);
504 return Create( parent, message, caption, chs.GetCount(), chs.GetStrings(),
505 clientData, style, pos );
506 }
507
508 // Set the selection
509 void wxSingleChoiceDialog::SetSelection(int sel)
510 {
511 wxCHECK_RET( sel >= 0 && (unsigned)sel < m_listbox->GetCount(),
512 "Invalid initial selection" );
513
514 m_listbox->SetSelection(sel);
515 m_selection = sel;
516 }
517
518 void wxSingleChoiceDialog::OnOK(wxCommandEvent& WXUNUSED(event))
519 {
520 DoChoice();
521 }
522
523 #ifndef __SMARTPHONE__
524 void wxSingleChoiceDialog::OnListBoxDClick(wxCommandEvent& WXUNUSED(event))
525 {
526 DoChoice();
527 }
528 #endif
529
530 #ifdef __WXWINCE__
531 void wxSingleChoiceDialog::OnJoystickButtonDown(wxJoystickEvent& WXUNUSED(event))
532 {
533 DoChoice();
534 }
535 #endif
536
537 void wxSingleChoiceDialog::DoChoice()
538 {
539 m_selection = m_listbox->GetSelection();
540 m_stringSelection = m_listbox->GetStringSelection();
541
542 if ( m_listbox->HasClientUntypedData() )
543 SetClientData(m_listbox->GetClientData(m_selection));
544
545 EndModal(wxID_OK);
546 }
547
548 // ----------------------------------------------------------------------------
549 // wxMultiChoiceDialog
550 // ----------------------------------------------------------------------------
551
552 IMPLEMENT_DYNAMIC_CLASS(wxMultiChoiceDialog, wxDialog)
553
554 bool wxMultiChoiceDialog::Create( wxWindow *parent,
555 const wxString& message,
556 const wxString& caption,
557 int n,
558 const wxString *choices,
559 long style,
560 const wxPoint& pos )
561 {
562 long styleLbox;
563 #if wxUSE_CHECKLISTBOX
564 styleLbox = wxLB_ALWAYS_SB;
565 #else
566 styleLbox = wxLB_ALWAYS_SB | wxLB_EXTENDED;
567 #endif
568
569 if ( !wxAnyChoiceDialog::Create(parent, message, caption,
570 n, choices,
571 style, pos,
572 styleLbox) )
573 return false;
574
575 return true;
576 }
577
578 bool wxMultiChoiceDialog::Create( wxWindow *parent,
579 const wxString& message,
580 const wxString& caption,
581 const wxArrayString& choices,
582 long style,
583 const wxPoint& pos )
584 {
585 wxCArrayString chs(choices);
586 return Create( parent, message, caption, chs.GetCount(),
587 chs.GetStrings(), style, pos );
588 }
589
590 void wxMultiChoiceDialog::SetSelections(const wxArrayInt& selections)
591 {
592 #if wxUSE_CHECKLISTBOX
593 wxCheckListBox* checkListBox = wxDynamicCast(m_listbox, wxCheckListBox);
594 if (checkListBox)
595 {
596 // first clear all currently selected items
597 size_t n,
598 count = checkListBox->GetCount();
599 for ( n = 0; n < count; ++n )
600 {
601 if (checkListBox->IsChecked(n))
602 checkListBox->Check(n, false);
603 }
604
605 // now select the ones which should be selected
606 count = selections.GetCount();
607 for ( n = 0; n < count; n++ )
608 {
609 checkListBox->Check(selections[n]);
610 }
611
612 return;
613 }
614 #endif
615
616 // first clear all currently selected items
617 size_t n,
618 count = m_listbox->GetCount();
619 for ( n = 0; n < count; ++n )
620 {
621 m_listbox->Deselect(n);
622 }
623
624 // now select the ones which should be selected
625 count = selections.GetCount();
626 for ( n = 0; n < count; n++ )
627 {
628 m_listbox->Select(selections[n]);
629 }
630 }
631
632 bool wxMultiChoiceDialog::TransferDataFromWindow()
633 {
634 m_selections.Empty();
635
636 #if wxUSE_CHECKLISTBOX
637 wxCheckListBox* checkListBox = wxDynamicCast(m_listbox, wxCheckListBox);
638 if (checkListBox)
639 {
640 size_t count = checkListBox->GetCount();
641 for ( size_t n = 0; n < count; n++ )
642 {
643 if ( checkListBox->IsChecked(n) )
644 m_selections.Add(n);
645 }
646 return true;
647 }
648 #endif
649
650 size_t count = m_listbox->GetCount();
651 for ( size_t n = 0; n < count; n++ )
652 {
653 if ( m_listbox->IsSelected(n) )
654 m_selections.Add(n);
655 }
656
657 return true;
658 }
659
660 #if wxUSE_CHECKLISTBOX
661
662 wxListBoxBase *wxMultiChoiceDialog::CreateList(int n, const wxString *choices, long styleLbox)
663 {
664 return new wxCheckListBox( this, wxID_LISTBOX,
665 wxDefaultPosition, wxDefaultSize,
666 n, choices,
667 styleLbox );
668 }
669
670 #endif // wxUSE_CHECKLISTBOX
671
672 #endif // wxUSE_CHOICEDLG