1 # -*- coding: utf-8 -*-
2 #Author: Pierre Ratinaud
3 #Copyright (c) 2012, Pierre Ratinaud
9 import wx.lib.agw.customtreectrl as CT
11 from openanalyse import OpenAnalyse
12 from corpus import Corpus, copycorpus
13 from tableau import Tableau, copymatrix
14 from functions import DoConf, GetTxtProfile, TGen
15 from profile_segment import ProfileSegment, ProfilType
16 from search_tools import SearchFrame
17 from dialog import PrefSimpleFile, PrefExport
18 from layout import open_antiprofil, TgenLayout
19 from guifunct import TGenFrame
20 from textaslexico import TgenSpec
22 log = logging.getLogger('iramuteq.tree')
24 class InfoDialog ( wx.Dialog ):
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 :
32 self.SetSizeHintsSz( wx.Size( 500,200 ), wx.DefaultSize )
34 bSizer1 = wx.BoxSizer( wx.VERTICAL )
36 self.m_panel2 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
37 bSizer2 = wx.BoxSizer( wx.VERTICAL )
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 )
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 )
49 self.m_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
51 fgSizer1 = wx.FlexGridSizer( 0, nb, 0, 0 )
52 fgSizer1.SetFlexibleDirection( wx.BOTH )
53 fgSizer1.SetNonFlexibleGrowMode( wx.FLEX_GROWMODE_SPECIFIED )
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)
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 )
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();
76 bSizer1.Add( m_sdbSizer1, 0, wx.EXPAND, 5 )
79 self.SetSizer( bSizer1 )
83 self.Centre( wx.BOTH )
89 class LeftTree(CT.CustomTreeCtrl):
91 def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
93 style=wx.SUNKEN_BORDER|wx.WANTS_CHARS,
94 agwStyle=CT.TR_HIDE_ROOT|CT.TR_HAS_BUTTONS|CT.TR_HAS_VARIABLE_ROW_HEIGHT):
96 CT.CustomTreeCtrl.__init__(self, parent, id, pos, size, style, agwStyle)
102 if data.startswith("TR_"):
103 treestyles.append(data)
104 elif data.startswith("EVT_"):
108 self.styles = treestyles
111 self.il = wx.ImageList(16, 16)
113 imgtextroot = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'textroot.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
114 self.ild['alceste'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'reinert.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
115 self.ild['corpus'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'textcorpus.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
116 self.ild['wordcloud'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'wordcloud.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
117 self.ild['stat'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'stats.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
118 self.ild['simitxt'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'simitxt.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
119 self.ild['clustersimitxt'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'clustersimitxt.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
120 self.ild['clustercloud'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'clustercloud.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
121 self.ild['spec'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'spec.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
122 imgmatroot = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'matroot.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
123 self.ild['matrix'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'matrix.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
124 self.ild['freq'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'frequences.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
125 self.ild['chi2'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'chi2.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
126 self.ild['reinertmatrix'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'reinertmatrix.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
127 self.ild['simimatrix'] = self.il.Add(wx.Image(os.path.join(self.parent.images_path,'simimatrix.png'), wx.BITMAP_TYPE_PNG).Scale(16,16).ConvertToBitmap())
128 self.SetImageList(self.il)
133 self.history = parent.history
134 self.h = self.history.history
135 self.root = self.AddRoot("Iramuteq")
137 if not(self.GetAGWWindowStyleFlag() & CT.TR_HIDE_ROOT):
138 self.SetPyData(self.root, None)
139 self.SetItemImage(self.root, 24, CT.TreeItemIcon_Normal)
140 self.SetItemImage(self.root, 13, CT.TreeItemIcon_Expanded)
142 self.textroot = self.AppendItem(self.root, u'Corpus texte')
143 self.SetPyData(self.textroot, {'uuid': 'textroot'})
144 self.SetItemImage(self.textroot, imgtextroot, CT.TreeItemIcon_Normal)
145 self.SetItemImage(self.textroot, imgtextroot, CT.TreeItemIcon_Expanded)
147 for corpus in reversed(self.h) :
148 child = self.AppendItem(self.textroot, corpus['corpus_name'])
149 self.SetPyData(child, corpus)
150 self.SetItemImage(child, self.ild['corpus'], CT.TreeItemIcon_Normal)
151 self.SetItemImage(child, self.ild['corpus'], CT.TreeItemIcon_Expanded)
153 if 'analyses' in corpus :
154 for y in corpus['analyses'] :
155 last = self.AppendItem(child, y['name'], ct_type=0)
156 self.SetPyData(last, y)
157 if y['type'] in self.ild :
158 img = self.ild[y['type']]
161 self.SetItemImage(last, img, CT.TreeItemIcon_Normal)
162 self.SetItemImage(last, img, CT.TreeItemIcon_Expanded)
164 self.matroot = self.AppendItem(self.root, u'Matrices')
165 self.SetPyData(self.matroot, {'uuid': 'matroot'})
166 self.SetItemImage(self.matroot, imgmatroot, CT.TreeItemIcon_Normal)
167 self.SetItemImage(self.matroot, imgmatroot, CT.TreeItemIcon_Expanded)
170 for matrix in reversed(self.history.matrix) :
171 if 'matrix_name' in matrix :
172 child = self.AppendItem(self.matroot, matrix['matrix_name'])
173 self.SetPyData(child, matrix)
174 self.SetItemImage(child, self.ild['matrix'], CT.TreeItemIcon_Normal)
175 self.SetItemImage(child, self.ild['matrix'], CT.TreeItemIcon_Expanded)
176 if 'analyses' in matrix :
177 for y in matrix['analyses'] :
178 last = self.AppendItem(child, y['name'], ct_type=0)
179 self.SetPyData(last, y)
180 if y['type'] in self.ild :
181 img = self.ild[y['type']]
184 self.SetItemImage(last, img, CT.TreeItemIcon_Normal)
185 self.SetItemImage(last, img, CT.TreeItemIcon_Expanded)
187 orphmat.append(matrix)
189 self.Bind(wx.EVT_LEFT_DCLICK, self.OnLeftDClick)
190 #self.Bind(wx.EVT_IDLE, self.OnIdle)
192 self.eventdict = {'EVT_TREE_BEGIN_DRAG': self.OnBeginDrag, 'EVT_TREE_BEGIN_LABEL_EDIT': self.OnBeginEdit,
193 'EVT_TREE_BEGIN_RDRAG': self.OnBeginRDrag, 'EVT_TREE_DELETE_ITEM': self.OnDeleteItem,
194 'EVT_TREE_END_DRAG': self.OnEndDrag, 'EVT_TREE_END_LABEL_EDIT': self.OnEndEdit,
195 'EVT_TREE_ITEM_ACTIVATED': self.OnActivate, 'EVT_TREE_ITEM_CHECKED': self.OnItemCheck,
196 'EVT_TREE_ITEM_CHECKING': self.OnItemChecking, 'EVT_TREE_ITEM_COLLAPSED': self.OnItemCollapsed,
197 'EVT_TREE_ITEM_COLLAPSING': self.OnItemCollapsing, 'EVT_TREE_ITEM_EXPANDED': self.OnItemExpanded,
198 'EVT_TREE_ITEM_EXPANDING': self.OnItemExpanding, 'EVT_TREE_ITEM_GETTOOLTIP': self.OnToolTip,
199 'EVT_TREE_ITEM_MENU': self.OnItemMenu, 'EVT_TREE_ITEM_RIGHT_CLICK': self.OnRightDown,
200 'EVT_TREE_KEY_DOWN': self.OnKey, 'EVT_TREE_SEL_CHANGED': self.OnSelChanged,
201 'EVT_TREE_SEL_CHANGING': self.OnSelChanging, "EVT_TREE_ITEM_HYPERLINK": self.OnHyperLink}
203 mainframe = wx.GetTopLevelParent(self)
205 if not hasattr(mainframe, "leftpanel"):
206 #self.Bind(CT.EVT_TREE_ITEM_EXPANDED, self.OnItemExpanded)
207 #self.Bind(CT.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed)
208 self.Bind(CT.EVT_TREE_SEL_CHANGED, self.OnSelChanged)
209 self.Bind(CT.EVT_TREE_SEL_CHANGING, self.OnSelChanging)
210 self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
211 self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
213 for combos in mainframe.treeevents:
214 self.BindEvents(combos)
216 if hasattr(mainframe, "leftpanel"):
217 self.ChangeStyle(mainframe.treestyles)
219 if not(self.GetAGWWindowStyleFlag() & CT.TR_HIDE_ROOT):
220 self.SelectItem(self.root)
221 self.Expand(self.root)
224 def BindEvents(self, choice, recreate=False):
226 value = choice.GetValue()
227 text = choice.GetLabel()
230 binder = self.eventdict[text]
233 if evt == "CT.EVT_TREE_BEGIN_RDRAG":
234 self.Bind(wx.EVT_RIGHT_DOWN, None)
235 self.Bind(wx.EVT_RIGHT_UP, None)
236 self.Bind(eval(evt), binder)
238 self.Bind(eval(evt), None)
239 if evt == "CT.EVT_TREE_BEGIN_RDRAG":
240 self.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown)
241 self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
244 def ChangeStyle(self, combos):
248 if combo.GetValue() == 1:
249 style = style | eval("CT." + combo.GetLabel())
251 if self.GetAGWWindowStyleFlag() != style:
252 self.SetAGWWindowStyleFlag(style)
255 def OnCompareItems(self, item1, item2):
257 t1 = self.GetItemText(item1)
258 t2 = self.GetItemText(item2)
269 def OnIdle(self, event):
273 # if self.gauge.IsEnabled() and self.gauge.IsShown():
274 # self.count = self.count + 1
276 # if self.count >= 50:
279 # self.gauge.SetValue(self.count)
287 def CloseItem(self, itemParent = None, uuid = None) :
288 if itemParent is None :
289 itemParent = self.root
290 child, cookie = self.GetFirstChild(itemParent)
292 pydata = self.GetPyData(child)
293 if pydata['uuid'] == uuid :
294 self.SetItemBold(child, False)
296 self.CloseItem(child, uuid)
297 child, cookie = self.GetNextChild(itemParent, cookie)
299 def GiveFocus(self, itemParent = None, uuid = None, bold = False) :
300 if itemParent is None :
301 itemParent = self.root
302 child, cookie = self.GetFirstChild(itemParent)
304 pydata = self.GetPyData(child)
305 if pydata['uuid'] == uuid :
306 self.SelectItem(child)
308 self.SetItemBold(child, True)
310 self.GiveFocus(child, uuid, bold)
311 child, cookie = self.GetNextChild(itemParent, cookie)
313 def IsInTree(self, itemParent = None, uuid = None) :
314 if itemParent is None :
315 itemParent = self.root
316 child, cookie = self.GetFirstChild(itemParent)
319 pydata = self.GetPyData(child)
320 if pydata['uuid'] == uuid :
322 self.GiveFocus(child, uuid)
323 child, cookie = self.GetNextChild(itemParent, cookie)
327 def OnRightDown(self, event):
329 pt = event.GetPosition()
330 item, flags = self.HitTest(pt)
334 #self.log.info("OnRightClick: %s, %s, %s" % (self.GetItemText(item), type(item), item.__class__) + "\n")
335 self.SelectItem(item)
338 def OnRightUp(self, event):
346 if not self.IsItemEnabled(item):
350 # Item Text Appearance
351 ishtml = self.IsItemHyperText(item)
352 back = self.GetItemBackgroundColour(item)
353 fore = self.GetItemTextColour(item)
354 isbold = self.IsBold(item)
355 font = self.GetItemFont(item)
358 normal = self.GetItemImage(item, CT.TreeItemIcon_Normal)
359 selected = self.GetItemImage(item, CT.TreeItemIcon_Selected)
360 expanded = self.GetItemImage(item, CT.TreeItemIcon_Expanded)
361 selexp = self.GetItemImage(item, CT.TreeItemIcon_SelectedExpanded)
363 # Enabling/Disabling Windows Associated To An Item
364 haswin = self.GetItemWindow(item)
366 # Enabling/Disabling Items
367 enabled = self.IsItemEnabled(item)
369 # Generic Item's Info
370 children = self.GetChildrenCount(item)
371 itemtype = self.GetItemType(item)
372 text = self.GetItemText(item)
373 pydata = self.GetPyData(item)
377 self.itemdict = {"ishtml": ishtml, "back": back, "fore": fore, "isbold": isbold,
378 "font": font, "normal": normal, "selected": selected, "expanded": expanded,
379 "selexp": selexp, "haswin": haswin, "children": children,
380 "itemtype": itemtype, "text": text, "pydata": pydata, "enabled": enabled}
382 if not item in [self.textroot, self.matroot] :
384 info = menu.Append(wx.ID_ANY, _(u"Informations").encode('utf8'))
385 rename = menu.Append(wx.ID_ANY, _(u"Rename").encode('utf8'))
386 menu.AppendSeparator()
388 if 'corpus_name' in pydata :
389 stat = menu.Append(wx.ID_ANY, _(u"Statistics").decode('utf8'))
390 spec = menu.Append(wx.ID_ANY, _(u"Specificities and CA").decode('utf8'))
391 classification = wx.Menu()
392 reinert = classification.Append(wx.ID_ANY, _(u"Reinert method").decode('utf8'))
393 #pam = classification.Append(wx.ID_ANY, u"Par matrice des distances")
394 menu.AppendMenu(-1, _(u"Clustering").decode('utf8'), classification)
395 simi = menu.Append(wx.ID_ANY, _(u"Similarities analysis").decode('utf8'))
396 wdc = menu.Append(wx.ID_ANY, _(u"Wordcloud").decode('utf8'))
397 subcorpus = wx.Menu()
398 subcorpusfrommeta = subcorpus.Append(wx.ID_ANY, _(u'Sub corpus from metadata').decode('utf8'))
399 subcorpusfromtheme = subcorpus.Append(wx.ID_ANY, _(u'Sub corpus from thematic').decode('utf8'))
400 menu.AppendMenu(-1, _(u"Sub corpus").decode('utf8'), subcorpus)
401 menu.AppendSeparator()
402 self.Bind(wx.EVT_MENU, self.OnReinert, reinert)
403 #self.Bind(wx.EVT_MENU, self.OnPam, pam)
404 self.Bind(wx.EVT_MENU, self.OnStat, stat)
405 self.Bind(wx.EVT_MENU, self.OnSpec, spec)
406 self.Bind(wx.EVT_MENU, self.OnSimiTxt, simi)
407 self.Bind(wx.EVT_MENU, self.OnWordCloud, wdc)
408 self.Bind(wx.EVT_MENU, self.OnSubTextFromMeta, subcorpusfrommeta)
409 self.Bind(wx.EVT_MENU, self.OnSubTextFromTheme, subcorpusfromtheme)
410 elif 'matrix_name' in pydata :
411 for i in range(self.parent.matrix_menu.GetMenuItemCount()) :
412 item = self.parent.matrix_menu.FindItemByPosition(i)
413 itemid = item.GetId()
414 itemtext = item.GetText()
415 menu.Append(itemid, itemtext)
417 splitfromvar = split.Append(-1, _(u"Split from variable").decode('utf8'))
418 menu.AppendMenu(-1, _(u"Split matrix").decode('utf8'), split)
419 self.Bind(wx.EVT_MENU, self.OnSplitFromVar, splitfromvar)
420 #print item, itemid, itemtext
421 #menu = self.parent.matrix_menu
422 #freq = menu.Append(wx.ID_ANY, _(u"Frequency").decode('utf8'))
423 #chi2 = menu.Append(wx.ID_ANY, _(u"Chi square").decode('utf8'))
424 #chdreinert = menu.Append(wx.ID_ANY, _(u"Reinert clustering").decode('utf8'))
425 #simi = menu.Append(wx.ID_ANY, _(u"Similarity analysis").decode('utf8'))
426 menu.AppendSeparator()
427 #self.Bind(wx.EVT_MENU, self.OnFreq, freq)
428 #self.Bind(wx.EVT_MENU, self.OnChiSquare, chi2)
429 #self.Bind(wx.EVT_MENU, self.OnSimiTab, simi)
430 #self.Bind(wx.EVT_MENU, self.OnCHDReinert, chdreinert)
431 elif pydata.get('type', False) == 'alceste' and pydata['uuid'] in self.parent.history.opened :
433 antipro = openmenu.Append(wx.ID_ANY, _(u"Antiprofiles").decode('utf8'))
434 menu.AppendMenu(wx.ID_ANY, _(u"Open ...").decode('utf8'), openmenu)
436 profsr = menu.Append(wx.ID_ANY, _(u"Repeated segments profiles").decode('utf8'))
437 profgram = menu.Append(wx.ID_ANY, _(u"POS profiles").decode('utf8'))
438 export_corpus = menu.Append(wx.ID_ANY, _(u"Export corpus").decode('utf8'))
439 colored = menu.Append(wx.ID_ANY, _(u"Colored corpus").decode('utf8'))
440 navig = menu.Append(wx.ID_ANY, _(u"Navigator").decode('utf8'))
441 statclasse = menu.Append(wx.ID_ANY, _(u"Clusters statistics").decode('utf8'))
442 rapport = menu.Append(wx.ID_ANY, _(u"Report").decode('utf8'))
443 export_classes = menu.Append(wx.ID_ANY, _(u"Export Clusters").decode('utf8'))
444 menu.AppendSeparator()
445 self.Bind(wx.EVT_MENU, self.OpenAntipro, antipro)
446 self.Bind(wx.EVT_MENU, self.OnProfSR, profsr)
447 self.Bind(wx.EVT_MENU, self.OnProfGram, profgram)
448 self.Bind(wx.EVT_MENU, self.OnExportCorpus, export_corpus)
449 self.Bind(wx.EVT_MENU, self.OnColored, colored)
450 self.Bind(wx.EVT_MENU, self.OnNavig, navig)
451 self.Bind(wx.EVT_MENU, self.StatClasse, statclasse)
452 self.Bind(wx.EVT_MENU, self.OnRapport, rapport)
453 self.Bind(wx.EVT_MENU, self.OnExportClasses, export_classes)
454 elif pydata.get('type', False) == 'stat' and pydata['uuid'] in self.parent.history.opened :
455 export_dictionary = menu.Append(wx.ID_ANY, _(u"Export dictionary").decode('utf8'))
456 export_lems = menu.Append(wx.ID_ANY, _(u"Export lemma dictionary").decode('utf8'))
457 self.Bind(wx.EVT_MENU, self.OnExportDictionary, export_dictionary)
458 self.Bind(wx.EVT_MENU, self.OnExportLems, export_lems)
459 menu.AppendSeparator()
460 elif pydata.get('type', False) == 'spec' and pydata['uuid'] in self.parent.history.opened :
461 tgen = menu.Append(wx.ID_ANY, _(u"Tgen Editor").decode('utf8'))
462 computetgen = menu.Append(wx.ID_ANY, _(u"Compute Tgen").decode('utf8'))
463 self.Bind(wx.EVT_MENU, self.OnTgenEditor, tgen)
464 self.Bind(wx.EVT_MENU, self.OnTgenCompute, computetgen)
465 menu.AppendSeparator()
466 elif pydata.get('type', False) == 'reinertmatrix' and pydata['uuid'] in self.parent.history.opened :
468 antipro = openmenu.Append(wx.ID_ANY, _(u"antiprofiles").decode('utf8'))
469 menu.AppendMenu(wx.ID_ANY, _(u"Open ...").decode('utf8'), openmenu)
470 self.Bind(wx.EVT_MENU, self.OpenAntipro, antipro)
473 itemdelete = menu.Append(wx.ID_ANY, _(u"Delete from history").decode('utf8'))
474 #item11 = menu.Append(wx.ID_ANY, "Prepend An Item")
475 #item12 = menu.Append(wx.ID_ANY, "Append An Item")
477 #self.Bind(wx.EVT_MENU, self.OnItemBackground, item1)
478 #self.Bind(wx.EVT_MENU, self.OnItemForeground, item2)
479 #self.Bind(wx.EVT_MENU, self.OnItemBold, item3)
480 #self.Bind(wx.EVT_MENU, self.OnItemFont, item4)
481 #self.Bind(wx.EVT_MENU, self.OnItemHyperText, item5)
482 #self.Bind(wx.EVT_MENU, self.OnEnableWindow, item6)
483 #self.Bind(wx.EVT_MENU, self.OnDisableItem, item7)
484 #self.Bind(wx.EVT_MENU, self.OnItemIcons, item8)
485 self.Bind(wx.EVT_MENU, self.OnItemInfo, info)
486 self.Bind(wx.EVT_MENU, self.OnRename, rename)
487 self.Bind(wx.EVT_MENU, self.OnItemDelete, itemdelete)
488 #self.Bind(wx.EVT_MENU, self.OnItemPrepend, item11)
489 #self.Bind(wx.EVT_MENU, self.OnItemAppend, item12)
495 busy = wx.BusyInfo(_("Please wait...Reading corpus").decode('utf8'), self.parent)
497 if self.pydata['uuid'] in self.parent.history.openedcorpus :
498 corpus = copycorpus(self.parent.history.openedcorpus[self.pydata['uuid']])
499 elif 'corpus_name' in self.pydata :
500 corpus = Corpus(self.parent, parametres = DoConf(self.pydata['ira']).getoptions('corpus'), read = True)
502 cuuid = self.pydata['corpus']
503 if cuuid in self.parent.history.openedcorpus :
504 corpus = copycorpus(self.parent.history.openedcorpus[cuuid])
506 irapath = self.parent.history.corpus[cuuid]['ira']
507 corpus = Corpus(self.parent, parametres = DoConf(irapath).getoptions('corpus'), read = True)
512 if 'matrix_name' in self.pydata :
513 matrix = Tableau(self.parent, parametres = DoConf(self.pydata['ira']).getoptions('matrix'))
515 return copymatrix(matrix)
517 cuuid = self.pydata['matrix']
518 matrix = Tableau(self.parent, parametres = DoConf(self.history.matrixanalyse[cuuid]['ira']).getoptions('matrix'))
520 return copymatrix(matrix)
522 def OnSpec(self, evt) :
523 self.parent.OnTextSpec(evt, self.getcorpus())
525 def OnStat(self, evt) :
526 self.parent.OnTextStat(evt, self.getcorpus())
528 def OnReinert(self, evt) :
529 self.parent.OnTextReinert(evt, self.getcorpus())
531 def OnPam(self, evt) :
532 self.parent.OnPamSimple(evt, self.getcorpus())
534 def OnSimiTxt(self, evt) :
535 self.parent.OnSimiTxt(evt, self.getcorpus())
537 def OnWordCloud(self, evt) :
538 self.parent.OnWordCloud(evt, self.getcorpus())
540 def OnFreq(self, evt):
541 self.parent.OnFreq(evt, self.getmatrix())
543 def OnChiSquare(self, evt):
544 self.parent.OnChi2(evt, self.getmatrix())
546 def OnSimiTab(self, evt):
547 self.parent.OnSimiTab(evt, self.getmatrix())
549 def OnProto(self, evt):
550 self.parent.OnProto(evt, self.getmatrix())
552 def OnSplitFromVar(self, evt):
553 self.parent.OnSplitVar(evt, self.getmatrix())
555 def OnCHDReinert(self, evt):
556 self.parent.OnCHDReinert(evt, self.getmatrix())
558 def OnSubTextFromMeta(self, evt):
559 self.parent.OnSubText(self.getcorpus(), parametres = {'frommeta' : True})
561 def OnSubTextFromTheme(self, evt):
562 self.parent.OnSubText(self.getcorpus(), parametres = {'fromtheme' : True})
564 def OnProfSR(self, evt) :
565 ProfileSegment(self.parent, self.page.dictpathout, self.page.parametres, self.page.corpus)
567 def OnProfGram(self, evt) :
568 ProfilType(self.parent, self.page.corpus, self.page.parametres)
570 def OnExportCorpus(self, evt) :
571 dial = PrefExport(self, self.parent)
572 dial.fbb.SetValue(os.path.join(os.path.dirname(self.page.dictpathout['ira']), 'export_corpus.txt'))
573 dial.CenterOnParent()
574 res = dial.ShowModal()
576 if dial.radio_type.GetSelection() == 0 : alc = True
578 if dial.radio_lem.GetSelection() == 0 : lem = True
580 if self.page.parametres['classif_mode'] != 2 :
584 self.page.corpus.export_corpus_classes(dial.fbb.GetValue(), alc = alc, lem = lem, uci = uci)
587 dlg = wx.MessageDialog(self.parent, msg, u"Export", wx.OK | wx.NO_DEFAULT | wx.ICON_INFORMATION)
592 def OnColored(self, evt) :
593 dial = PrefSimpleFile(self, self.parent, **{'mask' : '*.html', 'title': _(u"Colored corpus").decode('utf8')})
594 dial.fbb.SetValue(os.path.join(os.path.dirname(self.page.dictpathout['ira']), 'corpus_couleur.html'))
595 dial.CenterOnParent()
596 res = dial.ShowModal()
598 fileout = dial.fbb.GetValue()
600 if self.page.parametres['classif_mode'] != 2 :
604 txt = self.page.corpus.make_colored_corpus(uci = uci)
605 with open(fileout, 'w') as f :
607 msg = ' !\n'.join([_(u"Done").decode('utf8'), _(u"Open in a web browser ?").decode('utf8')])
608 dlg = wx.MessageDialog(self.parent, msg, u"Corpus en couleur", wx.NO | wx.YES | wx.NO_DEFAULT | wx.ICON_QUESTION)
610 if dlg.ShowModal() == wx.ID_YES :
611 webbrowser.open(fileout)
614 def OnNavig(self, evt):
615 if 'FrameSearch' not in dir(self.page) :
616 self.page.FrameSearch = SearchFrame(self.parent, -1, _(u"Search ...").decode('utf8'), self.page.corpus)
617 self.page.FrameSearch.Show()
619 def StatClasse(self, evt):
620 dial = PrefSimpleFile(self, self.parent, **{'mask' : '*.csv', 'title': _(u"Clusters statistics").decode('utf8')})
621 dial.fbb.SetValue( os.path.join(os.path.dirname(self.page.dictpathout['ira']), 'stat_par_classe.csv'))
622 dial.CenterOnParent()
623 res = dial.ShowModal()
625 fileout = dial.fbb.GetValue()
627 self.page.corpus.get_stat_by_cluster(fileout)
629 dlg = wx.MessageDialog(self.parent, msg, _(u"Clusters statistics").decode('utf8'), wx.OK | wx.NO_DEFAULT | wx.ICON_INFORMATION)
631 if dlg.ShowModal() == wx.ID_OK :
634 def OpenAntipro(self, evt) :
636 for i in range(0, self.page.TabChdSim.GetPageCount()) :
637 page = self.page.TabChdSim.GetPage(i)
638 if self.page.TabChdSim.GetPageText(i) == _(u"Antiprofiles").decode('utf8') :
639 self.page.TabChdSim.SetSelection(i)
643 open_antiprofil(self.page, self.page.dictpathout['ANTIPRO_OUT'], self.parent.syscoding)
644 self.page.TabChdSim.SetSelection(self.page.TabChdSim.GetPageCount() - 1)
646 def OnRapport(self, evt) :
647 dial = PrefSimpleFile(self, self.parent, **{'mask' : '*.txt', 'title': _(u"Report").decode('utf8')})
648 dial.fbb.SetValue(self.page.dictpathout['rapport'])
649 dial.CenterOnParent()
650 res = dial.ShowModal()
652 fileout = dial.fbb.GetValue()
654 with open(fileout, 'w') as f :
655 f.write(self.page.debtext + '\n' + GetTxtProfile(self.page.DictProfile, self.page.cluster_size))
657 dlg = wx.MessageDialog(self.parent, msg, _(u"Report").decode('utf8'), wx.OK | wx.NO_DEFAULT | wx.ICON_INFORMATION)
664 def OnExportDictionary(self, evt) :
665 corpus = self.page.corpus
666 corpus.export_dictionary(self.page.pathout['dictionary.csv'], self.parent.syscoding)
667 log.info('export dictionary %s' % self.page.pathout['dictionary.csv'])
668 dial = wx.MessageDialog(self.parent, self.page.pathout['dictionary.csv'], 'Export', wx.OK)
672 def OnExportLems(self, evt) :
673 corpus = self.page.corpus
674 corpus.export_lems(self.page.pathout['lemmes.csv'], self.parent.syscoding)
675 log.info('export lemmes %s' % self.page.pathout['lemmes.csv'])
676 dial = wx.MessageDialog(self.parent, self.page.pathout['lemmes.csv'], 'Export', wx.OK)
680 def OnTgenEditor(self, evt):
681 corpus = self.page.corpus
682 tgenpath = os.path.join(self.page.parametres['pathout'], 'tgen.csv')
683 tgen = TGen(path = tgenpath, encoding = self.parent.syscoding)
684 if os.path.exists(tgenpath) :
686 if isinstance(evt, list) :
688 while 'tgen%i' %i in tgen.tgen :
690 tgenname = 'tgen%i' %i
691 tgen.tgen[tgenname] = evt
692 tgenframe = TGenFrame(self.parent, corpus, tgen)
694 if isinstance(evt, list) :
695 tgenframe.OnNewTgen(None, tgen = tgenname)
697 def OnTgenCompute(self, evt):
698 corpus = self.page.corpus
699 tgenpath = os.path.join(self.page.parametres['pathout'], 'tgen.csv')
700 if not os.path.exists(tgenpath) :
701 message = wx.MessageDialog(self.parent, _(u"No TGen yet !"), style = wx.ICON_EXCLAMATION | wx.OK)
705 self.page.parametres['tgenpath'] = tgenpath
706 tgen = TGen(path = tgenpath, encoding = self.parent.syscoding)
707 self.page.parametres['etoiles'] = self.page.etoiles
708 TgenSpec(self.parent, corpus, self.page.parametres)
709 TgenLayout(self.page)
711 def OnExportClasses(self, event):
712 corpus = self.page.corpus
713 if self.page.parametres['classif_mode'] != 2 :
717 busy = wx.BusyInfo(_("Please wait...").decode('utf8'), self.parent)
719 for i in range(1, self.page.parametres['clnb'] + 1) :
720 corpus.export_classe(self.page.pathout['classe_%i_export.txt' % i], i, uci = uci)
722 dial = wx.MessageDialog(self, self.page.pathout['classe_x_export.txt'], u"Export", wx.OK|wx.ICON_INFORMATION)
726 def OnRename(self, event):
727 pydata = self.itemdict['pydata']
730 def OnItemBackground(self, event):
732 colourdata = wx.ColourData()
733 colourdata.SetColour(self.itemdict["back"])
734 dlg = wx.ColourDialog(self, colourdata)
736 dlg.GetColourData().SetChooseFull(True)
738 if dlg.ShowModal() == wx.ID_OK:
739 data = dlg.GetColourData()
740 col1 = data.GetColour().Get()
741 self.SetItemBackgroundColour(self.current, col1)
745 def OnItemForeground(self, event):
747 colourdata = wx.ColourData()
748 colourdata.SetColour(self.itemdict["fore"])
749 dlg = wx.ColourDialog(self, colourdata)
751 dlg.GetColourData().SetChooseFull(True)
753 if dlg.ShowModal() == wx.ID_OK:
754 data = dlg.GetColourData()
755 col1 = data.GetColour().Get()
756 self.SetItemTextColour(self.current, col1)
760 def OnItemBold(self, event):
762 self.SetItemBold(self.current, not self.itemdict["isbold"])
765 def OnItemFont(self, event):
768 font = self.itemdict["font"]
771 font = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
773 data.SetInitialFont(font)
775 dlg = wx.FontDialog(self, data)
777 if dlg.ShowModal() == wx.ID_OK:
778 data = dlg.GetFontData()
779 font = data.GetChosenFont()
780 self.SetItemFont(self.current, font)
785 def OnItemHyperText(self, event):
787 self.SetItemHyperText(self.current, not self.itemdict["ishtml"])
790 def OnEnableWindow(self, event):
792 enable = self.GetItemWindowEnabled(self.current)
793 self.SetItemWindowEnabled(self.current, not enable)
796 def OnDisableItem(self, event):
798 self.EnableItem(self.current, False)
801 def OnItemIcons(self, event):
803 bitmaps = [self.itemdict["normal"], self.itemdict["selected"],
804 self.itemdict["expanded"], self.itemdict["selexp"]]
807 dlg = TreeIcons(self, -1, bitmaps=bitmaps)
812 def SetNewIcons(self, bitmaps):
814 self.SetItemImage(self.current, bitmaps[0], CT.TreeItemIcon_Normal)
815 self.SetItemImage(self.current, bitmaps[1], CT.TreeItemIcon_Selected)
816 self.SetItemImage(self.current, bitmaps[2], CT.TreeItemIcon_Expanded)
817 self.SetItemImage(self.current, bitmaps[3], CT.TreeItemIcon_SelectedExpanded)
820 def OnItemInfo(self, event):
822 itemtext = self.itemdict["text"]
823 numchildren = str(self.itemdict["children"])
824 itemtype = self.itemdict["itemtype"]
825 pydata = self.itemdict['pydata']
826 #if 'analyses' in pydata :
827 # toshow = dict([[val, pydata[val]] for val in pydata if val not in['analyses', 'isload']])
829 toshow = pydata['ira']
830 toshow = DoConf(toshow).getoptions()
831 txt = DoConf().totext(toshow)
832 parametres = [val.split('\t\t:') for val in txt.splitlines()]
838 itemtype = "CheckBox"
840 itemtype = "RadioButton"
842 dlg = InfoDialog(self, itemtext, parametres)
849 def OnItemDelete(self, event):
851 strs = "Are You Sure You Want To Delete Item " + self.GetItemText(self.current) + "?"
852 dlg = wx.MessageDialog(None, strs, 'Deleting Item', wx.OK | wx.CANCEL | wx.ICON_QUESTION)
854 if dlg.ShowModal() in [wx.ID_NO, wx.ID_CANCEL]:
860 pydata = self.itemdict['pydata']
861 if 'corpus_name' in pydata :
862 self.history.delete(pydata, True)
864 self.history.delete(pydata)
865 self.DeleteChildren(self.current)
866 self.Delete(self.current)
871 def OnItemPrepend(self, event):
873 dlg = wx.TextEntryDialog(self, "Please Enter The New Item Name", 'Item Naming', 'Python')
875 if dlg.ShowModal() == wx.ID_OK:
876 newname = dlg.GetValue()
877 newitem = self.PrependItem(self.current, newname)
878 self.EnsureVisible(newitem)
882 def AddAnalyse(self, parametres, itemParent = None, bold = True) :
883 uuid = parametres.get('corpus', None)
884 if uuid is not None :
885 if itemParent is None :
886 itemParent = self.textroot
887 child, cookie = self.GetFirstChild(itemParent)
890 pydata = self.GetPyData(child)
891 if pydata['uuid'] == uuid :
894 self.GiveFocus(child, uuid)
895 child, cookie = self.GetNextChild(itemParent, cookie)
896 #item = self.AppendItem(child, parametres['name'])
897 if corpus is not None :
898 item = self.AppendItem(corpus, parametres['name'])
900 item = self.AppendItem(self.textroot, parametres['name'])
902 item = self.AppendItem(self.matroot, parametres['name'])
903 self.SetPyData(item, parametres)
904 if parametres['type'] in self.ild :
905 img = self.ild[parametres['type']]
908 self.SetItemImage(item, img, CT.TreeItemIcon_Normal)
909 self.SetItemImage(item, 13, CT.TreeItemIcon_Expanded)
910 self.SetItemBold(item, bold)
911 self.SelectItem(item)
913 def AddMatAnalyse(self, parametres, itemParent = None, bold = True) :
914 uuid = parametres.get('matrix', None)
915 if uuid is not None :
916 if itemParent is None :
917 itemParent = self.matroot
918 child, cookie = self.GetFirstChild(itemParent)
921 pydata = self.GetPyData(child)
922 if pydata['uuid'] == uuid :
925 self.GiveFocus(child, uuid)
926 child, cookie = self.GetNextChild(itemParent, cookie)
927 #item = self.AppendItem(child, parametres['name'])
928 if matrix is not None :
929 item = self.AppendItem(matrix, parametres['name'])
931 item = self.AppendItem(self.matroot, parametres['name'])
932 self.SetPyData(item, parametres)
933 if parametres['type'] in self.ild :
934 img = self.ild[parametres['type']]
937 self.SetItemImage(item, img, CT.TreeItemIcon_Normal)
938 self.SetItemImage(item, 13, CT.TreeItemIcon_Expanded)
939 self.SetItemBold(item, bold)
940 self.SelectItem(item)
942 def OnItemAppend(self, item):
943 if 'corpus_name' in item :
944 child = self.InsertItem(self.textroot, 0, item['corpus_name'])
946 child = self.InsertItem(self.matroot, 0, item['matrix_name'])
947 self.SetPyData(child, item)
948 self.history.addtab(item)
949 if item['type'] in self.ild :
950 img = self.ild[item['type']]
953 self.SetItemImage(child, img, CT.TreeItemIcon_Normal)
954 self.SetItemImage(child, img, CT.TreeItemIcon_Expanded)
955 self.SetItemBold(child, True)
957 #dlg = wx.TextEntryDialog(self, "Please Enter The New Item Name", 'Item Naming', 'Python')
959 #if dlg.ShowModal() == wx.ID_OK:
960 # newname = dlg.GetValue()
961 # newitem = self.AppendItem(self.current, newname)
962 # self.EnsureVisible(newitem)
968 def OnBeginEdit(self, event):
970 #self.log.info("OnBeginEdit" + "\n")
971 # show how to prevent edit...
972 item = event.GetItem()
973 if item and self.GetItemText(item) == "The Root Item":
975 #self.log.info("You can't edit this one..." + "\n")
977 # Lets just see what's visible of its children
979 root = event.GetItem()
980 (child, cookie) = self.GetFirstChild(root)
983 #self.log.info("Child [%s] visible = %d" % (self.GetItemText(child), self.IsVisible(child)) + "\n")
984 (child, cookie) = self.GetNextChild(root, cookie)
989 def OnEndEdit(self, event):
991 #self.log.info("OnEndEdit: %s %s" %(event.IsEditCancelled(), event.GetLabel()))
992 # show how to reject edit, we'll not allow any digits
993 for x in event.GetLabel():
994 if x in string.digits:
995 #self.log.info(", You can't enter digits..." + "\n")
1002 def OnLeftDClick(self, event):
1003 pt = event.GetPosition()
1004 item, flags = self.HitTest(pt)
1005 if item is not None :
1006 pydata = self.GetPyData(item)
1007 if pydata['uuid'] in self.parent.history.opened :
1008 for i in range(self.parent.nb.GetPageCount()) :
1009 page = self.parent.nb.GetPage(i)
1010 if 'parametres' in dir(page) :
1011 if page.parametres['uuid'] == pydata['uuid'] :
1012 self.parent.nb.SetSelection(i)
1014 elif pydata['uuid'] in ['textroot', 'matroot'] :
1017 busy = wx.BusyInfo(_("Please wait..."), self.parent)
1019 OpenAnalyse(self.parent, pydata)
1021 self.SetItemBold(item, True)
1022 self.OnSelChanged(pydata = pydata)
1023 #if item and (flags & CT.TREE_HITTEST_ONITEMLABEL):
1024 # if self.GetAGWWindowStyleFlag() & CT.TR_EDIT_LABELS:
1025 # self.log.info("OnLeftDClick: %s (manually starting label edit)"% self.GetItemText(item) + "\n")
1027 #self.EditLabel(item)
1029 # pydata = self.GetPyData(item)
1031 # self.log.info("OnLeftDClick: Cannot Start Manual Editing, Missing Style TR_EDIT_LABELS\n")
1036 def OnItemExpanded(self, event):
1038 item = event.GetItem()
1040 self.log.info("OnItemExpanded: %s" % self.GetItemText(item) + "\n")
1043 def OnItemExpanding(self, event):
1045 item = event.GetItem()
1047 self.log.info("OnItemExpanding: %s" % self.GetItemText(item) + "\n")
1052 def OnItemCollapsed(self, event):
1054 item = event.GetItem()
1056 self.log.info("OnItemCollapsed: %s" % self.GetItemText(item) + "\n")
1059 def OnItemCollapsing(self, event):
1061 item = event.GetItem()
1063 self.log.info("OnItemCollapsing: %s" % self.GetItemText(item) + "\n")
1068 def OnSelChanged(self, event = None, pydata = None):
1069 if event is not None :
1070 item = event.GetItem()
1071 pydata = self.GetPyData(item)
1072 if pydata is not None :
1073 self.pydata = pydata
1074 if pydata['uuid'] in self.parent.history.opened :
1075 for i in range(self.parent.nb.GetPageCount()) :
1076 self.page = self.parent.nb.GetPage(i)
1077 if 'parametres' in dir(self.page) :
1078 if self.page.parametres['uuid'] == pydata['uuid'] :
1079 self.parent.nb.SetSelection(i)
1081 if event is not None :
1085 def OnSelChanging(self, event):
1087 item = event.GetItem()
1088 olditem = event.GetOldItem()
1092 olditemtext = "None"
1094 olditemtext = self.GetItemText(olditem)
1095 #self.log.info("OnSelChanging: From %s" % olditemtext + " To %s" % self.GetItemText(item) + "\n")
1100 def OnBeginDrag(self, event):
1102 self.item = event.GetItem()
1104 self.log.info("Beginning Drag..." + "\n")
1109 def OnBeginRDrag(self, event):
1111 self.item = event.GetItem()
1113 self.log.info("Beginning Right Drag..." + "\n")
1118 def OnEndDrag(self, event):
1120 self.item = event.GetItem()
1122 self.log.info("Ending Drag!" + "\n")
1127 def OnDeleteItem(self, event):
1129 item = event.GetItem()
1134 self.log.info("Deleting Item: %s" % self.GetItemText(item) + "\n")
1138 def OnItemCheck(self, event):
1140 item = event.GetItem()
1141 self.log.info("Item " + self.GetItemText(item) + " Has Been Checked!\n")
1145 def OnItemChecking(self, event):
1147 item = event.GetItem()
1148 self.log.info("Item " + self.GetItemText(item) + " Is Being Checked...\n")
1152 def OnToolTip(self, event):
1154 item = event.GetItem()
1156 event.SetToolTip(wx.ToolTip(self.GetItemText(item)))
1159 def OnItemMenu(self, event):
1161 item = event.GetItem()
1163 self.log.info("OnItemMenu: %s" % self.GetItemText(item) + "\n")
1168 def OnKey(self, event):
1170 keycode = event.GetKeyCode()
1171 keyname = keyMap.get(keycode, None)
1173 if keycode == wx.WXK_BACK:
1174 self.log.info("OnKeyDown: HAHAHAHA! I Vetoed Your Backspace! HAHAHAHA\n")
1178 if "unicode" in wx.PlatformInfo:
1179 keycode = event.GetUnicodeKey()
1181 keycode = event.GetKeyCode()
1182 keyname = "\"" + unichr(event.GetUnicodeKey()) + "\""
1184 keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
1190 keyname = "Ctrl-%s" % chr(ord('A') + keycode-1)
1192 keyname = "\"%s\"" % chr(keycode)
1194 keyname = "unknown (%s)" % keycode
1196 self.log.info("OnKeyDown: You Pressed '" + keyname + "'\n")
1201 def OnActivate(self, event):
1204 self.log.info("OnActivate: %s" % self.GetItemText(self.item) + "\n")
1209 def OnHyperLink(self, event):
1211 item = event.GetItem()
1213 self.log.info("OnHyperLink: %s" % self.GetItemText(self.item) + "\n")
1216 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")
1224 def OnComboBox(self, event):
1226 selection = event.GetEventObject().GetValue()
1227 self.log.info("CHOICE FROM COMBOBOX: You Chose '" + selection + "'\n")