diff --git a/wxPython/wxPython/tools/XRCed/CHANGES.txt b/wxPython/wxPython/tools/XRCed/CHANGES.txt index f4304e4396..1462da7fd1 100644 --- a/wxPython/wxPython/tools/XRCed/CHANGES.txt +++ b/wxPython/wxPython/tools/XRCed/CHANGES.txt @@ -1,3 +1,18 @@ +0.1.1-2 +------- + +Bugs with currentEncoding and frame testing fixed. + +Some required parameters are set to default if missing. + +Unsupported classes are tolerated, with warning message. + +wxScrolledWindow added (to 'control' pulldown menu, not yet to the +tool palette). + +Multi-line editing for labels and some values (wxTextCtrl, +wxHtmlWindow). + 0.1.1-1 ------- @@ -24,6 +39,7 @@ Fixed double-refreshing after Ctrl+R. Maybe something else that I've forgot. It's been a looong day... :) + 0.0.9-6 ------- diff --git a/wxPython/wxPython/tools/XRCed/globals.py b/wxPython/wxPython/tools/XRCed/globals.py index e40180220d..9b6332e28f 100644 --- a/wxPython/wxPython/tools/XRCed/globals.py +++ b/wxPython/wxPython/tools/XRCed/globals.py @@ -15,7 +15,7 @@ modernFont = wxFont(sysFont.GetPointSize(), wxMODERN, wxNORMAL, wxNORMAL) smallerFont = wxFont(sysFont.GetPointSize()-2, wxDEFAULT, wxNORMAL, wxNORMAL) progname = 'XRCed' -version = '0.1.1-1' +version = '0.1.1-2' try: True @@ -34,5 +34,6 @@ class Globals: testWin = None testWinPos = wxDefaultPosition currentXXX = None + currentEncoding = sys.getdefaultencoding() # wxLocale_GetSystemEncodingName() g = Globals() diff --git a/wxPython/wxPython/tools/XRCed/params.py b/wxPython/wxPython/tools/XRCed/params.py index 5869b9a74d..53685901da 100644 --- a/wxPython/wxPython/tools/XRCed/params.py +++ b/wxPython/wxPython/tools/XRCed/params.py @@ -350,6 +350,50 @@ class ParamUnit(PPanel): def OnSpinDown(self, evt): self.Change(-1) +# Dialog for editing multi-line text +class TextDialog(wxDialogPtr): + def __init__(self, parent, value): + # Is this normal??? + w = g.frame.res.LoadDialog(parent, 'DIALOG_TEXT') + wxDialogPtr.__init__(self, w.this) + self.thisown = 1 + self.text = self.FindWindowByName('TEXT') + self.text.SetValue(value) + self.SetAutoLayout(True) + self.SetSize((300,200)) + def GetValue(self): + return self.text.GetValue() + +class ParamMultilineText(PPanel): + def __init__(self, parent, name, textWidth=-1): + PPanel.__init__(self, parent, name) + self.ID_TEXT_CTRL = wxNewId() + self.ID_BUTTON_EDIT = wxNewId() + self.SetBackgroundColour(g.panel.GetBackgroundColour()) + sizer = wxBoxSizer() + self.SetBackgroundColour(g.panel.GetBackgroundColour()) + self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(200,-1)) + sizer.Add(self.text, 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 5) + self.button = wxButton(self, self.ID_BUTTON_EDIT, 'Edit...', size=buttonSize) + sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL) + self.SetAutoLayout(True) + self.SetSizer(sizer) + sizer.Fit(self) + EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit) + EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange) + def GetValue(self): + return self.text.GetValue() + def SetValue(self, value): + self.freeze = True # disable other handlers + self.text.SetValue(value) + self.freeze = False # disable other handlers + def OnButtonEdit(self, evt): + dlg = TextDialog(self, self.text.GetValue()) + if dlg.ShowModal() == wxID_OK: + self.text.SetValue(dlg.GetValue()) + self.SetModified() + dlg.Destroy() + class ParamText(PPanel): def __init__(self, parent, name, textWidth=-1): PPanel.__init__(self, parent, name) @@ -395,7 +439,6 @@ class ContentDialog(wxDialogPtr): # Perform initialization with class pointer wxDialogPtr.__init__(self, w.this) self.thisown = 1 - self.Center() self.list = self.FindWindowByName('LIST') # Set list items for v in value: @@ -445,7 +488,6 @@ class ContentCheckListDialog(wxDialogPtr): w = g.frame.res.LoadDialog(parent, 'DIALOG_CONTENT_CHECK_LIST') wxDialogPtr.__init__(self, w.this) self.thisown = 1 - self.Center() self.list = self.FindWindowByName('CHECK_LIST') # Set list items i = 0 @@ -579,7 +621,6 @@ class IntListDialog(wxDialogPtr): w = g.frame.res.LoadDialog(parent, 'DIALOG_INTLIST') wxDialogPtr.__init__(self, w.this) self.thisown = 1 - self.Center() self.list = self.FindWindowByName('LIST') # Set list items value.sort() @@ -598,6 +639,7 @@ class IntListDialog(wxDialogPtr): EVT_UPDATE_UI(self, self.ID_BUTTON_REMOVE, self.OnUpdateUI) def OnButtonAppend(self, evt): s = wxGetTextFromUser('Enter new number:', 'Add', '', self) + if not s: return # Check that it's unique try: v = int(s) @@ -827,11 +869,11 @@ paramDict = { 'vgap': ParamUnit, 'hgap': ParamUnit, 'checkable': ParamBool, 'checked': ParamBool, 'radio': ParamBool, 'accel': ParamAccel, - 'label': ParamText, 'title': ParamText, 'value': ParamText, + 'label': ParamMultilineText, 'title': ParamText, 'value': ParamText, 'content': ParamContent, 'selection': ParamInt, 'min': ParamInt, 'max': ParamInt, 'fg': ParamColour, 'bg': ParamColour, 'font': ParamFont, 'enabled': ParamBool, 'focused': ParamBool, 'hidden': ParamBool, 'tooltip': ParamText, 'bitmap': ParamBitmap, 'icon': ParamBitmap, - 'label': ParamLabel, 'encoding': ParamEncoding + 'encoding': ParamEncoding } diff --git a/wxPython/wxPython/tools/XRCed/src-images/TreeToolBar.png b/wxPython/wxPython/tools/XRCed/src-images/TreeToolBar.png index bae7ec3efc..aaaae233a0 100644 Binary files a/wxPython/wxPython/tools/XRCed/src-images/TreeToolBar.png and b/wxPython/wxPython/tools/XRCed/src-images/TreeToolBar.png differ diff --git a/wxPython/wxPython/tools/XRCed/tree.py b/wxPython/wxPython/tools/XRCed/tree.py index 9de7f6b026..bdc9d3b3b7 100644 --- a/wxPython/wxPython/tools/XRCed/tree.py +++ b/wxPython/wxPython/tools/XRCed/tree.py @@ -68,6 +68,7 @@ class ID_NEW: LIST_CTRL = wxNewId() CHECK_LIST = wxNewId() NOTEBOOK = wxNewId() + SCROLLED_WINDOW = wxNewId() HTML_WINDOW = wxNewId() CALENDAR_CTRL = wxNewId() GENERIC_DIR_CTRL = wxNewId() @@ -137,6 +138,7 @@ class PullDownMenu: ID_NEW.LIST_CTRL: 'wxListCtrl', ID_NEW.CHECK_LIST: 'wxCheckList', ID_NEW.NOTEBOOK: 'wxNotebook', + ID_NEW.SCROLLED_WINDOW: 'wxScrolledWindow', ID_NEW.HTML_WINDOW: 'wxHtmlWindow', ID_NEW.CALENDAR_CTRL: 'wxCalendarCtrl', ID_NEW.GENERIC_DIR_CTRL: 'wxGenericDirCtrl', @@ -186,6 +188,7 @@ class PullDownMenu: (ID_NEW.TREE_CTRL, 'TreeCtrl', 'Create tree'), (ID_NEW.LIST_CTRL, 'ListCtrl', 'Create list'), (ID_NEW.CHECK_LIST, 'CheckList', 'Create check list'), + (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.GENERIC_DIR_CTRL, 'GenericDirCtrl', 'Create generic dir control'), @@ -680,7 +683,7 @@ class XML_Tree(wxTreeCtrl): memFile.close() # write to wxMemoryFS xmlFlags = wxXRC_NO_SUBCLASSING # Use translations if encoding is not specified - if xxx.currentEncoding == 'ascii': + if g.currentEncoding == 'ascii': xmlFlags != wxXRC_USE_LOCALE res = wxXmlResource('', xmlFlags) res.Load('memory:xxx.xrc') diff --git a/wxPython/wxPython/tools/XRCed/xrced.py b/wxPython/wxPython/tools/XRCed/xrced.py index ae328a759c..8674d1c12b 100644 --- a/wxPython/wxPython/tools/XRCed/xrced.py +++ b/wxPython/wxPython/tools/XRCed/xrced.py @@ -714,10 +714,10 @@ Homepage: http://xrced.sourceforge.net\ #undoMan.RegisterUndo(UndoPasteCreate(parentLeaf, parent, newItem, selected)) # Update view? - if g.testWin and tree.IsHighlatable(newItem): + if g.testWin and tree.IsHighlatable(selected): if conf.autoRefresh: tree.needUpdate = True - tree.pendingHighLight = newItem + tree.pendingHighLight = selected else: tree.pendingHighLight = None tree.SetFocus() @@ -821,13 +821,12 @@ Homepage: http://xrced.sourceforge.net\ f.seek(0) dom = minidom.parse(f) # Set encoding global variable and document encoding property - import xxx if mo: - dom.encoding = xxx.currentEncoding = mo.group('encd') + dom.encoding = g.currentEncoding = mo.group('encd') if dom.encoding not in ['ascii', sys.getdefaultencoding()]: wxLogWarning('Encoding is different from system default') else: - xxx.currentEncoding = 'ascii' + g.currentEncoding = 'ascii' dom.encoding = '' f.close() # Change dir diff --git a/wxPython/wxPython/tools/XRCed/xrced.xrc b/wxPython/wxPython/tools/XRCed/xrced.xrc index f79590b319..cc9554f0c5 100644 --- a/wxPython/wxPython/tools/XRCed/xrced.xrc +++ b/wxPython/wxPython/tools/XRCed/xrced.xrc @@ -1,7 +1,55 @@ + + Text Dialog + 1 + + wxVERTICAL + + + wxHORIZONTAL + + + + + + wxALL|wxEXPAND + 5 + + + + wxEXPAND + + + + wxEXPAND + + + + wxHORIZONTAL + + + + 1 + + wxRIGHT + 10 + + + + + + + + wxALL|wxALIGN_CENTRE_HORIZONTAL + 10 + + + + Content + 1 250,300 wxVERTICAL @@ -86,6 +134,7 @@ Content + 1 250,300 wxVERTICAL @@ -170,6 +219,7 @@ Numbers + 1 100,300 wxVERTICAL diff --git a/wxPython/wxPython/tools/XRCed/xxx.py b/wxPython/wxPython/tools/XRCed/xxx.py index fe0fbad82b..c5ba936c62 100644 --- a/wxPython/wxPython/tools/XRCed/xxx.py +++ b/wxPython/wxPython/tools/XRCed/xxx.py @@ -8,8 +8,6 @@ from xml.dom import minidom from globals import * from params import * -currentEncoding = sys.getdefaultencoding() # wxLocale_GetSystemEncodingName() - # Base class for interface parameter classes class xxxNode: def __init__(self, node): @@ -30,6 +28,15 @@ class xxxParam(xxxNode): else: text = node.childNodes[0] # first child must be text node assert text.nodeType == minidom.Node.TEXT_NODE + # Append other text nodes if present and delete them + extraText = '' + for n in node.childNodes[1:]: + if n.nodeType == minidom.Node.TEXT_NODE: + extraText += n.data + node.removeChild(n) + n.unlink() + else: break + if extraText: text.data = text.data + extraText # Use convertion from unicode to current encoding self.textNode = text # Value returns string @@ -40,9 +47,9 @@ class xxxParam(xxxNode): self.textNode.data = value else: def value(self): - return self.textNode.data.encode(currentEncoding) + return self.textNode.data.encode(g.currentEncoding) def update(self, value): - self.textNode.data = unicode(value, currentEncoding) + self.textNode.data = unicode(value, g.currentEncoding) # Integer parameter class xxxParamInt(xxxParam): @@ -236,7 +243,13 @@ class xxxObject: # If default is specified, set it if self.default.has_key(param): elem = g.tree.dom.createElement(param) - self.params[param] = xxxParam(elem) + if param == 'content': + if self.className == 'wxCheckList': + self.params[param] = xxxParamContentCheckList(elem) + else: + self.params[param] = xxxParamContent(elem) + else: + self.params[param] = xxxParam(elem) # Find place to put new element: first present element after param found = False paramStyles = self.allParams + self.styles @@ -346,6 +359,7 @@ class xxxDialog(xxxContainer): allParams = ['title', 'centered', 'pos', 'size', 'style'] paramDict = {'centered': ParamBool} required = ['title'] + default = {'title': ''} winStyles = ['wxDEFAULT_DIALOG_STYLE', 'wxSTAY_ON_TOP', 'wxDIALOG_MODAL', 'wxDIALOG_MODELESS', 'wxCAPTION', 'wxSYSTEM_MENU', 'wxRESIZE_BORDER', 'wxRESIZE_BOX', @@ -359,6 +373,7 @@ class xxxFrame(xxxContainer): allParams = ['title', 'centered', 'pos', 'size', 'style'] paramDict = {'centered': ParamBool} required = ['title'] + default = {'title': ''} winStyles = ['wxDEFAULT_FRAME_STYLE', 'wxDEFAULT_DIALOG_STYLE', 'wxSTAY_ON_TOP', 'wxCAPTION', 'wxSYSTEM_MENU', 'wxRESIZE_BORDER', @@ -417,10 +432,12 @@ class xxxTextCtrl(xxxObject): allParams = ['value', 'pos', 'size', 'style'] winStyles = ['wxTE_PROCESS_ENTER', 'wxTE_PROCESS_TAB', 'wxTE_MULTILINE', 'wxTE_PASSWORD', 'wxTE_READONLY', 'wxHSCROLL'] + paramDict = {'value': ParamMultilineText} class xxxChoice(xxxObject): allParams = ['content', 'selection', 'pos', 'size', 'style'] required = ['content'] + default = {'content': '[]'} winStyles = ['wxCB_SORT'] class xxxSlider(xxxObject): @@ -461,7 +478,7 @@ class xxxTreeCtrl(xxxObject): class xxxHtmlWindow(xxxObject): allParams = ['pos', 'size', 'style', 'borders', 'url', 'htmlcode'] - paramDict = {'borders': ParamInt} + paramDict = {'borders': ParamInt, 'htmlcode':ParamMultilineText} winStyles = ['wxHW_SCROLLBAR_NEVER', 'wxHW_SCROLLBAR_AUTO'] class xxxCalendarCtrl(xxxObject): @@ -478,6 +495,10 @@ class xxxGenericDirCtrl(xxxObject): winStyles = ['wxDIRCTRL_DIR_ONLY', 'wxDIRCTRL_3D_INTERNAL', 'wxDIRCTRL_SELECT_FIRST', 'wxDIRCTRL_SHOW_FILTERS', 'wxDIRCTRL_EDIT_LABELS'] +class xxxScrolledWindow(xxxObject): + allParams = ['pos', 'size', 'style'] + winStyles = ['wxHSCROLL', 'wxVSCROLL'] + ################################################################################ # Buttons @@ -521,6 +542,7 @@ class xxxRadioBox(xxxObject): allParams = ['label', 'content', 'selection', 'dimension', 'pos', 'size', 'style'] paramDict = {'dimension': ParamInt} required = ['label', 'content'] + default = {'content': '[]'} winStyles = ['wxRA_SPECIFY_ROWS', 'wxRA_SPECIFY_COLS'] class xxxCheckBox(xxxObject): @@ -531,17 +553,20 @@ class xxxCheckBox(xxxObject): class xxxComboBox(xxxObject): allParams = ['content', 'selection', 'value', 'pos', 'size', 'style'] required = ['content'] + default = {'content': '[]'} winStyles = ['wxCB_SIMPLE', 'wxCB_SORT', 'wxCB_READONLY', 'wxCB_DROPDOWN'] class xxxListBox(xxxObject): allParams = ['content', 'selection', 'pos', 'size', 'style'] required = ['content'] + default = {'content': '[]'} winStyles = ['wxLB_SINGLE', 'wxLB_MULTIPLE', 'wxLB_EXTENDED', 'wxLB_HSCROLL', 'wxLB_ALWAYS_SB', 'wxLB_NEEDED_SB', 'wxLB_SORT'] class xxxCheckList(xxxObject): allParams = ['content', 'pos', 'size', 'style'] required = ['content'] + default = {'content': '[]'} winStyles = ['wxLC_LIST', 'wxLC_REPORT', 'wxLC_ICON', 'wxLC_SMALL_ICON', 'wxLC_ALIGN_TOP', 'wxLC_ALIGN_LEFT', 'wxLC_AUTOARRANGE', 'wxLC_USER_TEXT', 'wxLC_EDIT_LABELS', 'wxLC_NO_HEADER', @@ -732,6 +757,7 @@ xxxDict = { 'wxCalendarCtrl': xxxCalendarCtrl, 'wxGenericDirCtrl': xxxGenericDirCtrl, 'wxSpinCtrl': xxxSpinCtrl, + 'wxScrolledWindow': xxxScrolledWindow, 'wxBoxSizer': xxxBoxSizer, 'wxStaticBoxSizer': xxxStaticBoxSizer, @@ -771,9 +797,9 @@ def MakeXXXFromDOM(parent, element): try: klass = xxxDict[element.getAttribute('class')] except KeyError: - # Verify that it's not recursive exception - print 'ERROR: unknown class:', element.getAttribute('class') - raise + # If we encounter a weird class, use unknown template + print 'WARNING: unsupported class:', element.getAttribute('class') + klass = xxxUnknown return klass(parent, element) # Make empty DOM element