windows
[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         self.itemDataMap = dlist
77         self.itemIndexMap = list(dlist.keys())
78         self.SetItemCount(len(dlist))
79         listmix.ColumnSorterMixin.__init__(self, len(first)+2)
80         #-----------------------------------------------------------
81         first = ['id','formes']+first
82         for i, name in enumerate(first) :
83             self.InsertColumn(i, name, wx.LIST_FORMAT_LEFT)
84         self.SetColumnWidth(0, wx.LIST_AUTOSIZE)
85         for i in range(1,len(first)-1):
86             self.SetColumnWidth(i, 130)
87         self.SortListItems(0, True)
88
89     # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
90     def GetListCtrl(self):
91         return self
92
93     # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
94     def GetSortImages(self):
95         return (self.sm_dn, self.sm_up)
96
97     def OnGetItemColumnImage(self, item, col):
98         return -1
99
100     def OnGetItemImage(self, item):
101         pass
102
103     def OnRightDown(self, event):
104         x = event.GetX()
105         y = event.GetY()
106         item, flags = self.HitTest((x, y))
107         if flags & wx.LIST_HITTEST_ONITEM:
108             self.Select(item)
109         event.Skip()
110
111     def getColumnText(self, index, col):
112         item = self.GetItem(index, col)
113         return item.GetText()
114
115     def OnGetItemText(self, item, col):
116         index=self.itemIndexMap[item]
117         s = self.itemDataMap[index][col]
118         return s
119
120     def OnGetItemData(self, item) :
121         index = self.itemIndexMap[item]
122         s = self.itemDataMap[index]
123         return s
124
125     def OnItemSelected(self, event):
126         self.currentItem = event.m_itemIndex
127         event.Skip()
128
129     def OnGetItemAttr(self, item):
130         index=self.itemIndexMap[item]
131         #genre=self.itemDataMap[index][2]
132         if index < self.lenact :
133             if item % 2 :
134                 return self.attr1
135             else :
136                 return self.attrsg
137         elif index >= self.lenact and index < (self.lenact + self.lensup) :
138             if item % 2 :
139                 return self.attr2
140             else :
141                 return self.attr2s
142         elif index >= (self.lenact + self.lensup) :
143             if item % 2 :
144                 return self.attr3
145             else :
146                 return self.attr3s
147         else :
148             return None
149
150 #    def SortItems(self,sorter=cmp): ancienne version pour python 2
151     def SortItems(self, sorter=None):
152         listTemp = sorted(self.itemDataMap.items(),
153             key=lambda x:x[1][self._col], reverse= (self._colSortFlag[self._col]!=True))
154         dlist = dict([[line[0],line[1]] for line in listTemp])
155         self.itemDataMap = dlist
156         self.itemIndexMap = list(dlist.keys())
157         self.Refresh() # redraw the list
158
159     def OnRightClick(self, event):
160         # only do this part the first time so the events are only bound once
161         if not hasattr(self, "popupID1"):
162             #self.popupID1 = wx.NewId()
163             #self.popupID2 = wx.NewId()
164             self.popupID3 = wx.NewId()
165             if self.add_dendro :
166                 self.id_adddendro = wx.NewId()
167                 self.Bind(wx.EVT_MENU, self.ongraphdendro, id = self.id_adddendro)
168             #self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
169             #self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
170             self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
171         # make a menu
172         menu = wx.Menu()
173         # add some items
174         #menu.Append(self.popupID1, "Formes associées")
175         #menu.Append(self.popupID2, "Concordancier")
176         menu.Append(self.popupID3, "Graphique")
177         if self.add_dendro :
178             menu.Append(self.id_adddendro, "Graphique + dendrogramme")
179         self.PopupMenu(menu)
180         menu.Destroy()
181
182     def getselectedwords(self) :
183         words = [self.getColumnText(self.GetFirstSelected(), 6)]
184         last = self.GetFirstSelected()
185         while self.GetNextSelected(last) != -1:
186             last = self.GetNextSelected(last)
187             words.append(self.getColumnText(last, 6))
188         return words
189
190     def OnPopupOne(self, event):
191         activenotebook = self.parent.nb.GetSelection()
192         page = self.parent.nb.GetPage(activenotebook)
193         corpus = page.corpus
194         word = self.getColumnText(self.GetFirstSelected(), 0)
195         lems = corpus.lems
196         rep = []
197         for forme in lems[word] :
198             rep.append([forme, corpus.formes[forme][0]])
199         win = message(self, "Formes associées", size=(300, 200))
200         win.html = '<html>\n' + '<br>'.join([' : '.join([str(val) for val in forme]) for forme in rep]) + '\n</html>'
201         win.HtmlPage.SetPage(win.html)
202         win.Show(True)
203
204     def OnPopupTwo(self, event):
205         activenotebook = self.parent.nb.GetSelection()
206         page = self.parent.nb.GetPage(activenotebook)
207         item=self.getColumnText(self.GetFirstSelected(), 0)
208         corpus = page.corpus
209         win = message(self, "Concordancier", size=(600, 200))
210         avap=60
211         listmot = corpus.lems[item]
212         uce_ok = [corpus.formes[forme][1] for forme in listmot]
213         uce_ok = list(set([tuple(val) for line in uce_ok for val in line]))
214         txt = '<h1>Concordancier</h1>'
215         for uce in uce_ok:
216             content = ' '+' '.join(corpus.ucis_paras_uces[uce[0]][uce[1]][uce[2]])+' '
217             for form in listmot :
218                 sp = ''
219                 i = 0
220                 forme = ' ' + form + ' '
221                 while i < len(content):
222                     coordword = content[i:].find(forme)
223                     if coordword != -1 and i == 0:
224                         txt += '<br><b>' + ' '.join(corpus.ucis[uce[0]][0]) + '</b><br>'
225                         if coordword < avap:
226                             sp = '&nbsp;' * (avap - coordword)
227                             deb = i
228                         else:
229                             deb = i + coordword - avap
230                         if len(content) < i + coordword + avap:
231                             fin = len(content) - 1
232                         else:
233                             fin = i + coordword + avap
234                         txt += '<TT>' + sp + content[deb:fin].replace(forme, '<font color=red>' + forme + '</font>') + '</TT><br>'
235                         i += coordword + len(forme)
236                         sp = ''
237                     elif coordword != -1 and i != 0 :
238                         if coordword < avap:
239                             sp = '&nbsp;' * (avap - coordword)
240                             deb = i
241                         else:
242                             deb = i + coordword - avap
243                         if len(content) < i + coordword + avap:
244                             fin = len(content) - 1
245                         else:
246                             fin = i + coordword + avap
247                         txt += '<TT>' + sp + content[deb:fin].replace(forme, '<font color=red>' + forme + '</font>') + '</TT><br>'
248                         i += coordword + len(forme)
249                         sp = ''                   
250                     else:
251                         i = len(content)
252                         sp = ''
253         win.HtmlPage.SetPage(txt)
254         win.Show(True)
255
256     def OnPopupThree(self, event) :
257         datas = [self.OnGetItemData(self.GetFirstSelected())]
258         last = self.GetFirstSelected()
259         while self.GetNextSelected(last) != -1:
260             last = self.GetNextSelected(last)
261             data = self.OnGetItemData(last)
262             datas += [data]
263         colnames = self.first[2:]
264         rownames = [val[1] for val in datas]
265         table = [[str(val) for val in line[2:]] for line in datas]
266         BarFrame(self.parent.parent, table, colnames, rownames)
267
268     def ongraphdendro(self, evt) :
269         corpus = self.parent.corpus
270         datas = [self.OnGetItemData(self.GetFirstSelected())]
271         last = self.GetFirstSelected()
272         while self.GetNextSelected(last) != -1:
273             last = self.GetNextSelected(last)
274             data = self.OnGetItemData(last)
275             datas += [data]
276         colnames = self.first[2:]
277         rownames = [val[1] for val in datas]
278         table = [[str(val) for val in line[2:]] for line in datas]
279         tmpgraph = tempfile.mktemp(dir=self.parent.parent.TEMPDIR)
280         BarFrame(self.parent.parent, table, colnames, rownames, tree = corpus.dictpathout['Rdendro'])