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