Someone need to make the clientdata be void* instead of this char*
[wxWidgets.git] / src / generic / choicdgg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: choicdgg.cpp
3 // Purpose: Choice dialogs
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "choicdgg.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #ifndef WX_PRECOMP
24 #include <stdio.h>
25 #include "wx/utils.h"
26 #include "wx/dialog.h"
27 #include "wx/button.h"
28 #include "wx/listbox.h"
29 #include "wx/stattext.h"
30 #include "wx/intl.h"
31 #endif
32
33 #if wxUSE_STATLINE
34 #include "wx/statline.h"
35 #endif
36
37 #include "wx/generic/choicdgg.h"
38
39 #define wxID_LISTBOX 3000
40
41 wxString wxGetSingleChoice( const wxString& message, const wxString& caption, int n,
42 const wxString *choices, wxWindow *parent,
43 int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(centre),
44 int WXUNUSED(width), int WXUNUSED(height) )
45 {
46 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
47 if ( dialog.ShowModal() == wxID_OK )
48 return dialog.GetStringSelection();
49 else
50 return _T("");
51 }
52
53 // Overloaded for backward compatibility
54 wxString wxGetSingleChoice( const wxString& message, const wxString& caption, int n,
55 char *choices[], wxWindow *parent,
56 int x, int y, bool centre,
57 int width, int height )
58 {
59 wxString *strings = new wxString[n];
60 int i;
61 for ( i = 0; i < n; i++)
62 {
63 strings[i] = choices[i];
64 }
65 wxString ans(wxGetSingleChoice(message, caption, n, (const wxString *)strings, parent,
66 x, y, centre, width, height));
67 delete[] strings;
68 return ans;
69 }
70
71 int wxGetSingleChoiceIndex( const wxString& message, const wxString& caption, int n,
72 const wxString *choices, wxWindow *parent,
73 int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(centre),
74 int WXUNUSED(width), int WXUNUSED(height) )
75 {
76 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
77 if ( dialog.ShowModal() == wxID_OK )
78 return dialog.GetSelection();
79 else
80 return -1;
81 }
82
83 // Overloaded for backward compatibility
84 int wxGetSingleChoiceIndex( const wxString& message, const wxString& caption, int n,
85 wxChar *choices[], wxWindow *parent,
86 int x, int y, bool centre,
87 int width, int height )
88 {
89 wxString *strings = new wxString[n];
90 for ( int i = 0; i < n; i++)
91 strings[i] = choices[i];
92 int ans = wxGetSingleChoiceIndex(message, caption, n, (const wxString *)strings, parent,
93 x, y, centre, width, height);
94 delete[] strings;
95 return ans;
96 }
97
98 wxChar *wxGetSingleChoiceData( const wxString& message, const wxString& caption, int n,
99 const wxString *choices, wxChar **client_data, wxWindow *parent,
100 int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(centre),
101 int WXUNUSED(width), int WXUNUSED(height) )
102 {
103 wxSingleChoiceDialog dialog(parent, message, caption, n, choices, (char **)client_data);
104 if ( dialog.ShowModal() == wxID_OK )
105 return (wxChar *)dialog.GetSelectionClientData();
106 else
107 return NULL;
108 }
109
110 // Overloaded for backward compatibility
111 wxChar *wxGetSingleChoiceData( const wxString& message, const wxString& caption, int n,
112 wxChar *choices[], wxChar **client_data, wxWindow *parent,
113 int x, int y, bool centre,
114 int width, int height )
115 {
116 wxString *strings = new wxString[n];
117 int i;
118 for ( i = 0; i < n; i++)
119 {
120 strings[i] = choices[i];
121 }
122 wxChar *data = wxGetSingleChoiceData(message, caption, n, (const wxString *)strings, client_data, parent,
123 x, y, centre, width, height);
124 delete[] strings;
125 return data;
126 }
127
128
129 /* Multiple choice dialog contributed by Robert Cowell
130 *
131
132 The new data passed are in the "int nsel" and "int * selection"
133
134 The idea is to make a multiple selection from list of strings.
135 The returned value is the total number selected. initialily there
136 are nsel selected, with indices stored in
137 selection[0],...,selection[nsel-1] which appear highlighted to
138 begin with. On exit with value i
139 selection[0..i-1] contains the indices of the selected items.
140 (Some prior selectecions might be deselected.)
141 Thus selection must be as big as choices, in case all items are
142 selected.
143
144 */
145 /*
146 int wxGetMultipleChoice(const wxString& message, const wxString& caption,
147 int n, const wxString *choices,
148 int nsel, int * selection,
149 wxWindow *parent , int x , int y, bool centre,
150 int width, int height)
151 {
152 return -1;
153 }
154 */
155
156 // wxSingleChoiceDialog
157
158 #if !USE_SHARED_LIBRARY
159 BEGIN_EVENT_TABLE(wxSingleChoiceDialog, wxDialog)
160 EVT_BUTTON(wxID_OK, wxSingleChoiceDialog::OnOK)
161 EVT_LISTBOX_DCLICK(wxID_LISTBOX, wxSingleChoiceDialog::OnListBoxDClick)
162 END_EVENT_TABLE()
163
164 IMPLEMENT_CLASS(wxSingleChoiceDialog, wxDialog)
165 #endif
166
167 #define wxCHOICEDLG_DIALOG_STYLE (wxDEFAULT_DIALOG_STYLE | \
168 wxDIALOG_MODAL | \
169 wxTAB_TRAVERSAL)
170
171 wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
172 const wxString& message,
173 const wxString& caption,
174 int n,
175 const wxString *choices,
176 char **clientData,
177 long style,
178 const wxPoint& pos)
179 : wxDialog(parent, -1, caption, pos, wxDefaultSize,
180 wxCHOICEDLG_DIALOG_STYLE)
181 {
182 Create(parent, message, caption, n, choices, clientData, style);
183 }
184
185 wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
186 const wxString& message,
187 const wxString& caption,
188 const wxStringList& choices,
189 char **clientData,
190 long style,
191 const wxPoint& pos)
192 : wxDialog(parent, -1, caption, pos, wxDefaultSize,
193 wxCHOICEDLG_DIALOG_STYLE)
194 {
195 Create(parent, message, caption, choices, clientData, style);
196 }
197
198 bool wxSingleChoiceDialog::Create(wxWindow *parent,
199 const wxString& message,
200 const wxString& caption,
201 const wxStringList& choices,
202 char **clientData,
203 long style,
204 const wxPoint& pos)
205 {
206 wxString *strings = new wxString[choices.Number()];
207 int i;
208 for ( i = 0; i < choices.Number(); i++)
209 {
210 strings[i] = (char *)choices.Nth(i)->Data();
211 }
212 bool ans = Create(parent, message, caption, choices.Number(), strings, clientData, style, pos);
213 delete[] strings;
214 return ans;
215 }
216
217 bool wxSingleChoiceDialog::Create( wxWindow *WXUNUSED(parent),
218 const wxString& message,
219 const wxString& WXUNUSED(caption),
220 int n,
221 const wxString *choices,
222 char **clientData,
223 long style,
224 const wxPoint& WXUNUSED(pos) )
225 {
226 m_selection = 0;
227 m_clientData = NULL;
228
229 // calc the message size
230 // ---------------------
231
232 wxArrayString lines;
233 wxSize sizeText = SplitTextMessage(message, &lines);
234 long heightTextMax = sizeText.GetHeight(),
235 widthTextMax = sizeText.GetWidth();
236 size_t nLineCount = lines.Count();
237 long hTotalMsg = heightTextMax*nLineCount;
238
239 // calc the button size
240 // --------------------
241
242 // always create the OK button - the code below supposes we do have buttons
243 // and besides the user should have some way to close this dialog
244 wxASSERT_MSG( style & wxOK, _T("this dialog should have OK button") );
245
246 bool hasCancel = (style & wxCANCEL) != 0;
247
248 wxSize sizeButtons = GetStandardButtonSize(hasCancel);
249
250 long wButton = sizeButtons.GetWidth(),
251 hButton = sizeButtons.GetHeight();
252
253 long wTotalButtons = wButton;
254 if ( hasCancel )
255 {
256 wTotalButtons *= 2; // second button
257 wTotalButtons += MARGIN_BETWEEN_BUTTONS; // margin between the 2
258 }
259
260 // listbox and stat line
261 // ---------------------
262
263 // make the listbox at least as tall as the message - otherwise it looks
264 // ugly (the lower limit of 300 for the width is arbitrary OTOH)
265 //
266 // NB: we write "n + 2" because the horiz. scrollbar also takes some place
267 long hListbox = wxMax((n + 2) * heightTextMax, hTotalMsg),
268 wListbox = wxMax(300, wxMax(wTotalButtons, widthTextMax));
269
270 #if wxUSE_STATLINE
271 long hStatLine = wxStaticLine::GetDefaultSize();
272 #endif
273
274 // now the complete dialog size
275 // ----------------------------
276
277 long hDialog = 2*LAYOUT_Y_MARGIN + // top margin
278 hTotalMsg + // message
279 2*LAYOUT_Y_MARGIN + // margin between text and listbox
280 hListbox + // listbox
281 #if wxUSE_STATLINE
282 LAYOUT_Y_MARGIN + // margin
283 hStatLine + // separator line
284 #endif
285 2*LAYOUT_Y_MARGIN + // margin between listbox and buttons
286 hButton + // button(s)
287 LAYOUT_Y_MARGIN; // bottom margin
288
289 long wDialog = wxMax(wListbox, wxMax(wTotalButtons, widthTextMax)) +
290 4*LAYOUT_X_MARGIN; // 2 from each side
291
292 // create the controls
293 // -------------------
294
295 // message
296 wxStaticText *text;
297 int y = 2*LAYOUT_Y_MARGIN;
298 for ( size_t nLine = 0; nLine < nLineCount; nLine++ )
299 {
300 text = new wxStaticText(this, -1, lines[nLine],
301 wxPoint(2*LAYOUT_X_MARGIN, y),
302 wxSize(widthTextMax, heightTextMax));
303 y += heightTextMax;
304 }
305
306 y += 2*LAYOUT_X_MARGIN;
307
308 // listbox
309 m_listbox = new wxListBox( this, wxID_LISTBOX,
310 wxPoint(2*LAYOUT_X_MARGIN, y),
311 wxSize(wListbox, hListbox),
312 n, choices,
313 wxLB_HSCROLL);
314 y += hListbox;
315
316 if ( clientData )
317 {
318 for (int i = 0; i < n; i++)
319 m_listbox->SetClientData(i, clientData[i]);
320 }
321
322 // separator line
323 #if wxUSE_STATLINE
324 (void) new wxStaticLine( this, -1,
325 wxPoint(2*LAYOUT_X_MARGIN, y + LAYOUT_Y_MARGIN),
326 wxSize(wDialog - 4*LAYOUT_X_MARGIN, hStatLine) );
327
328 y += LAYOUT_Y_MARGIN + hStatLine;
329 #endif
330
331 // buttons
332
333 y += 2*LAYOUT_X_MARGIN;
334
335 CreateStandardButtons(wDialog, y, wButton, hButton, hasCancel);
336
337 SetClientSize( wDialog, hDialog );
338
339 Centre( wxBOTH );
340
341 return TRUE;
342 }
343
344 // Set the selection
345 void wxSingleChoiceDialog::SetSelection(int sel)
346 {
347 m_listbox->SetSelection(sel);
348 m_selection = sel;
349 }
350
351 void wxSingleChoiceDialog::OnOK(wxCommandEvent& WXUNUSED(event))
352 {
353 m_selection = m_listbox->GetSelection();
354 m_stringSelection = m_listbox->GetStringSelection();
355 m_clientData = m_listbox->GetClientData(m_selection);
356
357 EndModal(wxID_OK);
358 }
359
360 void wxSingleChoiceDialog::OnListBoxDClick(wxCommandEvent& WXUNUSED(event))
361 {
362 m_selection = m_listbox->GetSelection();
363 m_stringSelection = m_listbox->GetStringSelection();
364 m_clientData = m_listbox->GetClientData(m_selection);
365
366 EndModal(wxID_OK);
367 }
368