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