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