Merged wxPython 2.4.x to the 2.5 branch (Finally!!!)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19793 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2003-03-25 06:35:27 +00:00
parent 9b4e3f352b
commit 1e4a197e4c
586 changed files with 62691 additions and 17740 deletions

View File

@@ -0,0 +1,162 @@
0.1.0
-----
Finally implemented tools panel for almost all controls (except
wxHtmlWindow, wxCalendarCtrl and wxGenericDirCtrl - they are too
rarely used).
Changed some sizes in panel to better work with different fonts.
Fixed double-refreshing after Ctrl+R.
Maybe something else that I've forgot. It's been a looong day... :)
0.0.9-6
-------
Added dialog unit support.
Dealing with non-specified required values (set to defaults, if exist).
Added 'minsize' parameter of sizeritem.
Added '-i' option to turn off translations and use international characters.
0.0.9-5
-------
Mac platform-specific checks.
0.0.9-4
-------
Implemented standard bitmap selection.
Fixed a bug in FlexGridSizer code.
0.0.9-3
-------
File browsing (for bitmaps/icons, etc.) had a small problem when current
file was not saved yet.
0.0.9-2
-------
Small bug fix for initial don't panic message.
0.0.9-1
-------
Changed program structure, reduced use of global variables (grouped in
module 'globals', which creates an instanse 'g' of class Globals.
First version of undo/redo working!
Support for toolbars inside panels and frames.
Added 'container' submenu for creating Panel, Notebook and ToolBar objects.
wxMSW-only: added code to switch focus back to main window when test
window is updated.
0.0.8-2
-------
Fixed unicode problem for unicode build.
0.0.8-1
-------
Using WX_2_4_BRANCH.
Added new controls: wxSpinCtrl, wxGenericDirCtrl, unknown (custom
control), improved wxXRC format suppor (menu styles, etc.).
Some I18N support: parsing "encoding" attribute in XML header, later
it can be modified in "properties" panel for "XML tree".
UNIX note: currently XML writing for non-ascii chars works only if
sys.getdefaultencoding() returns good value. To do this, one has to
put following lines to "sitecustomize.py" file:
# Start code segment
import sys
sys.setdefaultencoding('iso-8859-1') # or whatever
# End code segment
0.0.7
-----
Some command-line arguments.
"Test window" command and toolbar button.
New panel interphace (wxHTMLWindow is not used anymore).
Toggling between embedded and detached panel.
Cache for already used windows.
Current top-level control is bold, if test window shown.
Undo/redo broken.
CheckListBox does not work unless wxXRC source fixed (in both wxPytnon and
wxWin):
contrib/src/xrc/xmlrsall.cpp
45,46c45,46
< AddHandler(new wxListCtrlXmlHandler);
< #if CHECKLISTBOX
---
> AddHandler(new wxListCtrlXmlHandler);
> #if wxUSE_CHECKLISTBOX
This is fixed in CVS.
0.0.6
-----
Toolbar, bitmap, icon support (no display yet).
Changed parameter objects, added support for multiple parameters (like
`growablecols').
Fixed double-clicking problem with tree control on Windows.
Some performance improovements.
0.0.5
-----
Added notebook with properties page and style page. Fixed some problems
on Windows.
0.0.4
-----
Some fixes suggested by RD
0.0.3
-----
Faster preview window refresh.
Cut/Paste works better.
Some tree icons.
Tree item names.
Bugfixes.
0.0.2
-----
The first release.

View File

@@ -7,10 +7,11 @@
Installation on UNIX
--------------------
XRCed requires wxGTK and wxPython greater than 2.3.2, and Python 2.2 (it may
work with earlier version, but was not tested).
XRCed requires wxGTK and wxPython greater or equal to 2.3.3, and Python 2.2
(it may work with earlier version, but was not tested).
Of course wxGTK's XRC library (libwxxrc) must be installed.
Of course wxGTK's XRC library (libwxxrc) and it's python module must
be installed.
Installation on Windows
-----------------------

View File

@@ -1,9 +1,9 @@
TODO for XRCed
==============
- Undo/Redo
- better help
- menu - accel not displayed in preview
+ undo/redo
+ tree icons
@@ -13,7 +13,7 @@ TODO for XRCed
+ XML indents
? select same notebook pages after update
+ select same notebook pages after update
- put some default values in tree ctrl etc.
@@ -26,4 +26,4 @@ TODO for XRCed
+ disable some window creation when it's not valid
- check for memory leaks from wx objects
- selecting object by clicking in test window

View File

@@ -0,0 +1,27 @@
import sys, os, glob
from wxPython.tools import img2py
output = 'images.py'
# get the list of PNG files
files = glob.glob('src-images/*.png')
# Truncate the inages module
open(output, 'w')
# call img2py on each file
for file in files:
# extract the basename to be used as the image name
name = os.path.splitext(os.path.basename(file))[0]
# encode it
if file == files[0]:
cmd = "-u -i -n %s %s %s" % (name, file, output)
else:
cmd = "-a -u -i -n %s %s %s" % (name, file, output)
img2py.main(cmd.split())

View File

@@ -0,0 +1,39 @@
# Name: globals.py
# Purpose: XRC editor, global variables
# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
# Created: 02.12.2002
# RCS-ID: $Id$
from wxPython.wx import *
from wxPython.xrc import *
# Global constants
sysFont = wxSystemSettings_GetFont(wxSYS_SYSTEM_FONT)
labelFont = wxFont(sysFont.GetPointSize(), wxDEFAULT, wxNORMAL, wxBOLD)
modernFont = wxFont(sysFont.GetPointSize(), wxMODERN, wxNORMAL, wxNORMAL)
smallerFont = wxFont(sysFont.GetPointSize()-2, wxDEFAULT, wxNORMAL, wxNORMAL)
progname = 'XRCed'
version = '0.1.0'
try:
True
except NameError:
True = 1==1
False = 1==0
# Global variables
class Globals:
panel = None
tree = None
frame = None
tools = None
undoMan = None
testWin = None
testWinPos = wxDefaultPosition
currentXXX = None
xmlFlags = wxXRC_USE_LOCALE | wxXRC_NO_SUBCLASSING
g = Globals()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
Copyright (c) 2002, Roman Rolinsky <rollrom@users.sourceforge.net>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,365 @@
# Name: panel.py
# Purpose: XRC editor, Panel class and related
# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
# Created: 02.12.2002
# RCS-ID: $Id$
from xxx import * # xxx imports globals and params
from undo import *
from wxPython.html import wxHtmlWindow
# Properties panel containing notebook
class Panel(wxNotebook):
def __init__(self, parent, id = -1):
if wxPlatform != '__WXMAC__': # some problems with this style on macs
wxNotebook.__init__(self, parent, id, style=wxNB_BOTTOM)
else:
wxNotebook.__init__(self, parent, id)
global panel
g.panel = panel = self
self.modified = False
# Set common button size for parameter buttons
import params
params.buttonSize = self.DLG_SZE(buttonSize)
# List of child windows
self.pages = []
# Create scrolled windows for pages
self.page1 = wxScrolledWindow(self, -1)
sizer = wxBoxSizer()
sizer.Add(wxBoxSizer()) # dummy sizer
self.page1.SetAutoLayout(True)
self.page1.SetSizer(sizer)
self.AddPage(self.page1, 'Properties')
# Second page
self.page2 = wxScrolledWindow(self, -1)
sizer = wxBoxSizer()
sizer.Add(wxBoxSizer()) # dummy sizer
self.page2.SetAutoLayout(True)
self.page2.SetSizer(sizer)
# Cache for already used panels
self.pageCache = {} # cached property panels
self.stylePageCache = {} # cached style panels
# Dummy parent window for cache pages
self.cacheParent = wxFrame(None, -1, 'i am invisible')
# Delete child windows and recreate page sizer
def ResetPage(self, page):
topSizer = page.GetSizer()
sizer = topSizer.GetChildren()[0].GetSizer()
for w in page.GetChildren():
sizer.RemoveWindow(w)
if isinstance(w, ParamPage):
# With SetParent, we wouldn't need this
w.Reparent(self.cacheParent)
else:
w.Destroy()
topSizer.RemoveSizer(sizer)
# Create new windows
sizer = wxBoxSizer(wxVERTICAL)
# Special case - resize html window
if g.conf.panic:
topSizer.Add(sizer, 1, wxEXPAND)
else:
topSizer.Add(sizer, 0, wxALL, 5)
return sizer
def SetData(self, xxx):
self.pages = []
# First page
# Set cached or new page
# Remove current objects and sizer
sizer = self.ResetPage(self.page1)
if not xxx or (not xxx.allParams and not xxx.hasName):
if g.tree.selection:
sizer.Add(wxStaticText(self.page1, -1, 'This item has no properties.'))
else: # nothing selected
# If first time, show some help
if g.conf.panic:
html = wxHtmlWindow(self.page1, -1, wxDefaultPosition,
wxDefaultSize, wxSUNKEN_BORDER)
html.SetPage(g.helpText)
sizer.Add(html, 1, wxEXPAND)
g.conf.panic = False
else:
sizer.Add(wxStaticText(self.page1, -1, 'Select a tree item.'))
else:
g.currentXXX = xxx.treeObject()
try:
page = self.pageCache[xxx.__class__]
page.Reparent(self.page1)
except KeyError:
page = PropPage(self.page1, xxx.className, xxx)
self.pageCache[xxx.__class__] = page
page.SetValues(xxx)
self.pages.append(page)
sizer.Add(page, 1, wxEXPAND)
if xxx.hasChild:
# Special label for child objects - they may have different GUI
cacheID = (xxx.child.__class__, xxx.__class__)
try:
page = self.pageCache[cacheID]
page.Reparent(self.page1)
except KeyError:
page = PropPage(self.page1, xxx.child.className, xxx.child)
self.pageCache[cacheID] = page
page.SetValues(xxx.child)
self.pages.append(page)
sizer.Add(page, 0, wxEXPAND | wxTOP, 5)
self.page1.Layout()
size = self.page1.GetSizer().GetMinSize()
self.page1.SetScrollbars(1, 1, size.x, size.y, 0, 0, True)
# Second page
# Create if does not exist
if xxx and xxx.treeObject().hasStyle:
xxx = xxx.treeObject()
# Simplest case: set data if class is the same
sizer = self.ResetPage(self.page2)
try:
page = self.stylePageCache[xxx.__class__]
page.Reparent(self.page2)
except KeyError:
page = StylePage(self.page2, xxx.className + ' style', xxx)
self.stylePageCache[xxx.__class__] = page
page.SetValues(xxx)
self.pages.append(page)
sizer.Add(page, 0, wxEXPAND)
# Add page if not exists
if not self.GetPageCount() == 2:
self.AddPage(self.page2, 'Style')
self.page2.Layout()
size = self.page2.GetSizer().GetMinSize()
self.page2.SetScrollbars(1, 1, size.x, size.y, 0, 0, True)
else:
# Remove page if exists
if self.GetPageCount() == 2:
self.SetSelection(0)
self.page1.Refresh()
self.RemovePage(1)
self.modified = False
def Clear(self):
self.SetData(None)
self.modified = False
# If some parameter has changed
def IsModified(self):
return self.modified
def SetModified(self, value):
# Register undo object when modifying first time
if not self.modified and value:
g.undoMan.RegisterUndo(UndoEdit())
self.modified = value
def Apply(self):
for p in self.pages: p.Apply()
################################################################################
# General class for notebook pages
class ParamPage(wxPanel):
def __init__(self, parent, xxx):
wxPanel.__init__(self, parent, -1)
self.xxx = xxx
# Register event handlers
for id in paramIDs.values():
EVT_CHECKBOX(self, id, self.OnCheckParams)
self.checks = {}
self.controls = {} # save python objects
self.controlName = None
def OnCheckParams(self, evt):
xxx = self.xxx
param = evt.GetEventObject().GetName()
w = self.controls[param]
w.Enable(True)
objElem = xxx.element
if evt.IsChecked():
# Ad new text node in order of allParams
w.SetValue('') # set empty (default) value
w.SetModified() # mark as changed
elem = g.tree.dom.createElement(param)
# Some classes are special
if param == 'font':
xxx.params[param] = xxxParamFont(xxx.element, elem)
elif param in xxxObject.bitmapTags:
xxx.params[param] = xxxParamBitmap(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
for p in paramStyles[paramStyles.index(param) + 1:]:
# Content params don't have same type
if xxx.params.has_key(p) and p != 'content':
found = True
break
if found:
nextTextElem = xxx.params[p].node
objElem.insertBefore(elem, nextTextElem)
else:
objElem.appendChild(elem)
else:
# Remove parameter
xxx.params[param].remove()
del xxx.params[param]
w.SetValue('')
w.modified = False # mark as not changed
w.Enable(False)
# Set modified flag (provokes undo storing is necessary)
panel.SetModified(True)
def Apply(self):
xxx = self.xxx
if self.controlName:
name = self.controlName.GetValue()
if xxx.name != name:
xxx.name = name
xxx.element.setAttribute('name', name)
for param, w in self.controls.items():
if w.modified:
paramObj = xxx.params[param]
value = w.GetValue()
if param in xxx.specials:
xxx.setSpecial(param, value)
else:
paramObj.update(value)
# Save current state
def SaveState(self):
self.origChecks = map(lambda i: (i[0], i[1].GetValue()), self.checks.items())
self.origControls = map(lambda i: (i[0], i[1].GetValue(), i[1].IsEnabled()),
self.controls.items())
if self.controlName:
self.origName = self.controlName.GetValue()
# Return original values
def GetState(self):
if self.controlName:
return (self.origChecks, self.origControls, self.origName)
else:
return (self.origChecks, self.origControls)
# Set values from undo data
def SetState(self, state):
for k,v in state[0]:
self.checks[k].SetValue(v)
for k,v,e in state[1]:
self.controls[k].SetValue(v)
self.controls[k].Enable(e)
if e: self.controls[k].modified = True
if self.controlName:
self.controlName.SetValue(state[2])
################################################################################
# Panel for displaying properties
class PropPage(ParamPage):
def __init__(self, parent, label, xxx):
ParamPage.__init__(self, parent, xxx)
box = wxStaticBox(self, -1, label)
box.SetFont(labelFont)
topSizer = wxStaticBoxSizer(box, wxVERTICAL)
sizer = wxFlexGridSizer(len(xxx.allParams), 2, 1, 1)
sizer.AddGrowableCol(1)
if xxx.hasName:
label = wxStaticText(self, -1, 'XML ID:', size=(100,-1))
control = ParamText(self, 'XML_name', 200)
sizer.AddMany([ (label, 0, wxALIGN_CENTER_VERTICAL),
(control, 0, wxALIGN_CENTER_VERTICAL | wxBOTTOM | wxGROW, 5) ])
self.controlName = control
for param in xxx.allParams:
present = xxx.params.has_key(param)
if param in xxx.required:
label = wxStaticText(self, paramIDs[param], 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 = (100,-1), name = param)
self.checks[param] = label
try:
typeClass = xxx.paramDict[param]
except KeyError:
try:
# Standart type
typeClass = paramDict[param]
except KeyError:
# Default
typeClass = ParamText
control = typeClass(self, param)
control.Enable(present)
sizer.AddMany([ (label, 0, wxALIGN_CENTER_VERTICAL),
(control, 0, wxALIGN_CENTER_VERTICAL | wxGROW) ])
self.controls[param] = control
topSizer.Add(sizer, 1, wxALL | wxEXPAND, 3)
self.SetAutoLayout(True)
self.SetSizer(topSizer)
topSizer.Fit(self)
def SetValues(self, xxx):
self.xxx = xxx
self.origChecks = []
self.origControls = []
# Set values, checkboxes to False, disable defaults
if xxx.hasName:
self.controlName.SetValue(xxx.name)
self.origName = xxx.name
for param in xxx.allParams:
w = self.controls[param]
w.modified = False
try:
value = xxx.params[param].value()
w.Enable(True)
w.SetValue(value)
if not param in xxx.required:
self.checks[param].SetValue(True)
self.origChecks.append((param, True))
self.origControls.append((param, value, True))
except KeyError:
self.checks[param].SetValue(False)
w.SetValue('')
w.Enable(False)
self.origChecks.append((param, False))
self.origControls.append((param, '', False))
################################################################################
# Style notebook page
class StylePage(ParamPage):
def __init__(self, parent, label, xxx):
ParamPage.__init__(self, parent, xxx)
box = wxStaticBox(self, -1, label)
box.SetFont(labelFont)
topSizer = wxStaticBoxSizer(box, wxVERTICAL)
sizer = wxFlexGridSizer(len(xxx.styles), 2, 1, 1)
sizer.AddGrowableCol(1)
for param in xxx.styles:
present = xxx.params.has_key(param)
check = wxCheckBox(self, paramIDs[param],
param + ':', size = (100,-1), name = param)
check.SetValue(present)
control = paramDict[param](self, name = param)
control.Enable(present)
sizer.AddMany([ (check, 0, wxALIGN_CENTER_VERTICAL),
(control, 0, wxALIGN_CENTER_VERTICAL | wxGROW) ])
self.checks[param] = check
self.controls[param] = control
topSizer.Add(sizer, 1, wxALL | wxEXPAND, 3)
self.SetAutoLayout(True)
self.SetSizer(topSizer)
topSizer.Fit(self)
# Set data for a cahced page
def SetValues(self, xxx):
self.xxx = xxx
self.origChecks = []
self.origControls = []
for param in xxx.styles:
present = xxx.params.has_key(param)
check = self.checks[param]
check.SetValue(present)
w = self.controls[param]
w.modified = False
if present:
value = xxx.params[param].value()
else:
value = ''
w.SetValue(value)
w.Enable(present)
self.origChecks.append((param, present))
self.origControls.append((param, value, present))

View File

@@ -4,17 +4,11 @@
# Created: 22.08.2001
# RCS-ID: $Id$
from wxPython.wx import *
from wxPython.xrc import *
import string
import os.path
from globals import *
from types import *
# Object which is currently processed
currentXXX = None
def SetCurrentXXX(xxx):
global currentXXX
currentXXX = xxx
from wxPython.xrc import *
genericStyles = ['wxSIMPLE_BORDER', 'wxDOUBLE_BORDER',
'wxSUNKEN_BORDER', 'wxRAISED_BORDER',
@@ -22,53 +16,54 @@ genericStyles = ['wxSIMPLE_BORDER', 'wxDOUBLE_BORDER',
'wxTRANSPARENT_WINDOW', 'wxWANTS_CHARS',
'wxNO_FULL_REPAINT_ON_RESIZE']
buttonSize = (55,-1)
buttonSize = (30,-1) # in dialog units, transformed to pixels in panel ctor
# Class that can properly disable children
class PPanel(wxPanel):
def __init__(self, parent, name):
wxPanel.__init__(self, parent, -1, name=name)
self.modified = self.freeze = false
self.modified = self.freeze = False
def Enable(self, value):
# Something strange is going on with enable so we make sure...
for w in self.GetChildren():
w.Enable(value)
wxPanel.Enable(self, value)
def SetModified(self):
self.modified = true
panel.SetModified(true)
self.modified = True
g.panel.SetModified(True)
# Common method to set modified state
def OnChange(self, evt):
if self.freeze: return
self.SetModified()
evt.Skip()
class ParamBinaryOr(PPanel):
def __init__(self, parent, name):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wxNewId()
self.ID_BUTTON_CHOICES = wxNewId()
self.SetBackgroundColour(panel.GetBackgroundColour())
self.SetBackgroundColour(g.panel.GetBackgroundColour())
sizer = wxBoxSizer()
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_CHOICES, 'Edit...', size=buttonSize)
sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
self.SetAutoLayout(true)
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
EVT_BUTTON(self, self.ID_BUTTON_CHOICES, self.OnButtonChoices)
EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
def OnChange(self, evt):
if self.freeze: return
self.SetModified()
evt.Skip()
def GetValue(self):
return self.text.GetValue()
def SetValue(self, value):
self.freeze = true
self.freeze = True
self.text.SetValue(value)
self.freeze = false
self.freeze = False
def OnButtonChoices(self, evt):
dlg = wxDialog(self, -1, 'Choices')
topSizer = wxBoxSizer(wxVERTICAL)
listBox = wxCheckListBox(dlg, -1, choices=self.values, size=(250,200))
value = map(string.strip, string.split(self.text.GetValue(), '|'))
value = map(string.strip, self.text.GetValue().split('|'))
if value == ['']: value = []
ignored = []
for i in value:
@@ -89,7 +84,7 @@ class ParamBinaryOr(PPanel):
sizer.Add(0, 0, 1)
sizer.Add(wxButton(dlg, wxID_CANCEL, 'Cancel'))
topSizer.Add(sizer, 0, wxALL | wxEXPAND, 10)
dlg.SetAutoLayout(true)
dlg.SetAutoLayout(True)
dlg.SetSizer(topSizer)
topSizer.Fit(dlg)
dlg.Center()
@@ -109,7 +104,7 @@ class ParamBinaryOr(PPanel):
class ParamFlag(ParamBinaryOr):
values = ['wxTOP', 'wxBOTTOM', 'wxLEFT', 'wxRIGHT', 'wxALL',
'wxEXPAND', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT',
'wxEXPAND', 'wxGROW', 'wxSHAPED', 'wxALIGN_CENTRE', 'wxALIGN_RIGHT',
'wxALIGN_BOTTOM', 'wxALIGN_CENTRE_VERTICAL',
'wxALIGN_CENTRE_HORIZONTAL']
equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE',
@@ -121,18 +116,18 @@ class ParamFlag(ParamBinaryOr):
class ParamStyle(ParamBinaryOr):
equal = {'wxALIGN_CENTER': 'wxALIGN_CENTRE'}
def __init__(self, parent, name):
self.values = currentXXX.winStyles + genericStyles
self.values = g.currentXXX.winStyles + genericStyles
ParamBinaryOr.__init__(self, parent, name)
class ParamNonGenericStyle(ParamBinaryOr):
def __init__(self, parent, name):
self.values = currentXXX.winStyles
self.values = g.currentXXX.winStyles
ParamBinaryOr.__init__(self, parent, name)
class ParamExStyle(ParamBinaryOr):
def __init__(self, parent, name):
if currentXXX:
self.values = currentXXX.exStyles # constant at the moment
if g.currentXXX:
self.values = g.currentXXX.exStyles # constant at the moment
else:
self.values = []
ParamBinaryOr.__init__(self, parent, name)
@@ -142,33 +137,29 @@ class ParamColour(PPanel):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wxNewId()
self.ID_BUTTON = wxNewId()
self.SetBackgroundColour(panel.GetBackgroundColour())
self.SetBackgroundColour(g.panel.GetBackgroundColour())
sizer = wxBoxSizer()
self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=(65,-1))
sizer.Add(self.text, 0, wxRIGHT, 5)
self.button = wxPanel(self, self.ID_BUTTON, wxDefaultPosition, wxSize(20, 20))
sizer.Add(self.button, 0, wxGROW)
self.SetAutoLayout(true)
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
self.textModified = false
self.textModified = False
EVT_PAINT(self.button, self.OnPaintButton)
EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
EVT_LEFT_DOWN(self.button, self.OnLeftDown)
def GetValue(self):
return self.text.GetValue()
def SetValue(self, value):
self.freeze = true
self.freeze = True
if not value: value = '#FFFFFF'
self.text.SetValue(str(value)) # update text ctrl
colour = wxColour(int(value[1:3], 16), int(value[3:5], 16), int(value[5:7], 16))
self.button.SetBackgroundColour(colour)
self.button.Refresh()
self.freeze = false
def OnChange(self, evt):
if self.freeze: return
self.SetModified()
evt.Skip()
self.freeze = False
def OnPaintButton(self, evt):
dc = wxPaintDC(self.button)
dc.SetBrush(wxTRANSPARENT_BRUSH)
@@ -206,23 +197,21 @@ class ParamFont(PPanel):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wxNewId()
self.ID_BUTTON_SELECT = wxNewId()
self.SetBackgroundColour(panel.GetBackgroundColour())
self.SetBackgroundColour(g.panel.GetBackgroundColour())
sizer = wxBoxSizer()
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_SELECT, 'Select...', size=buttonSize)
sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
self.SetAutoLayout(true)
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
self.textModified = false
self.textModified = False
EVT_BUTTON(self, self.ID_BUTTON_SELECT, self.OnButtonSelect)
EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
def OnChange(self, evt):
if self.freeze: return
self.SetModified()
self.textModified = true
evt.Skip()
PPanel.OnChange(self, evt)
self.textModified = True
def _defaultValue(self):
return ['12', 'default', 'normal', 'normal', '0', '', '']
def GetValue(self):
@@ -234,11 +223,11 @@ class ParamFont(PPanel):
return self._defaultValue()
return self.value
def SetValue(self, value):
self.freeze = true # disable other handlers
self.freeze = True # disable other handlers
if not value: value = self._defaultValue()
self.value = value
self.text.SetValue(str(value)) # update text ctrl
self.freeze = false
self.freeze = False
def OnButtonSelect(self, evt):
if self.textModified: # text has newer value
try:
@@ -255,23 +244,23 @@ class ParamFont(PPanel):
face = ''
enc = wxFONTENCODING_DEFAULT
# Fall back to default if exceptions
error = false
error = False
try:
try: size = int(self.value[0])
except ValueError: error = true
except ValueError: error = True
try: family = fontFamiliesXml2wx[self.value[1]]
except KeyError: error = true
except KeyError: error = True
try: style = fontStylesXml2wx[self.value[2]]
except KeyError: error = true
except KeyError: error = True
try: weight = fontWeightsXml2wx[self.value[3]]
except KeyError: error = true
except KeyError: error = True
try: underlined = int(self.value[4])
except ValueError: error = true
except ValueError: error = True
face = self.value[5]
mapper = wxFontMapper()
if not self.value[6]: enc = mapper.CharsetToEncoding(self.value[6])
except IndexError:
error = true
error = True
if error: wxLogError('Invalid font specification')
if enc == wxFONTENCODING_DEFAULT: enc = wxFONTENCODING_SYSTEM
font = wxFont(size, family, style, weight, underlined, face, enc)
@@ -291,7 +280,7 @@ class ParamFont(PPanel):
# Add ignored flags
self.SetValue(value)
self.SetModified()
self.textModified = false
self.textModified = False
dlg.Destroy()
################################################################################
@@ -302,60 +291,108 @@ class ParamInt(PPanel):
self.ID_SPIN_CTRL = wxNewId()
sizer = wxBoxSizer()
self.spin = wxSpinCtrl(self, self.ID_SPIN_CTRL, size=wxSize(50,-1))
self.SetBackgroundColour(panel.GetBackgroundColour())
self.SetBackgroundColour(g.panel.GetBackgroundColour())
sizer.Add(self.spin)
self.SetAutoLayout(true)
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
EVT_SPINCTRL(self, self.ID_SPIN_CTRL, self.OnChange)
def GetValue(self):
return str(self.spin.GetValue())
def SetValue(self, value):
self.freeze = true
self.freeze = True
if not value: value = 0
self.spin.SetValue(int(value))
self.freeze = false
def OnChange(self, evt):
if self.freeze: return
self.SetModified()
evt.Skip()
self.freeze = False
# Same as int but allows dialog units (XXXd)
class ParamUnit(PPanel):
def __init__(self, parent, name):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wxNewId()
self.ID_SPIN_BUTTON = wxNewId()
sizer = wxBoxSizer()
self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(35,-1))
self.spin = wxSpinButton(self, self.ID_SPIN_BUTTON, style = wxSP_VERTICAL)
self.spin.SetRange(-10000, 10000)
self.SetBackgroundColour(g.panel.GetBackgroundColour())
sizer.Add(self.text, 0, wxEXPAND | wxRIGHT, 2)
sizer.Add(self.spin)
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
EVT_SPIN_UP(self, self.ID_SPIN_BUTTON, self.OnSpinUp)
EVT_SPIN_DOWN(self, self.ID_SPIN_BUTTON, self.OnSpinDown)
def GetValue(self):
return self.text.GetValue()
def SetValue(self, value):
self.freeze = True
if not value: value = '0'
self.text.SetValue(value)
self.freeze = False
def Change(self, x):
# Check if we are working with dialog units
value = self.text.GetValue()
units = ''
if value[-1].upper() == 'D':
units = value[-1]
value = value[:-1]
try:
intValue = int(value) + x
self.spin.SetValue(intValue)
self.text.SetValue(str(intValue) + units)
self.SetModified()
except:
# !!! Strange, if I use wxLogWarning, event is re-generated
print 'incorrect unit format'
def OnSpinUp(self, evt):
self.Change(1)
def OnSpinDown(self, evt):
self.Change(-1)
class ParamText(PPanel):
def __init__(self, parent, name, textWidth=200):
def __init__(self, parent, name, textWidth=-1):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wxNewId()
# We use sizer even here to have the same size of text control
sizer = wxBoxSizer()
self.SetBackgroundColour(panel.GetBackgroundColour())
self.SetBackgroundColour(g.panel.GetBackgroundColour())
self.text = wxTextCtrl(self, self.ID_TEXT_CTRL, size=wxSize(textWidth,-1))
sizer.Add(self.text, 0, wxALIGN_CENTER_VERTICAL)
self.SetAutoLayout(true)
if textWidth == -1: option = 1
else: option = 0
sizer.Add(self.text, option, wxALIGN_CENTER_VERTICAL)
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
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.freeze = True # disable other handlers
self.text.SetValue(value)
self.freeze = false # disable other handlers
def OnChange(self, evt):
if self.freeze: return
self.SetModified()
evt.Skip()
self.freeze = False # disable other handlers
class ParamAccel(ParamText):
def __init__(self, parent, name):
ParamText.__init__(self, parent, name, 50)
ParamText.__init__(self, parent, name, 100)
class ParamPosSize(ParamText):
def __init__(self, parent, name):
ParamText.__init__(self, parent, name, 80)
class ParamLabel(ParamText):
def __init__(self, parent, name):
ParamText.__init__(self, parent, name, 200)
class ParamEncoding(ParamText):
def __init__(self, parent, name):
ParamText.__init__(self, parent, name, 100)
class ContentDialog(wxDialogPtr):
def __init__(self, parent, value):
# Is this normal???
w = frame.res.LoadDialog(parent, 'DIALOG_CONTENT')
# Load from resource
w = g.frame.res.LoadDialog(parent, 'DIALOG_CONTENT')
# Perform initialization with class pointer
wxDialogPtr.__init__(self, w.this)
self.thisown = 1
self.Center()
@@ -363,7 +400,7 @@ class ContentDialog(wxDialogPtr):
# Set list items
for v in value:
self.list.Append(v)
self.SetAutoLayout(true)
self.SetAutoLayout(True)
self.GetSizer().Fit(self)
# Callbacks
self.ID_BUTTON_APPEND = XMLID('BUTTON_APPEND')
@@ -405,8 +442,7 @@ class ContentDialog(wxDialogPtr):
class ContentCheckListDialog(wxDialogPtr):
def __init__(self, parent, value):
# Is this normal???
w = frame.res.LoadDialog(parent, 'DIALOG_CONTENT_CHECK_LIST')
w = g.frame.res.LoadDialog(parent, 'DIALOG_CONTENT_CHECK_LIST')
wxDialogPtr.__init__(self, w.this)
self.thisown = 1
self.Center()
@@ -417,7 +453,7 @@ class ContentCheckListDialog(wxDialogPtr):
self.list.Append(v)
self.list.Check(i, ch)
i += 1
self.SetAutoLayout(true)
self.SetAutoLayout(True)
self.GetSizer().Fit(self)
# Callbacks
self.ID_BUTTON_APPEND = XMLID('BUTTON_APPEND')
@@ -468,23 +504,21 @@ class ParamContent(PPanel):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wxNewId()
self.ID_BUTTON_EDIT = wxNewId()
self.SetBackgroundColour(panel.GetBackgroundColour())
self.SetBackgroundColour(g.panel.GetBackgroundColour())
sizer = wxBoxSizer()
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.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
self.textModified = false
self.textModified = False
EVT_BUTTON(self, self.ID_BUTTON_EDIT, self.OnButtonEdit)
EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
def OnChange(self, evt):
if self.freeze: return
self.SetModified()
self.textModified = true
evt.Skip()
PPanel.OnChange(self, evt)
self.textModified = True
def GetValue(self):
if self.textModified: # text has newer value
try:
@@ -494,11 +528,11 @@ class ParamContent(PPanel):
return []
return self.value
def SetValue(self, value):
self.freeze = true
self.freeze = True
if not value: value = []
self.value = value
self.text.SetValue(str(value)) # update text ctrl
self.freeze = false
self.freeze = False
def OnButtonEdit(self, evt):
if self.textModified: # text has newer value
try:
@@ -514,7 +548,7 @@ class ParamContent(PPanel):
# Add ignored flags
self.SetValue(value)
self.SetModified()
self.textModified = false
self.textModified = False
dlg.Destroy()
# CheckList content
@@ -536,13 +570,13 @@ class ParamContentCheckList(ParamContent):
# Add ignored flags
self.SetValue(value)
self.SetModified()
self.textModified = false
self.textModified = False
dlg.Destroy()
class IntListDialog(wxDialogPtr):
def __init__(self, parent, value):
# Is this normal???
w = frame.res.LoadDialog(parent, 'DIALOG_INTLIST')
w = g.frame.res.LoadDialog(parent, 'DIALOG_INTLIST')
wxDialogPtr.__init__(self, w.this)
self.thisown = 1
self.Center()
@@ -554,7 +588,7 @@ class IntListDialog(wxDialogPtr):
wxLogError('Invalid item type')
else:
self.list.Append(str(v))
self.SetAutoLayout(true)
self.SetAutoLayout(True)
self.GetSizer().Fit(self)
# Callbacks
self.ID_BUTTON_ADD = XMLID('BUTTON_ADD')
@@ -571,10 +605,10 @@ class IntListDialog(wxDialogPtr):
i = self.list.FindString(s)
if i == -1: # ignore non-unique
# Find place to insert
found = false
found = False
for i in range(self.list.Number()):
if int(self.list.GetString(i)) > v:
found = true
found = True
break
if found: self.list.InsertItems([s], i)
else: self.list.Append(s)
@@ -605,7 +639,7 @@ class ParamIntList(ParamContent):
# Add ignored flags
self.SetValue(value)
self.SetModified()
self.textModified = false
self.textModified = False
dlg.Destroy()
# Boxless radiobox
@@ -613,22 +647,22 @@ class RadioBox(PPanel):
def __init__(self, parent, id, choices,
pos=wxDefaultPosition, name='radiobox'):
PPanel.__init__(self, parent, name)
self.SetBackgroundColour(panel.GetBackgroundColour())
self.SetBackgroundColour(g.panel.GetBackgroundColour())
self.choices = choices
topSizer = wxBoxSizer()
for i in choices:
button = wxRadioButton(self, -1, i, name=i)
topSizer.Add(button)
EVT_RADIOBUTTON(self, button.GetId(), self.OnRadioChoice)
self.SetAutoLayout(true)
self.SetAutoLayout(True)
self.SetSizer(topSizer)
topSizer.Fit(self)
def SetStringSelection(self, value):
self.freeze = true
self.freeze = True
for i in self.choices:
self.FindWindowByName(i).SetValue(i == value)
self.value = value
self.freeze = false
self.freeze = False
def OnRadioChoice(self, evt):
if self.freeze: return
if evt.GetSelection():
@@ -664,59 +698,140 @@ class ParamFile(PPanel):
PPanel.__init__(self, parent, name)
self.ID_TEXT_CTRL = wxNewId()
self.ID_BUTTON_BROWSE = wxNewId()
self.SetBackgroundColour(panel.GetBackgroundColour())
self.SetBackgroundColour(g.panel.GetBackgroundColour())
sizer = wxBoxSizer()
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_BROWSE, 'Browse...',size=buttonSize)
sizer.Add(self.button, 0, wxALIGN_CENTER_VERTICAL)
self.SetAutoLayout(true)
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
self.textModified = false
self.textModified = False
EVT_BUTTON(self, self.ID_BUTTON_BROWSE, self.OnButtonBrowse)
EVT_TEXT(self, self.ID_TEXT_CTRL, self.OnChange)
def OnChange(self, evt):
if self.freeze: return
self.SetModified()
self.textModified = true
evt.Skip()
PPanel.OnChange(self, evt)
self.textModified = True
def GetValue(self):
if self.textModified: # text has newer value
return self.text.GetValue()
return self.value
def SetValue(self, value):
self.freeze = true
self.freeze = True
self.value = value
self.text.SetValue(value) # update text ctrl
self.freeze = false
self.freeze = False
def OnButtonBrowse(self, evt):
if self.textModified: # text has newer value
self.value = self.text.GetValue()
dlg = wxFileDialog(self,
defaultDir = os.path.dirname(self.value),
defaultDir = os.path.abspath(os.path.dirname(self.value)),
defaultFile = os.path.basename(self.value))
if dlg.ShowModal() == wxID_OK:
# Make relative
common = os.path.commonprefix([os.path.abspath(frame.dataFile),
dlg.GetPath()])
# Get common part of selected path and current
if g.frame.dataFile:
curpath = os.path.abspath(g.frame.dataFile)
else:
curpath = os.path.join(os.getcwd(), '')
common = os.path.commonprefix([curpath, dlg.GetPath()])
self.SetValue(dlg.GetPath()[len(common):])
self.SetModified()
self.textModified = false
self.textModified = False
dlg.Destroy()
class ParamBitmap(PPanel):
def __init__(self, parent, name):
# Load from resource
w = g.frame.res.LoadPanel(parent, 'PANEL_BITMAP')
# Perform initialization with class pointer
wxPanelPtr.__init__(self, w.this)
self.thisown = 1
self.modified = self.freeze = False
self.SetBackgroundColour(g.panel.GetBackgroundColour())
self.radio_std = self.FindWindowByName('RADIO_STD')
self.radio_file = self.FindWindowByName('RADIO_FILE')
self.combo = self.FindWindowByName('COMBO_STD')
self.text = self.FindWindowByName('TEXT_FILE')
self.button = self.FindWindowByName('BUTTON_BROWSE')
self.textModified = False
self.SetAutoLayout(True)
self.GetSizer().SetMinSize((260, -1))
self.GetSizer().Fit(self)
EVT_RADIOBUTTON(self, XMLID('RADIO_STD'), self.OnRadioStd)
EVT_RADIOBUTTON(self, XMLID('RADIO_FILE'), self.OnRadioFile)
EVT_BUTTON(self, XMLID('BUTTON_BROWSE'), self.OnButtonBrowse)
EVT_COMBOBOX(self, XMLID('COMBO_STD'), self.OnCombo)
EVT_TEXT(self, XMLID('COMBO_STD'), self.OnChange)
EVT_TEXT(self, XMLID('TEXT_FILE'), self.OnChange)
def OnRadioStd(self, evt):
self.SetModified()
self.SetValue(['wxART_MISSING_IMAGE',''])
def OnRadioFile(self, evt):
self.SetModified()
self.SetValue(['',''])
def updateRadios(self):
if self.value[0]:
self.radio_std.SetValue(True)
self.text.Enable(False)
self.button.Enable(False)
self.combo.Enable(True)
else:
self.radio_file.SetValue(True)
self.text.Enable(True)
self.button.Enable(True)
self.combo.Enable(False)
def OnChange(self, evt):
PPanel.OnChange(self, evt)
self.textModified = True
def OnCombo(self, evt):
PPanel.OnChange(self, evt)
self.value[0] = self.combo.GetValue()
def GetValue(self):
if self.textModified: # text has newer value
return [self.combo.GetValue(), self.text.GetValue()]
return self.value
def SetValue(self, value):
self.freeze = True
if not value:
self.value = ['', '']
else:
self.value = value
self.combo.SetValue(self.value[0])
self.text.SetValue(self.value[1]) # update text ctrl
self.updateRadios()
self.freeze = False
def OnButtonBrowse(self, evt):
if self.textModified: # text has newer value
self.value[1] = self.text.GetValue()
dlg = wxFileDialog(self,
defaultDir = os.path.abspath(os.path.dirname(self.value[1])),
defaultFile = os.path.basename(self.value[1]))
if dlg.ShowModal() == wxID_OK:
# Get common part of selected path and current
if g.frame.dataFile:
curpath = os.path.abspath(g.frame.dataFile)
else:
curpath = os.path.join(os.getcwd(), '')
common = os.path.commonprefix([curpath, dlg.GetPath()])
self.SetValue(['', dlg.GetPath()[len(common):]])
self.SetModified()
self.textModified = False
dlg.Destroy()
paramDict = {
'flag': ParamFlag,
'style': ParamStyle, 'exstyle': ParamExStyle,
'pos': ParamPosSize, 'size': ParamPosSize,
'border': ParamInt, 'cols': ParamInt, 'rows': ParamInt,
'vgap': ParamInt, 'hgap': ParamInt,
'checkable': ParamBool, 'accel': ParamAccel,
'border': ParamUnit, 'cols': ParamInt, 'rows': ParamInt,
'vgap': ParamUnit, 'hgap': ParamUnit,
'checkable': ParamBool, 'checked': ParamBool, 'radio': ParamBool,
'accel': ParamAccel,
'label': ParamText, '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': ParamFile, 'icon': ParamFile,
'tooltip': ParamText, 'bitmap': ParamBitmap, 'icon': ParamBitmap,
'label': ParamLabel, 'encoding': ParamEncoding
}

View File

@@ -0,0 +1,24 @@
(require 'sawmill-defaults)
;;; Define two hooks to reset focus behavior while mapping test window
(define (xrced-match-window-before w)
(setq prop (aref (get-x-text-property w 'WM_CLASS) 0))
(cond ((equal prop "_XRCED_T_W")
(setq transients-get-focus-b transients-get-focus)
(setq transients-get-focus nil)
(setq focus-windows-when-mapped-b focus-windows-when-mapped)
(setq focus-windows-when-mapped nil)
)
)
)
(define (xrced-match-window-after w)
(setq prop (aref (get-x-text-property w 'WM_CLASS) 0))
(cond ((equal prop "_XRCED_T_W")
(setq transients-get-focus-b transients-get-focus-b)
(setq focus-windows-when-mapped focus-windows-when-mapped-b)
)
)
)
(add-hook 'map-notify-hook xrced-match-window-before)
(add-hook 'map-notify-hook xrced-match-window-after 't)

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 253 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

View File

@@ -0,0 +1,279 @@
# Name: tools.py
# Purpose: XRC editor, toolbar
# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
# Created: 19.03.2003
# RCS-ID: $Id$
from xxx import * # xxx imports globals and params
from tree import ID_NEW
# Icons
import images
# Groups of controls
GROUPNUM = 4
GROUP_WINDOWS, GROUP_MENUS, GROUP_SIZERS, GROUP_CONTROLS = range(GROUPNUM)
# States depending on current selection and Control/Shift keys
STATE_ROOT, STATE_MENUBAR, STATE_TOOLBAR, STATE_MENU, STATE_ELSE = range(5)
# Left toolbar for GUI elements
class Tools(wxPanel):
TOOL_SIZE = (30, 30)
def __init__(self, parent):
if wxPlatform == '__WXGTK__':
wxPanel.__init__(self, parent, -1,
style=wxRAISED_BORDER|wxWANTS_CHARS)
else:
wxPanel.__init__(self, parent, -1, style=wxWANTS_CHARS)
# Create sizer for groups
self.sizer = wxBoxSizer(wxVERTICAL)
# Data to create buttons
pullDownMenu = g.pullDownMenu
self.groups = []
self.ctrl = self.shift = False
# Current state (what to enable/disable)
self.state = None
groups = [
["Windows",
(ID_NEW.FRAME, images.getToolFrameBitmap()),
(ID_NEW.DIALOG, images.getToolDialogBitmap()),
(ID_NEW.PANEL, images.getToolPanelBitmap())],
["Menus",
(ID_NEW.TOOL_BAR, images.getToolToolBarBitmap()),
(ID_NEW.MENU_BAR, images.getToolMenuBarBitmap()),
(ID_NEW.MENU, images.getToolMenuBitmap()),
(ID_NEW.TOOL, images.getToolToolBitmap()),
(ID_NEW.MENU_ITEM, images.getToolMenuItemBitmap()),
(ID_NEW.SEPARATOR, images.getToolSeparatorBitmap())],
["Sizers",
(ID_NEW.BOX_SIZER, images.getToolBoxSizerBitmap()),
(ID_NEW.STATIC_BOX_SIZER, images.getToolStaticBoxSizerBitmap()),
(ID_NEW.GRID_SIZER, images.getToolGridSizerBitmap()),
(ID_NEW.FLEX_GRID_SIZER, images.getToolFlexGridSizerBitmap()),
(ID_NEW.SPACER, images.getToolSpacerBitmap())],
["Controls",
(ID_NEW.STATIC_TEXT, images.getToolStaticTextBitmap()),
(ID_NEW.STATIC_BITMAP, images.getToolStaticBitmapBitmap()),
(ID_NEW.STATIC_LINE, images.getToolStaticLineBitmap()),
(ID_NEW.BUTTON, images.getToolButtonBitmap()),
(ID_NEW.BITMAP_BUTTON, images.getToolBitmapButtonBitmap()),
(ID_NEW.STATIC_BOX, images.getToolStaticBoxBitmap()),
(ID_NEW.TEXT_CTRL, images.getToolTextCtrlBitmap()),
(ID_NEW.COMBO_BOX, images.getToolComboBoxBitmap()),
(ID_NEW.CHOICE, images.getToolChoiceBitmap()),
(ID_NEW.RADIO_BUTTON, images.getToolRadioButtonBitmap()),
(ID_NEW.CHECK_BOX, images.getToolCheckBoxBitmap()),
(ID_NEW.RADIO_BOX, images.getToolRadioBoxBitmap()),
(ID_NEW.SPIN_CTRL, images.getToolSpinCtrlBitmap()),
(ID_NEW.SPIN_BUTTON, images.getToolSpinButtonBitmap()),
(ID_NEW.SCROLL_BAR, images.getToolScrollBarBitmap()),
(ID_NEW.SLIDER, images.getToolSliderBitmap()),
(ID_NEW.GAUGE, images.getToolGaugeBitmap()),
(ID_NEW.TREE_CTRL, images.getToolTreeCtrlBitmap()),
(ID_NEW.LIST_BOX, images.getToolListBoxBitmap()),
(ID_NEW.CHECK_LIST, images.getToolCheckListBitmap()),
(ID_NEW.LIST_CTRL, images.getToolListCtrlBitmap()),
(ID_NEW.NOTEBOOK, images.getToolNotebookBitmap()),
(ID_NEW.UNKNOWN, images.getToolUnknownBitmap())]
]
for grp in groups:
self.AddGroup(grp[0])
for b in grp[1:]:
self.AddButton(b[0], b[1], g.pullDownMenu.createMap[b[0]])
self.SetAutoLayout(True)
self.SetSizerAndFit(self.sizer)
# Allow to be resized in vertical direction only
self.SetSizeHints(self.GetSize()[0], -1)
# Events
EVT_COMMAND_RANGE(self, ID_NEW.PANEL, ID_NEW.LAST,
wxEVT_COMMAND_BUTTON_CLICKED, g.frame.OnCreate)
EVT_KEY_DOWN(self, self.OnKeyDown)
EVT_KEY_UP(self, self.OnKeyUp)
def AddButton(self, id, image, text):
button = wxBitmapButton(self, id, image, size=self.TOOL_SIZE,
style=wxBU_AUTODRAW|wxNO_BORDER|wxWANTS_CHARS)
EVT_KEY_DOWN(button, self.OnKeyDown)
EVT_KEY_UP(button, self.OnKeyUp)
button.SetToolTipString(text)
self.curSizer.Add(button)
self.groups[-1][1][id] = button
def AddGroup(self, name):
# Each group is inside box
box = wxStaticBox(self, -1, name, style=wxWANTS_CHARS)
box.SetFont(smallerFont)
boxSizer = wxStaticBoxSizer(box, wxVERTICAL)
boxSizer.Add(0, 4)
self.curSizer = wxGridSizer(0, 3)
boxSizer.Add(self.curSizer)
self.sizer.Add(boxSizer, 0, wxTOP | wxLEFT | wxRIGHT, 4)
self.groups.append((box,{}))
# Enable/disable group
def EnableGroup(self, gnum, enable = True):
grp = self.groups[gnum]
grp[0].Enable(enable)
for b in grp[1].values(): b.Enable(enable)
# Enable/disable group item
def EnableGroupItem(self, gnum, id, enable = True):
grp = self.groups[gnum]
grp[1][id].Enable(enable)
# Enable/disable group items
def EnableGroupItems(self, gnum, ids, enable = True):
grp = self.groups[gnum]
for id in ids:
grp[1][id].Enable(enable)
# Process key events
def OnKeyDown(self, evt):
if evt.GetKeyCode() == WXK_CONTROL:
g.tree.ctrl = True
elif evt.GetKeyCode() == WXK_SHIFT:
g.tree.shift = True
self.UpdateIfNeeded()
evt.Skip()
def OnKeyUp(self, evt):
if evt.GetKeyCode() == WXK_CONTROL:
g.tree.ctrl = False
elif evt.GetKeyCode() == WXK_SHIFT:
g.tree.shift = False
self.UpdateIfNeeded()
evt.Skip()
def OnMouse(self, evt):
# Update control and shift states
g.tree.ctrl = evt.ControlDown()
g.tree.shift = evt.ShiftDown()
self.UpdateIfNeeded()
evt.Skip()
# Update UI after key presses, if necessary
def UpdateIfNeeded(self):
tree = g.tree
if self.ctrl != tree.ctrl or self.shift != tree.shift:
# Enabling is needed only for ctrl
if self.ctrl != tree.ctrl: self.UpdateUI()
self.ctrl = tree.ctrl
self.shift = tree.shift
if tree.ctrl:
status = 'SBL'
elif tree.shift:
status = 'INS'
else:
status = ''
g.frame.SetStatusText(status, 1)
# Update interface
def UpdateUI(self):
# Update status bar
pullDownMenu = g.pullDownMenu
tree = g.tree
item = tree.selection
# If nothing selected, disable everything and return
if not item:
# Disable everything
for grp in range(GROUPNUM):
self.EnableGroup(grp, False)
self.state = None
return
if tree.ctrl: needInsert = True
else: needInsert = tree.NeedInsert(item)
# Enable depending on selection
if item == tree.root or needInsert and tree.GetItemParent(item) == tree.root:
state = STATE_ROOT
else:
xxx = tree.GetPyData(item).treeObject()
# Check parent for possible child nodes if inserting sibling
if needInsert: xxx = xxx.parent
if xxx.__class__ == xxxMenuBar:
state = STATE_MENUBAR
elif xxx.__class__ in [xxxToolBar, xxxTool] or \
xxx.__class__ == xxxSeparator and xxx.parent.__class__ == xxxToolBar:
state = STATE_TOOLBAR
elif xxx.__class__ in [xxxMenu, xxxMenuItem]:
state = STATE_MENU
else:
state = STATE_ELSE
# Enable depending on selection
if state != self.state:
# Disable everything
for grp in range(GROUPNUM):
self.EnableGroup(grp, False)
# Enable some
if state == STATE_ROOT:
self.EnableGroup(GROUP_WINDOWS, True)
self.EnableGroup(GROUP_MENUS, True)
# But disable items
self.EnableGroupItems(GROUP_MENUS,
[ ID_NEW.TOOL,
ID_NEW.MENU_ITEM,
ID_NEW.SEPARATOR ],
False)
elif state == STATE_MENUBAR:
self.EnableGroup(GROUP_MENUS)
self.EnableGroupItems(GROUP_MENUS,
[ ID_NEW.TOOL_BAR,
ID_NEW.MENU_BAR,
ID_NEW.TOOL ],
False)
elif state == STATE_TOOLBAR:
self.EnableGroup(GROUP_MENUS)
self.EnableGroupItems(GROUP_MENUS,
[ ID_NEW.TOOL_BAR,
ID_NEW.MENU,
ID_NEW.MENU_BAR,
ID_NEW.MENU_ITEM ],
False)
self.EnableGroup(GROUP_CONTROLS)
self.EnableGroupItems(GROUP_CONTROLS,
[ ID_NEW.TREE_CTRL,
ID_NEW.NOTEBOOK ],
False)
elif state == STATE_MENU:
self.EnableGroup(GROUP_MENUS)
self.EnableGroupItems(GROUP_MENUS,
[ ID_NEW.TOOL_BAR,
ID_NEW.MENU_BAR,
ID_NEW.TOOL ],
False)
else:
self.EnableGroup(GROUP_WINDOWS)
self.EnableGroupItems(GROUP_WINDOWS,
[ ID_NEW.FRAME,
ID_NEW.DIALOG ],
False)
self.EnableGroup(GROUP_MENUS)
self.EnableGroupItems(GROUP_MENUS,
[ ID_NEW.MENU_BAR,
ID_NEW.MENU_BAR,
ID_NEW.MENU,
ID_NEW.MENU_ITEM,
ID_NEW.TOOL,
ID_NEW.SEPARATOR ],
False)
self.EnableGroup(GROUP_SIZERS)
self.EnableGroup(GROUP_CONTROLS)
# Special case for notebook (always executed)
if state == STATE_ELSE:
if xxx.__class__ == xxxNotebook:
self.EnableGroup(GROUP_SIZERS, False)
else:
self.EnableGroup(GROUP_SIZERS)
if not (xxx.isSizer or xxx.parent and xxx.parent.isSizer):
self.EnableGroupItem(GROUP_SIZERS, ID_NEW.SPACER, False)
# Save state
self.state = state

View File

@@ -0,0 +1,839 @@
# Name: tree.py
# Purpose: XRC editor, XML_tree class
# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
# Created: 02.12.2002
# RCS-ID: $Id$
from xxx import * # xxx imports globals and params
# Icons
import images
class MemoryFile:
def __init__(self, name):
self.name = name
self.buffer = ''
def write(self, data):
self.buffer += data.encode()
def close(self):
wxMemoryFSHandler_AddFile(self.name, self.buffer)
################################################################################
# Redefine writing to include encoding
class MyDocument(minidom.Document):
def __init__(self):
minidom.Document.__init__(self)
self.encoding = ''
def writexml(self, writer, indent="", addindent="", newl="", encoding=""):
if encoding: encdstr = 'encoding="%s"' % encoding
else: encdstr = ''
writer.write('<?xml version="1.0" %s?>\n' % encdstr)
for node in self.childNodes:
node.writexml(writer, indent, addindent, newl)
################################################################################
# Ids for menu commands
class ID_NEW:
PANEL = wxNewId()
DIALOG = wxNewId()
FRAME = wxNewId()
TOOL_BAR = wxNewId()
TOOL = wxNewId()
MENU_BAR = wxNewId()
MENU = wxNewId()
STATIC_TEXT = wxNewId()
TEXT_CTRL = wxNewId()
BUTTON = wxNewId()
BITMAP_BUTTON = wxNewId()
RADIO_BUTTON = wxNewId()
SPIN_BUTTON = wxNewId()
STATIC_BOX = wxNewId()
CHECK_BOX = wxNewId()
RADIO_BOX = wxNewId()
COMBO_BOX = wxNewId()
LIST_BOX = wxNewId()
STATIC_LINE = wxNewId()
STATIC_BITMAP = wxNewId()
CHOICE = wxNewId()
SLIDER = wxNewId()
GAUGE = wxNewId()
SCROLL_BAR = wxNewId()
TREE_CTRL = wxNewId()
LIST_CTRL = wxNewId()
CHECK_LIST = wxNewId()
NOTEBOOK = wxNewId()
HTML_WINDOW = wxNewId()
CALENDAR_CTRL = wxNewId()
GENERIC_DIR_CTRL = wxNewId()
SPIN_CTRL = wxNewId()
UNKNOWN = wxNewId()
BOX_SIZER = wxNewId()
STATIC_BOX_SIZER = wxNewId()
GRID_SIZER = wxNewId()
FLEX_GRID_SIZER = wxNewId()
SPACER = wxNewId()
TOOL_BAR = wxNewId()
TOOL = wxNewId()
MENU = wxNewId()
MENU_ITEM = wxNewId()
SEPARATOR = wxNewId()
LAST = wxNewId()
class PullDownMenu:
ID_EXPAND = wxNewId()
ID_COLLAPSE = wxNewId()
ID_PASTE_SIBLING = wxNewId()
def __init__(self, parent):
self.ID_DELETE = parent.ID_DELETE
EVT_MENU_RANGE(parent, ID_NEW.PANEL, 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(g.tree, parent.OnPullDownHighlight)
# Mapping from IDs to element names
self.createMap = {
ID_NEW.PANEL: 'wxPanel',
ID_NEW.DIALOG: 'wxDialog',
ID_NEW.FRAME: 'wxFrame',
ID_NEW.TOOL_BAR: 'wxToolBar',
ID_NEW.TOOL: 'tool',
ID_NEW.MENU_BAR: 'wxMenuBar',
ID_NEW.MENU: 'wxMenu',
ID_NEW.MENU_ITEM: 'wxMenuItem',
ID_NEW.SEPARATOR: 'separator',
ID_NEW.STATIC_TEXT: 'wxStaticText',
ID_NEW.TEXT_CTRL: 'wxTextCtrl',
ID_NEW.BUTTON: 'wxButton',
ID_NEW.BITMAP_BUTTON: 'wxBitmapButton',
ID_NEW.RADIO_BUTTON: 'wxRadioButton',
ID_NEW.SPIN_BUTTON: 'wxSpinButton',
ID_NEW.STATIC_BOX: 'wxStaticBox',
ID_NEW.CHECK_BOX: 'wxCheckBox',
ID_NEW.RADIO_BOX: 'wxRadioBox',
ID_NEW.COMBO_BOX: 'wxComboBox',
ID_NEW.LIST_BOX: 'wxListBox',
ID_NEW.STATIC_LINE: 'wxStaticLine',
ID_NEW.STATIC_BITMAP: 'wxStaticBitmap',
ID_NEW.CHOICE: 'wxChoice',
ID_NEW.SLIDER: 'wxSlider',
ID_NEW.GAUGE: 'wxGauge',
ID_NEW.SCROLL_BAR: 'wxScrollBar',
ID_NEW.TREE_CTRL: 'wxTreeCtrl',
ID_NEW.LIST_CTRL: 'wxListCtrl',
ID_NEW.CHECK_LIST: 'wxCheckList',
ID_NEW.NOTEBOOK: 'wxNotebook',
ID_NEW.HTML_WINDOW: 'wxHtmlWindow',
ID_NEW.CALENDAR_CTRL: 'wxCalendarCtrl',
ID_NEW.GENERIC_DIR_CTRL: 'wxGenericDirCtrl',
ID_NEW.SPIN_CTRL: 'wxSpinCtrl',
ID_NEW.BOX_SIZER: 'wxBoxSizer',
ID_NEW.STATIC_BOX_SIZER: 'wxStaticBoxSizer',
ID_NEW.GRID_SIZER: 'wxGridSizer',
ID_NEW.FLEX_GRID_SIZER: 'wxFlexGridSizer',
ID_NEW.SPACER: 'spacer',
ID_NEW.UNKNOWN: 'unknown',
}
self.controls = [
['control', 'Various controls',
(ID_NEW.STATIC_TEXT, 'Label', 'Create label'),
(ID_NEW.STATIC_BITMAP, 'Bitmap', 'Create bitmap'),
(ID_NEW.STATIC_LINE, 'Line', 'Create line'),
(ID_NEW.TEXT_CTRL, 'TextBox', 'Create text box'),
(ID_NEW.CHOICE, 'Choice', 'Create choice'),
(ID_NEW.SLIDER, 'Slider', 'Create slider'),
(ID_NEW.GAUGE, 'Gauge', 'Create gauge'),
(ID_NEW.SPIN_CTRL, 'SpinCtrl', 'Create spin'),
(ID_NEW.SCROLL_BAR, 'ScrollBar', 'Create scroll bar'),
(ID_NEW.TREE_CTRL, 'TreeCtrl', 'Create tree'),
(ID_NEW.LIST_CTRL, 'ListCtrl', 'Create list'),
(ID_NEW.CHECK_LIST, 'CheckList', 'Create check list'),
(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'),
(ID_NEW.UNKNOWN, 'Unknown', 'Create custom control placeholder'),
],
['button', 'Buttons',
(ID_NEW.BUTTON, 'Button', 'Create button'),
(ID_NEW.BITMAP_BUTTON, 'BitmapButton', 'Create bitmap button'),
(ID_NEW.RADIO_BUTTON, 'RadioButton', 'Create radio button'),
(ID_NEW.SPIN_BUTTON, 'SpinButton', 'Create spin button'),
],
['box', 'Boxes',
(ID_NEW.STATIC_BOX, 'StaticBox', 'Create static box'),
(ID_NEW.CHECK_BOX, 'CheckBox', 'Create check box'),
(ID_NEW.RADIO_BOX, 'RadioBox', 'Create radio box'),
(ID_NEW.COMBO_BOX, 'ComboBox', 'Create combo box'),
(ID_NEW.LIST_BOX, 'ListBox', 'Create list box'),
],
['container', 'Containers',
(ID_NEW.PANEL, 'Panel', 'Create panel'),
(ID_NEW.NOTEBOOK, 'Notebook', 'Create notebook control'),
(ID_NEW.TOOL_BAR, 'ToolBar', 'Create toolbar'),
],
['sizer', 'Sizers',
(ID_NEW.BOX_SIZER, 'BoxSizer', 'Create box sizer'),
(ID_NEW.STATIC_BOX_SIZER, 'StaticBoxSizer',
'Create static box sizer'),
(ID_NEW.GRID_SIZER, 'GridSizer', 'Create grid sizer'),
(ID_NEW.FLEX_GRID_SIZER, 'FlexGridSizer',
'Create flexgrid sizer'),
(ID_NEW.SPACER, 'Spacer', 'Create spacer'),
]
]
self.menuControls = [
(ID_NEW.MENU, 'Menu', 'Create menu'),
(ID_NEW.MENU_ITEM, 'MenuItem', 'Create menu item'),
(ID_NEW.SEPARATOR, 'Separator', 'Create separator'),
]
self.toolBarControls = [
(ID_NEW.TOOL, 'Tool', 'Create tool'),
(ID_NEW.SEPARATOR, 'Separator', 'Create separator'),
['control', 'Various controls',
(ID_NEW.STATIC_TEXT, 'Label', 'Create label'),
(ID_NEW.STATIC_BITMAP, 'Bitmap', 'Create bitmap'),
(ID_NEW.STATIC_LINE, 'Line', 'Create line'),
(ID_NEW.TEXT_CTRL, 'TextBox', 'Create text box'),
(ID_NEW.CHOICE, 'Choice', 'Create choice'),
(ID_NEW.SLIDER, 'Slider', 'Create slider'),
(ID_NEW.GAUGE, 'Gauge', 'Create gauge'),
(ID_NEW.SCROLL_BAR, 'ScrollBar', 'Create scroll bar'),
(ID_NEW.LIST_CTRL, 'ListCtrl', 'Create list control'),
(ID_NEW.CHECK_LIST, 'CheckList', 'Create check list'),
],
['button', 'Buttons',
(ID_NEW.BUTTON, 'Button', 'Create button'),
(ID_NEW.BITMAP_BUTTON, 'BitmapButton', 'Create bitmap button'),
(ID_NEW.RADIO_BUTTON, 'RadioButton', 'Create radio button'),
(ID_NEW.SPIN_BUTTON, 'SpinButton', 'Create spin button'),
],
['box', 'Boxes',
(ID_NEW.STATIC_BOX, 'StaticBox', 'Create static box'),
(ID_NEW.CHECK_BOX, 'CheckBox', 'Create check box'),
(ID_NEW.RADIO_BOX, 'RadioBox', 'Create radio box'),
(ID_NEW.COMBO_BOX, 'ComboBox', 'Create combo box'),
(ID_NEW.LIST_BOX, 'ListBox', 'Create list box'),
],
]
################################################################################
# Set menu to list items.
# Each menu command is a tuple (id, label, help)
# submenus are lists [id, label, help, submenu]
# and separators are any other type
def SetMenu(m, list):
for l in list:
if type(l) == types.TupleType:
apply(m.Append, l)
elif type(l) == types.ListType:
subMenu = wxMenu()
SetMenu(subMenu, l[2:])
m.AppendMenu(wxNewId(), l[0], subMenu, l[1])
else: # separator
m.AppendSeparator()
################################################################################
class HighLightBox:
def __init__(self, pos, size):
if size.x == -1: size.x = 0
if size.y == -1: size.y = 0
w = g.testWin.panel
l1 = wxWindow(w, -1, pos, wxSize(size.x, 2))
l1.SetBackgroundColour(wxRED)
l2 = wxWindow(w, -1, pos, wxSize(2, size.y))
l2.SetBackgroundColour(wxRED)
l3 = wxWindow(w, -1, wxPoint(pos.x + size.x - 2, pos.y), wxSize(2, size.y))
l3.SetBackgroundColour(wxRED)
l4 = wxWindow(w, -1, wxPoint(pos.x, pos.y + size.y - 2), wxSize(size.x, 2))
l4.SetBackgroundColour(wxRED)
self.lines = [l1, l2, l3, l4]
# Move highlight to a new position
def Replace(self, pos, size):
if size.x == -1: size.x = 0
if size.y == -1: size.y = 0
self.lines[0].SetDimensions(pos.x, pos.y, size.x, 2)
self.lines[1].SetDimensions(pos.x, pos.y, 2, size.y)
self.lines[2].SetDimensions(pos.x + size.x - 2, pos.y, 2, size.y)
self.lines[3].SetDimensions(pos.x, pos.y + size.y - 2, size.x, 2)
# Remove it
def Remove(self):
map(wxWindow.Destroy, self.lines)
g.testWin.highLight = None
################################################################################
class XML_Tree(wxTreeCtrl):
# Constant to define standart window name
stdName = '_XRCED_T_W'
def __init__(self, parent, id):
wxTreeCtrl.__init__(self, parent, id, style = wxTR_HAS_BUTTONS)
self.SetBackgroundColour(wxColour(224, 248, 224))
EVT_TREE_SEL_CHANGED(self, self.GetId(), self.OnSelChanged)
# One works on Linux, another on Windows
if wxPlatform == '__WXGTK__':
EVT_TREE_ITEM_ACTIVATED(self, self.GetId(), self.OnItemActivated)
else:
EVT_LEFT_DCLICK(self, self.OnDClick)
EVT_RIGHT_DOWN(self, self.OnRightDown)
self.needUpdate = False
self.pendingHighLight = None
self.ctrl = self.shift = False
self.dom = None
# Create image list
il = wxImageList(16, 16, True)
self.rootImage = il.AddIcon(images.getTreeRootIcon())
xxxObject.image = il.AddIcon(images.getTreeDefaultIcon())
xxxPanel.image = il.AddIcon(images.getTreePanelIcon())
xxxDialog.image = il.AddIcon(images.getTreeDialogIcon())
xxxFrame.image = il.AddIcon(images.getTreeFrameIcon())
xxxMenuBar.image = il.AddIcon(images.getTreeMenuBarIcon())
xxxMenu.image = il.AddIcon(images.getTreeMenuIcon())
xxxMenuItem.image = il.AddIcon(images.getTreeMenuItemIcon())
xxxToolBar.image = il.AddIcon(images.getTreeToolBarIcon())
xxxTool.image = il.AddIcon(images.getTreeToolIcon())
xxxSeparator.image = il.AddIcon(images.getTreeSeparatorIcon())
xxxSizer.imageH = il.AddIcon(images.getTreeSizerHIcon())
xxxSizer.imageV = il.AddIcon(images.getTreeSizerVIcon())
xxxStaticBoxSizer.imageH = il.AddIcon(images.getTreeStaticBoxSizerHIcon())
xxxStaticBoxSizer.imageV = il.AddIcon(images.getTreeStaticBoxSizerVIcon())
xxxGridSizer.image = il.AddIcon(images.getTreeSizerGridIcon())
xxxFlexGridSizer.image = il.AddIcon(images.getTreeSizerFlexGridIcon())
self.il = il
self.SetImageList(il)
def RegisterKeyEvents(self):
EVT_KEY_DOWN(self, g.tools.OnKeyDown)
EVT_KEY_UP(self, g.tools.OnKeyUp)
EVT_ENTER_WINDOW(self, g.tools.OnMouse)
EVT_LEAVE_WINDOW(self, g.tools.OnMouse)
def Unselect(self):
self.selection = None
wxTreeCtrl.Unselect(self)
g.tools.UpdateUI()
def ExpandAll(self, item):
if self.ItemHasChildren(item):
self.Expand(item)
i, cookie = self.GetFirstChild(item, 0)
children = []
while i.IsOk():
children.append(i)
i, cookie = self.GetNextChild(item, cookie)
for i in children:
self.ExpandAll(i)
def CollapseAll(self, item):
if self.ItemHasChildren(item):
i, cookie = self.GetFirstChild(item, 0)
children = []
while i.IsOk():
children.append(i)
i, cookie = self.GetNextChild(item, cookie)
for i in children:
self.CollapseAll(i)
self.Collapse(item)
# Clear tree
def Clear(self):
self.DeleteAllItems()
# Add minimal structure
if self.dom: self.dom.unlink()
self.dom = MyDocument()
self.dummyNode = self.dom.createComment('dummy node')
# Create main node
self.mainNode = self.dom.createElement('resource')
self.dom.appendChild(self.mainNode)
self.rootObj = xxxMainNode(self.dom)
self.root = self.AddRoot('XML tree', self.rootImage,
data=wxTreeItemData(self.rootObj))
self.SetItemHasChildren(self.root)
self.Expand(self.root)
self.Unselect()
# Clear old data and set new
def SetData(self, dom):
self.DeleteAllItems()
# Add minimal structure
if self.dom: self.dom.unlink()
self.dom = dom
self.dummyNode = self.dom.createComment('dummy node')
# Find 'resource' child, add it's children
self.mainNode = dom.documentElement
self.rootObj = xxxMainNode(self.dom)
self.root = self.AddRoot('XML tree', self.rootImage,
data=wxTreeItemData(self.rootObj))
self.SetItemHasChildren(self.root)
nodes = self.mainNode.childNodes[:]
for node in nodes:
if IsObject(node):
self.AddNode(self.root, None, node)
else:
self.mainNode.removeChild(node)
node.unlink()
self.Expand(self.root)
self.Unselect()
# Add tree item for given parent item if node is DOM element node with
# 'object' tag. xxxParent is parent xxx object
def AddNode(self, itemParent, xxxParent, node):
# Set item data to current node
try:
xxx = MakeXXXFromDOM(xxxParent, node)
except:
print 'ERROR: MakeXXXFromDom(%s, %s)' % (xxxParent, node)
raise
treeObj = xxx.treeObject()
# Append tree item
item = self.AppendItem(itemParent, treeObj.treeName(),
image=treeObj.treeImage(),
data=wxTreeItemData(xxx))
# Try to find children objects
if treeObj.hasChildren:
nodes = treeObj.element.childNodes[:]
for n in nodes:
if IsObject(n):
self.AddNode(item, treeObj, n)
elif n.nodeType != minidom.Node.ELEMENT_NODE:
treeObj.element.removeChild(n)
n.unlink()
# Insert new item at specific position
def InsertNode(self, itemParent, parent, elem, nextItem):
# Insert in XML tree and wxWin
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)
# 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)
newItem = self.AppendItem(itemParent, xxx.treeName(), image=xxx.treeImage(),
data=wxTreeItemData(xxx))
# Add children items
if xxx.hasChildren:
treeObj = xxx.treeObject()
for n in treeObj.element.childNodes:
if IsObject(n):
self.AddNode(newItem, treeObj, n)
return newItem
# Remove leaf of tree, return it's data object
def RemoveLeaf(self, leaf):
xxx = self.GetPyData(leaf)
node = xxx.element
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):
# Root at (0,0)
if item == g.testWin.item: return wxPoint(0, 0)
itemParent = self.GetItemParent(item)
# Select NB page
obj = self.FindNodeObject(item)
if self.GetPyData(itemParent).treeObject().__class__ == xxxNotebook:
notebook = self.FindNodeObject(itemParent)
# Find position
for i in range(notebook.GetPageCount()):
if notebook.GetPage(i) == obj:
if notebook.GetSelection() != i: notebook.SetSelection(i)
break
# Find first ancestor which is a wxWindow (not a sizer)
winParent = itemParent
while self.GetPyData(winParent).isSizer:
winParent = self.GetItemParent(winParent)
parentPos = self.FindNodePos(winParent)
# Position (-1,-1) is really (0,0)
pos = obj.GetPosition()
if pos == (-1,-1): pos = (0,0)
return parentPos + pos
# Find window (or sizer) corresponding to a tree item.
def FindNodeObject(self, item):
testWin = g.testWin
# If top-level, return testWin (or panel its panel)
if item == testWin.item: return testWin.panel
itemParent = self.GetItemParent(item)
xxx = self.GetPyData(item).treeObject()
parentWin = self.FindNodeObject(itemParent)
# Top-level sizer? return window's sizer
if xxx.isSizer and isinstance(parentWin, wxWindowPtr):
return parentWin.GetSizer()
# Otherwise get parent's object and it's child
child = parentWin.GetChildren()[self.ItemIndex(item)]
# Return window or sizer for sizer items
if child.GetClassName() == 'wxSizerItem':
if child.IsWindow(): child = child.GetWindow()
elif child.IsSizer():
child = child.GetSizer()
# Test for notebook sizers
if isinstance(child, wxNotebookSizerPtr):
child = child.GetNotebook()
return child
def OnSelChanged(self, evt):
# Apply changes
# !!! problem with wxGTK - GetOldItem is Ok if nothing selected
#oldItem = evt.GetOldItem()
status = ''
oldItem = self.selection
if oldItem:
xxx = self.GetPyData(oldItem)
# 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()
self.needUpdate = True
status = 'Changes were applied'
g.frame.SetStatusText(status)
# Generate view
self.selection = evt.GetItem()
if not self.selection.IsOk():
self.selection = None
return
xxx = self.GetPyData(self.selection)
# Update panel
g.panel.SetData(xxx)
# Update tools
g.tools.UpdateUI()
# Hightlighting is done in OnIdle
self.pendingHighLight = self.selection
# Check if item is in testWin subtree
def IsHighlatable(self, item):
if item == g.testWin.item: return False
while item != self.root:
item = self.GetItemParent(item)
if item == g.testWin.item: return True
return False
# Highlight selected item
def HighLight(self, item):
self.pendingHighLight = None
# Can highlight only with some top-level windows
if not g.testWin or self.GetPyData(g.testWin.item).treeObject().__class__ \
not in [xxxDialog, xxxPanel, xxxFrame]:
return
# If a control from another window is selected, remove highlight
if not self.IsHighlatable(item):
if g.testWin.highLight: g.testWin.highLight.Remove()
return
# Get window/sizer object
obj, pos = self.FindNodeObject(item), self.FindNodePos(item)
size = obj.GetSize()
# Highlight
# Nagative positions are not working wuite well
if g.testWin.highLight:
g.testWin.highLight.Replace(pos, size)
else:
g.testWin.highLight = HighLightBox(pos, size)
g.testWin.highLight.item = item
def ShowTestWindow(self, item):
xxx = self.GetPyData(item)
if g.panel.IsModified():
self.Apply(xxx, item) # apply changes
treeObj = xxx.treeObject()
if treeObj.className not in ['wxFrame', 'wxPanel', 'wxDialog',
'wxMenuBar', 'wxToolBar']:
wxLogMessage('No view for this element (yet)')
return
# Show item in bold
if g.testWin: # Reset old
self.SetItemBold(g.testWin.item, False)
self.CreateTestWin(item)
# Maybe an error occured, so we need to test
if g.testWin: self.SetItemBold(g.testWin.item)
# Double-click on Linux
def OnItemActivated(self, evt):
if evt.GetItem() != self.root:
self.ShowTestWindow(evt.GetItem())
# Double-click on Windows
def OnDClick(self, evt):
item, flags = self.HitTest(evt.GetPosition())
if flags in [wxTREE_HITTEST_ONITEMBUTTON, wxTREE_HITTEST_ONITEMLABEL]:
if item != self.root: self.ShowTestWindow(item)
else:
evt.Skip()
# (re)create test window
def CreateTestWin(self, item):
testWin = g.testWin
wxBeginBusyCursor()
wxYield()
# Create a window with this resource
xxx = self.GetPyData(item).treeObject()
# Close old window, remember where it was
highLight = None
if testWin:
pos = testWin.GetPosition()
if item == testWin.item:
# Remember highlight if same top-level window
if testWin.highLight:
highLight = testWin.highLight.item
if xxx.className == 'wxPanel':
if testWin.highLight:
testWin.pendingHighLight = highLight
testWin.highLight.Remove()
testWin.panel.Destroy()
testWin.panel = None
else:
testWin.Destroy()
testWin = g.testWin = None
else:
testWin.Destroy()
testWin = g.testWin = None
else:
pos = g.testWinPos
# Save in memory FS
memFile = MemoryFile('xxx.xrc')
# Create partial XML file - faster for big files
dom = MyDocument()
mainNode = dom.createElement('resource')
dom.appendChild(mainNode)
# Remove temporarily from old parent
elem = xxx.element
# Change window id to _XRCED_T_W. This gives some name for
# unnamed windows, and for named gives the possibility to
# write sawfish scripts.
if not xxx.name:
name = 'noname'
else:
name = xxx.name
elem.setAttribute('name', self.stdName)
parent = elem.parentNode
next = elem.nextSibling
parent.replaceChild(self.dummyNode, elem)
# Append to new DOM, write it
mainNode.appendChild(elem)
dom.writexml(memFile, encoding=self.rootObj.params['encoding'].value())
# Put back in place
mainNode.removeChild(elem)
dom.unlink()
parent.replaceChild(elem, self.dummyNode)
# Remove temporary name or restore changed
if not xxx.name:
elem.removeAttribute('name')
else:
elem.setAttribute('name', xxx.name)
memFile.close() # write to wxMemoryFS
res = wxXmlResource('', g.xmlFlags)
res.Load('memory:xxx.xrc')
if xxx.__class__ == xxxFrame:
# Frame can't have many children,
# but it's first child possibly can...
child = self.GetFirstChild(item, 0)[0]
if child.IsOk() and self.GetPyData(child).__class__ == xxxPanel:
# Clean-up before recursive call or error
wxMemoryFSHandler_RemoveFile('xxx.xrc')
wxEndBusyCursor()
self.CreateTestWin(child)
return
# This currently works under GTK, but not under MSW
testWin = g.testWin = wxPreFrame()
res.LoadOnFrame(testWin, g.frame, self.stdName)
# Create status bar
testWin.CreateStatusBar()
testWin.panel = testWin
testWin.SetPosition(pos)
testWin.Show(True)
elif xxx.__class__ == xxxPanel:
# Create new frame
if not testWin:
testWin = g.testWin = wxFrame(g.frame, -1, 'Panel: ' + name, pos=pos)
testWin.panel = res.LoadPanel(testWin, self.stdName)
testWin.SetClientSize(testWin.panel.GetSize())
testWin.Show(True)
elif xxx.__class__ == xxxDialog:
testWin = g.testWin = res.LoadDialog(None, self.stdName)
testWin.panel = testWin
testWin.Layout()
testWin.SetPosition(pos)
testWin.Show(True)
elif xxx.__class__ == xxxMenuBar:
testWin = g.testWin = wxFrame(g.frame, -1, 'MenuBar: ' + name, pos=pos)
testWin.panel = None
# Set status bar to display help
testWin.CreateStatusBar()
testWin.menuBar = res.LoadMenuBar(self.stdName)
testWin.SetMenuBar(testWin.menuBar)
testWin.Show(True)
elif xxx.__class__ == xxxToolBar:
testWin = g.testWin = wxFrame(g.frame, -1, 'ToolBar: ' + name, pos=pos)
testWin.panel = None
# Set status bar to display help
testWin.CreateStatusBar()
testWin.toolBar = res.LoadToolBar(testWin, self.stdName)
testWin.SetToolBar(testWin.toolBar)
testWin.Show(True)
wxMemoryFSHandler_RemoveFile('xxx.xrc')
testWin.item = item
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 self.pendingHighLight:
self.HighLight(highLight)
wxEndBusyCursor()
def OnCloseTestWin(self, evt):
self.SetItemBold(g.testWin.item, False)
g.testWinPos = g.testWin.GetPosition()
g.testWin.Destroy()
g.testWin = None
# Return item index in parent
def ItemIndex(self, item):
n = 0 # index of sibling
prev = self.GetPrevSibling(item)
while prev.IsOk():
prev = self.GetPrevSibling(prev)
n += 1
return n
# Full tree index of an item - list of positions
def ItemFullIndex(self, item):
if not item.IsOk(): return None
l = []
while item != self.root:
l.insert(0, self.ItemIndex(item))
item = self.GetItemParent(item)
return l
# Get item position from full index
def ItemAtFullIndex(self, index):
if index is None: return wxTreeItemId()
item = self.root
for i in index:
item = self.GetFirstChild(item, 0)[0]
for k in range(i): item = self.GetNextSibling(item)
return item
# 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 xxx.hasChildren and not self.GetChildrenCount(item, False):
return False
return not (self.IsExpanded(item) and self.GetChildrenCount(item, False))
# Pull-down
def OnRightDown(self, evt):
pullDownMenu = g.pullDownMenu
# select this item
pt = evt.GetPosition();
item, flags = self.HitTest(pt)
if item.Ok() and flags & wxTREE_HITTEST_ONITEM:
self.SelectItem(item)
# Setup menu
menu = wxMenu()
item = self.selection
if not item:
menu.Append(g.pullDownMenu.ID_EXPAND, 'Expand', 'Expand tree')
menu.Append(g.pullDownMenu.ID_COLLAPSE, 'Collapse', 'Collapse tree')
else:
# self.ctrl = evt.ControlDown() # save Ctrl state
# self.shift = evt.ShiftDown() # and Shift too
m = wxMenu() # create menu
if self.ctrl:
needInsert = True
else:
needInsert = self.NeedInsert(item)
if item == self.root or needInsert and self.GetItemParent(item) == self.root:
m.Append(ID_NEW.PANEL, 'Panel', 'Create panel')
m.Append(ID_NEW.DIALOG, 'Dialog', 'Create dialog')
m.Append(ID_NEW.FRAME, 'Frame', 'Create frame')
m.AppendSeparator()
m.Append(ID_NEW.TOOL_BAR, 'ToolBar', 'Create toolbar')
m.Append(ID_NEW.MENU_BAR, 'MenuBar', 'Create menubar')
m.Append(ID_NEW.MENU, 'Menu', 'Create menu')
else:
xxx = self.GetPyData(item).treeObject()
# Check parent for possible child nodes if inserting sibling
if needInsert: xxx = xxx.parent
if xxx.__class__ == xxxMenuBar:
m.Append(ID_NEW.MENU, 'Menu', 'Create menu')
elif xxx.__class__ in [xxxToolBar, xxxTool] or \
xxx.__class__ == xxxSeparator and xxx.parent.__class__ == xxxToolBar:
SetMenu(m, pullDownMenu.toolBarControls)
elif xxx.__class__ in [xxxMenu, xxxMenuItem]:
SetMenu(m, pullDownMenu.menuControls)
else:
SetMenu(m, pullDownMenu.controls)
if xxx.__class__ == xxxNotebook:
m.Enable(m.FindItem('sizer'), False)
elif not (xxx.isSizer or xxx.parent and xxx.parent.isSizer):
m.Enable(ID_NEW.SPACER, False)
# Select correct label for create menu
if not needInsert:
if self.shift:
menu.AppendMenu(wxNewId(), 'Insert Child', m,
'Create child object as the first child')
else:
menu.AppendMenu(wxNewId(), 'Append Child', m,
'Create child object as the last child')
else:
if self.shift:
menu.AppendMenu(wxNewId(), 'Create Sibling', m,
'Create sibling before selected object')
else:
menu.AppendMenu(wxNewId(), 'Create Sibling', m,
'Create sibling after selected object')
menu.AppendSeparator()
# Not using standart IDs because we don't want to show shortcuts
menu.Append(wxID_CUT, 'Cut', 'Cut to the clipboard')
menu.Append(wxID_COPY, 'Copy', 'Copy to the clipboard')
if self.ctrl and item != self.root:
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')
menu.Append(pullDownMenu.ID_DELETE,
'Delete', 'Delete object')
if self.ItemHasChildren(item):
menu.AppendSeparator()
menu.Append(pullDownMenu.ID_EXPAND, 'Expand', 'Expand subtree')
menu.Append(pullDownMenu.ID_COLLAPSE, 'Collapse', 'Collapse subtree')
self.PopupMenu(menu, evt.GetPosition())
menu.Destroy()
# Apply changes
def Apply(self, xxx, item):
g.panel.Apply()
# Update tree view
xxx = xxx.treeObject()
if xxx.hasName and self.GetItemText(item) != xxx.name:
self.SetItemText(item, xxx.treeName())
# Item width may have changed
# !!! Tric to update tree width (wxGTK, ??)
self.SetIndent(self.GetIndent())
# Change tree icon for sizers
if isinstance(xxx, xxxBoxSizer):
self.SetItemImage(item, xxx.treeImage())
# Set global modified state
g.frame.modified = True

View File

@@ -0,0 +1,151 @@
# Name: undo.py
# Purpose: XRC editor, undo/redo module
# Author: Roman Rolinsky <rolinsky@mema.ucl.ac.be>
# Created: 01.12.2002
# RCS-ID: $Id$
from globals import *
#from panel import *
# Undo/redo classes
class UndoManager:
# Undo/redo stacks
undo = []
redo = []
def RegisterUndo(self, undoObj):
self.undo.append(undoObj)
for i in self.redo: i.destroy()
self.redo = []
def Undo(self):
undoObj = self.undo.pop()
undoObj.undo()
self.redo.append(undoObj)
g.frame.modified = True
g.frame.SetStatusText('Undone')
def Redo(self):
undoObj = self.redo.pop()
undoObj.redo()
self.undo.append(undoObj)
g.frame.modified = True
g.frame.SetStatusText('Redone')
def Clear(self):
for i in self.undo: i.destroy()
self.undo = []
for i in self.redo: i.destroy()
self.redo = []
def CanUndo(self):
return not not self.undo
def CanRedo(self):
return not not self.redo
class UndoCutDelete:
def __init__(self, itemIndex, parent, elem):
self.itemIndex = itemIndex
self.parent = parent
self.elem = elem
def destroy(self):
if self.elem: self.elem.unlink()
def undo(self):
item = g.tree.InsertNode(g.tree.ItemAtFullIndex(self.itemIndex[:-1]),
self.parent, self.elem,
g.tree.ItemAtFullIndex(self.itemIndex))
# Scroll to show new item (!!! redundant?)
g.tree.EnsureVisible(item)
g.tree.SelectItem(item)
self.elem = None
# Update testWin if needed
if g.testWin and g.tree.IsHighlatable(item):
if g.conf.autoRefresh:
g.tree.needUpdate = True
g.tree.pendingHighLight = item
else:
g.tree.pendingHighLight = None
def redo(self):
item = g.tree.ItemAtFullIndex(self.itemIndex)
# Delete testWin?
if g.testWin:
# If deleting top-level item, delete testWin
if item == g.testWin.item:
g.testWin.Destroy()
g.testWin = None
else:
# Remove highlight, update testWin
if g.testWin.highLight:
g.testWin.highLight.Remove()
g.tree.needUpdate = True
self.elem = g.tree.RemoveLeaf(item)
g.tree.Unselect()
g.panel.Clear()
class UndoPasteCreate:
def __init__(self, itemParent, parent, item, selected):
self.itemParentIndex = g.tree.ItemFullIndex(itemParent)
self.parent = parent
self.itemIndex = g.tree.ItemFullIndex(item) # pasted item
self.selectedIndex = g.tree.ItemFullIndex(selected) # maybe different from item
self.elem = None
def destroy(self):
if self.elem: self.elem.unlink()
def undo(self):
self.elem = g.tree.RemoveLeaf(g.tree.ItemAtFullIndex(self.itemIndex))
# Restore old selection
selected = g.tree.ItemAtFullIndex(self.selectedIndex)
g.tree.EnsureVisible(selected)
g.tree.SelectItem(selected)
# 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()
g.tree.needUpdate = True
def redo(self):
item = g.tree.InsertNode(g.tree.ItemAtFullIndex(self.itemParentIndex),
self.parent, self.elem,
g.tree.ItemAtFullIndex(self.itemIndex))
# Scroll to show new item
g.tree.EnsureVisible(item)
g.tree.SelectItem(item)
self.elem = None
# Update testWin if needed
if g.testWin and g.tree.IsHighlatable(item):
if g.conf.autoRefresh:
g.tree.needUpdate = True
g.tree.pendingHighLight = item
else:
g.tree.pendingHighLight = None
class UndoEdit:
def __init__(self):
self.pages = map(ParamPage.GetState, g.panel.pages)
self.selectedIndex = g.tree.ItemFullIndex(g.tree.GetSelection())
def destroy(self):
pass
# Update test view
def update(self, selected):
g.tree.Apply(g.tree.GetPyData(selected), selected)
# Update view
if g.testWin:
if g.testWin.highLight:
g.testWin.highLight.Remove()
g.tree.pendingHighLight = selected
if g.testWin:
g.tree.needUpdate = True
def undo(self):
# Restore selection
selected = g.tree.ItemAtFullIndex(self.selectedIndex)
if selected != g.tree.GetSelection():
g.tree.SelectItem(selected)
# Save current state for redo
map(ParamPage.SaveState, g.panel.pages)
pages = map(ParamPage.GetState, g.panel.pages)
map(ParamPage.SetState, g.panel.pages, self.pages)
self.pages = pages
self.update(selected)
def redo(self):
self.undo()
self.update(g.tree.GetSelection())

File diff suppressed because it is too large Load Diff

View File

@@ -23,13 +23,14 @@
<object class="wxButton" name="BUTTON_UP">
<label>Move Up</label>
</object>
<flag>wxBOTTOM</flag>
<flag>wxBOTTOM|wxEXPAND</flag>
<border>5</border>
</object>
<object class="sizeritem">
<object class="wxButton" name="BUTTON_DOWN">
<label>Move Down</label>
</object>
<flag>wxEXPAND</flag>
</object>
<object class="spacer">
<size>10,20</size>
@@ -39,13 +40,14 @@
<object class="wxButton" name="BUTTON_APPEND">
<label>Append...</label>
</object>
<flag>wxBOTTOM</flag>
<flag>wxBOTTOM|wxEXPAND</flag>
<border>5</border>
</object>
<object class="sizeritem">
<object class="wxButton" name="BUTTON_REMOVE">
<label>Remove</label>
</object>
<flag>wxEXPAND</flag>
</object>
</object>
<flag>wxALL|wxEXPAND</flag>
@@ -80,7 +82,7 @@
<border>10</border>
</object>
</object>
<style>wxRESIZE_BORDER</style>
<style>wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</style>
</object>
<object class="wxDialog" name="DIALOG_CONTENT_CHECK_LIST">
<title>Content</title>
@@ -105,13 +107,14 @@
<object class="wxButton" name="BUTTON_UP">
<label>Move Up</label>
</object>
<flag>wxBOTTOM</flag>
<flag>wxBOTTOM|wxEXPAND</flag>
<border>5</border>
</object>
<object class="sizeritem">
<object class="wxButton" name="BUTTON_DOWN">
<label>Move Down</label>
</object>
<flag>wxEXPAND</flag>
</object>
<object class="spacer">
<size>10,20</size>
@@ -121,13 +124,14 @@
<object class="wxButton" name="BUTTON_APPEND">
<label>Append...</label>
</object>
<flag>wxBOTTOM</flag>
<flag>wxBOTTOM|wxEXPAND</flag>
<border>5</border>
</object>
<object class="sizeritem">
<object class="wxButton" name="BUTTON_REMOVE">
<label>Remove</label>
</object>
<flag>wxEXPAND</flag>
</object>
</object>
<flag>wxALL|wxEXPAND</flag>
@@ -162,7 +166,7 @@
<border>10</border>
</object>
</object>
<style>wxRESIZE_BORDER</style>
<style>wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</style>
</object>
<object class="wxDialog" name="DIALOG_INTLIST">
<title>Numbers</title>
@@ -230,6 +234,89 @@
<border>10</border>
</object>
</object>
<style>wxRESIZE_BORDER</style>
<style>wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</style>
</object>
<object class="wxPanel" name="PANEL_BITMAP">
<object class="wxStaticBoxSizer">
<label></label>
<orient>wxVERTICAL</orient>
<object class="sizeritem">
<object class="wxFlexGridSizer">
<cols>2</cols>
<rows>2</rows>
<object class="sizeritem">
<object class="wxRadioButton" name="RADIO_STD">
<label>art:</label>
</object>
</object>
<object class="sizeritem">
<object class="wxComboBox" name="COMBO_STD">
<content>
<item>wxART_ADD_BOOKMARK</item>
<item>wxART_DEL_BOOKMARK</item>
<item>wxART_HELP_SIDE_PANEL</item>
<item>wxART_HELP_SETTINGS</item>
<item>wxART_HELP_BOOK</item>
<item>wxART_HELP_FOLDER</item>
<item>wxART_HELP_PAGE</item>
<item>wxART_GO_BACK</item>
<item>wxART_GO_FORWARD</item>
<item>wxART_GO_UP</item>
<item>wxART_GO_DOWN</item>
<item>wxART_GO_TO_PARENT</item>
<item>wxART_GO_HOME</item>
<item>wxART_FILE_OPEN</item>
<item>wxART_PRINT</item>
<item>wxART_HELP</item>
<item>wxART_TIP</item>
<item>wxART_REPORT_VIEW</item>
<item>wxART_LIST_VIEW</item>
<item>wxART_NEW_DIR</item>
<item>wxART_FOLDER</item>
<item>wxART_GO_DIR_UP</item>
<item>wxART_EXECUTABLE_FILE</item>
<item>wxART_NORMAL_FILE</item>
<item>wxART_TICK_MARK</item>
<item>wxART_CROSS_MARK</item>
<item>wxART_ERROR</item>
<item>wxART_QUESTION</item>
<item>wxART_WARNING</item>
<item>wxART_INFORMATION</item>
<item>wxART_MISSING_IMAGE</item>
</content>
</object>
<flag>wxRIGHT|wxEXPAND</flag>
<border>5</border>
</object>
<object class="sizeritem">
<object class="wxRadioButton" name="RADIO_FILE">
<label>file:</label>
</object>
</object>
<object class="sizeritem">
<object class="wxBoxSizer">
<orient>wxHORIZONTAL</orient>
<object class="sizeritem">
<object class="wxTextCtrl" name="TEXT_FILE"/>
<option>1</option>
<flag>wxRIGHT|wxEXPAND</flag>
<border>5</border>
</object>
<object class="sizeritem">
<object class="wxButton" name="BUTTON_BROWSE">
<label>Browse...</label>
<size>30,-1d</size>
</object>
</object>
</object>
<flag>wxRIGHT|wxEXPAND</flag>
<border>5</border>
</object>
<vgap>2</vgap>
<growablecols>1</growablecols>
</object>
<flag>wxEXPAND</flag>
</object>
</object>
</object>
</resource>

View File

@@ -4,13 +4,14 @@
# Created: 22.08.2001
# RCS-ID: $Id$
from wxPython.wx import *
from wxPython.xrc import *
from xml.dom import minidom
import wxPython.lib.wxpTag
from globals import *
from params import *
currentEncoding = wxLocale_GetSystemEncodingName()
if not currentEncoding:
currentEncoding = 'ascii'
# Base class for interface parameter classes
class xxxNode:
def __init__(self, node):
@@ -26,17 +27,24 @@ class xxxParam(xxxNode):
xxxNode.__init__(self, node)
if not node.hasChildNodes():
# If does not have child nodes, create empty text node
text = tree.dom.createTextNode('')
text = g.tree.dom.createTextNode('')
node.appendChild(text)
else:
text = node.childNodes[0] # first child must be text node
assert text.nodeType == minidom.Node.TEXT_NODE
# Use convertion from unicode to current encoding
self.textNode = text
# Value returns string
def value(self):
return self.textNode.data
def update(self, value):
self.textNode.data = value
if wxUSE_UNICODE: # no conversion is needed
def value(self):
return self.textNode.data
def update(self, value):
self.textNode.data = value
else:
def value(self):
return self.textNode.data.encode(currentEncoding)
def update(self, value):
self.textNode.data = unicode(value, currentEncoding)
# Integer parameter
class xxxParamInt(xxxParam):
@@ -63,7 +71,7 @@ class xxxParamContent(xxxNode):
assert n.tagName == 'item', 'bad content content'
if not n.hasChildNodes():
# If does not have child nodes, create empty text node
text = tree.dom.createTextNode('')
text = g.tree.dom.createTextNode('')
node.appendChild(text)
else:
# !!! normalize?
@@ -85,8 +93,8 @@ class xxxParamContent(xxxNode):
self.node.removeChild(n)
l = []
for str in value:
itemElem = tree.dom.createElement('item')
itemText = tree.dom.createTextNode(str)
itemElem = g.tree.dom.createElement('item')
itemText = g.tree.dom.createTextNode(str)
itemElem.appendChild(itemText)
self.node.appendChild(itemElem)
l.append(itemText)
@@ -106,9 +114,10 @@ class xxxParamContentCheckList(xxxNode):
if n.nodeType == minidom.Node.ELEMENT_NODE:
assert n.tagName == 'item', 'bad content content'
checked = n.getAttribute('checked')
if not checked: checked = 0
if not n.hasChildNodes():
# If does not have child nodes, create empty text node
text = tree.dom.createTextNode('')
text = g.tree.dom.createTextNode('')
node.appendChild(text)
else:
# !!! normalize?
@@ -129,10 +138,11 @@ class xxxParamContentCheckList(xxxNode):
for n in childNodes:
self.node.removeChild(n)
l = []
for (s,ch) in value:
itemElem = tree.dom.createElement('item')
itemElem.setAttribute('checked', str(ch))
itemText = tree.dom.createTextNode(s)
for s,ch in value:
itemElem = g.tree.dom.createElement('item')
# Add checked only if True
if ch: itemElem.setAttribute('checked', '1')
itemText = g.tree.dom.createTextNode(s)
itemElem.appendChild(itemText)
self.node.appendChild(itemElem)
l.append((itemText, itemElem))
@@ -143,20 +153,37 @@ class xxxParamContentCheckList(xxxNode):
self.l[i][1].setAttribute('checked', str(value[i][1]))
self.data = value
# Bitmap parameter
class xxxParamBitmap(xxxParam):
def __init__(self, node):
xxxParam.__init__(self, node)
self.stock_id = node.getAttribute('stock_id')
def value(self):
return [self.stock_id, xxxParam.value(self)]
def update(self, value):
self.stock_id = value[0]
if self.stock_id:
self.node.setAttribute('stock_id', self.stock_id)
else:
self.node.removeAttribute('stock_id')
xxxParam.update(self, value[1])
################################################################################
# Classes to interface DOM objects
class xxxObject:
# Default behavior
hasChildren = false # has children elements?
hasStyle = true # almost everyone
hasName = true # has name attribute?
isSizer = hasChild = false
hasChildren = False # has children elements?
hasStyle = True # almost everyone
hasName = True # has name attribute?
isSizer = hasChild = False
allParams = None # Some nodes have no parameters
# Style parameters (all optional)
styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'tooltip']
# Special parameters
specials = []
# Bitmap tags
bitmapTags = ['bitmap', 'bitmap2', 'icon']
# Required paremeters: none by default
required = []
# Default parameters with default values
@@ -184,7 +211,7 @@ class xxxObject:
tag = node.tagName
if tag == 'object':
continue # do nothing for object children here
if not tag in self.allParams and not tag in self.styles:
if 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:
@@ -196,12 +223,38 @@ class xxxObject:
self.params[tag] = xxxParamContent(node)
elif tag == 'font': # has children
self.params[tag] = xxxParamFont(element, node)
elif tag in self.bitmapTags:
# Can have attributes
self.params[tag] = xxxParamBitmap(node)
else: # simple parameter
self.params[tag] = xxxParam(node)
else:
# Remove all other nodes
element.removeChild(node)
node.unlink()
# Check that all required params are set
for param in self.required:
if not self.params.has_key(param):
# If default is specified, set it
if self.default.has_key(param):
elem = g.tree.dom.createElement(param)
self.params[param] = xxxParam(elem)
# Find place to put new element: first present element after param
found = False
paramStyles = self.allParams + self.styles
for p in paramStyles[paramStyles.index(param) + 1:]:
# Content params don't have same type
if self.params.has_key(p) and p != 'content':
found = True
break
if found:
nextTextElem = self.params[p].node
self.element.insertBefore(elem, nextTextElem)
else:
self.element.appendChild(elem)
else:
wxLogWarning('Required parameter %s of %s missing' %
(param, self.className))
# Returns real tree object
def treeObject(self):
if self.hasChild: return self.child
@@ -244,8 +297,8 @@ class xxxParamFont(xxxObject, xxxNode):
v = []
for param in self.allParams:
if value[i]:
fontElem = tree.dom.createElement(param)
textNode = tree.dom.createTextNode(value[i])
fontElem = g.tree.dom.createElement(param)
textNode = g.tree.dom.createTextNode(value[i])
self.params[param] = textNode
fontElem.appendChild(textNode)
elem.appendChild(fontElem)
@@ -258,11 +311,27 @@ class xxxParamFont(xxxObject, xxxNode):
################################################################################
class xxxContainer(xxxObject):
hasChildren = true
hasChildren = True
# Simulate normal parameter for encoding
class xxxEncoding:
def __init__(self, val):
self.encd = val
def value(self):
return self.encd
def update(self, val):
self.encd = val
# Special class for root node
class xxxMainNode(xxxContainer):
hasStyle = hasName = false
allParams = ['encoding']
required = ['encoding']
default = {'encoding': ''}
hasStyle = hasName = False
def __init__(self, dom):
xxxContainer.__init__(self, None, dom.documentElement)
self.className = 'XML tree'
self.params['encoding'] = xxxEncoding(dom.encoding)
################################################################################
# Top-level windwows
@@ -275,12 +344,13 @@ class xxxPanel(xxxContainer):
exStyles = ['wxWS_EX_VALIDATE_RECURSIVELY']
class xxxDialog(xxxContainer):
allParams = ['title', 'pos', 'size', 'style']
allParams = ['title', 'centered', 'pos', 'size', 'style']
paramDict = {'centered': ParamBool}
required = ['title']
winStyles = ['wxDEFAULT_DIALOG_STYLE', 'wxSTAY_ON_TOP',
'wxDIALOG_MODAL', 'wxDIALOG_MODELESS',
'wxCAPTION', 'wxSYSTEM_MENU', 'wxRESIZE_BORDER', 'wxRESIZE_BOX',
'wxTHICK_FRAME',
'wxTHICK_FRAME',
'wxNO_3D', 'wxTAB_TRAVERSAL', 'wxCLIP_CHILDREN']
styles = ['fg', 'bg', 'font', 'enabled', 'focused', 'hidden', 'exstyle',
'tooltip']
@@ -291,7 +361,7 @@ class xxxFrame(xxxContainer):
paramDict = {'centered': ParamBool}
required = ['title']
winStyles = ['wxDEFAULT_FRAME_STYLE', 'wxDEFAULT_DIALOG_STYLE',
'wxSTAY_ON_TOP',
'wxSTAY_ON_TOP',
'wxCAPTION', 'wxSYSTEM_MENU', 'wxRESIZE_BORDER',
'wxRESIZE_BOX', 'wxMINIMIZE_BOX', 'wxMAXIMIZE_BOX',
'wxFRAME_FLOAT_ON_PARENT', 'wxFRAME_TOOL_WINDOW',
@@ -302,13 +372,14 @@ class xxxFrame(xxxContainer):
class xxxTool(xxxObject):
allParams = ['bitmap', 'bitmap2', 'toggle', 'tooltip', 'longhelp']
paramDict = {'bitmap2': ParamFile}
hasStyle = false
required = ['bitmap']
paramDict = {'bitmap2': ParamBitmap, 'toggle': ParamBool}
hasStyle = False
class xxxToolBar(xxxContainer):
allParams = ['bitmapsize', 'margins', 'packing', 'separation',
allParams = ['bitmapsize', 'margins', 'packing', 'separation',
'pos', 'size', 'style']
hasStyle = false
hasStyle = False
paramDict = {'bitmapsize': ParamPosSize, 'margins': ParamPosSize,
'packing': ParamInt, 'separation': ParamInt,
'style': ParamNonGenericStyle}
@@ -321,6 +392,7 @@ class xxxBitmap(xxxObject):
allParams = ['bitmap']
required = ['bitmap']
# Just like bitmap
class xxxIcon(xxxObject):
allParams = ['icon']
required = ['icon']
@@ -331,6 +403,7 @@ class xxxIcon(xxxObject):
class xxxStaticText(xxxObject):
allParams = ['label', 'pos', 'size', 'style']
required = ['label']
default = {'label': ''}
winStyles = ['wxALIGN_LEFT', 'wxALIGN_RIGHT', 'wxALIGN_CENTRE', 'wxST_NO_AUTORESIZE']
class xxxStaticLine(xxxObject):
@@ -392,7 +465,7 @@ class xxxHtmlWindow(xxxObject):
paramDict = {'borders': ParamInt}
winStyles = ['wxHW_SCROLLBAR_NEVER', 'wxHW_SCROLLBAR_AUTO']
class xxxCalendar(xxxObject):
class xxxCalendarCtrl(xxxObject):
allParams = ['pos', 'size', 'style']
class xxxNotebook(xxxContainer):
@@ -400,6 +473,12 @@ class xxxNotebook(xxxContainer):
paramDict = {'usenotebooksizer': ParamBool}
winStyles = ['wxNB_FIXEDWIDTH', 'wxNB_LEFT', 'wxNB_RIGHT', 'wxNB_BOTTOM']
class xxxGenericDirCtrl(xxxObject):
allParams = ['defaultfolder', 'filter', 'defaultfilter', 'pos', 'size', 'style']
paramDict = {'defaultfilter': ParamInt}
winStyles = ['wxDIRCTRL_DIR_ONLY', 'wxDIRCTRL_3D_INTERNAL', 'wxDIRCTRL_SELECT_FIRST',
'wxDIRCTRL_SHOW_FILTERS', 'wxDIRCTRL_EDIT_LABELS']
################################################################################
# Buttons
@@ -423,7 +502,13 @@ class xxxRadioButton(xxxObject):
winStyles = ['wxRB_GROUP']
class xxxSpinButton(xxxObject):
allParams = ['pos', 'size', 'style']
allParams = ['value', 'min', 'max', 'pos', 'size', 'style']
paramDict = {'value': ParamInt}
winStyles = ['wxSP_HORIZONTAL', 'wxSP_VERTICAL', 'wxSP_ARROW_KEYS', 'wxSP_WRAP']
class xxxSpinCtrl(xxxObject):
allParams = ['value', 'min', 'max', 'pos', 'size', 'style']
paramDict = {'value': ParamInt}
winStyles = ['wxSP_HORIZONTAL', 'wxSP_VERTICAL', 'wxSP_ARROW_KEYS', 'wxSP_WRAP']
################################################################################
@@ -440,7 +525,8 @@ class xxxRadioBox(xxxObject):
winStyles = ['wxRA_SPECIFY_ROWS', 'wxRA_SPECIFY_COLS']
class xxxCheckBox(xxxObject):
allParams = ['label', 'pos', 'size', 'style']
allParams = ['label', 'checked', 'pos', 'size', 'style']
paramDict = {'checked': ParamBool}
required = ['label']
class xxxComboBox(xxxObject):
@@ -462,14 +548,14 @@ class xxxCheckList(xxxObject):
'wxLC_USER_TEXT', 'wxLC_EDIT_LABELS', 'wxLC_NO_HEADER',
'wxLC_SINGLE_SEL', 'wxLC_SORT_ASCENDING', 'wxLC_SORT_DESCENDING']
paramDict = {'content': ParamContentCheckList}
################################################################################
# Sizers
class xxxSizer(xxxContainer):
hasName = hasStyle = false
hasName = hasStyle = False
paramDict = {'orient': ParamOrient}
isSizer = true
isSizer = True
class xxxBoxSizer(xxxSizer):
allParams = ['orient']
@@ -483,7 +569,6 @@ class xxxBoxSizer(xxxSizer):
class xxxStaticBoxSizer(xxxBoxSizer):
allParams = ['label', 'orient']
required = ['label', 'orient']
default = {'orient': 'wxVERTICAL'}
class xxxGridSizer(xxxSizer):
allParams = ['cols', 'rows', 'vgap', 'hgap']
@@ -492,7 +577,8 @@ class xxxGridSizer(xxxSizer):
# For repeated parameters
class xxxParamMulti:
def __init__(self):
def __init__(self, node):
self.node = node
self.l, self.data = [], []
def append(self, param):
self.l.append(param)
@@ -511,16 +597,17 @@ class xxxFlexGridSizer(xxxGridSizer):
# Special processing for growable* parameters
# (they are represented by several nodes)
def special(self, tag, node):
if tag not in self.params:
self.params[tag] = xxxParamMulti()
if not self.params.has_key(tag):
# Create new multi-group
self.params[tag] = xxxParamMulti(node)
self.params[tag].append(xxxParamInt(node))
def setSpecial(self, param, value):
# Straightforward implementation: remove, add again
self.params[param].remove()
del self.params[param]
for i in value:
node = tree.dom.createElement(param)
text = tree.dom.createTextNode(str(i))
node = g.tree.dom.createElement(param)
text = g.tree.dom.createTextNode(str(i))
node.appendChild(text)
self.element.appendChild(node)
self.special(param, node)
@@ -528,8 +615,8 @@ class xxxFlexGridSizer(xxxGridSizer):
# Container with only one child.
# Not shown in tree.
class xxxChildContainer(xxxObject):
hasName = hasStyle = false
hasChild = true
hasName = hasStyle = False
hasChild = True
def __init__(self, parent, element):
xxxObject.__init__(self, parent, element)
# Must have one child with 'object' tag, but we don't check it
@@ -550,8 +637,8 @@ class xxxChildContainer(xxxObject):
assert 0, 'no child found'
class xxxSizerItem(xxxChildContainer):
allParams = ['option', 'flag', 'border']
paramDict = {'option': ParamInt}
allParams = ['option', 'flag', 'border', 'minsize']
paramDict = {'option': ParamInt, 'minsize': ParamPosSize}
def __init__(self, parent, element):
xxxChildContainer.__init__(self, parent, element)
# Remove pos parameter - not needed for sizeritems
@@ -574,26 +661,37 @@ class xxxNotebookPage(xxxChildContainer):
self.child.allParams.remove('size')
class xxxSpacer(xxxObject):
hasName = hasStyle = false
hasName = hasStyle = False
allParams = ['size', 'option', 'flag', 'border']
paramDict = {'option': ParamInt}
default = {'size': '0,0'}
class xxxMenuBar(xxxContainer):
allParams = []
allParams = ['style']
paramDict = {'style': ParamNonGenericStyle} # no generic styles
winStyles = ['wxMB_DOCKABLE']
class xxxMenu(xxxContainer):
allParams = ['label']
allParams = ['label', 'help', 'style']
default = {'label': ''}
paramDict = {'style': ParamNonGenericStyle} # no generic styles
winStyles = ['wxMENU_TEAROFF']
class xxxMenuItem(xxxObject):
allParams = ['checkable', 'label', 'accel', 'help']
allParams = ['label', 'bitmap', 'accel', 'help',
'checkable', 'radio', 'enabled', 'checked']
default = {'label': ''}
hasStyle = False
class xxxSeparator(xxxObject):
hasName = hasStyle = false
hasName = hasStyle = False
################################################################################
# Unknown control
class xxxUnknown(xxxObject):
allParams = ['pos', 'size', 'style']
paramDict = {'style': ParamNonGenericStyle} # no generic styles
################################################################################
@@ -603,7 +701,7 @@ xxxDict = {
'wxFrame': xxxFrame,
'tool': xxxTool,
'wxToolBar': xxxToolBar,
'wxBitmap': xxxBitmap,
'wxIcon': xxxIcon,
@@ -632,8 +730,10 @@ xxxDict = {
'wxNotebook': xxxNotebook,
'notebookpage': xxxNotebookPage,
'wxHtmlWindow': xxxHtmlWindow,
'wxCalendar': xxxCalendar,
'wxCalendarCtrl': xxxCalendarCtrl,
'wxGenericDirCtrl': xxxGenericDirCtrl,
'wxSpinCtrl': xxxSpinCtrl,
'wxBoxSizer': xxxBoxSizer,
'wxStaticBoxSizer': xxxStaticBoxSizer,
'wxGridSizer': xxxGridSizer,
@@ -645,12 +745,14 @@ xxxDict = {
'wxMenu': xxxMenu,
'wxMenuItem': xxxMenuItem,
'separator': xxxSeparator,
'unknown': xxxUnknown,
}
# Create IDs for all parameters of all classes
paramIDs = {'fg': wxNewId(), 'bg': wxNewId(), 'exstyle': wxNewId(), 'font': wxNewId(),
'enabled': wxNewId(), 'focused': wxNewId(), 'hidden': wxNewId(),
'tooltip': wxNewId()
'tooltip': wxNewId(), 'encoding': wxNewId()
}
for cl in xxxDict.values():
if cl.allParams:
@@ -668,27 +770,27 @@ def IsObject(node):
# Make XXX object from some DOM object, selecting correct class
def MakeXXXFromDOM(parent, element):
try:
return xxxDict[element.getAttribute('class')](parent, element)
klass = xxxDict[element.getAttribute('class')]
except KeyError:
# Verify that it's not recursive exception
if element.getAttribute('class') not in xxxDict:
print 'ERROR: unknown class:', element.getAttribute('class')
print 'ERROR: unknown class:', element.getAttribute('class')
raise
return klass(parent, element)
# Make empty DOM element
def MakeEmptyDOM(className):
elem = tree.dom.createElement('object')
def MakeEmptyDOM(className):
elem = g.tree.dom.createElement('object')
elem.setAttribute('class', className)
# Set required and default parameters
xxxClass = xxxDict[className]
defaultNotRequired = filter(lambda x, l=xxxClass.required: x not in l,
xxxClass.default.keys())
for param in xxxClass.required + defaultNotRequired:
textElem = tree.dom.createElement(param)
textElem = g.tree.dom.createElement(param)
try:
textNode = tree.dom.createTextNode(xxxClass.default[param])
textNode = g.tree.dom.createTextNode(xxxClass.default[param])
except KeyError:
textNode = tree.dom.createTextNode('')
textNode = g.tree.dom.createTextNode('')
textElem.appendChild(textNode)
elem.appendChild(textElem)
return elem

View File

@@ -0,0 +1,256 @@
#----------------------------------------------------------------------------
# Name: dbg.py
# RCS-ID: $Id$
# Author: Will Sadkin
# Email: wsadkin@nameconnector.com
# Created: 07/11/2002
# Copyright: (c) 2002 by Will Sadkin, 2002
# License: wxWindows license
#----------------------------------------------------------------------------
"""
This module provides a useful debugging framework that supports
showing nesting of function calls and allows a program to contain
lots of debugging print statements that can easily be turned on
or off to debug the code. It also supports the ability to
have each function indent the debugging statements contained
within it, including those of any other function called within
its scope, thus allowing you to see in what order functions are
being called, and from where.
This capability is particularly useful in wxPython applications,
where exactly events occur that cause functions to be called is
not entirely clear, and because wxPython programs can't be run
from inside other debugging environments that have their own
message loops.
This module defines a Logger class, responsible for managing
debugging output. Each Logger instance can be given a name
at construction; if this is done, '<name>:' will precede each
logging output made by that Logger instance.
The log() function this class provides takes a set of positional
arguments that are printed in order if debugging is enabled
(just like print does), followed by a set of keyword arguments
that control the behavior of the log() function itself on subsequent
calls. The current keyword arguments are:
indent
When set to a value of 1, this increments the current
indentation level, causing all subsequent dbg() outputs to be
indented by 3 more spaces. When set to a value of 0,
this process is reversed, causing the indent to decrease by
3 spaces. The default indentation level is 0.
enable
When set to a value of 1, this turns on dbg() output for
for program importing this module, until told to do otherwise.
When set to a value of 0, dbg output is turned off. (dbg
output is off by default.)
suspend
When set to a value of 1, this increments the current
"suspension" level. This makes it possible for a function
to temporarily suspend its and any of its dependents'
potential outputs that use the same Logger instance.
When set to a value of 0, the suspension level is
decremented. When the value goes back to 0, potential
logging is resumed (actual output depends on the
"enable" status of the Logger instance in question.)
wxlog
When set to a value of 1, the output will be sent to the
active wxLog target.
stream
When set to a non-None value, the current output stream
(default of sys.stdout) is pushed onto a stack of streams,
and is replaced in the dbg system with the specified stream.
When called with a value of None, the previous stream will
be restored (if stacked.) If set to None without previously
changing it will result in no action being taken.
You can also call the log function implicitly on the Logger
instance, ie. you can type:
from wxPython.tools.dbg import Logger
dbg = Logger()
dbg('something to print')
Using this fairly simple mechanism, it is possible to get fairly
useful debugging output in a program. Consider the following
code example:
>>> d = {1:'a', 2:'dictionary', 3:'of', 4:'words'}
>>> dbg = dbg.Logger('module')
>>> dbg(enable=1)
module: dbg enabled
>>> def foo(d):
... dbg('foo', indent=1)
... bar(d)
... dbg('end of foo', indent=0)
...
>>> def bar(d):
... dbg('bar', indent=1)
... dbg('contents of d:', indent=1)
... l = d.items()
... l.sort()
... for key, value in l:
... dbg('%d =' % key, value)
... dbg(indent=0)
... dbg('end of bar', indent=0)
...
>>> foo(d)
module: foo
module: bar
module: contents of d:
module: 1 = a
module: 2 = dictionary
module: 3 = of
module: 4 = words
module: end of bar
module: end of foo
>>>
"""
class Logger:
def __init__(self, name=None):
import sys
self.name = name
self._indent = 0 # current number of indentations
self._dbg = 0 # enable/disable flag
self._suspend = 0 # allows code to "suspend/resume" potential dbg output
self._wxLog = 0 # use wxLogMessage for debug output
self._outstream = sys.stdout # default output stream
self._outstream_stack = [] # for restoration of streams as necessary
def IsEnabled():
return self._dbg
def IsSuspended():
return _suspend
def log(self, *args, **kwargs):
"""
This function provides a useful framework for generating
optional debugging output that can be displayed at an
arbitrary level of indentation.
"""
if not self._dbg and not 'enable' in kwargs.keys():
return
if self._dbg and len(args) and not self._suspend:
# (emulate print functionality)
strs = [str(arg) for arg in args]
output = ' '.join(strs)
if self.name: output = self.name+': ' + output
output = ' ' * 3 * self._indent + output
if self._wxLog:
from wxPython.wx import wxLogMessage # (if not already imported)
wxLogMessage(output)
else:
self._outstream.write(output + '\n')
self._outstream.flush()
# else do nothing
# post process args:
for kwarg, value in kwargs.items():
if kwarg == 'indent':
self.SetIndent(value)
elif kwarg == 'enable':
self.SetEnabled(value)
elif kwarg == 'suspend':
self.SetSuspend(value)
elif kwarg == 'wxlog':
self.SetWxLog(value)
elif kwarg == 'stream':
self.SetStream(value)
# aliases for the log function
dbg = log # backwards compatible
msg = log #
__call__ = log # this one lets you 'call' the instance directly
def SetEnabled(self, value):
if value:
old_dbg = self._dbg
self._dbg = 1
if not old_dbg:
self.dbg('dbg enabled')
else:
if self._dbg:
self.dbg('dbg disabled')
self._dbg = 0
def SetSuspend(self, value):
if value:
self._suspend += 1
elif self._suspend > 0:
self._suspend -= 1
def SetIndent(self, value):
if value:
self._indent += 1
elif self._indent > 0:
self._indent -= 1
def SetWxLog(self, value):
self._wxLog = value
def SetStream(self, value):
if value:
self._outstream_stack.append( self._outstream )
self._outstream = value
elif value is None and len(self._outstream_stack) > 0:
self._outstream = self._outstream_stack.pop(-1)
#------------------------------------------------------------
if __name__ == "__main__":
from wxPython.wx import *
wxLog_SetActiveTarget( wxLogStderr() )
logger = Logger('module')
dbg = logger.dbg
dbg(enable=1)
logger('test __call__ interface')
dbg('testing wxLog output to stderr:', wxlog=1, indent=1)
dbg('1,2,3...')
dbg('testing wxLogNull:')
devnull = wxLogNull()
dbg('4,5,6...') # shouldn't print, according to doc...
del devnull
dbg('(resuming to wxLogStdErr)', '7,8,9...', indent=0)
dbg('disabling wxLog output, switching to stderr:')
dbg(wxlog=0, stream=sys.stderr)
dbg(logger._outstream, 'switching back to stdout:')
dbg(stream=None)
dbg(logger._outstream )
def foo(str):
dbg('foo:', indent=1)
dbg(str, indent=0)
foo('testing dbg inside function')
class bar(Logger):
def __init__(self, name):
Logger.__init__(self, name)
def enable(self, value):
self.dbg(enable=value)
def foo(self, str):
self.dbg('foo:', indent=1)
self.dbg(str, indent=0)
f = bar('class mixin')
f.foo("shouldn't print")
f.enable(1)
f.foo("should print")
dbg('test completed.', enable=0)
dbg('(double-checking ;-)')

View File

@@ -0,0 +1,80 @@
#----------------------------------------------------------------------
# Name: wxPython.tools.helpviewer
# Purpose: HTML Help viewer
#
# Author: Robin Dunn
#
# Created: 11-Dec-2002
# RCS-ID: $Id$
# Copyright: (c) 2002 by Total Control Software
# Licence: wxWindows license
#----------------------------------------------------------------------
"""
helpviewer.py -- Displays HTML Help in a wxHtmlHelpController window.
Usage:
helpviewer [--cache=path] helpfile [helpfile(s)...]
Where helpfile is the path to either a .hhp file or a .zip file
which contians a .hhp file. The .hhp files are the same as those
used by Microsoft's HTML Help Workshop for creating CHM files.
"""
import sys, os
#---------------------------------------------------------------------------
def main(args=sys.argv):
if len(args) < 2:
print __doc__
return
args = args[1:]
cachedir = None
if args[0][:7] == '--cache':
cachedir = os.path.expanduser(args[0].split('=')[1])
args = args[1:]
if len(args) == 0:
print __doc__
return
from wxPython.wx import wxPySimpleApp, wxConfigBase_Get, \
wxLog_SetActiveTarget, wxLogStderr, \
wxLog_SetLogLevel, wxLOG_Error, \
wxFileSystem_AddHandler, wxZipFSHandler
import wxPython.html
from wxPython.htmlhelp import wxHtmlHelpController
app = wxPySimpleApp()
#wxLog_SetActiveTarget(wxLogStderr())
wxLog_SetLogLevel(wxLOG_Error)
# Set up the default config so the htmlhelp frame can save its preferences
app.SetVendorName('wxWindows')
app.SetAppName('helpviewer')
cfg = wxConfigBase_Get()
# Add the Zip filesystem
wxFileSystem_AddHandler(wxZipFSHandler())
# Create the viewer
helpctrl = wxHtmlHelpController()
if cachedir:
helpctrl.SetTempDir(cachedir)
# and add the books
for helpfile in args:
print "Adding %s..." % helpfile
helpctrl.AddBook(helpfile, 1)
# start it up!
helpctrl.DisplayContents()
app.MainLoop()
if __name__ == '__main__':
main()

View File

@@ -1,7 +1,16 @@
"""
Common routines for the image converter utilities.
"""
import sys, os, glob, getopt, string
#----------------------------------------------------------------------
# Name: wxPython.tools.img2img
# Purpose: Common routines for the image converter utilities.
#
# Author: Robin Dunn
#
# RCS-ID: $Id$
# Copyright: (c) 2002 by Total Control Software
# Licence: wxWindows license
#----------------------------------------------------------------------
import sys, os, glob, getopt
from wxPython.wx import *
if wxPlatform == "__WXGTK__":
@@ -11,7 +20,7 @@ if wxPlatform == "__WXGTK__":
wxInitAllImageHandlers()
def convert(file, maskClr, outputDir, outputName, outType, outExt):
if string.lower(os.path.splitext(file)[1]) == ".ico":
if os.path.splitext(file)[1].lower() == ".ico":
icon = wxIcon(file, wxBITMAP_TYPE_ICO)
img = wxBitmapFromIcon(icon)
else:

View File

@@ -1,4 +1,14 @@
#!/usr/bin/env python
#----------------------------------------------------------------------
# Name: wxPython.tools.img2png
# Purpose: Convert an image to PNG format
#
# Author: Robin Dunn
#
# RCS-ID: $Id$
# Copyright: (c) 2002 by Total Control Software
# Licence: wxWindows license
#----------------------------------------------------------------------
"""
img2png.py -- convert several image formats to PNG format

View File

@@ -1,4 +1,15 @@
#!/usr/bin/env python
#----------------------------------------------------------------------
# Name: wxPython.tools.img2py
# Purpose: Convert an image to Python code.
#
# Author: Robin Dunn
#
# RCS-ID: $Id$
# Copyright: (c) 2002 by Total Control Software
# Licence: wxWindows license
#----------------------------------------------------------------------
"""
img2py.py -- Convert an image to PNG format and embed it in a Python
module with appropriate code so it can be loaded into
@@ -22,6 +33,12 @@ Options:
specify a name that should be used to customize the access
fucntions, (getNameBitmap, etc.)
-c Maintain a catalog of names that can be used to reference
images. Catalog can be accessed via catalog and index attributes
of the module. If the -n <name> option is specified then <name>
is used for the catalog key and index value, otherwise
the filename without any path or extension is used as the key.
-a This flag specifies that the python_file should be appended
to instead of overwritten. This in combination with -n will
allow you to put multiple images in one Python source file.
@@ -32,9 +49,14 @@ Options:
"""
#
# Changes:
# - Cliff Wells <LogiplexSoftware@earthlink.net>
# 20021206: Added catalog (-c) option.
#
import sys, os, glob, getopt, tempfile, string
import sys, os, glob, getopt, tempfile
import cPickle, cStringIO, zlib
import img2img
from wxPython import wx
@@ -98,9 +120,10 @@ def main(args):
maskClr = None
imgName = ""
icon = 0
catalog = 0
try:
opts, fileArgs = getopt.getopt(args, "auin:m:")
opts, fileArgs = getopt.getopt(args, "auicn:m:")
except getopt.GetoptError:
print __doc__
return
@@ -116,6 +139,8 @@ def main(args):
maskClr = val
elif opt == "-i":
icon = 1
elif opt == "-c":
catalog = 1
if len(fileArgs) != 2:
print __doc__
@@ -139,6 +164,33 @@ def main(args):
else:
out = open(python_file, "w")
if catalog:
pyPath, pyFile = os.path.split(python_file)
imgPath, imgFile = os.path.split(image_file)
if not imgName:
imgName = os.path.splitext(imgFile)[0]
print "\nWarning: -n not specified. Using filename (%s) for catalog entry." % imgName
old_index = []
if append:
# check to see if catalog exists already (file may have been created
# with an earlier version of img2py or without -c option)
oldSysPath = sys.path[:]
sys.path = [pyPath] # make sure we don't import something else by accident
mod = __import__(os.path.splitext(pyFile)[0])
if 'index' not in dir(mod):
print "\nWarning: %s was originally created without catalog." % python_file
print " Any images already in file will not be cataloged.\n"
out.write("\n# ***************** Catalog starts here *******************")
out.write("\n\ncatalog = {}\n")
out.write("index = []\n\n")
out.write("class ImageClass: pass\n\n")
else: # save a copy of the old index so we can warn about duplicate names
old_index[:] = mod.index[:]
del mod
sys.path = oldSysPath[:]
out.write("#" + "-" * 70 + "\n")
if not append:
out.write("# This file was generated by %s\n#\n" % sys.argv[0])
@@ -150,6 +202,11 @@ def main(args):
else:
out.write("import cStringIO\n\n\n")
if catalog:
out.write("catalog = {}\n")
out.write("index = []\n\n")
out.write("class ImageClass: pass\n\n")
if compressed:
out.write("def get%sData():\n"
" return zlib.decompress(\n%s)\n\n"
@@ -173,6 +230,19 @@ def main(args):
" return icon\n\n"
% tuple([imgName] * 2))
if catalog:
if imgName in old_index:
print "Warning: %s already in catalog." % imgName
print " Only the last entry will be accessible.\n"
old_index.append(imgName)
out.write("index.append('%s')\n" % imgName)
out.write("catalog['%s'] = ImageClass()\n" % imgName)
out.write("catalog['%s'].getData = get%sData\n" % tuple([imgName] * 2))
out.write("catalog['%s'].getImage = get%sImage\n" % tuple([imgName] * 2))
out.write("catalog['%s'].getBitmap = get%sBitmap\n" % tuple([imgName] * 2))
if icon:
out.write("catalog['%s'].getIcon = get%sIcon\n" % tuple([imgName] * 2))
out.write("\n\n")
if imgName:
n_msg = ' using "%s"' % imgName

View File

@@ -1,4 +1,14 @@
#!/usr/bin/env python
#----------------------------------------------------------------------
# Name: wxPython.tools.img2xpm
# Purpose: Convert an image to XPM format
#
# Author: Robin Dunn
#
# RCS-ID: $Id$
# Copyright: (c) 2002 by Total Control Software
# Licence: wxWindows license
#----------------------------------------------------------------------
"""
img2xpm.py -- convert several image formats to XPM