summaryrefslogtreecommitdiff
path: root/lib/python2.7/site-packages/wx-3.0-msw/wx/tools/XRCed/presenter.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/wx-3.0-msw/wx/tools/XRCed/presenter.py')
-rw-r--r--lib/python2.7/site-packages/wx-3.0-msw/wx/tools/XRCed/presenter.py738
1 files changed, 738 insertions, 0 deletions
diff --git a/lib/python2.7/site-packages/wx-3.0-msw/wx/tools/XRCed/presenter.py b/lib/python2.7/site-packages/wx-3.0-msw/wx/tools/XRCed/presenter.py
new file mode 100644
index 0000000..9c3ae5f
--- /dev/null
+++ b/lib/python2.7/site-packages/wx-3.0-msw/wx/tools/XRCed/presenter.py
@@ -0,0 +1,738 @@
+# Name: presenter.py
+# Purpose: Presenter part
+# Author: Roman Rolinsky <rolinsky@femagsoft.com>
+# Created: 07.06.2007
+# RCS-ID: $Id: presenter.py 71860 2012-06-25 15:46:16Z ROL $
+
+import os,tempfile,shutil
+from xml.parsers import expat
+import cPickle
+from globals import *
+import view
+from model import Model, MyDocument
+from component import Manager
+import undo
+
+# Presenter class linking model to view objects
+class _Presenter:
+ def init(self):
+ Model.init()
+ self.path = ''
+ # Global modified state
+ self.setModified(False) # sets applied
+ view.frame.Clear()
+ view.tree.Clear()
+ view.tree.SetPyData(view.tree.root, Model.mainNode)
+ view.testWin.Init()
+ g.undoMan.Clear()
+ # Insert/append mode flags
+ self.createSibling = self.insertBefore = False
+ # Select main node attributes
+ self.setData(view.tree.root)
+
+ def loadXML(self, path):
+ Model.loadXML(path)
+ view.tree.Flush()
+ view.tree.SetPyData(view.tree.root, Model.mainNode)
+ self.setData(view.tree.root)
+ if g.conf.expandOnOpen:
+ view.tree.ExpandAll()
+
+ def saveXML(self, path):
+ Model.saveXML(path)
+
+ def open(self, path):
+ if not os.path.exists(path):
+ wx.LogError('File does not exists: %s' % path)
+ raise IOError
+ try:
+ self.path = os.path.abspath(path)
+ TRACE('Loading XML file: %s', self.path)
+ self.loadXML(self.path)
+ # Change dir
+ dir = os.path.dirname(self.path)
+ if dir: os.chdir(dir)
+ self.setModified(False)
+ g.conf.localconf = self.createLocalConf(path)
+ except:
+ logger.exception('error loading XML file')
+ wx.LogError('Error loading XML file: %s' % path)
+ raise
+
+ def save(self, path):
+ # Apply changes if needed
+ if not self.applied:
+ self.update(self.item)
+ try:
+ tmpFile,tmpName = tempfile.mkstemp(prefix='xrced-')
+ os.close(tmpFile)
+ TRACE('Saving temporary file: %s', tmpName)
+ self.saveXML(tmpName)
+ TRACE('copying to the main file: %s', path)
+ shutil.copy(tmpName, path)
+ self.path = path
+ self.setModified(False)
+ except:
+ logger.exception('error saving XML file')
+ wx.LogError('Error saving XML file: %s' % path)
+ raise
+
+ def setModified(self, state=True, setDirty=True):
+ '''Set global modified state.'''
+ TRACE('setModified %s %s', state, setDirty)
+ self.modified = state
+ # Set applied flag
+ if not state: self.applied = True
+ name = os.path.basename(self.path)
+ if not name: name = 'UNTITLED'
+ # Update GUI
+ if state:
+ view.frame.SetTitle(progname + ': ' + name + ' *')
+ # Update test window
+ if view.testWin.IsShown() and setDirty:
+ view.testWin.isDirty = True
+ if g.conf.autoRefresh:
+ self.refreshTestWin()
+ else:
+ view.frame.SetTitle(progname + ': ' + name)
+
+ def setApplied(self, state=True):
+ '''Set panel state.'''
+ TRACE('setApplied %s', state)
+ self.applied = state
+ if not state and not self.modified:
+ self.setModified(setDirty=False) # toggle global state
+
+ def createUndoEdit(self, item=None, page=None):
+ TRACE('createUndoEdit')
+ # Create initial undo object
+ if item is None: item = self.item
+ if page is None: page = view.panel.nb.GetSelection()
+ view.panel.undo = undo.UndoEdit(item, page)
+
+ def registerUndoEdit(self):
+ TRACE('registerUndoEdit')
+ g.undoMan.RegisterUndo(view.panel.undo)
+ view.panel.undo = None
+
+ def panelIsDirty(self):
+ '''Check if the panel was changed since last undo.'''
+ # Register undo
+ if view.panel.undo:
+ panel = view.panel.GetActivePanel()
+ if view.panel.undo.values != panel.GetValues():
+ return True
+ return False
+
+ def setData(self, item):
+ '''Set data and view for current tree item.'''
+
+ self.item = item
+ if item == view.tree.root:
+ TRACE('setData: root node')
+ self.container = None
+ self.comp = Manager.rootComponent
+ self.panels = view.panel.SetData(self.container, self.comp, Model.mainNode)
+ else:
+ node = view.tree.GetPyData(item)
+ if node.nodeType != node.COMMENT_NODE:
+ TRACE('setData: %s', node.getAttribute('class'))
+ self.comp = Manager.getNodeComp(node)
+ parentItem = view.tree.GetItemParent(item)
+ parentNode = view.tree.GetPyData(parentItem)
+ if parentNode == Model.mainNode:
+ self.container = Manager.rootComponent
+ else:
+ parentClass = parentNode.getAttribute('class')
+ self.container = Manager.components[parentClass]
+ self.panels = view.panel.SetData(self.container, self.comp, node)
+ # Create new pending undo
+ self.createUndoEdit(self.item)
+
+ if view.testWin.IsShown():
+ self.highlight(item)
+
+ def highlight(self, item):
+ TRACE('highlight')
+ if view.testWin.IsDirty() or item == view.tree.root or \
+ view.tree.GetPyData(item).nodeType == Model.dom.COMMENT_NODE:
+ view.testWin.RemoveHighlight()
+ return
+ try:
+ rect = view.testWin.FindObjectRect(item)
+ if not rect:
+ view.testWin.RemoveHighlight()
+ return
+ view.testWin.Highlight(rect)
+ except:
+ logger.exception('highlighting failed')
+
+ def updateCreateState(self, forceSibling, forceInsert):
+ if self.container:
+ if self.comp.isContainer():
+ self.createSibling = forceSibling
+ else:
+ self.createSibling = True
+ else:
+ self.createSibling = False
+ self.insertBefore = forceInsert
+ TRACE('updateCreateState: %s %s', self.createSibling, self.insertBefore)
+
+ def popupMenu(self, forceSibling, forceInsert, pos):
+ '''Show popup menu and set sibling/insert flags.'''
+ self.updateCreateState(forceSibling, forceInsert)
+ menu = view.XMLTreeMenu(self.container, self.comp, view.tree,
+ self.createSibling, self.insertBefore)
+ view.tree.PopupMenu(menu, pos)
+ menu.Destroy()
+
+ def create(self, comp, child=None):
+ '''
+ Add DOM node as child or sibling depending on flags. Return new item.
+
+ If child is passed replace by existing data.
+ '''
+ if child is None:
+ child = Model.createObjectNode(comp.klass)
+ # Set default values
+ for k,v in comp.defaults.items():
+ comp.addAttribute(child, k, v)
+ data = wx.TreeItemData(child)
+ item = self.item
+ if not self.applied:
+ self.update(item)
+ if item == view.tree.root:
+ self.createSibling = False # can't create sibling of root
+ if self.createSibling:
+ parentItem = view.tree.GetItemParent(item)
+ parentNode = view.tree.GetPyData(parentItem)
+ else:
+ parentNode = view.tree.GetPyData(item)
+ label = comp.getTreeText(child)
+ imageId = comp.getTreeImageId(child)
+ if self.createSibling:
+ node = view.tree.GetPyData(item)
+ if self.insertBefore:
+ self.container.insertBefore(parentNode, child, node)
+ item = view.tree.InsertItemBefore(
+ parentItem, item, label, imageId, data=data)
+
+ else:
+ self.container.insertAfter(parentNode, child, node)
+ item = view.tree.InsertItem(
+ parentItem, item, label, imageId, data=data)
+ else:
+ if self.insertBefore and view.tree.ItemHasChildren(item):
+ nextNode = view.tree.GetPyData(view.tree.GetFirstChild(item)[0])
+ self.comp.insertBefore(parentNode, child, nextNode)
+ item = view.tree.PrependItem(item, label, imageId, data=data)
+ else:
+ self.comp.appendChild(parentNode, child)
+ item = view.tree.AppendItem(item, label, imageId, data=data)
+ view.tree.SetItemStyle(item, child)
+ view.tree.EnsureVisible(item)
+ view.tree.UnselectAll()
+ if view.testWin.IsShown():
+ view.testWin.isDirty = True
+ view.tree.SelectItem(item)
+ self.setModified()
+ return item
+
+ def createRef(self, ref, child=None):
+ '''Create object_ref element node.'''
+ if child is None:
+ child = Model.createRefNode(ref)
+ refNode = Model.findResource(ref)
+ if refNode:
+ comp = Manager.getNodeComp(refNode)
+ else:
+ comp = Manager.getNodeComp(child)
+ self.create(comp, child)
+
+ def createComment(self):
+ '''Create comment node.'''
+ node = Model.createCommentNode()
+ comp = Manager.getNodeComp(node)
+ self.create(comp, node)
+
+ def replace(self, comp, node=None):
+ '''Replace DOM node by new or passed node. Return new item.'''
+ TRACE('replace')
+ if node is None:
+ node = Model.createObjectNode(comp.klass)
+ if not self.applied:
+ self.update(item)
+ data = wx.TreeItemData(node)
+ item = self.item
+ parentItem = view.tree.GetItemParent(item)
+ parentNode = view.tree.GetPyData(parentItem)
+ oldNode = view.tree.GetPyData(item)
+ self.container.replaceChild(parentNode, node, oldNode)
+ # Replace tree item: insert new, remove old
+ label = comp.getTreeText(node)
+ imageId = comp.getTreeImageId(node)
+ item = view.tree.InsertItem(parentItem, item, label, imageId, data=data)
+ view.tree.Delete(view.tree.GetPrevSibling(item))
+ self.item = item
+ # Add children
+ for n in filter(is_object, node.childNodes):
+ view.tree.AddNode(item, comp.getTreeNode(n))
+ view.tree.EnsureVisible(item)
+ # Update panel
+ view.tree.SelectItem(item)
+ self.setModified()
+ return oldNode
+
+ def subclass(self, item, subclass):
+ node = view.tree.GetPyData(item)
+ if subclass:
+ node.setAttribute('subclass', subclass)
+ elif node.hasAttribute('subclass'):
+ node.removeAttribute('subclass')
+ # Update item label
+ view.tree.SetItemImage(item, self.comp.getTreeImageId(node))
+ view.tree.SetItemText(item, self.comp.getTreeText(node))
+ # Update panel
+ view.tree.SelectItem(item)
+ self.setModified()
+
+ def update(self, item):
+ '''Update DOM with new attribute values. Update tree if necessary.'''
+ node = view.tree.GetPyData(item)
+ isComment = node.nodeType == node.COMMENT_NODE
+ if isComment:
+ subclass = None
+ else:
+ subclass = node.getAttribute('subclass')
+ # Update (sub)class if needed
+ cls = view.panel.textClass.GetValue()
+ if not subclass:
+ if not isComment and cls != self.comp.klass:
+ if node.tagName == 'object_ref' and not cls:
+ if node.hasAttribute('class'):
+ node.removeAttribute('class')
+ TRACE('removed "class" tag')
+ else:
+ TRACE('update class: %s', cls)
+ node.setAttribute('class', cls)
+ else:
+ value = subclass + '(%s)' % self.comp.klass
+ if cls != value:
+ iLeft = cls.find('(')
+ iRight = cls.find(')')
+ if iLeft != -1 and iLeft < iRight:
+ subclass = cls[:iLeft]
+ klass = cls[iLeft+1:iRight]
+ TRACE('update class/subclass: %s', cls)
+ node.setAttribute('class', klass)
+ node.setAttribute('subclass', subclass)
+ else:
+ TRACE('remove subclass')
+ node.removeAttribute('subclass')
+ node.setAttribute('class', cls)
+ if self.comp and self.comp.hasName:
+ name = view.panel.textName.GetValue()
+ if name:
+ node.setAttribute('name', name)
+ elif node.hasAttribute('name'): # clean up empty names
+ node.removeAttribute('name')
+ if item != view.tree.root:
+ for panel in self.panels:
+ if not panel.node: continue
+ # Replace node contents except object children
+ for n in panel.node.childNodes[:]:
+ if not is_object(n):
+ panel.node.removeChild(n)
+ n.unlink()
+ for panel in self.panels:
+ for a,value in panel.GetValues():
+ if value:
+ try:
+ if isinstance(panel, view.AttributePanel) and panel.comp:
+ comp = panel.comp
+ else:
+ comp = self.comp
+ comp.addAttribute(panel.node, a, value)
+ except:
+ logger.exception('addAttribute error: %s %s', a, value)
+ if item != view.tree.root:
+ view.tree.SetItemImage(item, self.comp.getTreeImageId(node))
+ view.tree.SetItemText(item, self.comp.getTreeText(node))
+ self.setApplied()
+ # Set dirty flag
+ if view.testWin.IsShown():
+ view.testWin.isDirty = True
+
+ def unselect(self):
+ if not self.applied:
+ self.update(self.item)
+ if view.testWin.IsShown() and view.testWin.item == self.item:
+ view.testWin.Destroy()
+ view.tree.UnselectAll()
+ self.setData(view.tree.root)
+
+ def flushSubtree(self, item=None, node=None):
+ # Remember test item index
+ TRACE('flushSubtree')
+ if view.testWin.item is not None:
+ itemIndex = view.tree.ItemFullIndex(view.testWin.item)
+ view.tree.FlushSubtree(item, node)
+ if view.testWin.item is not None:
+ view.testWin.item = view.tree.ItemAtFullIndex(itemIndex)
+
+ def delete(self, item):
+ '''Delete selected object(s). Return removed XML node.'''
+ TRACE('delete')
+ parentItem = view.tree.GetItemParent(item)
+ parentNode = view.tree.GetPyData(parentItem)
+ node = view.tree.GetPyData(item)
+ node = self.container.removeChild(parentNode, node)
+ view.tree.Delete(item)
+ # If deleting the top-level object, remove view
+ if view.testWin.IsShown() and view.testWin.item == item:
+ view.testWin.Destroy()
+ self.setApplied()
+ self.unselect()
+ self.setModified()
+ return node
+
+ def deleteMany(self, items):
+ '''Delete selected object(s).'''
+ for item in items:
+ if not item.IsOk(): continue # child already deleted
+ parentItem = view.tree.GetItemParent(item)
+ parentNode = view.tree.GetPyData(parentItem)
+ node = view.tree.GetPyData(item)
+ node = self.container.removeChild(parentNode, node)
+ node.unlink() # delete completely
+ view.tree.Delete(item)
+ self.setApplied()
+ self.unselect()
+ self.setModified()
+
+ def cut(self):
+ self.copy()
+ return self.delete(view.tree.GetSelection())
+
+ def copy(self):
+ # Update values from panel first
+ item = view.tree.GetSelection()
+ if not self.applied:
+ self.update(item)
+ node = view.tree.GetPyData(item)
+ if self.container.requireImplicit(node):
+ implicit = node.parentNode
+ else:
+ implicit = None
+ if wx.TheClipboard.Open():
+ if node.nodeType == node.ELEMENT_NODE:
+ data = wx.CustomDataObject('XRCED_elem')
+ s = node.toxml(encoding=expat.native_encoding)
+ # Replace by a pair
+ if implicit: s = [s, implicit.toxml(encoding=expat.native_encoding)]
+ else:
+ # Non-element nodes are normally comments
+ data = wx.CustomDataObject('XRCED_node')
+ s = node.data
+ data.SetData(cPickle.dumps(s))
+ wx.TheClipboard.SetData(data)
+ wx.TheClipboard.Close()
+ else:
+ wx.MessageBox("Unable to open the clipboard", "Error")
+
+ def checkCompatibility(self, comp):
+ '''Check parent/child compatibility.'''
+ if self.createSibling: container = self.container
+ else: container = self.comp
+ if not container.canHaveChild(comp):
+ wx.LogError('Incompatible parent/child: parent is %s, child is %s!' %
+ (container.klass, comp.klass))
+ return False
+ return True
+
+ def paste(self):
+ success = success_node = False
+ if wx.TheClipboard.IsOpened() or wx.TheClipboard.Open():
+ try:
+ data = wx.CustomDataObject('XRCED_elem')
+ if wx.TheClipboard.IsSupported(data.GetFormat()):
+ try:
+ success = wx.TheClipboard.GetData(data)
+ except:
+ # there is a problem if XRCED_node is in clipboard
+ # but previous SetData was for XRCED
+ pass
+ if not success: # try other format
+ data = wx.CustomDataObject('XRCED_node')
+ if wx.TheClipboard.IsSupported(data.GetFormat()):
+ success_node = wx.TheClipboard.GetData(data)
+ finally:
+ wx.TheClipboard.Close()
+
+ if not success and not success_node:
+ wx.MessageBox(
+ "There is no data in the clipboard in the required format",
+ "Error")
+ return
+
+ # XML representation of element or node value string
+ data = cPickle.loads(data.GetData())
+ implicit = None
+ if success:
+ if type(data) is list:
+ node = Model.parseString(data[0])
+ implicit = Model.parseString(data[1])
+ else:
+ node = Model.parseString(data)
+ else:
+ node = Model.dom.createComment(data)
+ comp = Manager.getNodeComp(node)
+
+ # Check compatibility
+ if not self.checkCompatibility(comp):
+ node.unlink()
+ return
+
+ item = view.tree.GetSelection()
+ if item and not self.applied:
+ self.update(item)
+
+ item = self.create(comp, node)
+ if implicit: # copy parameters for implicit node if possible
+ parentNode = view.tree.GetPyData(view.tree.GetItemParent(item))
+ parentComp = Manager.getNodeComp(parentNode)
+ if parentComp.requireImplicit(node) and \
+ parentComp.implicitKlass == implicit.getAttribute('class'):
+ parentComp.copyImplicitAttributes(implicit, node.parentNode, parentComp)
+ implicit.unlink()
+
+ # Add children
+ for n in filter(is_object, node.childNodes):
+ view.tree.AddNode(item, comp.getTreeNode(n))
+ self.setModified()
+ return item
+
+ def moveUp(self):
+ parentItem = view.tree.GetItemParent(self.item)
+ treeNode = view.tree.GetPyData(self.item)
+ node = self.container.getTreeOrImplicitNode(treeNode)
+ parent = node.parentNode
+ prevNode = node.previousSibling
+ while not is_object(prevNode):
+ prevNode = prevNode.previousSibling
+ parent.removeChild(node)
+ parent.insertBefore(node, prevNode)
+ index = view.tree.ItemFullIndex(self.item)
+ self.flushSubtree(parentItem, parent)
+ index[-1] -= 1
+ self.item = view.tree.ItemAtFullIndex(index)
+ self.setModified()
+ view.tree.SelectItem(self.item)
+
+ def moveDown(self):
+ parentItem = view.tree.GetItemParent(self.item)
+ treeNode = view.tree.GetPyData(self.item)
+ node = self.container.getTreeOrImplicitNode(treeNode)
+ parent = node.parentNode
+ nextNode = node.nextSibling
+ while not is_object(nextNode):
+ nextNode = nextNode.nextSibling
+ nextNode = nextNode.nextSibling
+ while nextNode and not is_object(nextNode):
+ nextNode = nextNode.nextSibling
+ parent.removeChild(node)
+ parent.insertBefore(node, nextNode)
+ index = view.tree.ItemFullIndex(self.item)
+ self.flushSubtree(parentItem, parent)
+ index[-1] += 1
+ self.item = view.tree.ItemAtFullIndex(index)
+ self.setModified()
+ view.tree.SelectItem(self.item)
+
+ def moveLeft(self):
+ parentItem = view.tree.GetItemParent(self.item)
+ grandParentItem = view.tree.GetItemParent(parentItem)
+ parent = view.tree.GetPyData(parentItem)
+ grandParent = view.tree.GetPyData(grandParentItem)
+ if grandParent is Model.mainNode:
+ grandParentComp = Manager.rootComponent
+ else:
+ grandParentComp = Manager.getNodeComp(grandParent)
+ if not grandParentComp.canHaveChild(self.comp):
+ wx.LogError('Incompatible parent/child: parent is %s, child is %s!' %
+ (grandParentComp.klass, self.comp.klass))
+ return
+
+ node = view.tree.GetPyData(self.item)
+ nextItem = view.tree.GetNextSibling(parentItem)
+ self.container.removeChild(parent, node)
+ if nextItem:
+ nextNode = view.tree.GetPyData(nextItem)
+ grandParentComp.insertBefore(grandParent, node, nextNode)
+ else:
+ grandParentComp.appendChild(grandParent, node)
+ index = view.tree.ItemFullIndex(self.item)
+ self.flushSubtree(grandParentItem, grandParent)
+ index.pop()
+ index[-1] += 1
+ self.item = view.tree.ItemAtFullIndex(index)
+ self.setModified()
+ view.tree.SelectItem(self.item)
+
+ def moveRight(self):
+ parentItem = view.tree.GetItemParent(self.item)
+ parent = view.tree.GetPyData(parentItem)
+ newParent = view.tree.GetPyData(view.tree.GetPrevSibling(self.item))
+ newParentComp = Manager.getNodeComp(newParent)
+ if not newParentComp.canHaveChild(self.comp):
+ wx.LogError('Incompatible parent/child: parent is %s, child is %s!' %
+ (newParentComp.klass, self.comp.klass))
+ return
+
+ node = view.tree.GetPyData(self.item)
+ self.container.removeChild(parent, node)
+ newParentComp.appendChild(newParent, node)
+ index = view.tree.ItemFullIndex(self.item)
+ n = view.tree.GetChildrenCount(view.tree.GetPrevSibling(self.item))
+ self.flushSubtree(parentItem, parent)
+ index[-1] -= 1
+ index.append(n)
+ self.item = view.tree.ItemAtFullIndex(index)
+ self.setModified()
+ view.tree.SelectItem(self.item)
+
+ def createLocalConf(self, path):
+ name = os.path.splitext(path)[0]
+ name += '.xcfg'
+ return wx.FileConfig(localFilename=name)
+
+ def createTestWin(self, item):
+ TRACE('createTestWin')
+ # Create a window with this resource
+ node = view.tree.GetPyData(item)
+ # Execute "pragma" comment node
+ if node.nodeType == node.COMMENT_NODE:
+ if node.data and node.data[0] == '%' and g.conf.allowExec != 'no':
+ say = wx.NO
+ if g.conf.allowExec == 'ask' and Model.allowExec is None:
+ say = wx.MessageBox('Execute comment directive?', 'Warning',
+ wx.ICON_EXCLAMATION | wx.YES_NO)
+ if g.conf.allowExec == 'yes' or say == wx.YES:
+ code = node.data[1:] # skip '%'
+ view.tree.ExecCode(code)
+ return
+ # Close old window, remember where it was
+ comp = Manager.getNodeComp(node)
+ # Use parent object if the current one does not support test view
+ testWinItem = item
+ while not comp.isTestable:
+ testWinItem = view.tree.GetItemParent(testWinItem)
+ node = view.tree.GetPyData(testWinItem)
+ comp = Manager.getNodeComp(node)
+ # Create memory XML file
+ elem = node.cloneNode(True)
+ if not node.hasAttribute('name'):
+ name = 'noname'
+ else:
+ name = node.getAttribute('name')
+ elem.setAttribute('name', STD_NAME)
+ Model.setTestElem(elem)
+ Model.saveTestMemoryFile()
+ xmlFlags = 0
+ if not g.conf.useSubclassing:
+ xmlFlags |= xrc.XRC_NO_SUBCLASSING
+ # Use translations if encoding is not specified
+ if not Model.dom.encoding:
+ xmlFlags |= xrc.XRC_USE_LOCALE
+ res = xrc.EmptyXmlResource(xmlFlags)
+ xrc.XmlResource.Set(res) # set as global
+ # Init other handlers
+ Manager.addXmlHandlers(res)
+ Manager.preload(res)
+ # Same module list
+ res.Load('memory:test.xrc')
+ testWin = view.testWin
+ try:
+ try:
+ frame, object = comp.makeTestWin(res, name)
+ if not object: # skip the rest
+ raise EOFError
+ # Reset previous tree item and locate tool
+ if testWin.item:
+ view.tree.SetItemBold(testWin.item, False)
+ testWin.SetView(frame, object, testWinItem)
+ testWin.Show()
+ view.tree.SetItemBold(testWinItem, True)
+ # For reused frame, object is not positioned immediately
+ wx.CallAfter(self.highlight, item)
+ except EOFError:
+ pass
+ except TestWinError:
+ wx.LogError('Test window could not be created for %s' % node.getAttribute('class'))
+ logger.exception('error creating test view')
+ except:
+ wx.LogError('Error creating test view')
+ logger.exception('error creating test view')
+ if get_debug(): raise
+ finally:
+ # Cleanup
+ res.Unload(TEST_FILE)
+ xrc.XmlResource.Set(None)
+ wx.MemoryFSHandler.RemoveFile(TEST_FILE)
+
+ def closeTestWin(self):
+ TRACE('closeTestWin')
+ if not view.testWin.object: return
+ view.tree.SetItemBold(view.testWin.item, False)
+ view.tree.Refresh()
+ view.frame.tb.ToggleTool(view.frame.ID_TOOL_LOCATE, False)
+ if view.frame.miniFrame:
+ view.frame.miniFrame.tb.ToggleTool(view.frame.ID_TOOL_LOCATE, False)
+ view.testWin.Destroy()
+
+ def refreshTestWin(self):
+ '''Refresh test window after some change.'''
+ TRACE('refreshTestWin')
+ if not view.testWin.IsDirty(): return
+ if not self.applied: self.update(self.item)
+ # Dumb refresh
+ self.createTestWin(view.testWin.item)
+ self.highlight(self.item)
+ if view.frame.miniFrame and view.frame.miniFrame.IsShown():
+ view.frame.miniFrame.Raise()
+ else:
+ view.frame.Raise()
+
+ def showXML(self):
+ '''Show some source.'''
+ node = view.tree.GetPyData(self.item)
+ dom = MyDocument()
+ node = dom.appendChild(node.cloneNode(True))
+ Model.indent(dom, node)
+ text = node.toxml()#Model.dom.encoding)
+ dom.unlink()
+ lines = text.split('\n')
+ maxLen = max(map(len, lines))
+ w = max(40, min(80, maxLen))
+ h = max(20, min(40, len(lines)))
+ dlg = view.ScrolledMessageDialog(view.frame, text, 'XML Source',
+ textSize=(w,h), centered=False)
+ dlg.Bind(wx.EVT_CLOSE, lambda evt: dlg.Destroy())
+ dlg.Bind(wx.EVT_BUTTON, lambda evt: dlg.Destroy(), id=wx.ID_OK)
+ dlg.Show()
+
+ def generatePython(self, dataFile, pypath, embed, genGettext):
+ try:
+ from wx.tools import pywxrc
+ rescomp = pywxrc.XmlResourceCompiler()
+ rescomp.MakePythonModule([dataFile], pypath, embed, genGettext,
+ assignVariables=False)
+ except:
+ logger.exception('error generating python code')
+ wx.LogError('Error generating python code : %s' % pypath)
+ raise
+
+# Singleton class
+Presenter = g.Presenter = _Presenter()
+
+undo.Presenter = Presenter