X-Git-Url: http://iramuteq.org/git?p=iramuteq;a=blobdiff_plain;f=vitemspicker.py;fp=vitemspicker.py;h=d385210c24a34c1cc20c6a2fa04661ffb9626a69;hp=0000000000000000000000000000000000000000;hb=94db7716520d397ab87a1a7730d2d0fd9f873da0;hpb=889c0c759bd1a27a90cbf0a1bbb3f080ab293aaf diff --git a/vitemspicker.py b/vitemspicker.py new file mode 100644 index 0000000..d385210 --- /dev/null +++ b/vitemspicker.py @@ -0,0 +1,267 @@ +''' +Created on Oct 3, 2010 + +@authors: Daphna Rosenbom,Gitty Zinger,Moshe Cohavi and Yoav Glazner +The widget is contributed by NDS ltd under the same license as wxPython + +items_picker.ItemsPicker: +- Displays available items to choose from, +- Selection is done by the Add button or Double Click, +- De-Selection is done by the Remove button or Double Click, + +Derived from wxPanel +''' +import wx +from listlex import ListForSpec +__version__ = 0.1 + +IP_DEFAULT_STYLE = 0 +IP_SORT_CHOICES = 1 +IP_SORT_SELECTED = 2 +IP_REMOVE_FROM_CHOICES = 4 + + +wxEVT_IP_SELECTION_CHANGED = wx.NewEventType() +EVT_IP_SELECTION_CHANGED = wx.PyEventBinder(wxEVT_IP_SELECTION_CHANGED, 1) +LB_STYLE = wx.LB_EXTENDED|wx.LB_HSCROLL + + +class IpSelectionChanged(wx.PyCommandEvent): + def __init__(self, id, items, object = None): + wx.PyCommandEvent.__init__(self, wxEVT_IP_SELECTION_CHANGED, id) + self.__items = items + self.SetEventObject(object) + + def GetItems(self): + return self.__items + + +class VItemsPicker(wx.Panel): + ''' +ItemsPicker is a widget that allows the user to form a set of picked +items out of a given list +''' + def __init__(self, parent, id=wx.ID_ANY, choices = [], + label = '', selectedLabel = '', + ipStyle = IP_DEFAULT_STYLE, + *args, **kw): + ''' +ItemsPicker(parent, choices = [], label = '', selectedLabel = '', +ipStyle = IP_DEFAULT_STYLE) +''' + self.parent = parent + self._destData = {} + wx.Panel.__init__(self, parent, id, *args, **kw) + self._ipStyle = ipStyle + sizer = wx.BoxSizer(wx.HORIZONTAL) + sizer.Add(self._CreateSourceList(choices, label), 1, + wx.EXPAND|wx.ALL, 5) + sizer.Add(self._CreateButtons(), 0, wx.ALIGN_CENTER|wx.ALL, 5) + sizer.Add(self._CreateDestList(selectedLabel), 1, + wx.EXPAND|wx.ALL, 5) + self.SetSizer(sizer) + + + def SetItems(self, items): + '''SetItems(self, items)=> None +items - Sequence of strings that the user can pick from''' + pass + #return self._source.SetItems(items) + + + def GetItems(self): + '''GetItems(self)=> items +returns list of strings that the user can pick from''' + return self._source.GetItems() + + + Items = property(fget = GetItems, + fset = SetItems, + doc = 'See GetItems/SetItems') + + + def GetSelections(self): + '''GetSelections(self)=>items +returns list of strings that were selected +''' + return [self._destData[i][0] for i in self._destData] + + + def SetSelections(self, items): + '''SetSelections(self, items)=>None +items - Sequence of strings to be selected +The items are displayed in the selection part of the widget''' + assert len(items)==len(set(items)),"duplicate items are not allowed" + if items != self._dest.GetItems(): + self._dest.SetItems(items) + self._FireIpSelectionChanged() + + + Selections = property(fget = GetSelections, + fset = SetSelections, + doc = 'See GetSelections/SetSelections') + + + def _CreateButtons(self): + sizer = wx.BoxSizer(wx.VERTICAL) + self.bAdd = wx.Button(self, -1, label = 'Add ->') + self.bAdd.Bind(wx.EVT_BUTTON, self._OnAdd) + self.bRemove = wx.Button(self, -1, label = '<- Remove') + self.bRemove.Bind(wx.EVT_BUTTON, self._OnRemove) + sizer.Add(self.bAdd, 0, wx.EXPAND|wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5) + sizer.Add(self.bRemove, 0, wx.EXPAND|wx.ALL, 5) + return sizer + + + def _set_add_button_label(self, label=None): + if label is None: + return + self.bAdd.SetLabel(label) + + add_button_label = property(fset = _set_add_button_label, fget = lambda x:x) + + + def _set_remove_button_label(self, label=None): + if label is None: + return + self.bRemove.SetLabel(label) + + remove_button_label = property(fset = _set_remove_button_label, fget = lambda x:x) + + + def _OnAdd(self, e): + if self._ipStyle & IP_REMOVE_FROM_CHOICES: + self._MoveItems(self._source,self._dest) + else: + self._AddSelectedItems() + + def _MoveItems(self,source,dest): + selections = source.GetSelections() + selectedItems = map(source.GetString, selections) + dest.SetItems(dest.GetItems() + selectedItems) + selections = set(selections) + #source.SetItems([item for i, item in enumerate(source.GetItems())\ + # if i not in selections]) + self._FireIpSelectionChanged() + + def _AddSelectedItems(self): + newItems = self._source.getselectedwords()#map(self._source.GetString, self._source.GetSelections()) + items = [self._destData[i][0] for i in self._destData] + oldItems = set(items) + for newItem in newItems: + if newItem not in oldItems: + self._destData[len(self._destData)] = [newItem, ''] + self._SetDestItems() + self._source.selected[newItem] = 1 + self._source.Refresh() + #self.SetSelections(items) + self._FireIpSelectionChanged() + + def _FireIpSelectionChanged(self): + self.GetEventHandler().ProcessEvent( + IpSelectionChanged(self.GetId(), + None, + self )) + + + def _OnRemove(self, e): + if self._ipStyle & IP_REMOVE_FROM_CHOICES: + self._MoveItems(self._dest, self._source) + else: + self._RemoveSelected() + + def _RemoveSelected(self): + selections = self._dest.getselectedwords() + if selections: + #allItems = self._dest.GetItems() + #items = [item for i, item in enumerate(allItems)\ + # if i not in selections] + #notselected = [item for i, item in enumerate(allItems)\ + # if i in selections] + + for item in selections : + del self._source.selected[item] + tokeep = [self._destData[i][0] for i in self._destData if self._destData[i][0] not in selections] + self._destData = dict([[i, [word, '']] for i, word in enumerate(tokeep)]) + self._source.Refresh() + self._SetDestItems() + #self.SetSelections(items) + self._FireIpSelectionChanged() + + + def _CreateSourceList(self, items, label): + style = LB_STYLE + if self._ipStyle & IP_SORT_CHOICES: + style |= wx.LB_SORT + sizer = wx.BoxSizer(wx.VERTICAL) + if label: + sizer.Add(wx.StaticText(self, label = label), 0, + wx.ALIGN_LEFT|wx.ALL, 5) + #self._source = wx.VListBox(self, -1, style = style) + self._source = ListForSpec(self, self.parent, dlist = items, first = ['eff'], menu = True) + self._source.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self._OnDClick) + #self._source.Bind(wx.EVT_LISTBOX_DCLICK, self._OnDClick) + #self._source.SetItems(items) + sizer.Add(self._source, 1, wx.EXPAND|wx.ALL, 5) + return sizer + + + def _CreateDestList(self, label): + style = LB_STYLE + if self._ipStyle & IP_SORT_SELECTED: + style |= wx.LB_SORT + sizer = wx.BoxSizer(wx.VERTICAL) + if label: + sizer.Add(wx.StaticText(self, label = label), 0, + wx.ALIGN_LEFT|wx.ALL, 5) + #self._dest = wx.ListBox(self, -1, style = style) + self._dest = ListForSpec(self, self.parent, dlist = {}, first = ['eff'], menu = True) + self._dest.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self._OnDClick) + #self._dest.Bind(wx.EVT_LISTBOX_DCLICK, self._OnDClick) + sizer.Add(self._dest, 1, wx.EXPAND|wx.ALL, 5) + return sizer + + def _SetDestItems(self): + self._dest.itemDataMap = self._destData + self._dest.itemIndexMap = self._destData.keys() + self._dest.SetItemCount(len(self._destData)) + self._dest.Refresh() + + def _OnDClick(self, e): + lb = e.GetEventObject() + selections = lb.GetSelections() + if len(selections) != 1: + return #DCLICK only works on one item + #if e.GetSelection() != selections[0]: + #this can happen using ^DCLICK when two items are selected + # return + if lb == self._source: + self._OnAdd(e) + else: + self._OnRemove(e) + + + + +if __name__ == '__main__': + print 'ezerzerzer' + test = wx.App(0) + frame = wx.Frame(None, -1) + d = wx.Dialog(frame, style = wx.RESIZE_BORDER|wx.DEFAULT_DIALOG_STYLE) + + d.sizer = wx.BoxSizer(wx.VERTICAL) + d.sizer.Add(wx.StaticText(d, -1, label = 'Example of the ItemsPicker'), + 0, wx.ALL, 10) + ip = ItemsPicker(d, -1, ['pop', 'cool', 'lame'], + 'Stuff:', 'Selected stuff:',IP_SORT_SELECTED|IP_SORT_CHOICES|IP_REMOVE_FROM_CHOICES) + ip.add_button_label = u'left -> right' + ip.remove_button_label = u'right -> left' + d.sizer.Add(ip, 1, wx.EXPAND, 1) + d.SetSizer(d.sizer) + test.SetTopWindow(frame) + def callback(e): + print 'selected items', e.GetItems() + d.Bind(EVT_IP_SELECTION_CHANGED, callback) + d.ShowModal() + d.Destroy() + frame.Close() \ No newline at end of file