]> git.saurik.com Git - wxWidgets.git/blame - src/generic/choicdgg.cpp
fixed crash on invalid data (patch 1039453)
[wxWidgets.git] / src / generic / choicdgg.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
dfad0599 2// Name: choicdgg.cpp
c801d85f
KB
3// Purpose: Choice dialogs
4// Author: Julian Smart
d6c9c1b7 5// Modified by: 03.11.00: VZ to add wxArrayString and multiple sel functions
c801d85f
KB
6// Created: 04/01/98
7// RCS-ID: $Id$
77ffb593 8// Copyright: (c) wxWidgets team
65571936 9// Licence: wxWindows licence
c801d85f
KB
10/////////////////////////////////////////////////////////////////////////////
11
d6c9c1b7
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
14f355c2 16#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
d427503c 17 #pragma implementation "choicdgg.h"
c801d85f
KB
18#endif
19
d6c9c1b7
VZ
20// ----------------------------------------------------------------------------
21// headers
22// ----------------------------------------------------------------------------
23
c801d85f
KB
24// For compilers that support precompilation, includes "wx.h".
25#include "wx/wxprec.h"
26
27#ifdef __BORLANDC__
d427503c 28 #pragma hdrstop
c801d85f
KB
29#endif
30
1e6feb95
VZ
31#if wxUSE_CHOICEDLG
32
c801d85f 33#ifndef WX_PRECOMP
257bf510
VZ
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"
92afa2b1 41 #include "wx/sizer.h"
2da2f941 42 #include "wx/arrstr.h"
dcf924a3
RR
43#endif
44
45#if wxUSE_STATLINE
c50f1fb9 46 #include "wx/statline.h"
c801d85f
KB
47#endif
48
49#include "wx/generic/choicdgg.h"
50
d6c9c1b7
VZ
51// ----------------------------------------------------------------------------
52// constants
53// ----------------------------------------------------------------------------
54
257bf510 55#define wxID_LISTBOX 3000
dcf924a3 56
4b088139
WS
57// ---------------------------------------------------------------------------
58// macros
59// ---------------------------------------------------------------------------
60
61/* Macro for avoiding #ifdefs when value have to be different depending on size of
9a357011 62 device we display on - take it from something like wxDesktopPolicy in the future
4b088139
WS
63 */
64
65#if defined(__SMARTPHONE__)
66 #define wxLARGESMALL(large,small) small
67#else
68 #define wxLARGESMALL(large,small) large
69#endif
70
d6c9c1b7
VZ
71// ----------------------------------------------------------------------------
72// private functions
73// ----------------------------------------------------------------------------
74
75// convert wxArrayString into a wxString[] which must be delete[]d by caller
76static int ConvertWXArrayToC(const wxArrayString& aChoices, wxString **choices);
77
78// ============================================================================
79// implementation
80// ============================================================================
81
82// ----------------------------------------------------------------------------
83// helpers
84// ----------------------------------------------------------------------------
85
86int ConvertWXArrayToC(const wxArrayString& aChoices, wxString **choices)
87{
88 int n = aChoices.GetCount();
89 *choices = new wxString[n];
54b84891 90
d6c9c1b7
VZ
91 for ( int i = 0; i < n; i++ )
92 {
ea660175 93 (*choices)[i] = aChoices[i];
d6c9c1b7
VZ
94 }
95
96 return n;
97}
98
99// ----------------------------------------------------------------------------
100// wrapper functions
101// ----------------------------------------------------------------------------
102
103wxString 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),
257bf510 109 int WXUNUSED(width), int WXUNUSED(height) )
c801d85f 110{
d427503c 111 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
3ca6a5f0 112 wxString choice;
d427503c 113 if ( dialog.ShowModal() == wxID_OK )
3ca6a5f0
BP
114 choice = dialog.GetStringSelection();
115
116 return choice;
c801d85f
KB
117}
118
d6c9c1b7
VZ
119wxString 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
d6c9c1b7
VZ
136int 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) )
c801d85f 143{
d427503c 144 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
3ca6a5f0 145 int choice;
d427503c 146 if ( dialog.ShowModal() == wxID_OK )
3ca6a5f0 147 choice = dialog.GetSelection();
d427503c 148 else
3ca6a5f0
BP
149 choice = -1;
150
151 return choice;
c801d85f
KB
152}
153
2adaf596
VS
154int 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
d6c9c1b7
VZ
171void *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) )
c801d85f 179{
b41ec29a
VZ
180 wxSingleChoiceDialog dialog(parent, message, caption, n, choices,
181 (char **)client_data);
3ca6a5f0 182 void *data;
d427503c 183 if ( dialog.ShowModal() == wxID_OK )
3ca6a5f0 184 data = dialog.GetSelectionClientData();
d427503c 185 else
3ca6a5f0
BP
186 data = NULL;
187
188 return data;
c801d85f
KB
189}
190
b41ec29a
VZ
191void *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
d6c9c1b7
VZ
210size_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);
e93bfe3c
VZ
220
221 if ( !selections.IsEmpty() )
222 dialog.SetSelections(selections);
223
d6c9c1b7
VZ
224 if ( dialog.ShowModal() == wxID_OK )
225 selections = dialog.GetSelections();
226 else
227 selections.Empty();
c801d85f 228
d6c9c1b7
VZ
229 return selections.GetCount();
230}
c801d85f 231
59bd9598 232size_t wxGetMultipleChoices(wxArrayInt& selections,
d6c9c1b7
VZ
233 const wxString& message,
234 const wxString& caption,
235 const wxArrayString& aChoices,
236 wxWindow *parent,
237 int x, int y,
238 bool centre,
239 int width, int height)
c801d85f 240{
d6c9c1b7
VZ
241 wxString *choices;
242 int n = ConvertWXArrayToC(aChoices, &choices);
243 size_t res = wxGetMultipleChoices(selections, message, caption,
244 n, choices, parent,
245 x, y, centre, width, height);
246 delete [] choices;
247
248 return res;
c801d85f 249}
c801d85f 250
d6c9c1b7
VZ
251// ----------------------------------------------------------------------------
252// wxAnyChoiceDialog
253// ----------------------------------------------------------------------------
254
255bool wxAnyChoiceDialog::Create(wxWindow *parent,
256 const wxString& message,
257 const wxString& caption,
258 int n, const wxString *choices,
ea660175 259 long styleDlg,
d6c9c1b7
VZ
260 const wxPoint& pos,
261 long styleLbox)
262{
ca65c044
WS
263 if ( !wxDialog::Create(parent, wxID_ANY, caption, pos, wxDefaultSize, styleDlg) )
264 return false;
d6c9c1b7
VZ
265
266 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
267
64c794f6 268 // 1) text message
718970e5 269 topsizer->Add( CreateTextSizer( message ), 0, wxALL, wxLARGESMALL(10,0) );
64c794f6
WS
270
271 // 2) list box
272 m_listbox = new wxListBox( this, wxID_LISTBOX,
273 wxDefaultPosition, wxDefaultSize,
274 n, choices,
275 styleLbox );
276 if ( n > 0 )
277 m_listbox->SetSelection(0);
278
718970e5 279 topsizer->Add( m_listbox, 1, wxEXPAND | wxLEFT|wxRIGHT, wxLARGESMALL(15,0) );
119727ad 280
9a357011 281 // smart phones does not support or do not waste space for wxButtons
119727ad 282#ifdef __SMARTPHONE__
64c794f6
WS
283
284 SetRightMenu(wxID_CANCEL, _("Cancel"));
285
286#else // __SMARTPHONE__/!__SMARTPHONE__
287
d6c9c1b7
VZ
288#if wxUSE_STATLINE
289 // 3) static line
ca65c044 290 topsizer->Add( new wxStaticLine( this, wxID_ANY ), 0, wxEXPAND | wxLEFT|wxRIGHT|wxTOP, 10 );
d6c9c1b7
VZ
291#endif
292
293 // 4) buttons
ea660175 294 topsizer->Add( CreateButtonSizer( styleDlg & (wxOK|wxCANCEL) ), 0, wxCENTRE | wxALL, 10 );
d6c9c1b7 295
64c794f6
WS
296#endif // !__SMARTPHONE__
297
ca65c044 298 SetAutoLayout( true );
d6c9c1b7
VZ
299 SetSizer( topsizer );
300
301 topsizer->SetSizeHints( this );
302 topsizer->Fit( this );
303
8316ff5d
VS
304 if ( styleDlg & wxCENTRE )
305 Centre(wxBOTH);
d6c9c1b7
VZ
306
307 m_listbox->SetFocus();
308
ca65c044 309 return true;
d6c9c1b7
VZ
310}
311
584ad2a3
MB
312bool wxAnyChoiceDialog::Create(wxWindow *parent,
313 const wxString& message,
314 const wxString& caption,
315 const wxArrayString& choices,
316 long styleDlg,
317 const wxPoint& pos,
318 long styleLbox)
319{
320 wxCArrayString chs(choices);
321 return Create(parent, message, caption, chs.GetCount(), chs.GetStrings(),
322 styleDlg, pos, styleLbox);
323}
324
d6c9c1b7 325// ----------------------------------------------------------------------------
c801d85f 326// wxSingleChoiceDialog
d6c9c1b7 327// ----------------------------------------------------------------------------
c801d85f 328
c801d85f 329BEGIN_EVENT_TABLE(wxSingleChoiceDialog, wxDialog)
d427503c
VZ
330 EVT_BUTTON(wxID_OK, wxSingleChoiceDialog::OnOK)
331 EVT_LISTBOX_DCLICK(wxID_LISTBOX, wxSingleChoiceDialog::OnListBoxDClick)
c801d85f
KB
332END_EVENT_TABLE()
333
d6c9c1b7 334IMPLEMENT_DYNAMIC_CLASS(wxSingleChoiceDialog, wxDialog)
257bf510
VZ
335
336wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
337 const wxString& message,
338 const wxString& caption,
c50f1fb9 339 int n,
257bf510
VZ
340 const wxString *choices,
341 char **clientData,
342 long style,
59bd9598 343 const wxPoint& WXUNUSED(pos))
c801d85f 344{
257bf510 345 Create(parent, message, caption, n, choices, clientData, style);
c801d85f
KB
346}
347
584ad2a3
MB
348wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
349 const wxString& message,
350 const wxString& caption,
351 const wxArrayString& choices,
352 char **clientData,
353 long style,
354 const wxPoint& WXUNUSED(pos))
355{
356 Create(parent, message, caption, choices, clientData, style);
357}
358
d6c9c1b7 359bool wxSingleChoiceDialog::Create( wxWindow *parent,
c50f1fb9 360 const wxString& message,
d6c9c1b7 361 const wxString& caption,
c50f1fb9 362 int n,
257bf510
VZ
363 const wxString *choices,
364 char **clientData,
365 long style,
d6c9c1b7 366 const wxPoint& pos )
c801d85f 367{
d6c9c1b7
VZ
368 if ( !wxAnyChoiceDialog::Create(parent, message, caption,
369 n, choices,
370 style, pos) )
ca65c044 371 return false;
92afa2b1 372
d6c9c1b7 373 m_selection = n > 0 ? 0 : -1;
92afa2b1 374
92afa2b1 375 if (clientData)
d427503c 376 {
257bf510
VZ
377 for (int i = 0; i < n; i++)
378 m_listbox->SetClientData(i, clientData[i]);
d427503c 379 }
c801d85f 380
ca65c044 381 return true;
c801d85f
KB
382}
383
584ad2a3
MB
384bool wxSingleChoiceDialog::Create( wxWindow *parent,
385 const wxString& message,
386 const wxString& caption,
387 const wxArrayString& choices,
388 char **clientData,
389 long style,
390 const wxPoint& pos )
391{
392 wxCArrayString chs(choices);
393 return Create( parent, message, caption, chs.GetCount(), chs.GetStrings(),
394 clientData, style, pos );
395}
396
ef77f91e
JS
397// Set the selection
398void wxSingleChoiceDialog::SetSelection(int sel)
399{
257bf510 400 m_listbox->SetSelection(sel);
ef77f91e
JS
401 m_selection = sel;
402}
403
c801d85f
KB
404void wxSingleChoiceDialog::OnOK(wxCommandEvent& WXUNUSED(event))
405{
257bf510
VZ
406 m_selection = m_listbox->GetSelection();
407 m_stringSelection = m_listbox->GetStringSelection();
eb553cb2 408 if ( m_listbox->HasClientUntypedData() )
59af5f19 409 SetClientData(m_listbox->GetClientData(m_selection));
d427503c 410 EndModal(wxID_OK);
c801d85f
KB
411}
412
debe6624
JS
413void wxSingleChoiceDialog::OnListBoxDClick(wxCommandEvent& WXUNUSED(event))
414{
257bf510
VZ
415 m_selection = m_listbox->GetSelection();
416 m_stringSelection = m_listbox->GetStringSelection();
25f47127 417
eb553cb2 418 if ( m_listbox->HasClientUntypedData() )
59af5f19 419 SetClientData(m_listbox->GetClientData(m_selection));
d427503c
VZ
420
421 EndModal(wxID_OK);
debe6624
JS
422}
423
d6c9c1b7
VZ
424// ----------------------------------------------------------------------------
425// wxMultiChoiceDialog
426// ----------------------------------------------------------------------------
427
d6c9c1b7
VZ
428IMPLEMENT_DYNAMIC_CLASS(wxMultiChoiceDialog, wxDialog)
429
430bool wxMultiChoiceDialog::Create( wxWindow *parent,
431 const wxString& message,
432 const wxString& caption,
433 int n,
434 const wxString *choices,
435 long style,
436 const wxPoint& pos )
437{
438 if ( !wxAnyChoiceDialog::Create(parent, message, caption,
439 n, choices,
440 style, pos,
3d49ce44 441 wxLB_ALWAYS_SB | wxLB_EXTENDED) )
ca65c044 442 return false;
d6c9c1b7 443
ca65c044 444 return true;
d6c9c1b7
VZ
445}
446
584ad2a3
MB
447bool wxMultiChoiceDialog::Create( wxWindow *parent,
448 const wxString& message,
449 const wxString& caption,
450 const wxArrayString& choices,
451 long style,
452 const wxPoint& pos )
453{
454 wxCArrayString chs(choices);
455 return Create( parent, message, caption, chs.GetCount(),
456 chs.GetStrings(), style, pos );
457}
458
d6c9c1b7
VZ
459void wxMultiChoiceDialog::SetSelections(const wxArrayInt& selections)
460{
d0cc483d
VZ
461 // first clear all currently selected items
462 size_t n,
463 count = m_listbox->GetCount();
464 for ( n = 0; n < count; ++n )
465 {
466 m_listbox->Deselect(n);
467 }
468
469 // now select the ones which should be selected
470 count = selections.GetCount();
471 for ( n = 0; n < count; n++ )
d6c9c1b7
VZ
472 {
473 m_listbox->Select(selections[n]);
474 }
475}
476
3d49ce44 477bool wxMultiChoiceDialog::TransferDataFromWindow()
d6c9c1b7
VZ
478{
479 m_selections.Empty();
480 size_t count = m_listbox->GetCount();
481 for ( size_t n = 0; n < count; n++ )
482 {
483 if ( m_listbox->IsSelected(n) )
484 m_selections.Add(n);
485 }
486
ca65c044 487 return true;
d6c9c1b7 488}
1e6feb95
VZ
489
490#endif // wxUSE_CHOICEDLG