📄 xrced.py
字号:
'', '*.xrc', wx.OPEN | wx.CHANGE_DIR)
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
self.SetStatusText('Loading...')
wx.BeginBusyCursor()
try:
if self.Open(path):
self.SetStatusText('Data loaded')
else:
self.SetStatusText('Failed')
self.SaveRecent(path)
finally:
wx.EndBusyCursor()
dlg.Destroy()
def OnSaveOrSaveAs(self, evt):
if evt.GetId() == wx.ID_SAVEAS or not self.dataFile:
if self.dataFile: name = ''
else: name = defaultName
dirname = os.path.abspath(os.path.dirname(self.dataFile))
dlg = wx.FileDialog(self, 'Save As', dirname, name, '*.xrc',
wx.SAVE | wx.OVERWRITE_PROMPT | wx.CHANGE_DIR)
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
dlg.Destroy()
else:
dlg.Destroy()
return
if conf.localconf:
# if we already have a localconf then it needs to be
# copied to a new config with the new name
lc = conf.localconf
nc = self.CreateLocalConf(path)
flag, key, idx = lc.GetFirstEntry()
while flag:
nc.Write(key, lc.Read(key))
flag, key, idx = lc.GetNextEntry(idx)
conf.localconf = nc
else:
# otherwise create a new one
conf.localconf = self.CreateLocalConf(path)
else:
path = self.dataFile
self.SetStatusText('Saving...')
wx.BeginBusyCursor()
try:
try:
tmpFile,tmpName = tempfile.mkstemp(prefix='xrced-')
os.close(tmpFile)
self.Save(tmpName) # save temporary file first
shutil.move(tmpName, path)
self.dataFile = path
if conf.localconf.ReadBool("autogenerate", False):
pypath = conf.localconf.Read("filename")
embed = conf.localconf.ReadBool("embedResource", False)
genGettext = conf.localconf.ReadBool("genGettext", False)
self.GeneratePython(self.dataFile, pypath, embed, genGettext)
self.SetStatusText('Data saved')
self.SaveRecent(path)
except IOError:
self.SetStatusText('Failed')
finally:
wx.EndBusyCursor()
def SaveRecent(self,path):
# append to recently used files
if path not in conf.recentfiles.values():
newid = wx.NewId()
self.recentMenu.Append(newid, path)
wx.EVT_MENU(self, newid, self.OnRecentFile)
conf.recentfiles[newid] = path
def GeneratePython(self, dataFile, pypath, embed, genGettext):
try:
import wx.tools.pywxrc
rescomp = wx.tools.pywxrc.XmlResourceCompiler()
rescomp.MakePythonModule([dataFile], pypath, embed, genGettext)
except:
inf = sys.exc_info()
wx.LogError(traceback.format_exception(inf[0], inf[1], None)[-1])
wx.LogError('Error generating python code : %s' % pypath)
raise
def OnGeneratePython(self, evt):
if self.modified or not conf.localconf:
wx.MessageBox("Save the XRC file first!", "Error")
return
dlg = PythonOptions(self, conf.localconf, self.dataFile)
dlg.ShowModal()
dlg.Destroy()
def OnExit(self, evt):
self.Close()
def OnUndo(self, evt):
# Extra check to not mess with idle updating
if undoMan.CanUndo():
undoMan.Undo()
def OnRedo(self, evt):
if undoMan.CanRedo():
undoMan.Redo()
def OnCopy(self, evt):
selected = tree.selection
if not selected: return # key pressed event
xxx = tree.GetPyData(selected)
if wx.TheClipboard.Open():
data = wx.CustomDataObject('XRCED')
# Set encoding in header
# (False,True)
s = xxx.element.toxml(encoding=expat.native_encoding)
data.SetData(cPickle.dumps(s))
wx.TheClipboard.SetData(data)
wx.TheClipboard.Close()
self.SetStatusText('Copied')
else:
wx.MessageBox("Unable to open the clipboard", "Error")
def OnPaste(self, evt):
selected = tree.selection
if not selected: return # key pressed event
# For pasting with Ctrl pressed
appendChild = True
if evt.GetId() == pullDownMenu.ID_PASTE_SIBLING: appendChild = False
elif evt.GetId() == self.ID_TOOL_PASTE:
if g.tree.ctrl: appendChild = False
else: appendChild = not tree.NeedInsert(selected)
else: appendChild = not tree.NeedInsert(selected)
xxx = tree.GetPyData(selected)
if not appendChild:
# If has next item, insert, else append to parent
nextItem = tree.GetNextSibling(selected)
parentLeaf = tree.GetItemParent(selected)
# Expanded container (must have children)
elif tree.IsExpanded(selected) and tree.GetChildrenCount(selected, False):
# Insert as first child
nextItem = tree.GetFirstChild(selected)[0]
parentLeaf = selected
else:
# No children or unexpanded item - appendChild stays True
nextItem = wx.TreeItemId() # no next item
parentLeaf = selected
parent = tree.GetPyData(parentLeaf).treeObject()
# Create a copy of clipboard pickled element
success = False
if wx.TheClipboard.Open():
data = wx.CustomDataObject('XRCED')
if wx.TheClipboard.IsSupported(data.GetFormat()):
success = wx.TheClipboard.GetData(data)
wx.TheClipboard.Close()
if not success:
wx.MessageBox(
"There is no data in the clipboard in the required format",
"Error")
return
xml = cPickle.loads(data.GetData()) # xml representation of element
elem = minidom.parseString(xml).childNodes[0]
# Tempopary xxx object to test things
xxx = MakeXXXFromDOM(parent, elem)
# Check compatibility
error = False
# Top-level
x = xxx.treeObject()
if x.__class__ in [xxxDialog, xxxFrame, xxxWizard]:
# Top-level classes
if parent.__class__ != xxxMainNode: error = True
elif x.__class__ == xxxMenuBar:
# Menubar can be put in frame or dialog
if parent.__class__ not in [xxxMainNode, xxxFrame, xxxDialog]: error = True
elif x.__class__ == xxxToolBar:
# Toolbar can be top-level of child of panel or frame
if parent.__class__ not in [xxxMainNode, xxxPanel, xxxFrame] and \
not parent.isSizer: error = True
elif x.__class__ == xxxPanel and parent.__class__ == xxxMainNode:
pass
elif x.__class__ == xxxSpacer:
if not parent.isSizer: error = True
elif x.__class__ == xxxSeparator:
if not parent.__class__ in [xxxMenu, xxxToolBar]: error = True
elif x.__class__ == xxxTool:
if parent.__class__ != xxxToolBar: error = True
elif x.__class__ == xxxMenu:
if not parent.__class__ in [xxxMainNode, xxxMenuBar, xxxMenu]: error = True
elif x.__class__ == xxxMenuItem:
if not parent.__class__ in [xxxMenuBar, xxxMenu]: error = True
elif x.isSizer and parent.__class__ in [xxxNotebook, xxxChoicebook, xxxListbook]:
error = True
else: # normal controls can be almost anywhere
if parent.__class__ == xxxMainNode or \
parent.__class__ in [xxxMenuBar, xxxMenu]: error = True
if error:
if parent.__class__ == xxxMainNode: parentClass = 'root'
else: parentClass = parent.className
wx.LogError('Incompatible parent/child: parent is %s, child is %s!' %
(parentClass, x.className))
return
# Check parent and child relationships.
# If parent is sizer or notebook, child is of wrong class or
# parent is normal window, child is child container then detach child.
isChildContainer = isinstance(xxx, xxxChildContainer)
parentIsBook = parent.__class__ in [xxxNotebook, xxxChoicebook, xxxListbook]
if isChildContainer and \
((parent.isSizer and not isinstance(xxx, xxxSizerItem)) or \
(parentIsBook and not isinstance(xxx, xxxPage)) or \
not (parent.isSizer or parentIsBook)):
elem.removeChild(xxx.child.element) # detach child
elem.unlink() # delete child container
elem = xxx.child.element # replace
# This may help garbage collection
xxx.child.parent = None
isChildContainer = False
# Parent is sizer or notebook, child is not child container
if parent.isSizer and not isChildContainer and not isinstance(xxx, xxxSpacer):
# Create sizer item element
sizerItemElem = MakeEmptyDOM(parent.itemTag)
sizerItemElem.appendChild(elem)
elem = sizerItemElem
elif isinstance(parent, xxxNotebook) and not isChildContainer:
pageElem = MakeEmptyDOM('notebookpage')
pageElem.appendChild(elem)
elem = pageElem
elif isinstance(parent, xxxChoicebook) and not isChildContainer:
pageElem = MakeEmptyDOM('choicebookpage')
pageElem.appendChild(elem)
elem = pageElem
elif isinstance(parent, xxxListbook) and not isChildContainer:
pageElem = MakeEmptyDOM('listbookpage')
pageElem.appendChild(elem)
elem = pageElem
# Insert new node, register undo
newItem = tree.InsertNode(parentLeaf, parent, elem, nextItem)
undoMan.RegisterUndo(UndoPasteCreate(parentLeaf, parent, newItem, selected))
# Scroll to show new item (!!! redundant?)
tree.EnsureVisible(newItem)
tree.SelectItem(newItem)
if not tree.IsVisible(newItem):
tree.ScrollTo(newItem)
tree.Refresh()
# Update view?
if g.testWin and tree.IsHighlatable(newItem):
if conf.autoRefresh:
tree.needUpdate = True
tree.pendingHighLight = newItem
else:
tree.pendingHighLight = None
self.SetModified()
self.SetStatusText('Pasted')
def OnCutDelete(self, evt):
selected = tree.selection
if not selected: return # key pressed event
# Undo info
if evt.GetId() == wx.ID_CUT:
self.lastOp = 'CUT'
status = 'Removed to clipboard'
else:
self.lastOp = 'DELETE'
status = 'Deleted'
# Delete testWin?
if g.testWin:
# If deleting top-level item, delete testWin
if selected == g.testWin.item:
g.testWin.Destroy()
g.testWin = None
else:
# Remove highlight, update testWin
if g.testWin.highLight:
g.testWin.highLight.Remove()
tree.needUpdate = True
# Prepare undo data
panel.Apply()
index = tree.ItemFullIndex(selected)
parent = tree.GetPyData(tree.GetItemParent(selected)).treeObject()
elem = tree.RemoveLeaf(selected)
undoMan.RegisterUndo(UndoCutDelete(index, parent, elem))
if evt.GetId() == wx.ID_CUT:
if wx.TheClipboard.Open():
data = wx.CustomDataObject('XRCED')
# (False, True)
s = elem.toxml(encoding=expat.native_encoding)
data.SetData(cPickle.dumps(s))
wx.TheClipboard.SetData(data)
wx.TheClipboard.Close()
else:
wx.MessageBox("Unable to open the clipboard", "Error")
tree.pendingHighLight = None
tree.UnselectAll()
tree.selection = None
# Update tools
g.tools.UpdateUI()
panel.Clear()
self.SetModified()
self.SetStatusText(status)
def OnSubclass(self, evt):
selected = tree.selection
xxx = tree.GetPyData(selected).treeObject()
elem = xxx.element
subclass = xxx.subclass
dlg = wx.TextEntryDialog(self, 'Subclass:', defaultValue=subclass)
if dlg.ShowModal() == wx.ID_OK:
subclass = dlg.GetValue()
if subclass:
elem.setAttribute('subclass', subclass)
elif elem.hasAttribute('subclass'):
elem.removeAttribute('subclass')
self.SetModified()
xxx.subclass = elem.getAttribute('subclass')
tree.SetItemText(selected, xxx.treeName())
panel.pages[0].box.SetLabel(xxx.panelName())
dlg.Destroy()
def OnEmbedPanel(self, evt):
conf.embedPanel = evt.IsChecked()
if conf.embedPanel:
# Remember last dimentions
conf.panelX, conf.panelY = self.miniFrame.GetPosition()
conf.panelWidth, conf.panelHeight = self.miniFrame.GetSize()
size = self.GetSize()
pos = self.GetPosition()
sizePanel = panel.GetSize()
panel.Reparent(self.splitter)
self.miniFrame.GetSizer().Remove(panel)
# Widen
self.SetDimensions(pos.x, pos.y, size.width + sizePanel.width, size.height)
self.splitter.SplitVertically(tree, panel, conf.sashPos)
self.miniFrame.Show(False)
else:
conf.sashPos = self.splitter.GetSashPosition()
pos = self.GetPosition()
size = self.GetSize()
sizePanel = panel.GetSize()
self.splitter.Unsplit(panel)
sizer = self.miniFrame.GetSizer()
panel.Reparent(self.miniFrame)
panel.Show(True)
sizer.Add(panel, 1, wx.EXPAND)
self.miniFrame.Show(True)
self.miniFrame.SetDimensions(conf.panelX, conf.panelY,
conf.panelWidth, conf.panelHeight)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -