multisplit
[iramuteq] / vitemspicker.py
1 # -*- coding: utf-8 -*-
2 #modification pour python 3 : Laurent Mérat, 6x7 - mai 2020
3
4 '''
5 Created on Oct 3, 2010
6
7 @authors: Daphna Rosenbom,Gitty Zinger,Moshe Cohavi and Yoav Glazner
8 The widget is contributed by NDS ltd under the same license as wxPython
9
10 items_picker.ItemsPicker:
11 - Displays available items to choose from,</LI>
12 - Selection is done by the Add button or Double Click,</LI>
13 - De-Selection is done by the Remove button or Double Click,</LI>
14
15 Derived from wxPanel
16 '''
17
18 #------------------------------------
19 # import des modules python
20 #------------------------------------
21 import langue
22 langue.run()
23
24 #------------------------------------
25 # import des modules wx
26 #------------------------------------
27 import wx
28
29 #------------------------------------
30 # import des fichiers du projet
31 #------------------------------------
32 from listlex import ListForSpec
33
34
35 __version__ = 0.1
36
37 IP_DEFAULT_STYLE = 0
38 IP_SORT_CHOICES = 1
39 IP_SORT_SELECTED = 2
40 IP_REMOVE_FROM_CHOICES = 4
41 wxEVT_IP_SELECTION_CHANGED = wx.NewEventType()
42 EVT_IP_SELECTION_CHANGED = wx.PyEventBinder(wxEVT_IP_SELECTION_CHANGED, 1)
43 LB_STYLE = wx.LB_EXTENDED|wx.LB_HSCROLL
44
45
46 class IpSelectionChanged(wx.PyCommandEvent):
47
48     def __init__(self, id, items, object = None):
49         wx.PyCommandEvent.__init__(self, wxEVT_IP_SELECTION_CHANGED, id)
50         self.__items = items
51         self.SetEventObject(object)
52
53     def GetItems(self):
54         return self.__items
55
56
57 class VItemsPicker(wx.Panel):
58     '''
59 ItemsPicker is a widget that allows the user to form a set of picked
60 items out of a given list
61 '''
62
63     def __init__(self, parent, id=wx.ID_ANY, choices = [],
64                  label = '', selectedLabel = '',
65                  ipStyle = IP_DEFAULT_STYLE,
66                  *args, **kw):
67         '''
68 ItemsPicker(parent, choices = [], label = '', selectedLabel = '',
69 ipStyle = IP_DEFAULT_STYLE)
70 '''
71         self.parent = parent
72         self._destData = {}
73         wx.Panel.__init__(self, parent, id, *args, **kw)
74         self._ipStyle = ipStyle
75         sizer = wx.BoxSizer(wx.HORIZONTAL)
76         sizer.Add(self._CreateSourceList(choices, label), 1,
77                    wx.EXPAND|wx.ALL, 5)
78         sizer.Add(self._CreateButtons(), 0, wx.ALIGN_CENTER|wx.ALL, 5)
79         sizer.Add(self._CreateDestList(selectedLabel), 1,
80                    wx.EXPAND|wx.ALL, 5)
81         self.SetSizer(sizer)
82
83     def SetItems(self, items):
84         '''SetItems(self, items)=> None
85 items - Sequence of strings that the user can pick from'''
86         pass
87         #return self._source.SetItems(items)
88
89     def GetItems(self):
90         '''GetItems(self)=> items
91 returns list of strings that the user can pick from'''
92         return self._source.GetItems()
93
94     # propriété de VItemsPicker
95     Items = property(fget = GetItems,
96                      fset = SetItems,
97                      doc = 'See GetItems/SetItems')
98
99     def GetSelections(self):
100         '''GetSelections(self)=>items
101 returns list of strings that were selected
102 '''
103         return [self._destData[i][0] for i in self._destData]
104
105     def SetSelections(self, items):
106         '''SetSelections(self, items)=>None
107 items - Sequence of strings to be selected
108 The items are displayed in the selection part of the widget'''
109         assert len(items)==len(set(items)),"duplicate items are not allowed"
110         if items != self._dest.GetItems():
111             self._dest.SetItems(items)
112             self._FireIpSelectionChanged()
113
114     # propriété de VItemsPicker
115     Selections = property(fget = GetSelections,
116                      fset = SetSelections,
117                      doc = 'See GetSelections/SetSelections')
118
119     def _CreateButtons(self):
120         sizer = wx.BoxSizer(wx.VERTICAL)
121         self.bAdd = wx.Button(self, -1, label = 'Add ->')
122         self.bAdd.Bind(wx.EVT_BUTTON, self._OnAdd)
123         self.bRemove = wx.Button(self, -1, label = '<- Remove')
124         self.bRemove.Bind(wx.EVT_BUTTON, self._OnRemove)
125         sizer.Add(self.bAdd, 0, wx.EXPAND, 5)
126         sizer.Add(self.bRemove, 0, wx.EXPAND|wx.ALL, 5)
127         return sizer
128
129     def _set_add_button_label(self, label=None):
130         if label is None:
131             return
132         self.bAdd.SetLabel(label)
133
134     # propriété ???
135     add_button_label = property(fset = _set_add_button_label, fget = lambda x:x)
136
137     def _set_remove_button_label(self, label=None):
138         if label is None:
139             return
140         self.bRemove.SetLabel(label)
141
142     # propriété ???
143     remove_button_label = property(fset = _set_remove_button_label, fget = lambda x:x)
144
145     def _OnAdd(self, e):
146         if self._ipStyle & IP_REMOVE_FROM_CHOICES:
147             self._MoveItems(self._source,self._dest)
148         else:
149             self._AddSelectedItems()
150
151     def _MoveItems(self,source,dest):
152         selections = source.GetSelections()
153         selectedItems = list(map(source.GetString, selections))
154         dest.SetItems(dest.GetItems() + selectedItems)
155         selections = set(selections)
156         #source.SetItems([item for i, item in enumerate(source.GetItems())\
157         #              if i not in selections])
158         self._FireIpSelectionChanged()
159
160     def _AddSelectedItems(self):
161         newItems = self._source.getselectedwords()#map(self._source.GetString, self._source.GetSelections())
162         items = [self._destData[i][0] for i in self._destData]
163         oldItems = set(items)
164         for newItem in newItems:
165             if newItem not in oldItems:
166                 self._destData[len(self._destData)] = [newItem, '']
167                 self._SetDestItems()
168                 self._source.selected[newItem] = 1
169                 self._source.Refresh()
170         #self.SetSelections(items)
171         self._FireIpSelectionChanged()
172
173     def _FireIpSelectionChanged(self):
174             self.GetEventHandler().ProcessEvent(
175                         IpSelectionChanged(self.GetId(),
176                                             None,
177                                              self ))
178
179     def _OnRemove(self, e):
180         if self._ipStyle & IP_REMOVE_FROM_CHOICES:
181             self._MoveItems(self._dest, self._source)
182         else:
183             self._RemoveSelected()
184
185     def _RemoveSelected(self):
186         selections = self._dest.getselectedwords()
187         if selections:
188             #allItems = self._dest.GetItems()
189             #items = [item for i, item in enumerate(allItems)\
190             #          if i not in selections]
191             #notselected = [item for i, item in enumerate(allItems)\
192             #          if i in selections]
193             for item in selections :
194                 print(item)
195                 del self._source.selected[item]
196             tokeep = [self._destData[i][0] for i in self._destData if self._destData[i][0] not in selections]
197             self._destData = dict([[i, [word, '']] for i, word in enumerate(tokeep)])
198             self._source.Refresh()
199             self._SetDestItems()
200             #self.SetSelections(items)
201             self._FireIpSelectionChanged()
202
203     def _CreateSourceList(self, items, label):
204         style = LB_STYLE
205         if self._ipStyle & IP_SORT_CHOICES:
206             style |= wx.LB_SORT
207         sizer = wx.BoxSizer(wx.VERTICAL)
208         if label:
209             sizer.Add(wx.StaticText(self, label = label), 0,
210                        wx.ALIGN_LEFT|wx.ALL, 5)
211         #self._source = wx.VListBox(self, -1, style = style)
212         self._source = ListForSpec(self, self.parent, dlist = items, first = ['eff', _("POS")], menu = True)
213         self._source.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self._OnDClick)
214         #self._source.Bind(wx.EVT_LISTBOX_DCLICK, self._OnDClick)
215         #self._source.SetItems(items)
216         sizer.Add(self._source, 1, wx.EXPAND|wx.ALL, 5)
217         return sizer
218
219     def _CreateDestList(self, label):
220         style = LB_STYLE
221         if self._ipStyle & IP_SORT_SELECTED:
222             style |= wx.LB_SORT
223         sizer = wx.BoxSizer(wx.VERTICAL)
224         if label:
225             sizer.Add(wx.StaticText(self, label = label), 0,
226                        wx.ALIGN_LEFT|wx.ALL, 5)
227         #self._dest = wx.ListBox(self, -1, style = style)
228         self._dest = ListForSpec(self, self.parent, dlist = {}, first = ['eff'], menu = True)
229         self._dest.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self._OnDClick)
230         #self._dest.Bind(wx.EVT_LISTBOX_DCLICK, self._OnDClick)
231         sizer.Add(self._dest, 1, wx.EXPAND|wx.ALL, 5)
232         return sizer
233
234     def _SetDestItems(self):
235         self._dest.itemDataMap = self._destData
236         self._dest.itemIndexMap = list(self._destData.keys())
237         self._dest.SetItemCount(len(self._destData))
238         self._dest.Refresh()
239
240     def _OnDClick(self, e):
241         lb = e.GetEventObject()
242         selections = lb.GetSelections()
243         if len(selections) != 1:
244             return #DCLICK only works on one item
245         #if e.GetSelection() != selections[0]:
246             #this can happen using ^DCLICK when two items are selected
247         #    return
248         if lb == self._source:
249             self._OnAdd(e)
250         else:
251             self._OnRemove(e)