don't limit the multiple choice dialog size to 300x200 pixels on big screens, this...
[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 size_t wxGetMultipleChoices(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 selections = dialog.GetSelections();
208 else
209 selections.Empty();
210
211 return selections.GetCount();
212 }
213
214 size_t wxGetMultipleChoices(wxArrayInt& selections,
215 const wxString& message,
216 const wxString& caption,
217 const wxArrayString& aChoices,
218 wxWindow *parent,
219 int x, int y,
220 bool centre,
221 int width, int height)
222 {
223 wxString *choices;
224 int n = ConvertWXArrayToC(aChoices, &choices);
225 size_t res = wxGetMultipleChoices(selections, message, caption,
226 n, choices, parent,
227 x, y, centre, width, height);
228 delete [] choices;
229
230 return res;
231 }
232
233 // ----------------------------------------------------------------------------
234 // wxAnyChoiceDialog
235 // ----------------------------------------------------------------------------
236
237 bool wxAnyChoiceDialog::Create(wxWindow *parent,
238 const wxString& message,
239 const wxString& caption,
240 int n, const wxString *choices,
241 long styleDlg,
242 const wxPoint& pos,
243 long styleLbox)
244 {
245 #ifdef __WXMAC__
246 // FIXME: why??
247 if ( !wxDialog::Create(parent, wxID_ANY, caption, pos, wxDefaultSize, styleDlg & (~wxCANCEL) ) )
248 return false;
249 #else
250 if ( !wxDialog::Create(parent, wxID_ANY, caption, pos, wxDefaultSize, styleDlg) )
251 return false;
252 #endif
253
254 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
255
256 // 1) text message
257 topsizer->
258 Add(CreateTextSizer(message), wxSizerFlags().Expand().TripleBorder());
259
260 // 2) list box
261 m_listbox = CreateList(n, choices, styleLbox);
262
263 if ( n > 0 )
264 m_listbox->SetSelection(0);
265
266 topsizer->
267 Add(m_listbox, wxSizerFlags().Expand().Proportion(1).TripleBorder(wxLEFT | wxRIGHT));
268
269 // 3) buttons if any
270 wxSizer *
271 buttonSizer = CreateSeparatedButtonSizer(styleDlg & ButtonSizerFlags);
272 if ( buttonSizer )
273 {
274 topsizer->Add(buttonSizer, wxSizerFlags().Expand().DoubleBorder());
275 }
276
277 SetSizer( topsizer );
278
279 topsizer->SetSizeHints( this );
280 topsizer->Fit( this );
281
282 if ( styleDlg & wxCENTRE )
283 Centre(wxBOTH);
284
285 m_listbox->SetFocus();
286
287 return true;
288 }
289
290 bool wxAnyChoiceDialog::Create(wxWindow *parent,
291 const wxString& message,
292 const wxString& caption,
293 const wxArrayString& choices,
294 long styleDlg,
295 const wxPoint& pos,
296 long styleLbox)
297 {
298 wxCArrayString chs(choices);
299 return Create(parent, message, caption, chs.GetCount(), chs.GetStrings(),
300 styleDlg, pos, styleLbox);
301 }
302
303 wxListBoxBase *wxAnyChoiceDialog::CreateList(int n, const wxString *choices, long styleLbox)
304 {
305 return new wxListBox( this, wxID_LISTBOX,
306 wxDefaultPosition, wxDefaultSize,
307 n, choices,
308 styleLbox );
309 }
310
311 // ----------------------------------------------------------------------------
312 // wxSingleChoiceDialog
313 // ----------------------------------------------------------------------------
314
315 BEGIN_EVENT_TABLE(wxSingleChoiceDialog, wxDialog)
316 EVT_BUTTON(wxID_OK, wxSingleChoiceDialog::OnOK)
317 #ifndef __SMARTPHONE__
318 EVT_LISTBOX_DCLICK(wxID_LISTBOX, wxSingleChoiceDialog::OnListBoxDClick)
319 #endif
320 #ifdef __WXWINCE__
321 EVT_JOY_BUTTON_DOWN(wxSingleChoiceDialog::OnJoystickButtonDown)
322 #endif
323 END_EVENT_TABLE()
324
325 IMPLEMENT_DYNAMIC_CLASS(wxSingleChoiceDialog, wxDialog)
326
327 wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
328 const wxString& message,
329 const wxString& caption,
330 int n,
331 const wxString *choices,
332 char **clientData,
333 long style,
334 const wxPoint& WXUNUSED(pos))
335 {
336 Create(parent, message, caption, n, choices, clientData, style);
337 }
338
339 wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
340 const wxString& message,
341 const wxString& caption,
342 const wxArrayString& choices,
343 char **clientData,
344 long style,
345 const wxPoint& WXUNUSED(pos))
346 {
347 Create(parent, message, caption, choices, clientData, style);
348 }
349
350 bool wxSingleChoiceDialog::Create( wxWindow *parent,
351 const wxString& message,
352 const wxString& caption,
353 int n,
354 const wxString *choices,
355 char **clientData,
356 long style,
357 const wxPoint& pos )
358 {
359 if ( !wxAnyChoiceDialog::Create(parent, message, caption,
360 n, choices,
361 style, pos) )
362 return false;
363
364 m_selection = n > 0 ? 0 : -1;
365
366 if (clientData)
367 {
368 for (int i = 0; i < n; i++)
369 m_listbox->SetClientData(i, clientData[i]);
370 }
371
372 return true;
373 }
374
375 bool wxSingleChoiceDialog::Create( wxWindow *parent,
376 const wxString& message,
377 const wxString& caption,
378 const wxArrayString& choices,
379 char **clientData,
380 long style,
381 const wxPoint& pos )
382 {
383 wxCArrayString chs(choices);
384 return Create( parent, message, caption, chs.GetCount(), chs.GetStrings(),
385 clientData, style, pos );
386 }
387
388 // Set the selection
389 void wxSingleChoiceDialog::SetSelection(int sel)
390 {
391 m_listbox->SetSelection(sel);
392 m_selection = sel;
393 }
394
395 void wxSingleChoiceDialog::OnOK(wxCommandEvent& WXUNUSED(event))
396 {
397 DoChoice();
398 }
399
400 #ifndef __SMARTPHONE__
401 void wxSingleChoiceDialog::OnListBoxDClick(wxCommandEvent& WXUNUSED(event))
402 {
403 DoChoice();
404 }
405 #endif
406
407 #ifdef __WXWINCE__
408 void wxSingleChoiceDialog::OnJoystickButtonDown(wxJoystickEvent& WXUNUSED(event))
409 {
410 DoChoice();
411 }
412 #endif
413
414 void wxSingleChoiceDialog::DoChoice()
415 {
416 m_selection = m_listbox->GetSelection();
417 m_stringSelection = m_listbox->GetStringSelection();
418
419 if ( m_listbox->HasClientUntypedData() )
420 SetClientData(m_listbox->GetClientData(m_selection));
421
422 EndModal(wxID_OK);
423 }
424
425 // ----------------------------------------------------------------------------
426 // wxMultiChoiceDialog
427 // ----------------------------------------------------------------------------
428
429 IMPLEMENT_DYNAMIC_CLASS(wxMultiChoiceDialog, wxDialog)
430
431 bool wxMultiChoiceDialog::Create( wxWindow *parent,
432 const wxString& message,
433 const wxString& caption,
434 int n,
435 const wxString *choices,
436 long style,
437 const wxPoint& pos )
438 {
439 long styleLbox;
440 #if wxUSE_CHECKLISTBOX
441 styleLbox = wxLB_ALWAYS_SB;
442 #else
443 styleLbox = wxLB_ALWAYS_SB | wxLB_EXTENDED;
444 #endif
445
446 if ( !wxAnyChoiceDialog::Create(parent, message, caption,
447 n, choices,
448 style, pos,
449 styleLbox) )
450 return false;
451
452 return true;
453 }
454
455 bool wxMultiChoiceDialog::Create( wxWindow *parent,
456 const wxString& message,
457 const wxString& caption,
458 const wxArrayString& choices,
459 long style,
460 const wxPoint& pos )
461 {
462 wxCArrayString chs(choices);
463 return Create( parent, message, caption, chs.GetCount(),
464 chs.GetStrings(), style, pos );
465 }
466
467 void wxMultiChoiceDialog::SetSelections(const wxArrayInt& selections)
468 {
469 #if wxUSE_CHECKLISTBOX
470 wxCheckListBox* checkListBox = wxDynamicCast(m_listbox, wxCheckListBox);
471 if (checkListBox)
472 {
473 // first clear all currently selected items
474 size_t n,
475 count = checkListBox->GetCount();
476 for ( n = 0; n < count; ++n )
477 {
478 if (checkListBox->IsChecked(n))
479 checkListBox->Check(n, false);
480 }
481
482 // now select the ones which should be selected
483 count = selections.GetCount();
484 for ( n = 0; n < count; n++ )
485 {
486 checkListBox->Check(selections[n]);
487 }
488
489 return;
490 }
491 #endif
492
493 // first clear all currently selected items
494 size_t n,
495 count = m_listbox->GetCount();
496 for ( n = 0; n < count; ++n )
497 {
498 m_listbox->Deselect(n);
499 }
500
501 // now select the ones which should be selected
502 count = selections.GetCount();
503 for ( n = 0; n < count; n++ )
504 {
505 m_listbox->Select(selections[n]);
506 }
507 }
508
509 bool wxMultiChoiceDialog::TransferDataFromWindow()
510 {
511 m_selections.Empty();
512
513 #if wxUSE_CHECKLISTBOX
514 wxCheckListBox* checkListBox = wxDynamicCast(m_listbox, wxCheckListBox);
515 if (checkListBox)
516 {
517 size_t count = checkListBox->GetCount();
518 for ( size_t n = 0; n < count; n++ )
519 {
520 if ( checkListBox->IsChecked(n) )
521 m_selections.Add(n);
522 }
523 return true;
524 }
525 #endif
526
527 size_t count = m_listbox->GetCount();
528 for ( size_t n = 0; n < count; n++ )
529 {
530 if ( m_listbox->IsSelected(n) )
531 m_selections.Add(n);
532 }
533
534 return true;
535 }
536
537 #if wxUSE_CHECKLISTBOX
538
539 wxListBoxBase *wxMultiChoiceDialog::CreateList(int n, const wxString *choices, long styleLbox)
540 {
541 return new wxCheckListBox( this, wxID_LISTBOX,
542 wxDefaultPosition, wxDefaultSize,
543 n, choices,
544 styleLbox );
545 }
546
547 #endif // wxUSE_CHECKLISTBOX
548
549 #endif // wxUSE_CHOICEDLG