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