Preferences for default "sizeritem" parameters for new panels and
controls can be configured ("File">"Preferences..."). Implemented comment object for including simple one-line comments and comment directives as tree nodes. No validation is performed for a valid XML string so comments must not contain "-->". Comment directive is a special comment starting with '%' character, followed by a line of python code. It is executed using 'exec' when the resource file is opened. This is useful to import plugin modules containing custom handlers which are specific to the resource file, hovewer this is of course a security hole if you use foreign XRC files. A warning is displayed if the preference option 'ask' is selected (by default). Added support for custom controls and plugin modules. Refer to this wxPythonWiki for the details: http://wiki.wxpython.org/index.cgi/XRCed#custom Tool panel sections can be collapsed/expanded by clicking on the label of a tool group. Some undo/redo and other fixes. Fixes for wxMSW (notebook highlighting, control sizes, tree Unselect). Notebook page highlighting fix. Highlight resizes when the window is resized. ParamUnit spin button detects event handler re-entry (wxGTK probably has a bug in wxSpinButton with repeated events). Fix for dealing with empty 'growable' property, using MiniFrame for properties panel, the panel is restored together with the main window. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@44949 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -86,10 +86,12 @@ class ID_NEW:
|
||||
CHOICEBOOK = wx.NewId()
|
||||
LISTBOOK = wx.NewId()
|
||||
SPLITTER_WINDOW = wx.NewId()
|
||||
GRID = wx.NewId()
|
||||
SCROLLED_WINDOW = wx.NewId()
|
||||
HTML_WINDOW = wx.NewId()
|
||||
CALENDAR_CTRL = wx.NewId()
|
||||
DATE_CTRL = wx.NewId()
|
||||
FILE_PICKER_CTRL = wx.NewId()
|
||||
GENERIC_DIR_CTRL = wx.NewId()
|
||||
SPIN_CTRL = wx.NewId()
|
||||
UNKNOWN = wx.NewId()
|
||||
@@ -124,6 +126,10 @@ class ID_NEW:
|
||||
CONTEXT_HELP_BUTTON = wx.NewId()
|
||||
|
||||
REF = wx.NewId()
|
||||
COMMENT = wx.NewId()
|
||||
|
||||
CUSTOM = wx.NewId()
|
||||
for i in range(99): wx.NewId() # reserve IDs for custom controls
|
||||
|
||||
LAST = wx.NewId()
|
||||
|
||||
@@ -193,10 +199,12 @@ class PullDownMenu:
|
||||
ID_NEW.CHOICEBOOK: 'wxChoicebook',
|
||||
ID_NEW.LISTBOOK: 'wxListbook',
|
||||
ID_NEW.SPLITTER_WINDOW: 'wxSplitterWindow',
|
||||
ID_NEW.GRID: 'wxGrid',
|
||||
ID_NEW.SCROLLED_WINDOW: 'wxScrolledWindow',
|
||||
ID_NEW.HTML_WINDOW: 'wxHtmlWindow',
|
||||
ID_NEW.CALENDAR_CTRL: 'wxCalendarCtrl',
|
||||
ID_NEW.DATE_CTRL: 'wxDatePickerCtrl',
|
||||
ID_NEW.FILE_PICKER_CTRL: 'wxFilePickerCtrl',
|
||||
ID_NEW.GENERIC_DIR_CTRL: 'wxGenericDirCtrl',
|
||||
ID_NEW.SPIN_CTRL: 'wxSpinCtrl',
|
||||
|
||||
@@ -268,10 +276,12 @@ class PullDownMenu:
|
||||
(ID_NEW.SCROLL_BAR, 'ScrollBar', 'Create scroll bar'),
|
||||
(ID_NEW.TREE_CTRL, 'TreeCtrl', 'Create tree'),
|
||||
(ID_NEW.LIST_CTRL, 'ListCtrl', 'Create list'),
|
||||
# (ID_NEW.GRID, 'Grid', 'Create grid'),
|
||||
(ID_NEW.SCROLLED_WINDOW, 'ScrolledWindow', 'Create scrolled window'),
|
||||
(ID_NEW.HTML_WINDOW, 'HtmlWindow', 'Create HTML window'),
|
||||
(ID_NEW.CALENDAR_CTRL, 'CalendarCtrl', 'Create calendar control'),
|
||||
(ID_NEW.DATE_CTRL, 'DatePickerCtrl', 'Create date picker control'),
|
||||
# (ID_NEW.FILE_PICKER_CTRL, 'FilePickerCtrl', 'Create file picker control'),
|
||||
(ID_NEW.GENERIC_DIR_CTRL, 'GenericDirCtrl', 'Create generic dir control'),
|
||||
(ID_NEW.UNKNOWN, 'Unknown', 'Create custom control placeholder'),
|
||||
],
|
||||
@@ -370,7 +380,13 @@ class PullDownMenu:
|
||||
ID_NEW.HELP_BUTTON: ('wxID_HELP', '&Help'),
|
||||
ID_NEW.CONTEXT_HELP_BUTTON: ('wxID_CONTEXT_HELP', '&Help'),
|
||||
}
|
||||
|
||||
self.custom = ['custom', 'User-defined controls']
|
||||
self.customMap = {}
|
||||
|
||||
def addCustom(self, klass):
|
||||
n = len(self.custom)-2
|
||||
self.custom.append((ID_NEW.CUSTOM + n, klass))
|
||||
self.customMap[ID_NEW.CUSTOM + n] = klass
|
||||
|
||||
|
||||
################################################################################
|
||||
@@ -409,6 +425,7 @@ class HighLightBox:
|
||||
l4 = wx.Window(w, -1, wx.Point(pos.x, pos.y + size.height - 2), wx.Size(size.width, 2))
|
||||
l4.SetBackgroundColour(wx.RED)
|
||||
self.lines = [l1, l2, l3, l4]
|
||||
self.size = size
|
||||
# Move highlight to a new position
|
||||
def Replace(self, pos, size):
|
||||
if size.width == -1: size.width = 0
|
||||
@@ -417,6 +434,7 @@ class HighLightBox:
|
||||
self.lines[1].SetDimensions(pos.x, pos.y, 2, size.height)
|
||||
self.lines[2].SetDimensions(pos.x + size.width - 2, pos.y, 2, size.height)
|
||||
self.lines[3].SetDimensions(pos.x, pos.y + size.height - 2, size.width, 2)
|
||||
self.size = size
|
||||
# Remove it
|
||||
def Remove(self):
|
||||
map(wx.Window.Destroy, self.lines)
|
||||
@@ -428,8 +446,12 @@ class HighLightBox:
|
||||
|
||||
class XML_Tree(wx.TreeCtrl):
|
||||
def __init__(self, parent, id):
|
||||
wx.TreeCtrl.__init__(self, parent, id, style = wx.TR_HAS_BUTTONS | wx.TR_MULTIPLE)
|
||||
wx.TreeCtrl.__init__(self, parent, id,
|
||||
style = wx.TR_HAS_BUTTONS | wx.TR_MULTIPLE | wx.TR_EDIT_LABELS)
|
||||
self.SetBackgroundColour(wx.Colour(224, 248, 224))
|
||||
self.fontComment = wx.FFont(self.GetFont().GetPointSize(),
|
||||
self.GetFont().GetFamily(),
|
||||
wx.FONTFLAG_ITALIC)
|
||||
# Register events
|
||||
wx.EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
|
||||
# One works on Linux, another on Windows
|
||||
@@ -440,6 +462,8 @@ class XML_Tree(wx.TreeCtrl):
|
||||
wx.EVT_RIGHT_DOWN(self, self.OnRightDown)
|
||||
wx.EVT_TREE_ITEM_EXPANDED(self, self.GetId(), self.OnItemExpandedCollapsed)
|
||||
wx.EVT_TREE_ITEM_COLLAPSED(self, self.GetId(), self.OnItemExpandedCollapsed)
|
||||
self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnBeginLabelEdit)
|
||||
self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEndLabelEdit)
|
||||
|
||||
self.selection = None
|
||||
self.selectionChanging = False
|
||||
@@ -450,6 +474,7 @@ class XML_Tree(wx.TreeCtrl):
|
||||
# Create image list
|
||||
il = wx.ImageList(16, 16, True)
|
||||
self.rootImage = il.Add(images.getTreeRootImage().Scale(16,16).ConvertToBitmap())
|
||||
xxxComment.image = il.Add(images.getTreeCommentImage().Scale(16,16).ConvertToBitmap())
|
||||
xxxObject.image = il.Add(images.getTreeDefaultImage().Scale(16,16).ConvertToBitmap())
|
||||
xxxPanel.image = il.Add(images.getTreePanelImage().Scale(16,16).ConvertToBitmap())
|
||||
xxxDialog.image = il.Add(images.getTreeDialogImage().Scale(16,16).ConvertToBitmap())
|
||||
@@ -560,19 +585,22 @@ class XML_Tree(wx.TreeCtrl):
|
||||
item = self.AppendItem(itemParent, treeObj.treeName(),
|
||||
image=treeObj.treeImage(),
|
||||
data=wx.TreeItemData(xxx))
|
||||
# Different color for references
|
||||
if treeObj.ref:
|
||||
# Different color for comments and references
|
||||
if xxx.className == 'comment':
|
||||
self.SetItemTextColour(item, 'Blue')
|
||||
self.SetItemFont(item, self.fontComment)
|
||||
elif treeObj.ref:
|
||||
self.SetItemTextColour(item, 'DarkGreen')
|
||||
elif treeObj.hasStyle and treeObj.params.get('hidden', False):
|
||||
self.SetItemTextColour(item, 'Grey')
|
||||
# Try to find children objects
|
||||
if treeObj.hasChildren:
|
||||
nodes = treeObj.element.childNodes[:]
|
||||
nodes = treeObj.node.childNodes[:]
|
||||
for n in nodes:
|
||||
if IsObject(n):
|
||||
self.AddNode(item, treeObj, n)
|
||||
elif n.nodeType != minidom.Node.ELEMENT_NODE:
|
||||
treeObj.element.removeChild(n)
|
||||
treeObj.node.removeChild(n)
|
||||
n.unlink()
|
||||
|
||||
# Insert new item at specific position
|
||||
@@ -581,23 +609,30 @@ class XML_Tree(wx.TreeCtrl):
|
||||
xxx = MakeXXXFromDOM(parent, elem)
|
||||
# If nextItem is None, we append to parent, otherwise insert before it
|
||||
if nextItem.IsOk():
|
||||
node = self.GetPyData(nextItem).element
|
||||
parent.element.insertBefore(elem, node)
|
||||
node = self.GetPyData(nextItem).node
|
||||
parent.node.insertBefore(elem, node)
|
||||
# Inserting before is difficult, se we insert after or first child
|
||||
index = self.ItemIndex(nextItem)
|
||||
newItem = self.InsertItemBefore(itemParent, index,
|
||||
xxx.treeName(), image=xxx.treeImage())
|
||||
self.SetPyData(newItem, xxx)
|
||||
else:
|
||||
parent.element.appendChild(elem)
|
||||
parent.node.appendChild(elem)
|
||||
newItem = self.AppendItem(itemParent, xxx.treeName(), image=xxx.treeImage(),
|
||||
data=wx.TreeItemData(xxx))
|
||||
# Different color for references
|
||||
if xxx.treeObject().ref: self.SetItemTextColour(newItem, 'DarkGreen')
|
||||
treeObj = xxx.treeObject()
|
||||
# Different color for references and comments
|
||||
if xxx.className == 'comment':
|
||||
self.SetItemTextColour(newItem, 'Blue')
|
||||
self.SetItemFont(newItem, self.fontComment)
|
||||
elif treeObj.ref:
|
||||
self.SetItemTextColour(newItem, 'DarkGreen')
|
||||
elif treeObj.hasStyle and treeObj.params.get('hidden', False):
|
||||
self.SetItemTextColour(newItem, 'Grey')
|
||||
# Add children items
|
||||
if xxx.hasChildren:
|
||||
treeObj = xxx.treeObject()
|
||||
for n in treeObj.element.childNodes:
|
||||
for n in treeObj.node.childNodes:
|
||||
if IsObject(n):
|
||||
self.AddNode(newItem, treeObj, n)
|
||||
return newItem
|
||||
@@ -605,13 +640,14 @@ class XML_Tree(wx.TreeCtrl):
|
||||
# Remove leaf of tree, return it's data object
|
||||
def RemoveLeaf(self, leaf):
|
||||
xxx = self.GetPyData(leaf)
|
||||
node = xxx.element
|
||||
node = xxx.node
|
||||
parent = node.parentNode
|
||||
parent.removeChild(node)
|
||||
self.Delete(leaf)
|
||||
# Reset selection object
|
||||
self.selection = None
|
||||
return node
|
||||
|
||||
# Find position relative to the top-level window
|
||||
def FindNodePos(self, item, obj=None):
|
||||
# Root at (0,0)
|
||||
@@ -631,17 +667,18 @@ class XML_Tree(wx.TreeCtrl):
|
||||
if g.testWin.highLight:
|
||||
g.testWin.highLight.Remove()
|
||||
break
|
||||
# Find first ancestor which is a wxWindow (not a sizer)
|
||||
# For sizers and notebooks we must select the first window-like parent
|
||||
winParent = itemParent
|
||||
while self.GetPyData(winParent).isSizer:
|
||||
winParent = self.GetItemParent(winParent)
|
||||
# Notebook children are layed out in a little strange way
|
||||
if self.GetPyData(itemParent).treeObject().__class__ == xxxNotebook:
|
||||
parentPos = wx.Point(0,0)
|
||||
else:
|
||||
parentPos = self.FindNodePos(winParent)
|
||||
# Position (-1,-1) is really (0,0)
|
||||
# wxGTK places NB panels relative to the NB parent
|
||||
if wx.Platform == '__WXGTK__':
|
||||
if self.GetPyData(itemParent).treeObject().__class__ == xxxNotebook:
|
||||
winParent = self.GetItemParent(winParent)
|
||||
parentPos = self.FindNodePos(winParent)
|
||||
pos = obj.GetPosition()
|
||||
# Position (-1,-1) is really (0,0)
|
||||
if pos == (-1,-1): pos = (0,0)
|
||||
return parentPos + pos
|
||||
|
||||
@@ -700,7 +737,6 @@ class XML_Tree(wx.TreeCtrl):
|
||||
# If some data was modified, apply changes
|
||||
if g.panel.IsModified():
|
||||
self.Apply(xxx, oldItem)
|
||||
#if conf.autoRefresh:
|
||||
if g.testWin:
|
||||
if g.testWin.highLight:
|
||||
g.testWin.highLight.Remove()
|
||||
@@ -747,16 +783,22 @@ class XML_Tree(wx.TreeCtrl):
|
||||
if not obj or xxx.hasStyle and xxx.params.get('hidden', False):
|
||||
if g.testWin.highLight: g.testWin.highLight.Remove()
|
||||
return
|
||||
pos = self.FindNodePos(item, obj)
|
||||
pos = self.FindNodePos(item, obj)
|
||||
size = obj.GetSize()
|
||||
# Highlight
|
||||
# Negative positions are not working quite well
|
||||
if g.testWin.highLight:
|
||||
g.testWin.highLight.Replace(pos, size)
|
||||
hl = g.testWin.highLight
|
||||
# If highlight object has the same size SetDimension does not repaint it
|
||||
# so we must remove the old HL window
|
||||
if hl and hl.size == size:
|
||||
hl.Remove()
|
||||
hl = None
|
||||
if hl:
|
||||
hl.Replace(pos, size)
|
||||
else:
|
||||
g.testWin.highLight = HighLightBox(pos, size)
|
||||
g.testWin.highLight.Refresh()
|
||||
g.testWin.highLight.item = item
|
||||
g.testWin.highLight = hl = HighLightBox(pos, size)
|
||||
hl.Refresh()
|
||||
hl.item = item
|
||||
|
||||
def ShowTestWindow(self, item):
|
||||
xxx = self.GetPyData(item)
|
||||
@@ -774,7 +816,7 @@ class XML_Tree(wx.TreeCtrl):
|
||||
return
|
||||
# Show item in bold
|
||||
if g.testWin: # Reset old
|
||||
self.Unselect()
|
||||
self.UnselectAll()
|
||||
self.SetItemBold(g.testWin.item, False)
|
||||
try:
|
||||
wx.BeginBusyCursor()
|
||||
@@ -810,19 +852,6 @@ class XML_Tree(wx.TreeCtrl):
|
||||
testWin = g.testWin
|
||||
# Create a window with this resource
|
||||
xxx = self.GetPyData(item).treeObject()
|
||||
|
||||
# If frame
|
||||
# if xxx.__class__ == xxxFrame:
|
||||
# Frame can't have many children,
|
||||
# but it's first child possibly can...
|
||||
# child = self.GetFirstChild(item)[0]
|
||||
# if child.IsOk() and self.GetPyData(child).__class__ == xxxPanel:
|
||||
# # Clean-up before recursive call or error
|
||||
# wx.MemoryFSHandler.RemoveFile('xxx.xrc')
|
||||
# wx.EndBusyCursor()
|
||||
# self.CreateTestWin(child)
|
||||
# return
|
||||
|
||||
# Close old window, remember where it was
|
||||
highLight = None
|
||||
if testWin:
|
||||
@@ -848,7 +877,7 @@ class XML_Tree(wx.TreeCtrl):
|
||||
# Save in memory FS
|
||||
memFile = MemoryFile('xxx.xrc')
|
||||
# Create memory XML file
|
||||
elem = xxx.element.cloneNode(True)
|
||||
elem = xxx.node.cloneNode(True)
|
||||
if not xxx.name:
|
||||
name = 'noname'
|
||||
else:
|
||||
@@ -877,6 +906,10 @@ class XML_Tree(wx.TreeCtrl):
|
||||
if not g.currentEncoding:
|
||||
xmlFlags != xrc.XRC_USE_LOCALE
|
||||
res = xrc.XmlResource('', xmlFlags)
|
||||
xrc.XmlResource.Set(res) # set as global
|
||||
# Register handlers
|
||||
addHandlers()
|
||||
# Same module list
|
||||
res.Load('memory:xxx.xrc')
|
||||
try:
|
||||
if xxx.__class__ == xxxFrame:
|
||||
@@ -907,7 +940,7 @@ class XML_Tree(wx.TreeCtrl):
|
||||
testWin.SetClientSize(testWin.GetBestSize())
|
||||
testWin.Show(True)
|
||||
elif xxx.__class__ == xxxDialog:
|
||||
testWin = g.testWin = res.LoadDialog(None, STD_NAME)
|
||||
testWin = g.testWin = res.LoadDialog(g.frame, STD_NAME)
|
||||
testWin.panel = testWin
|
||||
testWin.Layout()
|
||||
testWin.SetPosition(pos)
|
||||
@@ -917,7 +950,7 @@ class XML_Tree(wx.TreeCtrl):
|
||||
wx.EVT_BUTTON(testWin, wx.ID_CANCEL, self.OnCloseTestWin)
|
||||
elif xxx.__class__ == xxxWizard:
|
||||
wiz = wx.wizard.PreWizard()
|
||||
res.LoadOnObject(wiz, None, STD_NAME, 'wxWizard')
|
||||
res.LoadOnObject(wiz, g.frame, STD_NAME, 'wxWizard')
|
||||
# Find first page (don't know better way)
|
||||
firstPage = None
|
||||
for w in wiz.GetChildren():
|
||||
@@ -959,9 +992,11 @@ class XML_Tree(wx.TreeCtrl):
|
||||
testWin.toolBar = res.LoadToolBar(testWin, STD_NAME)
|
||||
testWin.SetToolBar(testWin.toolBar)
|
||||
testWin.Show(True)
|
||||
# Catch some events, set highlight
|
||||
if testWin:
|
||||
testWin.item = item
|
||||
wx.EVT_CLOSE(testWin, self.OnCloseTestWin)
|
||||
wx.EVT_SIZE(testWin, self.OnSizeTestWin)
|
||||
testWin.highLight = None
|
||||
if highLight and not self.pendingHighLight:
|
||||
self.HighLight(highLight)
|
||||
@@ -974,6 +1009,9 @@ class XML_Tree(wx.TreeCtrl):
|
||||
inf = sys.exc_info()
|
||||
wx.LogError(traceback.format_exception(inf[0], inf[1], None)[-1])
|
||||
wx.LogError('Error loading resource')
|
||||
# Cleanup
|
||||
res.Unload('xxx.xrc')
|
||||
xrc.XmlResource.Set(None)
|
||||
wx.MemoryFSHandler.RemoveFile('xxx.xrc')
|
||||
|
||||
def CloseTestWindow(self):
|
||||
@@ -987,6 +1025,11 @@ class XML_Tree(wx.TreeCtrl):
|
||||
def OnCloseTestWin(self, evt):
|
||||
self.CloseTestWindow()
|
||||
|
||||
def OnSizeTestWin(self, evt):
|
||||
if g.testWin.highLight:
|
||||
self.HighLight(g.testWin.highLight.item)
|
||||
evt.Skip()
|
||||
|
||||
# Return index in parent, for real window children
|
||||
def WindowIndex(self, item):
|
||||
n = 0 # index of sibling
|
||||
@@ -1068,6 +1111,7 @@ class XML_Tree(wx.TreeCtrl):
|
||||
SetMenu(m, pullDownMenu.topLevel)
|
||||
m.AppendSeparator()
|
||||
m.Append(ID_NEW.REF, 'reference...', 'Create object_ref node')
|
||||
m.Append(ID_NEW.COMMENT, 'comment', 'Create comment node')
|
||||
else:
|
||||
xxx = self.GetPyData(item).treeObject()
|
||||
# Check parent for possible child nodes if inserting sibling
|
||||
@@ -1089,8 +1133,12 @@ class XML_Tree(wx.TreeCtrl):
|
||||
m.Enable(ID_NEW.SPACER, False)
|
||||
if xxx.__class__ is not xxxFrame:
|
||||
m.Enable(ID_NEW.MENU_BAR, False)
|
||||
# Add custom controls menu
|
||||
if len(pullDownMenu.custom) > 2:
|
||||
SetMenu(m, [pullDownMenu.custom])
|
||||
m.AppendSeparator()
|
||||
m.Append(ID_NEW.REF, 'reference...', 'Create object_ref node')
|
||||
m.Append(ID_NEW.COMMENT, 'comment', 'Create comment node')
|
||||
# Select correct label for create menu
|
||||
if not needInsert:
|
||||
if self.shift:
|
||||
@@ -1126,11 +1174,12 @@ class XML_Tree(wx.TreeCtrl):
|
||||
SetMenu(m, pullDownMenu.sizers, shift=True)
|
||||
else:
|
||||
SetMenu(m, pullDownMenu.controls, shift=True)
|
||||
id = wx.NewId()
|
||||
menu.AppendMenu(id, 'Replace With', m)
|
||||
if not m.GetMenuItemCount(): menu.Enable(id, False)
|
||||
menu.Append(pullDownMenu.ID_SUBCLASS, 'Subclass...',
|
||||
'Set "subclass" property')
|
||||
if xxx.isElement:
|
||||
id = wx.NewId()
|
||||
menu.AppendMenu(id, 'Replace With', m)
|
||||
if not m.GetMenuItemCount(): menu.Enable(id, False)
|
||||
menu.Append(pullDownMenu.ID_SUBCLASS, 'Subclass...',
|
||||
'Set "subclass" property')
|
||||
menu.AppendSeparator()
|
||||
# Not using standart IDs because we don't want to show shortcuts
|
||||
menu.Append(wx.ID_CUT, 'Cut', 'Cut to the clipboard')
|
||||
@@ -1165,9 +1214,25 @@ class XML_Tree(wx.TreeCtrl):
|
||||
# Item width may have changed
|
||||
# !!! Tric to update tree width (wxGTK, ??)
|
||||
self.SetIndent(self.GetIndent())
|
||||
elif xxx.className == 'comment':
|
||||
self.SetItemText(item, xxx.treeName())
|
||||
# Change tree icon for sizers
|
||||
if isinstance(xxx, xxxBoxSizer):
|
||||
self.SetItemImage(item, xxx.treeImage())
|
||||
# Set global modified state
|
||||
g.frame.SetModified()
|
||||
|
||||
def OnBeginLabelEdit(self, evt):
|
||||
xxx = self.GetPyData(evt.GetItem())
|
||||
if xxx.isElement:
|
||||
evt.Veto()
|
||||
else:
|
||||
evt.Skip()
|
||||
|
||||
def OnEndLabelEdit(self, evt):
|
||||
xxx = self.GetPyData(evt.GetItem())
|
||||
node = xxx.node
|
||||
if not xxx.isElement:
|
||||
node.data = evt.GetLabel()
|
||||
g.panel.SetData(xxx)
|
||||
evt.Skip()
|
||||
|
Reference in New Issue
Block a user