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