multisplit
[iramuteq] / search_list.py
1 # -*- coding: utf-8 -*-
2 #Author: Pierre Ratinaud
3 #Copyright (c) 2008-2020 Pierre Ratinaud
4 #modification pour python 3 : Laurent Mérat, 6x7 - mai 2020
5 #License: GNU/GPL
6
7 #----------------------------------------------------------------------------
8 # comes from ListCtrl.py from the demo tool of wxPython:
9 # Author:       Robin Dunn & Gary Dumer
10 #
11 # Created:
12 # Copyright:    (c) 1998 by Total Control Software
13 # Licence:      wxWindows license
14 #----------------------------------------------------------------------------
15
16 #------------------------------------
17 # import des modules python
18 #------------------------------------
19 import os
20 import sys
21 import io
22 import tempfile
23
24 #------------------------------------
25 # import des modules wx
26 #------------------------------------
27 import wx
28 import wx.lib.mixins.listctrl as listmix
29
30 #------------------------------------
31 # import des fichiers du projet
32 #------------------------------------
33 from functions import exec_rcode
34 from dialog import message, BarFrame
35 from chemins import ffr
36
37
38 class SearchList(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.ColumnSorterMixin): #wx.Panel, listmix.ColumnSorterMixin):
39
40     def __init__(self, parent,gparent, dlist,first, nbactives, nbetoiles, add_dendro=True):
41         wx.ListCtrl.__init__( self, parent, -1, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES)
42         self.parent=parent
43         self.gparent=gparent
44         self.dlist=dlist
45         self.add_dendro=add_dendro
46         self.first = ['id','formes'] + first
47         self.lenact = nbactives
48         self.lensup = len(dlist) - (self.lenact + nbetoiles)
49         #adding some art
50         self.il = wx.ImageList(16, 16)
51         a={"sm_up":"GO_UP","sm_dn":"GO_DOWN","w_idx":"WARNING","e_idx":"ERROR","i_idx":"QUESTION"}
52         for k,v in list(a.items()):
53             s="self.%s= self.il.Add(wx.ArtProvider.GetBitmap(wx.ART_%s,wx.ART_TOOLBAR,(16,16)))" % (k,v)
54             exec(s)
55         self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
56         self.attr1 = wx.ListItemAttr()
57         self.attr1.SetBackgroundColour((220, 220, 220))
58         self.attrsg = wx.ListItemAttr()
59         self.attrsg.SetBackgroundColour((230, 230, 230))
60         self.attr2 = wx.ListItemAttr()
61         self.attr2.SetBackgroundColour((190, 249, 236))
62         self.attr2s = wx.ListItemAttr()
63         self.attr2s.SetBackgroundColour((211, 252, 244))
64         self.attr3 = wx.ListItemAttr()
65         self.attr3.SetBackgroundColour((245, 180, 180))
66         self.attr3s = wx.ListItemAttr()
67         self.attr3s.SetBackgroundColour((245, 190, 190))
68         tID = wx.NewId()
69         self.dlist = dlist 
70         self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self)
71         #self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick)
72         # for wxMSW
73         self.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
74         # for wxGTK
75         self.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
76
77         #-----------------------------------------------------------
78         first = ['id','formes']+first
79         for i, name in enumerate(first) :
80             self.InsertColumn(i, name, wx.LIST_FORMAT_LEFT)
81         self.SetColumnWidth(0, wx.LIST_AUTOSIZE)
82         for i in range(1,len(first)-1):
83             self.SetColumnWidth(i, 130)
84         self.itemDataMap = dlist
85         self.itemIndexMap = list(dlist.keys())
86         self.SetItemCount(len(dlist))
87         listmix.ColumnSorterMixin.__init__(self, len(first)+2)
88         self.SortListItems(0, True)
89
90     # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
91     def GetListCtrl(self):
92         return self
93
94     # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
95     def GetSortImages(self):
96         return (self.sm_dn, self.sm_up)
97
98     def OnGetItemColumnImage(self, item, col):
99         return -1
100
101     def OnGetItemImage(self, item):
102         pass
103
104     def OnRightDown(self, event):
105         x = event.GetX()
106         y = event.GetY()
107         item, flags = self.HitTest((x, y))
108         if flags & wx.LIST_HITTEST_ONITEM:
109             self.Select(item)
110         event.Skip()
111
112     def getColumnText(self, index, col):
113         item = self.GetItem(index, col)
114         return item.GetText()
115
116     def OnGetItemText(self, item, col):
117         index=self.itemIndexMap[item]
118         s = self.itemDataMap[index][col]
119         if isinstance(s, (int,float)):
120             return str(s)
121         else :
122             return s
123
124     def OnGetItemData(self, item) :
125         index = self.itemIndexMap[item]
126         s = self.itemDataMap[index]
127         return s
128
129     def OnItemSelected(self, event):
130         self.currentItem = event.m_itemIndex
131         event.Skip()
132
133     def OnGetItemAttr(self, item):
134         index=self.itemIndexMap[item]
135         #genre=self.itemDataMap[index][2]
136         if index < self.lenact :
137             if item % 2 :
138                 return self.attr1
139             else :
140                 return self.attrsg
141         elif index >= self.lenact and index < (self.lenact + self.lensup) :
142             if item % 2 :
143                 return self.attr2
144             else :
145                 return self.attr2s
146         elif index >= (self.lenact + self.lensup) :
147             if item % 2 :
148                 return self.attr3
149             else :
150                 return self.attr3s
151         else :
152             return None
153
154 #    def SortItems(self,sorter=cmp): ancienne version pour python 2
155     def SortItems(self, sorter=None):
156         listTemp = sorted(self.itemDataMap.items(),
157             key=lambda x:x[1][self._col], reverse= (self._colSortFlag[self._col]!=True))
158         dlist = dict([[line[0],line[1]] for line in listTemp])
159         self.itemDataMap = dlist
160         self.itemIndexMap = list(dlist.keys())
161         self.Refresh() # redraw the list
162
163     def OnRightClick(self, event):
164         # only do this part the first time so the events are only bound once
165         if not hasattr(self, "popupID1"):
166             #self.popupID1 = wx.NewId()
167             #self.popupID2 = wx.NewId()
168             self.popupID3 = wx.NewId()
169             if self.add_dendro :
170                 self.id_adddendro = wx.NewId()
171                 self.Bind(wx.EVT_MENU, self.ongraphdendro, id = self.id_adddendro)
172             #self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
173             #self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
174             self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
175         # make a menu
176         menu = wx.Menu()
177         # add some items
178         #menu.Append(self.popupID1, "Formes associées")
179         #menu.Append(self.popupID2, "Concordancier")
180         menu.Append(self.popupID3, "Graphique")
181         if self.add_dendro :
182             menu.Append(self.id_adddendro, "Graphique + dendrogramme")
183         self.PopupMenu(menu)
184         menu.Destroy()
185
186     def getselectedwords(self) :
187         words = [self.getColumnText(self.GetFirstSelected(), 6)]
188         last = self.GetFirstSelected()
189         while self.GetNextSelected(last) != -1:
190             last = self.GetNextSelected(last)
191             words.append(self.getColumnText(last, 6))
192         return words
193
194     def OnPopupOne(self, event):
195         activenotebook = self.parent.nb.GetSelection()
196         page = self.parent.nb.GetPage(activenotebook)
197         corpus = page.corpus
198         word = self.getColumnText(self.GetFirstSelected(), 0)
199         lems = corpus.lems
200         rep = []
201         for forme in lems[word] :
202             rep.append([forme, corpus.formes[forme][0]])
203         win = message(self, "Formes associées", size=(300, 200))
204         win.html = '<html>\n' + '<br>'.join([' : '.join([str(val) for val in forme]) for forme in rep]) + '\n</html>'
205         win.HtmlPage.SetPage(win.html)
206         win.Show(True)
207
208     def OnPopupTwo(self, event):
209         activenotebook = self.parent.nb.GetSelection()
210         page = self.parent.nb.GetPage(activenotebook)
211         item=self.getColumnText(self.GetFirstSelected(), 0)
212         corpus = page.corpus
213         win = message(self, "Concordancier", size=(600, 200))
214         avap=60
215         listmot = corpus.lems[item]
216         uce_ok = [corpus.formes[forme][1] for forme in listmot]
217         uce_ok = list(set([tuple(val) for line in uce_ok for val in line]))
218         txt = '<h1>Concordancier</h1>'
219         for uce in uce_ok:
220             content = ' '+' '.join(corpus.ucis_paras_uces[uce[0]][uce[1]][uce[2]])+' '
221             for form in listmot :
222                 sp = ''
223                 i = 0
224                 forme = ' ' + form + ' '
225                 while i < len(content):
226                     coordword = content[i:].find(forme)
227                     if coordword != -1 and i == 0:
228                         txt += '<br><b>' + ' '.join(corpus.ucis[uce[0]][0]) + '</b><br>'
229                         if coordword < avap:
230                             sp = '&nbsp;' * (avap - coordword)
231                             deb = i
232                         else:
233                             deb = i + coordword - avap
234                         if len(content) < i + coordword + avap:
235                             fin = len(content) - 1
236                         else:
237                             fin = i + coordword + avap
238                         txt += '<TT>' + sp + content[deb:fin].replace(forme, '<font color=red>' + forme + '</font>') + '</TT><br>'
239                         i += coordword + len(forme)
240                         sp = ''
241                     elif coordword != -1 and i != 0 :
242                         if coordword < avap:
243                             sp = '&nbsp;' * (avap - coordword)
244                             deb = i
245                         else:
246                             deb = i + coordword - avap
247                         if len(content) < i + coordword + avap:
248                             fin = len(content) - 1
249                         else:
250                             fin = i + coordword + avap
251                         txt += '<TT>' + sp + content[deb:fin].replace(forme, '<font color=red>' + forme + '</font>') + '</TT><br>'
252                         i += coordword + len(forme)
253                         sp = ''                   
254                     else:
255                         i = len(content)
256                         sp = ''
257         win.HtmlPage.SetPage(txt)
258         win.Show(True)
259
260     def OnPopupThree(self, event) :
261         datas = [self.OnGetItemData(self.GetFirstSelected())]
262         last = self.GetFirstSelected()
263         while self.GetNextSelected(last) != -1:
264             last = self.GetNextSelected(last)
265             data = self.OnGetItemData(last)
266             datas += [data]
267         colnames = self.first[2:]
268         rownames = [val[1] for val in datas]
269         table = [[str(val) for val in line[2:]] for line in datas]
270         BarFrame(self.parent.parent, table, colnames, rownames)
271
272     def ongraphdendro(self, evt) :
273         corpus = self.parent.corpus
274         datas = [self.OnGetItemData(self.GetFirstSelected())]
275         last = self.GetFirstSelected()
276         while self.GetNextSelected(last) != -1:
277             last = self.GetNextSelected(last)
278             data = self.OnGetItemData(last)
279             datas += [data]
280         colnames = self.first[2:]
281         rownames = [val[1] for val in datas]
282         table = [[str(val) for val in line[2:]] for line in datas]
283         tmpgraph = tempfile.mktemp(dir=self.parent.parent.TEMPDIR)
284         BarFrame(self.parent.parent, table, colnames, rownames, tree = corpus.dictpathout['Rdendro'])