fixes for unicode build, return values from event handlers (via

updated attributes)


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@26322 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2004-03-24 23:06:01 +00:00
parent 0bb309f75c
commit 0dabb2a2c6
6 changed files with 267 additions and 122 deletions

View File

@@ -55,6 +55,7 @@ typedef unsigned short VARTYPE;
%{
// Some conversion helpers
static wxVariant _PyObj2Variant(PyObject* value);
static bool _PyObj2Variant(PyObject* value, wxVariant& wv);
static PyObject* _Variant2PyObj(wxVariant& value, bool useNone=False);
static wxString _VARTYPEname(VARTYPE vt);
@@ -62,9 +63,9 @@ static wxString _VARTYPEname(VARTYPE vt);
inline bool wxPyErr_Occurred()
{
bool rval;
wxPyBeginBlockThreads();
bool blocked = wxPyBeginBlockThreads();
rval = PyErr_Occurred() != NULL;
wxPyEndBlockThreads();
wxPyEndBlockThreads(blocked);
return rval;
}
@@ -292,7 +293,7 @@ public:
NameMap::const_iterator it = m_methodNames.find(name);
if (it == m_methodNames.end()) {
wxString msg;
msg << "method <" << name << "> not found";
msg << _T("method <") << name << _T("> not found");
wxPyErr_SetString(PyExc_KeyError, msg.mb_str());
static wxFuncX BadVal;
return BadVal;
@@ -304,7 +305,7 @@ public:
NameMap::const_iterator it = m_propNames.find(name);
if (it == m_propNames.end()) {
wxString msg;
msg << "property <" << name << "> not found";
msg << _T("property <") << name << _T("> not found");
wxPyErr_SetString(PyExc_KeyError, msg.mb_str());
static wxPropX BadVal;
return BadVal;
@@ -324,11 +325,11 @@ public:
void SetAXProp(const wxString& name, PyObject* value)
{
const wxPropX& prop = GetAXPropDesc(name);
wxPyBeginBlockThreads();
bool blocked = wxPyBeginBlockThreads();
if (! PyErr_Occurred() ) {
if (! prop.CanSet()) {
wxString msg;
msg << "property <" << name << "> is readonly";
msg << _T("property <") << name << _T("> is readonly");
PyErr_SetString(PyExc_TypeError, msg.mb_str());
goto done;
} else {
@@ -338,9 +339,9 @@ public:
VARIANT v = {prop.arg.vt};
if (!VariantToMSWVariant(wxV, v) || PyErr_Occurred()) {
wxString msg;
msg << "Unable to convert value to expected type: ("
<< _VARTYPEname(prop.arg.vt) << ") for property <"
<< name << ">";
msg << _T("Unable to convert value to expected type: (")
<< _VARTYPEname(prop.arg.vt) << _T(") for property <")
<< name << _T(">");
PyErr_SetString(PyExc_TypeError, msg.mb_str());
goto done;
}
@@ -351,7 +352,7 @@ public:
}
}
done:
wxPyEndBlockThreads();
wxPyEndBlockThreads(blocked);
}
@@ -360,11 +361,11 @@ public:
{
PyObject* rval = NULL;
const wxPropX& prop = GetAXPropDesc(name);
wxPyBeginBlockThreads();
bool blocked = wxPyBeginBlockThreads();
if (! PyErr_Occurred() ) {
if (! prop.CanGet()) {
wxString msg;
msg << "property <" << name << "> is writeonly";
msg << _T("property <") << name << _T("> is writeonly");
PyErr_SetString(PyExc_TypeError, msg.mb_str());
goto done;
} else {
@@ -374,9 +375,9 @@ public:
wxVariant wv;
if (!MSWVariantToVariant(v, wv) || PyErr_Occurred()) {
wxString msg;
msg << "Unable to convert value to expected type: ("
<< _VARTYPEname(prop.arg.vt) << ") for property <"
<< name << ">";
msg << _T("Unable to convert value to expected type: (")
<< _VARTYPEname(prop.arg.vt) << _T(") for property <")
<< name << _T(">");
PyErr_SetString(PyExc_TypeError, msg.mb_str());
goto done;
}
@@ -385,7 +386,7 @@ public:
}
}
done:
wxPyEndBlockThreads();
wxPyEndBlockThreads(blocked);
return rval;
}
@@ -406,7 +407,7 @@ public:
PyObject* rval = NULL;
const wxFuncX& func = GetAXMethodDesc(name);
wxPyBeginBlockThreads();
bool blocked = wxPyBeginBlockThreads();
if (! PyErr_Occurred() ) {
nargs = func.params.size();
if (nargs > 0)
@@ -437,9 +438,9 @@ public:
goto done;
if (!VariantToMSWVariant(wxV, vargs[nargs - i - 1]) || PyErr_Occurred()) {
wxString msg;
msg << "Unable to convert value to expected type: ("
msg << _T("Unable to convert value to expected type: (")
<< _VARTYPEname(vargs[nargs - i - 1].vt)
<< ") for parameter " << i;
<< _T(") for parameter ") << i;
PyErr_SetString(PyExc_TypeError, msg.mb_str());
goto done;
}
@@ -486,7 +487,7 @@ public:
PyErr_Clear();
}
done:
wxPyEndBlockThreads();
wxPyEndBlockThreads(blocked);
if (vargs) {
for (int i = 0; i < nargs; i++)
VariantClear(&vargs[i]);
@@ -627,25 +628,41 @@ public:
wxString EventName();
%extend {
DocStr(_preInit,
"This is called by the EventThunker before calling the handler.
We'll convert and load the ActiveX event parameters into
attributes of the Python event object.");
void _preInit(PyObject* pyself) {
wxPyBeginBlockThreads();
// This is called by the EventThunker before calling the
// handler. We'll convert and load the ActiveX event parameters into
// attributes of the Python event object.
void _preCallInit(PyObject* pyself) {
bool blocked = wxPyBeginBlockThreads();
PyObject* pList = PyList_New(0);
PyObject_SetAttrString(pyself, "paramList", pList);
Py_DECREF(pList);
for (int i=0; i<self->ParamCount(); i+=1) {
PyObject* name = PyString_FromString((char*)self->ParamName(i).mb_str());
PyObject* name = PyString_FromString((char*)(const char*)self->ParamName(i).mb_str());
PyObject* val = _Variant2PyObj((*self)[i], True);
PyObject_SetAttr(pyself, name, val);
PyList_Append(pList, name);
Py_DECREF(val);
Py_DECREF(name);
}
wxPyEndBlockThreads();
wxPyEndBlockThreads(blocked);
}
// This one is called by the EventThunker after calling the
// handler. It reloads any "out" parameters from the python attributes
// back into the wxVariant they came from.
void _postCallCleanup(PyObject* pyself) {
bool blocked = wxPyBeginBlockThreads();
for (int i=0; i<self->ParamCount(); i+=1) {
PyObject* val = PyObject_GetAttrString(
pyself, (char*)(const char*)self->ParamName(i).mb_str());
_PyObj2Variant(val, (*self)[i]);
Py_DECREF(val);
}
wxPyEndBlockThreads(blocked);
}
}
};
@@ -661,9 +678,11 @@ wxVariant _PyObj2Variant(PyObject* value)
if (value == Py_None)
return rval;
#if PYTHON_API_VERSION >= 1012 // Python 2.3+
else if (PyBool_Check(value))
rval = (value == Py_True) ? true : false;
#endif
else if (PyInt_Check(value))
rval = PyInt_AS_LONG(value);
@@ -676,6 +695,7 @@ wxVariant _PyObj2Variant(PyObject* value)
// TODO: PyList of strings --> wxArrayString
// wxDateTime
// list of objects
// etc.
else {
PyErr_SetString(PyExc_TypeError, "Unsupported object type in _PyObj2Variant");
@@ -685,6 +705,26 @@ wxVariant _PyObj2Variant(PyObject* value)
return rval;
}
// This one uses the type of the variant to try and force the conversion
bool _PyObj2Variant(PyObject* value, wxVariant& wv)
{
wxString type = wv.GetType();
if ( type == _T("long") || type == _T("bool") || type == _T("char") )
wv = PyInt_AsLong(value);
else if ( type == _T("string") )
wv = Py2wxString(value);
else if ( type == _T("double") )
wv = PyFloat_AsDouble(value);
else {
// it's some other type that we dont' handle yet. Log it?
return false;
}
return true;
}
// Caller should already have the GIL!
PyObject* _Variant2PyObj(wxVariant& value, bool useNone)
@@ -703,8 +743,10 @@ PyObject* _Variant2PyObj(wxVariant& value, bool useNone)
else if (value.IsType(_T("double")))
rval = PyFloat_FromDouble(value);
else if (value.IsType(_T("bool")))
rval = PyBool_FromLong((bool)value);
else if (value.IsType(_T("bool"))) {
rval = (bool)value ? Py_True : Py_False;
Py_INCREF(rval);
}
else if (value.IsType(_T("string")))
rval = wx2PyString(value);
@@ -879,7 +921,11 @@ public:
// need to prepend this as poxy MSHTML will not recognise a HTML comment
// as starting a html document and treats it as plain text
// Does nayone know how to force it to html mode ?
pstrm->prepend = "<html>";
#if wxUSE_UNICODE
// TODO: What to do in this case???
#else
pstrm->prepend = _T("<html>");
#endif
// strip leading whitespace as it can confuse MSHTML
wxAutoOleInterface<IStream> strm(pstrm);