Changeset 1497 for branch/logging
- Timestamp:
- Sep 16, 2014 2:28:31 PM (9 years ago)
- Location:
- branch/logging
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
branch/logging/GSASII.py
r1477 r1497 123 123 '''Define the main GSAS-II frame and its associated menu items 124 124 ''' 125 def MenuBinding(self,event): 126 import log 127 log.InvokeMenuCommand(event.GetId(),self,event) 128 129 def Bind(self,eventtype,handler,*args,**kwargs): 130 '''Override the Bind() function so that we can wrap calls that will be logged. 131 ''' 132 import log 133 #print 'main frame bind',handler 134 if eventtype == wx.EVT_MENU and 'id' in kwargs: 135 menulabels = log.SaveMenuCommand(kwargs['id'],self,handler) 136 if menulabels: 137 #print 'intercepting bind for',handler,menulabels,kwargs['id'] 138 wx.Frame.Bind(self,eventtype,self.MenuBinding,*args,**kwargs) 139 return 140 wx.Frame.Bind(self,eventtype,handler,*args,**kwargs) 141 125 142 126 143 def _Add_FileMenuItems(self, parent): … … 1607 1624 return # success 1608 1625 1626 1627 def _init_Macro(self): 1628 menu = self.MacroMenu 1629 self.MacroRecordStatus = menu.Append( 1630 help='Start or stop recording of menu actions, etc.', id=wx.ID_ANY, 1631 kind=wx.ITEM_NORMAL,text='Record actions') 1632 self.MacroRecordStatus.SetText('Stop recording') # debug, start w/logging enabled 1633 import log 1634 log.LogOn() 1635 def OnMacroRecordStatus(event): 1636 import log 1637 if 'actions' in self.MacroRecordStatus.GetText(): 1638 self.MacroRecordStatus.SetText('Stop recording') 1639 log.LogOn() 1640 else: 1641 self.MacroRecordStatus.SetText('Record actions') 1642 log.LogOff() 1643 self.Bind(wx.EVT_MENU, OnMacroRecordStatus, self.MacroRecordStatus) 1644 1645 item = menu.Append( 1646 help='Show logged commands', id=wx.ID_ANY, 1647 kind=wx.ITEM_NORMAL,text='Show log') 1648 def OnShowLog(event): 1649 import log 1650 print 70*'=' 1651 print 'List of logged actions' 1652 for line in log.G2logList: 1653 if line: print line 1654 print 70*'=' 1655 self.Bind(wx.EVT_MENU, OnShowLog, item) 1656 1657 item = menu.Append( 1658 help='Save logged commands to file', id=wx.ID_ANY, 1659 kind=wx.ITEM_NORMAL,text='Save log') 1660 def OnSaveLog(event): 1661 import log 1662 import cPickle 1663 defnam = os.path.splitext( 1664 os.path.split(self.GSASprojectfile)[1] 1665 )[0]+'.gcmd' 1666 dlg = wx.FileDialog(self, 1667 'Choose an file to save past actions', '.', defnam, 1668 'GSAS-II cmd output (*.gcmd)|*.gcmd', 1669 wx.FD_SAVE|wx.FD_OVERWRITE_PROMPT|wx.CHANGE_DIR) 1670 dlg.CenterOnParent() 1671 try: 1672 if dlg.ShowModal() == wx.ID_OK: 1673 filename = dlg.GetPath() 1674 # make sure extension is correct 1675 filename = os.path.splitext(filename)[0]+'.gcmd' 1676 else: 1677 filename = None 1678 finally: 1679 dlg.Destroy() 1680 if filename: 1681 fp = open(filename,'wb') 1682 fp.write(str(len(log.G2logList))+'\n') 1683 for item in log.G2logList: 1684 cPickle.dump(item,fp) 1685 fp.close() 1686 self.Bind(wx.EVT_MENU, OnSaveLog, item) 1687 1688 item = menu.Append( 1689 help='Load logged commands from file', id=wx.ID_ANY, 1690 kind=wx.ITEM_NORMAL,text='Load log') 1691 def OnLoadLog(event): 1692 import log 1693 import cPickle 1694 defnam = os.path.splitext( 1695 os.path.split(self.GSASprojectfile)[1] 1696 )[0]+'.gcmd' 1697 dlg = wx.FileDialog(self, 1698 'Choose an file to read saved actions', '.', defnam, 1699 'GSAS-II cmd output (*.gcmd)|*.gcmd', 1700 wx.OPEN|wx.CHANGE_DIR) 1701 dlg.CenterOnParent() 1702 try: 1703 if dlg.ShowModal() == wx.ID_OK: 1704 filename = dlg.GetPath() 1705 # make sure extension is correct 1706 filename = os.path.splitext(filename)[0]+'.gcmd' 1707 else: 1708 filename = None 1709 finally: 1710 dlg.Destroy() 1711 if filename and os.path.exists(filename): 1712 fp = open(filename,'rb') 1713 lines = fp.readline() 1714 for i in range(int(lines)): 1715 log.G2logList.append(cPickle.load(fp)) 1716 fp.close() 1717 self.Bind(wx.EVT_MENU, OnLoadLog, item) 1718 1719 item = menu.Append( 1720 help='Replay saved commands', id=wx.ID_ANY, 1721 kind=wx.ITEM_NORMAL,text='Replay log') 1722 self.Bind(wx.EVT_MENU, log.ReplayLog, item) 1723 1609 1724 def _init_Exports(self,menu): 1610 1725 '''Find exporter routines and add them into menus … … 1814 1929 self._init_Exports(self.ExportMenu) 1815 1930 self._Add_ExportMenuItems(self.ExportMenu) 1931 self.MacroMenu = wx.Menu(title='') 1932 menubar.Append(menu=self.MacroMenu, title='Macro') 1933 self._init_Macro() 1816 1934 HelpMenu=G2gd.MyHelp(self,helpType='Data tree', 1817 1935 morehelpitems=[('&Tutorials','Tutorials')]) … … 1838 1956 # 1839 1957 self.GSASIIMenu = wx.MenuBar() 1958 # create a list of all dataframe menus (appended in PrefillDataMenu) 1959 self.dataMenuBars = [self.GSASIIMenu] 1840 1960 self.FillMainMenu(self.GSASIIMenu) 1841 1961 self.SetMenuBar(self.GSASIIMenu) … … 1849 1969 self.PatternTree = log.G2TreeCtrl(id=wxID_PATTERNTREE, 1850 1970 parent=self.mainPanel, pos=wx.Point(0, 0),style=wx.TR_DEFAULT_STYLE ) 1851 self.PatternTree.Bind(wx.EVT_TREE_SEL_CHANGED, 1852 self.OnPatternTreeSelChanged, id=wxID_PATTERNTREE) 1971 self.PatternTree.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnPatternTreeSelChanged) 1853 1972 self.PatternTree.Bind(wx.EVT_TREE_ITEM_COLLAPSED, 1854 1973 self.OnPatternTreeItemCollapsed, id=wxID_PATTERNTREE) -
branch/logging/GSASIIconstrGUI.py
r1417 r1497 1827 1827 1828 1828 G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.RigidBodyMenu) 1829 G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddRigidBody, id=G2gd.wxID_RIGIDBODYADD) 1830 G2frame.dataFrame.Bind(wx.EVT_MENU, OnImportRigidBody, id=G2gd.wxID_RIGIDBODYIMPORT) 1831 G2frame.dataFrame.Bind(wx.EVT_MENU, OnDefineTorsSeq, id=G2gd.wxID_RESIDUETORSSEQ) 1829 G2frame.dataFrame.Bind(wx.EVT_MENU, OnAddRigidBody, id=G2gd.wxID_RIGIDBODYADD) 1830 # no menu items yet 1831 #G2frame.dataFrame.Bind(wx.EVT_MENU, OnImportRigidBody, id=G2gd.wxID_RIGIDBODYIMPORT) 1832 #G2frame.dataFrame.Bind(wx.EVT_MENU, OnDefineTorsSeq, id=G2gd.wxID_RESIDUETORSSEQ) 1832 1833 G2frame.dataDisplay = G2gd.GSNoteBook(parent=G2frame.dataFrame,size=G2frame.dataFrame.GetClientSize()) 1833 1834 -
branch/logging/GSASIIgrid.py
r1477 r1497 152 152 wxID_PDFCOMPUTE, wxID_PDFCOMPUTEALL, wxID_PDFADDELEMENT, wxID_PDFDELELEMENT, 153 153 ] = [wx.NewId() for item in range(7)] 154 155 [ wxID_MCRON,wxID_MCRLIST,wxID_MCRSAVE,wxID_MCRPLAY, 156 ] = [wx.NewId() for item in range(4)] 154 157 155 158 VERY_LIGHT_GREY = wx.Colour(235,235,235) … … 2662 2665 where the functions to be called are defined. 2663 2666 ''' 2664 def Bind(self, *args,**kwargs):2667 def Bind(self,eventtype,handler,*args,**kwargs): 2665 2668 '''Override the Bind() function: on the Mac the binding is to 2666 2669 the main window, so that menus operate with any window on top. 2667 For other platforms, call the default wx.Frame Bind() 2670 For other platforms, either wrap calls that will be logged 2671 or call the default wx.Frame Bind() to bind to the menu item directly. 2668 2672 ''' 2669 2673 if sys.platform == "darwin": # mac 2670 self.G2frame.Bind(*args,**kwargs) 2671 else: 2672 wx.Frame.Bind(self,*args,**kwargs) 2674 self.G2frame.Bind(eventtype,handler,*args,**kwargs) 2675 return 2676 #print 'DataFrame Bind',eventtype,handler 2677 if eventtype == wx.EVT_MENU and 'id' in kwargs: 2678 menulabels = log.SaveMenuCommand(kwargs['id'],self.G2frame,handler) 2679 if menulabels: 2680 #print 'intercepting bind for',handler,menulabels,kwargs['id'] 2681 wx.Frame.Bind(self,eventtype,self.G2frame.MenuBinding,*args,**kwargs) 2682 return 2683 wx.Frame.Bind(self,eventtype,handler,*args,**kwargs) 2673 2684 2674 2685 def PrefillDataMenu(self,menu,helpType,helpLbl=None,empty=False): … … 2678 2689 ''' 2679 2690 self.datamenu = menu 2691 self.G2frame.dataMenuBars.append(menu) 2680 2692 self.helpType = helpType 2681 2693 self.helpLbl = helpLbl … … 3415 3427 wx.aui.AUI_NB_SCROLL_BUTTONS) 3416 3428 if size: self.SetSize(size) 3429 self.parent = parent 3430 self.PageChangeHandler = None 3431 # Note, if needed create a Logging event to paint the window with the initial tab setting here 3432 3433 def PageChangeEvent(self,event): 3434 import log 3435 G2frame = self.parent.G2frame 3436 page = event.GetSelection() 3437 if self.PageChangeHandler: 3438 if log.LogInfo['Logging']: 3439 log.G2logList.append(log.TabLogEntry( 3440 G2frame.dataFrame.GetTitle(), 3441 G2frame.dataDisplay.GetPageText(page) 3442 )) 3443 self.PageChangeHandler(event) 3444 3445 def Bind(self,eventtype,handler,*args,**kwargs): 3446 '''Override the Bind() function so that page change events can be trapped 3447 ''' 3448 if eventtype == wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED: 3449 self.PageChangeHandler = handler 3450 wx.aui.AuiNotebook.Bind(self,eventtype,self.PageChangeEvent) 3451 return 3452 wx.aui.AuiNotebook.Bind(self,eventtype,handler,*args,**kwargs) 3453 3454 3417 3455 3418 3456 def Clear(self): -
branch/logging/GSASIIphsGUI.py
r1477 r1497 3134 3134 shModels = ['cylindrical','none','shear - 2/m','rolling - mmm'] 3135 3135 SamSym = dict(zip(shModels,['0','-1','2/m','mmm'])) 3136 if generalData['doPawley'] and G2gd.GetPatternTreeItemId(G2frame,G2frame.root,'Sequential results'):3137 G2frame.dataFrame.RefineTexture.Enable(True)3138 3136 shAngles = ['omega','chi','phi'] 3139 3137 if Texture.GetSizer(): … … 5261 5259 5262 5260 def ChangePage(page): 5263 # in development: Log Tab Selection5264 import log5265 log.LogTabPress(G2frame,page)5266 5261 text = G2frame.dataDisplay.GetPageText(page) 5267 # print 'Select',page,text5268 5262 if text == 'General': 5269 5263 G2gd.SetDataMenuBar(G2frame,G2frame.dataFrame.DataGeneral) -
branch/logging/log.py
r1477 r1497 1 1 'Module to provide logging services' 2 2 import wx 3 G2loggingData = {} 3 import GSASIIgrid as G2gd 4 MenuBindingLookup = {} 4 5 G2logList = [None] 6 'Contains a list of logged actions; first item is ignored' 7 LogInfo = {'Logging':False, 'Tree':None} 8 'Contains a dict with values that are needed in the module' 9 10 debug = True 11 12 # TODO: 13 ### Note: no provinance info for histogram instrument parameters: need to remove insVal etc. 14 15 # track histograms and phases with relative indices 16 17 #=========================================================================== 18 # objects for logging variables 19 def _l2s(lst,separator='+'): 20 'Combine a list of objects into a string, with a separator' 21 s = '' 22 for i in lst: 23 if s != '': s += separator 24 s += '"'+str(i)+'"' 25 return s 5 26 6 27 class VarLogEntry(object): 28 'object that tracks changes to a variable' 7 29 def __init__(self,treeRefs,indexRefs,value): 8 30 self.treeRefs = treeRefs 9 31 self.indexRefs = indexRefs 10 32 self.value = value 11 12 def LogVarChange(result,key): 13 if hasattr(result,'treeRefs'): 14 lastLog = G2logList[-1] 15 fullrefs = result.indexRefs+[key] 16 if type(lastLog) is VarLogEntry: 17 if lastLog.treeRefs == result.treeRefs and lastLog.indexRefs == fullrefs: 18 lastLog.value = result[key] 19 print 'update last to ',result[key] 20 return 21 G2logList.append(VarLogEntry(result.treeRefs,fullrefs,result[key])) 22 print 'treeRefs',result.treeRefs,'indexRefs',fullrefs,'new value=',result[key] 23 else: 24 print key,'no provenance' 25 26 class G2TreeCtrl(wx.TreeCtrl): 27 '''Create a wrapper around the standard TreeCtrl so we can "trap" 28 various events''' 29 def __init__(self,parent=None,*args,**kwargs): 30 super(self.__class__,self).__init__(parent=parent,*args,**kwargs) 31 G2loggingData['frame'] = parent.GetParent() 32 G2loggingData['tree'] = self 33 G2loggingData['root'] = self.root = self.AddRoot('Loaded Data: ') 34 35 def GetItemPyData(self,*args,**kwargs): 36 data = super(self.__class__,self).GetItemPyData(*args,**kwargs) 37 item = args[0] 38 textlist = [self.GetItemText(item)] 39 parent = self.GetItemParent(item) 40 while parent: 41 if parent == G2loggingData['root']: break 42 textlist.insert(0,self.GetItemText(parent)) 43 parent = self.GetItemParent(parent) 44 #print 'GetItemPyData from ',textlist, 45 #data._treeorigin = textlist 46 #print type(data) 47 if type(data) is dict: 48 #print 'dict' 49 return dictLogged(data,textlist) 50 #return data 51 if type(data) is list: 52 #print 'list' 53 return listLogged(data,textlist) 54 if type(data) is tuple: 55 return listLogged(list(data),textlist) 56 #print 'other' 57 return data 58 59 # class loggedDict(object): 60 # def __init__(self,dictobj,treeRefs,indexRefs=[]): 61 # self.treeRefs = treeRefs 62 # self.indexRefs = indexRefs 63 # self.obj = dictobj 64 65 # def __getitem__(self,*args,**kwargs): 66 # print 'getitem',args,kwargs,'...', 67 # val = self.obj.__getitem__(*args,**kwargs) 68 # # if type(val) is dict and len(args) == 1: 69 # # print 'dict' 70 # # return loggedDict(val,self.treeRefs,self.indexRefs+[args[0]]) 71 # # elif type(val) is list and len(args) == 1: 72 # # print 'list' 73 # # return loggedList(val,self.treeRefs,self.indexRefs+[args[0]]) 74 # # else: 75 # # print type(val),val 76 # # return val 77 # return val 78 # def get(self,*args,**kwargs): 79 # print 'get',args,kwargs 80 # val = self.obj.get(*args,**kwargs) 81 # if val is None: return None 82 # return self.__getitem__(*args,**kwargs) 83 # def __setitem__(self,*args,**kwargs): 84 # self.obj.__setitem__(*args,**kwargs) 85 86 87 # def __repr__(self): 88 # return "loggedDict with "+str(len(self.obj))+" members; from "+str(self.treeRefs)+" indexed by "+str(self.indexRefs) 89 90 # def __str__(self): 91 # return str(self.obj) 92 93 # def clear(self,*args,**kwargs): 94 # return self.obj.clear(*args,**kwargs) 95 # def copy(self,*args,**kwargs): 96 # return self.obj.copy(*args,**kwargs) 97 # def fromkeys(self,*args,**kwargs): 98 # return self.obj.fromkey(*args,**kwargs) 99 # def has_key(self,*args,**kwargs): 100 # return self.obj.has_key(*args,**kwargs) 101 # def items(self,*args,**kwargs): 102 # return self.obj.items(*args,**kwargs) 103 # def iteritems(self,*args,**kwargs): 104 # return self.obj.iteritems(*args,**kwargs) 105 # def iterkeys(self,*args,**kwargs): 106 # return self.obj.iterkeys(*args,**kwargs) 107 # def itervalues(self,*args,**kwargs): 108 # return self.obj.itervalues(*args,**kwargs) 109 # def keys(self,*args,**kwargs): 110 # return self.obj.keys(*args,**kwargs) 111 # def pop(self,*args,**kwargs): 112 # return self.obj.pop(*args,**kwargs) 113 # def popitem(self,*args,**kwargs): 114 # return self.obj.popitem(*args,**kwargs) 115 # def setdefault(self,*args,**kwargs): 116 # return self.obj.setdefault(*args,**kwargs) 117 # def update(self,*args,**kwargs): 118 # return self.obj.update(*args,**kwargs) 119 # def values(self,*args,**kwargs): 120 # return self.obj.values(*args,**kwargs) 121 # def viewitems(self,*args,**kwargs): 122 # return self.obj.viewitems(*args,**kwargs) 123 # def viewkeys(self,*args,**kwargs): 124 # return self.obj.viewkeys(*args,**kwargs) 125 # def viewvalues(self,*args,**kwargs): 126 # return self.obj.viewvalues(*args,**kwargs) 127 128 129 130 # class loggedList(object): 131 # def __init__(self,listobj,treeRefs,indexRefs=[]): 132 # self.treeRefs = treeRefs 133 # self.indexRefs = indexRefs 134 # self.obj = listobj 135 136 # def __getitem__(self,*args,**kwargs): 137 # print 'list getitem',args,kwargs,'...', 138 # val = self.obj.__getitem__(*args,**kwargs) 139 # # if type(val) is dict and len(args) == 1: 140 # # print 'dict' 141 # # return loggedDict(val,self.treeRefs,self.indexRefs+[args[0]]) 142 # # elif type(val) is list and len(args) == 1: 143 # # print 'list' 144 # # return loggedList(val,self.treeRefs,self.indexRefs+[args[0]]) 145 # # else: 146 # # print type(val),val 147 # # return val 148 # return val 149 150 # def __len__(self,*args,**kwargs): 151 # return self.obj.__len__(*args,**kwargs) 152 153 # def __setitem__(self,*args,**kwargs): 154 # return self.obj.__setitem__(*args,**kwargs) 155 156 # def __repr__(self): 157 # return "loggedList with "+str(len(self.obj))+" members; from "+str(self.treeRefs)+" indexed by "+str(self.indexRefs) 158 159 # def __str__(self): 160 # return str(self.obj) 161 162 ############### 33 if debug: print 'Logging var change: w/treeRefs',treeRefs,'indexRefs',indexRefs,'new value=',value 34 def __str__(self): 35 return 'Variable change: Key(s)= '+_l2s(self.indexRefs)+' to value='+str(self.value) 36 37 class MenuLogEntry(object): 38 'object that tracks when a menu command is executed' 39 def __init__(self,menulabellist): 40 self.menulabellist = menulabellist 41 if debug: 42 t = menulabellist[:] 43 t.reverse() 44 l = '' 45 for item in t: 46 if l: l += ' -> ' 47 l += item 48 if debug: print 'Logging menu command: '+l 49 def __str__(self): 50 return 'Menu press: From '+_l2s(self.menulabellist,'/') 51 52 class TabLogEntry(object): 53 'Object to track when tabs are pressed in the DataFrame window' 54 def __init__(self,title,tabname): 55 self.wintitle = title 56 self.tablabel = tabname 57 if debug: print 'Logging tab: "'+tabname+'" on window titled '+title 58 def __str__(self): 59 return 'Tab press: Tab='+_l2s([self.tablabel])+' on window labeled '+str(self.wintitle) 60 61 class TreeLogEntry(object): 62 'Object to track when tree items are pressed in the main window' 63 def __init__(self,itemlist): 64 self.treeItemList = itemlist 65 if debug: print 'Logging press on tree: "',itemlist 66 def __str__(self): 67 return 'Tree item pressed: '+_l2s(self.treeItemList) 68 163 69 def _wrapper(func): 164 70 def _wrapped(self, *args, **kwargs): … … 175 81 176 82 class dictLogged(object): 83 '''A version of a dict object that tracks the source of the 84 object back to the location on the G2 tree. 85 If a list (tuple) or dict are pulled from inside this object 86 the source information is appended to the provinance tracking 87 lists. 88 89 tuples are converted to lists. 90 ''' 177 91 __metaclass__ = DictMeta 178 92 … … 183 97 184 98 def __getitem__(self,key): 185 #print "logging", key,186 99 val = self.obj.__getitem__(key) 187 100 if type(val) is tuple: 188 print 'Converting to list',key101 #if debug: print 'Converting to list',key 189 102 val = list(val) 190 103 self.obj[key] = val … … 195 108 #print 'list' 196 109 return listLogged(val,self.treeRefs,self.indexRefs+[key]) 197 elif type(val) is tuple:198 print type(val),val199 raise Exception200 return val201 110 else: 202 111 #print type(val) 203 112 return val 204 # return val205 113 206 114 def __str__(self): … … 216 124 217 125 class listLogged(object): 126 '''A version of a list object that tracks the source of the 127 object back to the location on the G2 tree. 128 If a list (tuple) or dict are pulled from inside this object 129 the source information is appended to the provinance tracking 130 lists. 131 132 tuples are converted to lists. 133 ''' 218 134 __metaclass__ = ListMeta 219 135 … … 224 140 225 141 def __getitem__(self,key): 226 #print "logging", key,227 142 val = self.obj.__getitem__(key) 228 143 if type(val) is tuple: 229 print 'Converting to list',key,144 #if debug: print 'Converting to list',key 230 145 val = list(val) 231 146 self.obj[key] = val … … 236 151 #print 'list' 237 152 return listLogged(val,self.treeRefs,self.indexRefs+[key]) 238 elif type(val) is tuple:239 print type(val),val240 raise Exception241 153 else: 242 154 #print type(val) 243 155 return val 244 return self.obj.__getitem__(key)245 156 246 157 def __str__(self): 247 158 return self.obj.__str__() + " : " + str(self.treeRefs) + ',' + str(self.indexRefs) 248 ############### 249 250 251 def SimTreeEvent(treekeylist): 252 # lookup key from list of items 253 parent = G2loggingData['root'] 254 for txt in treekeylist: 255 item = GetPatternTreeItemId(G2loggingData['frame'],parent,txt) 256 if not item: 257 print 'Not found',txt 159 160 #=========================================================================== 161 class G2TreeCtrl(wx.TreeCtrl): 162 '''Create a wrapper around the standard TreeCtrl so we can "wrap" 163 various events. 164 165 This logs when a tree item is selected (in :meth:`onSelectionChanged`) 166 167 This also wraps lists and dicts pulled out of the tree to track where 168 they were retrieved from. 169 ''' 170 def __init__(self,parent=None,*args,**kwargs): 171 super(self.__class__,self).__init__(parent=parent,*args,**kwargs) 172 self.G2frame = parent.GetParent() 173 self.root = self.AddRoot('Loaded Data: ') 174 self.SelectionChanged = None 175 self.repaintAction = None 176 LogInfo['Tree'] = self 177 178 def _getTreeItemsList(self,item): 179 '''Get the full tree hierarchy from a reference to a tree item. 180 Note that this effectively hard-codes phase and histogram names in the 181 returned list. We may want to make these names relative in the future. 182 ''' 183 textlist = [self.GetItemText(item)] 184 parent = self.GetItemParent(item) 185 while parent: 186 if parent == self.root: break 187 textlist.insert(0,self.GetItemText(parent)) 188 parent = self.GetItemParent(parent) 189 return textlist 190 191 def onSelectionChanged(self,event): 192 '''Log each press on a tree item here. 193 ''' 194 if self.SelectionChanged: 195 textlist = self._getTreeItemsList(event.GetItem()) 196 if LogInfo['Logging']: 197 G2logList.append(TreeLogEntry(textlist)) 198 self.SelectionChanged(event) 199 200 def Bind(self,eventtype,handler,*args,**kwargs): 201 '''Override the Bind() function so that page change events can be trapped 202 ''' 203 if eventtype == wx.EVT_TREE_SEL_CHANGED: 204 self.SelectionChanged = handler 205 wx.TreeCtrl.Bind(self,eventtype,self.onSelectionChanged) 258 206 return 259 else: 260 parent = item 207 wx.TreeCtrl.Bind(self,eventtype,handler,*args,**kwargs) 208 209 def GetItemPyData(self,*args,**kwargs): 210 '''Override the standard method to wrap the contents 211 so that the source can be tracked 212 ''' 213 data = super(self.__class__,self).GetItemPyData(*args,**kwargs) 214 textlist = self._getTreeItemsList(args[0]) 215 if type(data) is dict: 216 return dictLogged(data,textlist) 217 if type(data) is list: 218 return listLogged(data,textlist) 219 if type(data) is tuple: #N.B. tuples get converted to lists 220 return listLogged(list(data),textlist) 221 return data 222 223 def ClearDataRepaint(self): 224 self.repaintAction = None 225 226 def RepaintDataWindow(self): 227 item = self.repaintAction 228 if isinstance(item,TreeLogEntry): 229 self.SelectItem(self.root) # need to select something else 230 self.ReplayTreePress(item) 231 elif isinstance(item,TabLogEntry): 232 self.ReplayTabPress(item) 233 234 def ReplayLogItem(self,item): 235 'Execute an action taken from a log file entry' 236 if isinstance(item,MenuLogEntry): 237 self.ReplayMenuCommand(item) 238 elif isinstance(item,TreeLogEntry): 239 self.ReplayTreePress(item) 240 self.repaintAction = item 241 elif isinstance(item,VarLogEntry): 242 self.ReplayVariableChange(item) 243 elif isinstance(item,TabLogEntry): 244 self.ReplayTabPress(item) 245 self.repaintAction = item 246 else: 247 raise Exception("Unknown object in log: "+str(type(item))+": " 248 +str(item)) 249 250 def ReplayTreePress(self,logitem): 251 'Perform a Tree press action when read from the log' 252 parent = self.root 253 for txt in logitem.treeItemList: 254 item = G2gd.GetPatternTreeItemId(self.G2frame,parent,txt) 255 if not item: 256 print 'Not found',txt 257 return 258 else: 259 parent = item 260 else: 261 self.SelectItem(item) 262 263 def ReplayTabPress(self,logitem): 264 'Perform a Tab press action when read from the log' 265 wintitle = logitem.wintitle 266 tabname = logitem.tablabel 267 if self.G2frame.dataFrame.GetTitle() != wintitle: 268 print self.G2frame.dataFrame.GetTitle(),' != ',wintitle 269 raise Exception('tab in wrong window') 270 for PageNum in range(self.G2frame.dataDisplay.GetPageCount()): 271 if tabname == self.G2frame.dataDisplay.GetPageText(PageNum): 272 self.G2frame.dataDisplay.SetSelection(PageNum) 273 return 274 else: 275 print tabname,'not in',[ 276 self.G2frame.dataDisplay.GetPageText(PageNum) for 277 PageNum in range(self.G2frame.dataDisplay.GetPageCount())] 278 raise Exception('tab not found') 279 def ReplayVariableChange(self,logitem): 280 'Perform a Variable Change action, when read from the log' 281 parentId = self.root 282 for treeitem in logitem.treeRefs: 283 item, cookie = self.GetFirstChild(parentId) 284 while item: 285 if self.GetItemText(item) == treeitem: 286 parentId = item 287 break 288 else: 289 item, cookie = self.GetNextChild(parentId, cookie) 290 else: 291 raise Exception("Tree item not found for "+str(logitem)) 292 # get the inner most data array 293 data = super(self.__class__,self).GetItemPyData(item) 294 for item in logitem.indexRefs[:-1]: 295 data = data[item] 296 # set the value 297 data[logitem.indexRefs[-1]] = logitem.value 298 def ReplayMenuCommand(self,logitem): 299 'Perform a Menu item action when read from the log' 300 key = '' 301 for item in logitem.menulabellist: 302 if key: key += '+' 303 key += item 304 if MenuBindingLookup.get(key): 305 MenuBindingLookup[key](None) 306 else: 307 raise Exception('No binding for menu item '+key) 308 309 #=========================================================================== 310 # variable tracking 311 def LogVarChange(result,key): 312 'Called when a variable is changed to log that action' 313 if not LogInfo['Logging']: return 314 if hasattr(result,'treeRefs'): 315 lastLog = G2logList[-1] 316 fullrefs = result.indexRefs+[key] 317 if type(lastLog) is VarLogEntry: 318 if lastLog.treeRefs == result.treeRefs and lastLog.indexRefs == fullrefs: 319 lastLog.value = result[key] 320 if debug: print 'update last log to ',result[key] 321 return 322 G2logList.append(VarLogEntry(result.treeRefs,fullrefs,result[key])) 261 323 else: 262 print 'found',G2loggingData['tree'].GetItemText(item) 263 print item 264 #code = wx.EVT_TREE_SEL_CHANGED.typeId 265 #clickEvent = wx.TreeEvent(code, G2loggingData['tree'].GetId()) 266 #print clickEvent 267 #clickEvent.SetItem(item) 268 #G2loggingData['tree'].GetEventHandler().ProcessEvent(clickEvent) 269 G2loggingData['tree'].SelectItem(item) 270 def SimTabPress(wintitle,tabname): 271 if G2loggingData['frame'].dataFrame.GetTitle() != wintitle: 272 print G2loggingData['frame'].dataFrame.GetTitle(),' != ','Phase Data for CuCr2O4' 273 raise Exception('tab in wrong window') 274 for PageNum in range(G2loggingData['frame'].dataDisplay.GetPageCount()): 275 if tabname == G2loggingData['frame'].dataDisplay.GetPageText(PageNum): 276 G2loggingData['frame'].dataDisplay.SetSelection(PageNum) 324 print key,'Error: var change has no provenance info' 325 326 #=========================================================================== 327 # menu command tracking 328 def _getmenuinfo(id,G2frame,handler): 329 '''Look up the menu/menu-item label tree from a menuitem's Id 330 331 Note that menubars contain multiple menus which contain multiple menuitems. 332 A menuitem can itself point to a menu and if so that menu can contain 333 multiple menuitems. 334 335 Here we start with the last menuitem and look up the label for that as well 336 as all parents, which will be found in parent menuitems (if any) and the menubar. 337 338 menuitem -> menu -> menubar 339 | | 340 |->itemlabel |-> menulabel 341 342 or 343 344 menuitem -> (submenu -> menuitem)*(n times) -> menu -> menubar 345 | | | 346 |->itemlabel |-> sublabel(s) |-> menulabel 347 348 :returns: a list containing all the labels (or None) 349 ''' 350 # don't worry about help menuitems 351 if id == wx.ID_ABOUT: return 352 # get the menu item object by searching through all menubars and then its label 353 for menubar in G2frame.dataMenuBars: 354 menuitem = menubar.FindItemById(id) 355 if menuitem: 356 #print 'getmenuinfo found',id,menuitem 357 break 358 else: 359 print '****** getmenuinfo failed for id=',id,'binding to=',handler 360 #raise Exception('debug: getmenuinfo failed') 361 return 362 menuLabelList = [menuitem.GetItemLabel()] 363 364 # get the menu where the current item is located 365 menu = menuitem.GetMenu() 366 while menu.GetParent(): # is this menu a submenu of a previous menu? 367 parentmenu = menu.GetParent() 368 # cycle through the parentmenu until we find the menu 369 for i in range(parentmenu.GetMenuItemCount()): 370 if parentmenu.FindItemByPosition(i).GetSubMenu()==menu: 371 menuLabelList += [parentmenu.FindItemByPosition(i).GetItemLabel()] 372 break 373 else: 374 # menu not found in menu, something is wrong 375 print 'error tracing menuitem to parent menu',menuLabelList 376 #raise Exception('debug1: error tracing menuitem') 277 377 return 378 menu = parentmenu 379 380 menubar = menu.MenuBar 381 for i in range(menubar.GetMenuCount()): 382 if menubar.GetMenu(i) == menu: 383 menuLabelList += [menubar.GetMenuLabel(i)] 384 break 278 385 else: 279 print tabname,'not in',[ 280 G2loggingData['frame'].dataDisplay.GetPageText(PageNum) for 281 PageNum in range(G2loggingData['frame'].dataDisplay.GetPageCount())] 282 raise Exception('tab not found') 283 def LogTabPress(G2frame,page): 284 print 'Log page tab' 285 print G2frame.dataFrame.GetTitle() 286 print G2frame.dataDisplay.GetPageText(page) 287 386 # menu not found in menubar, something is wrong 387 print 'error tracing menuitem to menubar',menuLabelList 388 #raise Exception('debug2: error tracing menuitem') 389 return 390 return menuLabelList 391 392 def SaveMenuCommand(id,G2frame,handler): 393 '''Creates a table of menu items and their pseudo-bindings 394 ''' 395 menuLabelList = _getmenuinfo(id,G2frame,handler) 396 if not menuLabelList: return 397 key = '' 398 for item in menuLabelList: 399 if key: key += '+' 400 key += item 401 MenuBindingLookup[key] = handler 402 return menuLabelList 403 404 def InvokeMenuCommand(id,G2frame,event): 405 '''Called when a menu item is used to log the action as well as call the 406 routine "bind"ed to that menu item 407 ''' 408 menuLabelList = _getmenuinfo(id,G2frame,None) 409 key = '' 410 if menuLabelList: 411 for item in menuLabelList: 412 if key: key += '+' 413 key += item 414 if key in MenuBindingLookup: 415 if LogInfo['Logging']: 416 G2logList.append(MenuLogEntry(menuLabelList)) 417 MenuBindingLookup[key](event) 418 else: 419 print 'Error no binding for menu command',menuLabelList,'id=',id 420 return 421 422 #=========================================================================== 423 # Misc externally callable routines 424 def LogOn(): 425 'Turn On logging of actions' 426 LogInfo['Logging'] = True 427 428 def LogOff(): 429 'Turn Off logging of actions' 430 LogInfo['Logging'] = False 431 432 def ShowLogStatus(): 433 'Return the logging status' 434 return LogInfo['Logging'] 435 436 def ReplayLog(event): 437 'replay the logged actions (needs to be a wx.widget)' 438 LogOff() # TODO: need to update menu item as well 439 LogInfo['Tree'].ClearDataRepaint() 440 print 70*'=' 441 print 'Performing logged actions:' 442 for item in G2logList: 443 if item: 444 print item 445 LogInfo['Tree'].ReplayLogItem(item) 446 wx.Yield() 447 # do repaint here 448 LogInfo['Tree'].RepaintDataWindow() 449 print 70*'=' 450 451 452
Note: See TracChangeset
for help on using the changeset viewer.