...
[iramuteq] / ProfList.py
1 # -*- coding: utf-8 -*-
2
3 #----------------------------------------------------------------------------
4 # Name:         ListCtrl.py
5 # Author:       Pierre Ratinaud
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 import os
17 import sys
18 import  wx
19 import  wx.lib.mixins.listctrl  as  listmix
20 from tabsimi import DoSimi
21 from listlex import ListForSpec
22 from chemins import ConstructPathOut, ffr
23 from dialog import PrefExport, PrefUCECarac, SearchDial
24 from tableau import Tableau
25 from search_tools import SearchFrame
26 import webbrowser
27 import cStringIO
28 import tempfile
29 import codecs
30 from functions import exec_rcode, MessageImage, progressbar, treat_var_mod
31 from PrintRScript import barplot
32 from textclassechd import ClasseCHD
33 from shutil import copyfile
34
35 #---------------------------------------------------------------------------
36
37 class ProfListctrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
38     def __init__(self, parent, ID, pos=wx.DefaultPosition,
39                  size=wx.DefaultSize, style=0):
40         wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
41         listmix.ListCtrlAutoWidthMixin.__init__(self)
42
43
44 class ProfListctrlPanel(wx.Panel, listmix.ColumnSorterMixin):
45     def __init__(self, parent, gparent, ProfClasse, Alceste=False, cl=0):
46         self.parent = parent
47         classe = ProfClasse
48         self.cl = cl
49         self.Source = gparent
50         if 'tableau' in dir(self.Source):
51             self.tableau = self.Source.tableau
52         self.Alceste = Alceste
53         self.var_mod = {}
54         
55
56         wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
57         
58         search_id = wx.NewId()
59         searchall_id = wx.NewId()
60         self.parent.Bind(wx.EVT_MENU, self.onsearch, id = search_id)
61         self.parent.Bind(wx.EVT_MENU, self.onsearchall, id = searchall_id)
62         self.accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('F'), search_id),
63                                               (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('F'), searchall_id)])
64         self.SetAcceleratorTable(self.accel_tbl)
65        
66         self.il = wx.ImageList(16, 16)
67 #        self.idx1 = self.il.Add(images.getSmilesBitmap())
68         self.sm_up = self.il.Add(getSmallUpArrowBitmap())
69         self.sm_dn = self.il.Add(getSmallDnArrowBitmap())
70         tID = wx.NewId()
71
72         self.list = ProfListctrl(self, tID,
73                                  style=wx.LC_REPORT 
74                                  | wx.BORDER_NONE
75                                  | wx.LC_EDIT_LABELS
76                                  | wx.LC_SORT_ASCENDING
77                                  )
78         line1 = classe.pop(0)
79         limit = 0
80         limitsup = 0
81         i = 0
82         dictdata = {}
83         classen = [line for line in classe if line[0] != '*' and line[0] != '*****']
84         if len(classen) == 0 :
85             lenact = 0
86             lensup = 0
87             lenet = 0
88         else :
89             lenact = [i for i,b in enumerate(classe) if b[0] == '*****']
90             if lenact == [] :
91                 lensup = 0
92                 lenact = [i for i,b in enumerate(classe) if b[0] == '*']
93                 if lenact == [] :
94                     lenact = len(classen)
95                     lenet = 0
96                 else :
97                     lenact = 0
98                     lenet = len(classen)
99             else :
100                 lenact = lenact[0]
101                 lensup = [i for i,b in enumerate(classe[1:]) if b[0] == '*']
102                 if lensup != [] :
103                    lensup = lensup[0] - lenact
104                    lenet = len(classen) - lensup
105                 else :
106                    lensup == 0
107                    lenet = len(classen)
108         debsup = lenact
109                 
110         self.lenact = lenact
111
112         debet = lenact + lensup
113         dictdata = dict(zip([i for i in range(0,len(classen))], classen))
114         self.list.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
115         
116         self.PopulateList(dictdata, debet, debsup, Alceste)
117
118         self.Bind(wx.EVT_SIZE, self.OnSize)
119         self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick)
120         self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list)
121
122         # for wxMSW
123         self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
124
125         # for wxGTK
126         self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
127         self.itemDataMap = dictdata
128         listmix.ColumnSorterMixin.__init__(self, 8)
129         self.do_greyline()
130 #-----------------------------------------------------------------------------------------    
131
132     def PopulateList(self, dictdata, limit, limitsup, Alceste):
133         
134         
135             # for normal, simple columns, you can add them like this:
136         self.list.InsertColumn(0, "num", wx.LIST_FORMAT_RIGHT)
137         self.list.InsertColumn(1, "eff. uce", wx.LIST_FORMAT_RIGHT)
138         self.list.InsertColumn(2, "eff. total", wx.LIST_FORMAT_RIGHT)
139         self.list.InsertColumn(3, "pourcentage", wx.LIST_FORMAT_RIGHT)
140         self.list.InsertColumn(4, "chi2", wx.LIST_FORMAT_RIGHT)
141         self.list.InsertColumn(5, "Type", wx.LIST_FORMAT_RIGHT)
142         self.list.InsertColumn(6, "forme", wx.LIST_FORMAT_RIGHT)
143         self.list.InsertColumn(7, "p", wx.LIST_FORMAT_RIGHT)
144         
145         for key in dictdata : #.iteritems():
146                 index = self.list.InsertStringItem(sys.maxint, '%4i' % key)
147                 i = 1
148                 for val in dictdata[key][1:]:
149                     self.list.SetStringItem(index, i, str(dictdata[key][i]))
150                     i += 1
151                 self.list.SetItemData(index, key)
152
153         self.list.SetColumnWidth(0, 60)
154         self.list.SetColumnWidth(1, 70)
155         self.list.SetColumnWidth(2, 80)
156         self.list.SetColumnWidth(3, 100)
157         self.list.SetColumnWidth(4, 70)
158         self.list.SetColumnWidth(5, wx.LIST_AUTOSIZE)
159         self.list.SetColumnWidth(6, wx.LIST_AUTOSIZE)
160         self.list.SetColumnWidth(7, wx.LIST_AUTOSIZE)
161
162         # show how to change the colour of a couple items
163         for i in range(limitsup, limit):
164             item = self.list.GetItem(i)
165             item.SetTextColour(wx.RED) 
166             self.list.SetItem(item)
167         
168         for i in range(limit, len(dictdata)):
169             item = self.list.GetItem(i)
170             item.SetTextColour(wx.BLUE)
171             self.list.SetItem(item)          
172         
173         if self.lenact != 0 :
174             self.la = [self.getColumnText(i,6) for i in range(0, self.lenact)]
175             self.lchi = [float(self.getColumnText(i,4)) for i in range(0, self.lenact)]
176             self.lfreq = [int(self.getColumnText(i,1)) for i in range(0, self.lenact)]
177         else :
178             self.la = []
179             self.lchi = []
180             self.lfreq = []
181
182     def do_greyline(self):
183         for row in xrange(self.list.GetItemCount()):
184             if row % 2 :
185                 self.list.SetItemBackgroundColour(row, (230, 230, 230))
186             else :
187                 self.list.SetItemBackgroundColour(row, wx.WHITE)
188
189
190     # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
191     def GetListCtrl(self):
192         return self.list
193
194     # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
195     def GetSortImages(self):
196         return (self.sm_dn, self.sm_up)
197
198
199     def OnRightDown(self, event):
200         x = event.GetX()
201         y = event.GetY()
202         item, flags = self.list.HitTest((x, y))
203
204         if flags & wx.LIST_HITTEST_ONITEM:
205             self.list.Select(item)
206
207         event.Skip()
208
209
210     def getColumnText(self, index, col):
211         item = self.list.GetItem(index, col)
212         return item.GetText()
213
214
215     def OnItemSelected(self, event):
216         self.currentItem = event.m_itemIndex
217         event.Skip()
218
219     def onsearch(self, evt) :
220         self.dial = SearchDial(self, self, 6, True)
221         self.dial.CenterOnParent()
222         self.dial.ShowModal()
223         self.dial.Destroy()
224
225     def onsearchall(self, evt) :
226         if 'FrameSearch' not in dir(self.Source) :
227             self.Source.FrameSearch = SearchFrame(self.parent, -1, u"Rechercher...", self.Source.corpus)
228         self.dial = SearchDial(self, self.Source.FrameSearch.liste, 1, False)
229         self.dial.CenterOnParent()
230         self.dial.ShowModal()
231         self.dial.Destroy()
232
233     def OnRightClick(self, event):
234
235         # only do this part the first time so the events are only bound once
236         if self.Alceste:
237             if not hasattr(self, "popupID1"):
238                 self.popupID1 = wx.NewId()
239                 self.popupID2 = wx.NewId()
240                 self.popupID3 = wx.NewId()
241                 self.popupID4 = wx.NewId()
242                 self.popupID5 = wx.NewId()
243                 self.popupID6 = wx.NewId()
244                 self.popupID7 = wx.NewId()
245                 self.popupID8 = wx.NewId()
246                 self.popupID9 = wx.NewId()
247                 #self.popupID10 = wx.NewId()
248                 self.popupIDgraph = wx.NewId()
249                 self.idseg = wx.NewId()
250                 self.iducecarac = wx.NewId()
251                 self.idtablex = wx.NewId()
252                 self.idchimod = wx.NewId()
253                 self.idwordgraph = wx.NewId()
254                 self.popup_proxe = wx.NewId()
255                 self.idlexdendro = wx.NewId()
256                 self.idexport = wx.NewId()
257             #    self.export_classes = wx.NewId()
258    
259                 self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
260                 self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
261                 self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
262                 self.Bind(wx.EVT_MENU, self.OnPopupFour, id=self.popupID4)
263                 self.Bind(wx.EVT_MENU, self.OnPopupFive, id=self.popupID5)
264                 self.Bind(wx.EVT_MENU, self.OnPopupSix, id=self.popupID6)
265                 self.Bind(wx.EVT_MENU, self.OnPopupSeven, id=self.popupID7)
266                 self.Bind(wx.EVT_MENU, self.OnPopupHeight, id=self.popupID8)
267                 self.Bind(wx.EVT_MENU, self.OnPopupNine, id=self.popupID9)
268                 #self.Bind(wx.EVT_MENU, self.OnPopupSpec, id=self.popupID10)
269                 self.Bind(wx.EVT_MENU, self.on_graph, id=self.popupIDgraph)
270                 self.Bind(wx.EVT_MENU, self.on_segments, id=self.idseg)
271                 self.Bind(wx.EVT_MENU, self.on_uce_carac, id = self.iducecarac)
272                 self.Bind(wx.EVT_MENU, self.on_tablex, id = self.idtablex)
273                 self.Bind(wx.EVT_MENU, self.quest_var_mod, id = self.idchimod)
274                 self.Bind(wx.EVT_MENU, self.onwordgraph, id = self.idwordgraph)
275                 self.Bind(wx.EVT_MENU, self.onproxe, id = self.popup_proxe)
276                 self.Bind(wx.EVT_MENU, self.onlexdendro, id = self.idlexdendro)
277                 self.Bind(wx.EVT_MENU, self.onexport, id = self.idexport)
278               #  self.Bind(wx.EVT_MENU, self.on_export_classes, id = self.export_classes)
279     #            self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
280     
281             # make a menu
282             menu = wx.Menu()
283             menu.Append(self.popupID1, u"Formes associées")
284             menu.Append(self.idtablex, u"Chi2 par classe")
285             menu.Append(self.idlexdendro, u"Chi2 par classe + dendro")
286             menu.Append(self.idchimod, u"Chi2 modalités de la variable")
287             menu.Append(self.idwordgraph, u"Graphe du mot")
288             #menu.Append(self.export_classes, u"Exporter le corpus...") 
289             
290             #menu.Append(self.popupID10, u"Spécificités")
291
292             menu_conc = wx.Menu()
293             menu_conc.Append(self.popupID2, u"dans les uce de la classe")
294             menu_conc.Append(self.popupID3, u"dans les uce classées")
295             menu_conc.Append(self.popupID4, u"dans toutes les uce")
296             menu.AppendMenu(-1, u"Concordancier", menu_conc) 
297             menu_cnrtl = wx.Menu()      
298             menu_cnrtl.Append(self.popupID5, u"Définition")
299             menu_cnrtl.Append(self.popupID6, u"Etymologie")
300             menu_cnrtl.Append(self.popupID7, u"Synonymie")
301             menu_cnrtl.Append(self.popupID8, u"Antonymie")
302             menu_cnrtl.Append(self.popupID9, u"Morphologie")
303             menu_cnrtl.Append(self.popup_proxe, u"Proxémie")
304             menu.AppendMenu(-1, u"Outils du CNRTL", menu_cnrtl)
305             menu.AppendSeparator()
306             menu.Append(self.popupIDgraph, u"Graphe de la classe")
307             menu.Append(self.idseg, u"Segments répétés")
308             menu.Append(self.iducecarac, u"UCE caractéristiques")
309             menu.Append(self.idexport, 'Partitionner...')
310             #menu.Append(self.popupID2, u"Concordancier")
311     #        menu.Append(self.popupID3, "recharger")
312     
313             self.PopupMenu(menu)
314             menu.Destroy()
315         elif 'tableau' in dir(self.Source) :
316             if not hasattr(self, "pop1"):
317                 self.pop1 = wx.NewId()
318                 self.pop2 = wx.NewId()
319                 self.pop3 = wx.NewId()
320                 self.Bind(wx.EVT_MENU, self.quest_simi, id=self.pop1)
321                 self.Bind(wx.EVT_MENU, self.on_tablex, id=self.pop2)
322                 self.Bind(wx.EVT_MENU, self.quest_var_mod, id=self.pop3)
323
324             menu = wx.Menu()
325             menu.Append(self.pop2, u"Chi2 par classe")
326             menu.Append(self.pop3, u"Chi2 modalités de la variable")
327             menu.AppendSeparator()
328             menu.Append(self.pop1, u"Graph de la classe")
329             self.PopupMenu(menu)
330             menu.Destroy()
331
332     def onexport(self, evt) :
333         if 'corpus' in dir(self.Source):
334             corpus = self.Source.corpus
335         ClasseCHD(self.parent, corpus, self.cl)
336
337     def quest_var_mod(self, evt) :
338         if 'corpus' in dir(self.Source):
339             corpus = self.Source.corpus
340             if self.var_mod == {} :
341                 self.var_mod = treat_var_mod([val for val in corpus.make_etoiles()])
342         else :
343             corpus = self.Source.tableau
344             if self.var_mod == {} :
345                 self.var_mod = treat_var_mod([val for val in corpus.actives] + [val for val in corpus.sups])
346         with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
347             chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
348         title = chistable[0]
349         title.pop(0)
350         chistable.pop(0)
351         vchistable = [line[1:] for line in chistable]
352         fchistable = [line[0] for line in chistable]
353         word = self.getColumnText(self.list.GetFirstSelected(), 6)
354         if len(word.split('_')) > 1 :
355             var = word.split('_')[0]
356             words = [word for word in self.var_mod[var]]
357             words.sort()
358             tableout = []
359             kwords = []
360             for word in words :
361                 if word in fchistable :
362                     tableout.append(vchistable[fchistable.index(word)])
363                     kwords.append(word)
364             tmpgraph = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
365             txt = barplot(tableout, kwords, title, self.Source.parent.RscriptsPath['Rgraph'], tmpgraph)
366             tmpscript = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
367             file = open(tmpscript,'w')
368             file.write(txt)
369             file.close()
370             exec_rcode(self.Source.parent.RPath, tmpscript, wait = True)
371             win = MessageImage(self, -1, u"Graphique", size=(700, 500),style = wx.DEFAULT_FRAME_STYLE)
372             win.addsaveimage(tmpgraph)
373             txt = "<img src='%s'>" % tmpgraph
374             win.HtmlPage.SetPage(txt)
375             win.Show(True)
376         else :
377             dial = wx.MessageDialog(self, u"Ce n'est pas une forme du type variable_modalité", u"Problème", wx.OK | wx.ICON_WARNING)
378             dial.CenterOnParent()
379             dial.ShowModal()
380             dial.Destroy()
381
382     def quest_simi(self, evt) :
383         tableau = self.Source.tableau
384         tab = tableau.make_table_from_classe(self.cl, self.la)
385         pathout = ConstructPathOut(self.Source.pathout+'/', 'simi_classe_%i' %self.cl)
386         self.filename = os.path.join(pathout,'mat01.csv')
387         tableau.printtable(self.filename, tab)
388         del tab
389         paramsimi = {'coeff' : 0,
390                           'layout' : 2,
391                           'type' : 1,
392                           'arbremax' : 1,
393                           'coeff_tv' : 1,
394                           'coeff_tv_nb' : 0,
395                           'tvprop' : 0,
396                           'tvmin' : 5,
397                           'tvmax' : 30,
398                           'coeff_te' : 1,
399                           'coeff_temin' : 1,
400                           'coeff_temax' : 10,
401                           'label_v': 1,
402                           'label_e': 1,
403                           'vcex' : 0,
404                           'vcexmin' : 10,
405                           'vcexmax' : 25,
406                           'cex' : 10,
407                           'cexfromchi' : True,
408                           'sfromchi': False,
409                           'seuil_ok' : 0,
410                           'seuil' : 1,
411                           'cols' : (255,0,0),
412                           'cola' : (200,200,200),
413                           'width' : 1000,
414                           'height' : 1000,
415                           'first' : True,
416                           'keep_coord' : True,
417                           'alpha' : 20,
418                           'film': False,
419                           }
420 #        self.tableau.actives = {}
421 #        self.tableau.lchi = self.lchi
422 #        self.tableau.chi = {}
423 #        for i, val in enumerate(self.la) :
424 #            self.tableau.actives[val] = [self.lfreq[i]]
425 #            self.tableau.chi[val] = [self.lchi[i]]
426                           
427         act = {}
428         self.tableau.chi = {}
429         self.tableau.lchi = self.lchi
430         self.tableau.parametre['fromprof'] = True
431         for i, val in enumerate(self.la) :
432             act[val] = [self.lfreq[i]]
433             self.tableau.chi[val] = [self.lchi[i]]
434         DoSimi(self, param = paramsimi, fromprof = ffr(self.filename), pathout = pathout, listactives = self.la, actives = act)
435
436     def onwordgraph(self, evt):
437         word = self.getColumnText(self.list.GetFirstSelected(), 6)
438         dlg = progressbar(self, 2)
439         corpus = self.Source.corpus
440         uces = corpus.lc[self.cl-1]
441         dlg.Update(1, u'Tableau...')
442         #tab = corpus.make_table_with_classe(uces, self.la)
443         pathout = ConstructPathOut(self.Source.pathout.dirout + '/' , 'simi_%s' % word)
444         self.filename = os.path.join(pathout,'mat01.csv')
445         dlg.Update(2, u'Ecriture...')
446         #corpus.write_tab(tab, self.filename)
447         #del tab
448         corpus.make_and_write_sparse_matrix_from_classe(self.la, uces, self.filename)
449         dlg.Destroy()
450         paramsimi = {'coeff' : 0,
451                           'layout' : 2,
452                           'type' : 1,
453                           'arbremax' : 0,
454                           'coeff_tv' : 1,
455                           'coeff_tv_nb' : 0,
456                           'tvprop' : 0,
457                           'tvmin' : 5,
458                           'tvmax' : 30,
459                           'coeff_te' : 1,
460                           'coeff_temin' : 1,
461                           'coeff_temax' : 10,
462                           'label_v': 1,
463                           'label_e': 0,
464                           'vcex' : 1,
465                           'vcexmin' : 10,
466                           'vcexmax' : 25, 
467                           'cex' : 10,
468                           'seuil_ok' : 1,
469                           'seuil' : 1,
470                           'cols' : (255,0,0),
471                           'cola' : (200,200,200),
472                           'width' : 600,
473                           'height' : 600,
474                           'first' : True,
475                           'keep_coord' : True,
476                           'alpha' : 20,
477                           'film': False,
478                           }
479         self.tableau = Tableau(self.parent, '')
480         self.tableau.listactives = self.la
481         self.tableau.actives = {}
482         for i, val in enumerate(self.la) :
483             self.tableau.actives[val] = [self.lfreq[i]]
484         DoSimi(self, param = paramsimi, fromprof = ffr(self.filename), pathout = pathout, wordgraph = word)
485
486
487     def OnPopupOne(self, event):
488         corpus = self.Source.corpus
489         #print 'ATTENTION PRINT ET TABLE'
490         #corpus.make_et_table()
491         word = self.getColumnText(self.list.GetFirstSelected(), 6)
492         lems = corpus.getlems()
493         uces = corpus.lc[self.cl-1]
494         rep = []
495         #FIXME : donner aussi eff reel a la place de nb uce
496         for forme in lems[word].formes :
497             ucef = list(set(corpus.getworduces(forme)).intersection(uces))
498             #ucef = [uce for uce in corpus.formes[forme][1] if uce in uces]
499             if ucef != [] :
500                 nb = len(ucef)
501                 rep.append([corpus.getforme(forme).forme, nb])
502         win = message(self, -1, u"Formes associées", size=(300, 200), style=wx.DEFAULT_FRAME_STYLE)
503         win.html = '<html>\n' + '<br>'.join([' : '.join([str(val) for val in forme]) for forme in rep]) + '\n</html>'
504         win.HtmlPage.SetPage(win.html)
505         win.Show(True)
506
507     def on_graph(self, evt):
508         dlg = progressbar(self, 2)
509         corpus = self.Source.corpus
510         uces = corpus.lc[self.cl-1]
511         dlg.Update(1, u'Tableau...')
512         #tab = corpus.make_table_with_classe(uces, self.la)
513         pathout = ConstructPathOut(self.Source.pathout.dirout+'/', 'simi_classe_%i' %self.cl)
514         self.filename = os.path.join(pathout,'mat01.csv')
515         dlg.Update(2, u'Ecriture...')
516         #corpus.write_tab(tab, self.filename)
517         #del tab
518         corpus.make_and_write_sparse_matrix_from_classe(self.la, uces, self.filename)
519         dlg.Destroy()
520         paramsimi = {'coeff' : 0,
521                           'layout' : 2,
522                           'type' : 1,
523                           'arbremax' : 1,
524                           'coeff_tv' : 1,
525                           'coeff_tv_nb' : 0,
526                           'tvprop' : 0,
527                           'tvmin' : 5,
528                           'tvmax' : 30,
529                           'coeff_te' : 1,
530                           'coeff_temin' : 1,
531                           'coeff_temax' : 10,
532                           'label_v': 1,
533                           'label_e': 0,
534                           'vcex' : 0,
535                           'vcexmin' : 10,
536                           'vcexmax' : 25,
537                           'cex' : 10,
538                           'cexfromchi' : True,
539                           'sfromchi': False,
540                           'seuil_ok' : 0,
541                           'seuil' : 1,
542                           'cols' : (255,0,0),
543                           'cola' : (200,200,200),
544                           'width' : 1000,
545                           'height' : 1000,
546                           'first' : True,
547                           'keep_coord' : True,
548                           'alpha' : 20,
549                           'film': False,
550                           }
551         self.tableau = Tableau(self.parent, '')
552         self.tableau.listactives = self.la
553         self.tableau.actives = {}
554         self.tableau.lchi = self.lchi
555         self.tableau.chi = {}
556         self.tableau.parametre['fromprof'] = True
557         for i, val in enumerate(self.la) :
558             self.tableau.actives[val] = [self.lfreq[i]]
559             self.tableau.chi[val] = [self.lchi[i]]
560         DoSimi(self, param = paramsimi, fromprof = ffr(self.filename), pathout = pathout)
561
562     def on_segments(self,evt) :
563         dlg = progressbar(self, 2)
564         corpus = self.Source.corpus
565         uces = corpus.lc[self.cl-1]
566         l = []
567         dlg.Update(1, u'Segments...')
568         for i in range(2,10) :
569             li = corpus.find_segments_in_classe(uces, i, 1000)
570             if li == [] :
571                 break
572             else :
573                 l += li
574         l.sort(reverse = True)
575         d = {}
576         dlg.Update(2, 'Tri...')
577         for i, line in enumerate(l) :
578             d[i] = [line[1],line[0], line[2]]
579         first = ['','','']
580         para={'dico': d,'fline':first}
581         dlg.Destroy()
582         win = wliste(self, -1, u"Segments répétés - Classe %i" % self.cl, d, first, size=(600, 500))
583         win.Show(True)
584
585     def on_uce_carac(self,evt) :
586         dial = PrefUCECarac(self, self.parent)
587         dial.CenterOnParent()
588         if dial.ShowModal() == wx.ID_OK :
589             limite = dial.spin_eff.GetValue()
590             atype = dial.radio_type.GetSelection()
591             dlg = progressbar(self,maxi = 4)
592             corpus = self.Source.corpus
593             uces = corpus.lc[self.cl-1]
594             tab = corpus.make_table_with_classe(uces, self.la)
595             tab.pop(0)
596             dlg.Update(2, u'score...')
597             if atype == 0 :
598                 ntab = [round(sum([self.lchi[i] for i, word in enumerate(line) if word == 1]),2) for line in tab]
599             else :
600                 ntab = [round(sum([self.lchi[i] for i, word in enumerate(line) if word == 1])/float(sum(line)),2) if sum(line)!=0 else 0 for line in tab]
601             ntab2 = [[ntab[i], uces[i]] for i, val in enumerate(ntab)]
602             del ntab
603             ntab2.sort(reverse = True)
604             ntab2 = ntab2[:limite]
605             nuces = [val[1] for val in ntab2]
606             dlg.Update(3, u'concordancier...')
607             #ucestxt = [corpus.ucis_paras_uces[val[1][0]][val[1][1]][val[1][2]] for val in ntab2]
608             ucestxt1 = [row for row in corpus.getconcorde(nuces)]
609             ucestxt = []
610             ucis_txt = []
611             for uce in ucestxt1 :
612                 ucetxt = ' '+uce[1]+' '
613                 ucis_txt.append(' '.join(corpus.ucis[corpus.getucefromid(uce[0]).uci].etoiles) + '<br>')
614                 for lem in self.la :
615                     listmot = corpus.getlems()[lem].formes
616                     for id in listmot :
617                         forme = corpus.getforme(id).forme
618                         ucetxt = ucetxt.replace(' '+forme+' ', '<font color=red> ' + forme + ' </font>')
619                 ucestxt.append(ucetxt)        
620             #ucestxt = [corpus.make_concord(self.la, ' '.join(uce), 'red') for uce in ucestxt]
621             dlg.Update(4, u'texte...')
622             #ucis_txt = [' '.join(corpus.ucis[val[1][0]][0]) for val in ntab2]
623             win = message(self, -1, u"UCE caractéristiques - Classe %i" % self.cl, size=(600, 500), style=wx.DEFAULT_FRAME_STYLE)
624             win.html = '<html>\n' + '<br><br>'.join(['<br>'.join([ucis_txt[i], 'score : ' + str(ntab2[i][0]), ucestxt[i]]) for i in range(0,len(ucestxt))]) + '\n</html>'
625             win.HtmlPage.SetPage(win.html)
626             dlg.Destroy()
627             win.Show(True)
628     
629     def on_tablex(self, evt):
630         if 'corpus' in dir(self.Source):
631             corpus = self.Source.corpus
632         else :
633             corpus = self.Source.tableau
634         with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
635             chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
636         title = chistable[0]
637         title.pop(0)
638         chistable.pop(0)
639         vchistable = [line[1:] for line in chistable]
640         fchistable = [line[0] for line in chistable]
641         words = [self.getColumnText(self.list.GetFirstSelected(), 6)]
642         tableout = [vchistable[fchistable.index(words[0])]]
643         last = self.list.GetFirstSelected()
644         while self.list.GetNextSelected(last) != -1:
645             last = self.list.GetNextSelected(last)
646             word = self.getColumnText(last, 6)
647             words.append(word)
648             tableout.append(vchistable[fchistable.index(word)])
649         tmpgraph = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
650         nbcl = len(title)
651         txt = barplot(tableout, words, title, self.Source.parent.RscriptsPath['Rgraph'], tmpgraph)
652         tmpscript = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
653         file = open(tmpscript,'w')
654         file.write(txt)
655         file.close()
656         
657         exec_rcode(self.Source.parent.RPath, tmpscript, wait = True)
658         win = MessageImage(self, -1, u"Graphique", size=(700, 500),style = wx.DEFAULT_FRAME_STYLE)
659         win.addsaveimage(tmpgraph)
660         txt = "<img src='%s'>" % tmpgraph
661         win.HtmlPage.SetPage(txt)
662         win.Show(True)
663
664     def onlexdendro(self, evt):
665         if 'corpus' in dir(self.Source):
666             corpus = self.Source.corpus
667         else :
668             corpus = self.Source.tableau
669         with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
670             chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
671         title = chistable[0]
672         title.pop(0)
673         chistable.pop(0)
674         vchistable = [line[1:] for line in chistable]
675         fchistable = [line[0] for line in chistable]
676         words = [self.getColumnText(self.list.GetFirstSelected(), 6)]
677         tableout = [vchistable[fchistable.index(words[0])]]
678         last = self.list.GetFirstSelected()
679         while self.list.GetNextSelected(last) != -1:
680             last = self.list.GetNextSelected(last)
681             word = self.getColumnText(last, 6)
682             words.append(word)
683             tableout.append(vchistable[fchistable.index(word)])
684         tmpgraph = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
685         txttable = 'c(' + ','.join([','.join(line) for line in tableout]) + ')'
686         rownames = 'c("' + '","'.join(words) + '")'
687         colnames = 'c("' + '","'.join(title) + '")'
688         nbcl = len(title)
689         rownb = len(words)
690         txt = """
691         load("%s")
692         di <- matrix(data=%s, nrow=%i, byrow = TRUE)
693         rownames(di)<- %s
694         colnames(di) <- %s
695         library(ape)
696         source("%s")
697         height <- (30*ncol(di)) + (15*nrow(di))
698         height <- ifelse(height <= 400, 400, height)
699         width <- 500
700         open_file_graph("%s", width=width, height=height)
701         plot.dendro.lex(tree.cut1$tree.cl, di)
702         """ % (self.Source.pathout['Rdendro'], txttable, rownb, rownames, colnames, self.Source.parent.RscriptsPath['Rgraph'], ffr(tmpgraph))
703         tmpscript = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
704         file = open(tmpscript,'w')
705         file.write(txt)
706         file.close()
707         exec_rcode(self.Source.parent.RPath, tmpscript, wait = True)
708         win = MessageImage(self, -1, u"Graphique", size=(700, 500),style = wx.DEFAULT_FRAME_STYLE)
709         win.addsaveimage(tmpgraph)
710         txt = "<img src='%s'>" % tmpgraph
711         win.HtmlPage.SetPage(txt)
712         win.Show(True)
713
714
715     def make_concord(self, uces, title, color = 'red') :
716         corpus = self.Source.corpus
717         ListWord = [self.getColumnText(self.list.GetFirstSelected(), 6)]
718         last = self.list.GetFirstSelected()
719         while self.list.GetNextSelected(last) != -1:
720             last = self.list.GetNextSelected(last)
721             ListWord.append(self.getColumnText(last, 6))
722         listmot = [forme for item in ListWord for forme in corpus.getlems()[item].formes]
723         win = message(self, -1, title, size=(600, 500), style=wx.DEFAULT_FRAME_STYLE)
724         toshow = ['<html>\n<H1>Concordancier</H1>\n']
725         toshow.append('<h3><font color=%s>' % color + ' '.join(ListWord) + '</font></h3><br>')
726         duce = {}
727         ucef = []
728         for word in ListWord : 
729             ucef += list(set(corpus.getlemuces(word)).intersection(uces))
730         ucef = list(set(ucef))
731         ucef.sort()
732         res = corpus.getconcorde(ucef)
733         txt = '<br>'.join(toshow) +'<br><br>'
734         for uce in res :
735             ucetxt = ' '+uce[1]+' '
736             txt += ' '.join(corpus.ucis[corpus.getucefromid(uce[0]).uci].etoiles) + '<br>'
737             for forme in listmot:
738                 forme = corpus.getforme(forme).forme
739                 ucetxt = ucetxt.replace(' '+forme+' ', '<font color=red> ' + forme + ' </font>')
740             txt += ucetxt + '<br><br>'
741         win.HtmlPage.SetPage(txt)
742         return win
743
744     def OnPopupTwo(self, event):
745         corpus = self.Source.corpus
746         uces = corpus.lc[self.cl-1]
747         win = self.make_concord(uces, "Concordancier - Classe %i" % self.cl)
748         win.Show(True)
749     
750     def OnPopupThree(self, event):
751         corpus = self.Source.corpus
752         uces = [classe[i] for classe in corpus.lc for i in range(0,len(classe))]
753         win = self.make_concord(uces, "Concordancier - UCE classées")
754         win.Show(True)
755         
756     def OnPopupFour(self, event):
757         corpus = self.Source.corpus
758         uces = [classe[i] for classe in corpus.lc for i in range(0,len(classe))] + corpus.lc0
759         win = self.make_concord(uces, "Concordancier - Toutes les UCE")
760         win.Show(True)
761
762     def OnPopupFive(self, event):
763         word = self.getColumnText(self.list.GetFirstSelected(), 6)
764         lk = "http://www.cnrtl.fr/definition/" + word
765         webbrowser.open(lk)
766
767     def OnPopupSix(self, event):  
768         word = self.getColumnText(self.list.GetFirstSelected(), 6)
769         lk = "http://www.cnrtl.fr/etymologie/" + word
770         webbrowser.open(lk)
771         
772     def OnPopupSeven(self, event):        
773         word = self.getColumnText(self.list.GetFirstSelected(), 6)
774         lk = "http://www.cnrtl.fr/synonymie/" + word
775         webbrowser.open(lk)
776         
777     def OnPopupHeight(self, event):  
778         word = self.getColumnText(self.list.GetFirstSelected(), 6)
779         lk = "http://www.cnrtl.fr/antonymie/" + word
780         webbrowser.open(lk)
781         
782     def OnPopupNine(self, event):            
783         word = self.getColumnText(self.list.GetFirstSelected(), 6)
784         lk = "http://www.cnrtl.fr/morphologie/" + word
785         webbrowser.open(lk)
786
787     def onproxe(self, evt) :
788         word = self.getColumnText(self.list.GetFirstSelected(), 6)
789         lk = "http://www.cnrtl.fr/proxemie/" + word
790         webbrowser.open(lk)
791
792     def OnSize(self, event):
793         w, h = self.GetClientSizeTuple()
794         self.list.SetDimensions(0, 0, w, h)
795         
796     def OnColClick(self, event):
797         self.do_greyline()
798
799
800 class wliste(wx.Frame):
801     def __init__(self, parent, id, title, d, fline, size=(600, 500)):
802         wx.Frame.__init__(self, parent, id)
803         self.liste = ListForSpec(self, parent, d, fline)
804         self.button_1 = wx.Button(self, -1, "Fermer")
805         self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.button_1)
806         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
807         self.__do_layout()
808
809     def __do_layout(self):
810         sizer_1 = wx.BoxSizer(wx.VERTICAL)
811         sizer_2 = wx.BoxSizer(wx.VERTICAL)
812         sizer_2.Add(self.liste, 1, wx.EXPAND | wx.ADJUST_MINSIZE, 0)
813         sizer_2.Add(self.button_1, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ADJUST_MINSIZE, 0)
814         sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
815         self.SetAutoLayout(True)
816         self.SetSizer(sizer_1)
817         self.Layout()
818         
819     def OnCloseMe(self, event):
820         self.Close(True)
821
822     def OnCloseWindow(self, event):
823         self.Destroy()
824
825 class message(wx.Frame):
826     def __init__(self, *args, **kwds):
827         kwds["style"] = wx.DEFAULT_FRAME_STYLE
828         wx.Frame.__init__(self, *args, **kwds)
829         self.html = ""
830         self.HtmlPage=wx.html.HtmlWindow(self, -1)
831         if "gtk2" in wx.PlatformInfo:
832             self.HtmlPage.SetStandardFonts()
833         self.HtmlPage.SetFonts('Courier','Courier')
834         self.button_1 = wx.Button(self, -1, "Fermer")
835         self.button_2 = wx.Button(self, -1, u"Enregistrer...")
836
837         self.Bind(wx.EVT_BUTTON, self.OnSavePage, self.button_2)
838         self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.button_1)
839         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
840         self.__do_layout()
841
842     def __do_layout(self):
843         sizer_1 = wx.BoxSizer(wx.VERTICAL)
844         sizer_2 = wx.BoxSizer(wx.VERTICAL)
845         sizer_2.Add(self.HtmlPage, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
846         sizer_2.Add(self.button_1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
847         sizer_2.Add(self.button_2, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
848         sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
849         self.SetAutoLayout(True)
850         self.SetSizer(sizer_1)
851         self.Layout()
852
853     def OnSavePage(self, evt) :
854         dlg = wx.FileDialog(
855             self, message="Enregistrer sous...", defaultDir=os.getcwd(),
856             defaultFile="concordancier.html", wildcard="html|*.html", style=wx.SAVE | wx.OVERWRITE_PROMPT
857             )
858         dlg.SetFilterIndex(2)
859         dlg.CenterOnParent()
860         if dlg.ShowModal() == wx.ID_OK:
861             path = dlg.GetPath()
862             with open(path, 'w') as f :
863                 f.write(self.html)
864
865     def OnCloseMe(self, event):
866         self.Close(True)
867
868     def OnCloseWindow(self, event):
869         self.Destroy()
870
871 def getSmallUpArrowData():
872     return \
873 '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
874 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
875 \x00\x00<IDAT8\x8dcddbf\xa0\x040Q\xa4{h\x18\xf0\xff\xdf\xdf\xffd\x1b\x00\xd3\
876 \x8c\xcf\x10\x9c\x06\xa0k\xc2e\x08m\xc2\x00\x97m\xd8\xc41\x0c \x14h\xe8\xf2\
877 \x8c\xa3)q\x10\x18\x00\x00R\xd8#\xec\xb2\xcd\xc1Y\x00\x00\x00\x00IEND\xaeB`\
878 \x82' 
879
880 def getSmallUpArrowBitmap():
881     return wx.BitmapFromImage(getSmallUpArrowImage())
882
883 def getSmallUpArrowImage():
884     stream = cStringIO.StringIO(getSmallUpArrowData())
885     return wx.ImageFromStream(stream)
886
887 #----------------------------------------------------------------------
888 def getSmallDnArrowData():
889     return \
890 "\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
891 \x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
892 \x00\x00HIDAT8\x8dcddbf\xa0\x040Q\xa4{\xd4\x00\x06\x06\x06\x06\x06\x16t\x81\
893 \xff\xff\xfe\xfe'\xa4\x89\x91\x89\x99\x11\xa7\x0b\x90%\ti\xc6j\x00>C\xb0\x89\
894 \xd3.\x10\xd1m\xc3\xe5*\xbc.\x80i\xc2\x17.\x8c\xa3y\x81\x01\x00\xa1\x0e\x04e\
895 ?\x84B\xef\x00\x00\x00\x00IEND\xaeB`\x82" 
896
897 def getSmallDnArrowBitmap():
898     return wx.BitmapFromImage(getSmallDnArrowImage())
899
900 def getSmallDnArrowImage():
901     stream = cStringIO.StringIO(getSmallDnArrowData())
902     return wx.ImageFromStream(stream)