4 @authors: Daphna Rosenbom,Gitty Zinger,Moshe Cohavi and Yoav Glazner
5 The widget is contributed by NDS ltd under the same license as wxPython
7 items_picker.ItemsPicker:
8 - Displays available items to choose from,</LI>
9 - Selection is done by the Add button or Double Click,</LI>
10 - De-Selection is done by the Remove button or Double Click,</LI>
15 from listlex import ListForSpec
21 IP_REMOVE_FROM_CHOICES = 4
24 wxEVT_IP_SELECTION_CHANGED = wx.NewEventType()
25 EVT_IP_SELECTION_CHANGED = wx.PyEventBinder(wxEVT_IP_SELECTION_CHANGED, 1)
26 LB_STYLE = wx.LB_EXTENDED|wx.LB_HSCROLL
29 class IpSelectionChanged(wx.PyCommandEvent):
30 def __init__(self, id, items, object = None):
31 wx.PyCommandEvent.__init__(self, wxEVT_IP_SELECTION_CHANGED, id)
33 self.SetEventObject(object)
39 class VItemsPicker(wx.Panel):
41 ItemsPicker is a widget that allows the user to form a set of picked
42 items out of a given list
44 def __init__(self, parent, id=wx.ID_ANY, choices = [],
45 label = '', selectedLabel = '',
46 ipStyle = IP_DEFAULT_STYLE,
49 ItemsPicker(parent, choices = [], label = '', selectedLabel = '',
50 ipStyle = IP_DEFAULT_STYLE)
54 wx.Panel.__init__(self, parent, id, *args, **kw)
55 self._ipStyle = ipStyle
56 sizer = wx.BoxSizer(wx.HORIZONTAL)
57 sizer.Add(self._CreateSourceList(choices, label), 1,
59 sizer.Add(self._CreateButtons(), 0, wx.ALIGN_CENTER|wx.ALL, 5)
60 sizer.Add(self._CreateDestList(selectedLabel), 1,
65 def SetItems(self, items):
66 '''SetItems(self, items)=> None
67 items - Sequence of strings that the user can pick from'''
69 #return self._source.SetItems(items)
73 '''GetItems(self)=> items
74 returns list of strings that the user can pick from'''
75 return self._source.GetItems()
78 Items = property(fget = GetItems,
80 doc = 'See GetItems/SetItems')
83 def GetSelections(self):
84 '''GetSelections(self)=>items
85 returns list of strings that were selected
87 return [self._destData[i][0] for i in self._destData]
90 def SetSelections(self, items):
91 '''SetSelections(self, items)=>None
92 items - Sequence of strings to be selected
93 The items are displayed in the selection part of the widget'''
94 assert len(items)==len(set(items)),"duplicate items are not allowed"
95 if items != self._dest.GetItems():
96 self._dest.SetItems(items)
97 self._FireIpSelectionChanged()
100 Selections = property(fget = GetSelections,
101 fset = SetSelections,
102 doc = 'See GetSelections/SetSelections')
105 def _CreateButtons(self):
106 sizer = wx.BoxSizer(wx.VERTICAL)
107 self.bAdd = wx.Button(self, -1, label = 'Add ->')
108 self.bAdd.Bind(wx.EVT_BUTTON, self._OnAdd)
109 self.bRemove = wx.Button(self, -1, label = '<- Remove')
110 self.bRemove.Bind(wx.EVT_BUTTON, self._OnRemove)
111 sizer.Add(self.bAdd, 0, wx.EXPAND|wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
112 sizer.Add(self.bRemove, 0, wx.EXPAND|wx.ALL, 5)
116 def _set_add_button_label(self, label=None):
119 self.bAdd.SetLabel(label)
121 add_button_label = property(fset = _set_add_button_label, fget = lambda x:x)
124 def _set_remove_button_label(self, label=None):
127 self.bRemove.SetLabel(label)
129 remove_button_label = property(fset = _set_remove_button_label, fget = lambda x:x)
133 if self._ipStyle & IP_REMOVE_FROM_CHOICES:
134 self._MoveItems(self._source,self._dest)
136 self._AddSelectedItems()
138 def _MoveItems(self,source,dest):
139 selections = source.GetSelections()
140 selectedItems = map(source.GetString, selections)
141 dest.SetItems(dest.GetItems() + selectedItems)
142 selections = set(selections)
143 #source.SetItems([item for i, item in enumerate(source.GetItems())\
144 # if i not in selections])
145 self._FireIpSelectionChanged()
147 def _AddSelectedItems(self):
148 newItems = self._source.getselectedwords()#map(self._source.GetString, self._source.GetSelections())
149 items = [self._destData[i][0] for i in self._destData]
150 oldItems = set(items)
151 for newItem in newItems:
152 if newItem not in oldItems:
153 self._destData[len(self._destData)] = [newItem, '']
155 self._source.selected[newItem] = 1
156 self._source.Refresh()
157 #self.SetSelections(items)
158 self._FireIpSelectionChanged()
160 def _FireIpSelectionChanged(self):
161 self.GetEventHandler().ProcessEvent(
162 IpSelectionChanged(self.GetId(),
167 def _OnRemove(self, e):
168 if self._ipStyle & IP_REMOVE_FROM_CHOICES:
169 self._MoveItems(self._dest, self._source)
171 self._RemoveSelected()
173 def _RemoveSelected(self):
174 selections = self._dest.getselectedwords()
176 #allItems = self._dest.GetItems()
177 #items = [item for i, item in enumerate(allItems)\
178 # if i not in selections]
179 #notselected = [item for i, item in enumerate(allItems)\
180 # if i in selections]
182 for item in selections :
184 del self._source.selected[item]
185 tokeep = [self._destData[i][0] for i in self._destData if self._destData[i][0] not in selections]
186 self._destData = dict([[i, [word, '']] for i, word in enumerate(tokeep)])
187 self._source.Refresh()
189 #self.SetSelections(items)
190 self._FireIpSelectionChanged()
193 def _CreateSourceList(self, items, label):
195 if self._ipStyle & IP_SORT_CHOICES:
197 sizer = wx.BoxSizer(wx.VERTICAL)
199 sizer.Add(wx.StaticText(self, label = label), 0,
200 wx.ALIGN_LEFT|wx.ALL, 5)
201 #self._source = wx.VListBox(self, -1, style = style)
202 self._source = ListForSpec(self, self.parent, dlist = items, first = ['eff', _(u"POS").decode('utf8')], menu = True)
203 self._source.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self._OnDClick)
204 #self._source.Bind(wx.EVT_LISTBOX_DCLICK, self._OnDClick)
205 #self._source.SetItems(items)
206 sizer.Add(self._source, 1, wx.EXPAND|wx.ALL, 5)
210 def _CreateDestList(self, label):
212 if self._ipStyle & IP_SORT_SELECTED:
214 sizer = wx.BoxSizer(wx.VERTICAL)
216 sizer.Add(wx.StaticText(self, label = label), 0,
217 wx.ALIGN_LEFT|wx.ALL, 5)
218 #self._dest = wx.ListBox(self, -1, style = style)
219 self._dest = ListForSpec(self, self.parent, dlist = {}, first = ['eff'], menu = True)
220 self._dest.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self._OnDClick)
221 #self._dest.Bind(wx.EVT_LISTBOX_DCLICK, self._OnDClick)
222 sizer.Add(self._dest, 1, wx.EXPAND|wx.ALL, 5)
225 def _SetDestItems(self):
226 self._dest.itemDataMap = self._destData
227 self._dest.itemIndexMap = self._destData.keys()
228 self._dest.SetItemCount(len(self._destData))
231 def _OnDClick(self, e):
232 lb = e.GetEventObject()
233 selections = lb.GetSelections()
234 if len(selections) != 1:
235 return #DCLICK only works on one item
236 #if e.GetSelection() != selections[0]:
237 #this can happen using ^DCLICK when two items are selected
239 if lb == self._source: