Applied patch [ 679397 ] remove GPL code from motif build
[wxWidgets.git] / src / motif / combobox_native.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: combobox_native.cpp
3 // Purpose: wxComboBox class
4 // Author: Julian Smart, Ian Brown
5 // Modified by:
6 // Created: 01/02/03
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/setup.h"
13
14 #if wxUSE_COMBOBOX
15
16 #include "wx/combobox.h"
17
18 #ifdef __VMS__
19 #pragma message disable nosimpint
20 #endif
21 #include <Xm/Xm.h>
22 #ifdef __VMS__
23 #pragma message enable nosimpint
24 #endif
25
26 // use the new, shiny combobox for Motif 2.x
27 #if (XmVersion >= 2000)
28
29 #include <Xm/ComboBox.h>
30 #include <Xm/Text.h>
31 #include <Xm/List.h>
32
33 #include "wx/motif/private.h"
34
35 // utility
36 static Widget GetXmList( const wxComboBox* cb )
37 {
38 Widget ret;
39 XtVaGetValues( (Widget)cb->GetMainWidget(),
40 XmNlist, &ret,
41 NULL );
42
43 return ret;
44 }
45
46 static Widget GetXmText( const wxComboBox* cb )
47 {
48 Widget ret;
49 XtVaGetValues( (Widget)cb->GetMainWidget(),
50 XmNtextField, &ret,
51 NULL );
52
53 return ret;
54 }
55
56 void wxComboBoxCallback (Widget w, XtPointer clientData,
57 XmComboBoxCallbackStruct * cbs);
58
59 IMPLEMENT_DYNAMIC_CLASS(wxComboBox, wxControl)
60
61 bool wxComboBox::Create(wxWindow *parent, wxWindowID id,
62 const wxString& value,
63 const wxPoint& pos,
64 const wxSize& size,
65 int n, const wxString choices[],
66 long style,
67 const wxValidator& validator,
68 const wxString& name)
69 {
70 if( !CreateControl( parent, id, pos, size, style, validator, name ) )
71 return false;
72
73 Widget parentWidget = (Widget) parent->GetClientWidget();
74
75 int cb_type = ( style & wxCB_SIMPLE ) ? XmCOMBO_BOX :
76 ( style & wxCB_READONLY ) ? XmDROP_DOWN_LIST :
77 ( style & wxCB_DROPDOWN ) ? XmDROP_DOWN_COMBO_BOX :
78 // default to wxCB_DROPDOWN
79 XmDROP_DOWN_COMBO_BOX;
80
81 Widget buttonWidget= XtVaCreateManagedWidget(name.c_str(),
82 xmComboBoxWidgetClass, parentWidget,
83 XmNcomboBoxType, cb_type,
84 NULL);
85
86 m_mainWidget = (Widget) buttonWidget;
87
88 int i;
89 for ( i = 0; i < n; ++i)
90 Append( choices[i] );
91
92 XtManageChild (buttonWidget);
93
94 SetValue(value);
95
96 ChangeFont(false);
97
98 XtAddCallback (buttonWidget, XmNselectionCallback,
99 (XtCallbackProc) wxComboBoxCallback,
100 (XtPointer) this);
101 XtAddCallback (GetXmText(this), XmNvalueChangedCallback,
102 (XtCallbackProc) wxComboBoxCallback,
103 (XtPointer) this);
104
105 SetCanAddEventHandler(true);
106 AttachWidget (parent, m_mainWidget, (WXWidget) NULL,
107 pos.x, pos.y, size.x, size.y);
108
109 XtVaSetValues (GetXmList(this),
110 XmNvisibleItemCount, 10,
111 NULL);
112
113 ChangeBackgroundColour();
114
115 return true;
116 }
117
118 wxComboBox::~wxComboBox()
119 {
120 DetachWidget((Widget) m_mainWidget); // Removes event handlers
121 XtDestroyWidget((Widget) m_mainWidget);
122 m_mainWidget = (WXWidget) 0;
123 if ( HasClientObjectData() )
124 m_clientDataDict.DestroyData();
125 }
126
127 void wxComboBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
128 {
129 // Necessary so it doesn't call wxChoice::SetSize
130 wxWindow::DoSetSize(x, y, width, DoGetBestSize().y, sizeFlags);
131 }
132
133 wxString wxComboBox::GetValue() const
134 {
135 char* s = XmTextGetString (GetXmText (this));
136 wxString str(s);
137 if (s)
138 XtFree (s);
139 return str;
140 }
141
142 void wxComboBox::SetString(int n, const wxString& s)
143 {
144 wxXmString text(s);
145 Widget listBox = GetXmList(this);
146
147 // delete the item and add it again.
148 // FIXME isn't there a way to change it in place?
149 XmListDeletePos (listBox, n+1);
150 XmListAddItem (listBox, text(), n+1);
151 }
152
153 void wxComboBox::SetValue(const wxString& value)
154 {
155 m_inSetValue = true;
156
157 XtVaSetValues( GetXmText(this),
158 XmNvalue, (char *)value.c_str(),
159 NULL);
160
161 m_inSetValue = false;
162 }
163
164 int wxComboBox::DoAppend(const wxString& item)
165 {
166 wxXmString str( item.c_str() );
167 XmComboBoxAddItem((Widget) m_mainWidget, str(), 0, False);
168 m_stringList.Add(item);
169 m_noStrings ++;
170
171 return GetCount() - 1;
172 }
173
174 void wxComboBox::Delete(int n)
175 {
176 #ifdef LESSTIF_VERSION
177 XmListDeletePos (GetXmList(this), n + 1);
178 #else
179 XmComboBoxDeletePos((Widget) m_mainWidget, n+1);
180 #endif
181
182 wxStringList::Node *node = m_stringList.Item(n);
183 if (node)
184 {
185 delete[] node->GetData();
186 delete node;
187 }
188 m_clientDataDict.Delete(n, HasClientObjectData());
189 m_noStrings--;
190 }
191
192 void wxComboBox::Clear()
193 {
194 #ifdef LESSTIF_VERSION
195 XmListDeleteAllItems (GetXmList(this));
196 #else
197 while(m_noStrings > 0)
198 {
199 XmComboBoxDeletePos((Widget) m_mainWidget, m_noStrings--);
200 }
201 #endif
202
203 m_stringList.Clear();
204
205 if ( HasClientObjectData() )
206 m_clientDataDict.DestroyData();
207 m_noStrings = 0;
208 }
209
210 void wxComboBox::SetSelection (int n)
211 {
212 #ifdef LESSTIF_VERSION
213 XmListSelectPos (GetXmList(this), n + 1, false);
214 SetValue(GetString(n));
215 #else
216 wxXmString str( GetString(n).c_str() );
217 XmComboBoxSelectItem((Widget) m_mainWidget, str());
218 #if 0
219 // does it work for Motif
220 XtVaSetValues( (Widget)m_mainWidget,
221 XmNselectedPosition, n + 1,
222 NULL );
223 #endif
224 #endif
225 }
226
227 int wxComboBox::GetSelection (void) const
228 {
229 return wxDoGetSelectionInList( GetXmList( this ) );
230 }
231
232 wxString wxComboBox::GetString(int n) const
233 {
234 wxStringList::Node *node = m_stringList.Item(n);
235 if (node)
236 return wxString(node->GetData ());
237 else
238 return wxEmptyString;
239 }
240
241 int wxComboBox::FindString(const wxString& s) const
242 {
243 return wxDoFindStringInList( GetXmList( this ), s );
244 }
245
246 // Clipboard operations
247 void wxComboBox::Copy()
248 {
249 // XmComboBoxCopy((Widget) m_mainWidget, CurrentTime);
250 }
251
252 void wxComboBox::Cut()
253 {
254 // XmComboBoxCut((Widget) m_mainWidget, CurrentTime);
255 }
256
257 void wxComboBox::Paste()
258 {
259 // XmComboBoxPaste((Widget) m_mainWidget);
260 }
261
262 void wxComboBox::SetEditable(bool WXUNUSED(editable))
263 {
264 // TODO
265 }
266
267 void wxComboBox::SetInsertionPoint(long pos)
268 {
269 // XmComboBoxSetInsertionPosition ((Widget) m_mainWidget, (XmTextPosition) pos);
270 }
271
272 void wxComboBox::SetInsertionPointEnd()
273 {
274 // XmTextPosition pos = XmComboBoxGetLastPosition ((Widget) m_mainWidget);
275 // XmComboBoxSetInsertionPosition ((Widget) m_mainWidget, (XmTextPosition) (pos + 1));
276 }
277
278 long wxComboBox::GetInsertionPoint() const
279 {
280 // return (long) XmComboBoxGetInsertionPosition ((Widget) m_mainWidget);
281 return -1;
282 }
283
284 long wxComboBox::GetLastPosition() const
285 {
286 // return (long) XmComboBoxGetLastPosition ((Widget) m_mainWidget);
287 return -1;
288 }
289
290 void wxComboBox::Replace(long from, long to, const wxString& value)
291 {/*
292 XmComboBoxReplace ((Widget) m_mainWidget, (XmTextPosition) from, (XmTextPosition) to,
293 (char*) (const char*) value);
294 */
295 }
296
297 void wxComboBox::Remove(long from, long to)
298 {
299 /*
300 XmComboBoxSetSelection ((Widget) m_mainWidget, (XmTextPosition) from, (XmTextPosition) to,
301 (Time) 0);
302 XmComboBoxRemove ((Widget) m_mainWidget);
303 */
304 }
305
306 void wxComboBox::SetSelection(long from, long to)
307 {
308 /*
309 XmComboBoxSetSelection ((Widget) m_mainWidget, (XmTextPosition) from, (XmTextPosition) to,
310 (Time) 0);
311 */
312 }
313
314 void wxComboBoxCallback (Widget WXUNUSED(w), XtPointer clientData,
315 XmComboBoxCallbackStruct * cbs)
316 {
317 wxComboBox *item = (wxComboBox *) clientData;
318
319 switch (cbs->reason)
320 {
321 case XmCR_SELECT:
322 #if 0
323 case XmCR_SINGLE_SELECT:
324 case XmCR_BROWSE_SELECT:
325 #endif
326 {
327 wxCommandEvent event (wxEVT_COMMAND_COMBOBOX_SELECTED,
328 item->GetId());
329 int idx = cbs->item_position - 1;
330 event.m_commandInt = idx;
331 event.m_commandString = item->GetString (idx);
332 if ( item->HasClientObjectData() )
333 event.SetClientObject( item->GetClientObject(idx) );
334 else if ( item->HasClientUntypedData() )
335 event.SetClientData( item->GetClientData(idx) );
336 event.m_extraLong = true;
337 event.SetEventObject(item);
338 item->ProcessCommand (event);
339 break;
340 }
341 case XmCR_VALUE_CHANGED:
342 {
343 wxCommandEvent event (wxEVT_COMMAND_TEXT_UPDATED, item->GetId());
344 event.m_commandInt = -1;
345 event.m_commandString = item->GetValue();
346 event.m_extraLong = true;
347 event.SetEventObject(item);
348 item->ProcessCommand (event);
349 break;
350 }
351 default:
352 break;
353 }
354 }
355
356 void wxComboBox::ChangeFont(bool keepOriginalSize)
357 {
358 // Don't use the base class wxChoice's ChangeFont
359 wxWindow::ChangeFont(keepOriginalSize);
360 }
361
362 void wxComboBox::ChangeBackgroundColour()
363 {
364 wxWindow::ChangeBackgroundColour();
365 }
366
367 void wxComboBox::ChangeForegroundColour()
368 {
369 wxWindow::ChangeForegroundColour();
370 }
371
372 wxSize wxComboBox::DoGetBestSize() const
373 {
374 return wxWindow::DoGetBestSize();
375 }
376
377 #endif // XmVersion >= 2000
378
379 #endif // wxUSE_COMBOBOX