XRC: make wxStaticText's wrap property a dimension.
[wxWidgets.git] / src / common / ctrlsub.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/ctrlsub.cpp
3 // Purpose: wxItemContainer implementation
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 22.10.99
7 // Copyright: (c) wxWidgets team
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_CONTROLS
27
28 #ifndef WX_PRECOMP
29 #include "wx/ctrlsub.h"
30 #include "wx/arrstr.h"
31 #endif
32
33 IMPLEMENT_ABSTRACT_CLASS(wxControlWithItems, wxControl)
34
35 // ============================================================================
36 // wxItemContainerImmutable implementation
37 // ============================================================================
38
39 wxItemContainerImmutable::~wxItemContainerImmutable()
40 {
41 // this destructor is required for Darwin
42 }
43
44 // ----------------------------------------------------------------------------
45 // selection
46 // ----------------------------------------------------------------------------
47
48 wxString wxItemContainerImmutable::GetStringSelection() const
49 {
50 wxString s;
51
52 int sel = GetSelection();
53 if ( sel != wxNOT_FOUND )
54 s = GetString((unsigned int)sel);
55
56 return s;
57 }
58
59 bool wxItemContainerImmutable::SetStringSelection(const wxString& s)
60 {
61 const int sel = FindString(s);
62 if ( sel == wxNOT_FOUND )
63 return false;
64
65 SetSelection(sel);
66
67 return true;
68 }
69
70 wxArrayString wxItemContainerImmutable::GetStrings() const
71 {
72 wxArrayString result;
73
74 const unsigned int count = GetCount();
75 result.Alloc(count);
76 for ( unsigned int n = 0; n < count; n++ )
77 result.Add(GetString(n));
78
79 return result;
80 }
81
82 // ============================================================================
83 // wxItemContainer implementation
84 // ============================================================================
85
86 wxItemContainer::~wxItemContainer()
87 {
88 // this destructor is required for Darwin
89 }
90
91 // ----------------------------------------------------------------------------
92 // deleting items
93 // ----------------------------------------------------------------------------
94
95 void wxItemContainer::Clear()
96 {
97 if ( HasClientObjectData() )
98 {
99 const unsigned count = GetCount();
100 for ( unsigned i = 0; i < count; ++i )
101 ResetItemClientObject(i);
102 }
103
104 SetClientDataType(wxClientData_None);
105
106 DoClear();
107 }
108
109 void wxItemContainer::Delete(unsigned int pos)
110 {
111 wxCHECK_RET( pos < GetCount(), wxT("invalid index") );
112
113 if ( HasClientObjectData() )
114 ResetItemClientObject(pos);
115
116 DoDeleteOneItem(pos);
117
118 if ( IsEmpty() )
119 {
120 SetClientDataType(wxClientData_None);
121 }
122 }
123
124 // ----------------------------------------------------------------------------
125 //
126 // ----------------------------------------------------------------------------
127
128 int wxItemContainer::DoInsertItemsInLoop(const wxArrayStringsAdapter& items,
129 unsigned int pos,
130 void **clientData,
131 wxClientDataType type)
132 {
133 int n = wxNOT_FOUND;
134
135 const unsigned int count = items.GetCount();
136 for ( unsigned int i = 0; i < count; ++i )
137 {
138 n = DoInsertOneItem(items[i], pos++);
139 if ( n == wxNOT_FOUND )
140 break;
141
142 AssignNewItemClientData(n, clientData, i, type);
143 }
144
145 return n;
146 }
147
148 int
149 wxItemContainer::DoInsertOneItem(const wxString& WXUNUSED(item),
150 unsigned int WXUNUSED(pos))
151 {
152 wxFAIL_MSG( wxT("Must be overridden if DoInsertItemsInLoop() is used") );
153
154 return wxNOT_FOUND;
155 }
156
157
158 // ----------------------------------------------------------------------------
159 // client data
160 // ----------------------------------------------------------------------------
161
162 void wxItemContainer::SetClientObject(unsigned int n, wxClientData *data)
163 {
164 wxASSERT_MSG( !HasClientUntypedData(),
165 wxT("can't have both object and void client data") );
166
167 wxCHECK_RET( IsValid(n), "Invalid index passed to SetClientObject()" );
168
169 if ( HasClientObjectData() )
170 {
171 wxClientData * clientDataOld
172 = static_cast<wxClientData *>(DoGetItemClientData(n));
173 if ( clientDataOld )
174 delete clientDataOld;
175 }
176 else // didn't have any client data so far
177 {
178 // now we have object client data
179 DoInitItemClientData();
180
181 SetClientDataType(wxClientData_Object);
182 }
183
184 DoSetItemClientData(n, data);
185 }
186
187 wxClientData *wxItemContainer::GetClientObject(unsigned int n) const
188 {
189 wxCHECK_MSG( HasClientObjectData(), NULL,
190 wxT("this window doesn't have object client data") );
191
192 wxCHECK_MSG( IsValid(n), NULL,
193 "Invalid index passed to GetClientObject()" );
194
195 return static_cast<wxClientData *>(DoGetItemClientData(n));
196 }
197
198 wxClientData *wxItemContainer::DetachClientObject(unsigned int n)
199 {
200 wxClientData * const data = GetClientObject(n);
201 if ( data )
202 {
203 // reset the pointer as we don't own it any more
204 DoSetItemClientData(n, NULL);
205 }
206
207 return data;
208 }
209
210 void wxItemContainer::SetClientData(unsigned int n, void *data)
211 {
212 if ( !HasClientData() )
213 {
214 DoInitItemClientData();
215 SetClientDataType(wxClientData_Void);
216 }
217
218 wxASSERT_MSG( HasClientUntypedData(),
219 wxT("can't have both object and void client data") );
220
221 wxCHECK_RET( IsValid(n), "Invalid index passed to SetClientData()" );
222
223 DoSetItemClientData(n, data);
224 }
225
226 void *wxItemContainer::GetClientData(unsigned int n) const
227 {
228 wxCHECK_MSG( HasClientUntypedData(), NULL,
229 wxT("this window doesn't have void client data") );
230
231 wxCHECK_MSG( IsValid(n), NULL,
232 "Invalid index passed to GetClientData()" );
233
234 return DoGetItemClientData(n);
235 }
236
237 void wxItemContainer::AssignNewItemClientData(unsigned int pos,
238 void **clientData,
239 unsigned int n,
240 wxClientDataType type)
241 {
242 switch ( type )
243 {
244 case wxClientData_Object:
245 SetClientObject
246 (
247 pos,
248 (reinterpret_cast<wxClientData **>(clientData))[n]
249 );
250 break;
251
252 case wxClientData_Void:
253 SetClientData(pos, clientData[n]);
254 break;
255
256 default:
257 wxFAIL_MSG( wxT("unknown client data type") );
258 // fall through
259
260 case wxClientData_None:
261 // nothing to do
262 break;
263 }
264 }
265
266 void wxItemContainer::ResetItemClientObject(unsigned int n)
267 {
268 wxClientData * const data = GetClientObject(n);
269 if ( data )
270 {
271 delete data;
272 DoSetItemClientData(n, NULL);
273 }
274 }
275
276 // ============================================================================
277 // wxControlWithItems implementation
278 // ============================================================================
279
280 void
281 wxControlWithItemsBase::InitCommandEventWithItems(wxCommandEvent& event, int n)
282 {
283 InitCommandEvent(event);
284
285 if ( n != wxNOT_FOUND )
286 {
287 if ( HasClientObjectData() )
288 event.SetClientObject(GetClientObject(n));
289 else if ( HasClientUntypedData() )
290 event.SetClientData(GetClientData(n));
291 }
292 }
293
294 void wxControlWithItemsBase::SendSelectionChangedEvent(wxEventType eventType)
295 {
296 const int n = GetSelection();
297 if ( n == wxNOT_FOUND )
298 return;
299
300 wxCommandEvent event(eventType, m_windowId);
301 event.SetInt(n);
302 event.SetEventObject(this);
303 event.SetString(GetStringSelection());
304 InitCommandEventWithItems(event, n);
305
306 HandleWindowEvent(event);
307 }
308
309 #endif // wxUSE_CONTROLS