]> git.saurik.com Git - wxWidgets.git/blame - src/generic/choicdgg.cpp
Added #include wx/listbox.h needed under Linux (probably all precomp header
[wxWidgets.git] / src / generic / choicdgg.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
dfad0599 2// Name: choicdgg.cpp
c801d85f
KB
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
d427503c 9// Licence: wxWindows license
c801d85f
KB
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
d427503c 13 #pragma implementation "choicdgg.h"
c801d85f
KB
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
d427503c 20 #pragma hdrstop
c801d85f
KB
21#endif
22
23#ifndef WX_PRECOMP
257bf510
VZ
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"
dcf924a3
RR
31#endif
32
33#if wxUSE_STATLINE
257bf510 34 #include "wx/statline.h"
c801d85f
KB
35#endif
36
37#include "wx/generic/choicdgg.h"
38
257bf510 39#define wxID_LISTBOX 3000
dcf924a3 40
debe6624
JS
41wxString wxGetSingleChoice( const wxString& message, const wxString& caption, int n,
42 const wxString *choices, wxWindow *parent,
257bf510
VZ
43 int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(centre),
44 int WXUNUSED(width), int WXUNUSED(height) )
c801d85f 45{
d427503c
VZ
46 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
47 if ( dialog.ShowModal() == wxID_OK )
d427503c 48 return dialog.GetStringSelection();
d427503c 49 else
dcf924a3 50 return _T("");
c801d85f
KB
51}
52
53// Overloaded for backward compatibility
debe6624
JS
54wxString wxGetSingleChoice( const wxString& message, const wxString& caption, int n,
55 char *choices[], wxWindow *parent,
257bf510
VZ
56 int x, int y, bool centre,
57 int width, int height )
c801d85f 58{
d427503c
VZ
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;
c801d85f
KB
69}
70
debe6624
JS
71int wxGetSingleChoiceIndex( const wxString& message, const wxString& caption, int n,
72 const wxString *choices, wxWindow *parent,
d427503c
VZ
73 int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(centre),
74 int WXUNUSED(width), int WXUNUSED(height) )
c801d85f 75{
d427503c
VZ
76 wxSingleChoiceDialog dialog(parent, message, caption, n, choices);
77 if ( dialog.ShowModal() == wxID_OK )
d427503c 78 return dialog.GetSelection();
d427503c
VZ
79 else
80 return -1;
c801d85f
KB
81}
82
83// Overloaded for backward compatibility
debe6624 84int wxGetSingleChoiceIndex( const wxString& message, const wxString& caption, int n,
87138c52 85 wxChar *choices[], wxWindow *parent,
d427503c
VZ
86 int x, int y, bool centre,
87 int width, int height )
c801d85f 88{
d427503c 89 wxString *strings = new wxString[n];
dcf924a3 90 for ( int i = 0; i < n; i++)
d427503c 91 strings[i] = choices[i];
d427503c
VZ
92 int ans = wxGetSingleChoiceIndex(message, caption, n, (const wxString *)strings, parent,
93 x, y, centre, width, height);
94 delete[] strings;
95 return ans;
c801d85f
KB
96}
97
87138c52 98wxChar *wxGetSingleChoiceData( const wxString& message, const wxString& caption, int n,
d427503c
VZ
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) )
c801d85f 102{
d427503c
VZ
103 wxSingleChoiceDialog dialog(parent, message, caption, n, choices, client_data);
104 if ( dialog.ShowModal() == wxID_OK )
d427503c 105 return dialog.GetSelectionClientData();
d427503c
VZ
106 else
107 return NULL;
c801d85f
KB
108}
109
110// Overloaded for backward compatibility
87138c52 111wxChar *wxGetSingleChoiceData( const wxString& message, const wxString& caption, int n,
d427503c
VZ
112 wxChar *choices[], wxChar **client_data, wxWindow *parent,
113 int x, int y, bool centre,
114 int width, int height )
c801d85f 115{
d427503c
VZ
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;
c801d85f
KB
126}
127
128
129/* Multiple choice dialog contributed by Robert Cowell
130 *
131
132The new data passed are in the "int nsel" and "int * selection"
133
134The idea is to make a multiple selection from list of strings.
135The returned value is the total number selected. initialily there
136are nsel selected, with indices stored in
137selection[0],...,selection[nsel-1] which appear highlighted to
138begin with. On exit with value i
139selection[0..i-1] contains the indices of the selected items.
140(Some prior selectecions might be deselected.)
141Thus selection must be as big as choices, in case all items are
142selected.
143
144*/
145/*
146int wxGetMultipleChoice(const wxString& message, const wxString& caption,
d427503c
VZ
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)
c801d85f 151{
d427503c 152 return -1;
c801d85f
KB
153}
154*/
155
156// wxSingleChoiceDialog
157
158#if !USE_SHARED_LIBRARY
159BEGIN_EVENT_TABLE(wxSingleChoiceDialog, wxDialog)
d427503c
VZ
160 EVT_BUTTON(wxID_OK, wxSingleChoiceDialog::OnOK)
161 EVT_LISTBOX_DCLICK(wxID_LISTBOX, wxSingleChoiceDialog::OnListBoxDClick)
c801d85f
KB
162END_EVENT_TABLE()
163
164IMPLEMENT_CLASS(wxSingleChoiceDialog, wxDialog)
165#endif
166
257bf510
VZ
167#define wxCHOICEDLG_DIALOG_STYLE (wxDEFAULT_DIALOG_STYLE | \
168 wxDIALOG_MODAL | \
169 wxTAB_TRAVERSAL)
170
171wxSingleChoiceDialog::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)
c801d85f 181{
257bf510 182 Create(parent, message, caption, n, choices, clientData, style);
c801d85f
KB
183}
184
257bf510
VZ
185wxSingleChoiceDialog::wxSingleChoiceDialog(wxWindow *parent,
186 const wxString& message,
187 const wxString& caption,
188 const wxStringList& choices,
189 wxChar **clientData,
190 long style,
191 const wxPoint& pos)
192 : wxDialog(parent, -1, caption, pos, wxDefaultSize,
193 wxCHOICEDLG_DIALOG_STYLE)
c801d85f 194{
257bf510 195 Create(parent, message, caption, choices, clientData, style);
c801d85f
KB
196}
197
257bf510
VZ
198bool 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)
c801d85f 205{
d427503c
VZ
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;
c801d85f
KB
215}
216
257bf510
VZ
217bool 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,
d427503c 224 const wxPoint& WXUNUSED(pos) )
c801d85f 225{
d427503c
VZ
226 m_dialogStyle = style;
227 m_selection = 0;
d427503c 228 m_clientData = NULL;
c801d85f 229
257bf510
VZ
230 // dialog layout constants
231 static const int LAYOUT_X_MARGIN = 5;
232 static const int LAYOUT_Y_MARGIN = 5;
233 static const int MARGIN_BETWEEN_BUTTONS = 3*LAYOUT_X_MARGIN;
234
235 // calc the message size
236 // ---------------------
237
238 // TODO this should be factored out to a common function (also used in
239 // msgdlgg.cpp)
240 wxClientDC dc(this);
241 dc.SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
242
243 wxArrayString lines;
244 wxString curLine;
245 long height, width, heightTextMax = 0, widthTextMax = 0;
246 for ( const char *pc = message; ; pc++ ) {
247 if ( *pc == '\n' || *pc == '\0' ) {
248 dc.GetTextExtent(curLine, &width, &height);
249 if ( width > widthTextMax )
250 widthTextMax = width;
251 if ( height > heightTextMax )
252 heightTextMax = height;
253
254 lines.Add(curLine);
255
256 if ( *pc == '\n' ) {
257 curLine.Empty();
258 }
259 else {
260 // the end of string
261 break;
262 }
263 }
264 else {
265 curLine += *pc;
266 }
267 }
dcf924a3 268
257bf510
VZ
269 size_t nLineCount = lines.Count();
270 long hTotalMsg = heightTextMax*nLineCount;
271
272 // calc the button size
273 // --------------------
274
275 bool hasCancel = FALSE;
276
277 // always create the OK button - the code below supposes we do have buttons
278 // and besides the user should have some way to close this dialog
279 wxASSERT_MSG( style & wxOK, _T("this dialog should have OK button") );
280
281 wxString labelOk(_("OK"));
282 long wButton = 0;
283 dc.GetTextExtent(labelOk, &width, NULL);
284 if ( width > wButton )
285 wButton = width;
286
287 wxString labelCancel;
288 if ( style & wxCANCEL )
d427503c 289 {
257bf510
VZ
290 labelCancel = _("Cancel");
291 dc.GetTextExtent(labelCancel, &width, NULL);
292 if ( width > wButton )
293 wButton = width;
294
295 hasCancel = TRUE;
d427503c
VZ
296 }
297
257bf510
VZ
298 if ( wButton < 75 )
299 wButton = 75;
300 else
301 wButton += 10;
302
303 long hButton = wButton*23/75;
304 long wTotalButtons = wButton;
305 if ( hasCancel )
dcf924a3 306 {
257bf510
VZ
307 wTotalButtons *= 2; // second button
308 wTotalButtons += MARGIN_BETWEEN_BUTTONS; // margin between the 2
d427503c 309 }
c801d85f 310
257bf510
VZ
311 // listbox and stat line
312 // ---------------------
313
314 // make the listbox at least as tall as the message - otherwise it looks
315 // ugly (the lower limit of 300 for the width is arbitrary OTOH)
316 //
317 // NB: we write "n + 2" because the horiz. scrollbar also takes some place
318 long hListbox = wxMax((n + 2) * heightTextMax, hTotalMsg),
319 wListbox = wxMax(300, wxMax(wTotalButtons, widthTextMax));
320
321#if wxUSE_STATLINE
322 // arbitrary...
323 long hStatLine = 5;
324#endif
325
326 // now the complete dialog size
327 // ----------------------------
328
329 long hDialog = 2*LAYOUT_Y_MARGIN + // top margin
330 hTotalMsg + // message
331 2*LAYOUT_Y_MARGIN + // margin between text and listbox
332 hListbox + // listbox
333#if wxUSE_STATLINE
334 LAYOUT_Y_MARGIN + // margin
335 hStatLine + // separator line
336#endif
337 2*LAYOUT_Y_MARGIN + // margin between listbox and buttons
338 hButton + // button(s)
339 LAYOUT_Y_MARGIN; // bottom margin
340
341 long wDialog = wxMax(wTotalButtons, widthTextMax) +
342 4*LAYOUT_X_MARGIN; // 2 from each side
343
344 // create the controls
345 // -------------------
346
347 // message
348 wxStaticText *text;
349 int y = 2*LAYOUT_Y_MARGIN;
350 for ( size_t nLine = 0; nLine < nLineCount; nLine++ )
dcf924a3 351 {
257bf510
VZ
352 text = new wxStaticText(this, -1, lines[nLine],
353 wxPoint(2*LAYOUT_X_MARGIN, y),
354 wxSize(widthTextMax, heightTextMax));
355 y += heightTextMax;
d427503c 356 }
c801d85f 357
257bf510
VZ
358 y += 2*LAYOUT_X_MARGIN;
359
360 // listbox
361 m_listbox = new wxListBox( this, wxID_LISTBOX,
362 wxPoint(2*LAYOUT_X_MARGIN, y),
363 wxSize(wListbox, hListbox),
364 n, choices,
365 wxLB_HSCROLL);
366 y += hListbox;
367
368 if ( clientData )
d427503c 369 {
257bf510
VZ
370 for (int i = 0; i < n; i++)
371 m_listbox->SetClientData(i, clientData[i]);
d427503c 372 }
c801d85f 373
257bf510
VZ
374 // separator line
375#if wxUSE_STATLINE
376 (void) new wxStaticLine( this, -1,
377 wxPoint(0, y + LAYOUT_Y_MARGIN),
378 wxSize(wDialog, hStatLine) );
379
380 y += LAYOUT_Y_MARGIN + hStatLine;
381#endif
dcf924a3 382
257bf510
VZ
383 // buttons
384
385 y += 2*LAYOUT_X_MARGIN;
386
387 // NB: create [Ok] first to get the right tab order
388
389 wxButton *ok = (wxButton *) NULL;
390 wxButton *cancel = (wxButton *) NULL;
dcf924a3 391
257bf510
VZ
392 long x = wDialog / 2;
393 if ( hasCancel )
394 x -= MARGIN_BETWEEN_BUTTONS / 2 + wButton;
395 else
396 x -= wButton / 2;
397
398 ok = new wxButton( this, wxID_OK, labelOk,
399 wxPoint(x, y),
400 wxSize(wButton, hButton) );
401
402 if ( hasCancel )
dcf924a3 403 {
257bf510
VZ
404 x += MARGIN_BETWEEN_BUTTONS + wButton;
405 cancel = new wxButton( this, wxID_CANCEL, labelCancel,
406 wxPoint(x, y),
407 wxSize(wButton, hButton) );
dcf924a3 408 }
dcf924a3 409
257bf510
VZ
410 ok->SetDefault();
411 ok->SetFocus();
412
413 SetClientSize( wDialog, hDialog );
c801d85f 414
257bf510 415 Centre( wxBOTH );
c801d85f 416
d427503c 417 return TRUE;
c801d85f
KB
418}
419
ef77f91e
JS
420// Set the selection
421void wxSingleChoiceDialog::SetSelection(int sel)
422{
257bf510 423 m_listbox->SetSelection(sel);
ef77f91e
JS
424 m_selection = sel;
425}
426
c801d85f
KB
427void wxSingleChoiceDialog::OnOK(wxCommandEvent& WXUNUSED(event))
428{
257bf510
VZ
429 m_selection = m_listbox->GetSelection();
430 m_stringSelection = m_listbox->GetStringSelection();
431 m_clientData = m_listbox->GetClientData(m_selection);
d427503c
VZ
432
433 EndModal(wxID_OK);
c801d85f
KB
434}
435
debe6624
JS
436void wxSingleChoiceDialog::OnListBoxDClick(wxCommandEvent& WXUNUSED(event))
437{
257bf510
VZ
438 m_selection = m_listbox->GetSelection();
439 m_stringSelection = m_listbox->GetStringSelection();
440 m_clientData = m_listbox->GetClientData(m_selection);
d427503c
VZ
441
442 EndModal(wxID_OK);
debe6624
JS
443}
444