]> git.saurik.com Git - wxWidgets.git/blob - src/os2/choice.cpp
don't crash in UnselectAll() if the tree has no root
[wxWidgets.git] / src / os2 / choice.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: choice.cpp
3 // Purpose: wxChoice
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/13/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
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"
19 #endif
20
21 #include "wx/os2/private.h"
22
23 IMPLEMENT_DYNAMIC_CLASS(wxChoice, wxControl)
24
25 bool 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
33 #if wxUSE_VALIDATORS
34 , const wxValidator& rValidator
35 #endif
36 , const wxString& rsName
37 )
38 {
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 ))
51 return FALSE;
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),
62 wxT("this style flag is ignored by wxChoice, you "
63 "probably want to use a wxComboBox") );
64
65 if (!OS2CreateControl( wxT("COMBOBOX")
66 ,lSstyle
67 ))
68 return FALSE;
69
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++)
76 {
77 Append(asChoices[i]);
78 }
79 SetSize( rPos.x
80 ,rPos.y
81 ,rSize.x
82 ,rSize.y
83 );
84
85 return TRUE;
86 } // end of wxChoice::Create
87
88 // ----------------------------------------------------------------------------
89 // adding/deleting items to/from the list
90 // ----------------------------------------------------------------------------
91
92 int wxChoice::DoAppend(
93 const wxString& rsItem
94 )
95 {
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
111 void wxChoice::Delete(
112 int n
113 )
114 {
115 wxCHECK_RET( n < GetCount(), wxT("invalid item index in wxChoice::Delete") );
116 ::WinSendMsg(GetHwnd(), LM_DELETEITEM, (MPARAM)n, (MPARAM)0);
117 } // end of wxChoice::Delete
118
119 void wxChoice::Clear()
120 {
121 Free();
122 ::WinSendMsg(GetHwnd(), LM_DELETEALL, (MPARAM)0, (MPARAM)0);
123 } // end of wxChoice::Clear
124
125 // ----------------------------------------------------------------------------
126 // selection
127 // ----------------------------------------------------------------------------
128
129 int wxChoice::GetSelection() const
130 {
131 return((int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0)));
132 } // end of wxChoice::GetSelection
133
134 void wxChoice::SetSelection(
135 int n
136 )
137 {
138 ::WinSendMsg( GetHwnd()
139 ,LM_SELECTITEM
140 ,(MPARAM)n
141 ,(MPARAM)TRUE
142 );
143 } // end of wxChoice::SetSelection
144
145 // ----------------------------------------------------------------------------
146 // string list functions
147 // ----------------------------------------------------------------------------
148
149 int wxChoice::GetCount() const
150 {
151 return((int)LONGFROMMR(::WinSendMsg(GetHwnd(), LM_QUERYITEMCOUNT, (MPARAM)0, (MPARAM)0)));
152 } // end of wxChoice::GetCount
153
154 int wxChoice::FindString(
155 const wxString& rsStr
156 ) const
157 {
158 int nPos;
159 int nTextLength;
160 PSZ zStr;
161 int nItemCount;
162
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
178
179 void wxChoice::SetString(
180 int n
181 , const wxString& rsStr
182 )
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
190 } // end of wxChoice::SetString
191
192 wxString wxChoice::GetString(
193 int n
194 ) const
195 {
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;
211 }
212 return sStr;
213 } // end of wxChoice::GetString
214
215 // ----------------------------------------------------------------------------
216 // client data
217 // ----------------------------------------------------------------------------
218
219 void wxChoice::DoSetItemClientData(
220 int n
221 , void* pClientData
222 )
223 {
224 ::WinSendMsg(GetHwnd(), LM_SETITEMHANDLE, (MPARAM)n, MPFROMP(pClientData));
225 } // end of wxChoice::DoSetItemClientData
226
227 void* wxChoice::DoGetItemClientData( int n ) const
228 {
229 MRESULT rc = 0L;
230
231 rc = ::WinSendMsg(GetHwnd(), LM_QUERYITEMHANDLE, (MPARAM)n, (MPARAM)0);
232 return((void*)rc);
233 } // end of wxChoice::DoSetItemClientData
234
235 void wxChoice::DoSetItemClientObject(
236 int n
237 , wxClientData* pClientData
238 )
239 {
240 DoSetItemClientData( n
241 ,pClientData
242 );
243 } // end of wxChoice::DoSetItemClientObject
244
245 wxClientData* wxChoice::DoGetItemClientObject(
246 int n
247 ) const
248 {
249 return (wxClientData *)DoGetItemClientData(n);
250 } // end of wxChoice::DoGetItemClientObject
251
252 // ----------------------------------------------------------------------------
253 // wxOS2 specific helpers
254 // ----------------------------------------------------------------------------
255
256 void wxChoice::DoSetSize(
257 int nX
258 , int nY
259 , int nWidth
260 , int nHeight
261 , int nSizeFlags
262 )
263 {
264 //
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.
270 //
271 wxControl::DoSetSize( nX
272 ,nY
273 ,nWidth
274 ,-1
275 ,nSizeFlags
276 );
277 } // end of wxChoice::DoSetSize
278
279 wxSize wxChoice::DoGetBestSize() const
280 {
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++)
291 {
292 wxString sStr(GetString(i));
293
294 GetTextExtent( sStr
295 ,&nLineWidth
296 ,NULL
297 );
298 if (nLineWidth > nChoiceWidth)
299 nChoiceWidth = nLineWidth;
300 }
301
302 //
303 // Give it some reasonable default value if there are no strings in the
304 // list
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 //
320 // Choice drop-down list depends on number of items (limited to 10)
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
330 MRESULT wxChoice::OS2WindowProc(
331 WXUINT uMsg
332 , WXWPARAM wParam
333 , WXLPARAM lParam
334 )
335 {
336 return wxWindow::OS2WindowProc( uMsg
337 ,wParam
338 ,lParam
339 );
340 } // end of wxChoice::OS2WindowProc
341
342 bool wxChoice::OS2Command(
343 WXUINT uParam
344 , WXWORD WXUNUSED(wId)
345 )
346 {
347 if (uParam != LN_SELECT)
348 {
349 //
350 // "selection changed" is the only event we're after
351 //
352 return FALSE;
353 }
354 int n = GetSelection();
355
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 }
371 return TRUE;
372 } // end of wxChoice::OS2Command
373
374 void 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