]> git.saurik.com Git - wxWidgets.git/blame - src/univ/combobox.cpp
fix OpenWatcom warning (patch from Jaakko Salli)
[wxWidgets.git] / src / univ / combobox.cpp
CommitLineData
1e6feb95 1/////////////////////////////////////////////////////////////////////////////
11e62fe6 2// Name: src/univ/combobox.cpp
6d0ce565 3// Purpose: wxComboBox implementation
1e6feb95
VZ
4// Author: Vadim Zeitlin
5// Modified by:
6// Created: 15.12.00
7// RCS-ID: $Id$
442b35b5 8// Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
65571936 9// Licence: wxWindows licence
1e6feb95
VZ
10/////////////////////////////////////////////////////////////////////////////
11
1e6feb95
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
1e6feb95
VZ
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
23 #pragma hdrstop
24#endif
25
26#if wxUSE_COMBOBOX
27
28#ifndef WX_PRECOMP
29 #include "wx/log.h"
30
31 #include "wx/button.h"
32 #include "wx/combobox.h"
33 #include "wx/listbox.h"
34 #include "wx/textctrl.h"
8cb172b4 35 #include "wx/bmpbuttn.h"
1e6feb95
VZ
36
37 #include "wx/validate.h"
38#endif
39
d4e5272b 40#include "wx/tooltip.h"
a340b80d 41#include "wx/combo.h"
1e6feb95
VZ
42
43#include "wx/univ/renderer.h"
44#include "wx/univ/inphand.h"
45#include "wx/univ/theme.h"
46
1e6feb95
VZ
47
48// ----------------------------------------------------------------------------
49// wxComboListBox is a listbox modified to be used as a popup window in a
50// combobox
51// ----------------------------------------------------------------------------
52
53class wxComboListBox : public wxListBox, public wxComboPopup
54{
55public:
56 // ctor and dtor
a340b80d 57 wxComboListBox(wxComboControlBase *combo);
1e6feb95
VZ
58 virtual ~wxComboListBox();
59
60 // implement wxComboPopup methods
a340b80d
VZ
61 virtual bool Create(wxWindow* parent);
62 virtual void SetStringValue(const wxString& s);
63 virtual wxString GetStringValue() const;
64 virtual wxWindow *GetControl() { return this; }
65 virtual void OnPopup();
66 virtual wxSize GetAdjustedSize(int minWidth, int prefHeight, int maxHeight);
1e6feb95 67
d2fde247
VZ
68 // fix virtual function hiding
69 virtual void SetSelection(int n) { DoSetSelection(n, true); }
70 void SetSelection(int n, bool select) { DoSetSelection(n, select); }
71
6f02a879
VZ
72 // used to process wxUniv actions
73 bool PerformAction(const wxControlAction& action,
74 long numArg,
75 const wxString& strArg);
76
1e6feb95 77protected:
55f095d4
VZ
78 // set m_clicked value from here
79 void OnLeftUp(wxMouseEvent& event);
80
1e6feb95 81private:
1e6feb95
VZ
82 DECLARE_EVENT_TABLE()
83};
84
85// ----------------------------------------------------------------------------
86// event tables and such
87// ----------------------------------------------------------------------------
88
1e6feb95 89BEGIN_EVENT_TABLE(wxComboListBox, wxListBox)
55f095d4 90 EVT_LEFT_UP(wxComboListBox::OnLeftUp)
1e6feb95
VZ
91END_EVENT_TABLE()
92
a340b80d 93IMPLEMENT_DYNAMIC_CLASS2(wxComboBox, wxControl, wxComboControl)
1e6feb95
VZ
94
95// ============================================================================
96// implementation
97// ============================================================================
98
99// ----------------------------------------------------------------------------
a340b80d 100// wxComboListBox
1e6feb95
VZ
101// ----------------------------------------------------------------------------
102
a340b80d
VZ
103wxComboListBox::wxComboListBox(wxComboControlBase *combo)
104 : wxListBox(),
105 wxComboPopup(combo)
1e6feb95 106{
1e6feb95
VZ
107}
108
a340b80d 109bool wxComboListBox::Create(wxWindow* parent)
1e6feb95 110{
a340b80d
VZ
111 if ( !wxListBox::Create(parent, wxID_ANY,
112 wxDefaultPosition, wxDefaultSize,
113 0, NULL,
114 wxBORDER_SIMPLE | wxLB_INT_HEIGHT |
115 m_combo->GetWindowStyle() & wxCB_SORT ? wxLB_SORT : 0) )
a290fa5a 116 return false;
1e6feb95 117
a340b80d
VZ
118 // we don't react to the mouse events outside the window at all
119 StopAutoScrolling();
1e6feb95 120
a290fa5a 121 return true;
1e6feb95
VZ
122}
123
a340b80d 124wxComboListBox::~wxComboListBox()
1e6feb95 125{
1e6feb95
VZ
126}
127
a340b80d 128wxString wxComboListBox::GetStringValue() const
1e6feb95 129{
a340b80d 130 return wxListBox::GetStringSelection();
1e6feb95
VZ
131}
132
a340b80d 133void wxComboListBox::SetStringValue(const wxString& value)
1e6feb95 134{
a340b80d
VZ
135 if ( !value.empty() )
136 wxListBox::SetStringSelection(value);
137 else
138 wxListBox::SetSelection(-1);
1e6feb95 139
a340b80d
VZ
140 /*
141 // PRE-GLOBAL WXCOMBOCONTROL CODE:
1e6feb95 142
1e6feb95
VZ
143 // FindItem() would just find the current item for an empty string (it
144 // always matches), but we want to show the first one in such case
145 if ( value.empty() )
146 {
8228b893 147 if ( GetCount() > 0 )
1e6feb95
VZ
148 {
149 wxListBox::SetSelection(0);
150 }
151 //else: empty listbox - nothing to do
152 }
153 else if ( !FindItem(value) )
154 {
155 // no match att all
1e6feb95 156 }
a340b80d 157 */
1e6feb95
VZ
158}
159
a340b80d 160void wxComboListBox::OnPopup()
1e6feb95
VZ
161{
162}
163
164bool wxComboListBox::PerformAction(const wxControlAction& action,
165 long numArg,
166 const wxString& strArg)
167
168{
169 if ( action == wxACTION_LISTBOX_FIND )
170 {
171 // we don't let the listbox handle this as instead of just using the
172 // single key presses, as usual, we use the text ctrl value as prefix
173 // and this is done by wxComboControl itself
a290fa5a 174 return true;
1e6feb95
VZ
175 }
176
177 return wxListBox::PerformAction(action, numArg, strArg);
178}
179
55f095d4
VZ
180void wxComboListBox::OnLeftUp(wxMouseEvent& event)
181{
182 // we should dismiss the combo now
a340b80d
VZ
183 // first update the combo and close the listbox
184 Dismiss();
185 m_combo->SetValue(wxListBox::GetStringSelection());
55f095d4 186
a340b80d
VZ
187 // next let the user code have the event
188 wxCommandEvent evt(wxEVT_COMMAND_COMBOBOX_SELECTED,m_combo->GetId());
189 evt.SetInt(wxListBox::GetSelection());
190 evt.SetEventObject(m_combo);
191 m_combo->ProcessEvent(evt);
55f095d4 192
a340b80d 193 event.Skip();
e2ca829e
JS
194}
195
a340b80d
VZ
196wxSize wxComboListBox::GetAdjustedSize(int minWidth,
197 int WXUNUSED(prefHeight),
198 int maxHeight)
1e6feb95 199{
a340b80d
VZ
200 wxSize bestSize = wxListBox::GetBestSize();
201 return wxSize(wxMax(bestSize.x,minWidth),
202 wxMin(bestSize.y,maxHeight));
1e6feb95
VZ
203}
204
205// ----------------------------------------------------------------------------
206// wxComboBox
207// ----------------------------------------------------------------------------
208
209void wxComboBox::Init()
210{
211 m_lbox = (wxListBox *)NULL;
212}
213
584ad2a3
MB
214wxComboBox::wxComboBox(wxWindow *parent,
215 wxWindowID id,
216 const wxString& value,
217 const wxPoint& pos,
218 const wxSize& size,
219 const wxArrayString& choices,
220 long style,
221 const wxValidator& validator,
222 const wxString& name)
223{
224 Init();
225
226 Create(parent, id, value, pos, size, choices, style, validator, name);
227}
228
229bool wxComboBox::Create(wxWindow *parent,
230 wxWindowID id,
231 const wxString& value,
232 const wxPoint& pos,
233 const wxSize& size,
234 const wxArrayString& choices,
235 long style,
236 const wxValidator& validator,
237 const wxString& name)
238{
239 wxCArrayString chs(choices);
240
241 return Create(parent, id, value, pos, size, chs.GetCount(),
242 chs.GetStrings(), style, validator, name);
243}
244
1e6feb95
VZ
245bool wxComboBox::Create(wxWindow *parent,
246 wxWindowID id,
247 const wxString& value,
248 const wxPoint& pos,
249 const wxSize& size,
250 int n,
ba1e9d6c 251 const wxString choices[],
1e6feb95
VZ
252 long style,
253 const wxValidator& validator,
254 const wxString& name)
255{
256 if ( !wxComboControl::Create(parent, id, value, pos, size, style,
257 validator, name) )
258 {
a290fa5a 259 return false;
1e6feb95
VZ
260 }
261
a340b80d
VZ
262 wxComboListBox *combolbox = new wxComboListBox(this);
263 SetPopupControl(combolbox);
264
1e6feb95
VZ
265 m_lbox = combolbox;
266 m_lbox->Set(n, choices);
267
a290fa5a 268 return true;
1e6feb95
VZ
269}
270
271wxComboBox::~wxComboBox()
272{
273}
274
275// ----------------------------------------------------------------------------
276// wxComboBox methods forwarded to wxTextCtrl
277// ----------------------------------------------------------------------------
278
279wxString wxComboBox::GetValue() const
280{
a340b80d 281 return wxComboControl::GetValue();
1e6feb95
VZ
282}
283
284void wxComboBox::SetValue(const wxString& value)
285{
a340b80d 286 wxComboControl::SetValue(value);
1e6feb95
VZ
287}
288
289void wxComboBox::Copy()
290{
a340b80d 291 if ( GetTextCtrl() ) GetTextCtrl()->Copy();
1e6feb95
VZ
292}
293
294void wxComboBox::Cut()
295{
a340b80d 296 if ( GetTextCtrl() ) GetTextCtrl()->Cut();
1e6feb95
VZ
297}
298
299void wxComboBox::Paste()
300{
a340b80d 301 if ( GetTextCtrl() ) GetTextCtrl()->Paste();
1e6feb95
VZ
302}
303
304void wxComboBox::SetInsertionPoint(long pos)
305{
a340b80d 306 if ( GetTextCtrl() ) GetTextCtrl()->SetInsertionPoint(pos);
1e6feb95
VZ
307}
308
309void wxComboBox::SetInsertionPointEnd()
310{
a340b80d 311 if ( GetTextCtrl() ) GetTextCtrl()->SetInsertionPointEnd();
1e6feb95
VZ
312}
313
314long wxComboBox::GetInsertionPoint() const
315{
a340b80d
VZ
316 if ( GetTextCtrl() )
317 return GetTextCtrl()->GetInsertionPoint();
318 return -1;
1e6feb95
VZ
319}
320
7d8268a1 321wxTextPos wxComboBox::GetLastPosition() const
1e6feb95 322{
a340b80d
VZ
323 if ( GetTextCtrl() )
324 return GetTextCtrl()->GetLastPosition();
325 return -1;
1e6feb95
VZ
326}
327
328void wxComboBox::Replace(long from, long to, const wxString& value)
329{
a340b80d 330 if ( GetTextCtrl() ) GetTextCtrl()->Replace(from, to, value);
1e6feb95
VZ
331}
332
333void wxComboBox::Remove(long from, long to)
334{
a340b80d 335 if ( GetTextCtrl() ) GetTextCtrl()->Remove(from, to);
1e6feb95
VZ
336}
337
338void wxComboBox::SetSelection(long from, long to)
339{
a340b80d 340 if ( GetTextCtrl() ) GetTextCtrl()->SetSelection(from, to);
1e6feb95
VZ
341}
342
343void wxComboBox::SetEditable(bool editable)
344{
a340b80d 345 if ( GetTextCtrl() ) GetTextCtrl()->SetEditable(editable);
1e6feb95
VZ
346}
347
348// ----------------------------------------------------------------------------
349// wxComboBox methods forwarded to wxListBox
350// ----------------------------------------------------------------------------
351
352void wxComboBox::Clear()
353{
354 GetLBox()->Clear();
a340b80d 355 if ( GetTextCtrl() ) GetTextCtrl()->SetValue(wxEmptyString);
1e6feb95
VZ
356}
357
aa61d352 358void wxComboBox::Delete(unsigned int n)
1e6feb95 359{
8228b893 360 wxCHECK_RET( IsValid(n), _T("invalid index in wxComboBox::Delete") );
48aa18c0 361
aa61d352 362 if (GetSelection() == (int)n)
a340b80d 363 if ( GetTextCtrl() ) GetTextCtrl()->SetValue(wxEmptyString);
48aa18c0 364
1e6feb95
VZ
365 GetLBox()->Delete(n);
366}
367
aa61d352 368unsigned int wxComboBox::GetCount() const
1e6feb95
VZ
369{
370 return GetLBox()->GetCount();
371}
372
aa61d352 373wxString wxComboBox::GetString(unsigned int n) const
1e6feb95 374{
8228b893 375 wxCHECK_MSG( IsValid(n), wxEmptyString, _T("invalid index in wxComboBox::GetString") );
48aa18c0 376
1e6feb95
VZ
377 return GetLBox()->GetString(n);
378}
379
aa61d352 380void wxComboBox::SetString(unsigned int n, const wxString& s)
1e6feb95 381{
8228b893 382 wxCHECK_RET( IsValid(n), _T("invalid index in wxComboBox::SetString") );
48aa18c0 383
1e6feb95
VZ
384 GetLBox()->SetString(n, s);
385}
386
11e62fe6 387int wxComboBox::FindString(const wxString& s, bool bCase) const
1e6feb95 388{
11e62fe6 389 return GetLBox()->FindString(s, bCase);
1e6feb95
VZ
390}
391
c6179a84 392void wxComboBox::SetSelection(int n)
1e6feb95 393{
8228b893 394 wxCHECK_RET( IsValid(n), _T("invalid index in wxComboBox::Select") );
1e6feb95
VZ
395
396 GetLBox()->SetSelection(n);
a340b80d 397 if ( GetTextCtrl() ) GetTextCtrl()->SetValue(GetLBox()->GetString(n));
1e6feb95
VZ
398}
399
400int wxComboBox::GetSelection() const
401{
48aa18c0 402#if 1 // FIXME:: What is the correct behavior?
1e6feb95 403 // if the current value isn't one of the listbox strings, return -1
48aa18c0 404 return GetLBox()->GetSelection();
150e31d2
JS
405#else
406 // Why oh why is this done this way?
407 // It is not because the value displayed in the text can be found
48aa18c0 408 // in the list that it is the item that is selected!
a340b80d 409 return FindString(if ( GetTextCtrl() ) GetTextCtrl()->GetValue());
48aa18c0 410#endif
1e6feb95
VZ
411}
412
413int wxComboBox::DoAppend(const wxString& item)
414{
415 return GetLBox()->Append(item);
416}
417
aa61d352 418int wxComboBox::DoInsert(const wxString& item, unsigned int pos)
243dbf1a
VZ
419{
420 wxCHECK_MSG(!(GetWindowStyle() & wxCB_SORT), -1, wxT("can't insert into sorted list"));
8228b893 421 wxCHECK_MSG(IsValidInsert(pos), -1, wxT("invalid index"));
243dbf1a 422
aa61d352 423 if (pos == GetCount())
243dbf1a
VZ
424 return DoAppend(item);
425
3f85391e 426 GetLBox()->Insert(item, pos);
243dbf1a
VZ
427 return pos;
428}
429
aa61d352 430void wxComboBox::DoSetItemClientData(unsigned int n, void* clientData)
1e6feb95
VZ
431{
432 GetLBox()->SetClientData(n, clientData);
433}
434
aa61d352 435void *wxComboBox::DoGetItemClientData(unsigned int n) const
1e6feb95
VZ
436{
437 return GetLBox()->GetClientData(n);
438}
439
aa61d352 440void wxComboBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData)
1e6feb95
VZ
441{
442 GetLBox()->SetClientObject(n, clientData);
443}
444
aa61d352 445wxClientData* wxComboBox::DoGetItemClientObject(unsigned int n) const
1e6feb95
VZ
446{
447 return GetLBox()->GetClientObject(n);
448}
449
150e31d2
JS
450bool wxComboBox::IsEditable() const
451{
a340b80d 452 return GetTextCtrl() != NULL && (!HasFlag(wxCB_READONLY) || GetTextCtrl()->IsEditable() );
150e31d2
JS
453}
454
455void wxComboBox::Undo()
456{
457 if (IsEditable())
a340b80d 458 if ( GetTextCtrl() ) GetTextCtrl()->Undo();
150e31d2
JS
459}
460
461void wxComboBox::Redo()
462{
463 if (IsEditable())
a340b80d 464 if ( GetTextCtrl() ) GetTextCtrl()->Redo();
150e31d2
JS
465}
466
467void wxComboBox::SelectAll()
468{
a340b80d 469 if ( GetTextCtrl() ) GetTextCtrl()->SelectAll();
150e31d2
JS
470}
471
472bool wxComboBox::CanCopy() const
473{
a340b80d
VZ
474 if (GetTextCtrl() != NULL)
475 return GetTextCtrl()->CanCopy();
150e31d2
JS
476 else
477 return false;
478}
479
480bool wxComboBox::CanCut() const
481{
a340b80d
VZ
482 if (GetTextCtrl() != NULL)
483 return GetTextCtrl()->CanCut();
150e31d2
JS
484 else
485 return false;
486}
487
488bool wxComboBox::CanPaste() const
489{
490 if (IsEditable())
a340b80d 491 return GetTextCtrl()->CanPaste();
150e31d2
JS
492 else
493 return false;
494}
495
496bool wxComboBox::CanUndo() const
497{
498 if (IsEditable())
a340b80d 499 return GetTextCtrl()->CanUndo();
150e31d2
JS
500 else
501 return false;
502}
503
504bool wxComboBox::CanRedo() const
505{
506 if (IsEditable())
a340b80d 507 return GetTextCtrl()->CanRedo();
150e31d2
JS
508 else
509 return false;
510}
511
512
1e6feb95
VZ
513// ----------------------------------------------------------------------------
514// wxStdComboBoxInputHandler
515// ----------------------------------------------------------------------------
516
517wxStdComboBoxInputHandler::wxStdComboBoxInputHandler(wxInputHandler *inphand)
518 : wxStdInputHandler(inphand)
519{
520}
521
23645bfa 522bool wxStdComboBoxInputHandler::HandleKey(wxInputConsumer *consumer,
1e6feb95
VZ
523 const wxKeyEvent& event,
524 bool pressed)
525{
526 if ( pressed )
527 {
528 wxControlAction action;
529 switch ( event.GetKeyCode() )
530 {
531 case WXK_DOWN:
532 action = wxACTION_COMBOBOX_POPUP;
533 break;
534
535 case WXK_ESCAPE:
536 action = wxACTION_COMBOBOX_DISMISS;
537 break;
538 }
539
a290fa5a 540 if ( !action.IsEmpty() )
1e6feb95 541 {
23645bfa 542 consumer->PerformAction(action);
1e6feb95 543
a290fa5a 544 return true;
1e6feb95
VZ
545 }
546 }
547
23645bfa 548 return wxStdInputHandler::HandleKey(consumer, event, pressed);
1e6feb95
VZ
549}
550
a340b80d 551
1e6feb95 552#endif // wxUSE_COMBOBOX