don't preselect the first item if the array with the initial selections is empty...
[wxWidgets.git] / src / generic / choicdgg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: 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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
17 #pragma implementation "choicdgg.h"
18 #endif
19
20 // ----------------------------------------------------------------------------
21 // headers
22 // ----------------------------------------------------------------------------
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #if wxUSE_CHOICEDLG
32
33 #ifndef WX_PRECOMP
34 #include <stdio.h>
35 #include "wx/utils.h"
36 #include "wx/dialog.h"
37 #include "wx/button.h"
38 #include "wx/listbox.h"
39 #include "wx/stattext.h"
40 #include "wx/intl.h"
41 #include "wx/sizer.h"
42 #include "wx/arrstr.h"
43 #endif
44
45 #if wxUSE_STATLINE
46 #include "wx/statline.h"
47 #endif
48
49 #include "wx/generic/choicdgg.h"
50
51 // ----------------------------------------------------------------------------
52 // constants
53 // ----------------------------------------------------------------------------
54
55 #define wxID_LISTBOX 3000
56
57 // ---------------------------------------------------------------------------
58 // macros
59 // ---------------------------------------------------------------------------
60
61 /* Macro for avoiding #ifdefs when value have to be different depending on size of
62 device we display on - take it from something like wxDesktopPolicy in the future
63 */
64
65 #if defined(__SMARTPHONE__)
66 #define wxLARGESMALL(large,small) small
67 #else
68 #define wxLARGESMALL(large,small) large
69 #endif
70
71 // ----------------------------------------------------------------------------
72 // private functions
73 // ----------------------------------------------------------------------------
74
75 // convert wxArrayString into a wxString[] which must be delete[]d by caller
76 static int ConvertWXArrayToC(const wxArrayString& aChoices, wxString **choices);
77
78 // ============================================================================
79 // implementation
80 // ============================================================================
81
82 // ----------------------------------------------------------------------------
83 // helpers
84 // ----------------------------------------------------------------------------
85
86 int ConvertWXArrayToC(const wxArrayString& aChoices, wxString **choices)
87 {
88 int n = aChoices.GetCount();
89 *choices = new wxString[n];
90
91 for ( int i = 0; i < n; i++ )
92 {
93 (*choices)[i] = aChoices[i];
94 }
95
96 return n;
97 }
98
99 // ----------------------------------------------------------------------------
100 // wrapper functions
101 // ----------------------------------------------------------------------------
102
103 wxString wxGetSingleChoice( const wxString& message,
104 const wxString& caption,
105 int n, const wxString *choices,
106 wxWindow *parent,
107 int WXUNUSED(x), int WXUNUSED(y),
108 bool WXUNUSED(centre),
109 int WXUNUSED(width), int WXUNUSED(height) )
110 {
111 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
112 wxString choice;
113 if ( dialog.ShowModal() == wxID_OK )
114 choice = dialog.GetStringSelection();
115
116 return choice;
117 }
118
119 wxString wxGetSingleChoice( const wxString& message,
120 const wxString& caption,
121 const wxArrayString& aChoices,
122 wxWindow *parent,
123 int x, int y,
124 bool centre,
125 int width, int height)
126 {
127 wxString *choices;
128 int n = ConvertWXArrayToC(aChoices, &choices);
129 wxString res = wxGetSingleChoice(message, caption, n, choices, parent,
130 x, y, centre, width, height);
131 delete [] choices;
132
133 return res;
134 }
135
136 int wxGetSingleChoiceIndex( const wxString& message,
137 const wxString& caption,
138 int n, const wxString *choices,
139 wxWindow *parent,
140 int WXUNUSED(x), int WXUNUSED(y),
141 bool WXUNUSED(centre),
142 int WXUNUSED(width), int WXUNUSED(height) )
143 {
144 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
145 int choice;
146 if ( dialog.ShowModal() == wxID_OK )
147 choice = dialog.GetSelection();
148 else
149 choice = -1;
150
151 return choice;
152 }
153
154 int wxGetSingleChoiceIndex( const wxString& message,
155 const wxString& caption,
156 const wxArrayString& aChoices,
157 wxWindow *parent,
158 int x, int y,
159 bool centre,
160 int width, int height)
161 {
162 wxString *choices;
163 int n = ConvertWXArrayToC(aChoices, &choices);
164 int res = wxGetSingleChoiceIndex(message, caption, n, choices, parent,
165 x, y, centre, width, height);
166 delete [] choices;
167
168 return res;
169 }
170
171 void *wxGetSingleChoiceData( const wxString& message,
172 const wxString& caption,
173 int n, const wxString *choices,
174 void **client_data,
175 wxWindow *parent,
176 int WXUNUSED(x), int WXUNUSED(y),
177 bool WXUNUSED(centre),
178 int WXUNUSED(width), int WXUNUSED(height) )
179 {
180 wxSingleChoiceDialog dialog(parent, message, caption, n, choices,
181 (char **)client_data);
182 void *data;
183 if ( dialog.ShowModal() == wxID_OK )
184 data = dialog.GetSelectionClientData();
185 else
186 data = NULL;
187
188 return data;
189 }
190
191 void *wxGetSingleChoiceData( const wxString& message,
192 const wxString& caption,
193 const wxArrayString& aChoices,
194 void **client_data,
195 wxWindow *parent,
196 int x, int y,
197 bool centre,
198 int width, int height)
199 {
200 wxString *choices;
201 int n = ConvertWXArrayToC(aChoices, &choices);
202 void *res = wxGetSingleChoiceData(message, caption, n, choices,
203 client_data, parent,
204 x, y, centre, width, height);
205 delete [] choices;
206
207 return res;
208 }
209
210 size_t wxGetMultipleChoices(wxArrayInt& selections,
211 const wxString& message,
212 const wxString& caption,
213 int n, const wxString *choices,
214 wxWindow *parent,
215 int WXUNUSED(x), int WXUNUSED(y),
216 bool WXUNUSED(centre),
217 int WXUNUSED(width), int WXUNUSED(height))
218 {
219 wxMultiChoiceDialog dialog(parent, message, caption, n, choices);
220
221 // call this even if selections array is empty and this then (correctly)
222 // deselects the first item which is selected by default
223 dialog.SetSelections(selections);
224
225 if ( dialog.ShowModal() == wxID_OK )
226 selections = dialog.GetSelections();
227 else
228 selections.Empty();
229
230 return selections.GetCount();
231 }
232
233 size_t wxGetMultipleChoices(wxArrayInt& selections,
234 const wxString& message,
235 const wxString& caption,
236 const wxArrayString& aChoices,
237 wxWindow *parent,
238 int x, int y,
239 bool centre,
240 int width, int height)
241 {
242 wxString *choices;
243 int n = ConvertWXArrayToC(aChoices, &choices);
244 size_t res = wxGetMultipleChoices(selections, message, caption,
245 n, choices, parent,
246 x, y, centre, width, height);
247 delete [] choices;
248
249 return res;
250 }
251
252 // ----------------------------------------------------------------------------
253 // wxAnyChoiceDialog
254 // ----------------------------------------------------------------------------
255
256 bool wxAnyChoiceDialog::Create(wxWindow *parent,
257 const wxString& message,
258 const wxString& caption,
259 int n, const wxString *choices,
260 long styleDlg,
261 const wxPoint& pos,
262 long styleLbox)
263 {
264 if ( !wxDialog::Create(parent, wxID_ANY, caption, pos, wxDefaultSize, styleDlg) )
265 return false;
266
267 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
268
269 // 1) text message
270 topsizer->Add( CreateTextSizer( message ), 0, wxALL, wxLARGESMALL(10,0) );
271
272 // 2) list box
273 m_listbox = new wxListBox( this, wxID_LISTBOX,
274 wxDefaultPosition, wxDefaultSize,
275 n, choices,
276 styleLbox );
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, wxCENTRE | wxALL, 10 );
296
297 #endif // !__SMARTPHONE__
298
299 SetAutoLayout( true );
300 SetSizer( topsizer );
301
302 topsizer->SetSizeHints( this );
303 topsizer->Fit( this );
304
305 if ( styleDlg & wxCENTRE )
306 Centre(wxBOTH);
307
308 m_listbox->SetFocus();
309
310 return true;
311 }
312
313 bool wxAnyChoiceDialog::Create(wxWindow *parent,
314 const wxString& message,
315 const wxString& caption,
316 const wxArrayString& choices,
317 long styleDlg,
318 const wxPoint& pos,
319 long styleLbox)
320 {
321 wxCArrayString chs(choices);
322 return Create(parent, message, caption, chs.GetCount(), chs.GetStrings(),
323 styleDlg, pos, styleLbox);
324 }
325
326 // ----------------------------------------------------------------------------
327 // wxSingleChoiceDialog
328 // ----------------------------------------------------------------------------
329
330 BEGIN_EVENT_TABLE(wxSingleChoiceDialog, wxDialog)
331 EVT_BUTTON(wxID_OK, wxSingleChoiceDialog::OnOK)
332 EVT_LISTBOX_DCLICK(wxID_LISTBOX, wxSingleChoiceDialog::OnListBoxDClick)
333 END_EVENT_TABLE()
334
335 IMPLEMENT_DYNAMIC_CLASS(wxSingleChoiceDialog, wxDialog)
336
337 wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
338 const wxString& message,
339 const wxString& caption,
340 int n,
341 const wxString *choices,
342 char **clientData,
343 long style,
344 const wxPoint& WXUNUSED(pos))
345 {
346 Create(parent, message, caption, n, choices, clientData, style);
347 }
348
349 wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
350 const wxString& message,
351 const wxString& caption,
352 const wxArrayString& choices,
353 char **clientData,
354 long style,
355 const wxPoint& WXUNUSED(pos))
356 {
357 Create(parent, message, caption, choices, clientData, style);
358 }
359
360 bool wxSingleChoiceDialog::Create( wxWindow *parent,
361 const wxString& message,
362 const wxString& caption,
363 int n,
364 const wxString *choices,
365 char **clientData,
366 long style,
367 const wxPoint& pos )
368 {
369 if ( !wxAnyChoiceDialog::Create(parent, message, caption,
370 n, choices,
371 style, pos) )
372 return false;
373
374 m_selection = n > 0 ? 0 : -1;
375
376 if (clientData)
377 {
378 for (int i = 0; i < n; i++)
379 m_listbox->SetClientData(i, clientData[i]);
380 }
381
382 return true;
383 }
384
385 bool wxSingleChoiceDialog::Create( wxWindow *parent,
386 const wxString& message,
387 const wxString& caption,
388 const wxArrayString& choices,
389 char **clientData,
390 long style,
391 const wxPoint& pos )
392 {
393 wxCArrayString chs(choices);
394 return Create( parent, message, caption, chs.GetCount(), chs.GetStrings(),
395 clientData, style, pos );
396 }
397
398 // Set the selection
399 void wxSingleChoiceDialog::SetSelection(int sel)
400 {
401 m_listbox->SetSelection(sel);
402 m_selection = sel;
403 }
404
405 void wxSingleChoiceDialog::OnOK(wxCommandEvent& WXUNUSED(event))
406 {
407 m_selection = m_listbox->GetSelection();
408 m_stringSelection = m_listbox->GetStringSelection();
409 if ( m_listbox->HasClientUntypedData() )
410 SetClientData(m_listbox->GetClientData(m_selection));
411 EndModal(wxID_OK);
412 }
413
414 void wxSingleChoiceDialog::OnListBoxDClick(wxCommandEvent& WXUNUSED(event))
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 if ( !wxAnyChoiceDialog::Create(parent, message, caption,
440 n, choices,
441 style, pos,
442 wxLB_ALWAYS_SB | wxLB_EXTENDED) )
443 return false;
444
445 return true;
446 }
447
448 bool wxMultiChoiceDialog::Create( wxWindow *parent,
449 const wxString& message,
450 const wxString& caption,
451 const wxArrayString& choices,
452 long style,
453 const wxPoint& pos )
454 {
455 wxCArrayString chs(choices);
456 return Create( parent, message, caption, chs.GetCount(),
457 chs.GetStrings(), style, pos );
458 }
459
460 void wxMultiChoiceDialog::SetSelections(const wxArrayInt& selections)
461 {
462 // first clear all currently selected items
463 size_t n,
464 count = m_listbox->GetCount();
465 for ( n = 0; n < count; ++n )
466 {
467 m_listbox->Deselect(n);
468 }
469
470 // now select the ones which should be selected
471 count = selections.GetCount();
472 for ( n = 0; n < count; n++ )
473 {
474 m_listbox->Select(selections[n]);
475 }
476 }
477
478 bool wxMultiChoiceDialog::TransferDataFromWindow()
479 {
480 m_selections.Empty();
481 size_t count = m_listbox->GetCount();
482 for ( size_t n = 0; n < count; n++ )
483 {
484 if ( m_listbox->IsSelected(n) )
485 m_selections.Add(n);
486 }
487
488 return true;
489 }
490
491 #endif // wxUSE_CHOICEDLG