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