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