...
[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         self.page.parametres['tgenpath'] = tgenpath
701         tgen = TGen(path = tgenpath, encoding = self.parent.syscoding)
702         self.page.parametres['etoiles'] = self.page.etoiles
703         TgenSpec(self.parent, corpus, self.page.parametres)
704         TgenLayout(self.page)
705     
706     def OnExportClasses(self, event):
707         corpus = self.page.corpus
708         if self.page.parametres['classif_mode'] != 2 :
709             uci = False
710         else :
711             uci = True
712         busy = wx.BusyInfo(_("Please wait...").decode('utf8'), self.parent)
713         wx.SafeYield()
714         for i in range(1, self.page.parametres['clnb'] + 1) :
715             corpus.export_classe(self.page.pathout['classe_%i_export.txt' % i], i, uci = uci)
716         del busy
717         dial = wx.MessageDialog(self, self.page.pathout['classe_x_export.txt'], u"Export", wx.OK|wx.ICON_INFORMATION)
718         dial.ShowModal()
719         dial.Destroy()
720     
721     def OnRename(self, event):
722         pydata = self.itemdict['pydata']
723         print pydata
724
725     def OnItemBackground(self, event):
726
727         colourdata = wx.ColourData()
728         colourdata.SetColour(self.itemdict["back"])
729         dlg = wx.ColourDialog(self, colourdata)
730         
731         dlg.GetColourData().SetChooseFull(True)
732
733         if dlg.ShowModal() == wx.ID_OK:
734             data = dlg.GetColourData()
735             col1 = data.GetColour().Get()
736             self.SetItemBackgroundColour(self.current, col1)
737         dlg.Destroy()
738
739
740     def OnItemForeground(self, event):
741
742         colourdata = wx.ColourData()
743         colourdata.SetColour(self.itemdict["fore"])
744         dlg = wx.ColourDialog(self, colourdata)
745         
746         dlg.GetColourData().SetChooseFull(True)
747
748         if dlg.ShowModal() == wx.ID_OK:
749             data = dlg.GetColourData()
750             col1 = data.GetColour().Get()
751             self.SetItemTextColour(self.current, col1)
752         dlg.Destroy()
753
754
755     def OnItemBold(self, event):
756
757         self.SetItemBold(self.current, not self.itemdict["isbold"])
758
759
760     def OnItemFont(self, event):
761
762         data = wx.FontData()
763         font = self.itemdict["font"]
764         
765         if font is None:
766             font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
767             
768         data.SetInitialFont(font)
769
770         dlg = wx.FontDialog(self, data)
771         
772         if dlg.ShowModal() == wx.ID_OK:
773             data = dlg.GetFontData()
774             font = data.GetChosenFont()
775             self.SetItemFont(self.current, font)
776
777         dlg.Destroy()
778         
779
780     def OnItemHyperText(self, event):
781
782         self.SetItemHyperText(self.current, not self.itemdict["ishtml"])
783
784
785     def OnEnableWindow(self, event):
786
787         enable = self.GetItemWindowEnabled(self.current)
788         self.SetItemWindowEnabled(self.current, not enable)
789
790
791     def OnDisableItem(self, event):
792
793         self.EnableItem(self.current, False)
794         
795
796     def OnItemIcons(self, event):
797
798         bitmaps = [self.itemdict["normal"], self.itemdict["selected"],
799                    self.itemdict["expanded"], self.itemdict["selexp"]]
800
801         wx.BeginBusyCursor()        
802         dlg = TreeIcons(self, -1, bitmaps=bitmaps)
803         wx.EndBusyCursor()
804         dlg.ShowModal()
805
806
807     def SetNewIcons(self, bitmaps):
808
809         self.SetItemImage(self.current, bitmaps[0], CT.TreeItemIcon_Normal)
810         self.SetItemImage(self.current, bitmaps[1], CT.TreeItemIcon_Selected)
811         self.SetItemImage(self.current, bitmaps[2], CT.TreeItemIcon_Expanded)
812         self.SetItemImage(self.current, bitmaps[3], CT.TreeItemIcon_SelectedExpanded)
813
814
815     def OnItemInfo(self, event):
816
817         itemtext = self.itemdict["text"]
818         numchildren = str(self.itemdict["children"])
819         itemtype = self.itemdict["itemtype"]
820         pydata = self.itemdict['pydata']
821         #if 'analyses' in pydata :
822         #    toshow = dict([[val, pydata[val]] for val in pydata if val not in['analyses', 'isload']])
823         #else :
824         toshow = pydata['ira']
825         toshow = DoConf(toshow).getoptions()
826         txt = DoConf().totext(toshow)
827         parametres = [val.split('\t\t:') for val in txt.splitlines()]
828         parametres.sort()
829
830         if itemtype == 0:
831             itemtype = "Normal"
832         elif itemtype == 1:
833             itemtype = "CheckBox"
834         else:
835             itemtype = "RadioButton"
836
837         dlg = InfoDialog(self, itemtext, parametres)
838         dlg.CenterOnParent()
839         dlg.ShowModal()
840         dlg.Destroy()
841                 
842         
843
844     def OnItemDelete(self, event):
845
846         strs = "Are You Sure You Want To Delete Item " + self.GetItemText(self.current) + "?"
847         dlg = wx.MessageDialog(None, strs, 'Deleting Item', wx.OK | wx.CANCEL | wx.ICON_QUESTION)
848
849         if dlg.ShowModal() in [wx.ID_NO, wx.ID_CANCEL]:
850             dlg.Destroy()
851             return
852
853         dlg.Destroy()
854         
855         pydata = self.itemdict['pydata']
856         if 'corpus_name' in pydata :
857             self.history.delete(pydata, True)
858         else :
859             self.history.delete(pydata)
860         self.DeleteChildren(self.current)
861         self.Delete(self.current)
862         self.current = None
863         
864
865
866     def OnItemPrepend(self, event):
867
868         dlg = wx.TextEntryDialog(self, "Please Enter The New Item Name", 'Item Naming', 'Python')
869
870         if dlg.ShowModal() == wx.ID_OK:
871             newname = dlg.GetValue()
872             newitem = self.PrependItem(self.current, newname)
873             self.EnsureVisible(newitem)
874
875         dlg.Destroy()
876
877     def AddAnalyse(self, parametres, itemParent = None, bold = True) :
878         uuid = parametres.get('corpus', None)
879         if uuid is not None :
880             if itemParent is None :
881                 itemParent = self.textroot
882             child, cookie = self.GetFirstChild(itemParent)
883             corpus = None
884             while child :
885                 pydata = self.GetPyData(child)
886                 if pydata['uuid'] == uuid :
887                     corpus = child
888                     break
889                 self.GiveFocus(child, uuid)
890                 child, cookie = self.GetNextChild(itemParent, cookie)
891             #item = self.AppendItem(child, parametres['name'])
892             if corpus is not None : 
893                 item = self.AppendItem(corpus, parametres['name'])
894             else :
895                 item = self.AppendItem(self.textroot, parametres['name'])
896         else :
897             item = self.AppendItem(self.matroot, parametres['name'])
898         self.SetPyData(item, parametres)
899         if parametres['type'] in self.ild :
900             img = self.ild[parametres['type']]
901         else :
902             img = 24
903         self.SetItemImage(item, img, CT.TreeItemIcon_Normal)
904         self.SetItemImage(item, 13, CT.TreeItemIcon_Expanded)
905         self.SetItemBold(item, bold)
906         self.SelectItem(item)
907     
908     def AddMatAnalyse(self, parametres, itemParent = None, bold = True) :
909         uuid = parametres.get('matrix', None)
910         if uuid is not None :
911             if itemParent is None :
912                 itemParent = self.matroot
913             child, cookie = self.GetFirstChild(itemParent)
914             matrix = None
915             while child :
916                 pydata = self.GetPyData(child)
917                 if pydata['uuid'] == uuid :
918                     matrix = child
919                     break
920                 self.GiveFocus(child, uuid)
921                 child, cookie = self.GetNextChild(itemParent, cookie)
922             #item = self.AppendItem(child, parametres['name'])
923             if matrix is not None : 
924                 item = self.AppendItem(matrix, parametres['name'])
925             else :
926                 item = self.AppendItem(self.matroot, parametres['name'])
927         self.SetPyData(item, parametres)
928         if parametres['type'] in self.ild :
929             img = self.ild[parametres['type']]
930         else :
931             img = 24
932         self.SetItemImage(item, img, CT.TreeItemIcon_Normal)
933         self.SetItemImage(item, 13, CT.TreeItemIcon_Expanded)
934         self.SetItemBold(item, bold)
935         self.SelectItem(item)  
936         
937     def OnItemAppend(self, item):
938         if 'corpus_name' in item :
939             child = self.InsertItem(self.textroot, 0, item['corpus_name'])
940         else :
941             child = self.InsertItem(self.matroot, 0, item['matrix_name'])
942         self.SetPyData(child, item)
943         self.history.addtab(item)
944         if item['type'] in self.ild :
945             img = self.ild[item['type']]
946         else :
947             img = 24
948         self.SetItemImage(child, img, CT.TreeItemIcon_Normal)
949         self.SetItemImage(child, img, CT.TreeItemIcon_Expanded)
950         self.SetItemBold(child, True)
951         
952         #dlg = wx.TextEntryDialog(self, "Please Enter The New Item Name", 'Item Naming', 'Python')
953
954         #if dlg.ShowModal() == wx.ID_OK:
955         #    newname = dlg.GetValue()
956         #    newitem = self.AppendItem(self.current, newname)
957         #    self.EnsureVisible(newitem)
958         
959
960         #dlg.Destroy()
961         
962
963     def OnBeginEdit(self, event):
964         
965         #self.log.info("OnBeginEdit" + "\n")
966         # show how to prevent edit...
967         item = event.GetItem()
968         if item and self.GetItemText(item) == "The Root Item":
969             wx.Bell()
970             #self.log.info("You can't edit this one..." + "\n")
971
972             # Lets just see what's visible of its children
973             cookie = 0
974             root = event.GetItem()
975             (child, cookie) = self.GetFirstChild(root)
976
977             while child:
978                 #self.log.info("Child [%s] visible = %d" % (self.GetItemText(child), self.IsVisible(child)) + "\n")
979                 (child, cookie) = self.GetNextChild(root, cookie)
980
981             event.Veto()
982
983
984     def OnEndEdit(self, event):
985         
986         #self.log.info("OnEndEdit: %s %s" %(event.IsEditCancelled(), event.GetLabel()))
987         # show how to reject edit, we'll not allow any digits
988         for x in event.GetLabel():
989             if x in string.digits:
990                 #self.log.info(", You can't enter digits..." + "\n")
991                 event.Veto()
992                 return
993             
994         self.log.info("\n")
995
996
997     def OnLeftDClick(self, event):
998         pt = event.GetPosition()
999         item, flags = self.HitTest(pt)
1000         if item is not None :
1001             pydata = self.GetPyData(item)
1002             if pydata['uuid'] in self.parent.history.opened :
1003                 for i in range(self.parent.nb.GetPageCount()) :
1004                     page = self.parent.nb.GetPage(i)
1005                     if 'parametres' in dir(page) :
1006                         if page.parametres['uuid'] == pydata['uuid'] :
1007                             self.parent.nb.SetSelection(i)
1008                             break
1009             elif pydata['uuid'] in ['textroot', 'matroot'] :
1010                 pass
1011             else :
1012                 busy = wx.BusyInfo(_("Please wait..."), self.parent)
1013                 wx.SafeYield()
1014                 OpenAnalyse(self.parent, pydata)
1015                 del busy
1016                 self.SetItemBold(item, True)
1017                 self.OnSelChanged(pydata = pydata)
1018         #if item and (flags & CT.TREE_HITTEST_ONITEMLABEL):
1019         #    if self.GetAGWWindowStyleFlag() & CT.TR_EDIT_LABELS:
1020         #        self.log.info("OnLeftDClick: %s (manually starting label edit)"% self.GetItemText(item) + "\n")
1021                 
1022                 #self.EditLabel(item)
1023         #    else:
1024         #        pydata = self.GetPyData(item)
1025         #        print pydata
1026         #        self.log.info("OnLeftDClick: Cannot Start Manual Editing, Missing Style TR_EDIT_LABELS\n")
1027
1028         event.Skip()                
1029         
1030
1031     def OnItemExpanded(self, event):
1032         
1033         item = event.GetItem()
1034         if item:
1035             self.log.info("OnItemExpanded: %s" % self.GetItemText(item) + "\n")
1036
1037
1038     def OnItemExpanding(self, event):
1039         
1040         item = event.GetItem()
1041         if item:
1042             self.log.info("OnItemExpanding: %s" % self.GetItemText(item) + "\n")
1043             
1044         event.Skip()
1045
1046         
1047     def OnItemCollapsed(self, event):
1048
1049         item = event.GetItem()
1050         if item:
1051             self.log.info("OnItemCollapsed: %s" % self.GetItemText(item) + "\n")
1052             
1053
1054     def OnItemCollapsing(self, event):
1055
1056         item = event.GetItem()
1057         if item:
1058             self.log.info("OnItemCollapsing: %s" % self.GetItemText(item) + "\n")
1059     
1060         event.Skip()
1061
1062         
1063     def OnSelChanged(self, event = None, pydata = None):
1064         if event is not None :
1065             item = event.GetItem()
1066             pydata = self.GetPyData(item)
1067         if pydata is not None :
1068             self.pydata = pydata
1069             if pydata['uuid'] in self.parent.history.opened :
1070                 for i in range(self.parent.nb.GetPageCount()) :
1071                     self.page = self.parent.nb.GetPage(i)
1072                     if 'parametres' in dir(self.page) :
1073                         if self.page.parametres['uuid'] == pydata['uuid'] :
1074                             self.parent.nb.SetSelection(i)
1075                             break
1076         if event is not None :
1077             event.Skip()
1078
1079
1080     def OnSelChanging(self, event):
1081
1082         item = event.GetItem()
1083         olditem = event.GetOldItem()
1084         
1085         if item:
1086             if not olditem:
1087                 olditemtext = "None"
1088             else:
1089                 olditemtext = self.GetItemText(olditem)
1090             #self.log.info("OnSelChanging: From %s" % olditemtext + " To %s" % self.GetItemText(item) + "\n")
1091                 
1092         event.Skip()
1093
1094
1095     def OnBeginDrag(self, event):
1096
1097         self.item = event.GetItem()
1098         if self.item:
1099             self.log.info("Beginning Drag..." + "\n")
1100
1101             event.Allow()
1102
1103
1104     def OnBeginRDrag(self, event):
1105
1106         self.item = event.GetItem()
1107         if self.item:
1108             self.log.info("Beginning Right Drag..." + "\n")
1109
1110             event.Allow()
1111         
1112
1113     def OnEndDrag(self, event):
1114
1115         self.item = event.GetItem()
1116         if self.item:
1117             self.log.info("Ending Drag!" + "\n")
1118
1119         event.Skip()            
1120
1121
1122     def OnDeleteItem(self, event):
1123
1124         item = event.GetItem()
1125
1126         if not item:
1127             return
1128
1129         self.log.info("Deleting Item: %s" % self.GetItemText(item) + "\n")
1130         event.Skip()
1131         
1132
1133     def OnItemCheck(self, event):
1134
1135         item = event.GetItem()
1136         self.log.info("Item " + self.GetItemText(item) + " Has Been Checked!\n")
1137         event.Skip()
1138
1139
1140     def OnItemChecking(self, event):
1141
1142         item = event.GetItem()
1143         self.log.info("Item " + self.GetItemText(item) + " Is Being Checked...\n")
1144         event.Skip()
1145         
1146
1147     def OnToolTip(self, event):
1148
1149         item = event.GetItem()
1150         if item:
1151             event.SetToolTip(wx.ToolTip(self.GetItemText(item)))
1152
1153
1154     def OnItemMenu(self, event):
1155
1156         item = event.GetItem()
1157         if item:
1158             self.log.info("OnItemMenu: %s" % self.GetItemText(item) + "\n")
1159     
1160         event.Skip()
1161
1162
1163     def OnKey(self, event):
1164
1165         keycode = event.GetKeyCode()
1166         keyname = keyMap.get(keycode, None)
1167                 
1168         if keycode == wx.WXK_BACK:
1169             self.log.info("OnKeyDown: HAHAHAHA! I Vetoed Your Backspace! HAHAHAHA\n")
1170             return
1171
1172         if keyname is None:
1173             if "unicode" in wx.PlatformInfo:
1174                 keycode = event.GetUnicodeKey()
1175                 if keycode <= 127:
1176                     keycode = event.GetKeyCode()
1177                 keyname = "\"" + unichr(event.GetUnicodeKey()) + "\""
1178                 if keycode < 27:
1179                     keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
1180                 
1181             elif keycode < 256:
1182                 if keycode == 0:
1183                     keyname = "NUL"
1184                 elif keycode < 27:
1185                     keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
1186                 else:
1187                     keyname = "\"%s\"" % chr(keycode)
1188             else:
1189                 keyname = "unknown (%s)" % keycode
1190                 
1191         self.log.info("OnKeyDown: You Pressed '" + keyname + "'\n")
1192
1193         event.Skip()
1194         
1195         
1196     def OnActivate(self, event):
1197         
1198         if self.item:
1199             self.log.info("OnActivate: %s" % self.GetItemText(self.item) + "\n")
1200
1201         event.Skip()
1202
1203         
1204     def OnHyperLink(self, event):
1205
1206         item = event.GetItem()
1207         if item:
1208             self.log.info("OnHyperLink: %s" % self.GetItemText(self.item) + "\n")
1209             
1210
1211     def OnTextCtrl(self, event):
1212
1213         char = chr(event.GetKeyCode())
1214         self.log.info("EDITING THE TEXTCTRL: You Wrote '" + char + \
1215                        "' (KeyCode = " + str(event.GetKeyCode()) + ")\n")
1216         event.Skip()
1217
1218
1219     def OnComboBox(self, event):
1220
1221         selection = event.GetEventObject().GetValue()
1222         self.log.info("CHOICE FROM COMBOBOX: You Chose '" + selection + "'\n")
1223         event.Skip()