diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 90825e2392b2d70e43c7a25b8a3752299a933894 (patch) | |
tree | e33aa27f02b74604afbfd0ea4f1cfca8833d882a /korundum/rubylib/korundum | |
download | tdebindings-90825e2392b2d70e43c7a25b8a3752299a933894.tar.gz tdebindings-90825e2392b2d70e43c7a25b8a3752299a933894.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebindings@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'korundum/rubylib/korundum')
-rw-r--r-- | korundum/rubylib/korundum/Korundum.cpp | 1183 | ||||
-rw-r--r-- | korundum/rubylib/korundum/Makefile.am | 10 | ||||
-rw-r--r-- | korundum/rubylib/korundum/configure.in.in | 15 | ||||
-rw-r--r-- | korundum/rubylib/korundum/kdehandlers.cpp | 1428 | ||||
-rw-r--r-- | korundum/rubylib/korundum/lib/KDE/Korundum.rb | 1 | ||||
-rw-r--r-- | korundum/rubylib/korundum/lib/KDE/Makefile.am | 5 | ||||
-rw-r--r-- | korundum/rubylib/korundum/lib/KDE/korundum.rb | 1391 | ||||
-rw-r--r-- | korundum/rubylib/korundum/lib/Makefile.am | 1 |
8 files changed, 4034 insertions, 0 deletions
diff --git a/korundum/rubylib/korundum/Korundum.cpp b/korundum/rubylib/korundum/Korundum.cpp new file mode 100644 index 00000000..6cd3045a --- /dev/null +++ b/korundum/rubylib/korundum/Korundum.cpp @@ -0,0 +1,1183 @@ +/*************************************************************************** + Korundum.cpp - Runtime for KDE services, DCOP etc + ------------------- + begin : Sun Sep 28 2003 + copyright : (C) 2003-2004 by Richard Dale + email : Richard_Dale@tipitina.demon.co.uk + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <qobject.h> +#include <qstringlist.h> +#include <qmap.h> +#include <qdatastream.h> + +#include <kdeversion.h> +#include <dcopclient.h> +#include <dcopobject.h> +#include <dcopref.h> +#include <kapplication.h> +#include <kurl.h> +#if KDE_VERSION >= 0x030200 +#include <kconfigskeleton.h> +#endif +#include <kio/global.h> +#include <kparts/browserextension.h> +#include <kde_terminal_interface.h> + +#include <ruby.h> + +#include <marshall.h> +#include <qtruby.h> +#include <smokeruby.h> +#include <smoke.h> + +extern "C" { +extern VALUE qt_internal_module; +extern VALUE kconfigskeleton_class; +extern VALUE kconfigskeleton_itemenum_choice_class; +extern VALUE kio_udsatom_class; +extern VALUE konsole_part_class; +extern VALUE set_obj_info(const char * className, smokeruby_object * o); +extern void set_kde_resolve_classname(const char * (*kde_resolve_classname) (Smoke*, int, void *)); +extern const char * kde_resolve_classname(Smoke* smoke, int classId, void * ptr); +}; + +extern TypeHandler KDE_handlers[]; +extern void install_handlers(TypeHandler *); +extern Smoke *qt_Smoke; + + +static VALUE kde_internal_module; +Marshall::HandlerFn getMarshallFn(const SmokeType &type); + +/* + Copy items from the stack to the stream, each item has a corresponding description in the + args array of MocArguments. Used for marshalling the args to DCOP calls and sends, emitting + DCOP signals, and converting the return value of a DCOP slot to a stream. +*/ +static void +smokeStackToStream(Marshall *m, Smoke::Stack stack, QDataStream* stream, int items, MocArgument* args) +{ + for(int i = 0; i < items; i++) { + switch(args[i].argType) { + case xmoc_bool: + *stream << stack[i].s_bool; + break; + case xmoc_int: + *stream << stack[i].s_int; + break; + case xmoc_double: + *stream << stack[i].s_double; + break; + case xmoc_charstar: + *stream << (char *) stack[i].s_voidp; + break; + case xmoc_QString: + { + QString temp((const QString&) *((QString *) stack[i].s_voidp)); + *stream << temp; + } + break; + default: + { + const SmokeType &t = args[i].st; + switch(t.elem()) { + case Smoke::t_bool: + *stream << stack[i].s_bool; + break; + case Smoke::t_char: + *stream << stack[i].s_char; + break; + case Smoke::t_uchar: + *stream << stack[i].s_uchar; + break; + case Smoke::t_short: + *stream << stack[i].s_short; + break; + case Smoke::t_ushort: + *stream << stack[i].s_ushort; + break; + case Smoke::t_int: + *stream << stack[i].s_int; + break; + case Smoke::t_uint: + *stream << stack[i].s_uint; + break; + case Smoke::t_long: + *stream << stack[i].s_long; + break; + case Smoke::t_ulong: + *stream << stack[i].s_ulong; + break; + case Smoke::t_float: + *stream << stack[i].s_float; + break; + case Smoke::t_double: + *stream << stack[i].s_double; + break; + case Smoke::t_enum: + m->unsupported(); + break; + case Smoke::t_class: + case Smoke::t_voidp: + { + // Special case any types which are in the Smoke runtime, but + // don't have QDataStream '<<' methods + if (strcmp(t.name(), "QCString") == 0) { + QCString temp((const QCString&) *((QCString *) stack[i].s_voidp)); + *stream << temp; + break; + } else if (strcmp(t.name(), "QCStringList") == 0) { + QCStringList temp((const QCStringList&) *((QCStringList *) stack[i].s_voidp)); + *stream << temp; + break; + } else if (strcmp(t.name(), "QStringList") == 0) { + QStringList temp((const QStringList&) *((QStringList *) stack[i].s_voidp)); + *stream << temp; + break; + } else if (strcmp(t.name(), "KURL::List") == 0) { + KURL::List temp((const KURL::List&) *((KURL::List *) stack[i].s_voidp)); + *stream << temp; + break; + } else if (strcmp(t.name(), "QMap<QCString,DCOPRef>") == 0) { + QMap<QCString,DCOPRef> temp((const QMap<QCString,DCOPRef>&) *((QMap<QCString,DCOPRef>*) stack[i].s_voidp)); + *stream << temp; + break; + } + + // Look for methods of the form: QDataStream & operator<<(QDataStream&, const MyClass&) + Smoke::Index meth = t.smoke()->findMethod("QGlobalSpace", "operator<<##"); + Smoke::Index ix; + if (meth > 0) { + ix = t.smoke()->methodMaps[meth].method; + ix = -ix; // turn into ambiguousMethodList index + while (t.smoke()->ambiguousMethodList[ix]) { + Smoke::Method &method = t.smoke()->methods[t.smoke()->ambiguousMethodList[ix]]; + QString refType("const "); + refType += t.name(); + refType += "&"; + if ( strcmp( "QDataStream&", + t.smoke()->types[t.smoke()->argumentList[method.args+0]].name ) == 0 + && strcmp( refType.latin1(), + t.smoke()->types[t.smoke()->argumentList[method.args+1]].name ) == 0 ) + { + Smoke::ClassFn fn = t.smoke()->classes[method.classId].classFn; + Smoke::StackItem local_stack[3]; + local_stack[1].s_voidp = stream; + local_stack[2].s_voidp = stack[i].s_voidp; + // Call the QDataStream marshaller write method + // with the instance to be marshalled + (*fn)(method.method, 0, local_stack); + break; + } + ix++; + } + } + } + break; + default: + break; + } + } + } + } + return; +} + +/* + Copy items from the stream to the stack, each item has a corresponding description in the + args array of MocArguments. Used for marshalling the arguments to a DCOP slot invocation, + and for converting a dcop reply to a ruby value. +*/ +static void +smokeStackFromStream(Marshall *m, Smoke::Stack stack, QDataStream* stream, int items, MocArgument* args) +{ + for(int i = 0; i < items; i++) { + switch(args[i].argType) { + case xmoc_bool: + { + *stream >> stack[i].s_bool; + break; + } + case xmoc_int: + { + *stream >> stack[i].s_int; + break; + } + case xmoc_double: + *stream >> stack[i].s_double; + break; + case xmoc_charstar: + *stream >> (char *&) stack[i].s_voidp; + break; + case xmoc_QString: + { + QString temp; + *stream >> temp; + stack[i].s_voidp = new QString(temp); + } + break; + default: // case xmoc_ptr: + { + const SmokeType &t = args[i].st; + switch(t.elem()) { + case Smoke::t_bool: + { + *stream >> stack[i].s_bool; + break; + } + case Smoke::t_char: + { + *stream >> stack[i].s_char; + break; + } + case Smoke::t_uchar: + { + *stream >> stack[i].s_uchar; + break; + } + case Smoke::t_short: + { + *stream >> stack[i].s_short; + break; + } + case Smoke::t_ushort: + { + *stream >> stack[i].s_ushort; + break; + } + case Smoke::t_int: + { + *stream >> stack[i].s_int; + break; + } + case Smoke::t_uint: + { + *stream >> stack[i].s_uint; + break; + } + case Smoke::t_long: + { + *stream >> stack[i].s_long; + break; + } + case Smoke::t_ulong: + { + *stream >> stack[i].s_ulong; + break; + } + case Smoke::t_float: + *stream >> stack[i].s_float; + break; + case Smoke::t_double: + *stream >> stack[i].s_double; + break; + case Smoke::t_enum: + m->unsupported(); + break; + case Smoke::t_class: + case Smoke::t_voidp: + { + // Special case any types which are in the Smoke runtime, but + // don't have QDataStream '>>' methods + if (strcmp(t.name(), "QCString") == 0) { + QCString temp; + *stream >> temp; + stack[i].s_voidp = new QCString(temp); + break; + } else if (strcmp(t.name(), "QCStringList") == 0) { + QCStringList temp; + *stream >> temp; + stack[i].s_voidp = new QCStringList(temp); + break; + } else if (strcmp(t.name(), "QStringList") == 0) { + QStringList temp; + *stream >> temp; + stack[i].s_voidp = new QStringList(temp); + break; + } else if (strcmp(t.name(), "KURL::List") == 0) { + KURL::List temp; + *stream >> temp; + stack[i].s_voidp = new KURL::List(temp); + break; + } else if (strcmp(t.name(), "QMap<QCString,DCOPRef>") == 0) { + QMap<QCString,DCOPRef> temp; + *stream >> temp; + stack[i].s_voidp = new QMap<QCString,DCOPRef>(temp); + break; + } + + // First construct an instance to read the QDataStream into, + // so look for a no args constructor + Smoke::Index ctorId = t.smoke()->idMethodName(t.name()); + Smoke::Index ctorMeth = t.smoke()->findMethod(t.classId(), ctorId); + Smoke::Index ctor = t.smoke()->methodMaps[ctorMeth].method; + if(ctor < 1) { + stack[i].s_voidp = 0; + m->unsupported(); + break; // Ambiguous or non-existent method, shouldn't happen with a no arg constructor + } + // Okay, ctor is the constructor. Time to call it. + Smoke::StackItem ctor_stack[1]; + ctor_stack[0].s_voidp = 0; + Smoke::ClassFn classfn = t.smoke()->classes[t.classId()].classFn; + (*classfn)(t.smoke()->methods[ctor].method, 0, ctor_stack); + stack[i].s_voidp = ctor_stack[0].s_voidp; + + // Look for methods of the form: QDataStream & operator>>(QDataStream&, MyClass&) + Smoke::Index meth = t.smoke()->findMethod("QGlobalSpace", "operator>>##"); + Smoke::Index ix; + if (meth > 0) { + ix = t.smoke()->methodMaps[meth].method; + ix = -ix; // turn into ambiguousMethodList index + while (t.smoke()->ambiguousMethodList[ix]) { + Smoke::Method &method = t.smoke()->methods[t.smoke()->ambiguousMethodList[ix]]; + QString refType(t.name()); + refType += "&"; + if ( strcmp( "QDataStream&", + t.smoke()->types[t.smoke()->argumentList[method.args+0]].name ) == 0 + && strcmp( refType.latin1(), + t.smoke()->types[t.smoke()->argumentList[method.args+1]].name ) == 0 ) + { + Smoke::ClassFn fn = t.smoke()->classes[method.classId].classFn; + Smoke::StackItem local_stack[3]; + local_stack[1].s_voidp = stream; + local_stack[2].s_voidp = stack[i].s_voidp; + // Call the QDataStream marshaller read method + // on the instance to be marshalled + (*fn)(method.method, 0, local_stack); + break; + } + ix++; + } + } + } + break; + } + } + } + } +} + +/* + Converts a QByteArray returned from a DCOP call to a ruby value. +*/ +class DCOPReturn : public Marshall { + MocArgument * _replyType; + Smoke::Stack _stack; + VALUE * _result; +public: + DCOPReturn(QDataStream & retval, VALUE * result, VALUE replyType) + { + _result = result; + VALUE temp = rb_funcall(qt_internal_module, rb_intern("getMocArguments"), 1, replyType); + Data_Get_Struct(rb_ary_entry(temp, 1), MocArgument, _replyType); + _stack = new Smoke::StackItem[1]; + smokeStackFromStream(this, _stack, &retval, 1, _replyType); + Marshall::HandlerFn fn = getMarshallFn(type()); + (*fn)(this); + } + + SmokeType type() { + return _replyType[0].st; + } + Marshall::Action action() { return Marshall::ToVALUE; } + Smoke::StackItem &item() { return _stack[0]; } + VALUE * var() { + return _result; + } + + void unsupported() + { + rb_raise(rb_eArgError, "Cannot handle '%s' as DCOP return-type", type().name()); + } + Smoke *smoke() { return type().smoke(); } + + void next() {} + + bool cleanup() { return false; } + + ~DCOPReturn() + { + delete[] _stack; + } +}; + +class DCOPCall : public Marshall { + VALUE _obj; + QCString & _remFun; + int _items; + VALUE *_sp; + QByteArray *_data; + QDataStream *_stream; + int _id; + MocArgument *_args; + bool _useEventLoop; + int _timeout; + int _cur; + Smoke::Stack _stack; + VALUE _result; + bool _called; +public: + DCOPCall(VALUE obj, QCString & remFun, int items, VALUE *sp, VALUE args, bool useEventLoop, int timeout) : + _obj(obj), _remFun(remFun), _items(items), _sp(sp), + _useEventLoop(useEventLoop), _timeout(timeout), _cur(-1), _called(false) + { + _data = new QByteArray(); + _stream = new QDataStream(*_data, IO_WriteOnly); + Data_Get_Struct(rb_ary_entry(args, 1), MocArgument, _args); + _stack = new Smoke::StackItem[_items]; + _result = Qnil; + } + + ~DCOPCall() + { + delete[] _stack; + delete _data; + delete _stream; + } + const MocArgument &arg() { return _args[_cur]; } + SmokeType type() { return arg().st; } + Marshall::Action action() { return Marshall::FromVALUE; } + Smoke::StackItem &item() { return _stack[_cur]; } + VALUE * var() { + if(_cur < 0) return &_result; + return _sp + _cur; + } + + void unsupported() + { + rb_raise(rb_eArgError, "Cannot handle '%s' as a DCOP call argument", type().name()); + } + + Smoke *smoke() { return type().smoke(); } + + void dcopCall() + { + if(_called) return; + _called = true; + + smokeStackToStream(this, _stack, _stream, _items, _args); + smokeruby_object *o = value_obj_info(_obj); + DCOPRef * dcopRef = (DCOPRef *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("DCOPRef")); + DCOPClient* dc = dcopRef->dcopClient(); + QCString replyType; + QByteArray dataReceived; +#if KDE_VERSION >= 0x030200 + bool ok = dc->call(dcopRef->app(), dcopRef->obj(), _remFun, *_data, replyType, dataReceived, _useEventLoop, _timeout); +#else + bool ok = dc->call(dcopRef->app(), dcopRef->obj(), _remFun, *_data, replyType, dataReceived, _useEventLoop); +#endif + + if (!ok) { + // Note that a failed dcop call returns 'nil', not 'false' + _result = Qnil; + return; + } else if (replyType == "void" || replyType == "ASYNC") { + _result = Qtrue; + return; + } + + QDataStream ds(dataReceived, IO_ReadOnly); + + if (replyType == "QValueList<DCOPRef>") { + // Special case QValueList<DCOPRef> as a QDataStream marshaller + // isn't in the Smoke runtime + QValueList<DCOPRef> valuelist; + ds >> valuelist; + _result = rb_ary_new(); + for (QValueListIterator<DCOPRef> it = valuelist.begin(); it != valuelist.end(); ++it) { + void *p = new DCOPRef(*it); + VALUE obj = getPointerObject(p); + + if (obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->classId = qt_Smoke->idClass("DCOPRef"); + o->smoke = qt_Smoke; + o->ptr = p; + o->allocated = true; + obj = set_obj_info("KDE::DCOPRef", o); + } + + rb_ary_push(_result, obj); + } + } else if (replyType == "QValueList<QCString>") { + // And special case this type too + QValueList<QCString> propertyList; + ds >> propertyList; + _result = rb_ary_new(); + for (QValueListIterator<QCString> it = propertyList.begin(); it != propertyList.end(); ++it) { + rb_ary_push(_result, rb_str_new2((const char *) *it)); + } + } else if (replyType == "QValueList<int>") { + // And special case this type too + QValueList<int> propertyList; + ds >> propertyList; + _result = rb_ary_new(); + for (QValueListIterator<int> it = propertyList.begin(); it != propertyList.end(); ++it) { + rb_ary_push(_result, INT2NUM(*it)); + } + } else if (replyType == "QMap<QString,DCOPRef>") { + // And another.. + QMap<QString,DCOPRef> actionMap; + ds >> actionMap; + _result = rb_hash_new(); + + QMap<QString,DCOPRef>::Iterator it; + for (it = actionMap.begin(); it != actionMap.end(); ++it) { + void *p = new DCOPRef(it.data()); + VALUE obj = getPointerObject(p); + + if (obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->classId = qt_Smoke->idClass("DCOPRef"); + o->smoke = qt_Smoke; + o->ptr = p; + o->allocated = true; + obj = set_obj_info("KDE::DCOPRef", o); + } + + rb_hash_aset(_result, rb_str_new2(it.key().latin1()), obj); + } + } else { + DCOPReturn dcopReturn(ds, &_result, rb_str_new2((const char *) replyType)); + } + } + + void next() + { + int oldcur = _cur; + _cur++; + + while(!_called && _cur < _items) { + Marshall::HandlerFn fn = getMarshallFn(type()); + (*fn)(this); + _cur++; + } + + dcopCall(); + _cur = oldcur; + } + + bool cleanup() { return true; } +}; + +class DCOPSend : public Marshall { + VALUE _obj; + QCString & _remFun; + QByteArray *_data; + QDataStream *_stream; + int _id; + MocArgument *_args; + int _items; + VALUE *_sp; + int _cur; + VALUE * _result; + Smoke::Stack _stack; + bool _called; +public: + DCOPSend(VALUE obj, QCString & remFun, int items, VALUE *sp, VALUE args, VALUE * result) : + _obj(obj), _remFun(remFun), _items(items), _sp(sp), _cur(-1), _result(result), _called(false) + { + _data = new QByteArray(); + _stream = new QDataStream(*_data, IO_WriteOnly); + Data_Get_Struct(rb_ary_entry(args, 1), MocArgument, _args); + _stack = new Smoke::StackItem[_items]; + } + + ~DCOPSend() + { + delete[] _stack; + delete _data; + delete _stream; + } + const MocArgument &arg() { return _args[_cur]; } + SmokeType type() { return arg().st; } + Marshall::Action action() { return Marshall::FromVALUE; } + Smoke::StackItem &item() { return _stack[_cur]; } + VALUE * var() { return _sp + _cur; } + + void unsupported() + { + rb_raise(rb_eArgError, "Cannot handle '%s' as a DCOP send argument", type().name()); + } + + Smoke *smoke() { return type().smoke(); } + + void dcopSend() + { + if(_called) return; + _called = true; + + smokeStackToStream(this, _stack, _stream, _items, _args); + smokeruby_object *o = value_obj_info(_obj); + DCOPRef * dcopRef = (DCOPRef *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("DCOPRef")); + DCOPClient* dc = dcopRef->dcopClient(); + bool ok = dc->send(dcopRef->app(), dcopRef->obj(), _remFun, *_data); + *_result = (ok ? Qtrue : Qfalse); + } + + void next() + { + int oldcur = _cur; + _cur++; + + while(!_called && _cur < _items) { + Marshall::HandlerFn fn = getMarshallFn(type()); + (*fn)(this); + _cur++; + } + + dcopSend(); + _cur = oldcur; + } + + bool cleanup() { return true; } +}; + +class EmitDCOPSignal : public Marshall { + VALUE _obj; + const char * _signalName; + QByteArray *_data; + QDataStream *_stream; + int _id; + MocArgument *_args; + VALUE *_sp; + int _items; + int _cur; + Smoke::Stack _stack; + bool _called; +public: + EmitDCOPSignal(VALUE obj, const char * signalName, int items, VALUE *sp, VALUE args) : + _obj(obj), _signalName(signalName), _sp(sp), _items(items), _cur(-1), _called(false) + { + _data = new QByteArray(); + _stream = new QDataStream(*_data, IO_WriteOnly); + Data_Get_Struct(rb_ary_entry(args, 1), MocArgument, _args); + _stack = new Smoke::StackItem[_items]; + } + + ~EmitDCOPSignal() + { + delete[] _stack; + delete _stream; + delete _data; + } + const MocArgument &arg() { return _args[_cur]; } + SmokeType type() { return arg().st; } + Marshall::Action action() { return Marshall::FromVALUE; } + Smoke::StackItem &item() { return _stack[_cur]; } + VALUE * var() { return _sp + _cur; } + + void unsupported() + { + rb_raise(rb_eArgError, "Cannot handle '%s' as a DCOP signal argument", type().name()); + } + + Smoke *smoke() { return type().smoke(); } + + void emitSignal() + { + if(_called) return; + _called = true; + + smokeStackToStream(this, _stack, _stream, _items, _args); + smokeruby_object *o = value_obj_info(_obj); + DCOPObject * dcopObject = (DCOPObject *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("DCOPObject")); + dcopObject->emitDCOPSignal(_signalName, *_data); + } + + void next() + { + int oldcur = _cur; + _cur++; + + while(!_called && _cur < _items) { + Marshall::HandlerFn fn = getMarshallFn(type()); + (*fn)(this); + _cur++; + } + + emitSignal(); + _cur = oldcur; + } + + bool cleanup() { return true; } +}; + +/* + Converts a ruby value returned by a DCOP slot invocation to a QByteArray +*/ +class DCOPReplyValue : public Marshall { + MocArgument * _replyType; + Smoke::Stack _stack; + VALUE * _result; +public: + DCOPReplyValue(QByteArray & retval, VALUE * result, VALUE replyType) + { + QDataStream _retval(retval, IO_WriteOnly); + _result = result; + Data_Get_Struct(rb_ary_entry(replyType, 1), MocArgument, _replyType); + _stack = new Smoke::StackItem[1]; + Marshall::HandlerFn fn = getMarshallFn(type()); + (*fn)(this); + smokeStackToStream(this, _stack, &_retval, 1, _replyType); + } + + SmokeType type() { + return _replyType[0].st; + } + Marshall::Action action() { return Marshall::FromVALUE; } + Smoke::StackItem &item() { return _stack[0]; } + VALUE * var() { + return _result; + } + + void unsupported() + { + rb_raise(rb_eArgError, "Cannot handle '%s' as DCOP reply-type", type().name()); + } + Smoke *smoke() { return type().smoke(); } + + void next() {} + + bool cleanup() { return false; } + + ~DCOPReplyValue() { + delete[] _stack; + } +}; + +class InvokeDCOPSlot : public Marshall { + VALUE _obj; + ID _slotname; + int _items; + MocArgument * _args; + QDataStream * _stream; + const char * _replyTypeName; + VALUE _replyType; + QByteArray * _retval; + int _cur; + bool _called; + VALUE * _sp; + Smoke::Stack _stack; +public: + const MocArgument &arg() { return _args[_cur]; } + SmokeType type() { return arg().st; } + Marshall::Action action() { return Marshall::ToVALUE; } + Smoke::StackItem &item() { return _stack[_cur]; } + VALUE * var() { return _sp + _cur; } + Smoke *smoke() { return type().smoke(); } + bool cleanup() { return false; } + + void unsupported() + { + rb_raise(rb_eArgError, "Cannot handle '%s' as DCOP slot argument\n", type().name()); + } + + void copyArguments() + { + smokeStackFromStream(this, _stack, _stream, _items, _args); + return; + } + + void invokeSlot() + { + if (_called) { + return; + } + _called = true; + VALUE result = rb_funcall2(_obj, _slotname, _items, _sp); + + if ( strcmp(_replyTypeName, "QValueList<DCOPRef>") == 0 + && TYPE(result) == T_ARRAY ) + { + // Special case QValueList<DCOPRef> as a QDataStream marshaller + // isn't in the Smoke runtime + QValueList<DCOPRef> windowList; + + for (long i = 0; i < RARRAY(result)->len; i++) { + VALUE item = rb_ary_entry(result, i); + smokeruby_object *o = value_obj_info(item); + if( !o || !o->ptr) + continue; + void * ptr = o->ptr; + ptr = o->smoke->cast(ptr, o->classId, o->smoke->idClass("DCOPRef")); + windowList.append((DCOPRef)*(DCOPRef*)ptr); + } + QDataStream retval(*_retval, IO_WriteOnly); + retval << windowList; + } else if ( strcmp(_replyTypeName, "QValueList<QCString>") == 0 + && TYPE(result) == T_ARRAY ) + { + // And special case this type too + QValueList<QCString> propertyList; + + for (long i = 0; i < RARRAY(result)->len; i++) { + VALUE item = rb_ary_entry(result, i); + propertyList.append(QCString(StringValuePtr(item))); + } + QDataStream retval(*_retval, IO_WriteOnly); + retval << propertyList; + } else if ( strcmp(_replyTypeName, "QMap<QString,DCOPRef>") == 0 + && TYPE(result) == T_HASH ) + { + // And another.. + QMap<QString,DCOPRef> actionMap; + // Convert the ruby hash to an array of key/value arrays + VALUE temp = rb_funcall(result, rb_intern("to_a"), 0); + + for (long i = 0; i < RARRAY(temp)->len; i++) { + VALUE action = rb_ary_entry(rb_ary_entry(temp, i), 0); + VALUE item = rb_ary_entry(rb_ary_entry(temp, i), 1); + + smokeruby_object *o = value_obj_info(item); + if( !o || !o->ptr) + continue; + void * ptr = o->ptr; + ptr = o->smoke->cast(ptr, o->classId, o->smoke->idClass("DCOPRef")); + + actionMap[QString(StringValuePtr(action))] = (DCOPRef)*(DCOPRef*)ptr; + } + QDataStream retval(*_retval, IO_WriteOnly); + retval << actionMap; + } else if (_replyType != Qnil) { + DCOPReplyValue dcopReply(*_retval, &result, _replyType); + } + } + + void next() + { + int oldcur = _cur; + _cur++; + + while(!_called && _cur < _items) { + Marshall::HandlerFn fn = getMarshallFn(type()); + (*fn)(this); + _cur++; + } + + invokeSlot(); + _cur = oldcur; + } + + InvokeDCOPSlot(VALUE obj, ID slotname, VALUE args, QByteArray& data, VALUE replyTypeName, VALUE replyType, QByteArray& returnValue) : + _obj(obj), _slotname(slotname), _replyType(replyType), _cur(-1), _called(false) + { + _replyTypeName = StringValuePtr(replyTypeName); + _items = NUM2INT(rb_ary_entry(args, 0)); + _stream = new QDataStream(data, IO_ReadOnly); + _retval = &returnValue; + + Data_Get_Struct(rb_ary_entry(args, 1), MocArgument, _args); + _sp = ALLOC_N(VALUE, _items); + _stack = new Smoke::StackItem[_items]; + + copyArguments(); + } + + ~InvokeDCOPSlot() { + delete[] _stack; + delete _stream; + for(int i=0;i<_items;++i) { + free(_sp++); + } + } +}; + +extern "C" { +extern void Init_qtruby(); +extern void set_new_kde(VALUE (*new_kde) (int, VALUE *, VALUE)); +extern void set_kconfigskeletonitem_immutable(VALUE (*kconfigskeletonitem_immutable) (VALUE)); +extern void set_kde_resolve_classname(const char * (*kde_resolve_classname) (Smoke*, int, void *)); +extern const char * kde_resolve_classname(Smoke* smoke, int classId, void * ptr); +extern VALUE new_qt(int argc, VALUE * argv, VALUE klass); +extern VALUE qt_module; +extern VALUE qt_internal_module; +extern VALUE qt_base_class; +extern VALUE kde_module; +extern VALUE kio_module; +extern VALUE kparts_module; +extern VALUE khtml_module; + +VALUE +getdcopinfo(VALUE self, QString & signalname) +{ + VALUE member = rb_funcall( kde_internal_module, + rb_intern("fullSignalName"), + 2, self, rb_str_new2(signalname) ); + signalname.setLatin1(StringValuePtr(member)); + return rb_funcall( qt_internal_module, + rb_intern("getMocArguments"), + 1, member ); +} + +VALUE +k_dcop_signal(int argc, VALUE * argv, VALUE self) +{ + VALUE dcopObject = rb_funcall(kde_module, rb_intern("createDCOPObject"), 1, self); + + QString signalname(rb_id2name(rb_frame_last_func())); + VALUE args = getdcopinfo(self, signalname); + + if(args == Qnil) return Qfalse; + + EmitDCOPSignal signal(dcopObject, signalname.latin1(), argc, argv, args); + signal.next(); + + return Qtrue; +} + +static VALUE +dcop_functions(VALUE self) +{ + VALUE dcopObject = rb_funcall(kde_module, rb_intern("createDCOPObject"), 1, self); + return rb_funcall(dcopObject, rb_intern("functions"), 0); +} + +static VALUE +dcop_interfaces(VALUE self) +{ + VALUE dcopObject = rb_funcall(kde_module, rb_intern("createDCOPObject"), 1, self); + return rb_funcall(dcopObject, rb_intern("interfaces"), 0); +} + +static VALUE +dcop_connect_signal(VALUE self, VALUE sender, VALUE senderObj, VALUE signal, VALUE slot, VALUE volatile_connect) +{ + VALUE dcopObject = rb_funcall(kde_module, rb_intern("createDCOPObject"), 1, self); + return rb_funcall(dcopObject, rb_intern("connectDCOPSignal"), 5, sender, senderObj, signal, slot, volatile_connect); +} + +static VALUE +dcop_disconnect_signal(VALUE self, VALUE sender, VALUE senderObj, VALUE signal, VALUE slot) +{ + VALUE dcopObject = rb_funcall(kde_module, rb_intern("createDCOPObject"), 1, self); + return rb_funcall(dcopObject, rb_intern("disconnectDCOPSignal"), 4, sender, senderObj, signal, slot); +} + +static VALUE +dcop_process(VALUE /*self*/, VALUE target, VALUE slotname, VALUE args, VALUE data, VALUE replyTypeName, VALUE replyType, VALUE replyData) +{ + smokeruby_object *o = value_obj_info(data); + if (o == 0 || o->ptr == 0) { + return Qfalse; + } + QByteArray * dataArray = (QByteArray*) o->ptr; + + o = value_obj_info(replyData); + if (o == 0 || o->ptr == 0) { + return Qfalse; + } + QByteArray * replyArray = (QByteArray*) o->ptr; + + InvokeDCOPSlot dcopSlot(target, rb_intern(StringValuePtr(slotname)), args, *dataArray, replyTypeName, replyType, *replyArray); + dcopSlot.next(); + + return Qtrue; +} + +static VALUE +dcop_call(int argc, VALUE * argv, VALUE /*self*/) +{ + QCString fun(StringValuePtr(argv[1])); + VALUE args = argv[2]; + bool useEventLoop = (argv[argc-2] == Qtrue ? true : false); + int timeout = NUM2INT(argv[argc-1]); + + DCOPCall dcopCall(argv[0], fun, argc-5, argv+3, args, useEventLoop, timeout); + dcopCall.next(); + + return *(dcopCall.var()); +} + +static VALUE +dcop_send(int argc, VALUE * argv, VALUE /*self*/) +{ + QCString fun(StringValuePtr(argv[1])); + VALUE args = argv[2]; + VALUE result = Qnil; + + DCOPSend dcopSend(argv[0], fun, argc-3, argv+3, args, &result); + dcopSend.next(); + + return result; +} + +static VALUE +new_kde(int argc, VALUE * argv, VALUE klass) +{ + VALUE instance = new_qt(argc, argv, klass); + + if (rb_funcall(kde_module, rb_intern("hasDCOPSignals"), 1, klass) == Qtrue) { + VALUE signalNames = rb_funcall(kde_module, rb_intern("getDCOPSignalNames"), 1, klass); + for (long index = 0; index < RARRAY(signalNames)->len; index++) { + VALUE signal = rb_ary_entry(signalNames, index); + rb_define_method(klass, StringValuePtr(signal), (VALUE (*) (...)) k_dcop_signal, -1); + } + } + + if ( rb_funcall(kde_module, rb_intern("hasDCOPSlots"), 1, klass) == Qtrue + || rb_funcall(kde_module, rb_intern("hasDCOPSignals"), 1, klass) == Qtrue ) + { + VALUE dcop_object = rb_funcall(kde_module, rb_intern("createDCOPObject"), 1, instance); + if (dcop_object != Qnil) { + rb_define_method(klass, "interfaces", (VALUE (*) (...)) dcop_interfaces, 0); + rb_define_method(klass, "functions", (VALUE (*) (...)) dcop_functions, 0); + rb_define_method(klass, "connectDCOPSignal", (VALUE (*) (...)) dcop_connect_signal, 5); + rb_define_method(klass, "disconnectDCOPSignal", (VALUE (*) (...)) dcop_disconnect_signal, 4); + } + } + + return instance; +} + +#if KDE_VERSION >= 0x030200 + +static VALUE +kconfigskeletonitem_immutable(VALUE self) +{ + smokeruby_object *o = value_obj_info(self); + KConfigSkeletonItem * item = (KConfigSkeletonItem *) o->ptr; + return item->isImmutable() ? Qtrue : Qfalse; +} + +static VALUE +config_additem(int argc, VALUE * argv, VALUE self) +{ + smokeruby_object *o = value_obj_info(self); + KConfigSkeleton * config = (KConfigSkeleton *) o->ptr; + + if (argc < 1 || argc > 2) { + rb_raise(rb_eArgError, "wrong number of arguments(%d for 2)\n", argc); + } + + if (TYPE(argv[0]) != T_DATA) { + rb_raise(rb_eArgError, "wrong argument type, expected KDE::ConfigSkeletonItem\n", argc); + } + + smokeruby_object *c = value_obj_info(argv[0]); + KConfigSkeletonItem * item = (KConfigSkeletonItem *) c->ptr; + + if (argc == 1) { + config->addItem(item); + } else { + config->addItem(item, QString(StringValuePtr(argv[1]))); + } + + return self; +} + +#endif + +static VALUE +konsole_part_startprogram(VALUE self, VALUE value_program, VALUE value_args) +{ + smokeruby_object * o = value_obj_info(self); + TerminalInterface * t = static_cast<TerminalInterface*>(((KParts::ReadOnlyPart*) o->ptr)->qt_cast("TerminalInterface")); + + QStrList *args = new QStrList; + + if (value_args != Qnil) { + for (long i = 0; i < RARRAY(value_args)->len; i++) { + VALUE item = rb_ary_entry(value_args, i); + args->append(QString::fromLatin1(StringValuePtr(item), RSTRING(item)->len)); + } + } + + t->startProgram(QString::fromLatin1(StringValuePtr(value_program)), args); + return self; +} + +static VALUE +konsole_part_showshellindir(VALUE self, VALUE value_dir) +{ + smokeruby_object * o = value_obj_info(self); + TerminalInterface * t = static_cast<TerminalInterface*>(((KParts::ReadOnlyPart*) o->ptr)->qt_cast("TerminalInterface")); + t->showShellInDir(StringValuePtr(value_dir)); + return self; +} + +static VALUE +konsole_part_sendinput(VALUE self, VALUE value_text) +{ + smokeruby_object * o = value_obj_info(self); + TerminalInterface * t = static_cast<TerminalInterface*>(((KParts::ReadOnlyPart*) o->ptr)->qt_cast("TerminalInterface")); + t->sendInput(StringValuePtr(value_text)); + return self; +} + +#if KDE_VERSION >= 0x030500 +static VALUE +konsole_part_setautostartshell(VALUE self, VALUE enabled) +{ + smokeruby_object * o = value_obj_info(self); + ExtTerminalInterface * t = static_cast<ExtTerminalInterface*>(((KParts::ReadOnlyPart*) o->ptr)->qt_cast("ExtTerminalInterface")); + t->setAutoStartShell(enabled == Qtrue); + return self; +} + +static VALUE +konsole_part_setautodestroy(VALUE self, VALUE enabled) +{ + smokeruby_object * o = value_obj_info(self); + ExtTerminalInterface * t = static_cast<ExtTerminalInterface*>(((KParts::ReadOnlyPart*) o->ptr)->qt_cast("ExtTerminalInterface")); + t->setAutoDestroy(enabled == Qtrue); + return self; +} +#endif + +void +Init_korundum() +{ + if (qt_internal_module != Qnil) { + rb_fatal("require 'Korundum' must not follow require 'Qt'\n"); + return; + } + + set_new_kde(new_kde); +#if KDE_VERSION >= 0x030200 + set_kconfigskeletonitem_immutable(kconfigskeletonitem_immutable); +#endif + set_kde_resolve_classname(kde_resolve_classname); + + // The Qt extension is linked against libsmokeqt.so, but Korundum links against + // libsmokekde.so only. Specifying both a 'require Qt' and a 'require Korundum', + // would give a link error (see the rb_fatal() error above). + // So call the Init_qtruby() initialization function explicitely, not via 'require Qt' + // (Qt.o is linked into libqtruby.so, as well as the Qt.so extension). + Init_qtruby(); + install_handlers(KDE_handlers); + + kde_internal_module = rb_define_module_under(kde_module, "Internal"); + rb_define_singleton_method(kde_module, "dcop_process", (VALUE (*) (...)) dcop_process, 7); + rb_define_singleton_method(kde_module, "dcop_call", (VALUE (*) (...)) dcop_call, -1); + rb_define_singleton_method(kde_module, "dcop_send", (VALUE (*) (...)) dcop_send, -1); + +#if KDE_VERSION >= 0x030200 + rb_define_method(kconfigskeleton_class, "addItem", (VALUE (*) (...)) config_additem, -1); +#endif + + rb_define_method(konsole_part_class, "startProgram", (VALUE (*) (...)) konsole_part_startprogram, 2); + rb_define_method(konsole_part_class, "showShellInDir", (VALUE (*) (...)) konsole_part_showshellindir, 1); + rb_define_method(konsole_part_class, "sendInput", (VALUE (*) (...)) konsole_part_sendinput, 1); +#if KDE_VERSION >= 0x030500 + rb_define_method(konsole_part_class, "setAutoStartShell", (VALUE (*) (...)) konsole_part_setautostartshell, 1); + rb_define_method(konsole_part_class, "autoStartShell=", (VALUE (*) (...)) konsole_part_setautostartshell, 1); + rb_define_method(konsole_part_class, "setAutoDestroy", (VALUE (*) (...)) konsole_part_setautodestroy, 1); + rb_define_method(konsole_part_class, "autoDestroy=", (VALUE (*) (...)) konsole_part_setautodestroy, 1); +#endif + + rb_require("KDE/korundum.rb"); +} + +}; diff --git a/korundum/rubylib/korundum/Makefile.am b/korundum/rubylib/korundum/Makefile.am new file mode 100644 index 00000000..c135f4e9 --- /dev/null +++ b/korundum/rubylib/korundum/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = -I$(top_srcdir)/smoke -I$(top_srcdir)/qtruby/rubylib/qtruby $(all_includes) -I$(RUBY_ARCHDIR) + +rubylibdir = $(RUBY_SITEARCHDIR) +rubylib_LTLIBRARIES = korundum.la +korundum_la_LDFLAGS = -module $(all_libraries) -version-info 0:0:0 +korundum_la_METASOURCES = AUTO +korundum_la_SOURCES = Korundum.cpp kdehandlers.cpp +korundum_la_LIBADD = $(LIB_KDE) $(top_builddir)/smoke/kde/libsmokekde.la $(top_builddir)/qtruby/rubylib/qtruby/libqtrubyinternal.la + +SUBDIRS = lib diff --git a/korundum/rubylib/korundum/configure.in.in b/korundum/rubylib/korundum/configure.in.in new file mode 100644 index 00000000..de265e6d --- /dev/null +++ b/korundum/rubylib/korundum/configure.in.in @@ -0,0 +1,15 @@ +AC_CHECK_PROG(RUBY, ruby, ruby) + +if test -z "$RUBY"; then + DO_NOT_COMPILE="$DO_NOT_COMPILE korundum" +else + AC_MSG_CHECKING(for ruby dirs) + RUBY_ARCHDIR=`ruby -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"archdir"@:>@)'` + RUBY_SITEARCHDIR=`ruby -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitearchdir"@:>@)'` + RUBY_SITEDIR=`ruby -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitelibdir"@:>@)'` + AC_MSG_RESULT([archdir $RUBY_ARCHDIR, sitearchdir $RUBY_SITEARCHDIR, sitedir $RUBY_SITEDIR]) + AC_SUBST(RUBY_ARCHDIR) + AC_SUBST(RUBY_SITEARCHDIR) + AC_SUBST(RUBY_SITEDIR) +fi + diff --git a/korundum/rubylib/korundum/kdehandlers.cpp b/korundum/rubylib/korundum/kdehandlers.cpp new file mode 100644 index 00000000..4d8d5741 --- /dev/null +++ b/korundum/rubylib/korundum/kdehandlers.cpp @@ -0,0 +1,1428 @@ +/*************************************************************************** + kdehandlers.cpp - KDE specific marshallers + ------------------- + begin : Sun Sep 28 2003 + copyright : (C) 2003 by Richard Dale + email : Richard_Dale@tipitina.demon.co.uk + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include <qtruby.h> +#include <smokeruby.h> + +#include <kdeversion.h> +#include <dcopclient.h> +#include <dcopobject.h> +#include <dcopref.h> +#include <qptrlist.h> +#include <ktrader.h> +#include <kservicegroup.h> +#include <kservice.h> +#include <ksycocatype.h> +#include <kmainwindow.h> +#include <kfile.h> +#include <kfileview.h> +#include <kurl.h> +#include <kcmdlineargs.h> +#include <kaction.h> +#include <kdockwidget.h> +#include <kfiletreebranch.h> +#include <kfiletreeviewitem.h> +#include <khtml_part.h> +#include <kparts/plugin.h> +#include <kuserprofile.h> +#include <kaboutdata.h> +#include <karchive.h> +#if KDE_VERSION >= 0x030200 +#include <kconfigskeleton.h> +#include <kplugininfo.h> +#include <kmountpoint.h> +#endif +#include <kio/jobclasses.h> +#include <dom/dom_node.h> +#include <dom/dom_element.h> +#include <dom/dom_string.h> +#include <dom/html_element.h> + +extern "C" { +extern VALUE set_obj_info(const char * className, smokeruby_object * o); +}; + +extern bool isDerivedFromByName(Smoke *smoke, const char *className, const char *baseClassName); + +extern "C" { +/* + * Given an approximate classname and a kde instance, try to improve the resolution of the name + * by using the various KDE rtti mechanisms + */ +const char * +kde_resolve_classname(Smoke * smoke, int classId, void * ptr) +{ + if (isDerivedFromByName(smoke, smoke->classes[classId].className, "KArchiveEntry")) { + KArchiveEntry * entry = (KArchiveEntry *) smoke->cast(ptr, classId, smoke->idClass("KArchiveEntry")); + if (entry->isDirectory()) { + return "KDE::ArchiveDirectory"; + } else { + return "KDE::ArchiveFile"; + } + } else if (strcmp(smoke->classes[classId].className, "DOM::Node") == 0) { + DOM::Node * node = (DOM::Node *) smoke->cast(ptr, classId, smoke->idClass("DOM::Node")); + switch (node->nodeType()) { + case DOM::Node::ELEMENT_NODE: + if (((DOM::Element*)node)->isHTMLElement()) { + return "DOM::HTMLElement"; + } else { + return "DOM::Element"; + } + case DOM::Node::ATTRIBUTE_NODE: + return "DOM::Attr"; + case DOM::Node::TEXT_NODE: + return "DOM::Text"; + case DOM::Node::CDATA_SECTION_NODE: + return "DOM::CDATASection"; + case DOM::Node::ENTITY_REFERENCE_NODE: + return "DOM::EntityReference"; + case DOM::Node::ENTITY_NODE: + return "DOM::Entity"; + case DOM::Node::PROCESSING_INSTRUCTION_NODE: + return "DOM::ProcessingInstruction"; + case DOM::Node::COMMENT_NODE: + return "DOM::Comment"; + case DOM::Node::DOCUMENT_NODE: + return "DOM::Document"; + case DOM::Node::DOCUMENT_TYPE_NODE: + return "DOM::DocumentType"; + case DOM::Node::DOCUMENT_FRAGMENT_NODE: + return "DOM::DocumentFragment"; + case DOM::Node::NOTATION_NODE: + return "DOM::Notation"; + } + } + + return smoke->binding->className(classId); +} + +}; + +void marshall_QCStringList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + VALUE list = *(m->var()); + if (TYPE(list) != T_ARRAY) { + m->item().s_voidp = 0; + break; + } + + int count = RARRAY(list)->len; + QCStringList *stringlist = new QCStringList; + + for(long i = 0; i < count; i++) { + VALUE item = rb_ary_entry(list, i); + if(TYPE(item) != T_STRING) { + stringlist->append(QCString()); + continue; + } + stringlist->append(QCString(StringValuePtr(item), RSTRING(item)->len + 1)); + } + + m->item().s_voidp = stringlist; + m->next(); + + if(m->cleanup()) { + rb_ary_clear(list); + for(QCStringList::Iterator it = stringlist->begin(); it != stringlist->end(); ++it) + rb_ary_push(list, rb_str_new2(static_cast<const char *>(*it))); + delete stringlist; + } + break; + } + case Marshall::ToVALUE: + { + QCStringList *stringlist = static_cast<QCStringList *>(m->item().s_voidp); + if(!stringlist) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + for(QCStringList::Iterator it = stringlist->begin(); it != stringlist->end(); ++it) { + VALUE rv = rb_str_new2(static_cast<const char *>((*it))); + rb_ary_push(av, rv); + } + + if(m->cleanup()) + delete stringlist; + + *(m->var()) = av; + } + break; + default: + m->unsupported(); + break; + } +} + +#if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2 +# define BREAKPOINT { __asm__ __volatile__ ("int $03"); } +#else +# define BREAKPOINT { fprintf(stderr, "hit ctrl-c\n"); int b = 0; while (b == 0) { ; } } +#endif + +void marshall_KCmdLineOptions(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + VALUE optionslist = *(m->var()); + if (optionslist == Qnil + || TYPE(optionslist) != T_ARRAY + || RARRAY(optionslist)->len == 0 ) + { + m->item().s_voidp = 0; + break; + } + + // Allocate 'length + 1' entries, to include an all NULLs last entry + KCmdLineOptions *cmdLineOptions = (KCmdLineOptions *) calloc( RARRAY(optionslist)->len + 1, + sizeof(struct KCmdLineOptions) ); + + VALUE options; + long i; + for(i = 0; i < RARRAY(optionslist)->len; i++) { + options = rb_ary_entry(optionslist, i); + VALUE temp = rb_ary_entry(options, 0); + cmdLineOptions[i].name = StringValuePtr(temp); + temp = rb_ary_entry(options, 1); + cmdLineOptions[i].description = StringValuePtr(temp); + temp = rb_ary_entry(options, 2); + cmdLineOptions[i].def = StringValuePtr(temp); + } + cmdLineOptions[i].name = 0; + cmdLineOptions[i].description = 0; + cmdLineOptions[i].def = 0; + + + m->item().s_voidp = cmdLineOptions; + m->next(); + /* + if(m->cleanup()) { + rb_ary_clear(optionslist); + for(i = 0; cmdLineOptions[i].name; i++) + options = rb_ary_new(); + rb_ary_push(options, rb_str_new2(cmdLineOptions[i].name)); + rb_ary_push(options, rb_str_new2(cmdLineOptions[i].description)); + rb_ary_push(options, rb_str_new2(cmdLineOptions[i].def)); + rb_ary_push(optionslist, options); + } + */ + } + break; + case Marshall::ToVALUE: + { + } + break; + default: + m->unsupported(); + break; + } +} + +void marshall_WIdList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + VALUE list = *(m->var()); + if (TYPE(list) != T_ARRAY) { + m->item().s_voidp = 0; + break; + } + int count = RARRAY(list)->len; + QValueList<WId> *valuelist = new QValueList<WId>; + long i; + for(i = 0; i < count; i++) { + VALUE item = rb_ary_entry(list, i); + if(TYPE(item) != T_FIXNUM && TYPE(item) != T_BIGNUM) { + valuelist->append(0); + continue; + } + valuelist->append(NUM2LONG(item)); + } + + m->item().s_voidp = valuelist; + m->next(); + + if (!m->type().isConst()) { + rb_ary_clear(list); + for(QValueListIterator<WId> it = valuelist->begin(); + it != valuelist->end(); + ++it) + rb_ary_push(list, LONG2NUM((int)*it)); + } + + if (m->cleanup()) { + delete valuelist; + } + } + break; + case Marshall::ToVALUE: + { + QValueList<WId> *valuelist = (QValueList<WId>*)m->item().s_voidp; + if(!valuelist) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + for(QValueListIterator<WId> it = valuelist->begin(); + it != valuelist->end(); + ++it) + rb_ary_push(av, LONG2NUM(*it)); + + *(m->var()) = av; + + if(m->cleanup()) + delete valuelist; + } + break; + default: + m->unsupported(); + break; + } +} + +void marshall_KMimeTypeList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + } + break; + case Marshall::ToVALUE: + { + KMimeType::List *offerList = (KMimeType::List*)m->item().s_voidp; + if(!offerList) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + for(KMimeType::List::Iterator it = offerList->begin(); + it != offerList->end(); + ++it) { + KMimeType * item = new KMimeType (*(KMimeType*)((KMimeType::Ptr)(*it)).data()); + + VALUE obj = getPointerObject(item); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = m->smoke()->idClass("KMimeType"); + o->ptr = item; + o->allocated = true; + obj = set_obj_info("KDE::MimeType", o); + } + rb_ary_push(av, obj); + } + + *(m->var()) = av; + + if(m->cleanup()) + delete offerList; + } + break; + default: + m->unsupported(); + break; + } +} + +void marshall_KMimeTypePtr(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + } + break; + case Marshall::ToVALUE: + { + KMimeType::Ptr ptr(*(KMimeType::Ptr*)m->item().s_voidp); + if(ptr == 0) { + *(m->var()) = Qnil; + break; + } + KMimeType * mimeType = new KMimeType(*(KMimeType*)ptr); + + VALUE obj = getPointerObject(mimeType); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = m->smoke()->idClass("KMimeType"); + o->ptr = mimeType; + o->allocated = true; + obj = set_obj_info("KDE::MimeType", o); + } + + *(m->var()) = obj; + + if(m->cleanup()) + ; + } + break; + default: + m->unsupported(); + break; + } +} + +void marshall_KServicePtr(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + } + break; + case Marshall::ToVALUE: + { + KSharedPtr<KService> *ptr = new KSharedPtr<KService>(*(KSharedPtr<KService>*)m->item().s_voidp); + if(ptr == 0) { + *(m->var()) = Qnil; + break; + } + KService * service = ptr->data(); + + VALUE obj = getPointerObject(service); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = m->smoke()->idClass("KService"); + o->ptr = service; + o->allocated = true; + obj = set_obj_info("KDE::Service", o); + } + + *(m->var()) = obj; + + if(m->cleanup()) + ; + } + break; + default: + m->unsupported(); + break; + } +} + +void marshall_KServiceList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + } + break; + case Marshall::ToVALUE: + { + KService::List *offerList = (KService::List*)m->item().s_voidp; + if(!offerList) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + for(KService::List::Iterator it = offerList->begin(); + it != offerList->end(); + ++it) { + KSharedPtr<KService> *ptr = new KSharedPtr<KService>(*it); + KService * currentOffer = ptr->data(); + + VALUE obj = getPointerObject(currentOffer); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = m->smoke()->idClass("KService"); + o->ptr = currentOffer; + o->allocated = false; + obj = set_obj_info("KDE::Service", o); + } + rb_ary_push(av, obj); + } + + *(m->var()) = av; + + if(m->cleanup()) + delete offerList; + } + break; + default: + m->unsupported(); + break; + } +} + +void marshall_KServiceGroupPtr(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + } + break; + case Marshall::ToVALUE: + { + KServiceGroup::Ptr ptr(*(KServiceGroup::Ptr*)m->item().s_voidp); + if(ptr == 0) { + *(m->var()) = Qnil; + break; + } + KServiceGroup * serviceGroup = new KServiceGroup(*(KServiceGroup*)ptr); + + VALUE obj = getPointerObject(serviceGroup); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = m->smoke()->idClass("KServiceGroup"); + o->ptr = serviceGroup; + o->allocated = true; + obj = set_obj_info("KDE::ServiceGroup", o); + } + + *(m->var()) = obj; + + if(m->cleanup()) + ; + } + break; + default: + m->unsupported(); + break; + } +} + +void marshall_KServiceTypeList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + } + break; + case Marshall::ToVALUE: + { + KServiceType::List *offerList = (KServiceType::List*)m->item().s_voidp; + if(!offerList) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + for(KServiceType::List::Iterator it = offerList->begin(); + it != offerList->end(); + ++it) { + KServiceType * currentOffer = new KServiceType(*((KServiceType*)*it)); + + VALUE obj = getPointerObject(currentOffer); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = m->smoke()->idClass("KServiceType"); + o->ptr = currentOffer; + o->allocated = true; + obj = set_obj_info("KDE::ServiceType", o); + } + rb_ary_push(av, obj); + } + + *(m->var()) = av; + + if(m->cleanup()) + delete offerList; + } + break; + default: + m->unsupported(); + break; + } +} + +void marshall_KServiceGroupList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + } + break; + case Marshall::ToVALUE: + { + KServiceGroup::List *offerList = (KServiceGroup::List*)m->item().s_voidp; + if(!offerList) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + for(KServiceGroup::List::ConstIterator it = offerList->begin(); + it != offerList->end(); + ++it) { + KSycocaEntry *p = (*it); + VALUE obj = Qnil; + if (p->isType(KST_KService)) { + KService *s = static_cast<KService *>(p); + obj = getPointerObject(s); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = m->smoke()->idClass("KService"); + o->ptr = s; + o->allocated = true; + obj = set_obj_info("KDE::Service", o); + } + } else if (p->isType(KST_KServiceGroup)) { + KServiceGroup *g = static_cast<KServiceGroup *>(p); + obj = getPointerObject(g); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = m->smoke()->idClass("KServiceGroup"); + o->ptr = g; + o->allocated = true; + obj = set_obj_info("KDE::ServiceGroup", o); + } + } + + rb_ary_push(av, obj); + } + + *(m->var()) = av; + + if(m->cleanup()) + delete offerList; + } + break; + default: + m->unsupported(); + break; + } +} + +#if KDE_VERSION >= 0x030200 +void marshall_KMountPointList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + } + break; + case Marshall::ToVALUE: + { + KMountPoint::List *list = (KMountPoint::List*)m->item().s_voidp; + if(!list) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + for(KMountPoint::List::Iterator it = list->begin(); + it != list->end(); + ++it) { + KMountPoint * item = new KMountPoint(*((KMountPoint*)*it)); + + VALUE obj = getPointerObject(item); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = m->smoke()->idClass("KMountPoint"); + o->ptr = item; + o->allocated = true; + obj = set_obj_info("KDE::MountPoint", o); + } + rb_ary_push(av, obj); + } + + *(m->var()) = av; + + if(m->cleanup()) + delete list; + } + break; + default: + m->unsupported(); + break; + } +} + +void marshall_KPluginInfoList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + } + break; + case Marshall::ToVALUE: + { + KPluginInfo::List *valuelist = (KPluginInfo::List*)m->item().s_voidp; + if(!valuelist) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + int ix = m->smoke()->idClass("KPluginInfo"); + const char * className = m->smoke()->binding->className(ix); + + for(KPluginInfo::List::Iterator it = valuelist->begin(); + it != valuelist->end(); + ++it) { + void *p = (*it); + + if(m->item().s_voidp == 0) { + *(m->var()) = Qnil; + break; + } + + VALUE obj = getPointerObject(p); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = o->smoke->idClass("KPluginInfo"); + o->ptr = p; + o->allocated = false; + obj = set_obj_info(className, o); + } + rb_ary_push(av, obj); + } + + if(m->cleanup()) + delete valuelist; + else + *(m->var()) = av; + } + break; + default: + m->unsupported(); + break; + } +} +#endif + +void marshall_KActionPtrList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + } + break; + case Marshall::ToVALUE: + { + KActionPtrList *valuelist = (KActionPtrList*)m->item().s_voidp; + if (!valuelist) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + int ix = m->smoke()->idClass("KAction"); + const char * className = m->smoke()->binding->className(ix); + + for ( KActionPtrList::Iterator it = valuelist->begin(); + it != valuelist->end(); + ++it ) + { + void *p = (*it); + + if (m->item().s_voidp == 0) { + *(m->var()) = Qnil; + break; + } + + VALUE obj = getPointerObject(p); + if (obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = o->smoke->idClass("KAction"); + o->ptr = p; + o->allocated = false; + obj = set_obj_info(className, o); + } + rb_ary_push(av, obj); + } + + if (m->cleanup()) + delete valuelist; + else + *(m->var()) = av; + } + break; + default: + m->unsupported(); + break; + } +} + +void marshall_KTraderOfferList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + } + break; + case Marshall::ToVALUE: + { + KTrader::OfferList *offerList = (KTrader::OfferList*)m->item().s_voidp; + if(!offerList) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + for(KTrader::OfferList::Iterator it = offerList->begin(); + it != offerList->end(); + ++it) { + KSharedPtr<KService> *ptr = new KSharedPtr<KService>(*it); + KService * currentOffer = ptr->data(); + + VALUE obj = getPointerObject(currentOffer); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = m->smoke()->idClass("KService"); + o->ptr = currentOffer; + o->allocated = false; + obj = set_obj_info("KDE::Service", o); + } + rb_ary_push(av, obj); + } + + *(m->var()) = av; + + if(m->cleanup()) + delete offerList; + } + break; + default: + m->unsupported(); + break; + } +} + +void marshall_KURLList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + VALUE list = *(m->var()); + if (TYPE(list) != T_ARRAY) { + m->item().s_voidp = 0; + break; + } + int count = RARRAY(list)->len; + KURL::List *kurllist = new KURL::List; + long i; + for(i = 0; i < count; i++) { + VALUE item = rb_ary_entry(list, i); + // TODO do type checking! + smokeruby_object *o = value_obj_info(item); + if(!o || !o->ptr) + continue; + void *ptr = o->ptr; + ptr = o->smoke->cast( + ptr, // pointer + o->classId, // from + o->smoke->idClass("KURL") // to + ); + kurllist->append((KURL&)*(KURL*)ptr); + } + + m->item().s_voidp = kurllist; + m->next(); + + rb_ary_clear(list); + int ix = m->smoke()->idClass("KURL"); + const char * className = m->smoke()->binding->className(ix); + for ( KURL::List::Iterator it = kurllist->begin(); + it != kurllist->end(); + ++it ) + { + void *p = new KURL(*it); + VALUE obj = getPointerObject(p); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = ix; + o->ptr = p; + o->allocated = true; + obj = set_obj_info(className, o); + } + rb_ary_push(list, obj); + } + + if(m->cleanup()) { + delete kurllist; + } + } + break; + case Marshall::ToVALUE: + { + KURL::List *kurllist = (KURL::List*)m->item().s_voidp; + if(!kurllist) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + int ix = m->smoke()->idClass("KURL"); + const char * className = m->smoke()->binding->className(ix); + + for(KURL::List::Iterator it = kurllist->begin(); + it != kurllist->end(); + ++it) { + void *p = new KURL(*it); + + VALUE obj = getPointerObject(p); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = ix; + o->ptr = p; + o->allocated = true; + obj = set_obj_info(className, o); + } + rb_ary_push(av, obj); + } + + *(m->var()) = av; + + if(m->cleanup()) { + delete kurllist; + } + } + break; + default: + m->unsupported(); + break; + } +} + +void marshall_UDSEntryList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + VALUE list = *(m->var()); + if (TYPE(list) != T_ARRAY) { + m->item().s_voidp = 0; + break; + } + + KIO::UDSEntryList *cpplist = new KIO::UDSEntryList; + + for(long i = 0; i < RARRAY(list)->len; i++) { + VALUE item = rb_ary_entry(list, i); + KIO::UDSEntry *cppsublist = new KIO::UDSEntry; + + for (int j = 0; j < RARRAY(item)->len; j++) { + VALUE subitem = rb_ary_entry(item, j); + smokeruby_object *o = value_obj_info(subitem); + if(!o || !o->ptr) + continue; + void *ptr = o->ptr; + ptr = o->smoke->cast(ptr, o->classId, o->smoke->idClass("KIO::UDSAtom")); + cppsublist->append(*(KIO::UDSAtom*)ptr); + } + + cpplist->append(*cppsublist); + } + + m->item().s_voidp = cpplist; + m->next(); + } + break; + case Marshall::ToVALUE: + { + KIO::UDSEntryList *valuelist = (KIO::UDSEntryList*)m->item().s_voidp; + if (!valuelist) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + int ix = m->smoke()->idClass("KIO::UDSAtom"); + + for ( KIO::UDSEntryList::Iterator it = valuelist->begin(); + it != valuelist->end(); + ++it ) + { + KIO::UDSEntry * udsentry = &(*it); + VALUE subav = rb_ary_new(); + + for ( KIO::UDSEntry::Iterator it = udsentry->begin(); + it != udsentry->end(); + ++it ) + { + void * p = &(*it); + VALUE obj = getPointerObject(p); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = ix; + o->ptr = p; + o->allocated = false; + obj = set_obj_info("KIO::UDSAtom", o); + } + + rb_ary_push(subav, obj); + } + + rb_ary_push(av, subav); + } + + *(m->var()) = av; + } + break; + default: + m->unsupported(); + break; + } +} + + +// Some time saving magic from Alex Kellett here.. +template <class Item, class ItemList, const char *ItemSTR > +void marshall_ItemList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + VALUE list = *(m->var()); + if (TYPE(list) != T_ARRAY) { + m->item().s_voidp = 0; + break; + } + int count = RARRAY(list)->len; + ItemList *cpplist = new ItemList; + long i; + for(i = 0; i < count; i++) { + VALUE item = rb_ary_entry(list, i); + // TODO do type checking! + smokeruby_object *o = value_obj_info(item); + if(!o || !o->ptr) + continue; + void *ptr = o->ptr; + ptr = o->smoke->cast( + ptr, // pointer + o->classId, // from + o->smoke->idClass(ItemSTR) // to + ); + cpplist->append((Item*)ptr); + } + + m->item().s_voidp = cpplist; + m->next(); + + if(m->cleanup()) { + rb_ary_clear(list); + for( Item * it = cpplist->first(); + it != 0; + it = cpplist->next()) { + VALUE obj = getPointerObject((void*)it); + rb_ary_push(list, obj); + } + delete cpplist; + } + } + break; + case Marshall::ToVALUE: + { + ItemList *valuelist = (ItemList*)m->item().s_voidp; + if(!valuelist) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + int ix = m->smoke()->idClass(ItemSTR); + const char * className = m->smoke()->binding->className(ix); + + for(Item * it = valuelist->first(); + it != 0; + it = valuelist->next()) { + void *p = it; + + if(m->item().s_voidp == 0) { + *(m->var()) = Qnil; + break; + } + + VALUE obj = getPointerObject(p); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = o->smoke->idClass(ItemSTR); + o->ptr = p; + o->allocated = false; + obj = set_obj_info(className, o); + } + rb_ary_push(av, obj); + } + + if(m->cleanup()) + delete valuelist; + else + *(m->var()) = av; + } + break; + default: + m->unsupported(); + break; + } +} + +#define DEF_LIST_MARSHALLER(ListIdent,ItemList,Item) namespace { char ListIdent##STR[] = #Item; }; \ + Marshall::HandlerFn marshall_##ListIdent = marshall_ItemList<Item,ItemList,ListIdent##STR>; + +DEF_LIST_MARSHALLER( KFileItemList, QPtrList<KFileItem>, KFileItem ) +DEF_LIST_MARSHALLER( KMainWindowList, QPtrList<KMainWindow>, KMainWindow ) +DEF_LIST_MARSHALLER( KActionList, QPtrList<KAction>, KAction ) +DEF_LIST_MARSHALLER( DCOPObjectList, QPtrList<DCOPObject>, DCOPObject ) +DEF_LIST_MARSHALLER( KDockWidgetList, QPtrList<KDockWidget>, KDockWidget ) +DEF_LIST_MARSHALLER( KFileTreeBranch, QPtrList<KFileTreeBranch>, KFileTreeBranch ) +DEF_LIST_MARSHALLER( KFileTreeViewItem, QPtrList<KFileTreeViewItem>, KFileTreeViewItem ) +DEF_LIST_MARSHALLER( KPartList, QPtrList<KParts::Part>, KParts::Part ) +DEF_LIST_MARSHALLER( KPartPluginList, QPtrList<KParts::Plugin>, KParts::Plugin ) +DEF_LIST_MARSHALLER( KPartReadOnlyPartList, QPtrList<KParts::ReadOnlyPart>, KParts::ReadOnlyPart ) +DEF_LIST_MARSHALLER( KServiceTypeProfileList, QPtrList<KServiceTypeProfile>, KServiceTypeProfile ) + +template <class Item, class ItemList, class ItemListIterator, const char *ItemSTR > +void marshall_ValueItemList(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + VALUE list = *(m->var()); + if (TYPE(list) != T_ARRAY) { + m->item().s_voidp = 0; + break; + } + int count = RARRAY(list)->len; + ItemList *cpplist = new ItemList; + long i; + for(i = 0; i < count; i++) { + VALUE item = rb_ary_entry(list, i); + // TODO do type checking! + smokeruby_object *o = value_obj_info(item); + if(!o || !o->ptr) + continue; + void *ptr = o->ptr; + ptr = o->smoke->cast( + ptr, // pointer + o->classId, // from + o->smoke->idClass(ItemSTR) // to + ); + cpplist->append(*(Item*)ptr); + } + + m->item().s_voidp = cpplist; + m->next(); + + if(m->cleanup()) { + rb_ary_clear(list); + for(ItemListIterator it = cpplist->begin(); + it != cpplist->end(); + ++it) { + VALUE obj = getPointerObject((void*)&(*it)); + rb_ary_push(list, obj); + } + delete cpplist; + } + } + break; + case Marshall::ToVALUE: + { + ItemList *valuelist = (ItemList*)m->item().s_voidp; + if(!valuelist) { + *(m->var()) = Qnil; + break; + } + + VALUE av = rb_ary_new(); + + int ix = m->smoke()->idClass(ItemSTR); + const char * className = m->smoke()->binding->className(ix); + + for(ItemListIterator it = valuelist->begin(); + it != valuelist->end(); + ++it) { + void *p = &(*it); + + if(m->item().s_voidp == 0) { + *(m->var()) = Qnil; + break; + } + + VALUE obj = getPointerObject(p); + if(obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->smoke = m->smoke(); + o->classId = o->smoke->idClass(ItemSTR); + o->ptr = p; + o->allocated = false; + obj = set_obj_info(className, o); + } + rb_ary_push(av, obj); + } + + if(m->cleanup()) + delete valuelist; + else + *(m->var()) = av; + } + break; + default: + m->unsupported(); + break; + } +} + +#define DEF_VALUELIST_MARSHALLER(ListIdent,ItemList,Item,Itr) namespace { char ListIdent##STR[] = #Item; }; \ + Marshall::HandlerFn marshall_##ListIdent = marshall_ValueItemList<Item,ItemList,Itr,ListIdent##STR>; + +#if KDE_VERSION >= 0x030200 +DEF_VALUELIST_MARSHALLER( ChoicesList, QValueList<KConfigSkeleton::ItemEnum::Choice>, KConfigSkeleton::ItemEnum::Choice, QValueList<KConfigSkeleton::ItemEnum::Choice>::Iterator ) +#endif +DEF_VALUELIST_MARSHALLER( KAboutPersonList, QValueList<KAboutPerson>, KAboutPerson, QValueList<KAboutPerson>::Iterator ) +DEF_VALUELIST_MARSHALLER( KAboutTranslatorList, QValueList<KAboutTranslator>, KAboutTranslator, QValueList<KAboutTranslator>::Iterator ) +DEF_VALUELIST_MARSHALLER( KIOCopyInfoList, QValueList<KIO::CopyInfo>, KIO::CopyInfo, QValueList<KIO::CopyInfo>::Iterator ) +DEF_VALUELIST_MARSHALLER( KServiceOfferList, QValueList<KServiceOffer>, KServiceOffer, QValueList<KServiceOffer>::Iterator ) +DEF_VALUELIST_MARSHALLER( UDSEntry, QValueList<KIO::UDSAtom>, KIO::UDSAtom, QValueList<KIO::UDSAtom>::Iterator ) + +template <class Key, class Value, class ItemMapIterator, const char *KeySTR, const char *ValueSTR > +void marshall_Map(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + VALUE hash = *(m->var()); + if (TYPE(hash) != T_HASH) { + m->item().s_voidp = 0; + break; + } + + QMap<Key,Value> * map = new QMap<Key,Value>; + + // Convert the ruby hash to an array of key/value arrays + VALUE temp = rb_funcall(hash, rb_intern("to_a"), 0); + + for (long i = 0; i < RARRAY(temp)->len; i++) { + VALUE key = rb_ary_entry(rb_ary_entry(temp, i), 0); + VALUE value = rb_ary_entry(rb_ary_entry(temp, i), 1); + + smokeruby_object *o = value_obj_info(key); + if( !o || !o->ptr) + continue; + void * key_ptr = o->ptr; + key_ptr = o->smoke->cast(key_ptr, o->classId, o->smoke->idClass(KeySTR)); + + o = value_obj_info(value); + if( !o || !o->ptr) + continue; + void * val_ptr = o->ptr; + val_ptr = o->smoke->cast(val_ptr, o->classId, o->smoke->idClass(ValueSTR)); + + (*map)[(Key)*(Key*)key_ptr] = (Value)*(Value*)val_ptr; + } + + m->item().s_voidp = map; + m->next(); + + if(m->cleanup()) + delete map; + } + break; + case Marshall::ToVALUE: + { + QMap<Key,Value> *map = (QMap<Key,Value>*)m->item().s_voidp; + if(!map) { + *(m->var()) = Qnil; + break; + } + + VALUE hv = rb_hash_new(); + + int key_ix = m->smoke()->idClass(KeySTR); + const char * key_className = m->smoke()->binding->className(key_ix); + + int val_ix = m->smoke()->idClass(ValueSTR); + const char * val_className = m->smoke()->binding->className(val_ix); + + ItemMapIterator it; + for (it = map->begin(); it != map->end(); ++it) { + void *key_p = new Key(it.key()); + VALUE key_obj = getPointerObject(key_p); + smokeruby_object * o; + + if (key_obj == Qnil) { + o = ALLOC(smokeruby_object); + o->classId = m->smoke()->idClass(KeySTR); + o->smoke = m->smoke(); + o->ptr = key_p; + o->allocated = true; + key_obj = set_obj_info(key_className, o); + } + + void *val_p = new Value(it.data()); + VALUE value_obj = getPointerObject(val_p); + + if (value_obj == Qnil) { + o = ALLOC(smokeruby_object); + o->classId = m->smoke()->idClass(ValueSTR); + o->smoke = m->smoke(); + o->ptr = val_p; + o->allocated = true; + value_obj = set_obj_info(val_className, o); + } + + rb_hash_aset(hv, key_obj, value_obj); + } + + *(m->var()) = hv; + m->next(); + + if(m->cleanup()) + delete map; + } + break; + default: + m->unsupported(); + break; + } +} + +#define DEF_MAP_MARSHALLER(MapIdent,Key,Value) namespace { char KeyIdent##STR[] = #Key; char ValueIdent##STR[] = #Value; }; \ + Marshall::HandlerFn marshall_##MapIdent = marshall_Map<Key, Value,QMap<Key,Value>::Iterator,KeyIdent##STR, ValueIdent##STR>; + +DEF_MAP_MARSHALLER( QMapKEntryKeyKEntry, KEntryKey, KEntry ) + +void marshall_QMapQCStringDCOPRef(Marshall *m) { + switch(m->action()) { + case Marshall::FromVALUE: + { + VALUE hash = *(m->var()); + if (TYPE(hash) != T_HASH) { + m->item().s_voidp = 0; + break; + } + + QMap<QCString,DCOPRef> * map = new QMap<QCString,DCOPRef>; + + // Convert the ruby hash to an array of key/value arrays + VALUE temp = rb_funcall(hash, rb_intern("to_a"), 0); + + for (long i = 0; i < RARRAY(temp)->len; i++) { + VALUE key = rb_ary_entry(rb_ary_entry(temp, i), 0); + VALUE value = rb_ary_entry(rb_ary_entry(temp, i), 1); + + smokeruby_object *o = value_obj_info(value); + if( !o || !o->ptr) + continue; + void * ptr = o->ptr; + ptr = o->smoke->cast(ptr, o->classId, o->smoke->idClass("DCOPRef")); + + (*map)[QCString(StringValuePtr(key))] = (DCOPRef)*(DCOPRef*)ptr; + } + + m->item().s_voidp = map; + m->next(); + + if(m->cleanup()) + delete map; + } + break; + case Marshall::ToVALUE: + { + QMap<QCString,DCOPRef> *map = (QMap<QCString,DCOPRef>*)m->item().s_voidp; + if(!map) { + *(m->var()) = Qnil; + break; + } + + VALUE hv = rb_hash_new(); + + QMap<QCString,DCOPRef>::Iterator it; + for (it = map->begin(); it != map->end(); ++it) { + void *p = new DCOPRef(it.data()); + VALUE obj = getPointerObject(p); + + if (obj == Qnil) { + smokeruby_object * o = ALLOC(smokeruby_object); + o->classId = m->smoke()->idClass("DCOPRef"); + o->smoke = m->smoke(); + o->ptr = p; + o->allocated = true; + obj = set_obj_info("KDE::DCOPRef", o); + } + + rb_hash_aset(hv, rb_str_new2((const char *) it.key()), obj); + } + + *(m->var()) = hv; + m->next(); + + if(m->cleanup()) + delete map; + } + break; + default: + m->unsupported(); + break; + } +} + +TypeHandler KDE_handlers[] = { + { "QCStringList", marshall_QCStringList }, + { "KCmdLineOptions*", marshall_KCmdLineOptions }, + { "KActionPtrList", marshall_KActionList }, + { "QPtrList<KAction>", marshall_KActionList }, + { "QPtrList<KAction>&", marshall_KActionList }, + { "KMimeType::List", marshall_KMimeTypeList }, + { "KMimeType::Ptr", marshall_KMimeTypePtr }, + { "KService::Ptr", marshall_KServicePtr }, + { "KService::List", marshall_KServiceList }, + { "KServiceGroup::List", marshall_KServiceGroupList }, + { "KServiceGroup::Ptr", marshall_KServiceGroupPtr }, +#if KDE_VERSION >= 0x030200 + { "KMountPoint::List", marshall_KMountPointList }, + { "KPluginInfo::List", marshall_KPluginInfoList }, + { "QValueList<KConfigSkeleton::ItemEnum::Choice>", marshall_ChoicesList }, + { "QValueList<KConfigSkeleton::ItemEnum::Choice>&", marshall_ChoicesList }, +#endif + { "KServiceType::List", marshall_KServiceTypeList }, + { "KTrader::OfferList", marshall_KTraderOfferList }, + { "KURL::List", marshall_KURLList }, + { "KURL::List&", marshall_KURLList }, + { "KFileItemList", marshall_KFileItemList }, + { "KFileItemList*", marshall_KFileItemList }, + { "QPtrList<KMainWindow>*", marshall_KMainWindowList }, + { "QPtrList<DCOPObject>", marshall_DCOPObjectList }, + { "QPtrList<KDockWidget>&", marshall_KDockWidgetList }, + { "QPtrList<KDockWidget>*", marshall_KDockWidgetList }, + { "KFileTreeBranchList&", marshall_KFileTreeBranch }, + { "KFileTreeViewItemList&", marshall_KFileTreeViewItem }, + { "QPtrList<KParts::Part>*", marshall_KPartList }, + { "QPtrList<KParts::Plugin>", marshall_KPartPluginList }, + { "QPtrList<KParts::ReadOnlyPart>", marshall_KPartReadOnlyPartList }, + { "QPtrList<KServiceTypeProfile>&", marshall_KServiceTypeProfileList }, + { "QValueList<KAction*>", marshall_KActionPtrList }, + { "KActionPtrList", marshall_KActionPtrList }, + { "QValueList<KAboutPerson>", marshall_KAboutPersonList }, + { "QValueList<KAboutTranslator>", marshall_KAboutTranslatorList }, + { "QValueList<KIO::CopyInfo>&", marshall_KIOCopyInfoList }, + { "KIO::UDSEntry&", marshall_UDSEntry }, + { "KIO::UDSEntryList&", marshall_UDSEntryList }, + { "KServiceTypeProfile::OfferList", marshall_KServiceOfferList }, + { "KEntryMap", marshall_QMapKEntryKeyKEntry }, + { "KEntryMap&", marshall_QMapKEntryKeyKEntry }, + { "KEntryMap*", marshall_QMapKEntryKeyKEntry }, + { "QMap<QCString,DCOPRef>", marshall_QMapQCStringDCOPRef }, + { "QValueList<WId>&", marshall_WIdList }, + { "QValueList<WId>", marshall_WIdList }, + { 0, 0 } +}; diff --git a/korundum/rubylib/korundum/lib/KDE/Korundum.rb b/korundum/rubylib/korundum/lib/KDE/Korundum.rb new file mode 100644 index 00000000..101d3e30 --- /dev/null +++ b/korundum/rubylib/korundum/lib/KDE/Korundum.rb @@ -0,0 +1 @@ +require 'korundum' diff --git a/korundum/rubylib/korundum/lib/KDE/Makefile.am b/korundum/rubylib/korundum/lib/KDE/Makefile.am new file mode 100644 index 00000000..3f7b0c53 --- /dev/null +++ b/korundum/rubylib/korundum/lib/KDE/Makefile.am @@ -0,0 +1,5 @@ +kderubylibdir = $(RUBY_SITEDIR)/KDE +kderubylib_DATA = korundum.rb + +rubylibdir = $(RUBY_SITEDIR) +rubylib_DATA = Korundum.rb diff --git a/korundum/rubylib/korundum/lib/KDE/korundum.rb b/korundum/rubylib/korundum/lib/KDE/korundum.rb new file mode 100644 index 00000000..40c87260 --- /dev/null +++ b/korundum/rubylib/korundum/lib/KDE/korundum.rb @@ -0,0 +1,1391 @@ +=begin +/*************************************************************************** + Korundum.rb - KDE specific ruby runtime, dcop etc. + ------------------- + begin : Sun Sep 28 2003 + copyright : (C) 2003-2006 by Richard Dale + email : Richard_Dale@tipitina.demon.co.uk + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +=end + +module KDE + DCOPMeta = {} + + # An entry for each dcop signal or slot + # Example + # int foobar(QString,bool) + # :name is 'foobar' + # :full_name is 'foobar(QString,bool)' + # :arg_types is 'QString,bool' + # :reply_type is 'int' + DCOPMember = Struct.new :name, :full_name, :arg_types, :reply_type + + # If the class with the 'k_dcop' slots declaration is not a subclass of DCOPObject, + # then 'dcop_object' holds a instance of DCOPObject for the class to use as a + # proxy. For subclasses of DCOPObject, 'dcop_object' will always be nil + class DCOPMetaInfo + attr_accessor :dcop_object, :changed + attr_reader :k_dcop_signals, :k_dcop + + def initialize(aClass) + DCOPMeta[aClass.name] = self + @dcop_object = nil + @k_dcop_signals = {} + @k_dcop = {} + @changed = false + end + + def add_signals(signal_list) + signal_list.each do |signal| + signal = DCOPClient.normalizeFunctionSignature(signal) + if signal =~ /^([\w,<>:]*)\s+([^\s]*)\((.*)\)/ + args = DCOPClient.normalizeFunctionSignature($3) + @k_dcop_signals[$2] = DCOPMember.new($2, $2 + "(" + args + ")", args, $1) + else + qWarning( "Invalid DCOP signal format: '#{signal}'" ) + end + end + end + + def add_slots(slot_list) + slot_list.each do |slot| + if slot =~ /^([\w,<>:]*)\s+([^\s]*)\((.*)\)/ + args = DCOPClient.normalizeFunctionSignature($3) + @k_dcop[$2] = DCOPMember.new($2, $1 + ' ' + $2 + "(" + args + ")", args, $1) + else + qWarning( "Invalid DCOP slot format: '#{slot}'" ) + end + end + end + end # DCOPMetaInfo + + def KDE.hasDCOPSignals(aClass) + classname = aClass.name if aClass.is_a? Module + meta = DCOPMeta[classname] + return !meta.nil? && meta.k_dcop_signals.length > 0 + end + + def KDE.hasDCOPSlots(aClass) + classname = aClass.name if aClass.is_a? Module + meta = DCOPMeta[classname] + return !meta.nil? && meta.k_dcop.length > 0 + end + + def KDE.getDCOPSignalNames(aClass) + classname = aClass.name if aClass.is_a? Module + signals = DCOPMeta[classname].k_dcop_signals + return signals.keys + end + + module Internal + def Internal.fullSignalName(instance, signalName) + classname = instance.class.name if instance.class.is_a? Module + signals = DCOPMeta[classname].k_dcop_signals + return signals[signalName].full_name + end + end + + class KDE::DCOPObject + def initialize(*k) + super + end + + def process(fun, data, replyType, replyData) + if fun == 'functions()' or fun == 'interfaces()' + return super + end + + slots = DCOPMeta[@client.class.name].k_dcop + dcop_slot = slots[fun.sub(/\(.*/, '')] + if dcop_slot.nil? + # Can't find an entry for the slot being called? This shouldn't happen.. + return false + end + + replyType << dcop_slot.reply_type + KDE::dcop_process( @client, + dcop_slot.name, + Qt::Internal::getMocArguments(fun), + data, + replyType, + (replyType == 'void' or replyType == 'ASYNC') ? nil : Qt::Internal::getMocArguments(replyType), + replyData ) + end + + def interfaces() + ifaces = super() + return ifaces << @client.class.name + end + + def functions() + funcs = super() + return funcs + @functions + end + + def functions=(funcs) + @functions = funcs + end + + # If a ruby class has 'k_dcop' slots declarations, but isn't a + # subclass of DCOPObject, then keep an instance of it + def client=(obj) + @client = obj + end + + def inspect + str = super + if @functions != nil + str.sub(/>$/, " objId=%s, functions=Array (%d element(s))>" % [objId.inspect, functions.length]) + end + end + + def pretty_print(pp) + str = to_s + if @functions != nil + pp.text str.sub(/>$/, "\n objId=%s,\n functions=Array (%d element(s))>" % [objId.inspect, functions.length]) + end + end + end + + # If a class contains a k_dcop slots list declaration, then create a DCOPObject + # associated with it + def KDE.createDCOPObject(instance) + meta = DCOPMeta[instance.class.name] + return nil if meta.nil? + + if meta.dcop_object.nil? or meta.changed + funcs = [] + meta.k_dcop.each_value do |value| + sig = value.reply_type + ' ' + value.name + '(' + value.arg_types + ')' + funcs << sig + end + meta.changed = false + if instance.kind_of? DCOPObject + instance.functions = funcs + instance.client = instance + return nil + else + if meta.dcop_object.nil? + # Only ever allocate a single instance of a DCOPObject if the + # class isn't a subclass of DCOPObject + meta.dcop_object = DCOPObject.new(instance.class.name) + meta.dcop_object.client = instance + end + meta.dcop_object.functions = funcs + end + end + + return meta.dcop_object + end + + class DCOPRef < Qt::Base + def method_missing(*k) + # Enables DCOPRef calls to be made like this: + # + # dcopRef = DCOPRef.new("dcopslot", "MyWidget") + # result = dcopRef.getPoint("Hello from dcopcall") + begin + # First look for a method in the Smoke runtime. + # If not found, then throw an exception and try dcop. + super(*k) + rescue + dcopArgs = k[1, k.length-1] + dcopArgs << NoEventLoop << -1 + method = k[0].id2name + # Make 'parrot.age = 7' a synonym for 'parrot.setAge(7)' + method = 'set' + method[0,1].upcase + method[1,method.length].sub("=", "") if method =~ /.*[^-+%\/|]=$/ + + # If the method name contains underscores, convert to camel case + while method =~ /([^_]*)_(.)(.*)/ + method = $1 + $2.upcase + $3 + end + + # Get the functions() for this dcop ref and + # cache method_name => full_type_signature in a hash + if @functions.nil? + @functions = {} + funcs = call("functions()") + if funcs.nil? + return nil + end + funcs.each do |func| + if func =~ /^([\w,<>:]*)\s+(.*)(\(.*\))/ + return_type = $1 + name = $2 + args = $3 + if args =~ / / + # Remove any arg names + args.gsub!(/ \w*/, "") + end + + # Make thing? a synonym for isThing() or hasThing() + if name =~ /^(is|has)(.)(.*)/ + predicate = $2.downcase + $3 + '?' + if @functions[predicate].nil? + @functions[predicate] = return_type + " " + name + args + end + end + + if @functions[name].nil? + @functions[name] = return_type + " " + name + args + else + # If a function name is overloaded, just keep a single name entry in + # the hash, not all the full type signatures. Then leave dcopTypeNames() + # to try and resolve the ambiguous call from the ruby arg types passed. + @functions.delete(name) + @functions[name] = name + end + end + end + end + + method = @functions[method] + if method.nil? + qWarning( "DCOPRef: call #{k[0].id2name}() not found" ) + return + end + + return callExt(method, *dcopArgs) + end + end + + def dcopTypeNames(*k) + typeNames = "(" + k.each do |arg| + if arg.kind_of? Integer + typeNames << "int," + elsif arg.kind_of? Float + typeNames << "double," + elsif arg.kind_of? Array + typeNames << "QStringList," + elsif arg.kind_of? String + typeNames << "QString," + elsif arg.kind_of? Qt::Base + typeNames << arg.class.name + "," + elsif arg.instance_of? FalseClass or arg.instance_of? TrueClass + typeNames << "bool," + end + end + typeNames.sub!(/,$/, '') + typeNames.gsub!(/Qt::/, 'Q') + typeNames.gsub!(/KDE::/, 'K') + typeNames << ")" + return typeNames + end + + def call(fun, *k) + k << NoEventLoop << -1 + callExt(fun, *k) + end + + def callExt(fun, *k) + if isNull + qWarning( "DCOPRef: call #{fun} on null reference error" ) + return + end + sig = fun + if fun.index('(') == nil + sig << dcopTypeNames(*k[0, k.length - 2]) + end + dc = dcopClient() + if !dc || !dc.isAttached + qWarning( "DCOPRef::call(): no DCOP client or client not attached error" ) + return + end + if sig =~ /([^\s]*)(\(.*\))/ + full_name = $1+$2 + else + qWarning( "DCOPRef: call #{fun} invalid format, expecting '<function_name>(<args>)'" ) + return + end + return KDE::dcop_call( self, + full_name, + Qt::Internal::getMocArguments(full_name), + *k ) + end + + def send(fun, *k) + if isNull + qWarning( "DCOPRef: send #{fun} on null reference error" ) + end + sig = fun + if fun.index('(') == nil + sig << dcopTypeNames(*k) + end + dc = dcopClient() + if !dc || !dc.isAttached + qWarning( "DCOPRef::send(): no DCOP client or client not attached error" ) + return + end + if !sig =~ /^([^\s]*)(\(.*\))/ + qWarning( "DCOPRef: send #{sig} invalid format, expecting '<function_name>(<args>)'" ) + return + end + return KDE::dcop_send( self, + fun, + Qt::Internal::getMocArguments(sig), + *k ) + end + + def methods + if @functions.nil? + functions() + end + + result = super + @functions.keys.map {|k| k.sub(/^(set)([A-Z])(.*)/) { $2.downcase + $3 + '=' } } + return result.uniq + end + + def inspect + str = super + str.sub(/>$/, " app=%s, obj=%s>" % [app.inspect, obj.inspect]) + end + + def pretty_print(pp) + str = to_s + pp.text str.sub(/>$/, "\n app=%s,\n obj=%s>" % [app.inspect, obj.inspect]) + end + + def type(*args) + method_missing(:type, *args) + end + end + + def CmdLineArgs::init(*k) + if k.length > 0 + if k[0].kind_of? Array + # If init() is passed an array as the first argument, assume it's ARGV. + # Then convert to a pair of args 'ARGV.length+1, [$0]+ARGV' + array = k.shift + super(*([array.length+1] + [[$0] + array] + k)) + elsif k[0].kind_of? KDE::AboutData + super(1, [$0], k[0]) + end + else + super + end + end + + # A sane alternative to the strange looking C++ template version, + # this takes a variable number of ruby args as classes to restore + def MainWindow::kRestoreMainWindows(*k) + n = 1 + while MainWindow.canBeRestored(n) + className = MainWindow.classNameOfToplevel(n) + k.each do |klass| + if klass.name == className + klass.new.restore(n) + end + end + n += 1 + end + end + + class AboutData + def inspect + str = super + str.sub!(/>$/, " appName=%s, copyrightStatement=%s, programName=%s, version=%s, shortDescription=%s, homepage=%s, bugAddress=%s>" % + [appName.inspect, copyrightStatement.inspect, programName.inspect, version.inspect, + shortDescription.inspect, homepage.inspect, bugAddress.inspect] ) + length = authors.length + if length > 0 + str.sub!(/>$/, ", authors=Array (%d element(s))>" % length) + end + length = credits.length + if length > 0 + str.sub!(/>$/, ", credits=Array (%d element(s))>" % length) + end + length = translators.length + if length > 0 + str.sub!(/>$/, ", translators=Array (%d element(s))>" % length) + end + return str + end + + def pretty_print(pp) + str = to_s + str.sub!(/>$/, "\n appName=%s,\n copyrightStatement=%s,\n programName=%s,\n version=%s,\n shortDescription=%s,\n homepage=%s,\n bugAddress=%s>" % + [appName.inspect, copyrightStatement.inspect, programName.inspect, version.inspect, + shortDescription.inspect, homepage.inspect, bugAddress.inspect] ) + length = authors.length + if length > 0 + str.sub!(/>$/, ",\n authors=Array (%d element(s))>" % length) + end + length = credits.length + if length > 0 + str.sub!(/>$/, ",\n credits=Array (%d element(s))>" % length) + end + length = translators.length + if length > 0 + str.sub!(/>$/, ",\n translators=Array (%d element(s))>" % length) + end + pp.text str + end + end + + class AboutPerson + def inspect + str = super + str.sub(/>$/, " emailAddress=%s, name=%s, task=%s, webAddress=%s>" % + [emailAddress.inspect, name.inspect, task.inspect, webAddress.inspect] ) + end + + def pretty_print(pp) + str = to_s + pp.text str.sub(/>$/, "\n emailAddress=%s,\n name=%s,\n task=%s,\n webAddress=%s>" % + [emailAddress.inspect, name.inspect, task.inspect, webAddress.inspect] ) + end + + def name(*args) + method_missing(:name, *args) + end + end + + class AboutTranslator + def inspect + str = super + str.sub(/>$/, " emailAddress=%s, name=%s>" % + [emailAddress.inspect, name.inspect] ) + end + + def pretty_print(pp) + str = to_s + pp.text str.sub(/>$/, "\n emailAddress=%s,\n name=%s>" % + [emailAddress.inspect, name.inspect] ) + end + + def name(*args) + method_missing(:name, *args) + end + end + + class AccelShortcutList + def name(*args) + method_missing(:name, *args) + end + end + + class ActionPtrShortcutList + def name(*args) + method_missing(:name, *args) + end + end + + class ActionShortcutList + def name(*args) + method_missing(:name, *args) + end + end + + class Application + def initialize(*k) + super + $kapp = self + end + + # Delete the underlying C++ instance after exec returns + # Otherwise, rb_gc_call_finalizer_at_exit() can delete + # stuff that KDE::Application still needs for its cleanup. + def exec + method_missing(:exec) + self.dispose + Qt::Internal.application_terminated = true + end + end + + class Archive + def open(*args) + method_missing(:open, *args) + end + end + + class ArchiveEntry + def name(*args) + method_missing(:name, *args) + end + end + + class BookmarkDrag + def format(*args) + method_missing(:format, *args) + end + end + + class CModule + def load(*args) + method_missing(:load, *args) + end + end + + class Catalogue + def name(*args) + method_missing(:name, *args) + end + end + + class ColorDrag + def format(*args) + method_missing(:format, *args) + end + end + + class CustomMenuEditor + def load(*args) + method_missing(:load, *args) + end + end + + class FileItem + def name(*args) + method_missing(:name, *args) + end + end + + class FileMetaInfoGroup + def name(*args) + method_missing(:name, *args) + end + end + + class FileMetaInfoItem + def type(*args) + method_missing(:type, *args) + end + end + + class FileTreeBranch + def name(*args) + method_missing(:name, *args) + end + end + + class FilterDev + def open(*args) + method_missing(:open, *args) + end + end + + class HTMLView + def print(*args) + method_missing(:print, *args) + end + end + + class Icon + def type(*args) + method_missing(:type, *args) + end + end + + class ImageEffect + def hash(*args) + method_missing(:hash, *args) + end + end + + class ImageIO + def type(*args) + method_missing(:type, *args) + end + end + + class ListView + include Enumerable + + def each + it = Qt::ListViewItemIterator.new(self) + while it.current + yield it.current + it += 1 + end + end + + def sort(*args) + method_missing(:sort, *args) + end + end + + class ListViewItem + include Enumerable + + def each + it = Qt::ListViewItemIterator.new(self) + while it.current + yield it.current + it += 1 + end + end + + def sort(*args) + method_missing(:sort, *args) + end + + def inspect + str = super + str.sub!(/>$/, "") + for i in 0..(listView.columns - 1) + str << " text%d=%s," % [i, self.text(i)] + end + str.sub!(/,?$/, ">") + end + + def pretty_print(pp) + str = to_s + str.sub!(/>$/, "") + for i in 0..(listView.columns - 1) + str << " text%d=%s," % [i, self.text(i)] + end + str.sub!(/,?$/, ">") + pp.text str + end + end + + class MainWindowInterface + def raise(*args) + method_missing(:raise, *args) + end + end + + class MdiChildView + def raise(*args) + method_missing(:raise, *args) + end + end + + class MimeType + def load(*args) + method_missing(:load, *args) + end + end + + class MultiTabBarButton + def id(*args) + method_missing(:id, *args) + end + end + + class MultipleDrag + def format(*args) + method_missing(:format, *args) + end + end + + class NamedCommand + def name(*args) + method_missing(:name, *args) + end + end + + class NewStuff + def type(*args) + method_missing(:type, *args) + end + end + + class OCRDialog + def id(*args) + method_missing(:id, *args) + end + end + + class Palette + def name(*args) + method_missing(:name, *args) + end + end + + class PanelApplet + def type(*args) + method_missing(:type, *args) + end + end + + class PanelExtension + def type(*args) + method_missing(:type, *args) + end + end + + class Pixmap + def load(*args) + method_missing(:load, *args) + end + end + + class PixmapEffect + def hash(*args) + method_missing(:hash, *args) + end + end + + class PluginInfo + def load(*args) + method_missing(:load, *args) + end + + def name(*args) + method_missing(:name, *args) + end + end + + class PluginSelector + def load(*args) + method_missing(:load, *args) + end + end + + class PopupFrame + def exec(*args) + method_missing(:exec, *args) + end + end + + class PrintAction + def print(*args) + method_missing(:print, *args) + end + end + + class Printer + def abort(*args) + method_missing(:abort, *args) + end + end + + class Progress + def format(*args) + method_missing(:format, *args) + end + end + + class ProtocolInfo + def exec(*args) + method_missing(:exec, *args) + end + + def load(*args) + method_missing(:load, *args) + end + + def name(*args) + method_missing(:name, *args) + end + end + + class Pty + def open(*args) + method_missing(:open, *args) + end + end + + class Run + def abort(*args) + method_missing(:abort, *args) + end + end + + class SSLCertDlgRet + def send(*args) + method_missing(:send, *args) + end + end + + class SSLPKCS12 + def name(*args) + method_missing(:name, *args) + end + end + + class SSLPKCS7 + def name(*args) + method_missing(:name, *args) + end + end + + class SSLSettings + def load(*args) + method_missing(:load, *args) + end + end + + class SaveFile + def abort(*args) + method_missing(:abort, *args) + end + + def name(*args) + method_missing(:name, *args) + end + end + + class ScanDialog + def id(*args) + method_missing(:id, *args) + end + end + + class Service + def inspect + str = super + str.sub(/>$/, " library=%s, type=%s, name=%s>" % [library.inspect, type.inspect, name.inspect]) + end + + def pretty_print(pp) + str = to_s + pp.text str.sub(/>$/, "\n library=%s,\n type=%s,\n name=%s>" % [library.inspect, type.inspect, name.inspect]) + end + + def exec(*args) + method_missing(:exec, *args) + end + + def load(*args) + method_missing(:load, *args) + end + + def name(*args) + method_missing(:name, *args) + end + + def type(*args) + method_missing(:type, *args) + end + end + + class ServiceGroup + def load(*args) + method_missing(:load, *args) + end + + def name(*args) + method_missing(:name, *args) + end + end + + class ServiceSeparator + def load(*args) + method_missing(:load, *args) + end + + def name(*args) + method_missing(:name, *args) + end + end + + class ServiceType + def load(*args) + method_missing(:load, *args) + end + + def name(*args) + method_missing(:name, *args) + end + end + + class Socks + def select(*args) + method_missing(:select, *args) + end + + def send(*args) + method_missing(:send, *args) + end + end + + class StdAccel + def name(*args) + method_missing(:name, *args) + end + + def open(*args) + method_missing(:open, *args) + end + + def print(*args) + method_missing(:print, *args) + end + end + + class StdAccel::ShortcutList + def name(*args) + method_missing(:name, *args) + end + end + + class StdAction + def name(*args) + method_missing(:name, *args) + end + + def open(*args) + method_missing(:open, *args) + end + + def print(*args) + method_missing(:print, *args) + end + end + + class StdGuiItem + def open(*args) + method_missing(:open, *args) + end + + def print(*args) + method_missing(:print, *args) + end + + def test(*args) + method_missing(:test, *args) + end + end + + class TempDir + def name(*args) + method_missing(:name, *args) + end + end + + class TempFile + def name(*args) + method_missing(:name, *args) + end + end + + class ToolBarButton + def id(*args) + method_missing(:id, *args) + end + end + + class UniqueApplication + def initialize(*k) + super + $kapp = self + end + + # Delete the underlying C++ instance after exec returns + # Otherwise, rb_gc_call_finalizer_at_exit() can delete + # stuff that KDE::Application still needs for its cleanup. + def exec + method_missing(:exec) + self.dispose + Qt::Internal.application_terminated = true + end + end + + class URIFilterPlugin + def name(*args) + method_missing(:name, *args) + end + end + + class URL + def inspect + str = super + str.sub(/>$/, " url=%s, protocol=%s, host=%s, port=%d>" % [url.inspect, protocol.inspect, host.inspect, port]) + end + + def pretty_print(pp) + str = to_s + pp.text str.sub(/>$/, "\n url=%s,\n protocol=%s,\n host=%s,\n port=%d>" % [url.inspect, protocol.inspect, host.inspect, port]) + end + + def split(*args) + method_missing(:split, *args) + end + end + + class URLDrag + def format(*args) + method_missing(:format, *args) + end + end + + class VMAllocator + def allocate(*args) + method_missing(:allocate, *args) + end + end + + class WindowInfo + def display(*args) + method_missing(:display, *args) + end + end + +end + +module DOM + class Attr + def name(*args) + method_missing(:name, *args) + end + end + + class DOMString + def split(*args) + method_missing(:split, *args) + end + end + + class DocumentType + def name(*args) + method_missing(:name, *args) + end + end + + class Event + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLAnchorElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLAnchorElement + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLAppletElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLButtonElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLButtonElement + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLElement + def id(*args) + method_missing(:id, *args) + end + end + + class HTMLFormElement + def method(*args) + method_missing(:method, *args) + end + end + + class HTMLFormElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLFrameElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLIFrameElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLImageElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLInputElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLInputElement + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLLIElement + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLLinkElement + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLMapElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLMetaElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLOListElement + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLObjectElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLObjectElement + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLParamElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLParamElement + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLScriptElement + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLSelectElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLSelectElement + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLStyleElement + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLTextAreaElement + def name(*args) + method_missing(:name, *args) + end + end + + class HTMLTextAreaElement + def type(*args) + method_missing(:type, *args) + end + end + + class HTMLUListElement + def type(*args) + method_missing(:type, *args) + end + end + + class StyleSheet + def type(*args) + method_missing(:type, *args) + end + end + + class CSSRule + def type(*args) + method_missing(:type, *args) + end + end + + class Document + def abort(*args) + method_missing(:abort, *args) + end + end + + class Document + def load(*args) + method_missing(:load, *args) + end + end + + class HTMLDocument + def open(*args) + method_missing(:open, *args) + end + end + + class HTMLInputElement + def select(*args) + method_missing(:select, *args) + end + end + + class HTMLTextAreaElement + def select(*args) + method_missing(:select, *args) + end + end +end # DOM + +module KIO + class Connection + def send(*args) + method_missing(:send, *args) + end + end + + class NetRC::AutoLogin + def type(*args) + method_missing(:type, *args) + end + end + + class Slave + def send(*args) + method_missing(:send, *args) + end + end + + class SlaveBase + def exit(*args) + method_missing(:exit, *args) + end + end +end # KIO + +module KNS + class Engine + def type(*args) + method_missing(:type, *args) + end + end + + class Entry + def name(*args) + method_missing(:name, *args) + end + + def type(*args) + method_missing(:type, *args) + end + end + + class Provider + def name(*args) + method_missing(:name, *args) + end + end + + class ProviderLoader + def load(*args) + method_missing(:load, *args) + end + end +end # KNS + +module KParts + class Event + def test(*args) + method_missing(:test, *args) + end + end + + class GUIActivateEvent + def test(*args) + method_missing(:test, *args) + end + end + + class OpenURLEvent + def test(*args) + method_missing(:test, *args) + end + end + + class PartActivateEvent + def test(*args) + method_missing(:test, *args) + end + end + + class PartSelectEvent + def test(*args) + method_missing(:test, *args) + end + end +end # KParts + +module Win + class Win::WindowInfo + def name(*args) + method_missing(:name, *args) + end + end +end + +class Object + def RESTORE(klass) + n = 1 + while MainWindow.canBeRestored(n) + klass.new.restore(n) + n += 1 + end + end + + def I18N_NOOP(x) x end + def I18N_NOOP2(comment, x) x end +end + +class Qt::Base + def self.k_dcop_signals(*signal_list) + meta = KDE::DCOPMeta[self.name] || KDE::DCOPMetaInfo.new(self) + meta.add_signals(signal_list) + meta.changed = true + end + + def self.k_dcop(*slot_list) + meta = KDE::DCOPMeta[self.name] || KDE::DCOPMetaInfo.new(self) + meta.add_slots(slot_list) + meta.changed = true + end +end diff --git a/korundum/rubylib/korundum/lib/Makefile.am b/korundum/rubylib/korundum/lib/Makefile.am new file mode 100644 index 00000000..fba7d258 --- /dev/null +++ b/korundum/rubylib/korundum/lib/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = KDE |