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