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