...
[iramuteq] / tree.py
1 # -*- coding: utf-8 -*-
2 #Author: Pierre Ratinaud
3 #Copyright (c) 2012, Pierre Ratinaud
4 #License: GNU GPL
5
6 import wx
7 import os
8 import webbrowser
9 import wx.lib.agw.customtreectrl as CT
10 import logging
11 from openanalyse import OpenAnalyse
12 from corpus import Corpus, copycorpus
13 from tableau import Tableau, copymatrix
14 from functions import DoConf, GetTxtProfile, TGen
15 from profile_segment import ProfileSegment, ProfilType
16 from search_tools import SearchFrame
17 from dialog import PrefSimpleFile, PrefExport
18 from layout import open_antiprofil, TgenLayout
19 from guifunct import TGenFrame
20 from textaslexico import TgenSpec
21
22 log = logging.getLogger('iramuteq.tree')
23
24 class InfoDialog ( wx.Dialog ):
25     
26     def __init__( self, parent, txt, parametres ):
27         wx.Dialog.__init__ ( self, parent, id = wx.ID_ANY, title = u"Informations", pos = wx.DefaultPosition, size = wx.DefaultSize, style = wx.DEFAULT_DIALOG_STYLE )
28         if len(parametres) > 30 :
29             nb = 4
30         else :
31             nb = 2       
32         self.SetSizeHintsSz( wx.Size( 500,200 ), wx.DefaultSize )
33         
34         bSizer1 = wx.BoxSizer( wx.VERTICAL )
35         
36         self.m_panel2 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
37         bSizer2 = wx.BoxSizer( wx.VERTICAL )
38         
39         self.m_staticText4 = wx.StaticText( self.m_panel2, wx.ID_ANY, txt, wx.DefaultPosition, wx.DefaultSize, 0 )
40         self.m_staticText4.Wrap( -1 )
41         bSizer2.Add( self.m_staticText4, 0, wx.ALL, 5 )
42         
43         
44         self.m_panel2.SetSizer( bSizer2 )
45         self.m_panel2.Layout()
46         bSizer2.Fit( self.m_panel2 )
47         bSizer1.Add( self.m_panel2, 0, wx.EXPAND |wx.ALL, 5 )
48         
49         self.m_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
50
51         fgSizer1 = wx.FlexGridSizer( 0, nb, 0, 0 )
52         fgSizer1.SetFlexibleDirection( wx.BOTH )
53         fgSizer1.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
54         
55         txtctrl = []
56         for val in parametres :
57             fgSizer1.Add( wx.StaticText( self.m_panel1, wx.ID_ANY, val[0], wx.DefaultPosition, wx.DefaultSize, 0 ), 0, wx.ALL, 0)
58             #fgSizer1.Add( wx.StaticText( self.m_panel1, wx.ID_ANY, val[1], wx.DefaultPosition, wx.DefaultSize, 0 ), 0, wx.ALL, 0)
59             txtctrl.append( wx.TextCtrl( self.m_panel1, wx.ID_ANY, val[1], wx.DefaultPosition, (450, 20), wx.TE_READONLY ) )
60             txtctrl[-1].SetBackgroundColour('#DDE8EB')
61             #wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT))
62             fgSizer1.Add( txtctrl[-1], 0, wx.ALL|wx.EXPAND, 0)
63             #fgSizer1.Add( wx.StaticLine( self.m_panel1, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ), 0, wx.EXPAND |wx.ALL, 0)
64             #fgSizer1.Add( wx.StaticLine( self.m_panel1, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.LI_HORIZONTAL ), 0, wx.EXPAND|wx.ALL, 0)
65
66         self.m_panel1.SetSizer( fgSizer1 )
67         self.m_panel1.Layout()
68         fgSizer1.Fit( self.m_panel1 )
69         bSizer1.Add( self.m_panel1, 0, wx.EXPAND|wx.ALL, 3 )
70         
71         m_sdbSizer1 = wx.StdDialogButtonSizer()
72         self.m_sdbSizer1OK = wx.Button( self, wx.ID_OK )
73         m_sdbSizer1.AddButton( self.m_sdbSizer1OK )
74         m_sdbSizer1.Realize();
75         
76         bSizer1.Add( m_sdbSizer1, 0, wx.EXPAND, 5 )
77         
78         
79         self.SetSizer( bSizer1 )
80         self.Layout()
81         bSizer1.Fit( self )
82         
83         self.Centre( wx.BOTH )
84     
85     def __del__( self ):
86         pass
87
88
89 class LeftTree(CT.CustomTreeCtrl):
90
91     def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
92                  size=wx.DefaultSize,
93                  style=wx.SUNKEN_BORDER|wx.WANTS_CHARS,
94                  agwStyle=CT.TR_HIDE_ROOT|CT.TR_HAS_BUTTONS|CT.TR_HAS_VARIABLE_ROW_HEIGHT):
95
96         CT.CustomTreeCtrl.__init__(self, parent, id, pos, size, style, agwStyle)
97         self.log = log
98         alldata = dir(CT)
99         treestyles = []
100         events = []
101         for data in alldata:
102             if data.startswith("TR_"):
103                 treestyles.append(data)
104             elif data.startswith("EVT_"):
105                 events.append(data)
106         self.parent = parent
107         self.events = events
108         self.styles = treestyles
109         self.item = None
110         
111         self.il = wx.ImageList(16, 16)
112         self.ild = {}
113         imgtextroot = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'textroot.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
114         self.ild['alceste'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'reinert.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
115         self.ild['corpus'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'textcorpus.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
116         self.ild['wordcloud'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'wordcloud.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
117         self.ild['stat'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'stats.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
118         self.ild['simitxt'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'simitxt.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
119         self.ild['clustersimitxt'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'clustersimitxt.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
120         self.ild['clustercloud'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'clustercloud.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
121         self.ild['spec'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'spec.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
122         imgmatroot = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'matroot.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
123         self.ild['matrix'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'matrix.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
124         self.ild['freq'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'frequences.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
125         self.ild['chi2'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'chi2.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
126         self.ild['reinertmatrix'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'reinertmatrix.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
127         self.ild['simimatrix'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'simimatrix.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
128         self.SetImageList(self.il)
129         
130         self.count = 0
131         self.log = log
132
133         self.history = parent.history
134         self.h = self.history.history
135         self.root = self.AddRoot("Iramuteq")
136         
137         if not(self.GetAGWWindowStyleFlag() & CT.TR_HIDE_ROOT):
138             self.SetPyData(self.root, None)
139             self.SetItemImage(self.root, 24, CT.TreeItemIcon_Normal)
140             self.SetItemImage(self.root, 13, CT.TreeItemIcon_Expanded)
141         
142         self.textroot = self.AppendItem(self.root, u'Corpus texte')
143         self.SetPyData(self.textroot, {'uuid': 'textroot'})
144         self.SetItemImage(self.textroot, imgtextroot, CT.TreeItemIcon_Normal)
145         self.SetItemImage(self.textroot, imgtextroot, CT.TreeItemIcon_Expanded)     
146
147         for corpus in reversed(self.h) :
148             child = self.AppendItem(self.textroot, corpus['corpus_name'])
149             self.SetPyData(child, corpus)
150             self.SetItemImage(child, self.ild['corpus'], CT.TreeItemIcon_Normal)
151             self.SetItemImage(child, self.ild['corpus'], CT.TreeItemIcon_Expanded)
152
153             if 'analyses' in corpus :
154                 for y in corpus['analyses'] :
155                     last = self.AppendItem(child, y['name'], ct_type=0)
156                     self.SetPyData(last, y)
157                     if y['type'] in self.ild :
158                         img = self.ild[y['type']]
159                     else :
160                         img = 24
161                     self.SetItemImage(last, img, CT.TreeItemIcon_Normal)
162                     self.SetItemImage(last, img, CT.TreeItemIcon_Expanded)
163
164         self.matroot = self.AppendItem(self.root, u'Matrices')
165         self.SetPyData(self.matroot, {'uuid': 'matroot'})
166         self.SetItemImage(self.matroot, imgmatroot, CT.TreeItemIcon_Normal)
167         self.SetItemImage(self.matroot, imgmatroot, CT.TreeItemIcon_Expanded)
168         
169         orphmat = []
170         for matrix in reversed(self.history.matrix) :
171             if 'matrix_name' in matrix :
172                 child = self.AppendItem(self.matroot, matrix['matrix_name'])
173                 self.SetPyData(child, matrix)
174                 self.SetItemImage(child, self.ild['matrix'], CT.TreeItemIcon_Normal)
175                 self.SetItemImage(child, self.ild['matrix'], CT.TreeItemIcon_Expanded)
176                 if 'analyses' in matrix :
177                     for y in matrix['analyses'] :
178                         last = self.AppendItem(child, y['name'], ct_type=0)
179                         self.SetPyData(last, y)
180                         if y['type'] in self.ild :
181                             img = self.ild[y['type']]
182                         else :
183                             img = 24
184                         self.SetItemImage(last, img, CT.TreeItemIcon_Normal)
185                         self.SetItemImage(last, img, CT.TreeItemIcon_Expanded)
186             else :
187                 orphmat.append(matrix)     
188
189         self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDClick)
190         #self.Bind(wx.EVT_IDLE, self.OnIdle)
191
192         self.eventdict = {'EVT_TREE_BEGIN_DRAG': self.OnBeginDrag, 'EVT_TREE_BEGIN_LABEL_EDIT': self.OnBeginEdit,
193                           'EVT_TREE_BEGIN_RDRAG': self.OnBeginRDrag, 'EVT_TREE_DELETE_ITEM': self.OnDeleteItem,
194                           'EVT_TREE_END_DRAG': self.OnEndDrag, 'EVT_TREE_END_LABEL_EDIT': self.OnEndEdit,
195                           'EVT_TREE_ITEM_ACTIVATED': self.OnActivate, 'EVT_TREE_ITEM_CHECKED': self.OnItemCheck,
196                           'EVT_TREE_ITEM_CHECKING': self.OnItemChecking, 'EVT_TREE_ITEM_COLLAPSED': self.OnItemCollapsed,
197                           'EVT_TREE_ITEM_COLLAPSING': self.OnItemCollapsing, 'EVT_TREE_ITEM_EXPANDED': self.OnItemExpanded,
198                           'EVT_TREE_ITEM_EXPANDING': self.OnItemExpanding, 'EVT_TREE_ITEM_GETTOOLTIP': self.OnToolTip,
199                           'EVT_TREE_ITEM_MENU': self.OnItemMenu, 'EVT_TREE_ITEM_RIGHT_CLICK': self.OnRightDown,
200                           'EVT_TREE_KEY_DOWN': self.OnKey, 'EVT_TREE_SEL_CHANGED': self.OnSelChanged,
201                           'EVT_TREE_SEL_CHANGING': self.OnSelChanging, "EVT_TREE_ITEM_HYPERLINK": self.OnHyperLink}
202
203         mainframe = wx.GetTopLevelParent(self)
204         
205         if not hasattr(mainframe, "leftpanel"):
206             #self.Bind(CT.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded)
207             #self.Bind(CT.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed)
208             self.Bind(CT.EVT_TREE_SEL_CHANGED, self.OnSelChanged)
209             self.Bind(CT.EVT_TREE_SEL_CHANGING, self.OnSelChanging)
210             self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
211             self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
212         else:
213             for combos in mainframe.treeevents:
214                 self.BindEvents(combos)
215
216         if hasattr(mainframe, "leftpanel"):
217             self.ChangeStyle(mainframe.treestyles)
218
219         if not(self.GetAGWWindowStyleFlag() & CT.TR_HIDE_ROOT):
220             self.SelectItem(self.root)
221             self.Expand(self.root)
222
223
224     def BindEvents(self, choice, recreate=False):
225
226         value = choice.GetValue()
227         text = choice.GetLabel()
228         
229         evt = "CT." + text
230         binder = self.eventdict[text]
231
232         if value == 1:
233             if evt == "CT.EVT_TREE_BEGIN_RDRAG":
234                 self.Bind(wx.EVT_RIGHT_DOWN, None)
235                 self.Bind(wx.EVT_RIGHT_UP, None)
236             self.Bind(eval(evt), binder)
237         else:
238             self.Bind(eval(evt), None)
239             if evt == "CT.EVT_TREE_BEGIN_RDRAG":
240                 self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
241                 self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
242
243
244     def ChangeStyle(self, combos):
245
246         style = 0
247         for combo in combos:
248             if combo.GetValue() == 1:
249                 style = style | eval("CT." + combo.GetLabel())
250
251         if self.GetAGWWindowStyleFlag() != style:
252             self.SetAGWWindowStyleFlag(style)
253             
254
255     def OnCompareItems(self, item1, item2):
256         
257         t1 = self.GetItemText(item1)
258         t2 = self.GetItemText(item2)
259         
260
261         if t1 < t2:
262             return -1
263         if t1 == t2:
264             return 0
265
266         return 1
267
268     
269     def OnIdle(self, event):
270
271     #    if self.gauge:
272     #        try:
273     #            if self.gauge.IsEnabled() and self.gauge.IsShown():
274     #                self.count = self.count + 1
275
276     #                if self.count >= 50:
277     #                    self.count = 0
278
279     #                self.gauge.SetValue(self.count)
280
281     #        except:
282     #            self.gauge = None
283
284         event.Skip()
285
286
287     def CloseItem(self, itemParent = None, uuid = None) :
288         if itemParent is None :
289             itemParent = self.root
290         child, cookie = self.GetFirstChild(itemParent)
291         while child :
292             pydata = self.GetPyData(child)
293             if pydata['uuid'] == uuid :
294                 self.SetItemBold(child, False)
295                 break
296             self.CloseItem(child, uuid)
297             child, cookie = self.GetNextChild(itemParent, cookie)
298
299     def GiveFocus(self, itemParent = None, uuid = None, bold = False) :
300         if itemParent is None :
301             itemParent = self.root
302         child, cookie = self.GetFirstChild(itemParent)
303         while child :
304             pydata = self.GetPyData(child)
305             if pydata['uuid'] == uuid :
306                 self.SelectItem(child)
307                 if bold :
308                     self.SetItemBold(child, True)
309                 return
310             self.GiveFocus(child, uuid, bold)
311             child, cookie = self.GetNextChild(itemParent, cookie)
312
313     def IsInTree(self, itemParent = None, uuid = None) :
314         if itemParent is None :
315             itemParent = self.root
316         child, cookie = self.GetFirstChild(itemParent)
317         
318         while child :
319             pydata = self.GetPyData(child)
320             if pydata['uuid'] == uuid :
321                 return True
322             self.GiveFocus(child, uuid)
323             child, cookie = self.GetNextChild(itemParent, cookie)
324         return False
325
326
327     def OnRightDown(self, event):
328         
329         pt = event.GetPosition()
330         item, flags = self.HitTest(pt)
331
332         if item:
333             self.item = item
334             #self.log.info("OnRightClick: %s, %s, %s" % (self.GetItemText(item), type(item), item.__class__) + "\n")
335             self.SelectItem(item)
336
337
338     def OnRightUp(self, event):
339
340         item = self.item
341         
342         if not item:
343             event.Skip()
344             return
345
346         if not self.IsItemEnabled(item):
347             event.Skip()
348             return
349
350         # Item Text Appearance
351         ishtml = self.IsItemHyperText(item)
352         back = self.GetItemBackgroundColour(item)
353         fore = self.GetItemTextColour(item)
354         isbold = self.IsBold(item)
355         font = self.GetItemFont(item)
356
357         # Icons On Item
358         normal = self.GetItemImage(item, CT.TreeItemIcon_Normal)
359         selected = self.GetItemImage(item, CT.TreeItemIcon_Selected)
360         expanded = self.GetItemImage(item, CT.TreeItemIcon_Expanded)
361         selexp = self.GetItemImage(item, CT.TreeItemIcon_SelectedExpanded)
362
363         # Enabling/Disabling Windows Associated To An Item
364         haswin = self.GetItemWindow(item)
365
366         # Enabling/Disabling Items
367         enabled = self.IsItemEnabled(item)
368
369         # Generic Item's Info
370         children = self.GetChildrenCount(item)
371         itemtype = self.GetItemType(item)
372         text = self.GetItemText(item)
373         pydata = self.GetPyData(item)
374         self.pydata = pydata
375         
376         self.current = item
377         self.itemdict = {"ishtml": ishtml, "back": back, "fore": fore, "isbold": isbold,
378                          "font": font, "normal": normal, "selected": selected, "expanded": expanded,
379                          "selexp": selexp, "haswin": haswin, "children": children,
380                          "itemtype": itemtype, "text": text, "pydata": pydata, "enabled": enabled}
381         
382         if not item in [self.textroot, self.matroot] :
383             menu = wx.Menu()
384             info = menu.Append(wx.ID_ANY, _(u"Informations").encode('utf8'))
385             rename = menu.Append(wx.ID_ANY, _(u"Rename").encode('utf8'))
386             menu.AppendSeparator()
387     
388             if 'corpus_name' in pydata :
389                 stat = menu.Append(wx.ID_ANY, _(u"Statistics").decode('utf8'))
390                 spec = menu.Append(wx.ID_ANY, _(u"Specificities and CA").decode('utf8'))
391                 classification = wx.Menu()
392                 reinert = classification.Append(wx.ID_ANY, _(u"Reinert method").decode('utf8'))
393                 #pam = classification.Append(wx.ID_ANY, u"Par matrice des distances")
394                 menu.AppendMenu(-1, _(u"Clustering").decode('utf8'), classification)
395                 simi = menu.Append(wx.ID_ANY, _(u"Similarities analysis").decode('utf8'))
396                 wdc = menu.Append(wx.ID_ANY, _(u"Wordcloud").decode('utf8'))
397                 subcorpus = wx.Menu()
398                 subcorpusfrommeta = subcorpus.Append(wx.ID_ANY, _(u'Sub corpus from metadata').decode('utf8'))
399                 subcorpusfromtheme = subcorpus.Append(wx.ID_ANY, _(u'Sub corpus from thematic').decode('utf8'))
400                 menu.AppendMenu(-1, _(u"Sub corpus").decode('utf8'), subcorpus)
401                 menu.AppendSeparator()
402                 self.Bind(wx.EVT_MENU, self.OnReinert, reinert)
403                 #self.Bind(wx.EVT_MENU, self.OnPam, pam)
404                 self.Bind(wx.EVT_MENU, self.OnStat, stat)
405                 self.Bind(wx.EVT_MENU, self.OnSpec, spec)
406                 self.Bind(wx.EVT_MENU, self.OnSimiTxt, simi)
407                 self.Bind(wx.EVT_MENU, self.OnWordCloud, wdc)
408                 self.Bind(wx.EVT_MENU, self.OnSubTextFromMeta, subcorpusfrommeta)
409                 self.Bind(wx.EVT_MENU, self.OnSubTextFromTheme, subcorpusfromtheme)
410             elif 'matrix_name' in pydata :
411                 for i in range(self.parent.matrix_menu.GetMenuItemCount()) :
412                     item = self.parent.matrix_menu.FindItemByPosition(i)
413                     itemid = item.GetId()
414                     itemtext = item.GetText()
415                     menu.Append(itemid, itemtext)
416                 split = wx.Menu()
417                 splitfromvar = split.Append(-1, _(u"Split from variable").decode('utf8'))
418                 menu.AppendMenu(-1, _(u"Split matrix").decode('utf8'), split)
419                 self.Bind(wx.EVT_MENU, self.OnSplitFromVar, splitfromvar)
420                     #print item, itemid, itemtext
421                 #menu = self.parent.matrix_menu
422                 #freq = menu.Append(wx.ID_ANY, _(u"Frequency").decode('utf8'))
423                 #chi2 = menu.Append(wx.ID_ANY, _(u"Chi square").decode('utf8'))
424                 #chdreinert = menu.Append(wx.ID_ANY, _(u"Reinert clustering").decode('utf8'))
425                 #simi = menu.Append(wx.ID_ANY, _(u"Similarity analysis").decode('utf8'))
426                 menu.AppendSeparator()
427                 #self.Bind(wx.EVT_MENU, self.OnFreq, freq)
428                 #self.Bind(wx.EVT_MENU, self.OnChiSquare, chi2)
429                 #self.Bind(wx.EVT_MENU, self.OnSimiTab, simi)
430                 #self.Bind(wx.EVT_MENU, self.OnCHDReinert, chdreinert)
431             elif pydata.get('type', False) == 'alceste' and pydata['uuid'] in self.parent.history.opened :
432                 openmenu = wx.Menu()
433                 antipro = openmenu.Append(wx.ID_ANY, _(u"Antiprofiles").decode('utf8'))
434                 menu.AppendMenu(wx.ID_ANY, _(u"Open ...").decode('utf8'), openmenu)
435     
436                 profsr = menu.Append(wx.ID_ANY, _(u"Repeated segments profiles").decode('utf8'))
437                 profgram = menu.Append(wx.ID_ANY, _(u"POS profiles").decode('utf8'))
438                 export_corpus = menu.Append(wx.ID_ANY, _(u"Export corpus").decode('utf8'))
439                 colored = menu.Append(wx.ID_ANY, _(u"Colored corpus").decode('utf8'))
440                 navig = menu.Append(wx.ID_ANY, _(u"Navigator").decode('utf8'))
441                 statclasse = menu.Append(wx.ID_ANY, _(u"Clusters statistics").decode('utf8'))
442                 rapport = menu.Append(wx.ID_ANY, _(u"Report").decode('utf8'))
443                 export_classes = menu.Append(wx.ID_ANY, _(u"Export Clusters").decode('utf8'))
444                 menu.AppendSeparator()
445                 self.Bind(wx.EVT_MENU, self.OpenAntipro, antipro)
446                 self.Bind(wx.EVT_MENU, self.OnProfSR, profsr)
447                 self.Bind(wx.EVT_MENU, self.OnProfGram, profgram)
448                 self.Bind(wx.EVT_MENU, self.OnExportCorpus, export_corpus)
449                 self.Bind(wx.EVT_MENU, self.OnColored, colored)
450                 self.Bind(wx.EVT_MENU, self.OnNavig, navig)
451                 self.Bind(wx.EVT_MENU, self.StatClasse, statclasse)
452                 self.Bind(wx.EVT_MENU, self.OnRapport, rapport)
453                 self.Bind(wx.EVT_MENU, self.OnExportClasses, export_classes)
454             elif pydata.get('type', False) == 'stat'  and pydata['uuid'] in self.parent.history.opened :
455                 export_dictionary =  menu.Append(wx.ID_ANY, _(u"Export dictionary").decode('utf8'))
456                 export_lems =  menu.Append(wx.ID_ANY, _(u"Export lemma dictionary").decode('utf8'))
457                 self.Bind(wx.EVT_MENU, self.OnExportDictionary, export_dictionary)
458                 self.Bind(wx.EVT_MENU, self.OnExportLems, export_lems)
459                 menu.AppendSeparator()
460             elif pydata.get('type', False) == 'spec'  and pydata['uuid'] in self.parent.history.opened :
461                 tgen = menu.Append(wx.ID_ANY, _(u"Tgen Editor").decode('utf8'))
462                 computetgen = menu.Append(wx.ID_ANY, _(u"Compute Tgen").decode('utf8'))
463                 self.Bind(wx.EVT_MENU, self.OnTgenEditor, tgen)
464                 self.Bind(wx.EVT_MENU, self.OnTgenCompute, computetgen)
465                 menu.AppendSeparator()
466             elif pydata.get('type', False) == 'reinertmatrix' and pydata['uuid'] in self.parent.history.opened :
467                 openmenu = wx.Menu()
468                 antipro = openmenu.Append(wx.ID_ANY, _(u"antiprofiles").decode('utf8'))
469                 menu.AppendMenu(wx.ID_ANY, _(u"Open ...").decode('utf8'), openmenu)
470                 self.Bind(wx.EVT_MENU, self.OpenAntipro, antipro)
471     
472     
473             itemdelete = menu.Append(wx.ID_ANY, _(u"Delete from history").decode('utf8'))
474             #item11 = menu.Append(wx.ID_ANY, "Prepend An Item")
475             #item12 = menu.Append(wx.ID_ANY, "Append An Item")
476     
477             #self.Bind(wx.EVT_MENU, self.OnItemBackground, item1)
478             #self.Bind(wx.EVT_MENU, self.OnItemForeground, item2)
479             #self.Bind(wx.EVT_MENU, self.OnItemBold, item3)
480             #self.Bind(wx.EVT_MENU, self.OnItemFont, item4)
481             #self.Bind(wx.EVT_MENU, self.OnItemHyperText, item5)
482             #self.Bind(wx.EVT_MENU, self.OnEnableWindow, item6)
483             #self.Bind(wx.EVT_MENU, self.OnDisableItem, item7)
484             #self.Bind(wx.EVT_MENU, self.OnItemIcons, item8)
485             self.Bind(wx.EVT_MENU, self.OnItemInfo, info)
486             self.Bind(wx.EVT_MENU, self.OnRename, rename)
487             self.Bind(wx.EVT_MENU, self.OnItemDelete, itemdelete)
488             #self.Bind(wx.EVT_MENU, self.OnItemPrepend, item11)
489             #self.Bind(wx.EVT_MENU, self.OnItemAppend, item12)
490             
491             self.PopupMenu(menu)
492             menu.Destroy()
493
494     def getcorpus(self):
495         busy = wx.BusyInfo(_("Please wait...Reading corpus").decode('utf8'), self.parent)
496         wx.SafeYield()
497         if self.pydata['uuid'] in self.parent.history.openedcorpus :
498             corpus = copycorpus(self.parent.history.openedcorpus[self.pydata['uuid']])
499         elif 'corpus_name' in self.pydata :
500             corpus = Corpus(self.parent, parametres = DoConf(self.pydata['ira']).getoptions('corpus'), read = True)
501         else :
502             cuuid = self.pydata['corpus']
503             if cuuid in self.parent.history.openedcorpus :
504                 corpus = copycorpus(self.parent.history.openedcorpus[cuuid])
505             else :
506                 irapath = self.parent.history.corpus[cuuid]['ira']
507                 corpus = Corpus(self.parent, parametres = DoConf(irapath).getoptions('corpus'), read = True)
508         del busy
509         return corpus
510     
511     def getmatrix(self):
512         if 'matrix_name' in self.pydata :
513             matrix = Tableau(self.parent, parametres = DoConf(self.pydata['ira']).getoptions('matrix'))
514             matrix.open()
515             return copymatrix(matrix)
516         else :
517             cuuid = self.pydata['matrix']
518             matrix = Tableau(self.parent, parametres = DoConf(self.history.matrixanalyse[cuuid]['ira']).getoptions('matrix'))
519             matrix.open()
520             return copymatrix(matrix)
521
522     def OnSpec(self, evt) :
523         self.parent.OnTextSpec(evt, self.getcorpus())
524
525     def OnStat(self, evt) :
526         self.parent.OnTextStat(evt, self.getcorpus())
527         
528     def OnReinert(self, evt) :
529         self.parent.OnTextReinert(evt, self.getcorpus())
530
531     def OnPam(self, evt) :
532         self.parent.OnPamSimple(evt, self.getcorpus())
533
534     def OnSimiTxt(self, evt) :
535         self.parent.OnSimiTxt(evt, self.getcorpus())
536
537     def OnWordCloud(self, evt) :
538         self.parent.OnWordCloud(evt, self.getcorpus())
539     
540     def OnFreq(self, evt):
541         self.parent.OnFreq(evt, self.getmatrix())
542         
543     def OnChiSquare(self, evt):
544         self.parent.OnChi2(evt, self.getmatrix())
545         
546     def OnSimiTab(self, evt): 
547         self.parent.OnSimiTab(evt, self.getmatrix())
548     
549     def OnProto(self, evt):
550         self.parent.OnProto(evt, self.getmatrix())
551     
552     def OnSplitFromVar(self, evt):
553         self.parent.OnSplitVar(evt, self.getmatrix())
554         
555     def OnCHDReinert(self, evt):
556         self.parent.OnCHDReinert(evt, self.getmatrix())
557     
558     def OnSubTextFromMeta(self, evt):
559         self.parent.OnSubText(self.getcorpus(), parametres = {'frommeta' : True})
560     
561     def OnSubTextFromTheme(self, evt):
562         self.parent.OnSubText(self.getcorpus(), parametres = {'fromtheme' : True})    
563
564     def OnProfSR(self, evt) :
565         ProfileSegment(self.parent, self.page.dictpathout, self.page.parametres, self.page.corpus)
566
567     def OnProfGram(self, evt) :
568         ProfilType(self.parent, self.page.corpus, self.page.parametres)
569
570     def OnExportCorpus(self, evt) :
571         dial = PrefExport(self, self.parent)
572         dial.fbb.SetValue(os.path.join(os.path.dirname(self.page.dictpathout['ira']), 'export_corpus.txt'))
573         dial.CenterOnParent()
574         res = dial.ShowModal()
575         if res == wx.ID_OK :
576             if dial.radio_type.GetSelection() == 0 : alc = True
577             else : alc = False
578             if dial.radio_lem.GetSelection() == 0 : lem = True
579             else : lem = False
580             if self.page.parametres['classif_mode'] != 2 :
581                 uci = False
582             else :
583                 uci = True
584             self.page.corpus.export_corpus_classes(dial.fbb.GetValue(), alc = alc, lem = lem, uci = uci)
585             msg = u"Fini !"
586             dial.Destroy()
587             dlg = wx.MessageDialog(self.parent, msg, u"Export", wx.OK | wx.NO_DEFAULT | wx.ICON_INFORMATION)
588             dlg.CenterOnParent()
589             dlg.ShowModal()
590             dlg.Destroy()
591
592     def OnColored(self, evt) :
593         dial = PrefSimpleFile(self, self.parent, **{'mask' : '*.html', 'title': _(u"Colored corpus").decode('utf8')})
594         dial.fbb.SetValue(os.path.join(os.path.dirname(self.page.dictpathout['ira']), 'corpus_couleur.html'))
595         dial.CenterOnParent()
596         res = dial.ShowModal()
597         if res == wx.ID_OK :
598             fileout = dial.fbb.GetValue()
599             dial.Destroy()
600             if self.page.parametres['classif_mode'] != 2 :
601                 uci = False
602             else :
603                 uci = True
604             txt = self.page.corpus.make_colored_corpus(uci = uci)
605             with open(fileout, 'w') as f :
606                 f.write(txt)
607             msg = ' !\n'.join([_(u"Done").decode('utf8'), _(u"Open in a web browser ?").decode('utf8')])
608             dlg = wx.MessageDialog(self.parent, msg, u"Corpus en couleur", wx.NO | wx.YES | wx.NO_DEFAULT | wx.ICON_QUESTION)
609             dlg.CenterOnParent()
610             if dlg.ShowModal() == wx.ID_YES :
611                 webbrowser.open(fileout)
612             dlg.Destroy()
613
614     def OnNavig(self, evt):
615         if 'FrameSearch' not in dir(self.page) :
616             self.page.FrameSearch = SearchFrame(self.parent, -1, _(u"Search ...").decode('utf8'), self.page.corpus)
617         self.page.FrameSearch.Show()
618
619     def StatClasse(self, evt):
620         dial = PrefSimpleFile(self, self.parent, **{'mask' : '*.csv', 'title': _(u"Clusters statistics").decode('utf8')})
621         dial.fbb.SetValue( os.path.join(os.path.dirname(self.page.dictpathout['ira']), 'stat_par_classe.csv'))
622         dial.CenterOnParent()
623         res = dial.ShowModal()
624         if res == wx.ID_OK :
625             fileout = dial.fbb.GetValue()
626             dial.Destroy()
627             self.page.corpus.get_stat_by_cluster(fileout)
628             msg = u"Fini !"
629             dlg = wx.MessageDialog(self.parent, msg, _(u"Clusters statistics").decode('utf8'), wx.OK | wx.NO_DEFAULT | wx.ICON_INFORMATION)
630             dlg.CenterOnParent()
631             if dlg.ShowModal() == wx.ID_OK :
632                 dlg.Destroy()        
633
634     def OpenAntipro(self, evt) :
635         find = False
636         for i in range(0, self.page.TabChdSim.GetPageCount()) :
637             page = self.page.TabChdSim.GetPage(i)
638             if self.page.TabChdSim.GetPageText(i) == _(u"Antiprofiles").decode('utf8') :
639                 self.page.TabChdSim.SetSelection(i)
640                 find = True
641                 break
642         if not find :
643             open_antiprofil(self.page, self.page.dictpathout['ANTIPRO_OUT'], self.parent.syscoding)
644             self.page.TabChdSim.SetSelection(self.page.TabChdSim.GetPageCount() - 1)
645
646     def OnRapport(self, evt) :
647         dial = PrefSimpleFile(self, self.parent, **{'mask' : '*.txt', 'title': _(u"Report").decode('utf8')})
648         dial.fbb.SetValue(self.page.dictpathout['rapport'])
649         dial.CenterOnParent()
650         res = dial.ShowModal()
651         if res == wx.ID_OK :
652             fileout = dial.fbb.GetValue()
653             dial.Destroy()
654             with open(fileout, 'w') as f :
655                 f.write(self.page.debtext + '\n' + GetTxtProfile(self.page.DictProfile, self.page.cluster_size))
656             msg = u"Fini !"
657             dlg = wx.MessageDialog(self.parent, msg, _(u"Report").decode('utf8'), wx.OK | wx.NO_DEFAULT | wx.ICON_INFORMATION)
658             dlg.CenterOnParent()
659             dlg.ShowModal()
660             dlg.Destroy()
661         else :
662             dial.Destroy()
663
664     def OnExportDictionary(self, evt) :
665         corpus = self.page.corpus
666         corpus.export_dictionary(self.page.pathout['dictionary.csv'], self.parent.syscoding)
667         log.info('export dictionary %s' % self.page.pathout['dictionary.csv'])
668         dial = wx.MessageDialog(self.parent, self.page.pathout['dictionary.csv'], 'Export', wx.OK)
669         dial.ShowModal()
670         dial.Destroy()
671         
672     def OnExportLems(self, evt) :
673         corpus = self.page.corpus
674         corpus.export_lems(self.page.pathout['lemmes.csv'], self.parent.syscoding)
675         log.info('export lemmes %s' % self.page.pathout['lemmes.csv'])
676         dial = wx.MessageDialog(self.parent, self.page.pathout['lemmes.csv'], 'Export', wx.OK)
677         dial.ShowModal()
678         dial.Destroy()
679     
680     def OnTgenEditor(self, evt):
681         corpus = self.page.corpus
682         tgenpath = os.path.join(self.page.parametres['pathout'], 'tgen.csv')
683         tgen = TGen(path = tgenpath, encoding = self.parent.syscoding)
684         if os.path.exists(tgenpath) :
685             tgen.read(tgenpath)
686         if isinstance(evt, list) :
687             i = 0
688             while 'tgen%i' %i in tgen.tgen :
689                 i += 1
690             tgenname = 'tgen%i' %i
691             tgen.tgen[tgenname] = evt
692         tgenframe = TGenFrame(self.parent, corpus, tgen)
693         tgenframe.Show()
694         if isinstance(evt, list) :
695             tgenframe.OnNewTgen(None, tgen = tgenname)
696     
697     def OnTgenCompute(self, evt):
698         corpus = self.page.corpus
699         tgenpath = os.path.join(self.page.parametres['pathout'], 'tgen.csv')        
700         if not os.path.exists(tgenpath) :
701             message = wx.MessageDialog(self.parent, _(u"No TGen yet !"), style = wx.ICON_EXCLAMATION | wx.OK) 
702             message.ShowModal()
703             message.Destroy()
704         else :
705             self.page.parametres['tgenpath'] = tgenpath
706             tgen = TGen(path = tgenpath, encoding = self.parent.syscoding)
707             self.page.parametres['etoiles'] = self.page.etoiles
708             TgenSpec(self.parent, corpus, self.page.parametres)
709             TgenLayout(self.page)
710     
711     def OnExportClasses(self, event):
712         corpus = self.page.corpus
713         if self.page.parametres['classif_mode'] != 2 :
714             uci = False
715         else :
716             uci = True
717         busy = wx.BusyInfo(_("Please wait...").decode('utf8'), self.parent)
718         wx.SafeYield()
719         for i in range(1, self.page.parametres['clnb'] + 1) :
720             corpus.export_classe(self.page.pathout['classe_%i_export.txt' % i], i, uci = uci)
721         del busy
722         dial = wx.MessageDialog(self, self.page.pathout['classe_x_export.txt'], u"Export", wx.OK|wx.ICON_INFORMATION)
723         dial.ShowModal()
724         dial.Destroy()
725     
726     def OnRename(self, event):
727         pydata = self.itemdict['pydata']
728         print pydata
729
730     def OnItemBackground(self, event):
731
732         colourdata = wx.ColourData()
733         colourdata.SetColour(self.itemdict["back"])
734         dlg = wx.ColourDialog(self, colourdata)
735         
736         dlg.GetColourData().SetChooseFull(True)
737
738         if dlg.ShowModal() == wx.ID_OK:
739             data = dlg.GetColourData()
740             col1 = data.GetColour().Get()
741             self.SetItemBackgroundColour(self.current, col1)
742         dlg.Destroy()
743
744
745     def OnItemForeground(self, event):
746
747         colourdata = wx.ColourData()
748         colourdata.SetColour(self.itemdict["fore"])
749         dlg = wx.ColourDialog(self, colourdata)
750         
751         dlg.GetColourData().SetChooseFull(True)
752
753         if dlg.ShowModal() == wx.ID_OK:
754             data = dlg.GetColourData()
755             col1 = data.GetColour().Get()
756             self.SetItemTextColour(self.current, col1)
757         dlg.Destroy()
758
759
760     def OnItemBold(self, event):
761
762         self.SetItemBold(self.current, not self.itemdict["isbold"])
763
764
765     def OnItemFont(self, event):
766
767         data = wx.FontData()
768         font = self.itemdict["font"]
769         
770         if font is None:
771             font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
772             
773         data.SetInitialFont(font)
774
775         dlg = wx.FontDialog(self, data)
776         
777         if dlg.ShowModal() == wx.ID_OK:
778             data = dlg.GetFontData()
779             font = data.GetChosenFont()
780             self.SetItemFont(self.current, font)
781
782         dlg.Destroy()
783         
784
785     def OnItemHyperText(self, event):
786
787         self.SetItemHyperText(self.current, not self.itemdict["ishtml"])
788
789
790     def OnEnableWindow(self, event):
791
792         enable = self.GetItemWindowEnabled(self.current)
793         self.SetItemWindowEnabled(self.current, not enable)
794
795
796     def OnDisableItem(self, event):
797
798         self.EnableItem(self.current, False)
799         
800
801     def OnItemIcons(self, event):
802
803         bitmaps = [self.itemdict["normal"], self.itemdict["selected"],
804                    self.itemdict["expanded"], self.itemdict["selexp"]]
805
806         wx.BeginBusyCursor()        
807         dlg = TreeIcons(self, -1, bitmaps=bitmaps)
808         wx.EndBusyCursor()
809         dlg.ShowModal()
810
811
812     def SetNewIcons(self, bitmaps):
813
814         self.SetItemImage(self.current, bitmaps[0], CT.TreeItemIcon_Normal)
815         self.SetItemImage(self.current, bitmaps[1], CT.TreeItemIcon_Selected)
816         self.SetItemImage(self.current, bitmaps[2], CT.TreeItemIcon_Expanded)
817         self.SetItemImage(self.current, bitmaps[3], CT.TreeItemIcon_SelectedExpanded)
818
819
820     def OnItemInfo(self, event):
821
822         itemtext = self.itemdict["text"]
823         numchildren = str(self.itemdict["children"])
824         itemtype = self.itemdict["itemtype"]
825         pydata = self.itemdict['pydata']
826         #if 'analyses' in pydata :
827         #    toshow = dict([[val, pydata[val]] for val in pydata if val not in['analyses', 'isload']])
828         #else :
829         toshow = pydata['ira']
830         toshow = DoConf(toshow).getoptions()
831         txt = DoConf().totext(toshow)
832         parametres = [val.split('\t\t:') for val in txt.splitlines()]
833         parametres.sort()
834
835         if itemtype == 0:
836             itemtype = "Normal"
837         elif itemtype == 1:
838             itemtype = "CheckBox"
839         else:
840             itemtype = "RadioButton"
841
842         dlg = InfoDialog(self, itemtext, parametres)
843         dlg.CenterOnParent()
844         dlg.ShowModal()
845         dlg.Destroy()
846                 
847         
848
849     def OnItemDelete(self, event):
850
851         strs = "Are You Sure You Want To Delete Item " + self.GetItemText(self.current) + "?"
852         dlg = wx.MessageDialog(None, strs, 'Deleting Item', wx.OK | wx.CANCEL | wx.ICON_QUESTION)
853
854         if dlg.ShowModal() in [wx.ID_NO, wx.ID_CANCEL]:
855             dlg.Destroy()
856             return
857
858         dlg.Destroy()
859         
860         pydata = self.itemdict['pydata']
861         if 'corpus_name' in pydata :
862             self.history.delete(pydata, True)
863         else :
864             self.history.delete(pydata)
865         self.DeleteChildren(self.current)
866         self.Delete(self.current)
867         self.current = None
868         
869
870
871     def OnItemPrepend(self, event):
872
873         dlg = wx.TextEntryDialog(self, "Please Enter The New Item Name", 'Item Naming', 'Python')
874
875         if dlg.ShowModal() == wx.ID_OK:
876             newname = dlg.GetValue()
877             newitem = self.PrependItem(self.current, newname)
878             self.EnsureVisible(newitem)
879
880         dlg.Destroy()
881
882     def AddAnalyse(self, parametres, itemParent = None, bold = True) :
883         uuid = parametres.get('corpus', None)
884         if uuid is not None :
885             if itemParent is None :
886                 itemParent = self.textroot
887             child, cookie = self.GetFirstChild(itemParent)
888             corpus = None
889             while child :
890                 pydata = self.GetPyData(child)
891                 if pydata['uuid'] == uuid :
892                     corpus = child
893                     break
894                 self.GiveFocus(child, uuid)
895                 child, cookie = self.GetNextChild(itemParent, cookie)
896             #item = self.AppendItem(child, parametres['name'])
897             if corpus is not None : 
898                 item = self.AppendItem(corpus, parametres['name'])
899             else :
900                 item = self.AppendItem(self.textroot, parametres['name'])
901         else :
902             item = self.AppendItem(self.matroot, parametres['name'])
903         self.SetPyData(item, parametres)
904         if parametres['type'] in self.ild :
905             img = self.ild[parametres['type']]
906         else :
907             img = 24
908         self.SetItemImage(item, img, CT.TreeItemIcon_Normal)
909         self.SetItemImage(item, 13, CT.TreeItemIcon_Expanded)
910         self.SetItemBold(item, bold)
911         self.SelectItem(item)
912     
913     def AddMatAnalyse(self, parametres, itemParent = None, bold = True) :
914         uuid = parametres.get('matrix', None)
915         if uuid is not None :
916             if itemParent is None :
917                 itemParent = self.matroot
918             child, cookie = self.GetFirstChild(itemParent)
919             matrix = None
920             while child :
921                 pydata = self.GetPyData(child)
922                 if pydata['uuid'] == uuid :
923                     matrix = child
924                     break
925                 self.GiveFocus(child, uuid)
926                 child, cookie = self.GetNextChild(itemParent, cookie)
927             #item = self.AppendItem(child, parametres['name'])
928             if matrix is not None : 
929                 item = self.AppendItem(matrix, parametres['name'])
930             else :
931                 item = self.AppendItem(self.matroot, parametres['name'])
932         self.SetPyData(item, parametres)
933         if parametres['type'] in self.ild :
934             img = self.ild[parametres['type']]
935         else :
936             img = 24
937         self.SetItemImage(item, img, CT.TreeItemIcon_Normal)
938         self.SetItemImage(item, 13, CT.TreeItemIcon_Expanded)
939         self.SetItemBold(item, bold)
940         self.SelectItem(item)  
941         
942     def OnItemAppend(self, item):
943         if 'corpus_name' in item :
944             child = self.InsertItem(self.textroot, 0, item['corpus_name'])
945         else :
946             child = self.InsertItem(self.matroot, 0, item['matrix_name'])
947         self.SetPyData(child, item)
948         self.history.addtab(item)
949         if item['type'] in self.ild :
950             img = self.ild[item['type']]
951         else :
952             img = 24
953         self.SetItemImage(child, img, CT.TreeItemIcon_Normal)
954         self.SetItemImage(child, img, CT.TreeItemIcon_Expanded)
955         self.SetItemBold(child, True)
956         
957         #dlg = wx.TextEntryDialog(self, "Please Enter The New Item Name", 'Item Naming', 'Python')
958
959         #if dlg.ShowModal() == wx.ID_OK:
960         #    newname = dlg.GetValue()
961         #    newitem = self.AppendItem(self.current, newname)
962         #    self.EnsureVisible(newitem)
963         
964
965         #dlg.Destroy()
966         
967
968     def OnBeginEdit(self, event):
969         
970         #self.log.info("OnBeginEdit" + "\n")
971         # show how to prevent edit...
972         item = event.GetItem()
973         if item and self.GetItemText(item) == "The Root Item":
974             wx.Bell()
975             #self.log.info("You can't edit this one..." + "\n")
976
977             # Lets just see what's visible of its children
978             cookie = 0
979             root = event.GetItem()
980             (child, cookie) = self.GetFirstChild(root)
981
982             while child:
983                 #self.log.info("Child [%s] visible = %d" % (self.GetItemText(child), self.IsVisible(child)) + "\n")
984                 (child, cookie) = self.GetNextChild(root, cookie)
985
986             event.Veto()
987
988
989     def OnEndEdit(self, event):
990         
991         #self.log.info("OnEndEdit: %s %s" %(event.IsEditCancelled(), event.GetLabel()))
992         # show how to reject edit, we'll not allow any digits
993         for x in event.GetLabel():
994             if x in string.digits:
995                 #self.log.info(", You can't enter digits..." + "\n")
996                 event.Veto()
997                 return
998             
999         self.log.info("\n")
1000
1001
1002     def OnLeftDClick(self, event):
1003         pt = event.GetPosition()
1004         item, flags = self.HitTest(pt)
1005         if item is not None :
1006             pydata = self.GetPyData(item)
1007             if pydata['uuid'] in self.parent.history.opened :
1008                 for i in range(self.parent.nb.GetPageCount()) :
1009                     page = self.parent.nb.GetPage(i)
1010                     if 'parametres' in dir(page) :
1011                         if page.parametres['uuid'] == pydata['uuid'] :
1012                             self.parent.nb.SetSelection(i)
1013                             break
1014             elif pydata['uuid'] in ['textroot', 'matroot'] :
1015                 pass
1016             else :
1017                 busy = wx.BusyInfo(_("Please wait..."), self.parent)
1018                 wx.SafeYield()
1019                 OpenAnalyse(self.parent, pydata)
1020                 del busy
1021                 self.SetItemBold(item, True)
1022                 self.OnSelChanged(pydata = pydata)
1023         #if item and (flags & CT.TREE_HITTEST_ONITEMLABEL):
1024         #    if self.GetAGWWindowStyleFlag() & CT.TR_EDIT_LABELS:
1025         #        self.log.info("OnLeftDClick: %s (manually starting label edit)"% self.GetItemText(item) + "\n")
1026                 
1027                 #self.EditLabel(item)
1028         #    else:
1029         #        pydata = self.GetPyData(item)
1030         #        print pydata
1031         #        self.log.info("OnLeftDClick: Cannot Start Manual Editing, Missing Style TR_EDIT_LABELS\n")
1032
1033         event.Skip()                
1034         
1035
1036     def OnItemExpanded(self, event):
1037         
1038         item = event.GetItem()
1039         if item:
1040             self.log.info("OnItemExpanded: %s" % self.GetItemText(item) + "\n")
1041
1042
1043     def OnItemExpanding(self, event):
1044         
1045         item = event.GetItem()
1046         if item:
1047             self.log.info("OnItemExpanding: %s" % self.GetItemText(item) + "\n")
1048             
1049         event.Skip()
1050
1051         
1052     def OnItemCollapsed(self, event):
1053
1054         item = event.GetItem()
1055         if item:
1056             self.log.info("OnItemCollapsed: %s" % self.GetItemText(item) + "\n")
1057             
1058
1059     def OnItemCollapsing(self, event):
1060
1061         item = event.GetItem()
1062         if item:
1063             self.log.info("OnItemCollapsing: %s" % self.GetItemText(item) + "\n")
1064     
1065         event.Skip()
1066
1067         
1068     def OnSelChanged(self, event = None, pydata = None):
1069         if event is not None :
1070             item = event.GetItem()
1071             pydata = self.GetPyData(item)
1072         if pydata is not None :
1073             self.pydata = pydata
1074             if pydata['uuid'] in self.parent.history.opened :
1075                 for i in range(self.parent.nb.GetPageCount()) :
1076                     self.page = self.parent.nb.GetPage(i)
1077                     if 'parametres' in dir(self.page) :
1078                         if self.page.parametres['uuid'] == pydata['uuid'] :
1079                             self.parent.nb.SetSelection(i)
1080                             break
1081         if event is not None :
1082             event.Skip()
1083
1084
1085     def OnSelChanging(self, event):
1086
1087         item = event.GetItem()
1088         olditem = event.GetOldItem()
1089         
1090         if item:
1091             if not olditem:
1092                 olditemtext = "None"
1093             else:
1094                 olditemtext = self.GetItemText(olditem)
1095             #self.log.info("OnSelChanging: From %s" % olditemtext + " To %s" % self.GetItemText(item) + "\n")
1096                 
1097         event.Skip()
1098
1099
1100     def OnBeginDrag(self, event):
1101
1102         self.item = event.GetItem()
1103         if self.item:
1104             self.log.info("Beginning Drag..." + "\n")
1105
1106             event.Allow()
1107
1108
1109     def OnBeginRDrag(self, event):
1110
1111         self.item = event.GetItem()
1112         if self.item:
1113             self.log.info("Beginning Right Drag..." + "\n")
1114
1115             event.Allow()
1116         
1117
1118     def OnEndDrag(self, event):
1119
1120         self.item = event.GetItem()
1121         if self.item:
1122             self.log.info("Ending Drag!" + "\n")
1123
1124         event.Skip()            
1125
1126
1127     def OnDeleteItem(self, event):
1128
1129         item = event.GetItem()
1130
1131         if not item:
1132             return
1133
1134         self.log.info("Deleting Item: %s" % self.GetItemText(item) + "\n")
1135         event.Skip()
1136         
1137
1138     def OnItemCheck(self, event):
1139
1140         item = event.GetItem()
1141         self.log.info("Item " + self.GetItemText(item) + " Has Been Checked!\n")
1142         event.Skip()
1143
1144
1145     def OnItemChecking(self, event):
1146
1147         item = event.GetItem()
1148         self.log.info("Item " + self.GetItemText(item) + " Is Being Checked...\n")
1149         event.Skip()
1150         
1151
1152     def OnToolTip(self, event):
1153
1154         item = event.GetItem()
1155         if item:
1156             event.SetToolTip(wx.ToolTip(self.GetItemText(item)))
1157
1158
1159     def OnItemMenu(self, event):
1160
1161         item = event.GetItem()
1162         if item:
1163             self.log.info("OnItemMenu: %s" % self.GetItemText(item) + "\n")
1164     
1165         event.Skip()
1166
1167
1168     def OnKey(self, event):
1169
1170         keycode = event.GetKeyCode()
1171         keyname = keyMap.get(keycode, None)
1172                 
1173         if keycode == wx.WXK_BACK:
1174             self.log.info("OnKeyDown: HAHAHAHA! I Vetoed Your Backspace! HAHAHAHA\n")
1175             return
1176
1177         if keyname is None:
1178             if "unicode" in wx.PlatformInfo:
1179                 keycode = event.GetUnicodeKey()
1180                 if keycode <= 127:
1181                     keycode = event.GetKeyCode()
1182                 keyname = "\"" + unichr(event.GetUnicodeKey()) + "\""
1183                 if keycode < 27:
1184                     keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
1185                 
1186             elif keycode < 256:
1187                 if keycode == 0:
1188                     keyname = "NUL"
1189                 elif keycode < 27:
1190                     keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
1191                 else:
1192                     keyname = "\"%s\"" % chr(keycode)
1193             else:
1194                 keyname = "unknown (%s)" % keycode
1195                 
1196         self.log.info("OnKeyDown: You Pressed '" + keyname + "'\n")
1197
1198         event.Skip()
1199         
1200         
1201     def OnActivate(self, event):
1202         
1203         if self.item:
1204             self.log.info("OnActivate: %s" % self.GetItemText(self.item) + "\n")
1205
1206         event.Skip()
1207
1208         
1209     def OnHyperLink(self, event):
1210
1211         item = event.GetItem()
1212         if item:
1213             self.log.info("OnHyperLink: %s" % self.GetItemText(self.item) + "\n")
1214             
1215
1216     def OnTextCtrl(self, event):
1217
1218         char = chr(event.GetKeyCode())
1219         self.log.info("EDITING THE TEXTCTRL: You Wrote '" + char + \
1220                        "' (KeyCode = " + str(event.GetKeyCode()) + ")\n")
1221         event.Skip()
1222
1223
1224     def OnComboBox(self, event):
1225
1226         selection = event.GetEventObject().GetValue()
1227         self.log.info("CHOICE FROM COMBOBOX: You Chose '" + selection + "'\n")
1228         event.Skip()