Commit 16606142 authored by Sebastian Sauer's avatar Sebastian Sauer
Browse files

* added initial implementation of the ported "Export to HTML" script using forms. Needs more work.

* fixed crash on QMetaType::void.
* restore python exceptions once thrown + fixed wrong exception lineno + fixed QString::null handling.
* fixed wrong packagepath on guiclient
* extended KSpread's SheetAdaptor with the text+setText+value+setValue methods. Maybe move those methods to SheetAdaptor?
* ported KSpread Kross module work done on aKademy in the 1.6-branch.


svn path=/trunk/koffice/; revision=599644
parent b967dbc8
......@@ -166,21 +166,21 @@ bool GUIClient::writeConfigFromPackages()
config->writeEntry(QString("%1_icon").arg(name).toLatin1(), element.attribute("icon"));
config->writeEntry(QString("%1_interpreter").arg(name).toLatin1(), element.attribute("interpreter"));
QString file = element.attribute("file");
QFileInfo fi(file);
if(! fi.exists()) {
const QDir packagepath = fi.dir();
QFileInfo fi2(packagepath, file);
QString f = element.attribute("file");
QFileInfo fi(f);
if(! QFileInfo(f).exists()) {
const QDir packagepath = QFileInfo(file).dir();
QFileInfo fi2(packagepath, f);
if( fi2.exists() ) {
file = fi2.absoluteFilePath();
f = fi2.absoluteFilePath();
}
else {
QString resource = KGlobal::dirs()->findResource("appdata", QString("scripts/%1/%2").arg(name).arg(file));
QString resource = KGlobal::dirs()->findResource("appdata", QString("scripts/%1/%2").arg(name).arg(f));
if( ! resource.isNull() )
file = resource;
f = resource;
}
}
config->writeEntry(QString("%1_file").arg(name).toLatin1(), file);
config->writeEntry(QString("%1_file").arg(name).toLatin1(), f);
}
}
......
......@@ -18,6 +18,7 @@
***************************************************************************/
#include "pythonextension.h"
#include "pythoninterpreter.h"
#include "pythonvariant.h"
#include <QWidget>
......@@ -276,16 +277,22 @@ PyObject* PythonExtension::proxyhandler(PyObject *_self_and_name_tuple, PyObject
returntype = new MetaTypeVariant< QVariant >( QVariant( (QVariant::Type) typeId ) );
}
else {
// crashes on shared containers like e.g. QStringList and QList
typeId = QMetaType::type( metamethod.typeName() );
//Q_ASSERT(typeId != QMetaType::Void);
#ifdef KROSS_PYTHON_EXTENSION_CALL_DEBUG
krossdebug( QString("PythonExtension::proxyhandler typeName=%1 metatype.typeid=%2").arg(metamethod.typeName()).arg(typeId) );
#endif
//if (id != -1) {
void* myClassPtr = QMetaType::construct(typeId, 0);
//QMetaType::destroy(id, myClassPtr);
returntype = new MetaTypeVoidStar( typeId, myClassPtr );
if(typeId == QMetaType::Void) {
#ifdef KROSS_PYTHON_EXTENSION_CALL_DEBUG
krossdebug( QString("PythonExtension::proxyhandler typeName=%1 metatype.typeid is QMetaType::Void").arg(metamethod.typeName()) );
#endif
returntype = new MetaTypeVariant< QVariant >( QVariant() );
}
else {
#ifdef KROSS_PYTHON_EXTENSION_CALL_DEBUG
krossdebug( QString("PythonExtension::proxyhandler typeName=%1 metatype.typeid=%2").arg(metamethod.typeName()).arg(typeId) );
#endif
//if (id != -1) {
void* myClassPtr = QMetaType::construct(typeId, 0);
//QMetaType::destroy(id, myClassPtr);
returntype = new MetaTypeVoidStar( typeId, myClassPtr );
}
}
variantargs[0] = returntype;
......@@ -344,7 +351,10 @@ PyObject* PythonExtension::proxyhandler(PyObject *_self_and_name_tuple, PyObject
return pyresult.ptr();
}
catch(Py::Exception& e) {
krosswarning( QString("PythonExtension::proxyhandler Had exception: %1").arg(Py::value(e).as_string().c_str()) );
QStringList trace;
int lineno;
PythonInterpreter::extractException(trace, lineno);
krosswarning( QString("PythonExtension::proxyhandler Had exception on line %1:\n%2 \n%3").arg(lineno).arg(Py::value(e).as_string().c_str()).arg(trace.join("\n")) );
}
return Py_None;
......
......@@ -242,3 +242,68 @@ PythonModule* PythonInterpreter::mainModule() const
return d->mainmodule;
}
void PythonInterpreter::extractException(QStringList& errorlist, int& lineno)
{
lineno = -1;
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
Py_FlushLine();
PyErr_NormalizeException(&type, &value, &traceback);
if(traceback) {
Py::List tblist;
try {
Py::Module tbmodule( PyImport_Import(Py::String("traceback").ptr()), true );
Py::Dict tbdict = tbmodule.getDict();
Py::Callable tbfunc(tbdict.getItem("format_tb"));
Py::Tuple args(1);
args.setItem(0, Py::Object(traceback));
tblist = tbfunc.apply(args);
uint length = tblist.length();
for(Py::List::size_type i = 0; i < length; ++i)
errorlist.append( Py::Object(tblist[i]).as_string().c_str() );
}
catch(Py::Exception& e) {
QString err = Py::value(e).as_string().c_str();
e.clear(); // exception is handled. clear it now.
krosswarning( QString("Kross::PythonScript::toException() Failed to fetch a traceback: %1").arg(err) );
}
PyObject *next;
while (traceback && traceback != Py_None) {
PyFrameObject *frame = (PyFrameObject*)PyObject_GetAttrString(traceback, const_cast< char* >("tb_frame"));
Py_DECREF(frame);
{
PyObject *getobj = PyObject_GetAttrString(traceback, const_cast< char* >("tb_lineno") );
lineno = PyInt_AsLong(getobj);
Py_DECREF(getobj);
}
if(Py_OptimizeFlag) {
PyObject *getobj = PyObject_GetAttrString(traceback, const_cast< char* >("tb_lasti") );
int lasti = PyInt_AsLong(getobj);
Py_DECREF(getobj);
lineno = PyCode_Addr2Line(frame->f_code, lasti);
}
//const char* filename = PyString_AsString(frame->f_code->co_filename);
//const char* name = PyString_AsString(frame->f_code->co_name);
//errorlist.append( QString("%1#%2: \"%3\"").arg(filename).arg(lineno).arg(name) );
next = PyObject_GetAttrString(traceback, const_cast< char* >("tb_next") );
Py_DECREF(traceback);
traceback = next;
}
}
if(lineno < 0 && value && PyObject_HasAttrString(value, "lineno")) {
PyObject *getobj = PyObject_GetAttrString(value, const_cast< char* >("lineno") );
if(getobj) {
lineno = PyInt_AsLong(getobj);
Py_DECREF(getobj);
}
}
krossdebug( QString("PythonInterpreter::extractException: %1").arg( Py::Object(value).as_string().c_str() ) );
PyErr_Restore(type, value, traceback);
}
......@@ -65,6 +65,13 @@ namespace Kross {
*/
virtual Kross::Script* createScript(Kross::Action* Action);
/**
* Extract the current exception and fill the passed \p errorlist with
* the errortrace and \p lineno with the line-number where the exception
* got raised (-1 if not known else >= 0).
*/
static void extractException(QStringList& errorlist, int& lineno);
private:
/// \internal d-pointer instance.
PythonInterpreterPrivate* d;
......
......@@ -134,7 +134,10 @@ bool PythonScript::initialize()
Py_XDECREF(pyrun); // free the reference.
*/
krossdebug( QString("PythonScript::initialize() name=%1").arg(action()->objectName()) );
#ifdef KROSS_PYTHON_SCRIPT_INIT_DEBUG
krossdebug( QString("PythonScript::initialize() name=%1").arg(action()->objectName()) );
#endif
//PyCompilerFlags* cf = new PyCompilerFlags;
//cf->cf_flags |= PyCF_SOURCE_IS_UTF8;
......@@ -150,7 +153,10 @@ bool PythonScript::initialize()
}
}
catch(Py::Exception& e) {
setErrorFromException( Py::value(e).as_string().c_str() );
QStringList trace;
int lineno;
PythonInterpreter::extractException(trace, lineno);
setError(Py::value(e).as_string().c_str(), trace.join("\n"), lineno);
e.clear(); // exception is handled. clear it now.
return false;
}
......@@ -167,77 +173,6 @@ void PythonScript::finalize()
delete d->m_code; d->m_code = 0;
}
void PythonScript::setErrorFromException(const QString& error)
{
long lineno = -1;
QStringList errorlist;
PyObject *type, *value, *traceback;
PyErr_Fetch(&type, &value, &traceback);
Py_FlushLine();
PyErr_NormalizeException(&type, &value, &traceback);
if(traceback) {
Py::List tblist;
try {
Py::Module tbmodule( PyImport_Import(Py::String("traceback").ptr()), true );
Py::Dict tbdict = tbmodule.getDict();
Py::Callable tbfunc(tbdict.getItem("format_tb"));
Py::Tuple args(1);
args.setItem(0, Py::Object(traceback));
tblist = tbfunc.apply(args);
uint length = tblist.length();
for(Py::List::size_type i = 0; i < length; ++i)
errorlist.append( Py::Object(tblist[i]).as_string().c_str() );
}
catch(Py::Exception& e) {
QString err = Py::value(e).as_string().c_str();
e.clear(); // exception is handled. clear it now.
krosswarning( QString("Kross::PythonScript::toException() Failed to fetch a traceback: %1").arg(err) );
}
PyObject *next;
while (traceback && traceback != Py_None) {
PyFrameObject *frame = (PyFrameObject*)PyObject_GetAttrString(traceback, const_cast< char* >("tb_frame"));
Py_DECREF(frame);
{
PyObject *getobj = PyObject_GetAttrString(traceback, const_cast< char* >("tb_lineno") );
lineno = PyInt_AsLong(getobj);
Py_DECREF(getobj);
}
if(Py_OptimizeFlag) {
PyObject *getobj = PyObject_GetAttrString(traceback, const_cast< char* >("tb_lasti") );
int lasti = PyInt_AsLong(getobj);
Py_DECREF(getobj);
lineno = PyCode_Addr2Line(frame->f_code, lasti);
}
//const char* filename = PyString_AsString(frame->f_code->co_filename);
//const char* name = PyString_AsString(frame->f_code->co_name);
//errorlist.append( QString("%1#%2: \"%3\"").arg(filename).arg(lineno).arg(name) );
next = PyObject_GetAttrString(traceback, const_cast< char* >("tb_next") );
Py_DECREF(traceback);
traceback = next;
}
}
if(lineno < 0) {
if(value) {
PyObject *getobj = PyObject_GetAttrString(value, const_cast< char* >("lineno") );
if(getobj) {
lineno = PyInt_AsLong(getobj);
Py_DECREF(getobj);
}
}
if(lineno < 0)
lineno = 0;
}
//PyErr_Restore(type, value, traceback);
setError(error, errorlist.join("\n"), lineno - 1);
}
void PythonScript::execute()
{
#ifdef KROSS_PYTHON_SCRIPT_EXEC_DEBUG
......
......@@ -58,8 +58,9 @@ Py::Object PythonType<QVariant>::toPyObject(const QVariant& v)
#ifdef KROSS_PYTHON_VARIANT_DEBUG
krossdebug( QString("PythonType<QVariant>::toPyObject variant=%1 is QVariant::Invalid. Returning Py:None.").arg(v.toString()) );
#endif
//return Py::None();
} // fall through
//return Py::Object();
return Py::None(); //FIXME should we fall through here?
} break;
case QVariant::UserType: {
#ifdef KROSS_PYTHON_VARIANT_DEBUG
......
......@@ -204,6 +204,7 @@ namespace Kross {
inline static QString toVariant(const Py::Object& obj) {
/*
#ifdef Py_USING_UNICODE
//if(obj.isUnicode())
PyTypeObject *type = (PyTypeObject*) object.type().ptr();
if(type == &PyUnicode_Type) {
Py::unicodestring u = Py::String(object).as_unicodestring();
......@@ -213,7 +214,7 @@ namespace Kross {
}
#endif
*/
return Py::String(obj).as_string().c_str();
return obj.isString() ? Py::String(obj).as_string().c_str() : QString();
}
};
......
......@@ -179,16 +179,22 @@ VALUE RubyExtension::call_method(RubyExtension* extension, int argc, VALUE *argv
returntype = new MetaTypeVariant< QVariant >( QVariant( (QVariant::Type) typeId ) );
}
else {
// crashes on shared containers like e.g. QStringList and QList which are handled above already
typeId = QMetaType::type( metamethod.typeName() );
//Q_ASSERT(typeId != QMetaType::Void);
#ifdef KROSS_RUBY_EXTENSION_DEBUG
krossdebug( QString("RubyExtension::call_method typeName=%1 metatype.typeid=%2").arg(metamethod.typeName()).arg(typeId) );
#endif
//if (id != -1) {
void* myClassPtr = QMetaType::construct(typeId, 0);
//QMetaType::destroy(id, myClassPtr);
returntype = new MetaTypeVoidStar( typeId, myClassPtr );
if(typeId == QMetaType::Void) {
#ifdef KROSS_RUBY_EXTENSION_DEBUG
krossdebug( QString("RubyExtension::call_method typeName=%1 metatype.typeid is QMetaType::Void").arg(metamethod.typeName()) );
#endif
returntype = new MetaTypeVariant< QVariant >( QVariant() );
}
else {
#ifdef KROSS_RUBY_EXTENSION_DEBUG
krossdebug( QString("RubyExtension::call_method typeName=%1 metatype.typeid=%2").arg(metamethod.typeName()).arg(typeId) );
#endif
//if (id != -1) {
void* myClassPtr = QMetaType::construct(typeId, 0);
//QMetaType::destroy(id, myClassPtr);
returntype = new MetaTypeVoidStar( typeId, myClassPtr );
}
}
variantargs[0] = returntype;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment