...
[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, message
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, doconcorde
31 from PrintRScript import barplot
32 from textclassechd import ClasseCHD
33 from shutil import copyfile
34 from operator import itemgetter
35
36 #---------------------------------------------------------------------------
37 class ProfListctrlPanel(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.ColumnSorterMixin):
38     def __init__(self, parent, gparent, profclasse, Alceste=False, cl=0):
39         wx.ListCtrl.__init__( self, parent, -1, style=wx.LC_REPORT|wx.LC_VIRTUAL|wx.LC_HRULES|wx.LC_VRULES)
40
41         self.parent = parent
42         self.Alceste = Alceste
43         self.Source = gparent
44         self.cl = cl
45         self.var_mod = {}
46
47         line1 = profclasse.pop(0)
48         classen = [line for line in profclasse if line[0] != '*' and line[0] != '*****']
49         try :
50             self.lenact = profclasse.index([u'*****', u'*', u'*', u'*', u'*', u'*', '', ''])
51             profclasse.pop(self.lenact)
52         except ValueError:
53             try :
54                 self.lenact = profclasse.index([u'*', u'*', u'*', u'*', u'*', u'*', '', ''])
55                 profclasse.pop(self.lenact)
56             except ValueError:
57                 self.lenact = len(profclasse)
58         try :
59             self.lensup = profclasse.index([u'*', u'*', u'*', u'*', u'*', u'*', '', ''])
60             self.lensup = self.lensup - self.lenact
61             profclasse.pop(self.lensup)
62         except ValueError: 
63             self.lensup = len(profclasse) - self.lenact
64         self.lenet = len(profclasse) - (self.lenact + self.lensup)
65 #        print self.lenact, self.lensup, self.lenet
66         for i,  line in enumerate(classen) :
67             line[0] = i
68         dictdata = dict(zip([i for i in range(0,len(classen))], classen))
69
70         if self.lenact != 0 :
71             self.la = [dictdata[i][6] for i in range(0, self.lenact)]
72             self.lchi = [dictdata[i][4] for i in range(0, self.lenact)]
73             self.lfreq = [dictdata[i][1] for i in range(0, self.lenact)]
74         else :
75             self.la = []
76             self.lchi = []
77             self.lfreq = []
78         self.tmpchi = None
79             
80         #adding some art
81         self.il = wx.ImageList(16, 16)
82         a={"sm_up":"GO_UP","sm_dn":"GO_DOWN","w_idx":"WARNING","e_idx":"ERROR","i_idx":"QUESTION"}
83         for k,v in a.items():
84             s="self.%s= self.il.Add(wx.ArtProvider_GetBitmap(wx.ART_%s,wx.ART_TOOLBAR,(16,16)))" % (k,v)
85             exec(s)
86         self.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
87
88         #adding some attributes (colourful background for each item rows)
89         self.attr1 = wx.ListItemAttr()
90         self.attr1.SetBackgroundColour((220, 220, 220))
91         self.attrsg = wx.ListItemAttr()
92         self.attrsg.SetBackgroundColour((230, 230, 230))
93         self.attr2 = wx.ListItemAttr()
94         self.attr2.SetBackgroundColour((190, 249, 236))
95         self.attr2s = wx.ListItemAttr()
96         self.attr2s.SetBackgroundColour((211, 252, 244))        
97         self.attr3 = wx.ListItemAttr()
98         self.attr3.SetBackgroundColour((245, 180, 180))
99         self.attr3s = wx.ListItemAttr()
100         self.attr3s.SetBackgroundColour((245, 190, 190))
101
102
103         self.InsertColumn(0, "num", wx.LIST_FORMAT_RIGHT)
104         self.InsertColumn(1, "eff. s.t.", wx.LIST_FORMAT_RIGHT)
105         self.InsertColumn(2, "eff. total", wx.LIST_FORMAT_RIGHT)
106         self.InsertColumn(3, "pourcentage", wx.LIST_FORMAT_RIGHT)
107         self.InsertColumn(4, "chi2", wx.LIST_FORMAT_RIGHT)
108         self.InsertColumn(5, "Type", wx.LIST_FORMAT_RIGHT)
109         self.InsertColumn(6, "forme", wx.LIST_FORMAT_RIGHT)
110         self.InsertColumn(7, "p", wx.LIST_FORMAT_RIGHT)
111         
112
113         self.SetColumnWidth(0, 60)
114         self.SetColumnWidth(1, 70)
115         self.SetColumnWidth(2, 80)
116         self.SetColumnWidth(3, 100)
117         self.SetColumnWidth(4, 70)
118         self.SetColumnWidth(5, 60)
119         self.SetColumnWidth(6, 140)
120         self.SetColumnWidth(7, wx.LIST_AUTOSIZE)
121
122         #These two should probably be passed to init more cleanly
123         #setting the numbers of items = number of elements in the dictionary
124         self.itemDataMap = dictdata
125         self.itemIndexMap = dictdata.keys()
126         self.SetItemCount(len(dictdata))
127         
128         #mixins
129         listmix.ListCtrlAutoWidthMixin.__init__(self)
130         listmix.ColumnSorterMixin.__init__(self, len(classen[0]))
131
132         #sort by genre (column 2), A->Z ascending order (1)
133         self.SortListItems(0, 1)
134
135         #events
136         #self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected)
137         #self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
138         #self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.OnItemDeselected)
139         self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick)
140
141         # for wxMSW
142         self.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
143
144         # for wxGTK
145         self.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
146
147         #for searching
148         search_id = wx.NewId()
149         searchall_id = wx.NewId()
150         self.parent.Bind(wx.EVT_MENU, self.onsearch, id = search_id)
151         self.parent.Bind(wx.EVT_MENU, self.onsearchall, id = searchall_id)
152         self.accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('F'), search_id),
153                                               (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('F'), searchall_id)])
154         self.SetAcceleratorTable(self.accel_tbl)
155
156
157
158     def OnColClick(self,event):
159         event.Skip()
160
161     def OnItemSelected(self, event):
162         self.currentItem = event.m_itemIndex
163
164     def OnItemActivated(self, event):
165         self.currentItem = event.m_itemIndex
166
167     def getColumnText(self, index, col):
168         item = self.GetItem(index, col)
169         return item.GetText()
170
171     def OnItemDeselected(self, evt):
172         pass
173     #---------------------------------------------------
174     # These methods are callbacks for implementing the
175     # "virtualness" of the list...
176
177     def OnGetItemText(self, item, col):
178         index=self.itemIndexMap[item]
179         s = self.itemDataMap[index][col]
180         return s
181
182     def OnGetItemImage(self, item):
183         index=self.itemIndexMap[item]
184         genre=self.itemDataMap[index][2]
185
186         if genre=="Rock":
187             return self.w_idx
188         elif genre=="Jazz":
189             return self.e_idx
190         elif genre=="New Age":
191             return self.i_idx
192         else:
193             return -1
194
195     def OnGetItemAttr(self, item):
196         index=self.itemIndexMap[item]
197         if index < self.lenact :
198             if item % 2 :
199                 return self.attr1
200             else :
201                 return self.attrsg
202         elif index >= self.lenact and index < (self.lenact + self.lensup) :
203             if item % 2 :
204                 return self.attr2
205             else :
206                 return self.attr2s
207         elif index >= (self.lenact + self.lensup) :
208             if item % 2 :
209                 return self.attr3
210             else :
211                 return self.attr3s
212         else :
213             return None
214
215     #---------------------------------------------------
216     # Matt C, 2006/02/22
217     # Here's a better SortItems() method --
218     # the ColumnSorterMixin.__ColumnSorter() method already handles the ascending/descending,
219     # and it knows to sort on another column if the chosen columns have the same value.
220
221     def SortItems(self,sorter=cmp):
222         items = list(self.itemDataMap.keys())
223         items.sort(sorter)
224         self.itemIndexMap = items
225         
226         # redraw the list
227         self.Refresh()
228
229     # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
230     def GetListCtrl(self):
231         return self
232
233     # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
234     def GetSortImages(self):
235         return (self.sm_dn, self.sm_up)
236
237     def onsearch(self, evt) :
238         self.dial = SearchDial(self, self, 6, True)
239         self.dial.CenterOnParent()
240         self.dial.Show()
241         #self.dial.Destroy()
242
243     def onsearchall(self, evt) :
244         if 'FrameSearch' not in dir(self.Source) :
245             self.Source.FrameSearch = SearchFrame(self.parent, -1, u"Rechercher...", self.Source.corpus)
246         self.dial = SearchDial(self, self.Source.FrameSearch.liste, 1, False)
247         self.dial.CenterOnParent()
248         self.dial.Show()
249         #self.dial.Destroy()
250
251     def OnRightClick(self, event):
252
253         # only do this part the first time so the events are only bound once
254         if self.Alceste:
255             if not hasattr(self, "popupID1"):
256                 self.popupID1 = wx.NewId()
257                 self.popupID2 = wx.NewId()
258                 self.popupID3 = wx.NewId()
259                 self.popupID4 = wx.NewId()
260                 self.popupID5 = wx.NewId()
261                 self.popupID6 = wx.NewId()
262                 self.popupID7 = wx.NewId()
263                 self.popupID8 = wx.NewId()
264                 self.popupID9 = wx.NewId()
265                 #self.popupID10 = wx.NewId()
266                 self.popupIDgraph = wx.NewId()
267                 self.idseg = wx.NewId()
268                 self.iducecarac = wx.NewId()
269                 self.idtablex = wx.NewId()
270                 self.idchimod = wx.NewId()
271                 self.idwordgraph = wx.NewId()
272                 self.popup_proxe = wx.NewId()
273                 self.idlexdendro = wx.NewId()
274                 self.idcloud = wx.NewId()
275                 self.idexport = wx.NewId()
276             #    self.export_classes = wx.NewId()
277    
278                 self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
279                 self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
280                 self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
281                 self.Bind(wx.EVT_MENU, self.OnPopupFour, id=self.popupID4)
282                 self.Bind(wx.EVT_MENU, self.OnPopupFive, id=self.popupID5)
283                 self.Bind(wx.EVT_MENU, self.OnPopupSix, id=self.popupID6)
284                 self.Bind(wx.EVT_MENU, self.OnPopupSeven, id=self.popupID7)
285                 self.Bind(wx.EVT_MENU, self.OnPopupHeight, id=self.popupID8)
286                 self.Bind(wx.EVT_MENU, self.OnPopupNine, id=self.popupID9)
287                 #self.Bind(wx.EVT_MENU, self.OnPopupSpec, id=self.popupID10)
288                 self.Bind(wx.EVT_MENU, self.on_graph, id=self.popupIDgraph)
289                 self.Bind(wx.EVT_MENU, self.on_segments, id=self.idseg)
290                 self.Bind(wx.EVT_MENU, self.on_uce_carac, id = self.iducecarac)
291                 self.Bind(wx.EVT_MENU, self.on_tablex, id = self.idtablex)
292                 self.Bind(wx.EVT_MENU, self.quest_var_mod, id = self.idchimod)
293                 self.Bind(wx.EVT_MENU, self.onwordgraph, id = self.idwordgraph)
294                 self.Bind(wx.EVT_MENU, self.onproxe, id = self.popup_proxe)
295                 self.Bind(wx.EVT_MENU, self.onlexdendro, id = self.idlexdendro)
296                 self.Bind(wx.EVT_MENU, self.oncloud, id = self.idcloud)
297                 self.Bind(wx.EVT_MENU, self.onexport, id = self.idexport)
298              #  self.Bind(wx.EVT_MENU, self.on_export_classes, id = self.export_classes)
299    #            self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
300     
301             # make a menu
302             menu = wx.Menu()
303             menu.Append(self.popupID1, u"Formes associées")
304             menu.Append(self.idtablex, u"Chi2 par classe")
305             menu.Append(self.idlexdendro, u"Chi2 par classe + dendro")
306             menu.Append(self.idchimod, u"Chi2 modalités de la variable")
307             menu.Append(self.idwordgraph, u"Graphe du mot")
308             #menu.Append(self.export_classes, u"Exporter le corpus...") 
309             
310             #menu.Append(self.popupID10, u"Spécificités")
311
312             menu_conc = wx.Menu()
313             menu_conc.Append(self.popupID2, u"dans les segments de texte de la classe")
314             menu_conc.Append(self.popupID3, u"dans les segments de texte classés")
315             menu_conc.Append(self.popupID4, u"dans tous les segments de texte")
316             menu.AppendMenu(-1, u"Concordancier", menu_conc) 
317             menu_cnrtl = wx.Menu()      
318             menu_cnrtl.Append(self.popupID5, u"Définition")
319             menu_cnrtl.Append(self.popupID6, u"Etymologie")
320             menu_cnrtl.Append(self.popupID7, u"Synonymie")
321             menu_cnrtl.Append(self.popupID8, u"Antonymie")
322             menu_cnrtl.Append(self.popupID9, u"Morphologie")
323             menu_cnrtl.Append(self.popup_proxe, u"Proxémie")
324             menu.AppendMenu(-1, u"Outils du CNRTL", menu_cnrtl)
325             menu.AppendSeparator()
326             menu.Append(self.popupIDgraph, u"Graphe de la classe")
327             menu.Append(self.idseg, u"Segments répétés")
328             menu.Append(self.iducecarac, u"Segments de texte caractéristiques")
329             menu.Append(self.idcloud, u"Nuage de la classe")
330             menu.Append(self.idexport, u'Exporter...')
331             #menu.Append(self.popupID2, u"Concordancier")
332     #        menu.Append(self.popupID3, "recharger")
333     
334             self.PopupMenu(menu)
335             menu.Destroy()
336         elif 'tableau' in dir(self.Source) :
337             if not hasattr(self, "pop1"):
338                 self.pop1 = wx.NewId()
339                 self.pop2 = wx.NewId()
340                 self.pop3 = wx.NewId()
341                 self.Bind(wx.EVT_MENU, self.quest_simi, id=self.pop1)
342                 self.Bind(wx.EVT_MENU, self.on_tablex, id=self.pop2)
343                 self.Bind(wx.EVT_MENU, self.quest_var_mod, id=self.pop3)
344
345             menu = wx.Menu()
346             menu.Append(self.pop2, u"Chi2 par classe")
347             menu.Append(self.pop3, u"Chi2 modalités de la variable")
348             menu.AppendSeparator()
349             menu.Append(self.pop1, u"Graph de la classe")
350             self.PopupMenu(menu)
351             menu.Destroy()
352
353     def oncloud(self, evt) :
354         if 'corpus' in dir(self.Source):
355             corpus = self.Source.corpus
356         prof = [[self.la[i], self.lchi[i], self.lfreq[i]] for i, val in enumerate(self.la)]
357         parametres = self.Source.parametres
358         parametres['clusterprof'] = prof
359         parametres['type'] = 'clustercloud'
360         parametres['prof'] = self.Source.pathout['actprof_classe_%i.csv' % self.cl]
361         del  parametres['uuid']
362         #if not os.path.exists(self.Source.pathout['actprof_classe_%i.csv' % self.lc]) :
363         #    with open(self.Source.pathout['actprof_classe_%i.csv' % self.lc], 'w') as f :
364         #        f.write('\n'.join(prof).encode(self.parent.syscoding))
365         self.parent.OnClusterCloud(self.Source.corpus, parametres = parametres)
366
367     def onexport(self, evt) :
368         if 'corpus' in dir(self.Source):
369             corpus = self.Source.corpus
370         corpus.export_classe(self.Source.pathout['classe_%i_export.txt' % self.cl], self.cl)
371         dial = wx.MessageDialog(self, self.Source.pathout['classe_%i_export.txt' % self.cl], u"Export", wx.OK|wx.ICON_INFORMATION)
372         dial.ShowModal()
373         dial.Destroy()
374         #if 'corpus' in dir(self.Source):
375         #    corpus = self.Source.corpus
376         #ClasseCHD(self.parent, corpus, self.cl)
377
378     def getselectedwords(self) :
379         words = [self.getColumnText(self.GetFirstSelected(), 6)]
380         last = self.GetFirstSelected()
381         while self.GetNextSelected(last) != -1:
382             last = self.GetNextSelected(last)
383             words.append(self.getColumnText(last, 6))
384         return words
385
386     def quest_var_mod(self, evt) :
387         if 'corpus' in dir(self.Source):
388             corpus = self.Source.corpus
389             if self.var_mod == {} :
390                 self.var_mod = self.Source.corpus.make_etoiles_dict()
391         else :
392             corpus = self.Source.tableau
393             if self.var_mod == {} :
394                 self.var_mod = treat_var_mod([val for val in corpus.actives] + [val for val in corpus.sups])
395         with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
396             chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
397         title = chistable[0]
398         title.pop(0)
399         chistable.pop(0)
400         vchistable = [line[1:] for line in chistable]
401         fchistable = [line[0] for line in chistable]
402         word = self.getselectedwords()[0]
403         if len(word.split('_')) > 1 :
404             var = word.split('_')
405             #words = ['_'.join([var[0],word]) for word in self.var_mod[var[0]]]
406             words = [word for word in self.var_mod[var[0]]]
407             words.sort()
408             tableout = []
409             kwords = []
410             for word in words :
411                 if word in fchistable :
412                     tableout.append(vchistable[fchistable.index(word)])
413                     kwords.append(word)
414             tmpgraph = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
415             txt = barplot(tableout, kwords, title, self.Source.parent.RscriptsPath['Rgraph'], tmpgraph)
416             tmpscript = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
417             file = open(tmpscript,'w')
418             file.write(txt)
419             file.close()
420             exec_rcode(self.Source.parent.RPath, tmpscript, wait = True)
421             win = MessageImage(self,u"Graphique", size=(700, 500))
422             win.addsaveimage(tmpgraph)
423             txt = "<img src='%s'>" % tmpgraph
424             win.HtmlPage.SetPage(txt)
425             win.Show(True)
426         else :
427             dial = wx.MessageDialog(self, u"Ce n'est pas une forme du type variable_modalité", u"Problème", wx.OK | wx.ICON_WARNING)
428             dial.CenterOnParent()
429             dial.ShowModal()
430             dial.Destroy()
431
432     def quest_simi(self, evt) :
433         tableau = self.Source.tableau
434         if self.tmpchi is None :
435             self.tmpchi = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
436             with open(self.tmpchi, 'w') as f:
437                 f.write('\n'.join([str(val) for val in self.lchi]))
438         tab = tableau.make_table_from_classe(self.cl, self.la)
439         pathout = ConstructPathOut(self.Source.pathout.dirout, 'simi_classe_%i' %self.cl)
440         self.filename = os.path.join(pathout,'mat01.csv')
441         tableau.printtable(self.filename, tab)
442         del tab
443         paramsimi = {'coeff' : 0,
444                           'layout' : 2,
445                           'type_graph' : 1,
446                           'arbremax' : 1,
447                           'coeff_tv' : 1,
448                           'coeff_tv_nb' : 0,
449                           'tvprop' : 0,
450                           'tvmin' : 5,
451                           'tvmax' : 30,
452                           'coeff_te' : 1,
453                           'coeff_temin' : 1,
454                           'coeff_temax' : 10,
455                           'label_v': 1,
456                           'label_e': 1,
457                           'vcex' : 0,
458                           'vcexmin' : 10,
459                           'vcexmax' : 25,
460                           'cex' : 10,
461                           'cexfromchi' : True,
462                           'sfromchi': False,
463                           'seuil_ok' : 0,
464                           'seuil' : 1,
465                           'cols' : (255,0,0),
466                           'cola' : (200,200,200),
467                           'width' : 1000,
468                           'height' : 1000,
469                           'first' : True,
470                           'keep_coord' : True,
471                           'alpha' : 20,
472                           'film': False,
473                           'com' : 0,
474                           'communities' : 0,
475                           'halo' : 0,
476                           'tmpchi': self.tmpchi
477                           }
478         act = {}
479         tableau.chi = {}
480         tableau.lchi = self.lchi
481         tableau.parametre['fromprof'] = True
482         for i, val in enumerate(self.la) :
483             act[val] = [self.lfreq[i]]
484             tableau.chi[val] = [self.lchi[i]]
485         self.parent.SimiCluster(parametres = paramsimi, fromprof = ffr(self.filename), pathout = pathout, listactives = self.la, actives = act, tableau = tableau)
486
487     def onwordgraph(self, evt):
488         word = self.getColumnText(self.GetFirstSelected(), 6)
489         if self.tmpchi is None :
490             self.tmpchi = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
491             with open(self.tmpchi, 'w') as f:
492                 f.write('\n'.join([str(val) for val in self.lchi]))
493         index = self.la.index(word)
494         parametres = {'type' : 'clustersimitxt', 
495                         'pathout' : self.Source.parametres['pathout'],
496                         'word' : index ,
497                         'lem' : self.Source.parametres['lem'],
498                         'tmpchi' : self.tmpchi}
499         #try :
500         self.parent.SimiFromCluster(self.parent, self.Source.corpus, self.la, self.lfreq, self.lchi, self.cl - 1, parametres = parametres, dlg = progressbar(self, 4))
501         #except :
502         #    print 'not acitve'
503
504     def on_graph(self, evt):
505         if self.tmpchi is None :
506             self.tmpchi = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
507             with open(self.tmpchi, 'w') as f:
508                 f.write('\n'.join([str(val) for val in self.lchi]))
509         parametres = {'type' : 'clustersimitxt', 
510                         'pathout' : self.Source.parametres['pathout'],
511                         'lem' : self.Source.parametres['lem'],
512                         'tmpchi' : self.tmpchi}
513
514         self.parent.SimiFromCluster(self.parent, self.Source.corpus, self.la, self.lfreq, self.lchi, self.cl - 1, parametres = parametres, dlg = progressbar(self, 4))
515
516     def on_segments(self,evt) :
517         dlg = progressbar(self, 2)
518         corpus = self.Source.corpus
519         uces = corpus.lc[self.cl-1]
520         l = []
521         dlg.Update(1, u'Segments...')
522         for i in range(2,10) :
523             li = corpus.find_segments_in_classe(uces, i, 1000)
524             if li == [] :
525                 break
526             else :
527                 l += li
528         l.sort(reverse = True)
529         d = {}
530         dlg.Update(2, 'Tri...')
531         for i, line in enumerate(l) :
532             d[i] = [line[1],line[0], line[2]]
533         first = ['','','']
534         para={'dico': d,'fline':first}
535         dlg.Destroy()
536         win = wliste(self, -1, u"Segments répétés - Classe %i" % self.cl, d, first, size=(600, 500))
537         win.Show(True)
538
539     def on_uce_carac(self,evt) :
540         dial = PrefUCECarac(self, self.parent)
541         dial.CenterOnParent()
542         if dial.ShowModal() == wx.ID_OK :
543             limite = dial.spin_eff.GetValue()
544             atype = dial.radio_type.GetSelection()
545             dlg = progressbar(self,maxi = 4)
546             corpus = self.Source.corpus
547             uces = corpus.lc[self.cl-1]
548             tab = corpus.make_table_with_classe(uces, self.la)
549             tab.pop(0)
550             dlg.Update(2, u'score...')
551             if atype == 0 :
552                 ntab = [round(sum([self.lchi[i] for i, word in enumerate(line) if word == 1]),2) for line in tab]
553             else :
554                 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]
555             ntab2 = [[ntab[i], uces[i]] for i, val in enumerate(ntab)]
556             del ntab
557             ntab2.sort(reverse = True)
558             ntab2 = ntab2[:limite]
559             nuces = [val[1] for val in ntab2]
560             dlg.Update(3, u'concordancier...')
561             ucis_txt, ucestxt = doconcorde(corpus, nuces, self.la)
562             dlg.Update(4, u'texte...')
563             win = message(self, u"Segments de texte caractéristiques - Classe %i" % self.cl, (750, 600))
564             win.html = '<html>\n' + '<br>'.join(['<br>'.join([ucis_txt[i], '<table bgcolor = #1BF0F7 border=0><tr><td><b>score : %.2f</b></td></tr></table>' % ntab2[i][0], ucestxt[i]]) for i in range(0,len(ucestxt))]) + '\n</html>'
565             win.HtmlPage.SetPage(win.html)
566             dlg.Destroy()
567             win.Show(True)
568     
569     def on_tablex(self, evt):
570         if 'corpus' in dir(self.Source):
571             corpus = self.Source.corpus
572         else :
573             corpus = self.Source.tableau
574         with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
575             chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
576         title = chistable[0]
577         title.pop(0)
578         chistable.pop(0)
579         vchistable = [line[1:] for line in chistable]
580         fchistable = [line[0] for line in chistable]
581         words = self.getselectedwords()
582         tableout = [vchistable[fchistable.index(word)] for word in words]
583         tmpgraph = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
584         nbcl = len(title)
585         nbwords = len(words)
586         txt = barplot(tableout, words, title, self.Source.parent.RscriptsPath['Rgraph'], tmpgraph)
587         #print 'ATTENTION TEST R'
588         #txt = """
589         #sink('/Users/pierre/Desktop/qdfqsdfqsdfqsdf.txt')
590         #Sys.getlocale()
591         #sink()
592         #"""
593         tmpscript = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
594         file = open(tmpscript,'w')
595         file.write(txt)
596         file.close()
597         exec_rcode(self.Source.parent.RPath, tmpscript, wait = True)
598         w = 100 + (20 * nbwords) + (100 * nbcl)
599         h = 100 + (nbwords * 15)
600         if w > 1100 : w = 1100
601         if h > 800 : h = 800
602         if h < 450 : h = 450
603         win = MessageImage(self, u"Graphique", size=(w, h))
604         win.addsaveimage(tmpgraph)
605         txt = "<img src='%s'>" % tmpgraph
606         win.HtmlPage.SetPage(txt)
607         win.Show(True)
608
609     def onlexdendro(self, evt):
610         if 'corpus' in dir(self.Source):
611             corpus = self.Source.corpus
612         else :
613             corpus = self.Source.tableau
614         with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
615             chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
616         title = chistable[0]
617         title.pop(0)
618         chistable.pop(0)
619         vchistable = [line[1:] for line in chistable]
620         fchistable = [line[0] for line in chistable]
621         words = self.getselectedwords()
622         tableout = [vchistable[fchistable.index(word)] for word in words]
623         tmpgraph = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
624         txttable = 'c(' + ','.join([','.join(line) for line in tableout]) + ')'
625         rownames = 'c("' + '","'.join(words) + '")'
626         colnames = 'c("' + '","'.join(title) + '")'
627         nbcl = len(title)
628         rownb = len(words)
629         txt = """
630         load("%s")
631         di <- matrix(data=%s, nrow=%i, byrow = TRUE)
632         rownames(di)<- %s
633         colnames(di) <- %s
634         library(ape)
635         source("%s")
636         height <- (30*ncol(di)) + (15*nrow(di))
637         height <- ifelse(height <= 400, 400, height)
638         width <- 500
639         open_file_graph("%s", width=width, height=height)
640         plot.dendro.lex(tree.cut1$tree.cl, di)
641         """ % (self.Source.pathout['Rdendro'], txttable, rownb, rownames, colnames, self.Source.parent.RscriptsPath['Rgraph'], ffr(tmpgraph))
642         tmpscript = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
643         file = open(tmpscript,'w')
644         file.write(txt)
645         file.close()
646         exec_rcode(self.Source.parent.RPath, tmpscript, wait = True)
647         win = MessageImage(self, u"Graphique", size=(700, 500))
648         win.addsaveimage(tmpgraph)
649         txt = "<img src='%s'>" % tmpgraph
650         win.HtmlPage.SetPage(txt)
651         win.Show(True)
652
653
654     def make_concord(self, uces, title, color = 'red') :
655         corpus = self.Source.corpus
656         ListWord = [self.getColumnText(self.GetFirstSelected(), 6)]
657         last = self.GetFirstSelected()
658         while self.GetNextSelected(last) != -1:
659             last = self.GetNextSelected(last)
660             ListWord.append(self.getColumnText(last, 6))
661         ucef = []
662         for word in ListWord : 
663             ucef += list(set(corpus.getlemuces(word)).intersection(uces))
664         ucis_txt, ucestxt = doconcorde(corpus, ucef, ListWord)
665         win = message(self, title, size=(750, 600))
666         win.html = ('<html>\n<h1>%s</h1>' % ' '.join(ListWord)) + '<br>'.join(['<br>'.join([ucis_txt[i], ucestxt[i]]) for i in range(0,len(ucestxt))]) + '\n</html>'
667         win.HtmlPage.SetPage(win.html)
668         return win
669
670     def OnPopupTwo(self, event):
671         corpus = self.Source.corpus
672         uces = corpus.lc[self.cl-1]
673         win = self.make_concord(uces, "Concordancier - Classe %i" % self.cl)
674         win.Show(True)
675     
676     def OnPopupThree(self, event):
677         corpus = self.Source.corpus
678         uces = [classe[i] for classe in corpus.lc for i in range(0,len(classe))]
679         win = self.make_concord(uces, "Concordancier - UCE classées")
680         win.Show(True)
681         
682     def OnPopupFour(self, event):
683         corpus = self.Source.corpus
684         uces = [classe[i] for classe in corpus.lc for i in range(0,len(classe))] + corpus.lc0
685         win = self.make_concord(uces, "Concordancier - Toutes les UCE")
686         win.Show(True)
687
688     def OnPopupFive(self, event):
689         word = self.getColumnText(self.GetFirstSelected(), 6)
690         lk = "http://www.cnrtl.fr/definition/" + word
691         webbrowser.open(lk)
692
693     def OnPopupSix(self, event):  
694         word = self.getColumnText(self.GetFirstSelected(), 6)
695         lk = "http://www.cnrtl.fr/etymologie/" + word
696         webbrowser.open(lk)
697         
698     def OnPopupSeven(self, event):        
699         word = self.getColumnText(self.GetFirstSelected(), 6)
700         lk = "http://www.cnrtl.fr/synonymie/" + word
701         webbrowser.open(lk)
702         
703     def OnPopupHeight(self, event):  
704         word = self.getColumnText(self.GetFirstSelected(), 6)
705         lk = "http://www.cnrtl.fr/antonymie/" + word
706         webbrowser.open(lk)
707         
708     def OnPopupNine(self, event):            
709         word = self.getColumnText(self.GetFirstSelected(), 6)
710         lk = "http://www.cnrtl.fr/morphologie/" + word
711         webbrowser.open(lk)
712
713     def onproxe(self, evt) :
714         word = self.getColumnText(self.GetFirstSelected(), 6)
715         lk = "http://www.cnrtl.fr/proxemie/" + word
716         webbrowser.open(lk)
717
718     def OnPopupOne(self, event):
719         corpus = self.Source.corpus
720         #print 'ATTENTION PRINT ET TABLE'
721         #corpus.make_et_table()
722         word = self.getColumnText(self.GetFirstSelected(), 6)
723         lems = corpus.getlems()
724         uces = corpus.lc[self.cl-1]
725         rep = []
726         #FIXME : donner aussi eff reel a la place de nb uce
727         for forme in lems[word].formes :
728             ucef = list(set(corpus.getworduces(forme)).intersection(uces))
729             #ucef = [uce for uce in corpus.formes[forme][1] if uce in uces]
730             if ucef != [] :
731                 nb = len(ucef)
732                 rep.append([corpus.getforme(forme).forme, nb])
733         rep.sort(key = itemgetter(1), reverse = True)
734         win = message(self, u"Formes associées", wx.Size(300, 200))
735         win.html = '<html>\n' + '<br>'.join([' : '.join([str(val) for val in forme]) for forme in rep]) + '\n</html>'
736         win.HtmlPage.SetPage(win.html)
737         win.Show(True)
738
739
740 class wliste(wx.Frame):
741     def __init__(self, parent, id, title, d, fline, size=(600, 500)):
742         wx.Frame.__init__(self, parent, id)
743         self.liste = ListForSpec(self, parent, d, fline, menu = False)
744         self.button_1 = wx.Button(self, -1, "Fermer")
745         self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.button_1)
746         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
747         self.__do_layout()
748
749     def __do_layout(self):
750         sizer_1 = wx.BoxSizer(wx.VERTICAL)
751         sizer_2 = wx.BoxSizer(wx.VERTICAL)
752         sizer_2.Add(self.liste, 1, wx.EXPAND | wx.ADJUST_MINSIZE, 0)
753         sizer_2.Add(self.button_1, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ADJUST_MINSIZE, 0)
754         sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
755         self.SetAutoLayout(True)
756         self.SetSizer(sizer_1)
757         self.Layout()
758         
759     def OnCloseMe(self, event):
760         self.Close(True)
761
762     def OnCloseWindow(self, event):
763         self.Destroy()