]> git.saurik.com Git - wxWidgets.git/blame - src/generic/editlbox.cpp
added convenience functions wxString::To/From8BitData() for storing g binary data...
[wxWidgets.git] / src / generic / editlbox.cpp
CommitLineData
806ad819
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: editlbox.cpp
3// Purpose: ListBox with editable items
4// Author: Vaclav Slavik
5// RCS-ID: $Id$
6// Copyright: (c) Vaclav Slavik
7// Licence: wxWindows licence
8/////////////////////////////////////////////////////////////////////////////
9
10// For compilers that support precompilation, includes "wx/wx.h".
11#include "wx/wxprec.h"
12
13#ifdef __BORLANDC__
14 #pragma hdrstop
15#endif
16
23575150
RR
17#if wxUSE_EDITABLELISTBOX
18
806ad819
VZ
19// for all others, include the necessary headers (this file is usually all you
20// need because it includes almost all "standard" wxWidgets headers)
21#ifndef WX_PRECOMP
22 #include "wx/wx.h"
23#endif
24
25#include "wx/editlbox.h"
26#include "wx/sizer.h"
27#include "wx/listctrl.h"
28
29static char * eledit_xpm[] = {
30"16 16 3 1",
31" c None",
32". c #000000",
33"+ c #00007F",
34" ",
35" ",
36" .. .. ",
37" . ",
38" . ",
39" ++++ . ++++ ",
40" ++ . ++ ++",
41" +++++ . ++++++",
42" ++ ++ . ++ ",
43" ++ ++ . ++ ++",
44" +++++ . ++++ ",
45" . ",
46" . ",
47" .. .. ",
48" ",
49" "};
50
51static char * elnew_xpm[] = {
52"16 16 5 1",
53" c None",
54". c #7F7F7F",
55"+ c #FFFFFF",
56"@ c #FFFF00",
57"# c #000000",
58" ",
59" ",
60" . .+ .@ ",
61" . .@.@# # # ",
62" @.@+.... # ",
63" ... @@ ",
64" @ . @. # ",
65" .# .@ ",
66" . # ",
67" # ",
68" # ",
69" # ",
70" # ",
71" # # # # # # ",
72" ",
73" "};
74
75static char * eldel_xpm[] = {
76"16 16 3 1",
77" c None",
78". c #7F0000",
79"+ c #FFFFFF",
80" ",
81" ",
82" ",
83" ..+ ..+ ",
84" ....+ ..+ ",
85" ....+ ..+ ",
86" ...+ .+ ",
87" .....+ ",
88" ...+ ",
89" .....+ ",
90" ...+ ..+ ",
91" ...+ ..+ ",
92" ...+ .+ ",
93" ...+ .+ ",
94" . . ",
95" "};
96
97static char * eldown_xpm[] = {
98"16 16 2 1",
99" c None",
100". c #000000",
101" ",
102" ",
103" ... ",
104" ... ",
105" ... ",
106" ... ",
107" ... ",
108" ... ",
109" ........... ",
110" ......... ",
111" ....... ",
112" ..... ",
113" ... ",
114" . ",
115" ",
116" "};
117
118static char * elup_xpm[] = {
119"16 16 2 1",
120" c None",
121". c #000000",
122" ",
123" . ",
124" ... ",
125" ..... ",
126" ....... ",
127" ......... ",
128" ........... ",
129" ... ",
130" ... ",
131" ... ",
132" ... ",
133" ... ",
134" ... ",
135" ",
136" ",
137" "};
138
139// list control with auto-resizable column:
140class CleverListCtrl : public wxListCtrl
141{
142public:
143 CleverListCtrl(wxWindow *parent,
144 wxWindowID id = wxID_ANY,
145 const wxPoint &pos = wxDefaultPosition,
146 const wxSize &size = wxDefaultSize,
147 long style = wxLC_ICON,
148 const wxValidator& validator = wxDefaultValidator,
149 const wxString &name = wxListCtrlNameStr)
150 : wxListCtrl(parent, id, pos, size, style, validator, name)
151 {
152 CreateColumns();
153 }
154
155 void CreateColumns()
156 {
157 InsertColumn(0, _T("item"));
158 SizeColumns();
159 }
160
161 void SizeColumns()
162 {
163 int w = GetSize().x;
164#ifdef __WXMSW__
165 w -= wxSystemSettings::GetMetric(wxSYS_VSCROLL_X) + 6;
166#else
167 w -= 2*wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
168#endif
169 SetColumnWidth(0, w);
170 }
171
172private:
173 DECLARE_EVENT_TABLE()
174 void OnSize(wxSizeEvent& event)
175 {
176 SizeColumns();
177 event.Skip();
178 }
179};
180
181BEGIN_EVENT_TABLE(CleverListCtrl, wxListCtrl)
182 EVT_SIZE(CleverListCtrl::OnSize)
183END_EVENT_TABLE()
184
185IMPLEMENT_CLASS(wxEditableListBox, wxPanel)
186
187// NB: generate the IDs at runtime to avoid conflict with XRCID values,
188// they could cause XRCCTRL() failures in XRC-based dialogs
189const int wxID_ELB_DELETE = wxNewId();
190const int wxID_ELB_EDIT = wxNewId();
191const int wxID_ELB_NEW = wxNewId();
192const int wxID_ELB_UP = wxNewId();
193const int wxID_ELB_DOWN = wxNewId();
194const int wxID_ELB_LISTCTRL = wxNewId();
195
196BEGIN_EVENT_TABLE(wxEditableListBox, wxPanel)
197 EVT_LIST_ITEM_SELECTED(wxID_ELB_LISTCTRL, wxEditableListBox::OnItemSelected)
198 EVT_LIST_END_LABEL_EDIT(wxID_ELB_LISTCTRL, wxEditableListBox::OnEndLabelEdit)
199 EVT_BUTTON(wxID_ELB_NEW, wxEditableListBox::OnNewItem)
200 EVT_BUTTON(wxID_ELB_UP, wxEditableListBox::OnUpItem)
201 EVT_BUTTON(wxID_ELB_DOWN, wxEditableListBox::OnDownItem)
202 EVT_BUTTON(wxID_ELB_EDIT, wxEditableListBox::OnEditItem)
203 EVT_BUTTON(wxID_ELB_DELETE, wxEditableListBox::OnDelItem)
204END_EVENT_TABLE()
205
206wxEditableListBox::wxEditableListBox(wxWindow *parent, wxWindowID id,
207 const wxString& label,
208 const wxPoint& pos, const wxSize& size,
209 long style,
210 const wxString& name)
211 : wxPanel(parent, id, pos, size, wxTAB_TRAVERSAL, name)
212{
213 m_style = style;
214 m_bEdit = m_bNew = m_bDel = m_bUp = m_bDown = NULL;
215
216 wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
217
218 wxPanel *subp = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
219 wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
220 wxSizer *subsizer = new wxBoxSizer(wxHORIZONTAL);
221 subsizer->Add(new wxStaticText(subp, wxID_ANY, label), 1, wxALIGN_CENTRE_VERTICAL | wxLEFT, 4);
222
223#ifdef __WXMSW__
224 #define BTN_BORDER 4
225 // FIXME - why is this needed? There's some reason why sunken border is
226 // ignored by sizers in wxMSW but not in wxGTK that I can't
227 // figure out...
228#else
229 #define BTN_BORDER 0
230#endif
231
232 if ( m_style & wxEL_ALLOW_EDIT )
233 {
234 m_bEdit = new wxBitmapButton(subp, wxID_ELB_EDIT, wxBitmap(eledit_xpm));
235 subsizer->Add(m_bEdit, 0, wxALIGN_CENTRE_VERTICAL | wxTOP | wxBOTTOM, BTN_BORDER);
236 }
237
238 if ( m_style & wxEL_ALLOW_NEW )
239 {
240 m_bNew = new wxBitmapButton(subp, wxID_ELB_NEW, wxBitmap(elnew_xpm));
241 subsizer->Add(m_bNew, 0, wxALIGN_CENTRE_VERTICAL | wxTOP | wxBOTTOM, BTN_BORDER);
242 }
243
244 if ( m_style & wxEL_ALLOW_DELETE )
245 {
246 m_bDel = new wxBitmapButton(subp, wxID_ELB_DELETE, wxBitmap(eldel_xpm));
247 subsizer->Add(m_bDel, 0, wxALIGN_CENTRE_VERTICAL | wxTOP | wxBOTTOM, BTN_BORDER);
248 }
249
250 if (!(m_style & wxEL_NO_REORDER))
251 {
252 m_bUp = new wxBitmapButton(subp, wxID_ELB_UP, wxBitmap(elup_xpm));
253 subsizer->Add(m_bUp, 0, wxALIGN_CENTRE_VERTICAL | wxTOP | wxBOTTOM, BTN_BORDER);
254
255 m_bDown = new wxBitmapButton(subp, wxID_ELB_DOWN, wxBitmap(eldown_xpm));
256 subsizer->Add(m_bDown, 0, wxALIGN_CENTRE_VERTICAL | wxTOP | wxBOTTOM, BTN_BORDER);
257 }
258
259#if wxUSE_TOOLTIPS
260 if ( m_bEdit ) m_bEdit->SetToolTip(_("Edit item"));
261 if ( m_bNew ) m_bNew->SetToolTip(_("New item"));
262 if ( m_bDel ) m_bDel->SetToolTip(_("Delete item"));
263 if ( m_bUp ) m_bUp->SetToolTip(_("Move up"));
264 if ( m_bDown ) m_bDown->SetToolTip(_("Move down"));
265#endif
266
267 subp->SetSizer(subsizer);
268 subsizer->Fit(subp);
269
270 sizer->Add(subp, 0, wxEXPAND);
271
272 long st = wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL | wxSUNKEN_BORDER;
273 if ( style & wxEL_ALLOW_EDIT )
274 st |= wxLC_EDIT_LABELS;
275 m_listCtrl = new CleverListCtrl(this, wxID_ELB_LISTCTRL,
276 wxDefaultPosition, wxDefaultSize, st);
277 wxArrayString empty_ar;
278 SetStrings(empty_ar);
279
280 sizer->Add(m_listCtrl, 1, wxEXPAND);
281
282 SetSizer(sizer);
283 Layout();
284}
285
286void wxEditableListBox::SetStrings(const wxArrayString& strings)
287{
288 m_listCtrl->DeleteAllItems();
289 size_t i;
290
291 for (i = 0; i < strings.GetCount(); i++)
292 m_listCtrl->InsertItem(i, strings[i]);
293
294 m_listCtrl->InsertItem(strings.GetCount(), wxEmptyString);
295 m_listCtrl->SetItemState(0, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
296}
297
298void wxEditableListBox::GetStrings(wxArrayString& strings) const
299{
300 strings.Clear();
301
302 for (int i = 0; i < m_listCtrl->GetItemCount()-1; i++)
303 strings.Add(m_listCtrl->GetItemText(i));
304}
305
306void wxEditableListBox::OnItemSelected(wxListEvent& event)
307{
308 m_selection = event.GetIndex();
309 if (!(m_style & wxEL_NO_REORDER))
310 {
311 m_bUp->Enable(m_selection != 0 && m_selection < m_listCtrl->GetItemCount()-1);
312 m_bDown->Enable(m_selection < m_listCtrl->GetItemCount()-2);
313 }
314
315 if (m_style & wxEL_ALLOW_EDIT)
316 m_bEdit->Enable(m_selection < m_listCtrl->GetItemCount()-1);
317 if (m_style & wxEL_ALLOW_DELETE)
318 m_bDel->Enable(m_selection < m_listCtrl->GetItemCount()-1);
319}
320
321void wxEditableListBox::OnNewItem(wxCommandEvent& WXUNUSED(event))
322{
323 m_listCtrl->SetItemState(m_listCtrl->GetItemCount()-1,
324 wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
325 m_listCtrl->EditLabel(m_selection);
326}
327
328void wxEditableListBox::OnEndLabelEdit(wxListEvent& event)
329{
330 if ( event.GetIndex() == m_listCtrl->GetItemCount()-1 &&
331 !event.GetText().empty() )
332 {
333 // The user edited last (empty) line, i.e. added new entry. We have to
334 // add new empty line here so that adding one more line is still
335 // possible:
336 m_listCtrl->InsertItem(m_listCtrl->GetItemCount(), wxEmptyString);
337
338 // Simulate a wxEVT_COMMAND_LIST_ITEM_SELECTED event for the new item,
339 // so that the buttons are enabled/disabled properly
340 wxListEvent selectionEvent(wxEVT_COMMAND_LIST_ITEM_SELECTED, m_listCtrl->GetId());
341 selectionEvent.m_itemIndex = event.GetIndex();
342 m_listCtrl->GetEventHandler()->ProcessEvent(selectionEvent);
343 }
344}
345
346void wxEditableListBox::OnDelItem(wxCommandEvent& WXUNUSED(event))
347{
348 m_listCtrl->DeleteItem(m_selection);
349 m_listCtrl->SetItemState(m_selection,
350 wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
351}
352
353void wxEditableListBox::OnEditItem(wxCommandEvent& WXUNUSED(event))
354{
355 m_listCtrl->EditLabel(m_selection);
356}
357
358void wxEditableListBox::OnUpItem(wxCommandEvent& WXUNUSED(event))
359{
360 wxString t1, t2;
361
362 t1 = m_listCtrl->GetItemText(m_selection - 1);
363 t2 = m_listCtrl->GetItemText(m_selection);
364 m_listCtrl->SetItemText(m_selection - 1, t2);
365 m_listCtrl->SetItemText(m_selection, t1);
366 m_listCtrl->SetItemState(m_selection - 1,
367 wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
368}
369
370void wxEditableListBox::OnDownItem(wxCommandEvent& WXUNUSED(event))
371{
372 wxString t1, t2;
373
374 t1 = m_listCtrl->GetItemText(m_selection + 1);
375 t2 = m_listCtrl->GetItemText(m_selection);
376 m_listCtrl->SetItemText(m_selection + 1, t2);
377 m_listCtrl->SetItemText(m_selection, t1);
378 m_listCtrl->SetItemState(m_selection + 1,
379 wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
380}
23575150
RR
381
382#endif // wxUSE_EDITABLELISTBOX