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