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