From: Roman Rolinsky Date: Sun, 11 Mar 2007 05:08:45 +0000 (+0000) Subject: Implemented xxxComment. Due to different minidom XML types (Comments X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/b372319fa08ce9b2794040bcdcb82b559d53da25 Implemented xxxComment. Due to different minidom XML types (Comments are not Elements) had to add xxxObject.isElement flag and changed xxxObject.element variable to xxxObject.node (xxxComment is derived from xxxObject to minimize changes in processing). More testing is still needed to verify that things didn't break. Use previous commit (0.1.8-4 release on 2007/03/10) if you need a stable version. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@44764 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/wxPython/wx/tools/XRCed/CHANGES.txt b/wxPython/wx/tools/XRCed/CHANGES.txt index c4bdbc07a5..9936ba3cb6 100644 --- a/wxPython/wx/tools/XRCed/CHANGES.txt +++ b/wxPython/wx/tools/XRCed/CHANGES.txt @@ -1,3 +1,9 @@ +0.1.8-5 +------- + +Implemented comment object for simple one-line comments. No +validation is performed. + 0.1.8-4 ------- diff --git a/wxPython/wx/tools/XRCed/globals.py b/wxPython/wx/tools/XRCed/globals.py index dbf9769279..3da271cea2 100644 --- a/wxPython/wx/tools/XRCed/globals.py +++ b/wxPython/wx/tools/XRCed/globals.py @@ -15,7 +15,7 @@ import sys # Global constants progname = 'XRCed' -version = '0.1.8-4' +version = '0.1.8-5' # Minimal wxWidgets version MinWxVersion = (2,6,0) if wx.VERSION[:3] < MinWxVersion: diff --git a/wxPython/wx/tools/XRCed/panel.py b/wxPython/wx/tools/XRCed/panel.py index 17b09802fa..08600bc384 100644 --- a/wxPython/wx/tools/XRCed/panel.py +++ b/wxPython/wx/tools/XRCed/panel.py @@ -22,7 +22,7 @@ class Panel(wx.Notebook): # Set common button size for parameter buttons bTmp = wx.Button(self, -1, '') import params - params.buttonSize = (self.DLG_SZE(buttonSize)[0], bTmp.GetSize()[1]) + params.buttonSize = (self.DLG_SZE(buttonSizeD)[0], bTmp.GetSize()[1]) bTmp.Destroy() del bTmp @@ -184,7 +184,7 @@ class ParamPage(wx.Panel): param = evt.GetEventObject().GetName() w = self.controls[param] w.Enable(True) - objElem = xxx.element + objElem = xxx.node if evt.IsChecked(): # Ad new text node in order of allParams w.SetValue('') # set empty (default) value @@ -192,7 +192,7 @@ class ParamPage(wx.Panel): elem = g.tree.dom.createElement(param) # Some classes are special if param == 'font': - xxx.params[param] = xxxParamFont(xxx.element, elem) + xxx.params[param] = xxxParamFont(xxx.node, elem) elif param in xxxObject.bitmapTags: xxx.params[param] = xxxParamBitmap(elem) else: @@ -228,7 +228,7 @@ class ParamPage(wx.Panel): name = self.controlName.GetValue() if xxx.name != name: xxx.name = name - xxx.element.setAttribute('name', name) + xxx.node.setAttribute('name', name) for param, w in self.controls.items(): if w.modified: paramObj = xxx.params[param] @@ -284,8 +284,11 @@ class PropPage(ParamPage): for param in xxx.allParams: present = xxx.params.has_key(param) if param in xxx.required: - label = wx.StaticText(self, paramIDs[param], param + ':', - size = (LABEL_WIDTH,-1), name = param) + if isinstance(xxx, xxxComment): + label = None + else: + label = wx.StaticText(self, paramIDs[param], param + ':', + size = (LABEL_WIDTH,-1), name = param) else: # Notebook has one very loooooong parameter if param == 'usenotebooksizer': sParam = 'usesizer:' @@ -304,11 +307,14 @@ class PropPage(ParamPage): typeClass = ParamText control = typeClass(self, param) control.Enable(present) - sizer.AddMany([ (label, 0, wx.ALIGN_CENTER_VERTICAL), - (control, 0, wx.ALIGN_CENTER_VERTICAL | wx.GROW) ]) + # Comment has only one parameter + if isinstance(xxx, xxxComment): + sizer.Add(control, 0, wx.ALIGN_CENTER_VERTICAL | wx.GROW) + else: + sizer.AddMany([ (label, 0, wx.ALIGN_CENTER_VERTICAL), + (control, 0, wx.ALIGN_CENTER_VERTICAL | wx.GROW) ]) self.controls[param] = control topSizer.Add(sizer, 1, wx.ALL | wx.EXPAND, 3) - self.SetAutoLayout(True) self.SetSizer(topSizer) topSizer.Fit(self) def SetValues(self, xxx): diff --git a/wxPython/wx/tools/XRCed/params.py b/wxPython/wx/tools/XRCed/params.py index a246adab9a..3a05721ca0 100644 --- a/wxPython/wx/tools/XRCed/params.py +++ b/wxPython/wx/tools/XRCed/params.py @@ -25,7 +25,10 @@ genericExStyles = [ 'wxWS_EX_PROCESS_UI_UPDATES' ] -buttonSize = (35,-1) # in dialog units, transformed to pixels in panel ctor +# Global var initialized in Panel.__init__ for button size in screen pixels +buttonSize = None +# Button size in dialog units +buttonSizeD = (35,-1) # Class that can properly disable children class PPanel(wx.Panel): @@ -56,8 +59,7 @@ class ParamBinaryOr(PPanel): sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5) self.button = wx.Button(self, self.ID_BUTTON_CHOICES, 'Edit...', size=buttonSize) sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL) - self.SetAutoLayout(True) - self.SetSizerAndFit(sizer) + self.SetSizer(sizer) wx.EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoices) wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) def GetValue(self): @@ -190,8 +192,7 @@ class ParamColour(PPanel): sizer.Add(self.text, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.BOTTOM, 2) self.button = wx.Panel(self, self.ID_BUTTON, wx.DefaultPosition, wx.Size(20, 20)) sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 5) - self.SetAutoLayout(True) - self.SetSizerAndFit(sizer) + self.SetSizer(sizer) self.textModified = False wx.EVT_PAINT(self.button, self.OnPaintButton) wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) @@ -251,8 +252,7 @@ class ParamFont(PPanel): sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5) self.button = wx.Button(self, self.ID_BUTTON_SELECT, 'Select...', size=buttonSize) sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL) - self.SetAutoLayout(True) - self.SetSizerAndFit(sizer) + self.SetSizer(sizer) self.textModified = False wx.EVT_BUTTON(self, self.ID_BUTTON_SELECT, self.OnButtonSelect) wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) @@ -344,8 +344,7 @@ class ParamInt(PPanel): self.spin = wx.SpinCtrl(self, self.ID_SPIN_CTRL, size=(60,-1)) self.spin.SetRange(-2147483648, 2147483647) # min/max integers sizer.Add(self.spin) - self.SetAutoLayout(True) - self.SetSizerAndFit(sizer) + self.SetSizer(sizer) wx.EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange) def GetValue(self): return str(self.spin.GetValue()) @@ -364,8 +363,7 @@ class ParamIntNN(PPanel): self.spin = wx.SpinCtrl(self, self.ID_SPIN_CTRL, size=(60,-1)) self.spin.SetRange(0, 10000) # min/max integers sizer.Add(self.spin) - self.SetAutoLayout(True) - self.SetSizerAndFit(sizer) + self.SetSizer(sizer) wx.EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange) def GetValue(self): return str(self.spin.GetValue()) @@ -388,8 +386,7 @@ class ParamUnit(PPanel): self.spin.SetRange(-10000, 10000) sizer.Add(self.text, 0, wx.EXPAND) sizer.Add(self.spin, 0, wx.EXPAND) - self.SetAutoLayout(True) - self.SetSizerAndFit(sizer) + self.SetSizer(sizer) self.spin.Bind(wx.EVT_SPIN_UP, self.OnSpinUp) self.spin.Bind(wx.EVT_SPIN_DOWN, self.OnSpinDown) def GetValue(self): @@ -434,7 +431,6 @@ class ParamMultilineText(PPanel): sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5) self.button = wx.Button(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize) sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL) - self.SetAutoLayout(True) self.SetSizerAndFit(sizer) wx.EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit) wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) @@ -463,8 +459,7 @@ class ParamText(PPanel): if textWidth == -1: option = 1 else: option = 0 sizer.Add(self.text, option, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.BOTTOM, 2) - self.SetAutoLayout(True) - self.SetSizerAndFit(sizer) + self.SetSizer(sizer) wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) def GetValue(self): return self.text.GetValue() @@ -489,6 +484,10 @@ class ParamEncoding(ParamText): def __init__(self, parent, name): ParamText.__init__(self, parent, name, 100) +class ParamComment(ParamText): + def __init__(self, parent, name): + ParamText.__init__(self, parent, name, 330 + buttonSize[0]) + class ContentDialog(wx.Dialog): def __init__(self, parent, value): # Load from resource @@ -607,8 +606,7 @@ class ParamContent(PPanel): sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5) self.button = wx.Button(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize) sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL) - self.SetAutoLayout(True) - self.SetSizerAndFit(sizer) + self.SetSizer(sizer) self.textModified = False wx.EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit) wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) @@ -747,8 +745,7 @@ class RadioBox(PPanel): button = wx.RadioButton(self, -1, i, size=(-1,buttonSize[1]), name=i) topSizer.Add(button, 0, wx.RIGHT, 5) wx.EVT_RADIOBUTTON(self, button.GetId(), self.OnRadioChoice) - self.SetAutoLayout(True) - self.SetSizerAndFit(topSizer) + self.SetSizer(topSizer) def SetStringSelection(self, value): self.freeze = True for i in self.choices: @@ -806,8 +803,7 @@ class ParamFile(PPanel): sizer.Add(self.text, 0, wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, 5) self.button = wx.Button(self, self.ID_BUTTON_BROWSE, 'Browse...',size=buttonSize) sizer.Add(self.button, 0, wx.ALIGN_CENTER_VERTICAL) - self.SetAutoLayout(True) - self.SetSizerAndFit(sizer) + self.SetSizer(sizer) self.textModified = False wx.EVT_BUTTON(self, self.ID_BUTTON_BROWSE, self.OnButtonBrowse) wx.EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) @@ -934,5 +930,6 @@ paramDict = { 'fg': ParamColour, 'bg': ParamColour, 'font': ParamFont, 'enabled': ParamBool, 'focused': ParamBool, 'hidden': ParamBool, 'tooltip': ParamText, 'bitmap': ParamBitmap, 'icon': ParamBitmap, - 'encoding': ParamEncoding, 'borders': ParamUnit + 'encoding': ParamEncoding, 'borders': ParamUnit, + 'comment': ParamComment } diff --git a/wxPython/wx/tools/XRCed/tree.py b/wxPython/wx/tools/XRCed/tree.py index 9ea2fb3924..abc0a8e452 100644 --- a/wxPython/wx/tools/XRCed/tree.py +++ b/wxPython/wx/tools/XRCed/tree.py @@ -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,7 @@ class ID_NEW: CONTEXT_HELP_BUTTON = wx.NewId() REF = wx.NewId() + COMMENT = wx.NewId() LAST = wx.NewId() @@ -193,10 +196,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 +273,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'), ], @@ -430,6 +437,8 @@ class XML_Tree(wx.TreeCtrl): def __init__(self, parent, id): wx.TreeCtrl.__init__(self, parent, id, style = wx.TR_HAS_BUTTONS | wx.TR_MULTIPLE) self.SetBackgroundColour(wx.Colour(224, 248, 224)) + self.fontComment = wx.Font(g.sysFont().GetPointSize(), wx.DEFAULT, + wx.FONTSTYLE_ITALIC, wx.NORMAL) # Register events wx.EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged) # One works on Linux, another on Windows @@ -450,6 +459,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 +570,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 +594,29 @@ 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') + 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,7 +624,7 @@ 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) @@ -849,7 +868,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: @@ -1076,6 +1095,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 @@ -1099,6 +1119,7 @@ class XML_Tree(wx.TreeCtrl): m.Enable(ID_NEW.MENU_BAR, False) 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: @@ -1134,11 +1155,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') @@ -1173,6 +1195,8 @@ 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()) diff --git a/wxPython/wx/tools/XRCed/undo.py b/wxPython/wx/tools/XRCed/undo.py index a064264b94..4b28a76c38 100644 --- a/wxPython/wx/tools/XRCed/undo.py +++ b/wxPython/wx/tools/XRCed/undo.py @@ -134,11 +134,11 @@ class UndoReplace: item = g.tree.ItemAtFullIndex(self.itemIndex) xxx = g.tree.GetPyData(item) # Replace with old element - parent = xxx.parent.element + parent = xxx.parent.node if xxx is self.xxx: # sizeritem or notebookpage - replace child - parent.replaceChild(self.xxx.child.element, xxx.child.element) + parent.replaceChild(self.xxx.child.node, xxx.child.node) else: - parent.replaceChild(self.xxx.element, xxx.element) + parent.replaceChild(self.xxx.node, xxx.node) self.xxx.parent = xxx.parent xxx = self.xxx g.tree.SetPyData(item, xxx) @@ -191,9 +191,9 @@ class UndoMove: ((parent.isSizer and not isinstance(xxx, xxxSizerItem)) or \ (isinstance(parent, xxxNotebook) and not isinstance(xxx, xxxNotebookPage)) or \ not (parent.isSizer or isinstance(parent, xxxNotebook))): - elem.removeChild(xxx.child.element) # detach child + elem.removeChild(xxx.child.node) # detach child elem.unlink() # delete child container - elem = xxx.child.element # replace + elem = xxx.child.node # replace # This may help garbage collection xxx.child.parent = None isChildContainer = False @@ -227,9 +227,9 @@ class UndoMove: ((parent.isSizer and not isinstance(xxx, xxxSizerItem)) or \ (isinstance(parent, xxxNotebook) and not isinstance(xxx, xxxNotebookPage)) or \ not (parent.isSizer or isinstance(parent, xxxNotebook))): - elem.removeChild(xxx.child.element) # detach child + elem.removeChild(xxx.child.node) # detach child elem.unlink() # delete child container - elem = xxx.child.element # replace + elem = xxx.child.node # replace # This may help garbage collection xxx.child.parent = None isChildContainer = False diff --git a/wxPython/wx/tools/XRCed/xrced.py b/wxPython/wx/tools/XRCed/xrced.py index fbfd96ca4e..11d29e8763 100644 --- a/wxPython/wx/tools/XRCed/xrced.py +++ b/wxPython/wx/tools/XRCed/xrced.py @@ -489,10 +489,14 @@ class Frame(wx.Frame): 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) + if xxx.isElement: + data = wx.CustomDataObject('XRCED') + # Set encoding in header + # (False,True) + s = xxx.node.toxml(encoding=expat.native_encoding) + else: + data = wx.CustomDataObject('XRCED_node') + s = xxx.node.data data.SetData(cPickle.dumps(s)) wx.TheClipboard.SetData(data) wx.TheClipboard.Close() @@ -527,21 +531,28 @@ class Frame(wx.Frame): parent = tree.GetPyData(parentLeaf).treeObject() # Create a copy of clipboard pickled element - success = False + success = success_node = False if wx.TheClipboard.Open(): data = wx.CustomDataObject('XRCED') if wx.TheClipboard.IsSupported(data.GetFormat()): success = wx.TheClipboard.GetData(data) + if not success: # try other format + data = wx.CustomDataObject('XRCED_node') + if wx.TheClipboard.IsSupported(data.GetFormat()): + success_node = wx.TheClipboard.GetData(data) wx.TheClipboard.Close() - if not success: + if not success and not success_node: 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] + if success: + elem = minidom.parseString(xml).childNodes[0] + else: + elem = g.tree.dom.createComment(xml) # Tempopary xxx object to test things xxx = MakeXXXFromDOM(parent, elem) @@ -558,9 +569,9 @@ class Frame(wx.Frame): ((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.removeChild(xxx.child.node) # detach child elem.unlink() # delete child container - elem = xxx.child.element # replace + elem = xxx.child.node # replace # This may help garbage collection xxx.child.parent = None isChildContainer = False @@ -605,6 +616,9 @@ class Frame(wx.Frame): def ItemsAreCompatible(self, parent, child): # Check compatibility error = False + # Comments are always compatible + if child.__class__ == xxxComment: + return True # Top-level if child.__class__ in [xxxDialog, xxxFrame, xxxWizard]: # Top-level classes @@ -732,9 +746,9 @@ class Frame(wx.Frame): ((parent.isSizer and not isinstance(xxx, xxxSizerItem)) or \ (isinstance(parent, xxxNotebook) and not isinstance(xxx, xxxNotebookPage)) or \ not (parent.isSizer or isinstance(parent, xxxNotebook))): - elem.removeChild(xxx.child.element) # detach child + elem.removeChild(xxx.child.node) # detach child elem.unlink() # delete child container - elem = xxx.child.element # replace + elem = xxx.child.node # replace # This may help garbage collection xxx.child.parent = None isChildContainer = False @@ -789,9 +803,9 @@ class Frame(wx.Frame): ((parent.isSizer and not isinstance(xxx, xxxSizerItem)) or \ (isinstance(parent, xxxNotebook) and not isinstance(xxx, xxxNotebookPage)) or \ not (parent.isSizer or isinstance(parent, xxxNotebook))): - elem.removeChild(xxx.child.element) # detach child + elem.removeChild(xxx.child.node) # detach child elem.unlink() # delete child container - elem = xxx.child.element # replace + elem = xxx.child.node # replace # This may help garbage collection xxx.child.parent = None isChildContainer = False @@ -841,14 +855,19 @@ class Frame(wx.Frame): # Prepare undo data panel.Apply() index = tree.ItemFullIndex(selected) + xxx = tree.GetPyData(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) + if xxx.isElement: + data = wx.CustomDataObject('XRCED') + # (False, True) + s = elem.toxml(encoding=expat.native_encoding) + else: + data = wx.CustomDataObject('XRCED_node') + s = xxx.node.data data.SetData(cPickle.dumps(s)) wx.TheClipboard.SetData(data) wx.TheClipboard.Close() @@ -866,7 +885,7 @@ class Frame(wx.Frame): def OnSubclass(self, evt): selected = tree.selection xxx = tree.GetPyData(selected).treeObject() - elem = xxx.element + elem = xxx.node subclass = xxx.subclass dlg = wx.TextEntryDialog(self, 'Subclass:', defaultValue=subclass) if dlg.ShowModal() == wx.ID_OK: @@ -1063,29 +1082,33 @@ Homepage: http://xrced.sourceforge.net\ ref = wx.GetTextFromUser('Create reference to:', 'Create reference') if not ref: return xxx = MakeEmptyRefXXX(parent, ref) + elif evt.GetId() == ID_NEW.COMMENT: + xxx = MakeEmptyCommentXXX(parent) else: # Create empty element className = pullDownMenu.createMap[evt.GetId()] xxx = MakeEmptyXXX(parent, className) - # Set default name for top-level windows - if parent.__class__ == xxxMainNode: - cl = xxx.treeObject().__class__ - frame.maxIDs[cl] += 1 - xxx.setTreeName('%s%d' % (defaultIDs[cl], frame.maxIDs[cl])) - # And for some other standard controls - elif parent.__class__ == xxxStdDialogButtonSizer: - xxx.setTreeName(pullDownMenu.stdButtonIDs[evt.GetId()][0]) - # We can even set label - obj = xxx.treeObject() - elem = g.tree.dom.createElement('label') - elem.appendChild(g.tree.dom.createTextNode(pullDownMenu.stdButtonIDs[evt.GetId()][1])) - obj.params['label'] = xxxParam(elem) - xxx.treeObject().element.appendChild(elem) - # Insert new node, register undo - elem = xxx.element - newItem = tree.InsertNode(parentLeaf, parent, elem, nextItem) + if xxx.isElement: # true object + # Set default name for top-level windows + if parent.__class__ == xxxMainNode: + cl = xxx.treeObject().__class__ + frame.maxIDs[cl] += 1 + xxx.setTreeName('%s%d' % (defaultIDs[cl], frame.maxIDs[cl])) + # And for some other standard controls + elif parent.__class__ == xxxStdDialogButtonSizer: + xxx.setTreeName(pullDownMenu.stdButtonIDs[evt.GetId()][0]) + # We can even set label + obj = xxx.treeObject() + elem = g.tree.dom.createElement('label') + elem.appendChild(g.tree.dom.createTextNode(pullDownMenu.stdButtonIDs[evt.GetId()][1])) + obj.params['label'] = xxxParam(elem) + xxx.treeObject().node.appendChild(elem) + + newItem = tree.InsertNode(parentLeaf, parent, xxx.node, nextItem) + else: # comment node + newItem = tree.InsertNode(parentLeaf, parent, xxx.node, nextItem) undoMan.RegisterUndo(UndoPasteCreate(parentLeaf, parent, newItem, selected)) tree.EnsureVisible(newItem) tree.SelectItem(newItem) @@ -1093,7 +1116,7 @@ Homepage: http://xrced.sourceforge.net\ tree.ScrollTo(newItem) tree.Refresh() # Update view? - if g.testWin and tree.IsHighlatable(newItem): + if xxx.isElement and g.testWin and tree.IsHighlatable(newItem): if conf.autoRefresh: tree.needUpdate = True tree.pendingHighLight = newItem @@ -1106,7 +1129,7 @@ Homepage: http://xrced.sourceforge.net\ def OnReplace(self, evt): selected = tree.selection xxx = tree.GetPyData(selected).treeObject() - elem = xxx.element + elem = xxx.node parent = elem.parentNode undoMan.RegisterUndo(UndoReplace(selected)) # New class @@ -1383,6 +1406,10 @@ Homepage: http://xrced.sourceforge.net\ return True def Indent(self, node, indent = 0): + if node.nodeType == minidom.Node.COMMENT_NODE: + text = self.domCopy.createTextNode('\n' + ' ' * indent) + node.parentNode.insertBefore(text, node) + return # no children # Copy child list because it will change soon children = node.childNodes[:] # Main node doesn't need to be indented @@ -1396,7 +1423,8 @@ Homepage: http://xrced.sourceforge.net\ node.appendChild(text) # Indent children which are elements for n in children: - if n.nodeType == minidom.Node.ELEMENT_NODE: + if n.nodeType == minidom.Node.ELEMENT_NODE or \ + n.nodeType == minidom.Node.COMMENT_NODE: self.Indent(n, indent + 2) def Save(self, path): diff --git a/wxPython/wx/tools/XRCed/xrced.xrc b/wxPython/wx/tools/XRCed/xrced.xrc index 16ba037d94..59c625a1c2 100644 --- a/wxPython/wx/tools/XRCed/xrced.xrc +++ b/wxPython/wx/tools/XRCed/xrced.xrc @@ -1,5 +1,6 @@ + Text Dialog 1 @@ -619,4 +620,4 @@ - \ No newline at end of file + diff --git a/wxPython/wx/tools/XRCed/xxx.py b/wxPython/wx/tools/XRCed/xxx.py index 7226d26d91..659ddebfcc 100644 --- a/wxPython/wx/tools/XRCed/xxx.py +++ b/wxPython/wx/tools/XRCed/xxx.py @@ -189,6 +189,7 @@ class xxxObject: hasStyle = True # almost everyone hasName = True # has name attribute? isSizer = hasChild = False + isElement = True allParams = None # Some nodes have no parameters # Style parameters (all optional) styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'tooltip'] @@ -210,7 +211,7 @@ class xxxObject: # parent is parent xxx object (or None if none), element is DOM element object def __init__(self, parent, element, refElem=None): self.parent = parent - self.element = element + self.node = element self.refElem = refElem self.undo = None # Reference are dereferenced @@ -230,33 +231,32 @@ class xxxObject: if self.hasName: self.name = element.getAttribute('name') # Set parameters (text element children) self.params = {} - nodes = element.childNodes[:] - for node in nodes: - if node.nodeType == minidom.Node.ELEMENT_NODE: - tag = node.tagName + for n in element.childNodes[:]: + if n.nodeType == minidom.Node.ELEMENT_NODE: + tag = n.tagName if tag in ['object', 'object_ref']: continue # do nothing for object children here elif tag not in self.allParams and tag not in self.styles: print 'WARNING: unknown parameter for %s: %s' % \ (self.className, tag) elif tag in self.specials: - self.special(tag, node) + self.special(tag, n) elif tag == 'content': if self.className == 'wxCheckListBox': - self.params[tag] = xxxParamContentCheckList(node) + self.params[tag] = xxxParamContentCheckList(n) else: - self.params[tag] = xxxParamContent(node) + self.params[tag] = xxxParamContent(n) elif tag == 'font': # has children - self.params[tag] = xxxParamFont(element, node) + self.params[tag] = xxxParamFont(element, n) elif tag in self.bitmapTags: # Can have attributes - self.params[tag] = xxxParamBitmap(node) + self.params[tag] = xxxParamBitmap(n) else: # simple parameter - self.params[tag] = xxxParam(node) - elif node.nodeType == minidom.Node.TEXT_NODE and node.data.isspace(): + self.params[tag] = xxxParam(n) + elif n.nodeType == minidom.Node.TEXT_NODE and n.data.isspace(): # Remove empty text nodes - element.removeChild(node) - node.unlink() + element.removeChild(n) + n.unlink() # Check that all required params are set for param in self.required: @@ -281,9 +281,9 @@ class xxxObject: break if found: nextTextElem = self.params[p].node - self.element.insertBefore(elem, nextTextElem) + self.node.insertBefore(elem, nextTextElem) else: - self.element.appendChild(elem) + self.node.appendChild(elem) else: wx.LogWarning('Required parameter %s of %s missing' % (param, self.className)) @@ -313,7 +313,7 @@ class xxxObject: if self.hasChild: obj = self.child else: obj = self obj.name = name - obj.element.setAttribute('name', name) + obj.node.setAttribute('name', name) # Special processing for growablecols-like parameters # represented by several nodes def special(self, tag, node): @@ -329,7 +329,7 @@ class xxxObject: node = g.tree.dom.createElement(param) text = g.tree.dom.createTextNode(str(i)) node.appendChild(text) - self.element.appendChild(node) + self.node.appendChild(node) self.special(param, node) # Imitation of FindResource/DoFindResource from xmlres.cpp @@ -377,7 +377,7 @@ class xxxParamFont(xxxObject, xxxNode): self.data = v def update(self, value): # `value' is a list of strings corresponding to all parameters - elem = self.element + elem = self.node # Remove old elements first childNodes = elem.childNodes[:] for node in childNodes: elem.removeChild(node) @@ -655,6 +655,16 @@ class xxxDateCtrl(xxxObject): winStyles = ['wxDP_DEFAULT', 'wxDP_SPIN', 'wxDP_DROPDOWN', 'wxDP_ALLOWNONE', 'wxDP_SHOWCENTURY'] +class xxxGrid(xxxObject): + allParams = ['pos', 'size', 'style'] + +class xxxFilePickerCtrl(xxxObject): + allParams = ['value', 'message', 'wildcard', 'pos', 'size', 'style'] + winStyles = ['wxFLP_OPEN', 'wxFLP_SAVE', 'wxFLP_OVERWRITE_PROMPT', + 'wxFLP_FILE_MUST_EXIST', 'wxFLP_CHANGE_DIR', + 'wxFLP_DEFAULT_STYLE'] + + ################################################################################ # Buttons @@ -905,6 +915,31 @@ class xxxUnknown(xxxObject): allParams = ['pos', 'size', 'style'] winStyles = ['wxNO_FULL_REPAINT_ON_RESIZE'] +################################################################################ +# Comment + +class xxxParamComment(xxxParam): + def __init__(self, node): + xxxNode.__init__(self, node) + self.textNode = node + +class xxxComment(xxxObject): + hasStyle = hasName = False + allParams = required = ['comment'] + + def __init__(self, parent, node): + self.parent = parent + self.node = node + self.isElement = False + self.undo = None + self.className = 'comment' + self.ref = self.subclass = None + self.params = {'comment': xxxParamComment(node)} + + def treeName(self): + # Replace newlines by \n to avoid tree item resizing + return self.params['comment'].value().replace('\n', r'\n') + ################################################################################ xxxDict = { @@ -956,6 +991,8 @@ xxxDict = { 'wxGenericDirCtrl': xxxGenericDirCtrl, 'wxSpinCtrl': xxxSpinCtrl, 'wxScrolledWindow': xxxScrolledWindow, + 'wxGrid': xxxGrid, + 'wxFilePickerCtrl': xxxFilePickerCtrl, 'wxDatePickerCtrl': xxxDateCtrl, 'wxBoxSizer': xxxBoxSizer, @@ -973,13 +1010,15 @@ xxxDict = { 'separator': xxxSeparator, 'unknown': xxxUnknown, + 'comment': xxxComment, } # Create IDs for all parameters of all classes paramIDs = {'fg': wx.NewId(), 'bg': wx.NewId(), 'exstyle': wx.NewId(), 'font': wx.NewId(), 'enabled': wx.NewId(), 'focused': wx.NewId(), 'hidden': wx.NewId(), 'tooltip': wx.NewId(), 'encoding': wx.NewId(), - 'cellpos': wx.NewId(), 'cellspan': wx.NewId() + 'cellpos': wx.NewId(), 'cellspan': wx.NewId(), + 'text': wx.NewId() } for cl in xxxDict.values(): if cl.allParams: @@ -992,25 +1031,29 @@ for cl in xxxDict.values(): # Test for object elements def IsObject(node): - return node.nodeType == minidom.Node.ELEMENT_NODE and node.tagName in ['object', 'object_ref'] + return node.nodeType == minidom.Node.ELEMENT_NODE and \ + node.tagName in ['object', 'object_ref'] or \ + node.nodeType == minidom.Node.COMMENT_NODE # Make XXX object from some DOM object, selecting correct class -def MakeXXXFromDOM(parent, element): - if element.tagName == 'object_ref': - ref = element.getAttribute('ref') +def MakeXXXFromDOM(parent, node): + if node.nodeType == minidom.Node.COMMENT_NODE: + return xxxComment(parent, node) + if node.tagName == 'object_ref': + ref = node.getAttribute('ref') refElem = FindResource(ref) if refElem: cls = refElem.getAttribute('class') - else: return xxxUnknown(parent, element) + else: return xxxUnknown(parent, node) else: refElem = None - cls = element.getAttribute('class') + cls = node.getAttribute('class') try: klass = xxxDict[cls] except KeyError: # If we encounter a weird class, use unknown template - print 'WARNING: unsupported class:', element.getAttribute('class') + print 'WARNING: unsupported class:', node.getAttribute('class') klass = xxxUnknown - return klass(parent, element, refElem) + return klass(parent, node, refElem) # Make empty DOM element def MakeEmptyDOM(className): @@ -1090,3 +1133,15 @@ def MakeEmptyRefXXX(parent, ref): #xxx.allParams.remove('label') return xxx +# Make empty comment node +def MakeEmptyCommentDOM(): + node = g.tree.dom.createComment('') + return node + +# Make empty xxxComment +def MakeEmptyCommentXXX(parent): + node = MakeEmptyCommentDOM() + # Now just make object + xxx = MakeXXXFromDOM(parent, node) + return xxx +