]> git.saurik.com Git - wxWidgets.git/blame - src/os2/choice.cpp
Fix another crash when conversion fails in Unix PostScript code.
[wxWidgets.git] / src / os2 / choice.cpp
CommitLineData
0e320a79 1/////////////////////////////////////////////////////////////////////////////
11e62fe6 2// Name: src/os2/choice.cpp
0e320a79 3// Purpose: wxChoice
37f214d5 4// Author: David Webster
0e320a79 5// Modified by:
37f214d5 6// Created: 10/13/99
37f214d5 7// Copyright: (c) David Webster
65571936 8// Licence: wxWindows licence
0e320a79
DW
9/////////////////////////////////////////////////////////////////////////////
10
37f214d5
DW
11// For compilers that support precompilation, includes "wx.h".
12#include "wx/wxprec.h"
13
312ebad4
WS
14#if wxUSE_CHOICE
15
b36e08d0
WS
16#include "wx/choice.h"
17
37f214d5 18#ifndef WX_PRECOMP
37f214d5
DW
19 #include "wx/utils.h"
20 #include "wx/log.h"
a4a16252 21 #include "wx/settings.h"
0e320a79
DW
22#endif
23
37f214d5 24#include "wx/os2/private.h"
0e320a79 25
584ad2a3
MB
26bool wxChoice::Create(
27 wxWindow* pParent
28, wxWindowID vId
29, const wxPoint& rPos
30, const wxSize& rSize
31, const wxArrayString& asChoices
32, long lStyle
33, const wxValidator& rValidator
34, const wxString& rsName
35)
36{
37 wxCArrayString chs(asChoices);
38
39 return Create(pParent, vId, rPos, rSize, chs.GetCount(), chs.GetStrings(),
40 lStyle, rValidator, rsName);
41}
42
0cf6acbf
DW
43bool wxChoice::Create(
44 wxWindow* pParent
45, wxWindowID vId
46, const wxPoint& rPos
47, const wxSize& rSize
48, int n
49, const wxString asChoices[]
50, long lStyle
0cf6acbf 51, const wxValidator& rValidator
0cf6acbf
DW
52, const wxString& rsName
53)
0e320a79 54{
0cf6acbf
DW
55 long lSstyle;
56
b9b1d6c8
DW
57 if (!CreateControl( pParent
58 ,vId
59 ,rPos
60 ,rSize
61 ,lStyle
b9b1d6c8 62 ,rValidator
b9b1d6c8
DW
63 ,rsName
64 ))
312ebad4 65 return false;
0cf6acbf 66 lSstyle = CBS_DROPDOWNLIST |
5d44b24e
DW
67 WS_TABSTOP |
68 WS_VISIBLE;
0cf6acbf 69
2fbb8fbb
SN
70 // clipping siblings does not yet work
71 // if (lStyle & wxCLIP_SIBLINGS )
72 // lSstyle |= WS_CLIPSIBLINGS;
0cf6acbf
DW
73
74 wxASSERT_MSG( !(lStyle & wxCB_DROPDOWN) &&
75 !(lStyle & wxCB_READONLY) &&
76 !(lStyle & wxCB_SIMPLE),
37f214d5
DW
77 wxT("this style flag is ignored by wxChoice, you "
78 "probably want to use a wxComboBox") );
0e320a79 79
0cf6acbf
DW
80 if (!OS2CreateControl( wxT("COMBOBOX")
81 ,lSstyle
82 ))
312ebad4 83 return false;
0e320a79 84
0cf6acbf
DW
85 //
86 // A choice/combobox normally has a white background (or other, depending
87 // on global settings) rather than inheriting the parent's background colour.
88 //
a756f210 89 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
0934d91c
SN
90
91 // initialize the controls contents
0cf6acbf 92 for (int i = 0; i < n; i++)
37f214d5 93 {
0cf6acbf 94 Append(asChoices[i]);
37f214d5 95 }
0cf6acbf
DW
96 SetSize( rPos.x
97 ,rPos.y
98 ,rSize.x
99 ,rSize.y
100 );
21a9132e
SN
101
102 // Set height to use with sizers i.e. without the dropdown listbox
103 wxFont vFont = GetFont();
2fbb8fbb
SN
104 int nEditHeight;
105 wxGetCharSize( GetHWND(), NULL, &nEditHeight, &vFont );
106 nEditHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nEditHeight);
170acdc9 107 SetInitialSize(wxSize(-1,nEditHeight+4)); // +2x2 for the border
21a9132e 108
312ebad4 109 return true;
0cf6acbf 110} // end of wxChoice::Create
0e320a79 111
0934d91c
SN
112wxChoice::~wxChoice()
113{
a236aa20 114 Clear();
0934d91c
SN
115}
116
37f214d5
DW
117// ----------------------------------------------------------------------------
118// adding/deleting items to/from the list
119// ----------------------------------------------------------------------------
120
a236aa20
VZ
121int wxChoice::DoInsertItems(const wxArrayStringsAdapter& items
122 , unsigned int pos
123 , void **clientData
124 , wxClientDataType type
125 )
0e320a79 126{
a236aa20 127 int nIndex = wxNOT_FOUND;
9923c37d 128 LONG nIndexType = 0;
a236aa20
VZ
129 bool incrementPos = false;
130 if ( IsSorted() )
0cf6acbf 131 nIndexType = LIT_SORTASCENDING;
a236aa20 132 else if (pos == GetCount())
0cf6acbf 133 nIndexType = LIT_END;
243dbf1a 134 else
a236aa20 135 {
243dbf1a 136 nIndexType = pos;
a236aa20
VZ
137 incrementPos = true;
138 }
139
140 const unsigned int count = items.GetCount();
141 for( unsigned int i = 0; i < count; ++i )
142 {
143 nIndex = (int)::WinSendMsg( GetHwnd()
144 ,LM_INSERTITEM
145 ,(MPARAM)nIndexType
146 ,(MPARAM)items[i].wx_str()
147 );
148 if (nIndex < 0)
149 {
150 nIndex = wxNOT_FOUND;
151 break;
152 }
153 AssignNewItemClientData(nIndex, clientData, i, type);
154
155 if (incrementPos)
156 ++nIndexType;
157 }
243dbf1a 158 return nIndex;
a236aa20 159} // end of wxChoice::DoInsertAppendItemsWithData
243dbf1a 160
a236aa20 161void wxChoice::DoDeleteOneItem(unsigned int n)
0e320a79 162{
8228b893 163 wxCHECK_RET( IsValid(n), wxT("invalid item index in wxChoice::Delete") );
0934d91c 164
0cf6acbf
DW
165 ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0);
166} // end of wxChoice::Delete
0e320a79 167
a236aa20 168void wxChoice::DoClear()
0e320a79 169{
0cf6acbf
DW
170 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
171} // end of wxChoice::Clear
0e320a79 172
37f214d5
DW
173// ----------------------------------------------------------------------------
174// selection
175// ----------------------------------------------------------------------------
176
0e320a79
DW
177int wxChoice::GetSelection() const
178{
0cf6acbf
DW
179 return((int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0)));
180} // end of wxChoice::GetSelection
0e320a79 181
0cf6acbf
DW
182void wxChoice::SetSelection(
183 int n
184)
0e320a79 185{
0cf6acbf
DW
186 ::WinSendMsg( GetHwnd()
187 ,LM_SELECTITEM
188 ,(MPARAM)n
189 ,(MPARAM)TRUE
190 );
191} // end of wxChoice::SetSelection
37f214d5
DW
192
193// ----------------------------------------------------------------------------
194// string list functions
195// ----------------------------------------------------------------------------
196
aa61d352 197unsigned int wxChoice::GetCount() const
37f214d5 198{
aa61d352 199 return((unsigned int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMCOUNT, (MPARAM)0, (MPARAM)0)));
0cf6acbf 200} // end of wxChoice::GetCount
0e320a79 201
aa61d352 202void wxChoice::SetString(unsigned int n, const wxString& rsStr)
0e320a79 203{
11e62fe6
WS
204 LONG nIndexType = 0;
205 void* pData;
57ff8a87 206
37f68a79 207 if ( HasClientData() )
57ff8a87
DW
208 {
209 pData = DoGetItemClientData(n);
210 }
211 else // no client data
212 {
213 pData = NULL;
214 }
dcd307ee 215
e90bc5bf 216 ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, 0);
58238121 217
2fbb8fbb 218 if (m_windowStyle & wxCB_SORT)
58238121
DW
219 nIndexType = LIT_SORTASCENDING;
220 else
221 nIndexType = LIT_END;
e90bc5bf
DW
222 ::WinSendMsg( GetHwnd()
223 ,LM_INSERTITEM
224 ,(MPARAM)nIndexType
404aba09 225 ,(MPARAM)rsStr.wx_str()
e90bc5bf 226 );
57ff8a87
DW
227
228 if (pData)
229 {
aa61d352 230 DoSetItemClientData(n, pData);
57ff8a87 231 }
0cf6acbf 232} // end of wxChoice::SetString
dcd307ee 233
aa61d352 234wxString wxChoice::GetString(unsigned int n) const
0e320a79 235{
11e62fe6
WS
236 int nLen = 0;
237 wxString sStr = wxEmptyString;
238 wxChar* zBuf;
0cf6acbf
DW
239
240 nLen = (size_t)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMTEXTLENGTH, (MPARAM)n, (MPARAM)0));
cfcebdb1 241 if (nLen != LIT_ERROR && nLen > 0)
0cf6acbf 242 {
21a9132e 243 zBuf = new wxChar[++nLen];
0cf6acbf
DW
244 ::WinSendMsg( GetHwnd()
245 ,LM_QUERYITEMTEXT
246 ,MPFROM2SHORT((SHORT)n, (SHORT)nLen)
247 ,(MPARAM)zBuf
248 );
249 sStr = zBuf;
250 delete [] zBuf;
37f214d5 251 }
0cf6acbf
DW
252 return sStr;
253} // end of wxChoice::GetString
0e320a79 254
37f214d5
DW
255// ----------------------------------------------------------------------------
256// client data
257// ----------------------------------------------------------------------------
258
aa61d352 259void wxChoice::DoSetItemClientData(unsigned int n, void* pClientData)
0e320a79 260{
0cf6acbf
DW
261 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)n, MPFROMP(pClientData));
262} // end of wxChoice::DoSetItemClientData
0e320a79 263
aa61d352 264void* wxChoice::DoGetItemClientData(unsigned int n) const
0e320a79 265{
aa61d352 266 MRESULT rc = ::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, (MPARAM)n, (MPARAM)0);
0cf6acbf 267 return((void*)rc);
aa61d352 268} // end of wxChoice::DoGetItemClientData
0e320a79 269
37f214d5
DW
270// ----------------------------------------------------------------------------
271// wxOS2 specific helpers
272// ----------------------------------------------------------------------------
273
6670f564
WS
274void wxChoice::DoSetSize(int nX,
275 int nY,
276 int nWidth,
277 int WXUNUSED(nHeight),
278 int nSizeFlags)
37f214d5 279{
0cf6acbf 280 //
37f214d5
DW
281 // Ignore height parameter because height doesn't mean 'initially
282 // displayed' height, it refers to the drop-down menu as well. The
77ffb593 283 // wxWidgets interpretation is different; also, getting the size returns
37f214d5
DW
284 // the _displayed_ size (NOT the drop down menu size) so
285 // setting-getting-setting size would not work.
0cf6acbf
DW
286 //
287 wxControl::DoSetSize( nX
288 ,nY
289 ,nWidth
6670f564 290 ,wxDefaultCoord
0cf6acbf
DW
291 ,nSizeFlags
292 );
293} // end of wxChoice::DoSetSize
37f214d5 294
e78c4d50 295wxSize wxChoice::DoGetBestSize() const
37f214d5 296{
0cf6acbf
DW
297 //
298 // Find the widest string
299 //
8228b893
WS
300 int nLineWidth;
301 int nChoiceWidth = 0;
302 int nCx;
303 int nCy;
304 wxFont vFont = (wxFont)GetFont();
305
aa61d352 306 const unsigned int nItems = GetCount();
0cf6acbf 307
aa61d352 308 for (unsigned int i = 0; i < nItems; i++)
8228b893
WS
309 {
310 wxString sStr(GetString(i));
311 GetTextExtent( sStr, &nLineWidth, NULL );
0cf6acbf
DW
312 if (nLineWidth > nChoiceWidth)
313 nChoiceWidth = nLineWidth;
37f214d5
DW
314 }
315
0cf6acbf
DW
316 //
317 // Give it some reasonable default value if there are no strings in the
37f214d5 318 // list
0cf6acbf
DW
319 //
320 if (nChoiceWidth == 0L)
321 nChoiceWidth = 100L;
322
323 //
324 // The combobox should be larger than the widest string
325 //
8228b893 326 wxGetCharSize( GetHWND(), &nCx, &nCy, &vFont );
0cf6acbf
DW
327 nChoiceWidth += 5 * nCx;
328
329 //
37f214d5 330 // Choice drop-down list depends on number of items (limited to 10)
0cf6acbf 331 //
aa61d352
VZ
332 size_t nStrings = nItems == 0 ? 10 : wxMin(10, nItems) + 1;
333 int nChoiceHeight = EDIT_HEIGHT_FROM_CHAR_HEIGHT(nCy) * nStrings;
0cf6acbf 334
aa61d352 335 return wxSize(nChoiceWidth, nChoiceHeight);
0cf6acbf
DW
336} // end of wxChoice::DoGetBestSize
337
338MRESULT wxChoice::OS2WindowProc(
339 WXUINT uMsg
340, WXWPARAM wParam
341, WXLPARAM lParam
342)
37f214d5 343{
0cf6acbf
DW
344 return wxWindow::OS2WindowProc( uMsg
345 ,wParam
346 ,lParam
347 );
348} // end of wxChoice::OS2WindowProc
349
350bool wxChoice::OS2Command(
351 WXUINT uParam
352, WXWORD WXUNUSED(wId)
353)
37f214d5 354{
0cf6acbf 355 if (uParam != LN_SELECT)
37f214d5 356 {
0cf6acbf 357 //
37f214d5 358 // "selection changed" is the only event we're after
0cf6acbf 359 //
312ebad4 360 return false;
37f214d5 361 }
0cf6acbf 362 int n = GetSelection();
37f214d5 363
0cf6acbf
DW
364 if (n > -1)
365 {
ce7fe42e 366 wxCommandEvent vEvent( wxEVT_CHOICE
0cf6acbf
DW
367 ,m_windowId
368 );
369
370 vEvent.SetInt(n);
371 vEvent.SetEventObject(this);
0fba44b4 372 vEvent.SetString(GetStringSelection());
0cf6acbf
DW
373 if (HasClientObjectData())
374 vEvent.SetClientObject(GetClientObject(n));
375 else if (HasClientUntypedData())
376 vEvent.SetClientData(GetClientData(n));
377 ProcessCommand(vEvent);
378 }
312ebad4 379 return true;
0cf6acbf 380} // end of wxChoice::OS2Command
0e320a79 381
312ebad4 382#endif // wxUSE_CHOICE