...
[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         tab = tableau.make_table_from_classe(self.cl, self.la)
435         pathout = ConstructPathOut(self.Source.pathout.dirout, 'simi_classe_%i' %self.cl)
436         self.filename = os.path.join(pathout,'mat01.csv')
437         tableau.printtable(self.filename, tab)
438         del tab
439         paramsimi = {'coeff' : 0,
440                           'layout' : 2,
441                           'type_graph' : 1,
442                           'arbremax' : 1,
443                           'coeff_tv' : 1,
444                           'coeff_tv_nb' : 0,
445                           'tvprop' : 0,
446                           'tvmin' : 5,
447                           'tvmax' : 30,
448                           'coeff_te' : 1,
449                           'coeff_temin' : 1,
450                           'coeff_temax' : 10,
451                           'label_v': 1,
452                           'label_e': 1,
453                           'vcex' : 0,
454                           'vcexmin' : 10,
455                           'vcexmax' : 25,
456                           'cex' : 10,
457                           'cexfromchi' : True,
458                           'sfromchi': False,
459                           'seuil_ok' : 0,
460                           'seuil' : 1,
461                           'cols' : (255,0,0),
462                           'cola' : (200,200,200),
463                           'width' : 1000,
464                           'height' : 1000,
465                           'first' : True,
466                           'keep_coord' : True,
467                           'alpha' : 20,
468                           'film': False,
469                           'com' : 0,
470                           'communities' : 0,
471                           'halo' : 0
472                           }
473         act = {}
474         tableau.chi = {}
475         tableau.lchi = self.lchi
476         tableau.parametre['fromprof'] = True
477         for i, val in enumerate(self.la) :
478             act[val] = [self.lfreq[i]]
479             tableau.chi[val] = [self.lchi[i]]
480         self.parent.SimiCluster(parametres = paramsimi, fromprof = ffr(self.filename), pathout = pathout, listactives = self.la, actives = act, tableau = tableau)
481
482     def onwordgraph(self, evt):
483         word = self.getColumnText(self.GetFirstSelected(), 6)
484         if self.tmpchi is None :
485             self.tmpchi = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
486             with open(self.tmpchi, 'w') as f:
487                 f.write('\n'.join([str(val) for val in self.lchi]))
488         index = self.la.index(word)
489         parametres = {'type' : 'clustersimitxt', 
490                         'pathout' : self.Source.parametres['pathout'],
491                         'word' : index ,
492                         'lem' : self.Source.parametres['lem'],
493                         'tmpchi' : self.tmpchi}
494         #try :
495         self.parent.SimiFromCluster(self.parent, self.Source.corpus, self.la, self.lfreq, self.lchi, self.cl - 1, parametres = parametres, dlg = progressbar(self, 4))
496         #except :
497         #    print 'not acitve'
498
499     def on_graph(self, evt):
500         if self.tmpchi is None :
501             self.tmpchi = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
502             with open(self.tmpchi, 'w') as f:
503                 f.write('\n'.join([str(val) for val in self.lchi]))
504         parametres = {'type' : 'clustersimitxt', 
505                         'pathout' : self.Source.parametres['pathout'],
506                         'lem' : self.Source.parametres['lem'],
507                         'tmpchi' : self.tmpchi}
508
509         self.parent.SimiFromCluster(self.parent, self.Source.corpus, self.la, self.lfreq, self.lchi, self.cl - 1, parametres = parametres, dlg = progressbar(self, 4))
510
511     def on_segments(self,evt) :
512         dlg = progressbar(self, 2)
513         corpus = self.Source.corpus
514         uces = corpus.lc[self.cl-1]
515         l = []
516         dlg.Update(1, u'Segments...')
517         for i in range(2,10) :
518             li = corpus.find_segments_in_classe(uces, i, 1000)
519             if li == [] :
520                 break
521             else :
522                 l += li
523         l.sort(reverse = True)
524         d = {}
525         dlg.Update(2, 'Tri...')
526         for i, line in enumerate(l) :
527             d[i] = [line[1],line[0], line[2]]
528         first = ['','','']
529         para={'dico': d,'fline':first}
530         dlg.Destroy()
531         win = wliste(self, -1, u"Segments répétés - Classe %i" % self.cl, d, first, size=(600, 500))
532         win.Show(True)
533
534     def on_uce_carac(self,evt) :
535         dial = PrefUCECarac(self, self.parent)
536         dial.CenterOnParent()
537         if dial.ShowModal() == wx.ID_OK :
538             limite = dial.spin_eff.GetValue()
539             atype = dial.radio_type.GetSelection()
540             dlg = progressbar(self,maxi = 4)
541             corpus = self.Source.corpus
542             uces = corpus.lc[self.cl-1]
543             tab = corpus.make_table_with_classe(uces, self.la)
544             tab.pop(0)
545             dlg.Update(2, u'score...')
546             if atype == 0 :
547                 ntab = [round(sum([self.lchi[i] for i, word in enumerate(line) if word == 1]),2) for line in tab]
548             else :
549                 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]
550             ntab2 = [[ntab[i], uces[i]] for i, val in enumerate(ntab)]
551             del ntab
552             ntab2.sort(reverse = True)
553             ntab2 = ntab2[:limite]
554             nuces = [val[1] for val in ntab2]
555             dlg.Update(3, u'concordancier...')
556             ucis_txt, ucestxt = doconcorde(corpus, nuces, self.la)
557             dlg.Update(4, u'texte...')
558             win = message(self, u"Segments de texte caractéristiques - Classe %i" % self.cl, (750, 600))
559             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>'
560             win.HtmlPage.SetPage(win.html)
561             dlg.Destroy()
562             win.Show(True)
563     
564     def on_tablex(self, evt):
565         if 'corpus' in dir(self.Source):
566             corpus = self.Source.corpus
567         else :
568             corpus = self.Source.tableau
569         with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
570             chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
571         title = chistable[0]
572         title.pop(0)
573         chistable.pop(0)
574         vchistable = [line[1:] for line in chistable]
575         fchistable = [line[0] for line in chistable]
576         words = self.getselectedwords()
577         tableout = [vchistable[fchistable.index(word)] for word in words]
578         tmpgraph = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
579         nbcl = len(title)
580         nbwords = len(words)
581         txt = barplot(tableout, words, title, self.Source.parent.RscriptsPath['Rgraph'], tmpgraph)
582         #print 'ATTENTION TEST R'
583         #txt = """
584         #sink('/Users/pierre/Desktop/qdfqsdfqsdfqsdf.txt')
585         #Sys.getlocale()
586         #sink()
587         #"""
588         tmpscript = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
589         file = open(tmpscript,'w')
590         file.write(txt)
591         file.close()
592         exec_rcode(self.Source.parent.RPath, tmpscript, wait = True)
593         w = 100 + (20 * nbwords) + (100 * nbcl)
594         h = 100 + (nbwords * 15)
595         if w > 1100 : w = 1100
596         if h > 800 : h = 800
597         if h < 450 : h = 450
598         win = MessageImage(self, u"Graphique", size=(w, h))
599         win.addsaveimage(tmpgraph)
600         txt = "<img src='%s'>" % tmpgraph
601         win.HtmlPage.SetPage(txt)
602         win.Show(True)
603
604     def onlexdendro(self, evt):
605         if 'corpus' in dir(self.Source):
606             corpus = self.Source.corpus
607         else :
608             corpus = self.Source.tableau
609         with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
610             chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
611         title = chistable[0]
612         title.pop(0)
613         chistable.pop(0)
614         vchistable = [line[1:] for line in chistable]
615         fchistable = [line[0] for line in chistable]
616         words = self.getselectedwords()
617         tableout = [vchistable[fchistable.index(word)] for word in words]
618         tmpgraph = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
619         txttable = 'c(' + ','.join([','.join(line) for line in tableout]) + ')'
620         rownames = 'c("' + '","'.join(words) + '")'
621         colnames = 'c("' + '","'.join(title) + '")'
622         nbcl = len(title)
623         rownb = len(words)
624         txt = """
625         load("%s")
626         di <- matrix(data=%s, nrow=%i, byrow = TRUE)
627         rownames(di)<- %s
628         colnames(di) <- %s
629         library(ape)
630         source("%s")
631         height <- (30*ncol(di)) + (15*nrow(di))
632         height <- ifelse(height <= 400, 400, height)
633         width <- 500
634         open_file_graph("%s", width=width, height=height)
635         plot.dendro.lex(tree.cut1$tree.cl, di)
636         """ % (self.Source.pathout['Rdendro'], txttable, rownb, rownames, colnames, self.Source.parent.RscriptsPath['Rgraph'], ffr(tmpgraph))
637         tmpscript = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
638         file = open(tmpscript,'w')
639         file.write(txt)
640         file.close()
641         exec_rcode(self.Source.parent.RPath, tmpscript, wait = True)
642         win = MessageImage(self, u"Graphique", size=(700, 500))
643         win.addsaveimage(tmpgraph)
644         txt = "<img src='%s'>" % tmpgraph
645         win.HtmlPage.SetPage(txt)
646         win.Show(True)
647
648
649     def make_concord(self, uces, title, color = 'red') :
650         corpus = self.Source.corpus
651         ListWord = [self.getColumnText(self.GetFirstSelected(), 6)]
652         last = self.GetFirstSelected()
653         while self.GetNextSelected(last) != -1:
654             last = self.GetNextSelected(last)
655             ListWord.append(self.getColumnText(last, 6))
656         ucef = []
657         for word in ListWord : 
658             ucef += list(set(corpus.getlemuces(word)).intersection(uces))
659         ucis_txt, ucestxt = doconcorde(corpus, ucef, ListWord)
660         win = message(self, title, size=(750, 600))
661         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>'
662         win.HtmlPage.SetPage(win.html)
663         return win
664
665     def OnPopupTwo(self, event):
666         corpus = self.Source.corpus
667         uces = corpus.lc[self.cl-1]
668         win = self.make_concord(uces, "Concordancier - Classe %i" % self.cl)
669         win.Show(True)
670     
671     def OnPopupThree(self, event):
672         corpus = self.Source.corpus
673         uces = [classe[i] for classe in corpus.lc for i in range(0,len(classe))]
674         win = self.make_concord(uces, "Concordancier - UCE classées")
675         win.Show(True)
676         
677     def OnPopupFour(self, event):
678         corpus = self.Source.corpus
679         uces = [classe[i] for classe in corpus.lc for i in range(0,len(classe))] + corpus.lc0
680         win = self.make_concord(uces, "Concordancier - Toutes les UCE")
681         win.Show(True)
682
683     def OnPopupFive(self, event):
684         word = self.getColumnText(self.GetFirstSelected(), 6)
685         lk = "http://www.cnrtl.fr/definition/" + word
686         webbrowser.open(lk)
687
688     def OnPopupSix(self, event):  
689         word = self.getColumnText(self.GetFirstSelected(), 6)
690         lk = "http://www.cnrtl.fr/etymologie/" + word
691         webbrowser.open(lk)
692         
693     def OnPopupSeven(self, event):        
694         word = self.getColumnText(self.GetFirstSelected(), 6)
695         lk = "http://www.cnrtl.fr/synonymie/" + word
696         webbrowser.open(lk)
697         
698     def OnPopupHeight(self, event):  
699         word = self.getColumnText(self.GetFirstSelected(), 6)
700         lk = "http://www.cnrtl.fr/antonymie/" + word
701         webbrowser.open(lk)
702         
703     def OnPopupNine(self, event):            
704         word = self.getColumnText(self.GetFirstSelected(), 6)
705         lk = "http://www.cnrtl.fr/morphologie/" + word
706         webbrowser.open(lk)
707
708     def onproxe(self, evt) :
709         word = self.getColumnText(self.GetFirstSelected(), 6)
710         lk = "http://www.cnrtl.fr/proxemie/" + word
711         webbrowser.open(lk)
712
713     def OnPopupOne(self, event):
714         corpus = self.Source.corpus
715         #print 'ATTENTION PRINT ET TABLE'
716         #corpus.make_et_table()
717         word = self.getColumnText(self.GetFirstSelected(), 6)
718         lems = corpus.getlems()
719         uces = corpus.lc[self.cl-1]
720         rep = []
721         #FIXME : donner aussi eff reel a la place de nb uce
722         for forme in lems[word].formes :
723             ucef = list(set(corpus.getworduces(forme)).intersection(uces))
724             #ucef = [uce for uce in corpus.formes[forme][1] if uce in uces]
725             if ucef != [] :
726                 nb = len(ucef)
727                 rep.append([corpus.getforme(forme).forme, nb])
728         rep.sort(key = itemgetter(1), reverse = True)
729         win = message(self, u"Formes associées", wx.Size(300, 200))
730         win.html = '<html>\n' + '<br>'.join([' : '.join([str(val) for val in forme]) for forme in rep]) + '\n</html>'
731         win.HtmlPage.SetPage(win.html)
732         win.Show(True)
733
734
735 class wliste(wx.Frame):
736     def __init__(self, parent, id, title, d, fline, size=(600, 500)):
737         wx.Frame.__init__(self, parent, id)
738         self.liste = ListForSpec(self, parent, d, fline, menu = False)
739         self.button_1 = wx.Button(self, -1, "Fermer")
740         self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.button_1)
741         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
742         self.__do_layout()
743
744     def __do_layout(self):
745         sizer_1 = wx.BoxSizer(wx.VERTICAL)
746         sizer_2 = wx.BoxSizer(wx.VERTICAL)
747         sizer_2.Add(self.liste, 1, wx.EXPAND | wx.ADJUST_MINSIZE, 0)
748         sizer_2.Add(self.button_1, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ADJUST_MINSIZE, 0)
749         sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
750         self.SetAutoLayout(True)
751         self.SetSizer(sizer_1)
752         self.Layout()
753         
754     def OnCloseMe(self, event):
755         self.Close(True)
756
757     def OnCloseWindow(self, event):
758         self.Destroy()