from wxPython.wx import *
from wxPython.xrc import *
-from wxPython.html import *
+from wxPython.html import wxHtmlWindow
from xml.dom import minidom
import os
-import tempfile
import getopt
# Icons
# Constants
-if wxGetOsVersion()[1] == 1:
+# Return code from wxGetOsVersion
+wxGTK = 9
+
+if wxGetOsVersion()[0] == wxGTK:
labelFont = wxFont(12, wxDEFAULT, wxNORMAL, wxBOLD)
+ modernFont = wxFont(12, wxMODERN, wxNORMAL, wxNORMAL)
else:
labelFont = wxFont(10, wxDEFAULT, wxNORMAL, wxBOLD)
+ modernFont = wxFont(10, wxMODERN, wxNORMAL, wxNORMAL)
progname = 'XRCed'
-version = '0.0.7-1'
+version = '0.0.7-3'
# Local modules
from xxx import *
else:
# Remove page if exists
if self.GetPageCount() == 2:
+ self.SetSelection(0)
+ self.page1.Refresh()
self.RemovePage(1)
def Clear(self):
self.SetData(None)
w.SetValue('') # set empty (default) value
w.SetModified() # mark as changed
elem = tree.dom.createElement(param)
- xxx.params[param] = xxxParam(elem)
+ # Some classes are special
+ if param == 'font':
+ xxx.params[param] = xxxParamFont(xxx.element, elem)
+ else:
+ xxx.params[param] = xxxParam(elem)
# Find place to put new element: first present element after param
found = false
paramStyles = xxx.allParams + xxx.styles
topSizer = wxStaticBoxSizer(box, wxVERTICAL)
sizer = wxFlexGridSizer(len(xxx.allParams), 2, 1, 1)
if xxx.hasName:
- label = wxStaticText(self, -1, 'XML ID:', size=(80,-1))
+ label = wxStaticText(self, -1, 'XML ID:', size=(100,-1))
control = ParamText(self, name='XML_name')
sizer.AddMany([ (label, 0, wxALIGN_CENTER_VERTICAL),
(control, 0, wxALIGN_CENTER_VERTICAL) ])
present = param in xxx.params
if param in xxx.required:
label = wxStaticText(self, paramIDs[param], param + ':',
- size = (80,-1), name = param)
+ size = (100,-1), name = param)
else:
# Notebook has one very loooooong parameter
if param == 'usenotebooksizer': sParam = 'usesizer:'
else: sParam = param + ':'
label = wxCheckBox(self, paramIDs[param], sParam,
- size = (80,-1), name = param)
+ size = (100,-1), name = param)
self.checks[param] = label
try:
typeClass = xxx.paramDict[param]
sizer.AddMany([ (label, 0, wxALIGN_CENTER_VERTICAL),
(control, 0, wxALIGN_CENTER_VERTICAL) ])
self.controls[param] = control
- topSizer.Add(sizer, 1, wxALL | wxEXPAND, 5)
+ topSizer.Add(sizer, 1, wxALL | wxEXPAND, 3)
self.SetAutoLayout(true)
self.SetSizer(topSizer)
topSizer.Fit(self)
for param in xxx.styles:
present = param in xxx.params.keys()
check = wxCheckBox(self, paramIDs[param],
- param + ':', size = (80,-1), name = param)
+ param + ':', size = (100,-1), name = param)
check.SetValue(present)
control = paramDict[param](self, name = param)
control.Enable(present)
(control, 0, wxALIGN_CENTER_VERTICAL) ])
self.checks[param] = check
self.controls[param] = control
- topSizer.Add(sizer, 1, wxALL | wxEXPAND, 5)
+ topSizer.Add(sizer, 1, wxALL | wxEXPAND, 3)
self.SetAutoLayout(true)
self.SetSizer(topSizer)
topSizer.Fit(self)
present = param in xxx.params.keys()
check = self.checks[param]
check.SetValue(present)
- control = self.controls[param]
+ w = self.controls[param]
+ w.modified = false
if present:
- control.SetValue(xxx.params[param].value())
+ w.SetValue(xxx.params[param].value())
else:
- control.SetValue('')
- control.Enable(present)
+ w.SetValue('')
+ w.Enable(present)
self.SetModified(false)
################################################################################
self.SetBackgroundColour(wxColour(224, 248, 224))
EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
# One works on Linux, another on Windows
- if wxGetOsVersion()[1] == 1:
+ if wxGetOsVersion()[0] == wxGTK:
EVT_TREE_ITEM_ACTIVATED(self, self.GetId(), self.OnItemActivated)
else:
EVT_LEFT_DCLICK(self, self.OnDClick)
self.needUpdate = false
self.pendingHighLight = None
- self.ctrl = false
+ self.ctrl = self.shift = false
self.dom = None
# Create image list
il = wxImageList(16, 16, true)
except:
print 'ERROR: MakeXXXFromDom(%s, %s)' % (xxxParent, node)
raise
-# return
treeObj = xxx.treeObject()
# Append tree item
item = self.AppendItem(itemParent, treeObj.treeName(),
return node
# Find position relative to the top-level window
def FindNodePos(self, item):
+ # Root at (0,0)
+ if item == testWin.item: return wxPoint(0, 0)
itemParent = self.GetItemParent(item)
# Select NB page
obj = self.FindNodeObject(item)
if notebook.GetPage(i) == obj:
if notebook.GetSelection() != i: notebook.SetSelection(i)
break
- # Root at (0,0)
- if itemParent == self.root: return wxPoint(0, 0)
# Find first ancestor which is a wxWindow (not a sizer)
winParent = itemParent
while self.GetPyData(winParent).isSizer:
return parentPos + pos
# Find window (or sizer) corresponding to a tree item.
def FindNodeObject(self, item):
+ if item == testWin.item: return testWin.panel
itemParent = self.GetItemParent(item)
# If top-level, return testWin (or panel if wxFrame)
- if itemParent == self.root: return testWin.panel
xxx = self.GetPyData(item).treeObject()
parentWin = self.FindNodeObject(itemParent)
# Top-level sizer? return window's sizer
if panel.IsModified():
self.Apply(xxx, oldItem)
#if conf.autoRefresh:
- if testWin and tree.GetItemAncestor(oldItem) == testWin.item:
- if testWin.highLight:
+ if testWin:
+ if testWin.highLight and not tree.IsHighlatable(oldItem):
testWin.highLight.Remove()
self.needUpdate = true
status = 'Changes were applied'
panel.SetModified(false)
# Hightlighting is done in OnIdle
tree.pendingHighLight = self.selection
- # Find top-level parent
- def GetItemAncestor(self, item):
- while self.GetItemParent(item) != self.root:
+ # Check if item is in testWin subtree
+ def IsHighlatable(self, item):
+ if item == testWin.item: return false
+ while item != self.root:
item = self.GetItemParent(item)
- return item
+ if item == testWin.item: return true
+ return false
# Highlight selected item
def HighLight(self, item):
self.pendingHighLight = None
if testWin.highLight: testWin.highLight.Remove()
return
# If a control from another window is selected, remove highlight
- if self.GetItemAncestor(item) != testWin.item:
+ if not self.IsHighlatable(item):
if testWin.highLight: testWin.highLight.Remove()
return
# Get window/sizer object
# (re)create test window
def CreateTestWin(self, item):
global testWin
+ wxBeginBusyCursor()
# Create a window with this resource
xxx = self.GetPyData(item).treeObject()
# Close old window, remember where it was
if testWin.highLight:
highLight = testWin.highLight.item
# !!! if 0 is removed, refresh is broken (notebook not deleted?)
- if 0 and xxx.className == 'wxPanel':
+ if xxx.className == 'wxPanel':
if testWin.highLight:
testWin.pendingHighLight = highLight
testWin.highLight.Remove()
# Create new frame
testWin = wxPreFrame()
res.LoadFrame(testWin, frame, xxx.name)
+ # Create status bar
+ testWin.CreateStatusBar()
testWin.panel = testWin
testWin.SetPosition(pos)
testWin.Show(true)
testWin.Show(true)
elif xxx.className == 'wxMenuBar':
testWin = wxFrame(frame, -1, 'MenuBar: ' + xxx.name, pos=pos)
+ testWin.panel = None
# Set status bar to display help
testWin.CreateStatusBar()
testWin.menuBar = res.LoadMenuBar(xxx.name)
testWin.Show(true)
elif xxx.className == 'wxToolBar':
testWin = wxFrame(frame, -1, 'ToolBar: ' + xxx.name, pos=pos)
+ testWin.panel = None
# Set status bar to display help
testWin.CreateStatusBar()
testWin.toolBar = res.LoadToolBar(testWin, xxx.name)
testWin.Show(true)
wxMemoryFSHandler_RemoveFile('xxx.xrc')
testWin.item = item
- testWin.Connect(testWin.GetId(), -1, wxEVT_CLOSE_WINDOW, self.OnCloseTestWin)
+ EVT_CLOSE(testWin, self.OnCloseTestWin)
+ EVT_BUTTON(testWin, wxID_OK, self.OnCloseTestWin)
+ EVT_BUTTON(testWin, wxID_CANCEL, self.OnCloseTestWin)
testWin.highLight = None
if highLight and not tree.pendingHighLight:
self.HighLight(highLight)
+ wxEndBusyCursor()
def OnCloseTestWin(self, evt):
global testWin, testWinPos
testWinPos = testWin.GetPosition()
testWin.Destroy()
testWin = None
- evt.Skip()
+
+ # Return item index in parent
+ def ItemIndex(self, parent, item):
+ i = 0
+ it, cookie = self.GetFirstChild(parent, 0)
+ while it != item:
+ i += 1
+ it, cookie = self.GetNextChild(parent, cookie)
+ return i
# True if next item should be inserted after current (vs. appended to it)
def NeedInsert(self, item):
xxx = self.GetPyData(item)
if item == self.root: return false # root item
- if self.ctrl: return true # if Ctrl pressed, always insert
if xxx.hasChildren and not self.GetChildrenCount(item, false):
return false
return not (self.IsExpanded(item) and self.GetChildrenCount(item, false))
self.ctrl = evt.ControlDown() # save Ctrl state
self.shift = evt.ShiftDown() # and Shift too
m = wxMenu() # create menu
- needInsert = false
- if item != self.root: needInsert = self.NeedInsert(item)
- if item == self.root or \
- self.GetItemParent(item) == self.root and needInsert:
+ if self.ctrl:
+ needInsert = true
+ else:
+ needInsert = self.NeedInsert(item)
+ if item == self.root or needInsert and self.GetItemParent(item) == self.root:
m.Append(pullDownMenu.ID_NEW_PANEL, 'Panel', 'Create panel')
m.Append(pullDownMenu.ID_NEW_DIALOG, 'Dialog', 'Create dialog')
m.Append(pullDownMenu.ID_NEW_FRAME, 'Frame', 'Create frame')
menu.Append(wxID_CUT, 'Cut', 'Cut to the clipboard')
menu.Append(wxID_COPY, 'Copy', 'Copy to the clipboard')
if self.ctrl and item != tree.root:
- menu.Append(wxID_PASTE, 'Paste Sibling',
+ menu.Append(pullDownMenu.ID_PASTE_SIBLING, 'Paste Sibling',
'Paste from the clipboard as a sibling')
else:
menu.Append(wxID_PASTE, 'Paste', 'Paste from the clipboard')
ID_NEW_LAST = wxNewId()
ID_EXPAND = wxNewId()
ID_COLLAPSE = wxNewId()
+ ID_PASTE_SIBLING = wxNewId()
def __init__(self, parent):
self.ID_DELETE = parent.ID_DELETE
self.ID_NEW_LAST, parent.OnCreate)
EVT_MENU(parent, self.ID_COLLAPSE, parent.OnCollapse)
EVT_MENU(parent, self.ID_EXPAND, parent.OnExpand)
+ EVT_MENU(parent, self.ID_PASTE_SIBLING, parent.OnPaste)
# We connect to tree, but process in frame
EVT_MENU_HIGHLIGHT_ALL(tree, parent.OnPullDownHighlight)
################################################################################
+# ScrolledMessageDialog - modified from wxPython lib to set fixed-width font
+class ScrolledMessageDialog(wxDialog):
+ def __init__(self, parent, msg, caption, pos = wxDefaultPosition, size = (500,300)):
+ from wxPython.lib.layoutf import Layoutf
+ wxDialog.__init__(self, parent, -1, caption, pos, size)
+ text = wxTextCtrl(self, -1, msg, wxDefaultPosition,
+ wxDefaultSize, wxTE_MULTILINE | wxTE_READONLY)
+ text.SetFont(modernFont)
+ dc = wxWindowDC(text)
+ w, h = dc.GetTextExtent(' ')
+ ok = wxButton(self, wxID_OK, "OK")
+ text.SetConstraints(Layoutf('t=t5#1;b=t5#2;l=l5#1;r=r5#1', (self,ok)))
+ text.SetSize((w * 80 + 30, h * 40))
+ ok.SetConstraints(Layoutf('b=b5#1;x%w50#1;w!80;h!25', (self,)))
+ self.SetAutoLayout(TRUE)
+ self.Fit()
+ self.CenterOnScreen(wxBOTH)
+
+################################################################################
+
class Frame(wxFrame):
def __init__(self, pos, size):
global frame
frame = self
wxFrame.__init__(self, None, -1, '', pos, size)
self.CreateStatusBar()
- #self.SetIcon(wxIconFromXPMData(images.getIconData()))
- #icon = wxIconFromXPMData(images.getIconData())
icon = wxIcon(os.path.join(sys.path[0], 'xrced.ico'), wxBITMAP_TYPE_ICO)
self.SetIcon(icon)
- # Defaults
- self.sashPos = 100
- self.panelX = self.panelY = -1
- self.panelWidth = 300
- self.panelHeight = 200
+ # Idle flag
+ self.inIdle = false
# Make menus
menuBar = wxMenuBar()
'Refresh', 'Refresh view')
tb.AddSimpleTool(self.ID_AUTO_REFRESH, images.getAutoRefreshBitmap(),
'Auto-refresh', 'Toggle auto-refresh mode', true)
- if wxGetOsVersion()[1] == 1:
+ if wxGetOsVersion()[0] == wxGTK:
tb.AddSeparator() # otherwise auto-refresh sticks in status line
tb.ToggleTool(self.ID_AUTO_REFRESH, conf.autoRefresh)
tb.Realize()
self.tb = tb
+ self.minWidth = tb.GetSize()[0] # minimal width is the size of toolbar
# File
EVT_MENU(self, wxID_NEW, self.OnNew)
def OnCut(self, evt):
selected = tree.selection
+ if not selected: return # key pressed event
# Undo info
self.lastOp = 'CUT'
self.undo = [tree.GetItemParent(selected), tree.GetPrevSibling(selected)]
testWin = None
else:
# Remove highlight, update testWin
- if tree.GetItemAncestor(selected) == testWin.item:
+ if not tree.IsHighlatable(selected):
if testWin.highLight: testWin.highLight.Remove()
tree.needUpdate = true
self.clipboard = tree.RemoveLeaf(selected)
def OnCopy(self, evt):
selected = tree.selection
+ if not selected: return # key pressed event
xxx = tree.GetPyData(selected)
self.clipboard = xxx.element.cloneNode(true)
self.SetStatusText('Copied')
def OnPaste(self, evt):
selected = tree.selection
- appendChild = not tree.NeedInsert(selected)
+ if not selected: return # key pressed event
+ # For pasting with Ctrl pressed
+ if evt.GetId() == pullDownMenu.ID_PASTE_SIBLING: appendChild = false
+ else: appendChild = not tree.NeedInsert(selected)
xxx = tree.GetPyData(selected)
if not appendChild:
# If has next item, insert, else append to parent
x = xxx.treeObject()
if x.__class__ in [xxxDialog, xxxFrame, xxxMenuBar, xxxToolBar]:
if parent.__class__ != xxxMainNode: 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:
node = tree.GetPyData(nextItem).element
parent.element.insertBefore(elem, node)
# Inserting before is difficult, se we insert after or first child
- newItem = tree.InsertItem(parentLeaf, selected, xxx.treeName(),
- image=xxx.treeImage(), data=wxTreeItemData(xxx))
+ index = tree.ItemIndex(parentLeaf, nextItem)
+ newItem = tree.InsertItemBefore(parentLeaf, index,
+ xxx.treeName(), image=xxx.treeImage())
+ tree.SetPyData(newItem, xxx)
+# newItem = tree.InsertItem(parentLeaf, selected, xxx.treeName(),
+# image=xxx.treeImage(), data=wxTreeItemData(xxx))
# Add children items
if xxx.hasChildren:
treeObj = xxx.treeObject()
tree.ScrollTo(newItem)
tree.Refresh()
# Update view?
- if testWin and tree.GetItemAncestor(newItem) == testWin.item:
+ if testWin and tree.IsHighlatable(newItem):
if conf.autoRefresh:
tree.needUpdate = true
tree.pendingHighLight = newItem
def OnDelete(self, evt):
selected = tree.selection
+ if not selected: return # key pressed event
# Undo info
self.lastOp = 'DELETE'
self.undo = [tree.GetItemParent(selected), tree.GetPrevSibling(selected)]
testWin = None
else:
# Remove highlight, update testWin
- if tree.GetItemAncestor(selected) == testWin.item:
+ if not tree.IsHighlatable(selected):
if testWin.highLight: testWin.highLight.Remove()
tree.needUpdate = true
xnode = tree.RemoveLeaf(selected)
conf.embedPanel = evt.IsChecked()
if conf.embedPanel:
# Remember last dimentions
- self.panelWidth, self.panelHeight = panel.GetSize()
+ 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().RemoveWindow(panel)
- self.splitter.SplitVertically(tree, panel, self.sashPos)
+ wxYield()
+ # Widen
+ self.SetDimensions(pos.x, pos.y, size.x + sizePanel.x, size.y)
+ self.splitter.SplitVertically(tree, panel, conf.sashPos)
self.miniFrame.Show(false)
else:
- self.sashPos = self.splitter.GetSashPosition()
+ 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, wxEXPAND)
self.miniFrame.Show(true)
- self.miniFrame.SetSize((self.panelWidth, self.panelHeight))
+ self.miniFrame.SetDimensions(conf.panelX, conf.panelY,
+ conf.panelWidth, conf.panelHeight)
+ wxYield()
+ # Reduce width
+ self.SetDimensions(pos.x, pos.y,
+ max(size.x - sizePanel.x, self.minWidth), size.y)
def OnTest(self, evt):
+ if not tree.selection: return # key pressed event
tree.ShowTestWindow(tree.selection)
def OnRefresh(self, evt):
dlg.Destroy()
def OnReadme(self, evt):
- from wxPython.lib.dialogs import wxScrolledMessageDialog
text = open(os.path.join(sys.path[0], 'README'), 'r').read()
- dlg = wxScrolledMessageDialog(self, text, "XRCed README")
+ dlg = ScrolledMessageDialog(self, text, "XRCed README")
dlg.ShowModal()
dlg.Destroy()
def OnCreate(self, evt):
selected = tree.selection
- appendChild = not tree.NeedInsert(selected)
+ if tree.ctrl: appendChild = false
+ else: appendChild = not tree.NeedInsert(selected)
xxx = tree.GetPyData(selected)
if not appendChild:
# If insert before
if tree.shift:
# If has previous item, insert after it, else append to parent
nextItem = selected
- selected = tree.GetPrevSibling(selected)
- if selected:
- # Insert before nextItem
- parentLeaf = tree.GetItemParent(selected)
- else: # last child: change selected to parent
- parentLeaf = selected = tree.GetItemParent(nextItem)
+ parentLeaf = tree.GetItemParent(selected)
else:
# If has next item, insert, else append to parent
nextItem = tree.GetNextSibling(selected)
appendChild = true
selected = tree.GetItemParent(selected)
# Expanded container (must have children)
- else:
- # Can't use HasChildren because root always has
- if tree.shift and tree.IsExpanded(selected) \
- and tree.GetChildrenCount(selected, false):
- appendChild = false
- nextItem = tree.GetFirstChild(selected, 0)[0]
- parentLeaf = selected
+ elif tree.shift and tree.IsExpanded(selected) \
+ and tree.GetChildrenCount(selected, false):
+ appendChild = false
+ nextItem = tree.GetFirstChild(selected, 0)[0]
+ parentLeaf = selected
# Parent should be tree element or None
if appendChild:
parent = tree.GetPyData(selected)
else:
node = tree.GetPyData(nextItem).element
parent.element.insertBefore(elem, node)
- newItem = tree.InsertItem(parentLeaf, selected,
- xxx.treeName(), image=xxx.treeImage(),
- data=wxTreeItemData(xxx))
+ # !!! There is a different behavious on Win and GTK
+ # !!! On Win InsertItem(parent, parent, ...) inserts at the end.
+ index = tree.ItemIndex(parentLeaf, nextItem)
+ newItem = tree.InsertItemBefore(parentLeaf, index,
+ xxx.treeName(), image=xxx.treeImage())
+# data=wxTreeItemData(xxx)) # does not work
+ tree.SetPyData(newItem, xxx)
+# newItem = tree.InsertItem(parentLeaf, selected,
+# xxx.treeName(), image=xxx.treeImage(),
+# data=wxTreeItemData(xxx))
tree.EnsureVisible(newItem)
tree.SelectItem(newItem)
if not tree.IsVisible(newItem):
tree.ScrollTo(newItem)
tree.Refresh()
# Update view?
- if testWin and tree.GetItemAncestor(newItem) == testWin.item:
+ if testWin and tree.IsHighlatable(newItem):
if conf.autoRefresh:
tree.needUpdate = true
tree.pendingHighLight = newItem
evt.Enable((self.clipboard and tree.selection) != None)
elif evt.GetId() == self.ID_TEST:
evt.Enable(tree.selection != tree.root)
- elif evt.GetId() == self.ID_REFRESH:
- evt.Enable(testWin != None)
def OnIdle(self, evt):
+ if self.inIdle: return # Recursive call protection
+ self.inIdle = true
if tree.needUpdate:
if conf.autoRefresh:
if testWin:
+ self.SetStatusText('Refreshing test window...')
# (re)create
tree.CreateTestWin(testWin.item)
+ wxYield()
+ self.SetStatusText('')
tree.needUpdate = false
elif tree.pendingHighLight:
tree.HighLight(tree.pendingHighLight)
else:
evt.Skip()
+ self.inIdle = false
# We don't let close panel window
def OnCloseMiniFrame(self, evt):
if testWin: testWin.Destroy()
# Destroy cached windows
panel.cacheParent.Destroy()
-# for w in panel.styleCache.values(): w.Destroy()
if not panel.GetPageCount() == 2:
panel.page2.Destroy()
conf.x, conf.y = self.GetPosition()
conf.width, conf.height = self.GetSize()
if conf.embedPanel:
conf.sashPos = self.splitter.GetSashPosition()
- conf.panelWidth, conf.panelHeight = self.panelWidth, self.panelHeight
else:
- conf.sashPos = self.sashPos
conf.panelX, conf.panelY = self.miniFrame.GetPosition()
conf.panelWidth, conf.panelHeight = self.miniFrame.GetSize()
evt.Skip()
self.OnRefresh(wxCommandEvent())
f = open(path, 'w')
# Make temporary copy
- self.domCopy = domCopy = tree.dom.cloneNode(true)
- self.Indent(domCopy.getElementsByTagName('resource')[0])
- domCopy.writexml(f)
-# domCopy.unlink()
- self.domCopy = None
+ # !!! We can't clone dom node, it works only once
+ #self.domCopy = tree.dom.cloneNode(true)
+ self.domCopy = minidom.Document()
+ mainNode = self.domCopy.appendChild(tree.mainNode.cloneNode(true))
+ self.Indent(mainNode)
+ self.domCopy.writexml(f)
f.close()
+ self.domCopy.unlink()
+ self.domCopy = None
self.modified = false
panel.SetModified(false)
except: