...
[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                 subcorpusfromcl = menu.Append(wx.ID_ANY, _(u"Sub corpus from clusters").decode('utf8'))
445                 menu.AppendSeparator()
446                 self.Bind(wx.EVT_MENU, self.OpenAntipro, antipro)
447                 self.Bind(wx.EVT_MENU, self.OnProfSR, profsr)
448                 self.Bind(wx.EVT_MENU, self.OnProfGram, profgram)
449                 self.Bind(wx.EVT_MENU, self.OnExportCorpus, export_corpus)
450                 self.Bind(wx.EVT_MENU, self.OnColored, colored)
451                 self.Bind(wx.EVT_MENU, self.OnNavig, navig)
452                 self.Bind(wx.EVT_MENU, self.StatClasse, statclasse)
453                 self.Bind(wx.EVT_MENU, self.OnRapport, rapport)
454                 self.Bind(wx.EVT_MENU, self.OnExportClasses, export_classes)
455                 self.Bind(wx.EVT_MENU, self.OnSubCorpusFromClusters, subcorpusfromcl)
456             elif pydata.get('type', False) == 'stat'  and pydata['uuid'] in self.parent.history.opened :
457                 export_dictionary =  menu.Append(wx.ID_ANY, _(u"Export dictionary").decode('utf8'))
458                 export_lems =  menu.Append(wx.ID_ANY, _(u"Export lemma dictionary").decode('utf8'))
459                 self.Bind(wx.EVT_MENU, self.OnExportDictionary, export_dictionary)
460                 self.Bind(wx.EVT_MENU, self.OnExportLems, export_lems)
461                 menu.AppendSeparator()
462             elif pydata.get('type', False) == 'spec'  and pydata['uuid'] in self.parent.history.opened :
463                 tgen = menu.Append(wx.ID_ANY, _(u"Tgen Editor").decode('utf8'))
464                 computetgen = menu.Append(wx.ID_ANY, _(u"Compute Tgen").decode('utf8'))
465                 self.Bind(wx.EVT_MENU, self.OnTgenEditor, tgen)
466                 self.Bind(wx.EVT_MENU, self.OnTgenCompute, computetgen)
467                 menu.AppendSeparator()
468             elif pydata.get('type', False) == 'reinertmatrix' and pydata['uuid'] in self.parent.history.opened :
469                 openmenu = wx.Menu()
470                 antipro = openmenu.Append(wx.ID_ANY, _(u"antiprofiles").decode('utf8'))
471                 menu.AppendMenu(wx.ID_ANY, _(u"Open ...").decode('utf8'), openmenu)
472                 self.Bind(wx.EVT_MENU, self.OpenAntipro, antipro)
473     
474     
475             itemdelete = menu.Append(wx.ID_ANY, _(u"Delete from history").decode('utf8'))
476             #item11 = menu.Append(wx.ID_ANY, "Prepend An Item")
477             #item12 = menu.Append(wx.ID_ANY, "Append An Item")
478     
479             #self.Bind(wx.EVT_MENU, self.OnItemBackground, item1)
480             #self.Bind(wx.EVT_MENU, self.OnItemForeground, item2)
481             #self.Bind(wx.EVT_MENU, self.OnItemBold, item3)
482             #self.Bind(wx.EVT_MENU, self.OnItemFont, item4)
483             #self.Bind(wx.EVT_MENU, self.OnItemHyperText, item5)
484             #self.Bind(wx.EVT_MENU, self.OnEnableWindow, item6)
485             #self.Bind(wx.EVT_MENU, self.OnDisableItem, item7)
486             #self.Bind(wx.EVT_MENU, self.OnItemIcons, item8)
487             self.Bind(wx.EVT_MENU, self.OnItemInfo, info)
488             self.Bind(wx.EVT_MENU, self.OnRename, rename)
489             self.Bind(wx.EVT_MENU, self.OnItemDelete, itemdelete)
490             #self.Bind(wx.EVT_MENU, self.OnItemPrepend, item11)
491             #self.Bind(wx.EVT_MENU, self.OnItemAppend, item12)
492             
493             self.PopupMenu(menu)
494             menu.Destroy()
495
496     def getcorpus(self):
497         busy = wx.BusyInfo(_("Please wait...Reading corpus").decode('utf8'), self.parent)
498         wx.SafeYield()
499         if self.pydata['uuid'] in self.parent.history.openedcorpus :
500             corpus = copycorpus(self.parent.history.openedcorpus[self.pydata['uuid']])
501         elif 'corpus_name' in self.pydata :
502             corpus = Corpus(self.parent, parametres = DoConf(self.pydata['ira']).getoptions('corpus'), read = True)
503         else :
504             cuuid = self.pydata['corpus']
505             if cuuid in self.parent.history.openedcorpus :
506                 corpus = copycorpus(self.parent.history.openedcorpus[cuuid])
507             else :
508                 irapath = self.parent.history.corpus[cuuid]['ira']
509                 corpus = Corpus(self.parent, parametres = DoConf(irapath).getoptions('corpus'), read = True)
510         del busy
511         return corpus
512     
513     def getmatrix(self):
514         if 'matrix_name' in self.pydata :
515             matrix = Tableau(self.parent, parametres = DoConf(self.pydata['ira']).getoptions('matrix'))
516             matrix.open()
517             return copymatrix(matrix)
518         else :
519             cuuid = self.pydata['matrix']
520             matrix = Tableau(self.parent, parametres = DoConf(self.history.matrixanalyse[cuuid]['ira']).getoptions('matrix'))
521             matrix.open()
522             return copymatrix(matrix)
523
524     def OnSpec(self, evt) :
525         self.parent.OnTextSpec(evt, self.getcorpus())
526
527     def OnStat(self, evt) :
528         self.parent.OnTextStat(evt, self.getcorpus())
529         
530     def OnReinert(self, evt) :
531         self.parent.OnTextReinert(evt, self.getcorpus())
532
533     def OnPam(self, evt) :
534         self.parent.OnPamSimple(evt, self.getcorpus())
535
536     def OnSimiTxt(self, evt) :
537         self.parent.OnSimiTxt(evt, self.getcorpus())
538
539     def OnWordCloud(self, evt) :
540         self.parent.OnWordCloud(evt, self.getcorpus())
541     
542     def OnFreq(self, evt):
543         self.parent.OnFreq(evt, self.getmatrix())
544         
545     def OnChiSquare(self, evt):
546         self.parent.OnChi2(evt, self.getmatrix())
547         
548     def OnSimiTab(self, evt): 
549         self.parent.OnSimiTab(evt, self.getmatrix())
550     
551     def OnProto(self, evt):
552         self.parent.OnProto(evt, self.getmatrix())
553     
554     def OnSplitFromVar(self, evt):
555         self.parent.OnSplitVar(evt, self.getmatrix())
556         
557     def OnCHDReinert(self, evt):
558         self.parent.OnCHDReinert(evt, self.getmatrix())
559     
560     def OnSubTextFromMeta(self, evt):
561         self.parent.OnSubText(self.getcorpus(), parametres = {'frommeta' : True})
562     
563     def OnSubTextFromTheme(self, evt):
564         self.parent.OnSubText(self.getcorpus(), parametres = {'fromtheme' : True})    
565
566     def OnProfSR(self, evt) :
567         ProfileSegment(self.parent, self.page.dictpathout, self.page.parametres, self.page.corpus)
568
569     def OnProfGram(self, evt) :
570         ProfilType(self.parent, self.page.corpus, self.page.parametres)
571
572     def OnExportCorpus(self, evt) :
573         dial = PrefExport(self, self.parent)
574         dial.fbb.SetValue(os.path.join(os.path.dirname(self.page.dictpathout['ira']), 'export_corpus.txt'))
575         dial.CenterOnParent()
576         res = dial.ShowModal()
577         if res == wx.ID_OK :
578             if dial.radio_type.GetSelection() == 0 : alc = True
579             else : alc = False
580             if dial.radio_lem.GetSelection() == 0 : lem = True
581             else : lem = False
582             if self.page.parametres['classif_mode'] != 2 :
583                 uci = False
584             else :
585                 uci = True
586             self.page.corpus.export_corpus_classes(dial.fbb.GetValue(), alc = alc, lem = lem, uci = uci)
587             msg = u"Fini !"
588             dial.Destroy()
589             dlg = wx.MessageDialog(self.parent, msg, u"Export", wx.OK | wx.NO_DEFAULT | wx.ICON_INFORMATION)
590             dlg.CenterOnParent()
591             dlg.ShowModal()
592             dlg.Destroy()
593
594     def OnColored(self, evt) :
595         dial = PrefSimpleFile(self, self.parent, **{'mask' : '*.html', 'title': _(u"Colored corpus").decode('utf8')})
596         dial.fbb.SetValue(os.path.join(os.path.dirname(self.page.dictpathout['ira']), 'corpus_couleur.html'))
597         dial.CenterOnParent()
598         res = dial.ShowModal()
599         if res == wx.ID_OK :
600             fileout = dial.fbb.GetValue()
601             dial.Destroy()
602             if self.page.parametres['classif_mode'] != 2 :
603                 uci = False
604             else :
605                 uci = True
606             txt = self.page.corpus.make_colored_corpus(uci = uci)
607             with open(fileout, 'w') as f :
608                 f.write(txt)
609             msg = ' !\n'.join([_(u"Done").decode('utf8'), _(u"Open in a web browser ?").decode('utf8')])
610             dlg = wx.MessageDialog(self.parent, msg, u"Corpus en couleur", wx.NO | wx.YES | wx.NO_DEFAULT | wx.ICON_QUESTION)
611             dlg.CenterOnParent()
612             if dlg.ShowModal() == wx.ID_YES :
613                 webbrowser.open(fileout)
614             dlg.Destroy()
615
616     def OnNavig(self, evt):
617         if 'FrameSearch' not in dir(self.page) :
618             self.page.FrameSearch = SearchFrame(self.parent, -1, _(u"Search ...").decode('utf8'), self.page.corpus)
619         self.page.FrameSearch.Show()
620
621     def StatClasse(self, evt):
622         dial = PrefSimpleFile(self, self.parent, **{'mask' : '*.csv', 'title': _(u"Clusters statistics").decode('utf8')})
623         dial.fbb.SetValue( os.path.join(os.path.dirname(self.page.dictpathout['ira']), 'stat_par_classe.csv'))
624         dial.CenterOnParent()
625         res = dial.ShowModal()
626         if res == wx.ID_OK :
627             fileout = dial.fbb.GetValue()
628             dial.Destroy()
629             self.page.corpus.get_stat_by_cluster(fileout)
630             msg = u"Fini !"
631             dlg = wx.MessageDialog(self.parent, msg, _(u"Clusters statistics").decode('utf8'), wx.OK | wx.NO_DEFAULT | wx.ICON_INFORMATION)
632             dlg.CenterOnParent()
633             if dlg.ShowModal() == wx.ID_OK :
634                 dlg.Destroy()        
635
636     def OpenAntipro(self, evt) :
637         find = False
638         for i in range(0, self.page.TabChdSim.GetPageCount()) :
639             page = self.page.TabChdSim.GetPage(i)
640             if self.page.TabChdSim.GetPageText(i) == _(u"Antiprofiles").decode('utf8') :
641                 self.page.TabChdSim.SetSelection(i)
642                 find = True
643                 break
644         if not find :
645             open_antiprofil(self.page, self.page.dictpathout['ANTIPRO_OUT'], self.parent.syscoding)
646             self.page.TabChdSim.SetSelection(self.page.TabChdSim.GetPageCount() - 1)
647
648     def OnRapport(self, evt) :
649         dial = PrefSimpleFile(self, self.parent, **{'mask' : '*.txt', 'title': _(u"Report").decode('utf8')})
650         dial.fbb.SetValue(self.page.dictpathout['rapport'])
651         dial.CenterOnParent()
652         res = dial.ShowModal()
653         if res == wx.ID_OK :
654             fileout = dial.fbb.GetValue()
655             dial.Destroy()
656             with open(fileout, 'w') as f :
657                 f.write(self.page.debtext + '\n' + GetTxtProfile(self.page.DictProfile, self.page.cluster_size))
658             msg = u"Fini !"
659             dlg = wx.MessageDialog(self.parent, msg, _(u"Report").decode('utf8'), wx.OK | wx.NO_DEFAULT | wx.ICON_INFORMATION)
660             dlg.CenterOnParent()
661             dlg.ShowModal()
662             dlg.Destroy()
663         else :
664             dial.Destroy()
665
666     def OnExportDictionary(self, evt) :
667         corpus = self.page.corpus
668         corpus.export_dictionary(self.page.pathout['dictionary.csv'], self.parent.syscoding)
669         log.info('export dictionary %s' % self.page.pathout['dictionary.csv'])
670         dial = wx.MessageDialog(self.parent, self.page.pathout['dictionary.csv'], 'Export', wx.OK)
671         dial.ShowModal()
672         dial.Destroy()
673         
674     def OnExportLems(self, evt) :
675         corpus = self.page.corpus
676         corpus.export_lems(self.page.pathout['lemmes.csv'], self.parent.syscoding)
677         log.info('export lemmes %s' % self.page.pathout['lemmes.csv'])
678         dial = wx.MessageDialog(self.parent, self.page.pathout['lemmes.csv'], 'Export', wx.OK)
679         dial.ShowModal()
680         dial.Destroy()
681     
682     def OnTgenEditor(self, evt):
683         corpus = self.page.corpus
684         tgenpath = os.path.join(self.page.parametres['pathout'], 'tgen.csv')
685         tgen = TGen(path = tgenpath, encoding = self.parent.syscoding)
686         if os.path.exists(tgenpath) :
687             tgen.read(tgenpath)
688         if isinstance(evt, list) :
689             i = 0
690             while 'tgen%i' %i in tgen.tgen :
691                 i += 1
692             tgenname = 'tgen%i' %i
693             tgen.tgen[tgenname] = evt
694         tgenframe = TGenFrame(self.parent, corpus, tgen)
695         tgenframe.Show()
696         if isinstance(evt, list) :
697             tgenframe.OnNewTgen(None, tgen = tgenname)
698     
699     def OnTgenCompute(self, evt):
700         corpus = self.page.corpus
701         tgenpath = os.path.join(self.page.parametres['pathout'], 'tgen.csv')        
702         if not os.path.exists(tgenpath) :
703             message = wx.MessageDialog(self.parent, _(u"No TGen yet !"), style = wx.ICON_EXCLAMATION | wx.OK) 
704             message.ShowModal()
705             message.Destroy()
706         else :
707             self.page.parametres['tgenpath'] = tgenpath
708             tgen = TGen(path = tgenpath, encoding = self.parent.syscoding)
709             self.page.parametres['etoiles'] = self.page.etoiles
710             TgenSpec(self.parent, corpus, self.page.parametres)
711             TgenLayout(self.page)
712     
713     def OnExportClasses(self, event):
714         corpus = self.page.corpus
715         if self.page.parametres['classif_mode'] != 2 :
716             uci = False
717         else :
718             uci = True
719         busy = wx.BusyInfo(_("Please wait...").decode('utf8'), self.parent)
720         wx.SafeYield()
721         for i in range(1, self.page.parametres['clnb'] + 1) :
722             corpus.export_classe(self.page.pathout['classe_%i_export.txt' % i], i, uci = uci)
723         del busy
724         dial = wx.MessageDialog(self, self.page.pathout['classe_x_export.txt'], u"Export", wx.OK|wx.ICON_INFORMATION)
725         dial.ShowModal()
726         dial.Destroy()
727     
728     def OnSubCorpusFromClusters(self, evt):
729         self.parent.OnSubText(self.getcorpus(), parametres = {'fromclusters' : True, 'clnb': self.page.parametres['clnb'], 'lc' : self.page.corpus.lc})
730     
731     def OnRename(self, event):
732         pydata = self.itemdict['pydata']
733         print pydata
734
735     def OnItemBackground(self, event):
736
737         colourdata = wx.ColourData()
738         colourdata.SetColour(self.itemdict["back"])
739         dlg = wx.ColourDialog(self, colourdata)
740         
741         dlg.GetColourData().SetChooseFull(True)
742
743         if dlg.ShowModal() == wx.ID_OK:
744             data = dlg.GetColourData()
745             col1 = data.GetColour().Get()
746             self.SetItemBackgroundColour(self.current, col1)
747         dlg.Destroy()
748
749
750     def OnItemForeground(self, event):
751
752         colourdata = wx.ColourData()
753         colourdata.SetColour(self.itemdict["fore"])
754         dlg = wx.ColourDialog(self, colourdata)
755         
756         dlg.GetColourData().SetChooseFull(True)
757
758         if dlg.ShowModal() == wx.ID_OK:
759             data = dlg.GetColourData()
760             col1 = data.GetColour().Get()
761             self.SetItemTextColour(self.current, col1)
762         dlg.Destroy()
763
764
765     def OnItemBold(self, event):
766
767         self.SetItemBold(self.current, not self.itemdict["isbold"])
768
769
770     def OnItemFont(self, event):
771
772         data = wx.FontData()
773         font = self.itemdict["font"]
774         
775         if font is None:
776             font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
777             
778         data.SetInitialFont(font)
779
780         dlg = wx.FontDialog(self, data)
781         
782         if dlg.ShowModal() == wx.ID_OK:
783             data = dlg.GetFontData()
784             font = data.GetChosenFont()
785             self.SetItemFont(self.current, font)
786
787         dlg.Destroy()
788         
789
790     def OnItemHyperText(self, event):
791
792         self.SetItemHyperText(self.current, not self.itemdict["ishtml"])
793
794
795     def OnEnableWindow(self, event):
796
797         enable = self.GetItemWindowEnabled(self.current)
798         self.SetItemWindowEnabled(self.current, not enable)
799
800
801     def OnDisableItem(self, event):
802
803         self.EnableItem(self.current, False)
804         
805
806     def OnItemIcons(self, event):
807
808         bitmaps = [self.itemdict["normal"], self.itemdict["selected"],
809                    self.itemdict["expanded"], self.itemdict["selexp"]]
810
811         wx.BeginBusyCursor()        
812         dlg = TreeIcons(self, -1, bitmaps=bitmaps)
813         wx.EndBusyCursor()
814         dlg.ShowModal()
815
816
817     def SetNewIcons(self, bitmaps):
818
819         self.SetItemImage(self.current, bitmaps[0], CT.TreeItemIcon_Normal)
820         self.SetItemImage(self.current, bitmaps[1], CT.TreeItemIcon_Selected)
821         self.SetItemImage(self.current, bitmaps[2], CT.TreeItemIcon_Expanded)
822         self.SetItemImage(self.current, bitmaps[3], CT.TreeItemIcon_SelectedExpanded)
823
824
825     def OnItemInfo(self, event):
826
827         itemtext = self.itemdict["text"]
828         numchildren = str(self.itemdict["children"])
829         itemtype = self.itemdict["itemtype"]
830         pydata = self.itemdict['pydata']
831         #if 'analyses' in pydata :
832         #    toshow = dict([[val, pydata[val]] for val in pydata if val not in['analyses', 'isload']])
833         #else :
834         toshow = pydata['ira']
835         toshow = DoConf(toshow).getoptions()
836         txt = DoConf().totext(toshow)
837         parametres = [val.split('\t\t:') for val in txt.splitlines()]
838         parametres.sort()
839
840         if itemtype == 0:
841             itemtype = "Normal"
842         elif itemtype == 1:
843             itemtype = "CheckBox"
844         else:
845             itemtype = "RadioButton"
846
847         dlg = InfoDialog(self, itemtext, parametres)
848         dlg.CenterOnParent()
849         dlg.ShowModal()
850         dlg.Destroy()
851                 
852         
853
854     def OnItemDelete(self, event):
855
856         strs = "Are You Sure You Want To Delete Item " + self.GetItemText(self.current) + "?"
857         dlg = wx.MessageDialog(None, strs, 'Deleting Item', wx.OK | wx.CANCEL | wx.ICON_QUESTION)
858
859         if dlg.ShowModal() in [wx.ID_NO, wx.ID_CANCEL]:
860             dlg.Destroy()
861             return
862
863         dlg.Destroy()
864         
865         pydata = self.itemdict['pydata']
866         if 'corpus_name' in pydata :
867             self.history.delete(pydata, True)
868         else :
869             self.history.delete(pydata)
870         self.DeleteChildren(self.current)
871         self.Delete(self.current)
872         self.current = None
873         
874
875
876     def OnItemPrepend(self, event):
877
878         dlg = wx.TextEntryDialog(self, "Please Enter The New Item Name", 'Item Naming', 'Python')
879
880         if dlg.ShowModal() == wx.ID_OK:
881             newname = dlg.GetValue()
882             newitem = self.PrependItem(self.current, newname)
883             self.EnsureVisible(newitem)
884
885         dlg.Destroy()
886
887     def AddAnalyse(self, parametres, itemParent = None, bold = True) :
888         uuid = parametres.get('corpus', None)
889         if uuid is not None :
890             if itemParent is None :
891                 itemParent = self.textroot
892             child, cookie = self.GetFirstChild(itemParent)
893             corpus = None
894             while child :
895                 pydata = self.GetPyData(child)
896                 if pydata['uuid'] == uuid :
897                     corpus = child
898                     break
899                 self.GiveFocus(child, uuid)
900                 child, cookie = self.GetNextChild(itemParent, cookie)
901             #item = self.AppendItem(child, parametres['name'])
902             if corpus is not None : 
903                 item = self.AppendItem(corpus, parametres['name'])
904             else :
905                 item = self.AppendItem(self.textroot, parametres['name'])
906         else :
907             item = self.AppendItem(self.matroot, parametres['name'])
908         self.SetPyData(item, parametres)
909         if parametres['type'] in self.ild :
910             img = self.ild[parametres['type']]
911         else :
912             img = 24
913         self.SetItemImage(item, img, CT.TreeItemIcon_Normal)
914         self.SetItemImage(item, 13, CT.TreeItemIcon_Expanded)
915         self.SetItemBold(item, bold)
916         self.SelectItem(item)
917     
918     def AddMatAnalyse(self, parametres, itemParent = None, bold = True) :
919         uuid = parametres.get('matrix', None)
920         if uuid is not None :
921             if itemParent is None :
922                 itemParent = self.matroot
923             child, cookie = self.GetFirstChild(itemParent)
924             matrix = None
925             while child :
926                 pydata = self.GetPyData(child)
927                 if pydata['uuid'] == uuid :
928                     matrix = child
929                     break
930                 self.GiveFocus(child, uuid)
931                 child, cookie = self.GetNextChild(itemParent, cookie)
932             #item = self.AppendItem(child, parametres['name'])
933             if matrix is not None : 
934                 item = self.AppendItem(matrix, parametres['name'])
935             else :
936                 item = self.AppendItem(self.matroot, parametres['name'])
937         self.SetPyData(item, parametres)
938         if parametres['type'] in self.ild :
939             img = self.ild[parametres['type']]
940         else :
941             img = 24
942         self.SetItemImage(item, img, CT.TreeItemIcon_Normal)
943         self.SetItemImage(item, 13, CT.TreeItemIcon_Expanded)
944         self.SetItemBold(item, bold)
945         self.SelectItem(item)  
946         
947     def OnItemAppend(self, item):
948         if 'corpus_name' in item :
949             child = self.InsertItem(self.textroot, 0, item['corpus_name'])
950         else :
951             child = self.InsertItem(self.matroot, 0, item['matrix_name'])
952         self.SetPyData(child, item)
953         self.history.addtab(item)
954         if item['type'] in self.ild :
955             img = self.ild[item['type']]
956         else :
957             img = 24
958         self.SetItemImage(child, img, CT.TreeItemIcon_Normal)
959         self.SetItemImage(child, img, CT.TreeItemIcon_Expanded)
960         self.SetItemBold(child, True)
961         
962         #dlg = wx.TextEntryDialog(self, "Please Enter The New Item Name", 'Item Naming', 'Python')
963
964         #if dlg.ShowModal() == wx.ID_OK:
965         #    newname = dlg.GetValue()
966         #    newitem = self.AppendItem(self.current, newname)
967         #    self.EnsureVisible(newitem)
968         
969
970         #dlg.Destroy()
971         
972
973     def OnBeginEdit(self, event):
974         
975         #self.log.info("OnBeginEdit" + "\n")
976         # show how to prevent edit...
977         item = event.GetItem()
978         if item and self.GetItemText(item) == "The Root Item":
979             wx.Bell()
980             #self.log.info("You can't edit this one..." + "\n")
981
982             # Lets just see what's visible of its children
983             cookie = 0
984             root = event.GetItem()
985             (child, cookie) = self.GetFirstChild(root)
986
987             while child:
988                 #self.log.info("Child [%s] visible = %d" % (self.GetItemText(child), self.IsVisible(child)) + "\n")
989                 (child, cookie) = self.GetNextChild(root, cookie)
990
991             event.Veto()
992
993
994     def OnEndEdit(self, event):
995         
996         #self.log.info("OnEndEdit: %s %s" %(event.IsEditCancelled(), event.GetLabel()))
997         # show how to reject edit, we'll not allow any digits
998         for x in event.GetLabel():
999             if x in string.digits:
1000                 #self.log.info(", You can't enter digits..." + "\n")
1001                 event.Veto()
1002                 return
1003             
1004         self.log.info("\n")
1005
1006
1007     def OnLeftDClick(self, event):
1008         pt = event.GetPosition()
1009         item, flags = self.HitTest(pt)
1010         if item is not None :
1011             pydata = self.GetPyData(item)
1012             if pydata['uuid'] in self.parent.history.opened :
1013                 for i in range(self.parent.nb.GetPageCount()) :
1014                     page = self.parent.nb.GetPage(i)
1015                     if 'parametres' in dir(page) :
1016                         if page.parametres['uuid'] == pydata['uuid'] :
1017                             self.parent.nb.SetSelection(i)
1018                             break
1019             elif pydata['uuid'] in ['textroot', 'matroot'] :
1020                 pass
1021             else :
1022                 busy = wx.BusyInfo(_("Please wait..."), self.parent)
1023                 wx.SafeYield()
1024                 OpenAnalyse(self.parent, pydata)
1025                 del busy
1026                 self.SetItemBold(item, True)
1027                 self.OnSelChanged(pydata = pydata)
1028         #if item and (flags & CT.TREE_HITTEST_ONITEMLABEL):
1029         #    if self.GetAGWWindowStyleFlag() & CT.TR_EDIT_LABELS:
1030         #        self.log.info("OnLeftDClick: %s (manually starting label edit)"% self.GetItemText(item) + "\n")
1031                 
1032                 #self.EditLabel(item)
1033         #    else:
1034         #        pydata = self.GetPyData(item)
1035         #        print pydata
1036         #        self.log.info("OnLeftDClick: Cannot Start Manual Editing, Missing Style TR_EDIT_LABELS\n")
1037
1038         event.Skip()                
1039         
1040
1041     def OnItemExpanded(self, event):
1042         
1043         item = event.GetItem()
1044         if item:
1045             self.log.info("OnItemExpanded: %s" % self.GetItemText(item) + "\n")
1046
1047
1048     def OnItemExpanding(self, event):
1049         
1050         item = event.GetItem()
1051         if item:
1052             self.log.info("OnItemExpanding: %s" % self.GetItemText(item) + "\n")
1053             
1054         event.Skip()
1055
1056         
1057     def OnItemCollapsed(self, event):
1058
1059         item = event.GetItem()
1060         if item:
1061             self.log.info("OnItemCollapsed: %s" % self.GetItemText(item) + "\n")
1062             
1063
1064     def OnItemCollapsing(self, event):
1065
1066         item = event.GetItem()
1067         if item:
1068             self.log.info("OnItemCollapsing: %s" % self.GetItemText(item) + "\n")
1069     
1070         event.Skip()
1071
1072         
1073     def OnSelChanged(self, event = None, pydata = None):
1074         if event is not None :
1075             item = event.GetItem()
1076             pydata = self.GetPyData(item)
1077         if pydata is not None :
1078             self.pydata = pydata
1079             if pydata['uuid'] in self.parent.history.opened :
1080                 for i in range(self.parent.nb.GetPageCount()) :
1081                     self.page = self.parent.nb.GetPage(i)
1082                     if 'parametres' in dir(self.page) :
1083                         if self.page.parametres['uuid'] == pydata['uuid'] :
1084                             self.parent.nb.SetSelection(i)
1085                             break
1086         if event is not None :
1087             event.Skip()
1088
1089
1090     def OnSelChanging(self, event):
1091
1092         item = event.GetItem()
1093         olditem = event.GetOldItem()
1094         
1095         if item:
1096             if not olditem:
1097                 olditemtext = "None"
1098             else:
1099                 olditemtext = self.GetItemText(olditem)
1100             #self.log.info("OnSelChanging: From %s" % olditemtext + " To %s" % self.GetItemText(item) + "\n")
1101                 
1102         event.Skip()
1103
1104
1105     def OnBeginDrag(self, event):
1106
1107         self.item = event.GetItem()
1108         if self.item:
1109             self.log.info("Beginning Drag..." + "\n")
1110
1111             event.Allow()
1112
1113
1114     def OnBeginRDrag(self, event):
1115
1116         self.item = event.GetItem()
1117         if self.item:
1118             self.log.info("Beginning Right Drag..." + "\n")
1119
1120             event.Allow()
1121         
1122
1123     def OnEndDrag(self, event):
1124
1125         self.item = event.GetItem()
1126         if self.item:
1127             self.log.info("Ending Drag!" + "\n")
1128
1129         event.Skip()            
1130
1131
1132     def OnDeleteItem(self, event):
1133
1134         item = event.GetItem()
1135
1136         if not item:
1137             return
1138
1139         self.log.info("Deleting Item: %s" % self.GetItemText(item) + "\n")
1140         event.Skip()
1141         
1142
1143     def OnItemCheck(self, event):
1144
1145         item = event.GetItem()
1146         self.log.info("Item " + self.GetItemText(item) + " Has Been Checked!\n")
1147         event.Skip()
1148
1149
1150     def OnItemChecking(self, event):
1151
1152         item = event.GetItem()
1153         self.log.info("Item " + self.GetItemText(item) + " Is Being Checked...\n")
1154         event.Skip()
1155         
1156
1157     def OnToolTip(self, event):
1158
1159         item = event.GetItem()
1160         if item:
1161             event.SetToolTip(wx.ToolTip(self.GetItemText(item)))
1162
1163
1164     def OnItemMenu(self, event):
1165
1166         item = event.GetItem()
1167         if item:
1168             self.log.info("OnItemMenu: %s" % self.GetItemText(item) + "\n")
1169     
1170         event.Skip()
1171
1172
1173     def OnKey(self, event):
1174
1175         keycode = event.GetKeyCode()
1176         keyname = keyMap.get(keycode, None)
1177                 
1178         if keycode == wx.WXK_BACK:
1179             self.log.info("OnKeyDown: HAHAHAHA! I Vetoed Your Backspace! HAHAHAHA\n")
1180             return
1181
1182         if keyname is None:
1183             if "unicode" in wx.PlatformInfo:
1184                 keycode = event.GetUnicodeKey()
1185                 if keycode <= 127:
1186                     keycode = event.GetKeyCode()
1187                 keyname = "\"" + unichr(event.GetUnicodeKey()) + "\""
1188                 if keycode < 27:
1189                     keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
1190                 
1191             elif keycode < 256:
1192                 if keycode == 0:
1193                     keyname = "NUL"
1194                 elif keycode < 27:
1195                     keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
1196                 else:
1197                     keyname = "\"%s\"" % chr(keycode)
1198             else:
1199                 keyname = "unknown (%s)" % keycode
1200                 
1201         self.log.info("OnKeyDown: You Pressed '" + keyname + "'\n")
1202
1203         event.Skip()
1204         
1205         
1206     def OnActivate(self, event):
1207         
1208         if self.item:
1209             self.log.info("OnActivate: %s" % self.GetItemText(self.item) + "\n")
1210
1211         event.Skip()
1212
1213         
1214     def OnHyperLink(self, event):
1215
1216         item = event.GetItem()
1217         if item:
1218             self.log.info("OnHyperLink: %s" % self.GetItemText(self.item) + "\n")
1219             
1220
1221     def OnTextCtrl(self, event):
1222
1223         char = chr(event.GetKeyCode())
1224         self.log.info("EDITING THE TEXTCTRL: You Wrote '" + char + \
1225                        "' (KeyCode = " + str(event.GetKeyCode()) + ")\n")
1226         event.Skip()
1227
1228
1229     def OnComboBox(self, event):
1230
1231         selection = event.GetEventObject().GetValue()
1232         self.log.info("CHOICE FROM COMBOBOX: You Chose '" + selection + "'\n")
1233         event.Skip()