mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2025-12-15 17:20:07 +01:00
273 lines
10 KiB
Python
273 lines
10 KiB
Python
#---------------------------------------------------------------------------
|
|
# Name: etg/property.py
|
|
# Author: Robin Dunn
|
|
#
|
|
# Created: 23-Feb-2015
|
|
# Copyright: (c) 2015-2020 by Total Control Software
|
|
# License: wxWindows License
|
|
#---------------------------------------------------------------------------
|
|
|
|
import etgtools
|
|
import etgtools.tweaker_tools as tools
|
|
|
|
PACKAGE = "wx"
|
|
MODULE = "_propgrid"
|
|
NAME = "propgridproperty" # Base name of the file to generate to for this script
|
|
DOCSTRING = ""
|
|
|
|
# The classes and/or the basename of the Doxygen XML files to be processed by
|
|
# this script.
|
|
ITEMS = [ 'wxPGPaintData',
|
|
'wxPGCellRenderer',
|
|
'wxPGDefaultRenderer',
|
|
'wxPGCellData',
|
|
'wxPGCell',
|
|
'wxPGAttributeStorage',
|
|
|
|
'wxPGProperty',
|
|
'wxPropertyCategory',
|
|
'wxPGChoiceEntry',
|
|
'wxPGChoicesData',
|
|
'wxPGChoices',
|
|
]
|
|
|
|
#---------------------------------------------------------------------------
|
|
|
|
def run():
|
|
# Parse the XML file(s) building a collection of Extractor objects
|
|
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
|
etgtools.parseDoxyXML(module, ITEMS)
|
|
|
|
#-----------------------------------------------------------------
|
|
# Tweak the parsed meta objects in the module object as needed for
|
|
# customizing the generated code and docstrings.
|
|
|
|
c = module.find('wxPGCellData')
|
|
assert isinstance(c, etgtools.ClassDef)
|
|
c.find('~wxPGCellData').ignore(False)
|
|
c.bases = ['wxRefCounter']
|
|
|
|
|
|
#---------------------------------------------------------
|
|
c = module.find('wxPGCell')
|
|
tools.ignoreConstOverloads(c)
|
|
|
|
|
|
#---------------------------------------------------------
|
|
c = module.find('wxPGCellRenderer')
|
|
c.bases = ['wxRefCounter']
|
|
|
|
|
|
#---------------------------------------------------------
|
|
c = module.find('wxPGAttributeStorage')
|
|
c.find('const_iterator').ignore()
|
|
c.find('StartIteration').ignore()
|
|
c.find('GetNext').ignore()
|
|
|
|
|
|
#---------------------------------------------------------
|
|
c = module.find('wxPGProperty')
|
|
tools.ignoreConstOverloads(c)
|
|
|
|
# The ctors are protected, so unignore them
|
|
for ctor in c.find('wxPGProperty').all():
|
|
ctor.ignore(False)
|
|
|
|
c.find('StringToValue.variant').out = True
|
|
c.find('IntToValue.variant').out = True
|
|
|
|
c.find('HasFlag').findOverload('FlagType').ignore()
|
|
|
|
c.addProperty('m_value GetValue SetValue')
|
|
|
|
|
|
# SIP needs to be able to make a copy of the wxPGAttributeStorage value
|
|
# but the C++ class doesn't have a copy ctor and the default will cause it
|
|
# to lose references to the variants it contains, so let's just override
|
|
# the use of the MappedType and convert it to a Python dictionary here
|
|
# instead.
|
|
m = c.find('GetAttributes')
|
|
m.type = 'PyObject*'
|
|
m.setCppCode("""\
|
|
const wxPGAttributeStorage& attrs = self->GetAttributes();
|
|
wxPGAttributeStorage::const_iterator it = attrs.StartIteration();
|
|
wxVariant v;
|
|
wxPyThreadBlocker blocker;
|
|
|
|
PyObject* dict = PyDict_New();
|
|
if ( !dict ) return NULL;
|
|
|
|
while ( attrs.GetNext( it, v ) ) {
|
|
const wxString& name = v.GetName();
|
|
PyObject* pyStr = wx2PyString(name);
|
|
PyObject* pyVal = wxPGVariant_out_helper(v);
|
|
int res = PyDict_SetItem( dict, pyStr, pyVal );
|
|
}
|
|
return dict;
|
|
""")
|
|
|
|
# SetAttributes uses wxPGAttributeStorage too, but we'll just replace it
|
|
# with a simple Python method.
|
|
c.find('SetAttributes').ignore()
|
|
c.addPyMethod('SetAttributes', '(self, attributes)',
|
|
doc="Set the property's attributes from a Python dictionary.",
|
|
body="""\
|
|
for name,value in attributes.items():
|
|
self.SetAttribute(name, value)
|
|
""")
|
|
|
|
c.find('AddPrivateChild.prop').transfer = True
|
|
c.find('AddChild.prop').transfer = True
|
|
|
|
# The [G|S]etClientData methods deal with untyped void* values, which we
|
|
# don't support. The [G|S]etClientObject methods use wxClientData instances
|
|
# which we have a MappedType for, so make the ClientData methods just be
|
|
# aliases for ClientObjects. From the Python programmer's perspective they
|
|
# would be virtually the same anyway.
|
|
c.find('SetClientObject.clientObject').transfer = True
|
|
c.find('SetClientObject.clientObject').name = 'data'
|
|
c.find('GetClientData').ignore()
|
|
c.find('SetClientData').ignore()
|
|
c.find('GetClientObject').pyName = 'GetClientData'
|
|
c.find('SetClientObject').pyName = 'SetClientData'
|
|
c.addPyMethod('GetClientObject', '(self, n)',
|
|
doc="Alias for :meth:`GetClientData`",
|
|
body="return self.GetClientData(n)")
|
|
c.addPyMethod('SetClientObject', '(self, n, data)',
|
|
doc="Alias for :meth:`SetClientData`",
|
|
body="self.SetClientData(n, data)")
|
|
|
|
c.find('GetEditorDialog').factory = True
|
|
|
|
# deprecated and removed
|
|
c.find('AddChild').ignore()
|
|
c.find('GetValueString').ignore()
|
|
|
|
|
|
#---------------------------------------------------------
|
|
c = module.find('wxPGChoicesData')
|
|
tools.ignoreConstOverloads(c)
|
|
c.bases = ['wxRefCounter']
|
|
c.find('~wxPGChoicesData').ignore(False)
|
|
|
|
|
|
#---------------------------------------------------------
|
|
c = module.find('wxPGChoices')
|
|
c.find('wxPGChoices').findOverload('wxChar **').ignore()
|
|
c.find('wxPGChoices').findOverload('wxString *').ignore()
|
|
c.find('Add').findOverload('wxChar **').ignore()
|
|
c.find('Add').findOverload('wxString *').ignore()
|
|
c.find('Set').findOverload('wxChar **').ignore()
|
|
c.find('Set').findOverload('wxString *').ignore()
|
|
tools.ignoreConstOverloads(c)
|
|
c.find('operator[]').ignore()
|
|
c.find('GetId').type = 'wxIntPtr'
|
|
c.find('GetId').setCppCode_sip("""\
|
|
sipRes = new ::wxIntPtr((wxIntPtr)sipCpp->GetId());
|
|
""")
|
|
|
|
c.addPyMethod('__getitem__', '(self, index)',
|
|
doc="Returns a reference to a :class:PGChoiceEntry using Python list syntax.",
|
|
body="return self.Item(index)",
|
|
)
|
|
c.addPyMethod('__len__', '(self)',
|
|
doc="",
|
|
body="return self.GetCount()",
|
|
)
|
|
|
|
|
|
#---------------------------------------------------------
|
|
# Ignore some string constants (#defines) coming from dox, and add them
|
|
# back in Python code. They are wchar_t* values and this seemed the
|
|
# simplest way to deal with them.
|
|
for name in [ 'wxPG_ATTR_DEFAULT_VALUE',
|
|
'wxPG_ATTR_MIN',
|
|
'wxPG_ATTR_MAX',
|
|
'wxPG_ATTR_UNITS',
|
|
'wxPG_ATTR_HINT',
|
|
'wxPG_ATTR_AUTOCOMPLETE',
|
|
'wxPG_BOOL_USE_CHECKBOX',
|
|
'wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING',
|
|
'wxPG_FLOAT_PRECISION',
|
|
'wxPG_STRING_PASSWORD',
|
|
'wxPG_UINT_BASE',
|
|
'wxPG_UINT_PREFIX',
|
|
'wxPG_FILE_WILDCARD',
|
|
'wxPG_FILE_SHOW_FULL_PATH',
|
|
'wxPG_FILE_SHOW_RELATIVE_PATH',
|
|
'wxPG_FILE_INITIAL_PATH',
|
|
# 'wxPG_FILE_DIALOG_TITLE',
|
|
'wxPG_DIALOG_TITLE',
|
|
'wxPG_FILE_DIALOG_STYLE',
|
|
# 'wxPG_DIR_DIALOG_MESSAGE',
|
|
'wxPG_ARRAY_DELIMITER',
|
|
'wxPG_DATE_FORMAT',
|
|
'wxPG_DATE_PICKER_STYLE',
|
|
'wxPG_ATTR_SPINCTRL_STEP',
|
|
'wxPG_ATTR_SPINCTRL_WRAP',
|
|
'wxPG_ATTR_SPINCTRL_MOTION',
|
|
'wxPG_ATTR_MULTICHOICE_USERSTRINGMODE',
|
|
'wxPG_COLOUR_ALLOW_CUSTOM',
|
|
'wxPG_COLOUR_HAS_ALPHA',
|
|
|
|
# and some other #defines with similar issues
|
|
'wxNullProperty',
|
|
'wxPGChoicesEmptyData',
|
|
]:
|
|
module.find(name).ignore()
|
|
|
|
module.addPyCode("""\
|
|
PG_ATTR_DEFAULT_VALUE = u"DefaultValue"
|
|
PG_ATTR_MIN = u"Min"
|
|
PG_ATTR_MAX = u"Max"
|
|
PG_ATTR_UNITS = u"Units"
|
|
PG_ATTR_HINT = u"Hint"
|
|
PG_ATTR_INLINE_HELP = PG_ATTR_HINT
|
|
PG_ATTR_AUTOCOMPLETE = u"AutoComplete"
|
|
PG_BOOL_USE_CHECKBOX = u"UseCheckbox"
|
|
PG_BOOL_USE_DOUBLE_CLICK_CYCLING = u"UseDClickCycling"
|
|
PG_FLOAT_PRECISION = u"Precision"
|
|
PG_STRING_PASSWORD = u"Password"
|
|
PG_UINT_BASE = u"Base"
|
|
PG_UINT_PREFIX = u"Prefix"
|
|
PG_FILE_WILDCARD = u"Wildcard"
|
|
PG_FILE_SHOW_FULL_PATH = u"ShowFullPath"
|
|
PG_FILE_SHOW_RELATIVE_PATH = u"ShowRelativePath"
|
|
PG_FILE_INITIAL_PATH = u"InitialPath"
|
|
PG_FILE_DIALOG_TITLE = u"DialogTitle"
|
|
PG_DIALOG_TITLE = u"DialogTitle"
|
|
PG_FILE_DIALOG_STYLE = u"DialogStyle"
|
|
PG_DIR_DIALOG_MESSAGE = u"DialogMessage"
|
|
PG_ARRAY_DELIMITER = u"Delimiter"
|
|
PG_DATE_FORMAT = u"DateFormat"
|
|
PG_DATE_PICKER_STYLE = u"PickerStyle"
|
|
PG_ATTR_SPINCTRL_STEP = u"Step"
|
|
PG_ATTR_SPINCTRL_WRAP = u"Wrap"
|
|
PG_ATTR_SPINCTRL_MOTION = u"MotionSpin"
|
|
PG_ATTR_SPINCTRL_MOTIONSPIN = PG_ATTR_SPINCTRL_MOTION
|
|
PG_ATTR_MULTICHOICE_USERSTRINGMODE= u"UserStringMode"
|
|
PG_COLOUR_ALLOW_CUSTOM = u"AllowCustom"
|
|
PG_COLOUR_HAS_ALPHA = u"HasAlpha"
|
|
|
|
NullProperty = None
|
|
PGChoicesEmptyData = None
|
|
""")
|
|
|
|
|
|
# Switch all wxVariant types to wxPGVariant, so the propgrid-specific
|
|
# version of the MappedType will be used for converting to/from Python
|
|
# objects.
|
|
for item in module.allItems():
|
|
if hasattr(item, 'type') and 'wxVariant' in item.type:
|
|
item.type = item.type.replace('wxVariant', 'wxPGVariant')
|
|
|
|
#-----------------------------------------------------------------
|
|
tools.doCommonTweaks(module)
|
|
tools.runGenerators(module)
|
|
|
|
|
|
#---------------------------------------------------------------------------
|
|
if __name__ == '__main__':
|
|
run()
|
|
|