1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxComboBox class 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  13 #pragma implementation "combobox.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  23 #include "wx/combobox.h" 
  24 #include "wx/arrstr.h" 
  27 #pragma message disable nosimpint 
  31 #pragma message enable nosimpint 
  34 // use the old, GPL'd combobox 
  35 #if (XmVersion < 2000) 
  37 #include "xmcombo/xmcombo.h" 
  39 #include "wx/motif/private.h" 
  41 void  wxComboBoxCallback (Widget w
, XtPointer clientData
, 
  42                           XmComboBoxSelectionCallbackStruct 
* cbs
); 
  44 IMPLEMENT_DYNAMIC_CLASS(wxComboBox
, wxControl
) 
  46 bool wxComboBox::Create(wxWindow 
*parent
, wxWindowID id
, 
  47                         const wxString
& value
, 
  50                         int n
, const wxString choices
[], 
  52                         const wxValidator
& validator
, 
  55     if( !CreateControl( parent
, id
, pos
, size
, style
, validator
, name 
) ) 
  60     Widget parentWidget 
= (Widget
) parent
->GetClientWidget(); 
  62     Widget buttonWidget 
= XtVaCreateManagedWidget(name
.c_str(), 
  63         xmComboBoxWidgetClass
, parentWidget
, 
  67         XmNeditable
, ((style 
& wxCB_READONLY
) != wxCB_READONLY
), 
  68         XmNsorted
, ((style 
& wxCB_SORT
) == wxCB_SORT
), 
  69         XmNstaticList
, ((style 
& wxCB_SIMPLE
) == wxCB_SIMPLE
), 
  73     for (i 
= 0; i 
< n
; i
++) 
  75         wxXmString 
str( choices
[i
] ); 
  76         XmComboBoxAddItem(buttonWidget
, str(), 0); 
  77         m_stringList
.Add(choices
[i
]); 
  80     m_mainWidget 
= (Widget
) buttonWidget
; 
  82     XtManageChild (buttonWidget
); 
  88     XtAddCallback (buttonWidget
, XmNselectionCallback
, (XtCallbackProc
) wxComboBoxCallback
, 
  90     XtAddCallback (buttonWidget
, XmNvalueChangedCallback
, (XtCallbackProc
) wxComboBoxCallback
, 
  93     AttachWidget (parent
, m_mainWidget
, (WXWidget
) NULL
, pos
.x
, pos
.y
, size
.x
, size
.y
); 
  95     ChangeBackgroundColour(); 
 100 bool wxComboBox::Create(wxWindow 
*parent
, wxWindowID id
, 
 101                         const wxString
& value
, 
 104                         const wxArrayString
& choices
, 
 106                         const wxValidator
& validator
, 
 107                         const wxString
& name
) 
 109     wxCArrayString 
chs(choices
); 
 110     return Create(parent
, id
, value
, pos
, size
, chs
.GetCount(),  
 111                   chs
.GetStrings(), style
, validator
, name
); 
 114 wxComboBox::~wxComboBox() 
 116     DetachWidget((Widget
) m_mainWidget
); // Removes event handlers 
 117     XtDestroyWidget((Widget
) m_mainWidget
); 
 118     m_mainWidget 
= (WXWidget
) 0; 
 119     if ( HasClientObjectData() ) 
 120         m_clientDataDict
.DestroyData(); 
 123 void wxComboBox::DoSetSize(int x
, int y
, int width
, int height
, int sizeFlags
) 
 125     // Necessary so it doesn't call wxChoice::SetSize 
 126     wxWindow::DoSetSize(x
, y
, width
, DoGetBestSize().y
, sizeFlags
); 
 129 wxString 
wxComboBox::GetValue() const 
 131     char *s 
= XmComboBoxGetString ((Widget
) m_mainWidget
); 
 139         return wxEmptyString
; 
 142 void wxComboBox::SetValue(const wxString
& value
) 
 146         XmComboBoxSetString( (Widget
)m_mainWidget
, 
 147                              wxConstCast(value
.c_str(), char) ); 
 148     m_inSetValue 
= FALSE
; 
 151 void wxComboBox::SetString(int n
, const wxString
& s
) 
 153     wxFAIL_MSG( wxT("wxComboBox::SetString only implemented for Motif 2.0") ); 
 156 int wxComboBox::DoAppend(const wxString
& item
) 
 158     wxXmString 
str( item
.c_str() ); 
 159     XmComboBoxAddItem((Widget
) m_mainWidget
, str(), 0); 
 160     m_stringList
.Add(item
); 
 163     return GetCount() - 1; 
 166 int wxComboBox::DoInsert(const wxString
& item
, int pos
) 
 168     wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT
), -1, wxT("can't insert into sorted list")); 
 169     wxCHECK_MSG((pos
>=0) && (pos
<=GetCount()), -1, wxT("invalid index")); 
 171     if (pos 
== GetCount()) 
 172         return DoAppend(item
); 
 174     wxXmString 
str( item
.c_str() ); 
 175     XmComboBoxAddItem((Widget
) m_mainWidget
, str(), pos
+1); 
 176     wxChar
* copy 
= wxStrcpy(new wxChar
[item
.length() + 1], item
.c_str()); 
 177     m_stringList
.Insert(pos
, copy
); 
 183 void wxComboBox::Delete(int n
) 
 185     XmComboBoxDeletePos((Widget
) m_mainWidget
, n
+1); 
 186     wxStringList::Node 
*node 
= m_stringList
.Item(n
); 
 189         delete[] node
->GetData(); 
 192     m_clientDataDict
.Delete(n
, HasClientObjectData()); 
 196 void wxComboBox::Clear() 
 198     XmComboBoxDeleteAllItems((Widget
) m_mainWidget
); 
 199     m_stringList
.Clear(); 
 201     if ( HasClientObjectData() ) 
 202         m_clientDataDict
.DestroyData(); 
 206 void wxComboBox::SetSelection (int n
) 
 208     XmComboBoxSelectPos((Widget
) m_mainWidget
, n
+1, False
); 
 211 int wxComboBox::GetSelection (void) const 
 213     int sel 
= XmComboBoxGetSelectedPos((Widget
) m_mainWidget
); 
 220 wxString 
wxComboBox::GetString(int n
) const 
 222     wxStringList::Node 
*node 
= m_stringList
.Item(n
); 
 224         return wxString(node
->GetData ()); 
 226         return wxEmptyString
; 
 229 int wxComboBox::FindString(const wxString
& s
) const 
 231     int *pos_list 
= NULL
; 
 233     wxXmString 
text( s 
); 
 234     bool found 
= (XmComboBoxGetMatchPos((Widget
) m_mainWidget
, 
 235         text(), &pos_list
, &count
) != 0); 
 237     if (found 
&& count 
> 0) 
 239         int pos 
= pos_list
[0] - 1; 
 247 // Clipboard operations 
 248 void wxComboBox::Copy() 
 250     XmComboBoxCopy((Widget
) m_mainWidget
, CurrentTime
); 
 253 void wxComboBox::Cut() 
 255     XmComboBoxCut((Widget
) m_mainWidget
, CurrentTime
); 
 258 void wxComboBox::Paste() 
 260     XmComboBoxPaste((Widget
) m_mainWidget
); 
 263 void wxComboBox::SetEditable(bool WXUNUSED(editable
)) 
 268 void wxComboBox::SetInsertionPoint(long pos
) 
 270     XmComboBoxSetInsertionPosition ((Widget
) m_mainWidget
, (XmTextPosition
) pos
); 
 273 void wxComboBox::SetInsertionPointEnd() 
 275     XmTextPosition pos 
= XmComboBoxGetLastPosition ((Widget
) m_mainWidget
); 
 276     XmComboBoxSetInsertionPosition ((Widget
) m_mainWidget
, (XmTextPosition
) (pos 
+ 1)); 
 279 long wxComboBox::GetInsertionPoint() const 
 281     return (long) XmComboBoxGetInsertionPosition ((Widget
) m_mainWidget
); 
 284 long wxComboBox::GetLastPosition() const 
 286     return (long) XmComboBoxGetLastPosition ((Widget
) m_mainWidget
); 
 289 void wxComboBox::Replace(long from
, long to
, const wxString
& value
) 
 291     XmComboBoxReplace ((Widget
) m_mainWidget
, (XmTextPosition
) from
, 
 293                        wxConstCast(value
.c_str(), char)); 
 296 void wxComboBox::Remove(long from
, long to
) 
 298     XmComboBoxSetSelection ((Widget
) m_mainWidget
, (XmTextPosition
) from
, (XmTextPosition
) to
, 
 300     XmComboBoxRemove ((Widget
) m_mainWidget
); 
 303 void wxComboBox::SetSelection(long from
, long to
) 
 305     XmComboBoxSetSelection ((Widget
) m_mainWidget
, (XmTextPosition
) from
, (XmTextPosition
) to
, 
 309 void  wxComboBoxCallback (Widget 
WXUNUSED(w
), XtPointer clientData
, 
 310                           XmComboBoxSelectionCallbackStruct 
* cbs
) 
 312     wxComboBox 
*item 
= (wxComboBox 
*) clientData
; 
 316     case XmCR_SINGLE_SELECT
: 
 317     case XmCR_BROWSE_SELECT
: 
 319             wxCommandEvent 
event (wxEVT_COMMAND_COMBOBOX_SELECTED
, 
 321             event
.m_commandInt 
= cbs
->index 
- 1; 
 322             event
.m_commandString 
= item
->GetString (event
.m_commandInt
); 
 323             if ( item
->HasClientObjectData() ) 
 324                 event
.SetClientObject( item
->GetClientObject(cbs
->index 
- 1) ); 
 325             else if ( item
->HasClientUntypedData() ) 
 326                 event
.SetClientData( item
->GetClientData(cbs
->index 
- 1) ); 
 327             event
.m_extraLong 
= TRUE
; 
 328             event
.SetEventObject(item
); 
 329             item
->ProcessCommand (event
); 
 332     case XmCR_VALUE_CHANGED
: 
 334             wxCommandEvent 
event (wxEVT_COMMAND_TEXT_UPDATED
, item
->GetId()); 
 335             event
.m_commandInt 
= -1; 
 336             event
.m_commandString 
= item
->GetValue(); 
 337             event
.m_extraLong 
= TRUE
; 
 338             event
.SetEventObject(item
); 
 339             item
->ProcessCommand (event
); 
 347 void wxComboBox::ChangeFont(bool keepOriginalSize
) 
 349     // Don't use the base class wxChoice's ChangeFont 
 350     wxWindow::ChangeFont(keepOriginalSize
); 
 353 void wxComboBox::ChangeBackgroundColour() 
 355     wxWindow::ChangeBackgroundColour(); 
 358 void wxComboBox::ChangeForegroundColour() 
 360     wxWindow::ChangeForegroundColour(); 
 363 wxSize 
wxComboBox::DoGetBestSize() const 
 365     if( (GetWindowStyle() & wxCB_DROPDOWN
) == wxCB_DROPDOWN 
|| 
 366         (GetWindowStyle() & wxCB_READONLY
) == wxCB_READONLY 
) 
 368         wxSize items 
= GetItemsSize(); 
 369         // FIXME arbitrary constants 
 370         return wxSize( ( items
.x 
? items
.x 
+ 50 : 120 ), 
 374         return wxWindow::DoGetBestSize(); 
 377 #endif // XmVersion < 2000 
 379 #endif // wxUSE_COMBOBOX