diff options
Diffstat (limited to 'kalyptus/kalyptusCxxToJNI.pm')
-rw-r--r-- | kalyptus/kalyptusCxxToJNI.pm | 5595 |
1 files changed, 5595 insertions, 0 deletions
diff --git a/kalyptus/kalyptusCxxToJNI.pm b/kalyptus/kalyptusCxxToJNI.pm new file mode 100644 index 00000000..df45eb94 --- /dev/null +++ b/kalyptus/kalyptusCxxToJNI.pm @@ -0,0 +1,5595 @@ +#*************************************************************************** +# kalyptusCxxToJNI.pm - Generates *.java and *.cpp files for a JNI based +# version of Qt/KDE java bindings +# ------------------- +# begin : Sun Nov 16 12:00:00 2003 +# copyright : (C) 2003, Richard Dale. All Rights Reserved. +# email : Richard_Dale@tipitina.demon.co.uk +# author : Richard Dale, based on the SMOKE generation code +# by David Faure. +#***************************************************************************/ + +#/*************************************************************************** +# * * +# * 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. * +# * * +#***************************************************************************/ + +package kalyptusCxxToJNI; + +use File::Path; +use File::Basename; + +use Carp; +use Ast; +use kdocAstUtil; +use kdocUtil; +use Iter; +use kalyptusDataDict; + +use strict; +no strict "subs"; + +use vars qw/ + $libname $rootnode $outputdir $opt $debug + $qapplicationExtras $qapplicationjniExtras $qbitmapExtras $qbitmapjniExtras + $qlistviewExtras $qlistviewjniExtras $qlistviewitemExtras $qlistviewitemjniExtras + $qpopupmenujniExtras $qmenudatajniExtras $qmenubarjniExtras + $qdragobjectExtras $qdragobjectjniExtras $qdropeventExtras $qdropeventjniExtras $qmimesourceExtras $qmimesourcejniExtras + $qtExtras $qtjniExtras $qobjectExtras $qobjectjniExtras $qimagejniExtras $qwidgetExtras $qwidgetjniExtras + $qpixmapExtras $qpixmapjniExtras $qpaintdeviceExtras $qpaintdevicejniExtras + $qdragobjectExtras $qdragobjectjniExtras $qiodeviceExtras $qpointarrayExtras $qpointarrayjniExtras + $qtextcodecExtras $qtextcodecjniExtras $quridragExtras $quridragjniExtras + $kapplicationExtras $kapplicationjniExtras $kmainwindowExtras $kmainwindowjniExtras + $kcmdlineargsjniExtras $schedulerjniExtras + $methodNumber + %builtins %typeunion %allMethods %allTypes %enumValueToType %typedeflist %mungedTypeMap %javaImports + %skippedClasses %skippedJniMethods %operatorNames /; + +BEGIN +{ + +# Types supported by the StackItem union +# Key: C++ type Value: Union field of that type +%typeunion = ( + 'void*' => 's_voidp', + 'bool' => 's_bool', + 'char' => 's_char', + 'uchar' => 's_uchar', + 'short' => 's_short', + 'ushort' => 's_ushort', + 'int' => 's_int', + 'uint' => 's_uint', + 'long' => 's_long', + 'ulong' => 's_ulong', + 'float' => 's_float', + 'double' => 's_double', + 'enum' => 's_enum', + 'class' => 's_class' +); + +# Mapping for iterproto, when making up the munged method names +%mungedTypeMap = ( + 'QString' => '$', + 'QString*' => '$', + 'QString&' => '$', + 'QCString' => '$', + 'QCString*' => '$', + 'QCString&' => '$', + 'QByteArray' => '$', + 'QByteArray&' => '$', + 'QByteArray*' => '$', + 'char*' => '$', + 'QCOORD*' => '?', + 'QRgb*' => '?', +); + +# Yes some of this is in kalyptusDataDict's ctypemap +# but that one would need to be separated (builtins vs normal classes) +%typedeflist = +( + 'signed char' => 'char', + 'unsigned char' => 'uchar', + 'signed short' => 'short', + 'unsigned short' => 'ushort', + 'signed' => 'int', + 'signed int' => 'int', + 'unsigned' => 'uint', + 'unsigned int' => 'uint', + 'KIO::filesize_t' => 'long', + 'signed long' => 'long', + 'unsigned long' => 'ulong', + +# Anything that is not known is mapped to void*, so no need for those here anymore +# 'QWSEvent*' => 'void*', +# 'QDiskFont*' => 'void*', +# 'XEvent*' => 'void*', +# 'FILE*' => 'void*', +# 'QUnknownInterface*' => 'void*', +# 'GDHandle' => 'void*', +# '_NPStream*' => 'void*', +# 'QTextFormat*' => 'void*', +# 'QTextDocument*' => 'void*', +# 'QTextCursor*' => 'void*', +# 'QTextParag**' => 'void*', +# 'QTextParag*' => 'void*', +# 'QRemoteInterface*' => 'void*', +# 'QSqlRecordPrivate*' => 'void*', +# 'QTSMFI' => 'void*', # QTextStream's QTSManip +# 'const GUID&' => 'void*', +# 'QWidgetMapper*' => 'void*', +# 'MSG*' => 'void*', +# 'const QSqlFieldInfoList&' => 'void*', # QSqlRecordInfo - TODO (templates) + + 'QStyleHintReturn*' => 'void*', + 'QPtrCollection::Item' => 'void*', # to avoid a warning + + 'mode_t' => 'long', + 'QProcess::PID' => 'long', + 'size_type' => 'int', # QSqlRecordInfo + 'Qt::ComparisonFlags' => 'uint', + 'Qt::ToolBarDock' => 'int', # compat thing, Qt shouldn't use it + 'QIODevice::Offset' => 'ulong', + 'WState' => 'int', + 'WId' => 'ulong', + 'QRgb' => 'uint', + 'ksocklen_t' => 'uint', + 'QCOORD' => 'int', + 'QTSMFI' => 'int', + 'Qt::WState' => 'int', + 'Qt::WFlags' => 'int', + 'Qt::HANDLE' => 'uint', + 'QEventLoop::ProcessEventsFlags' => 'uint', + 'QStyle::SCFlags' => 'int', + 'QStyle::SFlags' => 'int', + 'Q_INT16' => 'short', + 'Q_INT32' => 'int', + 'Q_INT64' => 'long', + 'Q_INT8' => 'char', + 'Q_LONG' => 'long', + 'Q_LLONG' => 'long', + 'Q_ULLONG' => 'long', + 'Q_UINT16' => 'ushort', + 'Q_UINT32' => 'uint', + 'Q_UINT64' => 'long', + 'Q_UINT8' => 'uchar', + 'Q_ULONG' => 'long', + 'pid_t' => 'int', + 'size_t' => 'int', + 'pid_t' => 'int', + 'time_t' => 'int', + 'short int' => 'short', + 'unsigned long long int' => 'ulong', + 'long long int' => 'long', + 'signed long int' => 'long', + 'unsigned long int' => 'ulong', + 'int long' => 'long', + 'unsigned short int' => 'ushort', +); + +%operatorNames = +( + 'operator^' => 'op_xor', + 'operator^=' => 'op_xor_assign', + 'operator<' => 'op_lt', + 'operator<<' => 'op_write', + 'operator<=' => 'op_lte', +# 'operator=' => 'op_assign', + 'operator==' => 'op_equals', + 'operator>' => 'op_gt', + 'operator>=' => 'op_gte', + 'operator>>' => 'op_read', + 'operator|' => 'op_or', + 'operator|=' => 'op_or_assign', + 'operator-' => 'op_minus', + 'operator-=' => 'op_minus_assign', + 'operator--' => 'op_decr', + 'operator!' => 'op_not', + 'operator!=' => 'op_not_equals', + 'operator/' => 'op_div', + 'operator/=' => 'op_div_assign', + 'operator()' => 'op_expr', + 'operator[]' => 'op_at', + 'operator*' => 'op_mult', + 'operator*=' => 'op_mult_assign', + 'operator&' => 'op_and', + 'operator&=' => 'op_and_assign', + 'operator+' => 'op_plus', + 'operator+=' => 'op_plus_assign', + 'operator++' => 'op_incr', +); + +%skippedJniMethods = +( + 'Java_org_kde_qt_QApplication_newQApplication___3Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QApplication_newQApplication___3Ljava_lang_String_2Z' => 1, + 'Java_org_kde_qt_QApplication_newQApplication___3Ljava_lang_String_2I' => 1, + 'Java_org_kde_qt_QApplication_newQApplication___3I_3Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QApplication_newQApplication___3I_3Ljava_lang_String_2Z' => 1, + 'Java_org_kde_qt_QApplication_newQApplication___3I_3Ljava_lang_String_2I' => 1, + 'Java_org_kde_qt_QApplication_newQApplication__I_3Ljava_lang_String_2I' => 1, + 'Java_org_kde_qt_QApplication_newQApplication__I_3Ljava_lang_String_2Z' => 1, + 'Java_org_kde_qt_QApplication_newQApplication__I_3Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QApplication_args__' => 1, + 'Java_org_kde_qt_QBitmap_newQBitmap__Lorg_kde_qt_QPixmap_2' => 1, + 'Java_org_kde_qt_QBitmap_newQBitmap__Lorg_kde_qt_QImage_2' => 1, + 'Java_org_kde_qt_QListView_itemList' => 1, + 'Java_org_kde_qt_QListViewItem_itemList' => 1, + 'Java_org_kde_qt_Qt_color0' => 1, + 'Java_org_kde_qt_Qt_color1' => 1, + 'Java_org_kde_qt_Qt_black' => 1, + 'Java_org_kde_qt_Qt_white' => 1, + 'Java_org_kde_qt_Qt_darkGray' => 1, + 'Java_org_kde_qt_Qt_lightGray' => 1, + 'Java_org_kde_qt_Qt_gray' => 1, + 'Java_org_kde_qt_Qt_red' => 1, + 'Java_org_kde_qt_Qt_green' => 1, + 'Java_org_kde_qt_Qt_blue' => 1, + 'Java_org_kde_qt_Qt_cyan' => 1, + 'Java_org_kde_qt_Qt_magenta' => 1, + 'Java_org_kde_qt_Qt_yellow' => 1, + 'Java_org_kde_qt_Qt_darkRed' => 1, + 'Java_org_kde_qt_Qt_darkGreen' => 1, + 'Java_org_kde_qt_Qt_darkBlue' => 1, + 'Java_org_kde_qt_Qt_darkCyan' => 1, + 'Java_org_kde_qt_Qt_darkMagenta' => 1, + 'Java_org_kde_qt_Qt_darkYellow' => 1, + 'Java_org_kde_qt_Qt_arrowCursor' => 1, + 'Java_org_kde_qt_Qt_upArrowCursor' => 1, + 'Java_org_kde_qt_Qt_crossCursor' => 1, + 'Java_org_kde_qt_Qt_waitCursor' => 1, + 'Java_org_kde_qt_Qt_ibeamCursor' => 1, + 'Java_org_kde_qt_Qt_sizeVerCursor' => 1, + 'Java_org_kde_qt_Qt_sizeHorCursor' => 1, + 'Java_org_kde_qt_Qt_sizeBDiagCursor' => 1, + 'Java_org_kde_qt_Qt_sizeFDiagCursor' => 1, + 'Java_org_kde_qt_Qt_sizeAllCursor' => 1, + 'Java_org_kde_qt_Qt_blankCursor' => 1, + 'Java_org_kde_qt_Qt_splitVCursor' => 1, + 'Java_org_kde_qt_Qt_splitHCursor' => 1, + 'Java_org_kde_qt_Qt_pointingHandCursor' => 1, + 'Java_org_kde_qt_Qt_forbiddenCursor' => 1, + 'Java_org_kde_qt_Qt_qApp' => 1, + 'Java_org_kde_qt_Qt_qDebug' => 1, + 'Java_org_kde_qt_Qt_qWarning' => 1, + 'Java_org_kde_qt_Qt_qFatal' => 1, + 'Java_org_kde_qt_QObject_connect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QObject_connect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QObject_disconnect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QObject_disconnect__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QObject_emit' => 1, + 'Java_org_kde_qt_QWidget_paintDevice' => 1, + 'Java_org_kde_qt_QImage_bits__' => 1, + 'Java_org_kde_qt_QImage_colorTable__' => 1, + 'Java_org_kde_qt_QImage_scanLine__I' => 1, + 'Java_org_kde_qt_QPixmap_paintDevice' => 1, + 'Java_org_kde_qt_QPixmap_loadFromData___3C' => 1, + 'Java_org_kde_qt_QPaintDevice_paintDevice' => 1, + 'Java_org_kde_qt_QDragObject_mimeSource' => 1, + 'Java_org_kde_qt_QPointArray_point__I_3I_3I' => 1, + 'Java_org_kde_qt_QPointArray_setPoints__I_3S' => 1, + 'Java_org_kde_qt_QPointArray_putPoints__II_3S' => 1, + 'Java_org_kde_qt_QPointArray_count__' => 1, + 'Java_org_kde_qt_QPointArray_isEmpty__' => 1, + 'Java_org_kde_qt_QPointArray_isNull__' => 1, + 'Java_org_kde_qt_QPointArray_resize__' => 1, + 'Java_org_kde_qt_QPopupMenu_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QKeySequence_2II' => 1, + 'Java_org_kde_qt_QPopupMenu_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QPopupMenu_connectItem__ILorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QPopupMenu_disconnectItem__ILorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuData_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QKeySequence_2II' => 1, + 'Java_org_kde_qt_QMenuData_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuData_connectItem__ILorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuData_disconnectItem__ILorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuBar_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QKeySequence_2II' => 1, + 'Java_org_kde_qt_QMenuBar_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuBar_connectItem__ILorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QMenuBar_disconnectItem__ILorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QUriDrag_decode__Lorg_kde_qt_QMimeSourceInterface_2_3Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QUriDrag_decodeToUnicodeUris__Lorg_kde_qt_QMimeSourceInterface_2_3Ljava_lang_String_2' => 1, + 'Java_org_kde_qt_QUriDrag_decodeLocalFiles__Lorg_kde_qt_QMimeSourceInterface_2_3Ljava_lang_String_2' => 1, + 'Java_org_kde_koala_KApplication_setJavaSlotFactory' => 1, + 'Java_org_kde_koala_KMainWindow_memberList' => 1, + 'Java_org_kde_koala_KCmdLineArgs_init__I_3Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2' => 1, + 'Java_org_kde_koala_KCmdLineArgs_init__I_3Ljava_lang_String_2Lorg_kde_koala_KAboutData_2' => 1, + 'Java_org_kde_koala_KCmdLineArgs_init__I_3Ljava_lang_String_2Lorg_kde_koala_KAboutData_2Z' => 1, + 'Java_org_kde_koala_KCmdLineArgs_init__I_3Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Z' => 1, + 'Java_org_kde_koala_Scheduler_connect__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_koala_Scheduler_connect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Ljava_lang_String_2' => 1, + 'Java_org_kde_koala_Scheduler_disconnect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2' => 1, + 'Java_org_kde_koala_Scheduler_disconnect' => 1, +); + + $qapplicationExtras = <<EOF; + public native String[] args(); + +EOF + + $qapplicationjniExtras = <<EOF; +static jobjectArray _args = 0; + +JNIEXPORT void JNICALL +Java_org_kde_qt_QApplication_newQApplication___3Ljava_lang_String_2(JNIEnv *env, jobject obj, jobjectArray args) +{ + int argc = (int) env->GetArrayLength(args) + 1; + _args = (jobjectArray) env->NewGlobalRef(args); + if (QtSupport::getQt(env, obj) == 0) { + QtSupport::setQt(env, obj, new QApplicationJBridge(argc, QtSupport::toArgv(env, args))); + QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj)); + } + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_qt_QApplication_newQApplication___3Ljava_lang_String_2Z(JNIEnv *env, jobject obj, jobjectArray args, jboolean GUIenabled) +{ + int argc = (int) env->GetArrayLength(args) + 1; + _args = (jobjectArray) env->NewGlobalRef(args); + if (QtSupport::getQt(env, obj) == 0) { + QtSupport::setQt(env, obj, new QApplicationJBridge(argc, QtSupport::toArgv(env, args), (bool) GUIenabled)); + QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj)); + } + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_qt_QApplication_newQApplication___3Ljava_lang_String_2I(JNIEnv *env, jobject obj, jobjectArray args, jint arg1) +{ + int argc = (int) env->GetArrayLength(args) + 1; + _args = (jobjectArray) env->NewGlobalRef(args); + if (QtSupport::getQt(env, obj) == 0) { + QtSupport::setQt(env, obj, new QApplicationJBridge(argc, QtSupport::toArgv(env, args), (QApplication::Type) arg1)); + QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj)); + } + return; +} + +JNIEXPORT jobjectArray JNICALL +Java_org_kde_qt_QApplication_args(JNIEnv *env, jobject obj) +{ + (void) env; + (void) obj; + return _args; +} + +EOF + + $qbitmapExtras = <<EOF; + public QBitmap(QPixmap arg1) { + super((Class) null); + newQBitmap(arg1); + } + private native void newQBitmap(QPixmap arg1); + public QBitmap(QImage arg1) { + super((Class) null); + newQBitmap(arg1); + } + private native void newQBitmap(QImage arg1); + +EOF + + $qbitmapjniExtras = <<EOF; +JNIEXPORT void JNICALL +Java_org_kde_qt_QBitmap_newQBitmap__Lorg_kde_qt_QPixmap_2(JNIEnv *env, jobject obj, jobject arg1) +{ + if (QtSupport::getQt(env, obj) == 0) { + QBitmap temp; + temp = (QPixmap&) *(QPixmap *) QtSupport::getQt(env, arg1); + QtSupport::setQt(env, obj, new QBitmapJBridge(temp)); + QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj)); + } + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_qt_QBitmap_newQBitmap__Lorg_kde_qt_QImage_2(JNIEnv *env, jobject obj, jobject arg1) +{ + if (QtSupport::getQt(env, obj) == 0) { + QBitmap temp; + temp = (QImage&) *(QImage *) QtSupport::getQt(env, arg1); + QtSupport::setQt(env, obj, new QBitmapJBridge(temp)); + QtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj)); + } + return; +} + +EOF + + $qlistviewExtras = <<EOF; + public native ArrayList itemList(); + +EOF + + $qlistviewjniExtras = <<EOF; +JNIEXPORT jobject JNICALL +Java_org_kde_qt_QListView_itemList(JNIEnv *env, jobject obj) +{ + QListViewItemIterator iterator((QListView*) QtSupport::getQt(env, obj)); + return QtSupport::arrayWithQListViewItemList(env, &iterator); +} + +EOF + $qlistviewitemExtras = <<EOF; + public native ArrayList itemList(); + +EOF + + $qlistviewitemjniExtras = <<EOF; +JNIEXPORT jobject JNICALL +Java_org_kde_qt_QListViewItem_itemList(JNIEnv *env, jobject obj) +{ + QListViewItemIterator iterator((QListViewItem*) QtSupport::getQt(env, obj)); + return QtSupport::arrayWithQListViewItemList(env, &iterator); +} + +EOF + + $qtExtras = <<EOF; + /** This member allows a typecast of an instance which wraps a Qt instance, + to a more specialized type. Invokes the private qtjava.dynamicCast() + via reflection, as that method isn't part of the public Qt api */ + public static QtSupport dynamicCast(String type, QtSupport source) { + Method method = null; + + try { + method = qtjava.class.getDeclaredMethod( "dynamicCast", + new Class[] { String.class, QtSupport.class } ); + } catch (NoSuchMethodException e1) { + Qt.qWarning("No such method : qtjava.dynamicCast()"); + } + + try { + method.setAccessible(true); + Object result = method.invoke(qtjava.class, new Object[] { type, source } ); + return (QtSupport) result; + } catch (InvocationTargetException e) { + Qt.qWarning("Invocation failed : qtjava.dynamicCast()"); + return null; + } catch (IllegalAccessException e) { + Qt.qWarning("Invocation failed : qtjava.dynamicCast()"); + return null; + } + } + + public static native QColor color0(); + public static native QColor color1(); + public static native QColor black(); + public static native QColor white(); + public static native QColor darkGray(); + public static native QColor gray(); + public static native QColor lightGray(); + public static native QColor red(); + public static native QColor green(); + public static native QColor blue(); + public static native QColor cyan(); + public static native QColor magenta(); + public static native QColor yellow(); + public static native QColor darkRed(); + public static native QColor darkGreen(); + public static native QColor darkBlue(); + public static native QColor darkCyan(); + public static native QColor darkMagenta(); + public static native QColor darkYellow(); + + // Global cursors + + public static native QCursor arrowCursor(); // standard arrow cursor + public static native QCursor upArrowCursor(); // upwards arrow + public static native QCursor crossCursor(); // crosshair + public static native QCursor waitCursor(); // hourglass/watch + public static native QCursor ibeamCursor(); // ibeam/text entry + public static native QCursor sizeVerCursor(); // vertical resize + public static native QCursor sizeHorCursor(); // horizontal resize + public static native QCursor sizeBDiagCursor(); // diagonal resize (/) + public static native QCursor sizeFDiagCursor(); // diagonal resize (\) + public static native QCursor sizeAllCursor(); // all directions resize + public static native QCursor blankCursor(); // blank/invisible cursor + public static native QCursor splitVCursor(); // vertical bar with left-right + // arrows + public static native QCursor splitHCursor(); // horizontal bar with up-down + // arrows + public static native QCursor pointingHandCursor(); // pointing hand + public static native QCursor forbiddenCursor(); // forbidden cursor (slashed circle) + public static native QCursor whatsThisCursor(); // arrow with a question mark + + public static native QApplication qApp(); + + public static native void qDebug(String message); + public static void qDebug(String pattern, Object[] arguments) { + qDebug(MessageFormat.format(pattern, arguments)); + } + + public static native void qWarning(String message); + public static void qWarning(String pattern, Object[] arguments) { + qWarning(MessageFormat.format(pattern, arguments)); + } + + public static native void qFatal(String message); + public static void qFatal(String pattern, Object[] arguments) { + qFatal(MessageFormat.format(pattern, arguments)); + } + + private static String sqeezeOut(String from, char toss) { + char[] chars = from.toCharArray(); + int len = chars.length; + int put = 0; + + for (int i = 0; i < len; i++) { + if (chars[i] != toss) { + chars[put++] = chars[i]; + } + } + + return new String(chars, 0, put); + } + + /** Prepend a '2' to a signal string and remove any spaces */ + public static String SIGNAL(String signal) { + return "2" + sqeezeOut(signal, ' '); + } + + /** Prepend a '1' to a slot string and remove any spaces */ + public static String SLOT(String slot) { + return "1" + sqeezeOut(slot, ' '); + } + + /** Convert from a UTF-8 string to Unicode - the java equivalent to QString::fromUtf8() */ + public String fromUtf8(byte[] bytes) { + String result = null; + + try { + result = new String(bytes, "UTF-8"); + } catch (UnsupportedEncodingException e) { + qWarning("UTF-8 encoding not supported"); + } finally { + return result; + } + } + +EOF + + $qtjniExtras = <<EOF; +#include <qapplication.h> +#include <qstring.h> +#include <qcstring.h> + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_color0(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::color0, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_color1(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::color1, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_black(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::black, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_white(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::white, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkGray(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkGray, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_lightGray(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::lightGray, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_gray(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::gray, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_red(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::red, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_green(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::green, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_blue(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::blue, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_cyan(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::cyan, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_magenta(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::magenta, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_yellow(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::yellow, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkRed(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkRed, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkGreen(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkGreen, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkBlue(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkBlue, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkCyan(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkCyan, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkMagenta(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkMagenta, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_darkYellow(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::darkYellow, "org.kde.qt.QColor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_arrowCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::arrowCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_upArrowCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::upArrowCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_crossCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::crossCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_waitCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::waitCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_ibeamCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::ibeamCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_sizeVerCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::sizeVerCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_sizeHorCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::sizeHorCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_sizeBDiagCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::sizeBDiagCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_sizeFDiagCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::sizeFDiagCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_sizeAllCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::sizeAllCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_blankCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::blankCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_splitVCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::splitVCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_splitHCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::splitHCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_pointingHandCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::pointingHandCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_forbiddenCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::forbiddenCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_whatsThisCursor(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, (void*)&Qt::whatsThisCursor, "org.kde.qt.QCursor"); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_Qt_qApp(JNIEnv* env, jclass cls) +{ + (void) cls; + return (jobject) QtSupport::objectForQtKey(env, qApp, "org.kde.qt.QApplication"); +} + +JNIEXPORT void JNICALL +Java_org_kde_qt_Qt_qDebug(JNIEnv* env, jclass cls, jstring message) +{ +static QCString * _qstring_message = 0; + (void) cls; + qDebug("%s", (const char *) QtSupport::toCharString(env, message, &_qstring_message)); + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_qt_Qt_qWarning(JNIEnv* env, jclass cls, jstring message) +{ +static QCString * _qstring_message = 0; + (void) cls; + qWarning("%s", (const char *) QtSupport::toCharString(env, message, &_qstring_message)); + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_qt_Qt_qFatal(JNIEnv* env, jclass cls, jstring message) +{ +static QCString * _qstring_message = 0; + (void) cls; + qFatal("%s", (const char *) QtSupport::toCharString(env, message, &_qstring_message)); + return; +} + +EOF + + $qobjectExtras = <<EOF; + /** i18n() is just a synonym of tr() for now */ + public static String i18n(String s) { + return tr(s); + } + + public native void emit(String signal, Object[] args); + + protected void emit(String signal) { + Object[] args = new Object[0]; + emit("2" + signal.trim() + "()", args); + } + + protected void emit(String signal, Object value) { + Object[] args = new Object[1]; + args[0] = value; + emit("2" + signal.trim() + "(" + value.getClass().getName() + ")", args); + } + + protected void emit(String signal, Object value1, Object value2) { + Object[] args = new Object[2]; + args[0] = value1; + args[1] = value2; + emit("2" + signal.trim() + "(" + value1.getClass().getName() + "," + + value2.getClass().getName() + + ")", args); + } + + protected void emit(String signal, Object value1, Object value2, Object value3) { + Object[] args = new Object[3]; + args[0] = value1; + args[1] = value2; + args[2] = value3; + emit("2" + signal.trim() + "(" + value1.getClass().getName() + "," + + value2.getClass().getName() + "," + + value3.getClass().getName() + + ")", args); + } + + protected void emit(String signal, Object value1, Object value2, Object value3, Object value4) { + Object[] args = new Object[4]; + args[0] = value1; + args[1] = value2; + args[2] = value3; + args[3] = value4; + emit("2" + signal.trim() + "(" + value1.getClass().getName() + "," + + value2.getClass().getName() + "," + + value3.getClass().getName() + "," + + value4.getClass().getName() + + ")", args); + } + + protected void emit(String signal, boolean value) { + Object[] args = new Object[1]; + args[0] = new Boolean(value); + emit("2" + signal.trim() + "(boolean)", args); + } + + protected void emit(String signal, char value) { + Object[] args = new Object[1]; + args[0] = new Character(value); + emit("2" + signal.trim() + "(char)", args); + } + + protected void emit(String signal, byte value) { + Object[] args = new Object[1]; + args[0] = new Byte(value); + emit("2" + signal.trim() + "(byte)", args); + } + + protected void emit(String signal, short value) { + Object[] args = new Object[1]; + args[0] = new Short(value); + emit("2" + signal.trim() + "(short)", args); + } + + protected void emit(String signal, int value) { + Object[] args = new Object[1]; + args[0] = new Integer(value); + emit("2" + signal.trim() + "(int)", args); + } + + protected void emit(String signal, int value1, int value2) { + Object[] args = new Object[2]; + args[0] = new Integer(value1); + args[1] = new Integer(value2); + emit("2" + signal.trim() + "(int,int)", args); + } + + protected void emit(String signal, Object value1, int value2) { + Object[] args = new Object[2]; + args[0] = value1; + args[1] = new Integer(value2); + emit("2" + signal.trim() + "(" + value1.getClass().getName() + "," + + "int" + + ")", args); + } + + protected void emit(String signal, int value1, int value2, int value3) { + Object[] args = new Object[3]; + args[0] = new Integer(value1); + args[1] = new Integer(value2); + args[2] = new Integer(value3); + emit("2" + signal.trim() + "(int,int,int)", args); + } + + protected void emit(String signal, int value1, int value2, int value3, Object value4) { + Object[] args = new Object[4]; + args[0] = new Integer(value1); + args[1] = new Integer(value2); + args[2] = new Integer(value3); + args[3] = value4; + emit("2" + signal.trim() + "(int,int,int," + value4.getClass().getName() + ")", args); + } + + protected void emit(String signal, int value1, Object value2, Object value3) { + Object[] args = new Object[3]; + args[0] = new Integer(value1); + args[1] = value2; + args[2] = value3; + emit("2" + signal.trim() + "(int," + + value2.getClass().getName() + "," + + value3.getClass().getName() + + ")", args); + } + + protected void emit(String signal, int value1, Object value2, Object value3, int value4) { + Object[] args = new Object[4]; + args[0] = new Integer(value1); + args[1] = value2; + args[2] = value3; + args[3] = new Integer(value4); + emit("2" + signal.trim() + "(int," + + value2.getClass().getName() + "," + + value3.getClass().getName() + + ",int)", args); + } + + protected void emit(String signal, int value1, boolean value2) { + Object[] args = new Object[2]; + args[0] = new Integer(value1); + args[1] = new Boolean(value2); + emit("2" + signal.trim() + "(int,boolean)", args); + } + + protected void emit(String signal, long value) { + Object[] args = new Object[1]; + args[0] = new Long(value); + emit("2" + signal.trim() + "(long)", args); + } + + protected void emit(String signal, float value) { + Object[] args = new Object[1]; + args[0] = new Float(value); + emit("2" + signal.trim() + "(float)", args); + } + + protected void emit(String signal, double value) { + Object[] args = new Object[1]; + args[0] = new Double(value); + emit("2" + signal.trim() + "(double)", args); + } + + protected void emit(String signal, Object value1, int value2, int value3) { + Object[] args = new Object[3]; + args[0] = value1; + args[1] = new Integer(value2); + args[2] = new Integer(value3); + emit("2" + signal.trim() + "(" + value1.getClass().getName() + ",int,int)", args); + } + +EOF + + $qobjectjniExtras = <<EOF; +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QObject_connect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv* env, jclass cls, jobject sender, jstring signal, jobject receiver, jstring member) +{ + (void) cls; + return (jboolean) QtSupport::connect(env, sender, signal, receiver, member); +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QObject_connect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Ljava_lang_String_2(JNIEnv* env, jobject obj, jobject sender, jstring signal, jstring member) +{ + return (jboolean) QtSupport::connect(env, sender, signal, obj, member); +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QObject_disconnect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jclass cls, jobject sender, jstring signal, jobject receiver, jstring member) +{ + (void) cls; + return (jboolean) QtSupport::disconnect(env, sender, signal, receiver, member); +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QObject_disconnect__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv* env, jobject obj, jstring signal, jobject receiver, jstring member) +{ + return (jboolean) QtSupport::disconnect(env, obj, signal, receiver, member); +} + +JNIEXPORT void JNICALL +Java_org_kde_qt_QObject_emit(JNIEnv* env, jobject obj, jstring signal, jobjectArray args) +{ + QtSupport::emitJavaSignal(env, obj, signal, args); + return; +} + +EOF + + $qwidgetExtras = <<EOF; + /** Internal method */ + protected native long paintDevice(); + +EOF + + $qwidgetjniExtras = <<EOF; +JNIEXPORT jlong JNICALL +Java_org_kde_qt_QWidget_paintDevice(JNIEnv* env, jobject obj) +{ + return (jlong) (QPaintDevice*)(QWidget*) QtSupport::getQt(env, obj); +} + +EOF + + $qimagejniExtras = <<EOF; +JNIEXPORT jbyteArray JNICALL +Java_org_kde_qt_QImage_bits(JNIEnv *env, jobject obj) +{ +static uchar * ptr = 0; + ptr = ((QImageJBridge*) QtSupport::getQt(env, obj))->bits(); + int len = ((QImageJBridge*) QtSupport::getQt(env, obj))->numBytes(); + jbyteArray result = env->NewByteArray(len); + env->SetByteArrayRegion(result, 0, len, (jbyte *) ptr); + return result; +} + +JNIEXPORT jbyteArray JNICALL +Java_org_kde_qt_QImage_scanLine(JNIEnv *env, jobject obj, jint arg1) +{ +static uchar * ptr = 0; + ptr = ((QImageJBridge*) QtSupport::getQt(env, obj))->scanLine(arg1); + int len = ((QImageJBridge*) QtSupport::getQt(env, obj))->numBytes() / ((QImageJBridge*) QtSupport::getQt(env, obj))->height(); + jbyteArray result = env->NewByteArray(len); + env->SetByteArrayRegion(result, 0, len, (jbyte *) ptr); + return result; +} + +JNIEXPORT jintArray JNICALL +Java_org_kde_qt_QImage_colorTable(JNIEnv *env, jobject obj) +{ +static QRgb * ptr = 0; + ptr = ((QImageJBridge*) QtSupport::getQt(env, obj))->colorTable(); + int len = ((QImageJBridge*) QtSupport::getQt(env, obj))->numColors(); + jintArray result = env->NewIntArray(len); + env->SetIntArrayRegion(result, 0, len, (jint *) ptr); + return result; +} + +EOF + + $qpixmapExtras = <<EOF; + public native boolean loadFromData(char[] data); + + /** Internal method */ + protected native long paintDevice(); + +EOF + + $qpixmapjniExtras = <<EOF; +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPixmap_loadFromData___3C(JNIEnv *env, jobject obj, jcharArray data) +{ +static QByteArray * _qbyteArray_data = 0; + return (jboolean) ((QPixmapJBridge*) QtSupport::getQt(env, obj))->loadFromData((uchar *) QtSupport::toUcharArray(env, data, &_qbyteArray_data), env->GetArrayLength(data), 0, 0); +} + +JNIEXPORT jlong JNICALL +Java_org_kde_qt_QPixmap_paintDevice(JNIEnv* env, jobject obj) +{ + return (jlong) (QPaintDevice*)(QPixmap*) QtSupport::getQt(env, obj); +} + +EOF + + $qpaintdeviceExtras = <<EOF; + /** Internal method */ + protected native long paintDevice(); + +EOF + + $qpaintdevicejniExtras = <<EOF; +JNIEXPORT jlong JNICALL +Java_org_kde_qt_QPaintDevice_paintDevice(JNIEnv* env, jobject obj) +{ + return (jlong) (QPaintDevice *) QtSupport::getQt(env, obj); +} + +EOF + + $qdragobjectExtras = <<EOF; + /** Internal method */ + protected native long mimeSource(); + +EOF + + $qdragobjectjniExtras = <<EOF; +JNIEXPORT jlong JNICALL +Java_org_kde_qt_QDragObject_mimeSource(JNIEnv* env, jobject obj) +{ + return (jlong) (QMimeSource*) (QDragObject*) QtSupport::getQt(env, obj); +} + +EOF + + $qdropeventExtras = <<EOF; + /** Internal method */ + protected native long mimeSource(); + +EOF + + $qdropeventjniExtras = <<EOF; +JNIEXPORT jlong JNICALL +Java_org_kde_qt_QDropEvent_mimeSource(JNIEnv* env, jobject obj) +{ + return (jlong) (QMimeSource*) (QDropEvent*) QtSupport::getQt(env, obj); +} + +EOF + + $qmimesourceExtras = <<EOF; + /** Internal method */ + protected native long mimeSource(); + +EOF + + $qmimesourcejniExtras = <<EOF; +JNIEXPORT jlong JNICALL +Java_org_kde_qt_QMimeSource_mimeSource(JNIEnv* env, jobject obj) +{ + return (jlong) (QMimeSource *) QtSupport::getQt(env, obj); +} + +EOF + + $qiodeviceExtras = <<EOF; + public static final int IO_Direct = 0x0100; // direct access device + public static final int IO_Sequential = 0x0200; // sequential access device + public static final int IO_Combined = 0x0300; // combined direct/sequential + public static final int IO_TypeMask = 0x0f00; + +// IO handling modes + + public static final int IO_Raw = 0x0040; // raw access (not buffered) + public static final int IO_Async = 0x0080; // asynchronous mode + +// IO device open modes + + public static final int IO_ReadOnly = 0x0001; // readable device + public static final int IO_WriteOnly = 0x0002; // writable device + public static final int IO_ReadWrite = 0x0003; // read+write device + public static final int IO_Append = 0x0004; // append + public static final int IO_Truncate = 0x0008; // truncate device + public static final int IO_Translate = 0x0010; // translate CR+LF + public static final int IO_ModeMask = 0x00ff; + +// IO device state + + public static final int IO_Open = 0x1000; // device is open + public static final int IO_StateMask = 0xf000; + + +// IO device status + + public static final int IO_Ok = 0; + public static final int IO_ReadError = 1; // read error + public static final int IO_WriteError = 2; // write error + public static final int IO_FatalError = 3; // fatal unrecoverable error + public static final int IO_ResourceError = 4; // resource limitation + public static final int IO_OpenError = 5; // cannot open device + public static final int IO_ConnectError = 5; // cannot connect to device + public static final int IO_AbortError = 6; // abort error + public static final int IO_TimeOutError = 7; // time out + public static final int IO_UnspecifiedError = 8; // unspecified error + +EOF + + $qpointarrayExtras = <<EOF; + public native int size(); + public native int count(); + public native boolean isEmpty(); + public native boolean isNull(); + public native boolean resize( int size); + public native boolean truncate( int pos); + public native int begin(); + public native int end(); + public native QPoint at(int index); + +EOF + + $qpointarrayjniExtras = <<EOF; +JNIEXPORT void JNICALL +Java_org_kde_qt_QPointArray_point__I_3I_3I(JNIEnv *env, jobject obj, jint i, jintArray x, jintArray y) +{ + int argx; + int argy; + ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->point((uint) i, &argx, &argy); + env->SetIntArrayRegion(x, 0, 1, (jint *) &argx); + env->SetIntArrayRegion(y, 0, 1, (jint *) &argy); + return; +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPointArray_setPoints(JNIEnv *env, jobject obj, jint nPoints, jshortArray points) +{ + if (!((QPointArrayJBridge*) QtSupport::getQt(env, obj))->resize((uint)nPoints)) { + return JNI_FALSE; + } + + short * shortArray = QtSupport::toShortPtr(env, points); + for (int index = 0; index < nPoints; index++) { + ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->setPoint(index, shortArray[index * 2], shortArray[(index * 2) + 1]); + } + return JNI_TRUE; +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPointArray_putPoints__II_3S(JNIEnv *env, jobject obj, jint index, jint nPoints, jshortArray points) +{ + if ( ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->size() < (uint) nPoints + && !((QPointArrayJBridge*) QtSupport::getQt(env, obj))->resize((uint) nPoints) ) + { + return JNI_FALSE; + } + + short * shortArray = QtSupport::toShortPtr(env, points); + for (int i = (int) index; nPoints > 0; i++, nPoints--) { + ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->setPoint(i, shortArray[i * 2], shortArray[(i * 2) + 1]); + } + return JNI_TRUE; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QPointArray_size(JNIEnv* env, jobject obj) +{ + return (jint) ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->size(); +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QPointArray_count(JNIEnv* env, jobject obj) +{ + return (jint) ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->count(); +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPointArray_isEmpty(JNIEnv* env, jobject obj) +{ + return (jboolean) ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->isEmpty(); +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPointArray_isNull(JNIEnv* env, jobject obj) +{ + return (jboolean) ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->isNull(); +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPointArray_resize(JNIEnv* env, jobject obj, jint size) +{ + return (jboolean) ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->resize((uint) size); +} +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPointArray_truncate(JNIEnv *env, jobject obj, jint pos) +{ + return (jboolean) ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->truncate((uint) pos); +} + +JNIEXPORT jobject JNICALL +Java_org_kde_qt_QPointArray_at(JNIEnv * env, jobject obj, jint index) +{ + QPoint _p= ((QPointArrayJBridge*) QtSupport::getQt(env, obj))->at((uint) index); + return (jobject) QtSupport::objectForQtKey(env, (void *)new QPoint(_p.x(),_p.y()), "org.kde.qt.QPoint", TRUE); +} + +EOF + + $qpopupmenujniExtras = <<EOF; +JNIEXPORT jint JNICALL +Java_org_kde_qt_QPopupMenu_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QKeySequence_2II(JNIEnv *env, jobject obj, jstring text, jobject receiver, jstring member, jobject accel, jint identifier, jint index) +{ + identifier = Java_org_kde_qt_QPopupMenu_insertItem__Ljava_lang_String_2II(env, obj, text, identifier, index); + + if ((bool) Java_org_kde_qt_QPopupMenu_connectItem(env, obj, identifier, receiver, member)) { + Java_org_kde_qt_QPopupMenu_setAccel(env, obj, accel, identifier); + } + + return identifier; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QPopupMenu_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jstring text, jobject receiver, jstring member) +{ + jint identifier = Java_org_kde_qt_QPopupMenu_insertItem__Ljava_lang_String_2II(env, obj, text, -1, -1); + Java_org_kde_qt_QPopupMenu_connectItem(env, obj, identifier, receiver, member); + + return identifier; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject icon, jstring text, jobject receiver, jstring member) +{ +static QString * _qstring_text = 0; + jint identifier = Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2II(env, obj, icon, text, -1, -1); + Java_org_kde_qt_QPopupMenu_connectItem(env, obj, identifier, receiver, member); + + return identifier; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject pixmap, jobject receiver, jstring member) +{ + jint identifier = Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QPixmap_2II(env, obj, pixmap, -1, -1); + Java_org_kde_qt_QPopupMenu_connectItem(env, obj, identifier, receiver, member); + + return identifier; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject icon, jobject pixmap, jobject receiver, jstring member) +{ + jint identifier = Java_org_kde_qt_QPopupMenu_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2II(env, obj, icon, pixmap, -1, -1); + Java_org_kde_qt_QPopupMenu_connectItem(env, obj, identifier, receiver, member); + + return identifier; +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPopupMenu_connectItem(JNIEnv *env, jobject obj, jint identifier, jobject receiver, jstring member) +{ + JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member); + + if ( ((QPopupMenuJBridge*) QtSupport::getQt(env, obj))->connectItem( identifier, + javaSlot, + javaSlot->javaToQtSlotName(env, member) ) ) + { + return(jboolean) JNI_TRUE; + } else { + return (jboolean) JNI_FALSE; + } +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QPopupMenu_disconnectItem(JNIEnv *env, jobject obj, jint identifier, jobject receiver, jstring member) +{ + JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member); + + if ( ((QPopupMenuJBridge*) QtSupport::getQt(env, obj))->disconnectItem( identifier, + javaSlot, + javaSlot->javaToQtSlotName(env, member) ) ) + { + return(jboolean) JNI_TRUE; + } else { + return (jboolean) JNI_FALSE; + } +} + +EOF + + $qmenudatajniExtras = <<EOF; +JNIEXPORT jint JNICALL +Java_org_kde_qt_QMenuData_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QKeySequence_2II(JNIEnv *env, jobject obj, jstring text, jobject receiver, jstring member, jobject accel, jint identifier, jint index) +{ + identifier = Java_org_kde_qt_QMenuData_insertItem__Ljava_lang_String_2II(env, obj, text, identifier, index); + + if ((bool) Java_org_kde_qt_QMenuData_connectItem(env, obj, identifier, receiver, member)) { + Java_org_kde_qt_QMenuData_setAccel(env, obj, accel, identifier); + } + + return identifier; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QMenuData_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jstring text, jobject receiver, jstring member) +{ + jint identifier = Java_org_kde_qt_QMenuData_insertItem__Ljava_lang_String_2II(env, obj, text, -1, -1); + Java_org_kde_qt_QMenuData_connectItem(env, obj, identifier, receiver, member); + + return identifier; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject icon, jstring text, jobject receiver, jstring member) +{ +static QString * _qstring_text = 0; + jint identifier = Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2II(env, obj, icon, text, -1, -1); + Java_org_kde_qt_QMenuData_connectItem(env, obj, identifier, receiver, member); + + return identifier; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject pixmap, jobject receiver, jstring member) +{ + jint identifier = Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QPixmap_2II(env, obj, pixmap, -1, -1); + Java_org_kde_qt_QMenuData_connectItem(env, obj, identifier, receiver, member); + + return identifier; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject icon, jobject pixmap, jobject receiver, jstring member) +{ + jint identifier = Java_org_kde_qt_QMenuData_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2II(env, obj, icon, pixmap, -1, -1); + Java_org_kde_qt_QMenuData_connectItem(env, obj, identifier, receiver, member); + + return identifier; +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QMenuData_connectItem(JNIEnv *env, jobject obj, jint identifier, jobject receiver, jstring member) +{ + JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member); + + if ( ((QMenuDataJBridge*) QtSupport::getQt(env, obj))->connectItem( identifier, + javaSlot, + javaSlot->javaToQtSlotName(env, member) ) ) + { + return(jboolean) JNI_TRUE; + } else { + return (jboolean) JNI_FALSE; + } +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QMenuData_disconnectItem(JNIEnv *env, jobject obj, jint identifier, jobject receiver, jstring member) +{ + JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member); + + if ( ((QMenuDataJBridge*) QtSupport::getQt(env, obj))->disconnectItem( identifier, + javaSlot, + javaSlot->javaToQtSlotName(env, member) ) ) + { + return(jboolean) JNI_TRUE; + } else { + return (jboolean) JNI_FALSE; + } +} + +EOF + + $qmenubarjniExtras = <<EOF; +JNIEXPORT jint JNICALL +Java_org_kde_qt_QMenuBar_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2Lorg_kde_qt_QKeySequence_2II(JNIEnv *env, jobject obj, jstring text, jobject receiver, jstring member, jobject accel, jint identifier, jint index) +{ + identifier = Java_org_kde_qt_QMenuBar_insertItem__Ljava_lang_String_2II(env, obj, text, identifier, index); + + if ((bool) Java_org_kde_qt_QMenuBar_connectItem(env, obj, identifier, receiver, member)) { + Java_org_kde_qt_QMenuBar_setAccel(env, obj, accel, identifier); + } + + return identifier; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QMenuBar_insertItem__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jstring text, jobject receiver, jstring member) +{ + jint identifier = Java_org_kde_qt_QMenuBar_insertItem__Ljava_lang_String_2II(env, obj, text, -1, -1); + Java_org_kde_qt_QMenuBar_connectItem(env, obj, identifier, receiver, member); + + return identifier; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject icon, jstring text, jobject receiver, jstring member) +{ +static QString * _qstring_text = 0; + jint identifier = Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QIconSet_2Ljava_lang_String_2II(env, obj, icon, text, -1, -1); + Java_org_kde_qt_QMenuBar_connectItem(env, obj, identifier, receiver, member); + + return identifier; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject pixmap, jobject receiver, jstring member) +{ + jint identifier = Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QPixmap_2II(env, obj, pixmap, -1, -1); + Java_org_kde_qt_QMenuBar_connectItem(env, obj, identifier, receiver, member); + + return identifier; +} + +JNIEXPORT jint JNICALL +Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject icon, jobject pixmap, jobject receiver, jstring member) +{ + jint identifier = Java_org_kde_qt_QMenuBar_insertItem__Lorg_kde_qt_QIconSet_2Lorg_kde_qt_QPixmap_2II(env, obj, icon, pixmap, -1, -1); + Java_org_kde_qt_QMenuBar_connectItem(env, obj, identifier, receiver, member); + + return identifier; +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QMenuBar_connectItem(JNIEnv *env, jobject obj, jint identifier, jobject receiver, jstring member) +{ + JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member); + + if ( ((QMenuBarJBridge*) QtSupport::getQt(env, obj))->connectItem( identifier, + javaSlot, + javaSlot->javaToQtSlotName(env, member) ) ) + { + return(jboolean) JNI_TRUE; + } else { + return (jboolean) JNI_FALSE; + } +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QMenuBar_disconnectItem(JNIEnv *env, jobject obj, jint identifier, jobject receiver, jstring member) +{ + JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member); + + if ( ((QMenuBarJBridge*) QtSupport::getQt(env, obj))->disconnectItem( identifier, + javaSlot, + javaSlot->javaToQtSlotName(env, member) ) ) + { + return(jboolean) JNI_TRUE; + } else { + return (jboolean) JNI_FALSE; + } +} + + +EOF + + $quridragExtras = <<EOF; + public static native boolean decode(QMimeSourceInterface e, ArrayList i); + public static native boolean decodeToUnicodeUris(QMimeSourceInterface e, ArrayList i); + public static native boolean decodeLocalFiles(QMimeSourceInterface e, ArrayList i); + +EOF + + $quridragjniExtras = <<EOF; +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QUriDrag_decode(JNIEnv *env, jclass cls, jobject e, jobject i) +{ +static QStrList * _qlist_i = 0; + if (_qlist_i == 0) { + _qlist_i = new QStrList(); + } + (void) cls; + jboolean result = (jboolean) QUriDragJBridge::decode(QtSupport::mimeSource(env, e), *_qlist_i); + QtSupport::arrayWithQStrList(env, _qlist_i, i); + return result; +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QUriDrag_decodeToUnicodeUris(JNIEnv *env, jclass cls, jobject e, jobject i) +{ +static QStringList * _qlist_i = 0; + if (_qlist_i == 0) { + _qlist_i = new QStringList(); + } + (void) cls; + jboolean result = (jboolean) QUriDragJBridge::decodeToUnicodeUris(QtSupport::mimeSource(env, e), *_qlist_i); + QtSupport::arrayWithQStringList(env, _qlist_i, i); + return result; +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_qt_QUriDrag_decodeLocalFiles(JNIEnv *env, jclass cls, jobject e, jobject i) +{ +static QStringList * _qlist_i = 0; + if (_qlist_i == 0) { + _qlist_i = new QStringList(); + } + (void) cls; + jboolean result = (jboolean) QUriDragJBridge::decodeLocalFiles(QtSupport::mimeSource(env, e), *_qlist_i); + QtSupport::arrayWithQStringList(env, _qlist_i, i); + return result; +} + +EOF + + $kapplicationExtras = <<EOF; + /** + Used internally by the KDE Koala Java bindings runtime + */ + public static native void setJavaSlotFactory(); + +EOF + + $kapplicationjniExtras = <<EOF; +#include <kdejava/KDEJavaSlot.h> + +JNIEXPORT void JNICALL +Java_org_kde_koala_KApplication_setJavaSlotFactory(JNIEnv* env, jclass cls) +{ + (void) env; + (void) cls; + JavaSlot::setJavaSlotFactory(new KDEJavaSlotFactory()); + return; +} + +EOF + + $kmainwindowExtras = <<EOF; + /** + List of members of KMainWindow class. + */ + public native ArrayList memberList(); + + public static void RESTORE(String typeName) { + Class savedClass; + + try { + savedClass = Class.forName(typeName); + int n = 1; + while (KMainWindow.canBeRestored(n)){ + ((KMainWindow) savedClass.newInstance()).restore(n); + n++; + } + } catch(Exception e) { + return; + } + + return; + } + +EOF + + $kmainwindowjniExtras = <<EOF; +JNIEXPORT jobject JNICALL +Java_org_kde_koala_KMainWindow_memberList(JNIEnv* env, jobject obj) +{ + return (jobject) KDESupport::arrayWithKMainWindowList(env, KMainWindow::memberList); +} + +EOF + + $kcmdlineargsjniExtras = <<EOF; +JNIEXPORT void JNICALL +Java_org_kde_koala_KCmdLineArgs_init___3Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2(JNIEnv* env, jclass cls, jobjectArray args, jstring _appname, jstring programName, jstring _description, jstring _version) +{ + (void) cls; +static QCString* _qstring__appname = 0; +static QCString* _qstring_programName = 0; +static QCString* _qstring__description = 0; +static QCString* _qstring__version = 0; + int argc = (int) env->GetArrayLength(args); + KCmdLineArgsJBridge::init((int) argc+1, (char**) QtSupport::toArgv(env, args), (const char*) QtSupport::toCharString(env, _appname, &_qstring__appname), (const char*) QtSupport::toCharString(env, programName, &_qstring_programName), (const char*) QtSupport::toCharString(env, _description, &_qstring__description), (const char*) QtSupport::toCharString(env, _version, &_qstring__version)); + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_koala_KCmdLineArgs_init___3Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Ljava_lang_String_2Z(JNIEnv* env, jclass cls, jobjectArray args, jstring _appname, jstring programName, jstring _description, jstring _version, jboolean noKApp) +{ + (void) cls; +static QCString* _qstring__appname = 0; +static QCString* _qstring_programName = 0; +static QCString* _qstring__description = 0; +static QCString* _qstring__version = 0; + int argc = (int) env->GetArrayLength(args); + KCmdLineArgsJBridge::init(argc+1, (char**) QtSupport::toArgv(env, args), (const char*) QtSupport::toCharString(env, _appname, &_qstring__appname), (const char*) QtSupport::toCharString(env, programName, &_qstring_programName), (const char*) QtSupport::toCharString(env, _description, &_qstring__description), (const char*) QtSupport::toCharString(env, _version, &_qstring__version), (bool) noKApp); + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_koala_KCmdLineArgs_init___3Ljava_lang_String_2Lorg_kde_koala_KAboutData_2(JNIEnv* env, jclass cls, jobjectArray args, jobject about) +{ + (void) cls; + int argc = (int) env->GetArrayLength(args); + KCmdLineArgsJBridge::init(argc+1, (char**) QtSupport::toArgv(env, args), (const KAboutData*) QtSupport::getQt(env, about)); + return; +} + +JNIEXPORT void JNICALL +Java_org_kde_koala_KCmdLineArgs_init___3Ljava_lang_String_2Lorg_kde_koala_KAboutData_2Z(JNIEnv* env, jclass cls, jobjectArray args, jobject about, jboolean noKApp) +{ + (void) cls; + int argc = (int) env->GetArrayLength(args); + KCmdLineArgsJBridge::init(argc+1, (char**) QtSupport::toArgv(env, args), (const KAboutData*) QtSupport::getQt(env, about), (bool) noKApp); + return; +} + +EOF + + $schedulerjniExtras = <<EOF; +JNIEXPORT jboolean JNICALL +Java_org_kde_koala_Scheduler_connect__Ljava_lang_String_2Lorg_kde_qt_QObject_2Ljava_lang_String_2(JNIEnv* env, jclass cls, jstring signal, jobject receiver, jstring member) +{ + (void) cls; + JavaSlot * javaSlot = QtSupport::slotForReceiver(env, receiver, member); + QString qtSignalName(javaSlot->javaToQtSignalName(env, signal, 0)); + jboolean xret = (jboolean) SchedulerJBridge::connect((const char*) qtSignalName, (const QObject*) javaSlot, javaSlot->javaToQtSlotName(env, member, qtSignalName)); + return xret; +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_koala_Scheduler_connect__Lorg_kde_qt_QObject_2Ljava_lang_String_2Ljava_lang_String_2(JNIEnv *env, jobject obj, jobject sender, jstring signal, jstring member) +{ + return QtSupport::connect(env, sender, signal, obj, member); +} + +JNIEXPORT jboolean JNICALL +Java_org_kde_koala_Scheduler_disconnect(JNIEnv *env, jclass cls, jobject sender, jstring signal, jobject receiver, jstring member) +{ + (void) cls; + return QtSupport::disconnect(env, sender, signal, receiver, member); +} + +EOF + +} + +sub javaImport($) +{ + my ( $classname ) = @_; + my $classname_ptr = $classname . "*"; + if ( cplusplusToJava($classname_ptr) eq "" or $classname eq $main::globalSpaceClassName ) { + return ""; + } elsif ( cplusplusToJava($classname_ptr) eq "ArrayList" ) { + return "java.util.ArrayList"; + } elsif ( cplusplusToJava($classname_ptr) eq "Calendar" ) { + return "java.util.Calendar"; + } elsif ( cplusplusToJava($classname_ptr) eq "StringBuffer" ) { + return ""; + } elsif ( cplusplusToJava($classname_ptr) eq "String" ) { + return ""; + } elsif ( cplusplusToJava($classname_ptr) eq "String[][]" ) { + return ""; + } elsif ( cplusplusToJava($classname_ptr) eq "String[]" ) { + return ""; + } elsif ( cplusplusToJava($classname_ptr) eq "Date" ) { + return "java.util.Date"; + } elsif ( cplusplusToJava($classname_ptr) =~ /^[a-z]/ ) { + return ""; + } elsif ( $classname =~ /^Q/ ) { + return "org.kde.qt." . $classname; + } else { + return "org.kde.koala." . $classname; + } +} + +sub cplusplusToJava +{ + my ( $cplusplusType ) = @_; + my $isConst = ($cplusplusType =~ /const / or $cplusplusType !~ /[*&]/ ? 1 : 0); + $cplusplusType =~ s/const //; + $cplusplusType =~ s/^signed//; + my $className = $cplusplusType; + $className =~ s/[*&]//; + + if ( $cplusplusType =~ /void\*|DCOPArg|DCOPRef|^MSG\s*\*|QGfx|^Display\s*\*|KHTMLPart::PageSecurity|QFileInfoList|QValueList<QIconDragItem>|QValueList<QCString>|QValueList<QVariant>|QValueList<QPixmap>|QValueListConstIterator<QString>|QMap|EditMode|QPtrList<QPixmap>|QPtrList<QPoint>|QTextFormat|QTextCursor|QTextDocument|QNetworkProtocolFactoryBase|QDomNodePrivate|QSqlDriverCreatorBase|QSqlFieldInfoList|QObjectUserData|QUObject|QTextParag|QWidgetMapper|QMemArray<int>|QBitArray|QLayoutIterator|QAuBucket|QUnknownInterface|QConnectionList/ ) { + return ""; # Unsupported type + } elsif ( $cplusplusType =~ /QSignal\s*\*|QMenuItem|QWSEvent|QWSDisplay|QWSSocket|QPaintDeviceX11Data|QWindowsMime|QDirectPainter|QMember|QDiskFont|QGCache|QRichText|QWSDecoration/ && $main::qt_embedded ) { + return ""; # Unsupported Qt/E type + } elsif ( $cplusplusType =~ /bool/ && kalyptusDataDict::ctypemap($cplusplusType) eq "int" ) { + return "boolean"; + } elsif ( $cplusplusType =~ /bool\s*[*&]/ ) { + return "boolean[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^void\s*\*/ ) { + return "int"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^\s*(unsigned )?int\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /^qt_QIntValueList\*/ + || $cplusplusType =~ /^int[*&]$/ ) + { + return "int[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^\s*double\s*\*/ ) { + return "double[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /^\s*(unsigned )?short\s*\*/ ) { + return "short[]"; + } elsif ( $cplusplusType =~ /KCmdLineOptions/ ) { + return "String[][]"; + } elsif ( $cplusplusType =~ /char\s*\*\*/ || $cplusplusType =~ /QStringList/|| $cplusplusType =~ /QStrList/) { + return "String[]"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QUrlInfoValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QVariantValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QIconDragItemValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QPixmapValueList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_QCStringList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QObjectList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QDomNodeList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QWidgetList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KURLList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KMainWindow\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KFileItemList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_KFileViewItemList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_DOMNodeList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_StyleSheetList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_MediaList\s*\*/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_OfferList\s*\*/ + || $cplusplusType =~ /QMemArray<QRect>/ + || $cplusplusType =~ /QArray<QRect>/ + || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QCanvasItemList\s*\*/ ) { + return "ArrayList" + } elsif ( $cplusplusType =~ /uchar\s*\*/ ) { + return "char[]"; + } elsif ( $cplusplusType =~ /QC?String/ and !$isConst ) { + return "StringBuffer" + } elsif ( $cplusplusType =~ /(DOM::)?DOMString/ || $cplusplusType =~ /QString/ || $cplusplusType =~ /QCString/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /^(const )?char\s*\*/ ) { + return "String" + } elsif ( $cplusplusType =~ /QChar\s*[&\*]?/ || $cplusplusType =~ /^char$/ ) { + return "char" + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QTime\s*\*/ ) { + return "Date" + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QDateTime\s*\*/ || kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_QDate\s*\*/ ) { + return "Calendar" + } elsif ( $cplusplusType =~ /QPaintDevice/ ) { + return "QPaintDeviceInterface" + } elsif ( $cplusplusType =~ /QByteArray/ ) { + return "byte[]" + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /qt_([^\*\s]*)(.*)$/ and !$skippedClasses{$className}) { + if ( kalyptusDataDict::interfacemap($1) ne () ) { + return $1."Interface"; + } else { + return $1; + } + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /kde_([^\*\s]*)(.*)$/ and !$skippedClasses{$className}) { + if ( kalyptusDataDict::interfacemap($1) ne () ) { + return $1."Interface"; + } else { + return $1; + } + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /unsigned char/ ) { + return "short"; + } elsif ( $typedeflist{$cplusplusType} =~ /ulong|long/ ) { + return "long"; + } elsif ( $typedeflist{$cplusplusType} =~ /uint|int/ or $cplusplusType =~ /^int\&$/ ) { + return "int"; + } elsif ( $typedeflist{$cplusplusType} =~ /ushort|short/ ) { + return "short"; + } elsif ( kalyptusDataDict::ctypemap($cplusplusType) =~ /(unsigned )(.*)/ ) { + return $2; + } else { + my $node; + my $item; + if ($className =~ /^(\w+)::(\w+)$/) { + $node = kdocAstUtil::findRef( $rootnode, $1 ); + $item = kdocAstUtil::findRef( $node, $2 ) if defined $node; + if (defined $item && $item->{NodeType} eq 'enum') { + return "int"; + } elsif (defined $item && ($item->{NodeType} eq 'class' || $item->{NodeType} eq 'struct')) { + return $skippedClasses{$className} ? "" : $2; + } + } + + if ($className =~ /^\w+$/) { + $item = kdocAstUtil::findRef( $rootnode, $className ); + if (defined $item && ($item->{NodeType} eq 'class' || $item->{NodeType} eq 'struct')) { + return $skippedClasses{$className} ? "" : $className; + } + } + return kalyptusDataDict::ctypemap($cplusplusType); + } + +} + +sub cplusplusToJNI +{ + my ( $cplusplusType ) = @_; + my $javaType = cplusplusToJava( $cplusplusType ); + + if ( $cplusplusType =~ /void/ ) { + return "void" + } elsif ( $javaType =~ /^Calendar$/ ) { + return "jobject" + } elsif ( $javaType =~ /^Date$/ ) { + return "jobject" + } elsif ( $javaType =~ /ArrayList/ ) { + return "jobjectArray" + } elsif ( $javaType =~ /String\[\]\[\]/ ) { + return "jobjectArray"; + } elsif ( $javaType =~ /String\[\]/ ) { + return "jobjectArray"; + } elsif ( $javaType =~ /StringBuffer/ ) { + return "jobject"; + } elsif ( $javaType =~ /^String$/ ) { + return "jstring"; + } elsif ( $javaType =~ /boolean\[\]/ ) { + return "jbooleanArray"; + } elsif ( $javaType =~ /char\[\]/ ) { + return "jcharArray"; + } elsif ( $javaType =~ /byte\[\]/ ) { + return "jbyteArray"; + } elsif ( $javaType =~ /short\[\]/ ) { + return "jshortArray"; + } elsif ( $javaType =~ /int\[\]/ ) { + return "jintArray"; + } elsif ( $javaType =~ /double\[\]/ ) { + return "jdoubleArray"; + } elsif ( $javaType =~ /^Q/ ) { + return "jobject"; + } elsif ( $javaType =~ /^[A-Z]/ ) { + return "jobject"; + } elsif ( $javaType =~ /^boolean\s*/ ) { + return "jboolean"; + } elsif ( $javaType =~ /^byte\s*/ ) { + return "jbyte"; + } elsif ( $javaType =~ /^char\s*/ ) { + return "jchar"; + } elsif ( $javaType =~ /^short\s*/ ) { + return "jshort"; + } elsif ( $javaType =~ /^int\s*/ ) { + return "jint"; + } elsif ( $javaType =~ /^long\s*/ ) { + return "jlong"; + } elsif ( $javaType =~ /^float\s*/ ) { + return "jfloat"; + } elsif ( $javaType =~ /^double\s*/ ) { + return "jdouble"; + } else { + return ""; + } + +} + +sub cplusplusToJNISignature +{ + my ( $cplusplusType ) = @_; + my $javaType = cplusplusToJava( $cplusplusType ); + + if ( $javaType =~ /^Calendar$/ ) { + return "Ljava_util_Calendar_2" + } elsif ( $javaType eq 'Date' ) { + return "Ljava_util_Date_2" + } elsif ( $javaType =~ /ArrayList/ ) { + return "Ljava_util_ArrayList_2" + } elsif ( $javaType =~ /String\[\]\[\]/ ) { + return "_3_3Ljava_lang_String_2"; + } elsif ( $javaType =~ /String\[\]/ ) { + return "_3Ljava_lang_String_2"; + } elsif ( $javaType =~ /StringBuffer/ ) { + return "Ljava_lang_StringBuffer_2"; + } elsif ( $javaType eq 'String' ) { + return "Ljava_lang_String_2"; + } elsif ( $javaType =~ /boolean\[\]/ ) { + return "_3Z"; + } elsif ( $javaType =~ /char\[\]/ ) { + return "_3C"; + } elsif ( $javaType =~ /byte\[\]/ ) { + return "_3B"; + } elsif ( $javaType =~ /short\[\]/ ) { + return "_3S"; + } elsif ( $javaType =~ /int\[\]/ ) { + return "_3I"; + } elsif ( $javaType =~ /double\[\]/ ) { + return "_3D"; + } elsif ( $javaType =~ /^Q/ ) { + return "Lorg_kde_qt_$javaType"."_2"; + } elsif ( $javaType =~ /^[A-Z]/ ) { + return "Lorg_kde_koala_$javaType"."_2"; + } elsif ( $javaType =~ /^boolean\s*/ ) { + return "Z"; + } elsif ( $javaType =~ /^byte\s*/ ) { + return "B"; + } elsif ( $javaType =~ /^char\s*/ ) { + return "C"; + } elsif ( $javaType =~ /^short\s*/ ) { + return "S"; + } elsif ( $javaType =~ /^int\s*/ ) { + return "I"; + } elsif ( $javaType =~ /^long\s*/ ) { + return "J"; + } elsif ( $javaType =~ /^float\s*/ ) { + return "F"; + } elsif ( $javaType =~ /^double\s*/ ) { + return "D"; + } else { + return ""; + } + +} + +sub jniArgTocplusplus +{ + my ( $cplusplusType, $argName ) = @_; + my $jniLocal = ''; # output + my $jniArg = ''; # output + my $jniCleanup = ''; # output + + my $javaType = cplusplusToJava( $cplusplusType ); + my $jniType = cplusplusToJNI( $cplusplusType ); + + if ( $javaType =~ /^Calendar$/ ) { + my $dateclass = $cplusplusType =~ /QDateTime/ ? "QDateTime" : "QDate"; + $jniLocal = "static $dateclass* _qdate_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::to$dateclass(env, $argName, &_qdate_$argName)"; + } else { + $jniArg = "($cplusplusType)*($dateclass*) QtSupport::to$dateclass(env, $argName, &_qdate_$argName)"; + } + } elsif ( $javaType =~ /^Date$/ ) { + $jniLocal = "static QTime* _qtime_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toQTime(env, $argName, &_qtime_$argName)"; + } else { + $jniArg = "($cplusplusType)*(QTime*) QtSupport::toQTime(env, $argName, &_qtime_$argName)"; + } + } elsif ( $javaType =~ /ArrayList/ ) { + if ( $cplusplusType =~ /KFileItemList/ ) { + $jniLocal ="static KFileItemList* _qlist_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) KDESupport::toKFileItemList(env, $argName, &_qlist_$argName)"; + } else { + $jniArg = "($cplusplusType)*(QStrList*) KDESupport::toKFileItemList(env, $argName, &_qlist_$argName)"; + } + } elsif ( $cplusplusType =~ /QCStringList/ ) { + $jniLocal ="static QCStringList* _qlist_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) KDESupport::toQCStringList(env, $argName, &_qlist_$argName)"; + } else { + $jniArg = "($cplusplusType)*(QCStringList*) KDESupport::toQCStringList(env, $argName, &_qlist_$argName)"; + } + } elsif ( $cplusplusType =~ /KURL::List/ ) { + $jniLocal ="static KURL::List* _qlist_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) KDESupport::toKURLList(env, $argName, &_qlist_$argName)"; + } else { + $jniArg = "($cplusplusType)*(KURL::List*) KDESupport::toKURLList(env, $argName, &_qlist_$argName)"; + } + } + } elsif ( $javaType =~ /String\[\]\[\]/ ) { + if ( $cplusplusType =~ /KCmdLineOptions/ ) { + $jniArg = "(KCmdLineOptions*) KDESupport::toKCmdLineOptions(env, $argName)"; + } + } elsif ( $javaType =~ /String\[\]/ ) { + if ( $cplusplusType =~ /QStringList/ ) { + $jniLocal ="static QStringList* _qlist_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toQStringList(env, $argName, &_qlist_$argName)"; + } else { + $jniArg = "($cplusplusType)*(QStringList*) QtSupport::toQStringList(env, $argName, &_qlist_$argName)"; + } + } elsif ( $cplusplusType =~ /QStrList/ ) { + $jniLocal ="static QStrList* _qlist_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toQStrList(env, $argName, &_qlist_$argName)"; + } else { + $jniArg = "($cplusplusType)*(QStrList*) QtSupport::toQStrList(env, $argName, &_qlist_$argName)"; + } + } elsif ( $cplusplusType =~ /char\s*\*\*/ ) { + $jniArg = "($cplusplusType) QtSupport::toStringArray(env, $argName)"; + } + } elsif ( $javaType =~ /StringBuffer/ ) { + if ( $cplusplusType =~ /QCString/ ) { + $jniLocal = "static QCString* _qcstring_$argName = 0;\n"; + $jniLocal .= "\tif (_qcstring_$argName == 0) {\n"; + $jniLocal .= "\t\t_qcstring_$argName = new QCString();\n"; + $jniLocal .= "\t}\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) _qcstring_$argName"; + } else { + $jniArg = "($cplusplusType)*(QCString*) _qcstring_$argName"; + } + $jniCleanup = "\tQtSupport::fromQCStringToStringBuffer(env, _qcstring_$argName, $argName);\n"; + } else { + $jniLocal ="static QString* _qstring_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toQStringFromStringBuffer(env, $argName, &_qstring_$argName)"; + } else { + $jniArg = "($cplusplusType)*(QString*) QtSupport::toQStringFromStringBuffer(env, $argName, &_qstring_$argName)"; + } + $jniCleanup = "\tQtSupport::fromQStringToStringBuffer(env, _qstring_$argName, $argName);\n"; + } + } elsif ( $javaType =~ /^String$/ ) { + if ( $cplusplusType =~ /QString/ ) { + $jniLocal ="static QString* _qstring_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toQString(env, $argName, &_qstring_$argName)"; + } else { + $jniArg = "($cplusplusType)*(QString*) QtSupport::toQString(env, $argName, &_qstring_$argName)"; + } + } elsif ( $cplusplusType =~ /QCString/ ) { + $jniLocal ="static QCString* _qcstring_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toQCString(env, $argName, &_qcstring_$argName)"; + } else { + $jniArg = "($cplusplusType)*(QCString*) QtSupport::toQCString(env, $argName, &_qcstring_$argName)"; + } + } elsif ( $cplusplusType =~ /DOMString/ ) { + $jniLocal ="static DOM::DOMString* _domstring_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "(DOM::DOMString*) KDESupport::toDOMString(env, $argName, &_domstring_$argName)"; + } else { + $jniArg = "(DOM::DOMString)*(DOM::DOMString*) KDESupport::toDOMString(env, $argName, &_domstring_$argName)"; + } + } else { + $jniLocal ="static QCString* _qstring_$argName = 0;\n"; + $jniArg = "($cplusplusType) ". ($cplusplusType =~ /[\&]/ ? "*(char*)" : "") . "QtSupport::toCharString(env, $argName, &_qstring_$argName)"; + } + } elsif ( $javaType =~ /boolean\[\]/ ) { + $jniLocal ="\tbool* _bool_$argName = QtSupport::toBooleanPtr(env, $argName);\n"; + $jniArg = " ($cplusplusType) " . ($cplusplusType =~ /[\*]/ ? "" : "*") . "_bool_$argName"; + $jniCleanup = "\tenv->SetBooleanArrayRegion($argName, 0, 1, (jboolean*) _bool_$argName);\n"; + } elsif ( $javaType =~ /char\[\]/ ) { + $jniLocal ="static QByteArray* _qbytearray_$argName = 0;\n"; + $jniArg = "($cplusplusType) QtSupport::toUcharArray(env, $argName, &_qbytearray_$argName)"; + } elsif ( $javaType =~ /byte\[\]/ ) { + $jniLocal = "static QByteArray* _qbyteArray_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toQByteArray(env, $argName, &_qbyteArray_$argName)"; + } else { + $jniArg = "($cplusplusType)*(QByteArray*) QtSupport::toQByteArray(env, $argName, &_qbyteArray_$argName)"; + } + } elsif ( $javaType =~ /short\[\]/ ) { + $jniLocal ="\tshort* _short_$argName = QtSupport::toShortPtr(env, $argName);\n"; + $jniArg = " ($cplusplusType) " . ($cplusplusType =~ /[\*]/ ? "" : "*") . "_short_$argName"; + $jniCleanup = "\tenv->SetShortArrayRegion($argName, 0, 1, (jshort*) _short_$argName);\n"; + } elsif ( $javaType =~ /int\[\]/ ) { + if ( $cplusplusType =~ /QValueList/ ) { + $jniLocal = "static QValueList<int>* _qlist_$argName = 0;\n"; + $jniArg = "($cplusplusType) QtSupport::toQIntValueList(env, $argName, &_qlist_$argName)"; + } else { + $jniLocal ="\tint* _int_$argName = QtSupport::toIntPtr(env, $argName);\n"; + $jniArg = " ($cplusplusType) " . ($cplusplusType =~ /[\*]/ ? "" : "*") . "_int_$argName"; + $jniCleanup = "\tenv->SetIntArrayRegion($argName, 0, 1, (jint *) _int_$argName);\n"; + } + } elsif ( $javaType =~ /double\[\]/ ) { + $jniLocal ="\tdouble* _double_$argName = QtSupport::toDoublePtr(env, $argName);\n"; + $jniArg = " ($cplusplusType) " . ($cplusplusType =~ /[\*]/ ? "" : "*") . "_double_$argName"; + $jniCleanup = "\tenv->SetDoubleArrayRegion($argName, 0, 1, (jdouble*) _double_$argName);\n"; + } elsif ( $javaType =~ /^QPaintDeviceInterface$/ ) { + $jniArg = "($cplusplusType) QtSupport::paintDevice(env, $argName)"; + } elsif ( $javaType =~ /^QMimeSourceInterface$/ ) { + $jniArg = "($cplusplusType) QtSupport::mimeSource(env, $argName)"; + } elsif ( $javaType =~ /^[A-Z]/ ) { + ( my $className = $cplusplusType ) =~ s/[&*]//g; + $jniArg = (($cplusplusType !~ /[\*]/ or $cplusplusType =~ /\*\&/) ? "($cplusplusType)*" : "") . "($className*) QtSupport::getQt(env, $argName)"; + } elsif ( $javaType =~ /^boolean\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } elsif ( $javaType =~ /^byte\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } elsif ( $javaType =~ /^char\s*/ ) { + if ( $cplusplusType =~ /QChar/ ) { + $jniLocal = "static QChar* _qchar_$argName = 0;\n"; + if ( $cplusplusType =~ /[\*]/ ) { + $jniArg = "($cplusplusType) QtSupport::toQChar(env, $argName, &_qchar_$argName)"; + } else { + $jniArg = "($cplusplusType)*(QChar*) QtSupport::toQChar(env, $argName, &_qchar_$argName)"; + } + } else { + $jniArg = "($cplusplusType) $argName"; + } + } elsif ( $javaType =~ /^short\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } elsif ( $javaType =~ /^int\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } elsif ( $javaType =~ /^long\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } elsif ( $javaType =~ /^float\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } elsif ( $javaType =~ /^double\s*/ ) { + $jniArg = "($cplusplusType) $argName"; + } else { + ; + } + + return ($jniLocal, $jniArg, $jniCleanup); +} + +sub jniToReturnValue($$$) +{ + my ( $cplusplusType, $functionCall, $jniCleanups ) = @_; + my $jniLocal = ''; # output + my $returnCall = ''; # output + + my $javaType = cplusplusToJava( $cplusplusType ); + my $const = ($cplusplusType =~ /const / ? "const " : ""); + + if ( $cplusplusType =~ /void/ ) { + $returnCall = "\t$functionCall;\n\treturn;\n"; + $returnCall = "\t$functionCall;\n$jniCleanups\treturn;\n"; + } elsif ( $javaType =~ /^Calendar$/ ) { + $cplusplusType =~ /(QDateTime|QDate)\s*(\*)?&?\s*$/; + $jniLocal = "\t$1 $2 _qdate;\n"; + $returnCall = "\t_qdate = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn (jobject) QtSupport::from$1(env, ($1*) " . ($2 eq "\*" ? "" : "&") . "_qdate);\n"; + } elsif ( $javaType =~ /^Date$/ ) { + $cplusplusType =~ /(QTime)\s*(\*)?&?\s*$/; + $jniLocal = "\t$1 $2 _qtime;\n"; + $returnCall = "\t_qtime = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn (jobject) QtSupport::fromQTime(env, ($1*) " . ($2 eq "\*" ? "" : "&") . "_qtime);\n"; + } elsif ( $javaType =~ /ArrayList/ || $javaType =~ /String\[\]/ ) { + if ( $cplusplusType !~ /\*/ ) { + $const = ""; + } + $cplusplusType =~ /(const )?([^\&]*)(\*)?&?/; + $jniLocal = "\t$const$2 $3 _qlist;\n"; + $returnCall = "\t_qlist = $functionCall;\n$jniCleanups"; + if ( $cplusplusType =~ /(QStrList|QStringList|QCanvasItemList|QWidgetList|QDomNodeList|QObjectList)\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) QtSupport::arrayWith$1(env, ($1*) " . ($2 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /DOM::(NodeList|StyleSheetList|MediaList)\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) KDESupport::arrayWith$1(env, (DOM::$1 *) " . ($2 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /(QCStringList|KFileItemList|KFileViewItemList)\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) KDESupport::arrayWith$1(env, ($1*) " . ($2 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /(KTrader::OfferList)\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) KDESupport::arrayWithOfferList(env, ($1*) " . ($2 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /(KURL::List)\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) KDESupport::arrayWithKURLList(env, ($1*) " . ($2 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /QValueList<QIconDragItem>\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) QtSupport::arrayWithQIconDragItemList(env, (QValueList<QIconDragItem>*) " . ($1 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /QMemArray<QRect>\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) QtSupport::arrayWithQRectList(env, (QMemArray<QRect>*) " . ($1 eq "\*" ? "" : "&") . "_qlist);\n"; + } elsif ( $cplusplusType =~ /QArray<QRect>\s*([\*\&])?\s*$/ ) { + $returnCall .= "\treturn (jobject) QtSupport::arrayWithQRectList(env, (QArray<QRect>*) " . ($1 eq "\*" ? "" : "&") . "_qlist);\n"; + } + } elsif ( $javaType =~ /String\[\]/ ) { + ; # Do nothing, string arrays are ArrayLists as return values + } elsif ( $javaType =~ /String/ || $javaType =~ /StringBuffer/ ) { + if ( $cplusplusType =~ /QString(\s*\*)?/ ) { + $jniLocal = "\tQString $1 _qstring;\n"; + $returnCall = "\t_qstring = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn QtSupport::fromQString(env, " . ($cplusplusType =~ /\*/ ? "" : "&") . "_qstring);\n"; + } elsif ($cplusplusType =~ /QCString(\s*\*)?/) { + $jniLocal = "\tQCString $1 _qstring;\n"; + $returnCall = "\t_qstring = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn QtSupport::fromQCString(env, " . ($cplusplusType =~ /\*/ ? "" : "&") . "_qstring);\n"; + } elsif ($cplusplusType =~ /DOM::DOMString(\s*\*)?/) { + $jniLocal = "\tDOM::DOMString $1 _qstring;\n"; + $returnCall = "\t_qstring = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn KDESupport::fromDOMString(env, " . ($cplusplusType =~ /\*/ ? "" : "&") . "_qstring);\n"; + } else { + $jniLocal = "\t$cplusplusType _qstring;\n"; + $returnCall = "\t_qstring = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn QtSupport::fromCharString(env, (char *) _qstring);\n"; + } + } elsif ( $javaType =~ /boolean\[\]/ ) { + ; + } elsif ( $cplusplusType =~ /uchar\s*\*/ ) { + ; + } elsif ( $javaType =~ /char\[\]/ ) { + ; + } elsif ( $javaType =~ /byte\[\]/ ) { + $jniLocal = "\tQByteArray " . ($cplusplusType =~ /\*/ ? "*" : "") . "_qbyteArray;\n"; + $returnCall = "\t_qbyteArray = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn QtSupport::fromQByteArray(env, " . ($cplusplusType =~ /\*/ ? "" : "&") . "_qbyteArray);\n"; + } elsif ( $javaType =~ /short\[\]/ ) { + ; + } elsif ( $javaType =~ /int\[\]/ && $cplusplusType !~ /\&/ ) { + if ( $cplusplusType =~ /(int\*|QRgb\*)/ ) { + $jniLocal = "\t$1 _qint;\n"; + $returnCall = "\t_qint = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn QtSupport::fromIntPtr(env, (int*)_qint);\n"; + } else { + $jniLocal = "\tQValueList<int> _qintArray;\n"; + $returnCall = "\t_qintArray = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn QtSupport::fromQIntValueList(env, &_qintArray);\n"; + } + } elsif ( $javaType =~ /double\[\]/ ) { + ; + } elsif ( $javaType =~ /^[A-Z]/ ) { + my $className = $cplusplusType; + $className =~ s/[\*\&]|const //g; + $returnCall = "\tjobject xret = QtSupport::objectForQtKey(env, (void*)"; + my $fullyQualifiedReturnType = ($javaType =~ /^Q/ ? "org.kde.qt.$javaType" : "org.kde.koala.$javaType"); + if ($cplusplusType =~ /\*/) { + $returnCall .= "$functionCall, \"$fullyQualifiedReturnType\");\n"; + } elsif ($cplusplusType =~ /\&/) { + $returnCall .= "($className *) &$functionCall, \"$fullyQualifiedReturnType\");\n"; + } else { + $returnCall .= "new $className($functionCall), \"$fullyQualifiedReturnType\", TRUE);\n"; + } + $returnCall .= "$jniCleanups\treturn xret;\n"; + } elsif ( $javaType =~ /^char\s*/ ) { + if ( $cplusplusType =~ /(QChar)(\s*\*)?\s*$/ ) { + $jniLocal = "\t$const$1 $2 _qchar;\n"; + $returnCall = "\t_qchar = $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn (jchar) QtSupport::fromQChar(env, (QChar*) " . ($cplusplusType =~ /\*/ ? "" : "&") . "_qchar);\n"; + } else { + $returnCall = "\tjchar xret = (jchar) $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn xret;\n"; + } + } elsif ( $javaType =~ /int\[\]/ && $cplusplusType =~ /\&/ ) { + $returnCall = "\tjint xret = (jint) $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn xret;\n"; + } elsif ( $javaType =~ /(^boolean|^byte|^short|^int|^long|^float|^double)/ ) { + $returnCall = "\tj$1 xret = (j$1) $functionCall;\n$jniCleanups"; + $returnCall .= "\treturn xret;\n"; + } + + return ($jniLocal, $returnCall); +} + +sub writeDoc +{ + ( $libname, $rootnode, $outputdir, $opt ) = @_; + + print STDERR "Starting writeDoc for $libname...\n"; + + $debug = $main::debuggen; + + mkpath( $outputdir ) unless -f $outputdir; + + # Define QPtrCollection::Item, for resolveType + unless ( kdocAstUtil::findRef( $rootnode, "QPtrCollection::Item" ) ) { + my $cNode = kdocAstUtil::findRef( $rootnode, "QPtrCollection" ); + warn "QPtrCollection not found" if (!$cNode); + my $node = Ast::New( 'Item' ); + $node->AddProp( "NodeType", "Forward" ); + $node->AddProp( "Source", $cNode->{Source} ) if ($cNode); + kdocAstUtil::attachChild( $cNode, $node ) if ($cNode); + $node->AddProp( "Access", "public" ); + } + + print STDERR "Preparsing...\n"; + + # Preparse everything, to prepare some additional data in the classes and methods + Iter::LocalCompounds( $rootnode, sub { preParseClass( shift ); } ); + + # Have a look at each class again, to propagate CanBeCopied + Iter::LocalCompounds( $rootnode, sub { propagateCanBeCopied( shift ); } ); + + # Write out smokedata.cpp + writeSmokeDataFile($rootnode); + + print STDERR "Writing *.java...\n"; + + # Generate *java file for each class + Iter::LocalCompounds( $rootnode, sub { writeClassDoc( shift ); } ); + + print STDERR "Done.\n"; +} + +=head2 preParseClass + Called for each class +=cut +sub preParseClass +{ + my( $classNode ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + if( $#{$classNode->{Kids}} < 0 || + $classNode->{Access} eq "private" || + $classNode->{Access} eq "protected" || # e.g. QPixmap::QPixmapData + exists $classNode->{Tmpl} || + # Don't generate standard bindings for QString, this class is handled as a native type + $className eq 'QString' || + $className eq 'QConstString' || + $className eq 'QCString' || + # Don't map classes which are really arrays + $className eq 'QStringList' || + $className eq 'QCanvasItemList' || + $className eq 'QWidgetList' || + $className eq 'QObjectList' || + $className eq 'QStrList' || + # Those are template related + $className eq 'QTSManip' || # cause compiler errors with several gcc versions + $className eq 'QIconFactory' || + $className eq 'QGDict' || + $className eq 'QGList' || + $className eq 'QGVector' || + $className eq 'QStrIList' || + $className eq 'QStrIVec' || + $className eq 'QByteArray' || + $className eq 'QBitArray' || + $className eq 'QWExtra' || + $className eq 'QTLWExtra' || + $className eq 'QMetaEnum::Item' || + $className eq 'QWidgetContainerPlugin' || + $className eq 'QGArray::array_data' || + $className eq 'KBookmarkMenu::DynMenuInfo' || + $className eq 'KCompletionMatches' || + $className eq 'KDEDesktopMimeType::Service' || + $className eq 'KGlobalSettings::KMouseSettings' || + $className eq 'KMimeType::Format' || + $className eq 'KNotifyClient::Instance' || + $className eq 'KParts::Plugin::PluginInfo' || + $className eq 'KProtocolInfo::ExtraField' || + $className eq 'KXMLGUIClient::StateChange' || + $className eq 'KIconTheme' || + $className eq 'KEditListBox::CustomEditor' || + $className eq 'KIO::KBookmarkMenuNSImporter' || + $className eq 'KPerDomainSettings' || + $className eq 'KApplicationPropsPlugin' || + $className eq 'KPrinter' || + $className eq 'KPty' || + $className eq 'KOpenWithHandler' || + $className eq 'KFileOpenWithHandler' || + $className eq 'KBindingPropsPlugin' || + $className eq 'KPropsDlgPlugin' || + $className eq 'KFileSharePropsPlugin' || + $className eq 'KBookmarkMenuNSImporter' || + $className eq 'KDevicePropsPlugin' || + $className eq 'KWin::WindowInfo' || + $className eq 'KDEDModule' || + $className eq 'KFileMetaInfoProvider' || + $className eq 'KFileMimeTypeInfo' || + $className eq 'KExecPropsPlugin' || + $className eq 'KFilePermissionsPropsPlugin' || + $className eq 'KImageFilePreview' || + $className eq 'KBookmarkManager' || + $className eq 'KBookmarkNotifier' || + $className eq 'KOCRDialogFactory' || + $className eq 'KExtendedBookmarkOwner' || + $className eq 'KSharedPixmap' || + $className eq 'KSocket' || + $className eq 'KLibrary' || + $className eq 'KScanDialogFactory' || + $className eq 'KDictSpellingHighlighter' || + $className eq 'KPropertiesDialog' || + $className eq 'ProgressItem' || + $className eq 'KIO::ChmodInfo' || + $className eq 'KIO::MetaData' || + $className eq 'KFileMimeTypeInfo::ItemInfo' || + $className eq 'KIO::UDSAtom' || + $className eq 'khtml::DrawContentsEvent' || # the khtml:: classes build, but don't link + $className eq 'khtml::MouseDoubleClickEvent' || + $className eq 'khtml::MouseMoveEvent' || + $className eq 'khtml::MousePressEvent' || + $className eq 'khtml::MouseReleaseEvent' || + $className eq 'khtml::MouseEvent' || + $className eq 'KURL::List' || + $className eq 'KWin::Info' || + $className eq 'TerminalInterface' || + $className =~ /.*Private$/ || # Ignore any classes which aren't for public consumption + $className =~ /.*Impl$/ || + $className =~ /.*Internal.*/ || +# $classNode->{Deprecated} || + $classNode->{NodeType} eq 'union' # Skip unions for now, e.g. QPDevCmdParam + ) { + print STDERR "Skipping $className\n" if ($debug); + print STDERR "Skipping union $className\n" if ( $classNode->{NodeType} eq 'union'); + $skippedClasses{$className} = 1; + delete $classNode->{Compound}; # Cheat, to get it excluded from Iter::LocalCompounds + return; + } + + my $signalCount = 0; + my $eventHandlerCount = 0; + my $defaultConstructor = 'none'; # none, public, protected or private. 'none' will become 'public'. + my $constructorCount = 0; # total count of _all_ ctors + # If there are ctors, we need at least one public/protected one to instanciate the class + my $hasPublicProtectedConstructor = 0; + # We need a public dtor to destroy the object --- ### aren't protected dtors ok too ?? + my $hasPublicDestructor = 1; # by default all classes have a public dtor! + #my $hasVirtualDestructor = 0; + my $hasDestructor = 0; + my $hasPrivatePureVirtual = 0; + my $hasCopyConstructor = 0; + my $hasPrivateCopyConstructor = 0; + # Note: no need for hasPureVirtuals. $classNode{Pure} has that. + + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + # Look at each class member (looking for methods and enums in particular) + Iter::MembersByType ( $classNode, undef, + sub { + + my( $classNode, $m ) = @_; + my $name = $m->{astNodeName}; + + if( $m->{NodeType} eq "method" ) { + if ( $m->{ReturnType} eq 'typedef' # QFile's EncoderFn/DecoderFn callback, very badly parsed + ) { + $m->{NodeType} = 'deleted'; + next; + } + + print STDERR "preParseClass: looking at $className\::$name $m->{Params}\n" if ($debug); + + if ( $name eq $classNode->{astNodeName} ) { + if ( $m->{ReturnType} =~ /~/ ) { + # A destructor + $hasPublicDestructor = 0 if $m->{Access} ne 'public'; + #$hasVirtualDestructor = 1 if ( $m->{Flags} =~ "v" && $m->{Access} ne 'private' ); + $hasDestructor = 1; + } else { + # A constructor + $constructorCount++; + $defaultConstructor = $m->{Access} if ( $m->{Params} eq '' ); + $hasPublicProtectedConstructor = 1 if ( $m->{Access} ne 'private' ); + + # Copy constructor? + if ( $#{$m->{ParamList}} == 0 ) { + my $theArgType = @{$m->{ParamList}}[0]->{ArgType}; + if ($theArgType =~ /$className\s*\&/) { + $hasCopyConstructor = 1; + $hasPrivateCopyConstructor = 1 if ( $m->{Access} eq 'private' ); + } + } + # Hack the return type for constructors, since constructors return an object pointer + $m->{ReturnType} = $className."*"; + } + } + + if ( $name =~ /~$classNode->{astNodeName}/ && $m->{Access} ne "private" ) { # not used + $hasPublicDestructor = 0 if $m->{Access} ne 'public'; + #$hasVirtualDestructor = 1 if ( $m->{Flags} =~ "v" ); + $hasDestructor = 1; + } + + if ( $m->{Flags} =~ "p" && $m->{Access} =~ /private/ ) { + $hasPrivatePureVirtual = 1; # ouch, can't inherit from that one + } + + # All we want from private methods is to check for virtuals, nothing else + next if ( $m->{Access} =~ /private/ ); + + # Don't generate code for deprecated methods, + # or where the code won't compile/link for obscure reasons. Or even obvious reasons.. + if ( ($classNode->{astNodeName} eq 'KCharSelectTable' and $name eq 'paintCell') + || ($classNode->{astNodeName} eq 'KAnimWidget' and $name eq 'KAnimWidget' and @{$m->{ParamList}} == 2) + || ($classNode->{astNodeName} eq 'KDCOPActionProxy' and $name eq 'actions') + || ($classNode->{astNodeName} eq 'KFileDialog' and $name eq 'addDirEntry') + || ($classNode->{astNodeName} eq 'KFileDialog' and $name eq 'getDirEntry') + || ($classNode->{astNodeName} eq 'KFileView' and $name eq 'selectionMode') + || ($classNode->{astNodeName} eq 'KFind' and $name eq 'KFind' and @{$m->{ParamList}} == 4) + || ($classNode->{astNodeName} eq 'KGlobalAccel' and $name eq 'setEnabled') + || ($classNode->{astNodeName} eq 'KCharsets' and $name eq 'encodingsForLanguage') + || ($classNode->{astNodeName} eq 'KInputDialog' and $name eq 'getInteger') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'buildHTMLErrorString') + || ($classNode->{astNodeName} eq 'KIO' and $name eq 'calculateRemainingSeconds') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'checkCachedAuthentication') + || ($classNode->{astNodeName} eq 'SlaveBase' and $name eq 'cacheAuthentication') + || ($classNode->{astNodeName} eq 'KInputDialog' and $name eq 'getDouble') + || ($classNode->{astNodeName} eq 'KToolBar' and $name eq 'enable') + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'insert' and @{$m->{ParamList}} == 2) + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'autoupdate') + || ($classNode->{astNodeName} eq 'KAccel' and $name eq 'getAutoUpdate') + || ($classNode->{astNodeName} eq 'KStdAccel' and $name eq 'insert') + || ($classNode->{astNodeName} eq 'KBookmarkMenu' and $name eq 'invalid') + || ($classNode->{astNodeName} eq 'KCharsets' and $name eq 'languages') + || ($classNode->{astNodeName} eq 'KCombiView' and $name eq 'setDropOptions') + || ($classNode->{astNodeName} eq 'KFileMetaInfoItem' and $name eq 'unit') + || ($classNode->{astNodeName} eq 'KInstance' and $name eq 'charsets') + || ($classNode->{astNodeName} eq 'KInstance' and $name eq 'KInstance' and $m->{Access} =~ /protected/) + || ($classNode->{astNodeName} eq 'KKey' and $name eq 'isValidQt') + || ($classNode->{astNodeName} eq 'KKey' and $name eq 'isValidNative') + || ($classNode->{astNodeName} eq 'KKeySequence' and $name eq 'init') + || ($classNode->{astNodeName} eq 'KKeySequence' and $name eq 'setTriggerOnRelease') + || ($classNode->{astNodeName} eq 'KEMailSettings' and $name eq 'getExtendedSetting') + || ($classNode->{astNodeName} eq 'KEMailSettings' and $name eq 'setExtendedSetting') + || ($classNode->{astNodeName} eq 'KHTMLSettings' and $name eq 'fallbackAccessKeysAssignments') + || ($classNode->{astNodeName} eq 'KProtocolManager' and $name eq 'defaultConnectTimeout') + || ($classNode->{astNodeName} eq 'KMD5' and $name eq 'transform') + || ($classNode->{astNodeName} eq 'KSSLCertificate' and $name eq 'operator!=') + || ($classNode->{astNodeName} eq 'KSSLPKCS7' and $name eq 'validate') + || ($classNode->{astNodeName} eq 'KSSLPKCS7' and $name eq 'revalidate') + || ($classNode->{astNodeName} eq 'KSSLSession' and $name eq 'KSSLSession' and @{$m->{ParamList}} == 1) + || ($classNode->{astNodeName} eq 'KSimpleFileFilter' and $name eq 'nameFilters') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'isTabReorderingEnabled') + || ($classNode->{astNodeName} eq 'KTabWidget' and $name eq 'hoverCloseButton') + || ($classNode->{astNodeName} eq 'KTar' and $name eq 'writeFile_impl') + + # Various methods to skip in Qt/E (Qt 2.3.x) + || ($main::qt_embedded + && ( ($classNode->{astNodeName} eq 'QUriDrag' and $name =~ /^decode$|decodeLocalFiles|decodeToUnicodeUris/) + || ($classNode->{astNodeName} eq 'QApplication' and $name =~ /^qwsSetCustomColors|^setArgs$|^winMouseButtonUp|^winFocus|^winMouseButtonUP$|^winVersion$/) + || ($classNode->{astNodeName} eq 'QPrinter' and $name =~ /^setIdle$|^setActive$/) + || ($classNode->{astNodeName} eq 'QDragObject' and $name eq 'dragLink') + || ($classNode->{astNodeName} eq 'QFont' and $name eq 'qwsRenderToDisk') + || ($classNode->{astNodeName} eq 'QFontInfo' and $name eq 'font') + || ($classNode->{astNodeName} eq 'QLineEdit' and $name eq 'getSelection') + || ($classNode->{astNodeName} eq 'QMainWindow' and $name eq 'toolBars') + || ($classNode->{astNodeName} eq 'QMovie' and $name eq 'setDisplayWidget') + || ($classNode->{astNodeName} eq 'QMetaObject' and $name =~ /^new_metaenum_item$|^new_metaaccess$/) + || ($classNode->{astNodeName} eq 'QPainter' and $name eq 'pos') + || ($classNode->{astNodeName} eq 'QPixmap' and $name =~ /^allocCell$|^clut$|^freeCell|^hbm|^isMultiCellPixmap|^multiCellPixmap|^multiCellBitmap|^multiCellHandle|^multiCellOffset|^numCols/) + || ($name eq 'handle') + || ($name eq 'resetInputContext') + || ($name eq 'propagateUpdates') + || ($name eq 'bytesPerLine') + || ($name eq 'scanLine') + || ($name eq 'hPal') + || ($name eq 'copyX11Data') + || ($name eq 'getX11Data') + || ($name eq 'setX11Data') + || ($name eq 'realizePal') + || ($name eq 'qwsDisplay') + || ($name eq 'fixport') + || ($name eq 'hack_strrchr') + || ($name eq 'hack_strchr') + || ($name eq 'hack_strstr') ) ) + + || ($name eq 'virtual_hook') + || ($name =~ /_KShared_/) + || ($name eq 'qObject') + || ($name =~ /argv/) + || ($name =~ /argc/) + || ($name eq 'qt_emit') + || ($name eq 'qt_invoke') + || ($name eq 'qt_cast') + || ($name eq 'qt_property') + || ($name eq 'staticMetaObject') + # Assume only Qt classes have tr() and trUtf8() in their Q_OBJECT macro + || ($classNode->{astNodeName} !~ /^Q/ and $name eq 'tr') + || ($classNode->{astNodeName} !~ /^Q/ and $name eq 'trUtf8') + || $name eq 'trUtf8' + || $m->{Deprecated} ) { + $m->{NodeType} = 'deleted'; + next; + } + + my $argId = 0; + my $firstDefaultParam; + foreach my $arg ( @{$m->{ParamList}} ) { + # Look for first param with a default value + if ( defined $arg->{DefaultValue} && !defined $firstDefaultParam ) { + $firstDefaultParam = $argId; + } + + if ( $arg->{ArgType} eq '...' # refuse a method with variable arguments + or $arg->{ArgType} eq 'image_io_handler' # QImage's callback + or $arg->{ArgType} eq 'DecoderFn' # QFile's callback + or $arg->{ArgType} eq 'EncoderFn' # QFile's callback + or $arg->{ArgType} =~ /bool \(\*\)\(QObject/ # QMetaObject's ctor + or $arg->{ArgType} eq 'QtStaticMetaObjectFunction' # QMetaObjectCleanUp's ctor with func pointer + or $arg->{ArgType} eq 'const QTextItem&' # ref to a private class in 3.2.0b1 + or $arg->{ArgType} eq 'FILE*' # won't be able to handle that I think + or $arg->{ArgType} eq 'const KKeyNative&' # + ) { + $m->{NodeType} = 'deleted'; + } + else + { + # Resolve type in full, e.g. for QSessionManager::RestartHint + # (QSessionManagerJBridge doesn't inherit QSessionManager) + $arg->{ArgType} = kalyptusDataDict::resolveType($arg->{ArgType}, $classNode, $rootnode); + registerType( $arg->{ArgType} ); + $argId++; + } + } + $m->AddProp( "FirstDefaultParam", $firstDefaultParam ); + $m->{ReturnType} = kalyptusDataDict::resolveType($m->{ReturnType}, $classNode, $rootnode) if ($m->{ReturnType}); + registerType( $m->{ReturnType} ); + } + elsif( $m->{NodeType} eq "enum" ) { + if ( ! $m->{astNodeName} ) { + $m->{Access} = 'protected'; + } + my $fullEnumName = $className."::".$m->{astNodeName}; + if ( ($fullEnumName eq 'KMimeType::Format' and $name eq 'compression') + || $m->{Deprecated} ) { + $m->{NodeType} = 'deleted'; + next; + } + + $classNode->{enumerations}{$m->{astNodeName}} = $fullEnumName; +# if $m->{astNodeName} and $m->{Access} ne 'private'; +# if $m->{astNodeName} ; + + # Define a type for this enum + registerType( $fullEnumName ); + + # Remember that it's an enum + findTypeEntry( $fullEnumName )->{isEnum} = 1; + } + elsif( $m->{NodeType} eq 'var' ) { + my $varType = $m->{Type}; + # We are interested in public static vars, like QColor::blue + if ( $varType =~ s/static\s+// && $m->{Access} ne 'private' + && $className."::".$m->{astNodeName} ne "KSpell::modalListText" ) + { + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + print STDERR "var: $m->{astNodeName} '$varType'\n" if ($debug); + + # Register the type + registerType( $varType ); + + } else { + # To avoid duplicating the above test, we just get rid of any other var + $m->{NodeType} = 'deleted'; + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; + + print STDERR "$className: ctor count: $constructorCount, hasPublicProtectedConstructor: $hasPublicProtectedConstructor, hasCopyConstructor: $hasCopyConstructor:, defaultConstructor: $defaultConstructor, hasPublicDestructor: $hasPublicDestructor, hasPrivatePureVirtual:$hasPrivatePureVirtual\n" if ($debug); + + # Note that if the class has _no_ constructor, the default ctor applies. Let's even generate it. + if ( !$constructorCount && $defaultConstructor eq 'none' && !$hasPrivatePureVirtual ) { + # Create a method node for the constructor + my $methodNode = Ast::New( $classNode->{astNodeName} ); + $methodNode->AddProp( "NodeType", "method" ); + $methodNode->AddProp( "Flags", "" ); + $methodNode->AddProp( "Params", "" ); + $methodNode->AddProp( "ParamList", [] ); + kdocAstUtil::attachChild( $classNode, $methodNode ); + + # Hack the return type for constructors, since constructors return an object pointer + $methodNode->AddProp( "ReturnType", $className."*" ); + registerType( $className."*" ); + $methodNode->AddProp( "Access", "public" ); # after attachChild + $defaultConstructor = 'public'; + $hasPublicProtectedConstructor = 1; + } + + # Also, if the class has no explicit destructor, generate a default one. + if ( !$hasDestructor && !$hasPrivatePureVirtual ) { + my $methodNode = Ast::New( "$classNode->{astNodeName}" ); + $methodNode->AddProp( "NodeType", "method" ); + $methodNode->AddProp( "Flags", "" ); + $methodNode->AddProp( "Params", "" ); + $methodNode->AddProp( "ParamList", [] ); + kdocAstUtil::attachChild( $classNode, $methodNode ); + + $methodNode->AddProp( "ReturnType", "~" ); + $methodNode->AddProp( "Access", "public" ); + } + + # If we have a private pure virtual, then the class can't be instanciated (e.g. QCanvasItem) + # Same if the class has only private constructors (e.g. QInputDialog) + $classNode->AddProp( "CanBeInstanciated", $hasPublicProtectedConstructor +# && !$hasPrivatePureVirtual + && (!$classNode->{Pure} or $classNode->{astNodeName} eq 'QValidator') + && !($classNode->{NodeType} eq 'namespace') + && ($classNode->{astNodeName} !~ /^DrawContentsEvent$|^MouseEvent$|^MouseDoubleClickEvent$|^MouseMoveEvent$|^MouseReleaseEvent$|^MousePressEvent$/) + && ($classNode->{astNodeName} !~ /QMetaObject|QDragObject|Slave|CopyJob|KMdiChildFrm|KNamedCommand/) ); + + # We will derive from the class only if it has public or protected constructors. + # (_Even_ if it has pure virtuals. But in that case the *.cpp class can't be instantiated either.) + $classNode->AddProp( "BindingDerives", $hasPublicProtectedConstructor ); + + # We need a public dtor to destroy the object --- ### aren't protected dtors ok too ?? + $classNode->AddProp( "HasPublicDestructor", $hasPublicDestructor ); + + # Hack for QAsyncIO. We don't implement the "if a class has no explicit copy ctor, + # then all of its member variables must be copiable, otherwise the class isn't copiable". + $hasPrivateCopyConstructor = 1 if ( $className eq 'QAsyncIO' ); + + # Remember if this class can't be copied - it means all its descendants can't either + $classNode->AddProp( "CanBeCopied", !$hasPrivateCopyConstructor ); + $classNode->AddProp( "HasCopyConstructor", $hasCopyConstructor ); +} + +sub propagateCanBeCopied($) +{ + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + my @super = superclass_list($classNode); + # A class can only be copied if none of its ancestors have a private copy ctor. + for my $s (@super) { + if (!$s->{CanBeCopied}) { + $classNode->{CanBeCopied} = 0; + print STDERR "$classNode->{astNodeName} cannot be copied\n" if ($debug); + last; + } + } + + # Prepare the {case} dict for the class + prepareCaseDict( $classNode ); +} + +=head2 writeClassDoc + + Called by writeDoc for each class to be written out + +=cut + +sub writeClassDoc +{ + my( $node ) = @_; + my $className = join( "::", kdocAstUtil::heritage($node) ); + my $javaClassName = $node->{astNodeName}; + # Makefile doesn't like '::' in filenames, so use __ + my $fileName = $node->{astNodeName}; +# my $fileName = join( "__", kdocAstUtil::heritage($node) ); + print "Enter: $className\n" if $debug; + + my $typeprefix = ($className =~ /^Q/ ? "qt_" : "kde_"); + my $packagename = ($typeprefix eq 'qt_' ? "org.kde.qt" : "org.kde.koala"); + + # Write out the *.java file + my $classFile = "$outputdir/$fileName.java"; + open( CLASS, ">$classFile" ) || die "Couldn't create $classFile\n"; + print STDERR "Writing $fileName.java\n" if ($debug); + + print CLASS "//Auto-generated by $0. DO NOT EDIT.\n"; + + print CLASS "package $packagename;\n\n"; + + # And write out the *.cpp file + my $jniFile = "$outputdir/$fileName.cpp"; + open( JNISOURCE, ">$jniFile" ) || die "Couldn't create $jniFile\n"; + print STDERR "Writing $fileName.cpp\n" if ($debug); + + print JNISOURCE "//Auto-generated by $0. DO NOT EDIT.\n"; + + my %javaMethods = (); + my %jniMethods = (); + my $jniCode; + my %addImport = (); + my %addInclude = (); + + my @ancestors = (); + my @ancestor_nodes = (); + Iter::Ancestors( $node, $rootnode, undef, undef, sub { + my ( $ances, $name, $type, $template ) = @_; + if ( $name ne "QMemArray" and $name ne "QArray" and $name ne "QSqlFieldInfoList" ) { + push @ancestor_nodes, $ances; + push @ancestors, $name; + } + }, + undef + ); + + my ($methodCode, $interfaceCode, $signalCode, $jbridgeCode) = generateAllMethods( $node, $#ancestors + 1, + \%javaMethods, \%jniMethods, + $node, + ($node->{NodeType} eq 'namespace' ? 0 : 1), + \%addImport, \%addInclude ); + + my $signalFile = "$outputdir/$fileName" . "Signals.java"; + if ( $signalCode ne '' ) { + open( SIGNALS, ">$signalFile" ) || die "Couldn't create $signalFile\n"; + print SIGNALS "//Auto-generated by $0. DO NOT EDIT.\n"; + print SIGNALS "package $packagename;\n\n"; + } + + my $tempMethodNumber = $methodNumber; + + # Add method calls for the interfaces implemented by the class + foreach my $ancestor_node ( @ancestor_nodes ) { + if ( kalyptusDataDict::interfacemap($ancestor_node->{astNodeName}) ne () && ($#ancestors > 0) ) { + my ($meth, $interf, $sig, $jbridge) = generateAllMethods( $ancestor_node, 0, \%javaMethods, \%jniMethods, $node, 0, \%addImport, \%addInclude ); + $methodCode .= $meth; + $jbridgeCode .= $jbridge; + } + } + + + if ( $className eq 'Qt' or $className eq 'KDE' ) { + my $globalSpace = kdocAstUtil::findRef( $rootnode, $main::globalSpaceClassName ); + my ($meth, $interf, $sig, $jbridge) = generateAllMethods( $globalSpace, 0, \%javaMethods, \%jniMethods, $node, 0, \%addImport, \%addInclude ); + $methodCode .= $meth; + $jbridgeCode .= $jbridge; + } + + + $jbridgeCode .= virtualMethodCallbacks( $node ); + + $methodNumber = $tempMethodNumber; + + if ( $className eq 'Qt' ) { + print CLASS "import java.io.*;\n"; + print CLASS "import java.text.MessageFormat;\n"; + print CLASS "import java.lang.reflect.*;\n"; + } else { + if ( $className eq 'QListView' or $className eq 'QListViewItem' or $className eq 'QUriDrag' ) { + # Special case these two classes as they have methods that use ArrayList added as 'extras' + print CLASS "import java.util.ArrayList;\n"; + } + print CLASS "import org.kde.qt.Qt;\n"; + } + + if ( kalyptusDataDict::interfacemap($javaClassName) ne () ) { + my $interfaceFile = "$outputdir/" . kalyptusDataDict::interfacemap($javaClassName) . ".java"; + open( INTERFACE, ">$interfaceFile" ) || die "Couldn't create $interfaceFile\n"; + print INTERFACE "//Auto-generated by $0. DO NOT EDIT.\n"; + print INTERFACE "package $packagename;\n\n"; + } + + foreach my $imp (keys %addImport) { + die if $imp eq ''; + # Ignore any imports for classes in the same package as the current class + if ($imp !~ /$packagename/) { + print CLASS "import $imp;\n"; + print INTERFACE "import $imp;\n"; + print SIGNALS "import $imp;\n" unless $signalCode eq '';; + } + } + + if ( kalyptusDataDict::interfacemap($javaClassName) ne () ) { + print INTERFACE "\npublic interface " . kalyptusDataDict::interfacemap($javaClassName) . " {\n"; + print INTERFACE $interfaceCode; + print INTERFACE "}\n"; + close INTERFACE; + } + + my $classdec; + if ($node->{NodeType} eq 'namespace') { + $classdec = "public class $javaClassName {\n"; + } elsif ( $#ancestors < 0 ) { + $classdec = "public class $javaClassName implements QtSupport"; + if ( kalyptusDataDict::interfacemap($javaClassName) ne () ) { + $classdec .= ", " . kalyptusDataDict::interfacemap($javaClassName); + } + + $classdec .= " {\n\tprivate long _qt;\n"; + $classdec .= "\tprivate boolean _allocatedInJavaWorld = true;\n"; + $classdec .= "\tprotected $javaClassName(Class dummy){}\n\n"; + } else { + $classdec = "public class $javaClassName extends "; + my $ancestor; + foreach $ancestor ( @ancestors ) { + if ( kalyptusDataDict::interfacemap($ancestor) eq () or $ancestor eq @ancestors[$#ancestors] ) { + $ancestor =~ s/^.*:://; + $classdec .= "$ancestor "; + if ( $typeprefix ne 'qt_' and $ancestor =~ /^Q/ ) { + print CLASS "import org.kde.qt.$ancestor;\n"; + } + last; + } + } + + my @implements = (); + if ( $#ancestors >= 1 ) { + foreach $ancestor ( @ancestors ) { + if ( kalyptusDataDict::interfacemap($ancestor) ne () ) { + push(@implements, kalyptusDataDict::interfacemap($ancestor)); + } + } + } + + if ($#implements >= 0) { + $classdec .= "implements "; + $classdec .= join(", ", @implements); + } + + $classdec .= " {\n"; + $classdec .= "\tprotected $javaClassName(Class dummy){super((Class) null);}\n"; + } + + print CLASS "\n"; + if ( $javaClassName !~ /^Q/ or $signalCode ne '' ) { + my $signalLink = ''; + if ( $signalCode ne '' ) { + print SIGNALS "\npublic interface $javaClassName" . "Signals {\n"; + print SIGNALS $signalCode; + print SIGNALS "}\n"; + close SIGNALS; + + $signalLink = " See {\@link $javaClassName" . "Signals} for signals emitted by $javaClassName\n"; + } + my $docnode = $node->{DocNode}; + print CLASS "/**\n"; + if ( defined $docnode ) { + print CLASS printJavadocComment( $docnode, "", "", $signalLink ) . "\n" + } else { + print CLASS $signalLink; + } + print CLASS "*/\n"; + } + + print CLASS $classdec; + print CLASS $methodCode; + + my %jniNames; + my $name; + foreach my $methodName (keys %jniMethods) { + die if $methodName eq ''; + $name = $methodName; + $name =~ s/(.*[^_])__[^1].*/$1/; + $name =~ s/(.*[^_])__$/$1/; + if (defined $jniNames{$name}) { + $jniNames{$name}++; + } else { + $jniNames{$name} = 1; + } + } + + # Add the JNI functions sorted by name. And with the correct + # signature minus the arg types if name not duplicated + foreach my $methodName (sort keys %jniMethods) { + die if $methodName eq ''; + my $methodCode = $jniMethods{$methodName}; + $methodName =~ s/(.*[^_])__[^1].*/$1/; + $methodName =~ s/(.*[^_])__$/$1/; + if ($jniNames{$methodName} == 1) { + $methodCode =~ s/__\(/\(/; + $methodCode =~ s/__[^1][^\(]*\(/\(/; + } + $jniCode .= $methodCode; + } + + if ( $className eq 'Qt' ) { + if ($main::qt_embedded) { + $qtExtras =~ s/public static native QCursor whatsThisCursor\(\);//; + $qtjniExtras =~ s/JNIEXPORT jobject JNICALL\nJava_org_kde_qt_Qt_whatsThisCursor[^}]*}//; + } + print CLASS $qtExtras; + $jniCode .= $qtjniExtras; + } elsif ( $className eq 'QApplication' ) { + print CLASS $qapplicationExtras; + $jniCode .= $qapplicationjniExtras; + } elsif ( $className eq 'QBitmap' ) { + print CLASS $qbitmapExtras; + $jniCode .= $qbitmapjniExtras; + } elsif ( $className eq 'QDropEvent' ) { + print CLASS $qdropeventExtras; + $jniCode .= $qdropeventjniExtras; + } elsif ( $className eq 'QDragObject' ) { + print CLASS $qdragobjectExtras; + $jniCode .= $qdragobjectjniExtras; + } elsif ( $className eq 'QObject' ) { + print CLASS $qobjectExtras; + $jniCode .= $qobjectjniExtras; + } elsif ( $className eq 'QImage' ) { + $jniCode .= $qimagejniExtras; + } elsif ( $className eq 'QListView' ) { + print CLASS $qlistviewExtras; + $jniCode .= $qlistviewjniExtras; + } elsif ( $className eq 'QListViewItem' ) { + print CLASS $qlistviewitemExtras; + $jniCode .= $qlistviewitemjniExtras; + } elsif ( $className eq 'QMenuBar' ) { + if ($main::qt_embedded) { + $qmenubarjniExtras =~ s/jobject accel/jlong accel/; + } + $jniCode .= $qmenubarjniExtras; + } elsif ( $className eq 'QMenuData' ) { + if ($main::qt_embedded) { + $qmenudatajniExtras =~ s/jobject accel/jlong accel/; + } + $jniCode .= $qmenudatajniExtras; + } elsif ( $className eq 'QMimeSource' ) { + print CLASS $qmimesourceExtras; + $jniCode .= $qmimesourcejniExtras; + } elsif ( $className eq 'QPopupMenu' ) { + if ($main::qt_embedded) { + $qpopupmenujniExtras =~ s/jobject accel/jlong accel/; + } + $jniCode .= $qpopupmenujniExtras; + } elsif ( $className eq 'QWidget' ) { + print CLASS $qwidgetExtras; + $jniCode .= $qwidgetjniExtras; + } elsif ( $className eq 'QPaintDevice' ) { + print CLASS $qpaintdeviceExtras; + $jniCode .= $qpaintdevicejniExtras; + } elsif ( $className eq 'QPixmap' ) { + print CLASS $qpixmapExtras; + $jniCode .= $qpixmapjniExtras; + } elsif ( $className eq 'QIODevice' ) { + print CLASS $qiodeviceExtras; + } elsif ( $className eq 'QPointArray' ) { + print CLASS $qpointarrayExtras; + $jniCode .= $qpointarrayjniExtras; + } elsif ( $className eq 'QUriDrag' ) { + print CLASS $quridragExtras; + $jniCode .= $quridragjniExtras; + } elsif ( $className eq 'KCmdLineArgs' ) { + $jniCode .= $kcmdlineargsjniExtras; + } elsif ( $className eq 'KIO::Scheduler' ) { + $jniCode .= $schedulerjniExtras; + } elsif ( $className eq 'KApplication' ) { + print CLASS $kapplicationExtras; + $jniCode .= $kapplicationjniExtras; + } elsif ( $className eq 'KMainWindow' ) { + print CLASS $kmainwindowExtras; + $jniCode .= $kmainwindowjniExtras; + } + + print CLASS "}\n"; + close CLASS; + + foreach my $incl (keys %addInclude) { + die if $incl eq ''; + print JNISOURCE "#include <$incl>\n"; + } + + print JNISOURCE "\n"; + print JNISOURCE "#include <qtjava/QtSupport.h>\n"; + + if ($jniCode =~ /JavaSlot/) { + print JNISOURCE "#include <qtjava/JavaSlot.h>\n"; + } + + if ( $typeprefix eq "qt_" ) { + print JNISOURCE "#include <qtjava/$javaClassName" . ".h>\n"; + } else { + print JNISOURCE "#include <kdejava/KDESupport.h>\n"; + print JNISOURCE "#include <kdejava/$javaClassName" . ".h>\n"; + } + + if ($javaClassName eq 'KIO') { + # Hack: namespaces can be defined in several source files, which doesn't work, so this.. + print JNISOURCE "#include <kio/job.h>\n"; + print JNISOURCE "#include <kio/davjob.h>\n"; + print JNISOURCE "#include <kio/metainfojob.h>\n"; + print JNISOURCE "#include <kio/previewjob.h>\n"; + print JNISOURCE "#include <kio/paste.h>\n"; + } + + print JNISOURCE "\n"; + + if ($jbridgeCode ne '' && $node->{CanBeInstanciated}) { + print JNISOURCE "class $javaClassName" . "JBridge : public $className\n"; + print JNISOURCE "{\npublic:\n"; + print JNISOURCE $jbridgeCode; + print JNISOURCE "};\n\n" + } + print JNISOURCE $jniCode; + close JNISOURCE; +} + + +# Generate the prototypes for a method (one per arg with a default value) +# Helper for makeprotos +sub iterproto($$$$$) { + my $classidx = shift; # to check if a class exists + my $method = shift; + my $proto = shift; + my $idx = shift; + my $protolist = shift; + + my $argcnt = scalar @{ $method->{ParamList} } - 1; + if($idx > $argcnt) { + push @$protolist, $proto; + return; + } + if(defined $method->{FirstDefaultParam} and $method->{FirstDefaultParam} <= $idx) { + push @$protolist, $proto; + } + + my $arg = $method->{ParamList}[$idx]->{ArgType}; + + my $typeEntry = findTypeEntry( $arg ); + my $realType = $typeEntry->{realType}; + + # A scalar ? + $arg =~ s/\bconst\b//g; + $arg =~ s/\s+//g; + if($typeEntry->{isEnum} || $allTypes{$realType}{isEnum} || exists $typeunion{$realType} || exists $mungedTypeMap{$arg}) + { + my $id = '$'; # a 'scalar + $id = '?' if $arg =~ /[*&]{2}/; + $id = $mungedTypeMap{$arg} if exists $mungedTypeMap{$arg}; + iterproto($classidx, $method, $proto . $id, $idx + 1, $protolist); + return; + } + + # A class ? + if(exists $classidx->{$realType}) { + iterproto($classidx, $method, $proto . '#', $idx + 1, $protolist); + return; + } + + # A non-scalar (reference to array or hash, undef) + iterproto($classidx, $method, $proto . '?', $idx + 1, $protolist); + return; +} + +# Generate the prototypes for a method (one per arg with a default value) +sub makeprotos($$$) { + my $classidx = shift; + my $method = shift; + my $protolist = shift; + iterproto($classidx, $method, $method->{astNodeName}, 0, $protolist); +} + +# Return the string containing the signature for this method (without return type). +# If the 2nd arg is not the size of $m->{ParamList}, this method returns a +# partial signature (this is used to handle default values). +sub methodSignature($$) { + my $method = shift; + my $last = shift; + my $sig = $method->{astNodeName}; + my @argTypeList; + my $argId = 0; + foreach my $arg ( @{$method->{ParamList}} ) { + last if $argId > $last; + push @argTypeList, $arg->{ArgType}; + $argId++; + } + $sig .= "(". join(", ",@argTypeList) .")"; + $sig .= " const" if $method->{Flags} =~ "c"; + return $sig; +} + +# Return the string containing the java signature for this method (without return type). +# If the 2nd arg is not the size of $m->{ParamList}, this method returns a +# partial signature (this is used to handle default values). +sub javaMethodSignature($$) { + my $method = shift; + my $last = shift; + my $sig = $method->{astNodeName}; + my @argTypeList; + my $argId = 0; + foreach my $arg ( @{$method->{ParamList}} ) { + $argId++; + last if $argId > $last; + push @argTypeList, "arg" . "$argId ". cplusplusToJava( $arg->{ArgType} ); + } + $sig .= "(". join(", ",@argTypeList) .")"; + return $sig; +} + +# Return the string containing the JNI signature for this method (without return type). +# If the 2nd arg is not the size of $m->{ParamList}, this method returns a +# partial signature (this is used to handle default values). +sub jniMethodSignature($$$$$) { + my $method = shift; + my $methodname = shift; + my $last = shift; + my $javaClassName = shift; + my $javaArgList = shift; + + my $sig = ($javaClassName =~ /^Q/ ? "Java_org_kde_qt_" : "Java_org_kde_koala_"); + $sig .= $javaClassName . "_"; + $methodname =~ s/_/_1/g; + $sig .= $methodname . "__"; + my @argTypeList; + my @argList; + my $javaStatic = ($method->{Flags} =~ "s" or $method->{Parent}->{NodeType} eq 'namespace'); + push @argTypeList, "JNIEnv*"; + push @argTypeList, ($javaStatic ? "jclass" : "jobject"); + push @argList, "JNIEnv* env"; + push @argList, ($javaStatic ? "jclass cls" : "jobject obj"); + my $argId = 0; + foreach my $arg ( @{$method->{ParamList}} ) { + $argId++; + last if $argId > $last; + push @argTypeList, cplusplusToJNI( $arg->{ArgType} ); + push @argList, cplusplusToJNI( $arg->{ArgType} ) . " " . $javaArgList->[$argId - 1]; + $sig .= cplusplusToJNISignature( $arg->{ArgType} ); + } + my $call = $sig; + $sig .= "(" . join(", ",@argTypeList) .")"; + $call .= "(" . join(", ",@argList) .")"; + return ( $sig, $call ); +} + +sub coerce_type($$$$) { + #my $m = shift; + my $union = shift; + my $var = shift; + my $type = shift; + my $new = shift; # 1 if this is a return value, 0 for a normal param + + my $typeEntry = findTypeEntry( $type ); + my $realType = $typeEntry->{realType}; + + my $unionfield = $typeEntry->{typeId}; +# die "$type" unless defined( $unionfield ); + if ( ! defined( $unionfield ) ) { + print STDERR "type field not defined: $type\n"; + return ""; + } + + $unionfield =~ s/t_/s_/; + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + my $code = "$union.$unionfield = "; + if($type =~ /&$/) { + $code .= "(void*)&$var;\n"; + } elsif($type =~ /\*$/) { + $code .= "(void*)$var;\n"; + } else { + if ( $unionfield eq 's_class' + or ( $unionfield eq 's_voidp' and $type ne 'void*' ) + or $type eq 'QString' ) { # hack + $type =~ s/^const\s+//; + if($new) { + $code .= "(void*)new $type($var);\n"; + } else { + $code .= "(void*)&$var;\n"; + } + } else { + $code .= "$var;\n"; + } + } + + return $code; +} + +# Generate the list of args casted to their real type, e.g. +# (QObject*)x[1].s_class,(QEvent*)x[2].s_class,x[3].s_int +sub makeCastedArgList +{ + my @castedList; + my $i = 1; # The args start at x[1]. x[0] is the return value + my $arg; + foreach $arg (@_) { + my $type = $arg; + my $cast; + + my $typeEntry = findTypeEntry( $type ); + my $unionfield = $typeEntry->{typeId}; +# die "$type" unless defined( $unionfield ); + if ( ! defined( $unionfield ) ) { + print STDERR "type field not defined: $type\n"; + return ""; + } + $unionfield =~ s/t_/s_/; + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + my $v .= " arg$i"; + if($type =~ /&$/) { + $cast = "*($type *)"; + } elsif($type =~ /\*$/) { + $cast = "($type)"; + } elsif($type =~ /\(\*\)\s*\(/) { # function pointer ... (*)(...) + $cast = "($type)"; + } else { + if ( $unionfield eq 's_class' + or ( $unionfield eq 's_voidp' and $type ne 'void*' ) + or $type eq 'QString' ) { # hack + $cast = "*($type *)"; + } else { + $cast = "($type)"; + } + } + push @castedList, "$type$v"; + $i++; + } + return @castedList; +} + +# Adds the header for node $1 to be included in $2 if not already there +# Prints out debug stuff if $3 +sub addIncludeForClass($$$) +{ + my ( $node, $addInclude, $debugMe ) = @_; + my $sourcename = $node->{Source}->{astNodeName}; + if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|kdeprint/|kdesu/)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } +# die "Empty source name for $node->{astNodeName}" if ( $sourcename eq '' ); + return if ( $sourcename eq '' ); + unless ( defined $addInclude->{$sourcename} ) { + print " Including $sourcename\n" if ($debugMe); + $addInclude->{$sourcename} = 1; + } + else { print " $sourcename already included.\n" if ($debugMe); } +} + +sub checkIncludesForObject($$) +{ + my $type = shift; + my $addInclude = shift; + + my $debugCI = 0; #$debug + #print "checkIncludesForObject $type\n"; + $type =~ s/const\s+//; + my $it = $type; + if (!($it and exists $typeunion{$it}) and $type !~ /\*/ and $type ne "" + #and $type !~ /&/ # in fact we also want refs, due to the generated code + ) { + $type =~ s/&//; + print " Detecting an object by value/ref: $type\n" if ($debugCI); + my $node = kdocAstUtil::findRef( $rootnode, $type ); + if ($node) { + addIncludeForClass( $node, $addInclude, $debugCI ); + } + else { print " No header found for $type\n" if ($debugCI); } + } +} + + + +# Adds the import for node $1 to be imported in $2 if not already there +# Prints out debug stuff if $3 +sub addImportForClass($$$) +{ + my ( $node, $addImport, $debugMe ) = @_; + my $importname = javaImport( $node->{astNodeName} ); +# print " Importing $importname for node name: " . $node->{astNodeName} . "\n"; + # No import needed, so return + return if ( $importname eq '' ); + unless ( defined $addImport->{$importname} ) { + print " Importing $importname\n" if ($debugMe); + $addImport->{$importname} = 1; + if ( kalyptusDataDict::interfacemap($node->{astNodeName}) ) { + $addImport->{$importname . "Interface"} = 1; + } + } + else { print " $importname already imported.\n" if ($debugMe); } +} + +sub checkImportsForObject($$) +{ + my $type = shift; + my $addImport = shift; + + my $debugCI = 0; #$debug + # print "checkImportsForObject $type\n"; + $type =~ s/const\s+//; + my $it = $type; + if (!($it and exists $typeunion{$it}) and $type ne "" + #and $type !~ /&/ # in fact we also want refs, due to the generated code + ) { + $type =~ s/&//; + $type =~ s/[*]//; + print " Detecting an object by value/ref: $type\n" if ($debugCI); + my $node = kdocAstUtil::findRef( $rootnode, $type ); + if ($node and $node->{NodeType} eq "class" ) { + print " NodeType: " . $node->{NodeType} . "\n" if ($debugCI); + addImportForClass( $node, $addImport, $debugCI ); + } + else { + if ( cplusplusToJava($it) eq 'ArrayList' ) { + $addImport->{"java.util.ArrayList"} = 1; + } else { + print " No import found for $type\n" if ($debugCI); + } + } + } +} + +sub generateVirtualMethod($$$$$) +{ + # Generating methods for $class. + # $m: method node. $methodClass: the node of the class in which the method is really declared + # (can be different from $class when the method comes from a super class) + # This is important because of $allMethods, which has no entry for class::method in that case. + + my( $classNode, $signature, $m, $methodClass, $addImport ) = @_; + my $methodCode = ''; # output + my $returnType = $m->{ReturnType}; + return ('', '') if $returnType eq '~'; # skip destructors + + my $className = $classNode->{astNodeName}; + my $flags = $m->{Flags}; + my @argList = @{$m->{ParamList}}; + + print "generateVirtualMethod $className: $signature ($m->{Access})\n" if ($debug); + + # Detect objects returned by value + checkImportsForObject( $returnType, $addImport ) if ($returnType ne 'void'); + + # Generate a matching virtual method in the x_ class + $methodCode .= "\tvirtual $returnType $m->{astNodeName}("; + my $i = 0; + foreach my $arg ( @argList ) { + $methodCode .= ", " if $i++; + $methodCode .= $arg->{ArgType}; + $methodCode .= " x$i"; + + # Detect objects passed by value + checkImportsForObject( $arg->{ArgType}, $addImport ); + } + $methodCode .= ") "; + $methodCode .= "const " if ($flags =~ "c"); + $methodCode .= "\{\n"; + + # Now the code of the method + my $this = $classNode->{BindingDerives} > 0 ? "this" : "xthis"; + + $i++; # Now the number of args + $methodCode .= "\tSmoke::StackItem x[$i];\n"; + $i = 1; + for my $arg (@argList) { + $methodCode .= "\t"; + $methodCode .= coerce_type("x[$i]", "x$i", $arg->{ArgType}, 0); + $i++; + } + + my $sig = $methodClass->{astNodeName} . "::" . $signature; + my $idx = $allMethods{$sig}; +# die "generateVirtualMethod: $className: No method found for $sig\n" if !defined $idx; + if ( !defined $idx ) { + print STDERR "generateVirtualMethod: $className: No method found for $sig\n"; + return ""; + } + + if($flags =~ "p") { # pure virtual + $methodCode .= "\t${libname}_Smoke->binding->callMethod($idx, (void*)$this, x, true /*pure virtual*/);\n"; + } else { + $methodCode .= "\tif(${libname}_Smoke->binding->callMethod($idx, (void*)$this, x)) "; + } + + $returnType = undef if ($returnType eq 'void'); + if($returnType) { + my $arg = $returnType; + my $it = $arg; + my $cast; + my $v = "x[0]"; + my $indent = ($flags =~ "p") ? "\t" : ""; + if($it and exists $typeunion{$it}) { + $v .= ".$typeunion{$it}"; + $cast = "($arg)"; + $methodCode .= "${indent}return $cast$v;\n"; + } else { + $v .= ".s_class"; + if($arg =~ s/&//) { + $cast = "*($arg *)"; + $methodCode .= "${indent}return $cast$v;\n"; + } elsif($arg !~ /\*/) { + unless($flags =~ "p") { + $indent = "\t "; + $methodCode .= "{\n"; + } + # we assume it's a new thing, and handle it + $methodCode .= "${indent}$arg *xptr = ($arg *)$v;\n"; + $methodCode .= "${indent}$arg xret(*xptr);\n"; + $methodCode .= "${indent}delete xptr;\n"; + $methodCode .= "${indent}return xret;\n"; + $methodCode .= "\t}\n" unless $flags =~ "p"; + } else { + $cast = "($arg)"; + $methodCode .= "${indent}return $cast$v;\n"; + } + } + } else { + $methodCode .= "\t" if $flags =~ "p"; + $methodCode .= "return;\n"; + } + if($flags =~ "p") { + $methodCode .= "\t// ABSTRACT\n"; + $methodCode .= " }\n"; + return ( $methodCode ); + } + $methodCode .= "\t"; + if($returnType) { + $methodCode .= "return "; + } + $methodCode .= "$this\->$methodClass->{astNodeName}\::$m->{astNodeName}("; + $i = 0; + for my $arg (@argList) { + $methodCode .= ", " if $i++; + $methodCode .= "x$i"; + } + $methodCode .= ");\n"; + $methodCode .= "\t}\n"; + return ( $methodCode ); +} + +sub generateMethod($$$$$$$$$) +{ + my( $classNode, $m, $addImport, $addInclude, $ancestorCount, $javaMethods, $jniMethods, $mainClassNode, $generateConstructors ) = @_; # input + my $methodCode = ''; # output + my $interfaceCode = ''; # output + my $signalCode = ''; # output + my $jbridgeCode = ''; # output + + my $jniCode; + my $name = $m->{astNodeName}; # method name + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + + @heritage = kdocAstUtil::heritage($mainClassNode); + my $mainClassName = join( "::", @heritage ); + + # The javaClassName might be 'QWidget', while currentClassName is 'QRangeControl' + # and the QRangeControl methods are being copied into QWidget. + my $javaClassName = $mainClassNode->{astNodeName}; + my $currentClassName = $classNode->{astNodeName}; + + my $bridgeClassName; + if ($classNode->{astNodeName} eq $main::globalSpaceClassName) { + $bridgeClassName = ""; + } elsif (!$mainClassNode->{CanBeInstanciated}) { + $bridgeClassName = $className; + } else { + $bridgeClassName = $mainClassNode->{astNodeName} . "JBridge"; + } + + my $firstUnknownArgType = 99; + my $returnType = $m->{ReturnType}; + + # Don't use $className here, it's never the fully qualified (A::B) name for a ctor. + my $isConstructor = ($name eq $classNode->{astNodeName} ); + my $isDestructor = ($returnType eq '~'); + + # Don't generate anything for destructors, or constructors for namespaces + return if $isDestructor + or ($classNode->{NodeType} eq 'namespace' and $isConstructor) + or (!$mainClassNode->{CanBeInstanciated} and $m->{Access} =~ /protected/); + + # Rename operator methods 'op_...' + if ( $name =~ /^operator.*/ ) { + $methodNumber++; + $name =~ s/ //; + if (! exists $operatorNames{$name} ) { + return; + } + $name = $operatorNames{$name}; + } + + if ($classNode->{astNodeName} eq $main::globalSpaceClassName) { + my $sourcename = $m->{Source}->{astNodeName}; + # Only put Global methods which came from sources beginning with q into class Qt + # Skip any methods in qstring.h/qcstring.h apart from QByteArray compress/uncompress + if ($javaClassName eq 'Qt' + and ( $sourcename !~ /\/q[^\/]*$/ or ($sourcename =~ /string.h$/ and $name !~ /[Cc]ompress/) )) { + return; + } + # ..and any other global methods into KDE + if ($javaClassName eq 'KDE' and $m->{Source}->{astNodeName} =~ /\/q[^\/]*$/) { + return; + } + + if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|kdeprint/|kdesu/)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } + if ( $sourcename eq '' ) { + return; + } + $addInclude->{$sourcename} = 1; + } + + if ($returnType eq 'void') { + $returnType = undef; + } else { + # Detect objects returned by value + checkImportsForObject( $returnType, $addImport ); + checkIncludesForObject( $returnType, $addInclude ); + } + + my $hasDuplicateSignature = 0; + my $isStatic = $m->{Flags} =~ "s"; + my $isPure = $m->{Flags} =~ "p"; + + return if ( $m->{SkipFromSwitch} && $m->{Flags} !~ "p" ); + +# # Skip internal methods, which return unknown types +# # Hmm, the C# bindings have a list of those too. +# return if ( $returnType =~ m/QGfx\s*\*/ ); +# return if ( $returnType eq 'CGContextRef' ); +# return if ( $returnType eq 'QWSDisplay *' ); +# # This stuff needs callback, or ** +# return if ( $name eq 'defineIOHandler' or $name eq 'qt_init_internal' ); +# # Skip casting operators, but not == < etc. +# return if ( $name =~ /operator \w+/ ); +# # QFile's EncoderFn/DecoderFn +# return if ( $name =~ /set[ED][ne]codingFunction/ ); +# # How to implement this? (QXmlDefaultHandler/QXmlEntityResolver::resolveEntity, needs A*&) +# return if ( $name eq 'resolveEntity' and $className =~ /^QXml/ ); +# return if ( $className eq 'QBitArray' && $m->{Access} eq 'protected' ); + + #print STDERR "Tests passed, generating.\n"; + + + my $argId = 0; + + my @argTypeList=(); + my @javaArgTypeList=(); + my @javaArgList = (); + my @jniArgList = (); + my @jniArgLocals = (); + my @jniCleanups = (); + my @namedArgTypeList=(); + + foreach my $arg ( @{$m->{ParamList}} ) { + $argId++; + + if ( $arg->{ArgName} =~ /^super$|^int$|^env$|^cls$|^obj$|^byte$/ ) { + $arg->{ArgName} = ""; + } + + if ( $arg->{ArgName} =~ /^short$|^long$/ ) { + # Oops looks like a parser error + $arg->{ArgType} = $arg->{ArgName}; + $arg->{ArgName} = ""; + } + + print STDERR " Param ".$arg->{astNodeName}." type: ".$arg->{ArgType}." name:".$arg->{ArgName}." default: ".$arg->{DefaultValue}." java: ".cplusplusToJava($arg->{ArgType})."\n" if ($debug); + + my $argType = $arg->{ArgType}; + my $namedArgType; + my $javaArgType; + my $javaArg; + my $jniArg; + my $jniLocal; + my $jniCleanup; + my $argName; + + if ( cplusplusToJava($argType) eq "" && $firstUnknownArgType > $argId ) { + $firstUnknownArgType = $argId; + } + + $javaArg = ($arg->{ArgName} eq "" ? "arg" . $argId : $arg->{ArgName}); + $namedArgType = $argType . " " . $javaArg; + $javaArgType = cplusplusToJava($argType) . " " . $javaArg; + ($jniLocal, $jniArg, $jniCleanup) = jniArgTocplusplus($argType, $javaArg); + + push @argTypeList, $argType; + push @javaArgTypeList, $javaArgType; + push @javaArgList, $javaArg; + push @jniArgLocals, $jniLocal; + push @jniCleanups, $jniCleanup; + push @jniArgList, $jniArg; + push @namedArgTypeList, $namedArgType; + + # Detect objects passed by value + checkImportsForObject( $argType, $addImport ); + checkIncludesForObject( $argType, $addInclude ); + } + + if ( $name eq 'QApplication' or ($javaClassName eq 'KCmdLineArgs' and $name eq 'init' and scalar(@javaArgList) > 1) ) { + # Junk the 'int argc' parameter + shift @javaArgTypeList; + shift @javaArgList; + } + + my @castedArgList = makeCastedArgList( @argTypeList ); + + # We iterate as many times as we have default params + my $firstDefaultParam = $m->{FirstDefaultParam}; + $firstDefaultParam = scalar(@argTypeList) unless defined $firstDefaultParam; + my $iterationCount = scalar(@argTypeList) - $firstDefaultParam; + + my $jniReturnType = cplusplusToJNI($m->{ReturnType}); + # ArrayLists are jobjectArrays in args, but jobjects in return types + $jniReturnType =~ s/jobjectArray/jobject/; + + my $javaReturnType = cplusplusToJava($m->{ReturnType}); + if ( $javaReturnType =~ s/StringBuffer/String/ ) { + $jniReturnType =~ s/jobject/jstring/; + } elsif ( $javaReturnType =~ s/String\[\]/ArrayList/ ) { + $addImport->{"java.util.ArrayList"} = 1; + } + + if ($m->{ReturnType} =~ /^int\&/) { + $javaReturnType = 'int'; + $jniReturnType =~ s/jintArray/jint/; + } + + if ($javaReturnType eq "") { + $firstUnknownArgType = 0; + } + + print STDERR " ". ($iterationCount+1). " iterations for $name\n" if ($debug); + + my $javaSignature = javaMethodSignature( $m, @argTypeList ); + + if ( defined $javaMethods->{$javaSignature} ) { + $hasDuplicateSignature = 1; + } + + my $docnode = $m->{DocNode}; + if ( $firstUnknownArgType >= 0 && $m->{Access} !~ /signals/ && ! $hasDuplicateSignature + && defined $docnode && ($generateConstructors || !$isConstructor) ) + { + my $javadocComment = printJavadocComment( $docnode, "", "\t", "" ); + $methodCode .= "\t/**" . $javadocComment . "*/\n" unless $javadocComment =~ /^\s*$/; + } + + while($iterationCount >= 0) { + + $javaMethods->{$javaSignature} = 1; + + local($") = ","; + + if($firstUnknownArgType <= scalar(@argTypeList) || $hasDuplicateSignature || ($name =~ /^qObject$/) || $m->{Access} =~ /dcop/ ) { + if ( $firstUnknownArgType <= scalar(@argTypeList) || $m->{Access} =~ /dcop/ ) { + my $failedConversion = "\t// " . $m->{ReturnType} . " $name(@castedArgList[0..$#argTypeList]); >>>> NOT CONVERTED\n"; + if ( $m->{Access} =~ /signals/ ) { + $signalCode .= $failedConversion; + } else { + $methodCode .= $failedConversion; + } + } + } else { + +# $jniCode .= "\tcase $methodNumber: "; +# if ($flags =~ "s" || $isConstructor) { # static or constructor +# $jniCode .= "$bridgeClassName\::"; +# } else { +# $jniCode .= "xself->" +# } +# $jniCode .= "x_$methodNumber(args);"; +# $jniCode .= "\tbreak;\n"; + + if ($name eq 'find' and $javaClassName eq 'QButtonGroup') { + # Can't override a static method find() in QWidget + $name = "findButton"; + } elsif ( $name eq 'null' ) { + $name = "nil"; + } elsif ( $name eq 'form' and $javaClassName =~ /^HTML/ ) { + $name = "formElement"; + } elsif ( $name eq 'wait' and $javaClassName eq 'KProcess' ) { + $name = "waitThread"; + } elsif ( $name eq 'finalize' and $javaClassName eq 'KMD5' ) { + $name = "finalizeDigest"; + } elsif ( $name eq 'icon' and $javaClassName eq 'QMessageBox' ) { + $name = "iconId"; + } elsif ( $name eq 'icon' and $javaClassName eq 'KURLBarItemDialog' ) { + $name = "iconName"; + } elsif ( $name eq 'iconText' and $javaClassName eq 'KToolBar' ) { + $name = "iconTextId"; + } elsif ( $name eq 'reset' and $javaClassName eq 'KExtendedSocket' ) { + $name = "resetSocket"; + } elsif ( $name eq 'palette' and $javaClassName eq 'KPaletteTable' ) { + $name = "paletteName"; + } elsif ( $name eq 'size' and $javaClassName eq 'KAnimWidget' ) { + $name = "iconSize"; + } elsif ( $name eq 'size' and $javaClassName eq 'KFontCombo' ) { + $name = "pointSize"; + } elsif ($javaSignature eq "icon()" and $javaClassName eq 'KIconButton') { + $name = "iconName"; + } elsif ($javaSignature eq "close()" and $javaClassName eq 'KDirOperator') { + $name = "closeLoading"; + } elsif ($javaSignature eq "font()" and $javaClassName eq 'KCharSelect') { + $name = "fontName"; + } elsif ($javaSignature eq "layout()" and $javaReturnType eq 'void') { + $name = "updateLayout"; + } elsif ( $name eq 'sorting' and $javaReturnType eq 'boolean' ) { + $name = "sortOnInsert"; + } elsif ($javaSignature eq "statusBar()" and $javaClassName =~ /^K/ ) { + $name = "kstatusBar"; + } elsif ($javaSignature eq "menuBar()" and $javaClassName =~ /^K/ ) { + $name = "kmenuBar"; + } elsif ( $name eq 'addLabel' and $javaClassName eq 'QTableHeader' ) { + $name = "addHeaderLabel"; + } + + my $javaparams = join( ", ", @javaArgTypeList ); + my ( $jniSignature, $jniCall ) = jniMethodSignature( $m, + ($isConstructor ? "new$name" : $name), + @argTypeList, $javaClassName, \@javaArgList ); + + my $cplusplusparams; + my $i = 0; + for my $arg (@argTypeList) { + $cplusplusparams .= "," if $i++; + $cplusplusparams .= "arg" . $i; + } + + if ($isConstructor) { + if ( $generateConstructors && $mainClassNode->{CanBeInstanciated} ) { + $jbridgeCode .= "\t$bridgeClassName(@castedArgList[0..$#argTypeList]) : $className($cplusplusparams) {};\n"; + + $methodCode .= "\tpublic $javaClassName($javaparams) {\n"; + if ( $ancestorCount > 0 ) { + $methodCode .= "\t\tsuper((Class) null);\n" + } + $methodCode .= "\t\tnew$javaClassName(@javaArgList[0..$#javaArgTypeList]);\n"; + $methodCode .= "\t}\n"; + $methodCode .= "\tprivate native void new$javaClassName($javaparams);\n"; + + $jniCode = "JNIEXPORT void JNICALL\n"; + $jniCode .= "$jniCall\n"; + $jniCode .= "{\n"; + $jniCode .= join( "", @jniArgLocals ); + $jniCode .= "\tif (QtSupport::getQt(env, obj) == 0) {\n"; + $jniCode .= "\t\tQtSupport::setQt(env, obj, new $bridgeClassName(" . join( ", ", @jniArgList ). "));\n"; + $jniCode .= "\t\tQtSupport::setObjectForQtKey(env, obj, QtSupport::getQt(env, obj));\n"; + $jniCode .= join( "", @jniCleanups ); + $jniCode .= "\t}\n\treturn;\n}\n\n"; + + # Look for args which are are a QQbject/slot string pair and replace with a java proxy slot + if ($jniCode =~ s/QtSupport::getQt\(env, (receiver|recvr|pObjSlot)\), \(const char\*\) QtSupport::toCharString\(env, (member|slot|psMethodSlot), \&_qstring_(member|slot|psMethodSlot)\)/QtSupport::slotForReceiver(env, $1, $2), "1invoke()"/) { + $jniCode =~ s/static QCString\* _qstring_(member|slot|psMethodSlot) = 0;\n//; + } + + $jniSignature =~ /^([^\)]*)\(.*/; + if ($skippedJniMethods{$1}) { + # Don't generate code for jni methods added as 'extras' + $jniMethods->{$jniSignature} = ""; + } else { + $jniMethods->{$jniSignature} = $jniCode; + } + } + } else { + my $access = $m->{Access}; + $access =~ s/_slots//; + + if ( $access eq 'public' or $access eq 'protected' ) { + if ( $name =~ /^takeItem$|^setPixmap$|^clearCell$|^setItem$|^item$|^minimumSize$/ + or $name =~ /^stepUp$|^stepDown$|^sectionFormattedText$|^addNumber$|^removeLastNumber$/ + or $name =~ /^cancel$|^setSource$|^paintCell$|^updateContents$|^sizeHint$|^setFocusSection$/ + or $name =~ /^event$|^eventFilter$|^copy$|^detach$|^showEvent$|^format$|^encodedData$/ + or $name =~ /^styleChange$|^insertItem$|^setStatus$|^setState$|^minimumSizeHint$/ + or $name =~ /^bytesPerLine$|^paintBranches$|^scanLine$|^ensureCursorVisible$|^setCursor$/ + or $name =~ /^updateGeometry$|^setState$|^exec$|^pixmap$|^areaPoints$|^draw$|^writeDir$/ ) { + # These methods are public in some places, but protected in others, + # so make them all public. + $access = "public"; + } + + $methodCode .= "\t" . $access . (($isStatic or $classNode->{NodeType} eq 'namespace') ? " static " : " ") . "native "; +# $methodCode .= ( $m->{Flags} =~ "v" || $isStatic ? "" : "final " ); + + my $altReturnType = undef; + if ($name =~ /^xForm$/ ) { + $javaReturnType = "Object"; + } elsif ($javaSignature eq "layout()" and $javaReturnType ne 'void') { + $altReturnType = "QLayout"; + } elsif ($javaSignature eq "defaultFactory()" and $javaReturnType eq 'QSqlEditorFactory') { + $javaReturnType = "QEditorFactory"; + } elsif ($javaSignature =~ /^bits|^scanLine/) { + $javaReturnType = "byte[]"; + } elsif ($javaSignature eq "at()" and $javaClassName eq 'KFilterDev') { + $javaReturnType = "long"; + } elsif ($javaSignature =~ /copyTo/ and $javaClassName eq "KDesktopFile" ) { + $altReturnType = "KConfig"; + } + + if ( defined $altReturnType ) { + checkImportsForObject( $altReturnType, $addImport ); + $javaReturnType = $altReturnType; + } + $methodCode .= $javaReturnType; + $methodCode .= " $name($javaparams);\n"; + + if ($access eq 'public' and !$isStatic) { + $interfaceCode .= "\t\t$javaReturnType $name($javaparams);\n"; + } + + my $methodName = $m->{astNodeName}; + # Hack to stop calling super for QWidget::polish() from looping + if ( $m->{Access} =~ /public/ + && $returnType eq '' + && $m->{Flags} =~ "v" + && $cplusplusparams eq '' + && $bridgeClassName ne $className ) + { + $methodName = "public_" . $m->{astNodeName}; + $jbridgeCode .= "\t"; + $jbridgeCode .= "void $methodName() {\n"; + $jbridgeCode .= "\t\t$className" . "::" . $m->{astNodeName} . "();\n"; + $jbridgeCode .= "\t\treturn;\n"; + $jbridgeCode .= "\t}\n"; + } + + if ($m->{Access} =~ /protected/) { + $methodName = "protected_" . $m->{astNodeName}; + $jbridgeCode .= (($isStatic or $classNode->{NodeType} eq 'namespace') ? "\tstatic " : "\t"); + if ( $returnType eq '' ) { + $jbridgeCode .= "void $methodName(@castedArgList[0..$#argTypeList]) {\n"; + $jbridgeCode .= "\t\t$className" . "::" . $m->{astNodeName} . "($cplusplusparams);\n"; + $jbridgeCode .= "\t\treturn;\n"; + } else { + $jbridgeCode .= "$returnType $methodName(@castedArgList[0..$#argTypeList]) {\n"; + $jbridgeCode .= "\t\treturn ($returnType) $className" . "::" . $m->{astNodeName} . "($cplusplusparams);\n"; + } + $jbridgeCode .= "\t}\n"; + + } + + $jniCode = "JNIEXPORT $jniReturnType JNICALL\n"; + $jniCode .= "$jniCall\n"; + $jniCode .= "{\n"; + my $selfstring; + if ( $isStatic or $classNode->{NodeType} eq 'namespace' ) { + $selfstring = $bridgeClassName . "::" . $methodName; + } else { + if ($m->{Access} =~ /protected/ || $methodName =~ /^public_/) { + $selfstring = "(($bridgeClassName*) QtSupport::getQt(env, obj))->$methodName"; + } else { + $selfstring = "(($className*)" . ($mainClassName eq $className ? "" : "($mainClassName*)") . " QtSupport::getQt(env, obj))->" . $m->{astNodeName}; + } + } + my ($locals, $fcall) = jniToReturnValue( $m->{ReturnType}, "$selfstring(" . join( ", ", @jniArgList ). ")", join( "", @jniCleanups ) ); + # Add dummy statements to avoid compiler warnings if needed + $locals .= ($jniSignature =~ /jclass/ ? "\t(void) cls;\n" : ""); + $locals .= ($fcall !~ /env/ ? "\t(void) env;\n" : ""); + + my $slotArgType = ''; + if ($name eq 'insertAnimatedWidget' or $name eq 'connectStatus' or $name eq 'disconnectStatus') { + $slotArgType = 'int'; + } elsif ($name eq 'connectResize' or $name eq 'disconnectResize') { + $slotArgType = 'const QSize&'; + } elsif ($name eq 'connectUpdate' or $name eq 'disconnectUpdate') { + $slotArgType = 'const QRect&'; + } + # Look for args which are are a QQbject/slot string pair and replace with a java proxy slot + + $locals .= join( "", @jniArgLocals ); + + if ($fcall =~ s/QtSupport::getQt\(env, (receiver|recvr|pObjSlot)\), \(const char\*\) QtSupport::toCharString\(env, (member|slot|psMethodSlot), \&_qstring_(member|slot|psMethodSlot)\)/QtSupport::slotForReceiver(env, $1, $2), "1invoke($slotArgType)"/) { + $locals =~ s/static QCString\* _qstring_(member|slot|psMethodSlot) = 0;\n//; + } + + $jniCode .= $locals; + + if ($name eq 'readBlock') { + $interfaceCode =~ s/String /StringBuffer /; + $methodCode =~ s/String /StringBuffer /; + $jniCode =~ s/jstring/jobject/; + $jniCode =~ /(jlong|jint) (\w+)\)/; + my $arg2 = $2; + $jniCode =~ s/_qstring_(\w+) = 0;\n/_qstring_$1 = 0;\n\tif \(_qstring_$1 == 0\) { _qstring_$1 = new QCString\(\); }\n\t_qstring_$1->resize\(\(uint\) $arg2\);\n/; + my $arg1 = $1; + $fcall =~ s/QtSupport::toCharString\([^\)]*\)/_qstring_$arg1->data()/; + $fcall =~ s/return xret;/QtSupport::fromQCStringToStringBuffer(env, _qstring_$arg1, $arg1);\n\treturn xret;/; + } + + $jniCode .= $fcall; + $jniCode .= "}\n\n"; + + if ($isPure && $m->{Access} =~ /protected/) { + # Can't do a lot with implementing these, so give up + $jniCode = ""; + $jbridgeCode = ""; + } + + $jniSignature =~ /^([^\)]*)\(.*/; + if ($skippedJniMethods{$1}) { + # Don't generate code for jni methods added as 'extras' + $jniMethods->{$jniSignature} = ""; + } else { + $jniMethods->{$jniSignature} = $jniCode; + } + } else { + if ( $access =~ /signals/ ) { + my $docnode = $m->{DocNode}; + if ( defined $docnode ) { + my $javadocComment = printJavadocComment( $docnode, "", "\t", "" ); + $signalCode .= "\t/**" . $javadocComment . "*/\n" unless $javadocComment =~ /^\s*$/; + } + $signalCode .= "\tvoid $name($javaparams);\n"; + } + } + } + } + + pop @argTypeList; + pop @javaArgTypeList; + pop @javaArgList; + pop @jniArgList; + pop @jniArgLocals; + pop @jniCleanups; + + $javaSignature = javaMethodSignature( $m, @argTypeList ); + $hasDuplicateSignature = (defined $javaMethods->{$javaSignature} ? 1 : 0); + + $methodNumber++; + $iterationCount--; + } # Iteration loop + + return ( $methodCode, $interfaceCode, $signalCode, $jbridgeCode ); +} + + +sub generateEnum($$$) +{ + my( $classNode, $m, $generateAnonymous ) = @_; # input + my $methodCode = ''; # output + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + my $javaClassName = $classNode->{astNodeName}; + + if ( ($generateAnonymous and $m->{astNodeName} ) or (! $generateAnonymous and ! $m->{astNodeName}) ) { + return; + } + + if ( defined $m->{DocNode} ) { + my $javadocComment = printJavadocComment( $m->{DocNode}, "", "\t", "" ); + $methodCode .= "\t/**" . $javadocComment . "*/\n" unless $javadocComment =~ /^\s*$/; + } + + my @enums = split(",", $m->{Params}); + my $enumCount = 0; + foreach my $enum ( @enums ) { + $enum =~ s/\s//g; + $enum =~ s/::/./g; + $enum =~ s/\(mode_t\)//; + if ( $enum =~ /(.*)=([-0-9]+)$/ ) { + $methodCode .= "\tpublic static final int $1 = $2;\n"; + $enumCount = $2; + $enumCount++; + } elsif ( $enum =~ /(.*)=(.*)/ ) { + $methodCode .= "\tpublic static final int $1 = $2;\n"; + } else { + $methodCode .= "\tpublic static final int $enum = $enumCount;\n"; + $enumCount++; + } + } + + $methodCode .= "\n"; + $methodNumber++; + + return ( $methodCode ); +} + +sub generateVar($$$) +{ + my( $classNode, $m, $addImport ) = @_; # input + my $methodCode = ''; # output + my $interfaceCode = ''; # output + + my @heritage = kdocAstUtil::heritage($classNode); + my $className = join( "::", @heritage ); + my $javaClassName = $classNode->{astNodeName}; + + my $name = $m->{astNodeName}; + my $varType = $m->{Type}; + $varType =~ s/static\s//; + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + my $fullName = "$className\::$name"; + + checkImportsForObject( $varType, $addImport ); + +# die "Invalid index for $fullName: $classNode->{case}{$fullName} instead of $methodNumber" if $classNode->{case}{$fullName} != $methodNumber; +# $methodCode .= " static void x_$methodNumber(Smoke::Stack x) {\n"; +# $methodCode .= "\tx[0].s_class = (void*)new $varType($fullName);\n"; +# $methodCode .= " }\n"; + +# if ( ($name !~ /^null$/) && (cplusplusToJava($varType) ne "") ) { + if ( ($name !~ /^null$/) && (cplusplusToJava($varType) ne "" ) ) { +# $interfaceCode .= "\t\t". cplusplusToJava($varType) . " $name();\n"; + +# $methodCode .= "\tpublic native static ". cplusplusToJava($varType) . " $name();\n"; + } + + $methodNumber++; + return ( $methodCode, $interfaceCode ); +} + +## Called by writeClassDoc +sub generateAllMethods($$$$$$$$) +{ + my ($classNode, $ancestorCount, $javaMethods, $jniMethods, $mainClassNode, $generateConstructors, $addImport, $addInclude) = @_; + my $methodCode = ''; + my $interfaceCode = ''; + my $signalCode = ''; + my $jbridgeCode = ''; + $methodNumber = 0; + #my $className = $classNode->{astNodeName}; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + my $javaClassName = $mainClassNode->{astNodeName}; + my $jniClassName = ($classNode->{astNodeName} =~ /^Q/ ? "Java_org_kde_qt_" : "Java_org_kde_koala_") . $classNode->{astNodeName}; + # If the C++ class had multiple inheritance, then the code for all but one of the + # parents must be copied into the code for javaClassName. Hence, for QWidget current + # classname might be QPaintDevice, as its methods are needed in QWidget. + my $currentClassName = join( ".", kdocAstUtil::heritage($classNode) ); + + my $sourcename = $classNode->{Source}->{astNodeName}; + + if ( $sourcename !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|kdeprint/|kdesu/)(.*)!$1$2!m ) { + $sourcename =~ s!.*/(.*)!$1!m; + } +# die "Empty source name for $classNode->{astNodeName} $classNode->{Source}->{astNodeName}" if ( $sourcename eq '' ); + + if ($classNode->{astNodeName} ne $main::globalSpaceClassName && $sourcename ne '') { + $addInclude->{$sourcename} = 1; +# my $s; +# for my $sn( @{$classNode->{Sources}} ) { +# if ( ($s = $sn->{astNodeName}) !~ s!.*(kio/|kparts/|dom/|kabc/|ksettings/|kjs/|ktexteditor/|kdeprint/|kdesu/)(.*)!$1$2!m ) { +# $s =~ s!.*/(.*)!$1!m; +# } +# $addInclude->{$s} = 1; +# } + } + + $addImport->{"org.kde.qt.QtSupport"} = 1; + + # Do all enums first, anonymous ones and then named enums + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'enum' and $currentClassName eq $javaClassName ) { + my ($meth) = generateEnum( $classNode, $methodNode, 1 ); + $methodCode .= $meth; + } + }, undef ); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'enum' and $currentClassName eq $javaClassName ) { + my ($meth) = generateEnum( $classNode, $methodNode, 0 ); + $methodCode .= $meth; + } + }, undef ); + + # Then all static vars + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'var' and $currentClassName eq $javaClassName ) { + my ($meth, $interface) = generateVar( $classNode, $methodNode, $addImport ); + $methodCode .= $meth; +# $interfaceCode .= $interface; + } + }, undef ); + + # Then all methods + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $methodNode ) = @_; + + if ( $methodNode->{NodeType} eq 'method' ) { + my ($meth, $interf, $signals, $jbridge) = generateMethod( $classNode, $methodNode, $addImport, $addInclude, $ancestorCount, $javaMethods, $jniMethods, $mainClassNode, $generateConstructors ); + $methodCode .= $meth; + $interfaceCode .= $interf; + $signalCode .= $signals; + $jbridgeCode .= $jbridge; +# $jniCode .= $jni; + } + }, undef ); + + # Virtual methods +# if ($classNode->{BindingDerives}) { +# my %virtualMethods; +# allVirtualMethods( $classNode, \%virtualMethods ); + +# for my $sig (sort keys %virtualMethods) { +# my ($meth) = generateVirtualMethod( $classNode, $sig, $virtualMethods{$sig}{method}, $virtualMethods{$sig}{class}, \%addImport ); +# $methodCode .= $meth; +# } +# } + + # Destructor + # "virtual" is useless, if the base class has a virtual destructor then the x_* class too. + #if($classNode->{HasVirtualDestructor} and $classNode->{HasDestructor}) { + # $methodCode .= " virtual ~$bridgeClassName() {}\n"; + #} + # We generate a dtor though, because we might want to add stuff into it + + if ($currentClassName eq $javaClassName and $classNode->{CanBeInstanciated} and $classNode->{HasPublicDestructor}) { + if ( $generateConstructors ) { + my $jniCode; + my $jniSignature; + + $jbridgeCode .= "\t~$className" . "JBridge() {QtSupport::qtKeyDeleted(this);}\n"; + $methodCode .= "\t/** Deletes the wrapped C++ instance */\n"; + $methodCode .= "\tprotected native void finalize() throws InternalError;\n"; + + $jniSignature = $jniClassName . "_finalize"; + $jniCode = "JNIEXPORT void JNICALL\n$jniSignature(JNIEnv* env, jobject obj)\n{"; + + if ( is_kindof($classNode, 'QCheckListItem') ) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QCheckListItem*)($className*)QtSupport::getQt(env, obj))->parent() == 0 && ((QCheckListItem*)($className*)QtSupport::getQt(env, obj))->listView() == 0) {\n"; + } elsif ( $classNode->{astNodeName} =~ /^KFileTreeViewToolTip$/ ) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && (($className*)QtSupport::getQt(env, obj))->parentWidget() == 0) {\n"; + } elsif ( is_kindof($classNode, 'QTableItem')) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QTableItem*)($className*)QtSupport::getQt(env, obj))->table() == 0) {\n"; + } elsif ( is_kindof($classNode, 'QPopupMenu')) { + if ($main::qt_embedded) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QPopupMenu*)($className*)QtSupport::getQt(env, obj))->parentWidget() == 0) {\n"; + } else { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QPopupMenu*)($className*)QtSupport::getQt(env, obj))->parentWidget(FALSE) == 0) {\n"; + } + } elsif ( is_kindof($classNode, 'QListViewItem') ) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QListViewItem*)($className*)QtSupport::getQt(env, obj))->parent() == 0 && ((QListViewItem*)($className*)QtSupport::getQt(env, obj))->listView() == 0) {\n"; + } elsif ( is_kindof($classNode, 'QIconViewItem')) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QIconViewItem*)($className*)QtSupport::getQt(env, obj))->iconView() == 0) {\n"; + } elsif ( is_kindof($classNode, 'QLayoutItem')) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QLayoutItem*)($className*)QtSupport::getQt(env, obj))->layout() == 0 && ((QLayoutItem*)($className*)QtSupport::getQt(env, obj))->widget() == 0 && ((QLayoutItem*)($className*)QtSupport::getQt(env, obj))->spacerItem() == 0) {\n"; + } elsif ( $classNode->{astNodeName} =~ /^KSpell$|^KReplace$/ ) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj)) {\n"; + } elsif ( $classNode->{astNodeName} =~ /^QWidget$/ || defined kdocAstUtil::findOverride( $rootnode, $classNode, "parentWidget" ) ) { + if ($main::qt_embedded) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QWidget*)($className*)QtSupport::getQt(env, obj))->parentWidget() == 0) {\n"; + } else { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && ((QWidget*)($className*)QtSupport::getQt(env, obj))->parentWidget(TRUE) == 0) {\n"; + } + } elsif ( $classNode->{astNodeName} =~ /^QObject$/ || defined kdocAstUtil::findOverride( $rootnode, $classNode, "parent" ) ) { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj) && (($className*)QtSupport::getQt(env, obj))->parent() == 0) {\n"; + } else { + $jniCode .= "\n\tif (QtSupport::allocatedInJavaWorld(env, obj)) {\n"; + } + + if ($classNode->{astNodeName} !~ /^Q.*Style$/) { + $jniCode .= "\t\tdelete ($className*)QtSupport::getQt(env, obj);\n"; + } + + $jniCode .= "\t\tQtSupport::setQt(env, obj, 0);\n\t}\n\treturn;\n}\n\n"; + $jniMethods->{$jniSignature} = $jniCode; + +# $interfaceCode .= "\t\tvoid dispose();\n"; + $methodCode .= "\t/** Delete the wrapped C++ instance ahead of finalize() */\n"; + $methodCode .= "\tpublic native void dispose();\n"; + +# $interfaceCode .= "\t\tboolean isDisposed();\n"; + $methodCode .= "\t/** Has the wrapped C++ instance been deleted? */\n"; + $methodCode .= "\tpublic native boolean isDisposed();\n"; + + + $jniSignature = $jniClassName . "_dispose"; + $jniCode = "JNIEXPORT void JNICALL\n$jniSignature(JNIEnv* env, jobject obj)\n{"; + $jniCode .= "\n\t$jniClassName" . "_finalize(env, obj);\n\treturn;\n}\n\n"; + $jniMethods->{$jniSignature} = $jniCode; + + $jniSignature = $jniClassName . "_isDisposed"; + $jniCode = "JNIEXPORT jboolean JNICALL\n$jniSignature(JNIEnv* env, jobject obj)\n{"; + $jniCode .= "\n\treturn (QtSupport::getQt(env, obj) == 0);\n}\n\n"; + $jniMethods->{$jniSignature} = $jniCode; + } +# die "$className destructor: methodNumber=$methodNumber != case entry=".$classNode->{case}{"~$className()"}."\n" +# if $methodNumber != $classNode->{case}{"~$className()"}; + $methodNumber++; + } + + return ( $methodCode, $interfaceCode, $signalCode, $jbridgeCode ); +} + +sub virtualMethodCallbacks +{ + my( $node ) = @_; + my $jbridgeCode = ''; # output + my %allmem = (); + my $key; + + my $m; + my $name; + my $isQObject = is_kindof($node, 'QObject'); + + kdocAstUtil::allMembers( \%allmem, $node ); + + foreach $key (keys (%allmem)) { + $m = $allmem{$key}; + $name = $m->{astNodeName} ; + my $type = $m->{NodeType}; + my $docnode = $m->{DocNode}; + my $parent = $m->{Parent}; + + if ( $type eq "method" && ($m->{Flags} =~ "v" || $name =~ /^.*Event$/) && !$m->{SkipFromSwitch} + && $m->{Access} =~ /public|protected/ + && $name !~ /qwsEvent/ && $name !~ /x11Event/ && $name !~ /winEvent/ + && $name !~ /macEvent/ && $name !~ /movableDropEvent/ ) + { + my @argTypeList = (); + my @castedArgList; + my $i = 0; + my $cplusplusparams; + foreach my $arg ( @{$m->{ParamList}} ) { + my $argType = $arg->{ArgType}; + push @argTypeList, $argType; + $cplusplusparams .= "," if $i++; + $cplusplusparams .= "arg" . $i; + } + + my $qobjectType = $node->{astNodeName}; + $qobjectType =~ s/(.*)\*.*$/$1/; + $qobjectType =~ s/^([^Q].*)/org.kde.koala.$1/; + $qobjectType =~ s/^(Q.*)/org.kde.qt.$1/; + if( $m->{ReturnType} eq 'void' && $#argTypeList eq 0 + && cplusplusToJNISignature( @argTypeList[0] ) =~ /Lorg_kde/ + && $isQObject ) + { + @castedArgList = makeCastedArgList( @argTypeList ); + my $eventType = cplusplusToJava( @argTypeList[0] ); + $eventType =~ s/(.*)\*.*$/$1/; + $eventType =~ s/^([^Q].*)/org.kde.koala.$1/; + $eventType =~ s/^(Q.*)/org.kde.qt.$1/; + $jbridgeCode .= "\tvoid $name(@castedArgList[0..$#argTypeList]) {\n"; + $jbridgeCode .= "\t\tif (!QtSupport::eventDelegate(this,\"$name\",(void*)" . (@argTypeList[0] =~ /\*/ ? "" : "&") . "arg1,\"$eventType\")) {\n"; + $jbridgeCode .= "\t\t\t" . $parent->{astNodeName} . "::" . "$name(arg1);\n"; + $jbridgeCode .= "\t\t}\n"; + $jbridgeCode .= "\t\treturn;\n\t}\n"; + } elsif( $name =~ /eventFilter$/ and $isQObject and $#argTypeList eq 1) { + $jbridgeCode .= "\tbool eventFilter(QObject* object,QEvent* event) {\n"; + $jbridgeCode .= "\t\tif (!QtSupport::eventFilterDelegate(this,\"$qobjectType\",object,event)) {\n"; + $jbridgeCode .= "\t\t\treturn " . $parent->{astNodeName} . "::eventFilter(object,event);\n"; + $jbridgeCode .= "\t\t} else {\n"; + $jbridgeCode .= "\t\t\treturn TRUE;\n"; + $jbridgeCode .= "\t\t}\n\t}\n"; + } elsif( $name =~ /^fixup$/ and $node->{astNodeName} eq 'QValidator' ) { + $jbridgeCode .= "\tQValidator::State validate(QString& input,int& pos) const\n"; + $jbridgeCode .= "\t{\n"; + $jbridgeCode .= "\t\treturn (QValidator::State) QtSupport::validateDelegate((QValidator*)this,input,pos);\n"; + $jbridgeCode .= "\t}\n"; + $jbridgeCode .= "\tvoid fixup(QString& input) const\n"; + $jbridgeCode .= "\t{\n"; + $jbridgeCode .= "\t\tQtSupport::fixupDelegate((QValidator*) this, input);\n"; + $jbridgeCode .= "\t\treturn;\n\t}\n"; + } elsif( $m->{ReturnType} eq 'void' and $#argTypeList eq -1 and $isQObject) { + $jbridgeCode .= "\tvoid $name() {\n"; + $jbridgeCode .= "\t\tif (!QtSupport::voidDelegate(this,\"$qobjectType\",\"$name\")) {\n"; + $jbridgeCode .= "\t\t\t" . $parent->{astNodeName} . "::$name();\n"; + $jbridgeCode .= "\t\t}\n"; + $jbridgeCode .= "\t\treturn;\n\t}\n"; + } elsif( cplusplusToJava( $m->{ReturnType} ) eq 'boolean' and $#argTypeList eq -1 and $isQObject ) { + $jbridgeCode .= "\t" . $m->{ReturnType} . " $name() {\n"; + $jbridgeCode .= "\t\treturn QtSupport::booleanDelegate(this,\"$name\");\n"; + $jbridgeCode .= "\t}\n"; + } + } + } + + return $jbridgeCode; +} + +# Return 0 if the class has no virtual dtor, 1 if it has, 2 if it's private +sub hasVirtualDestructor($) +{ + my ( $classNode ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if ( $skippedClasses{$className} ); + + my $parentHasIt; + # Look at ancestors, and (recursively) call hasVirtualDestructor for each + # It's enough to have one parent with a prot/public virtual dtor + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + my $vd = hasVirtualDestructor( $_[0] ); + $parentHasIt = $vd unless $parentHasIt > $vd; + } ); + return $parentHasIt if $parentHasIt; # 1 or 2 + + # Now look in $classNode - including private methods + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + my $result; + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + return unless( $m->{NodeType} eq "method" && $m->{ReturnType} eq '~' ); + + if ( $m->{Flags} =~ /[vp]/ ) { + if ( $m->{Access} =~ /private/ ) { + $result=2; # private virtual + } else { + $result=1; # [protected or public] virtual + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; + $result=0 if (!defined $result); + return $result; +} + +=head2 allVirtualMethods + + Parameters: class node, dict + + Adds to the dict, for all method nodes that are virtual, in this class and in parent classes : + {method} the method node, {class} the class node (the one where the virtual is implemented) + +=cut + +sub allVirtualMethods($$) +{ + my ( $classNode, $virtualMethods ) = @_; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if ( $skippedClasses{$className} ); + + # Look at ancestors, and (recursively) call allVirtualMethods for each + # This is done first, so that virtual methods that are reimplemented as 'private' + # can be removed from the list afterwards (below) + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + allVirtualMethods( @_[0], $virtualMethods ); + }, undef + ); + + # Now look for virtual methods in $classNode - including private ones + my $doPrivate = $main::doPrivate; + $main::doPrivate = 1; + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + # Only interested in methods, and skip destructors + return unless( $m->{NodeType} eq "method" && $m->{ReturnType} ne '~' ); + + my $signature = methodSignature( $m, $#{$m->{ParamList}} ); + print STDERR $signature . " ($m->{Access})\n" if ($debug); + + # A method is virtual if marked as such (v=virtual p=pure virtual) + # or if a parent method with same signature was virtual + if ( $m->{Flags} =~ /[vp]/ or defined $virtualMethods->{$signature} ) { + if ( $m->{Access} =~ /private/ ) { + if ( defined $virtualMethods->{$signature} ) { # remove previously defined + delete $virtualMethods->{$signature}; + } + # else, nothing, just ignore private virtual method + } else { + $virtualMethods->{$signature}{method} = $m; + $virtualMethods->{$signature}{class} = $classNode; + } + } + }, + undef + ); + $main::doPrivate = $doPrivate; +} + +# Known typedef? If so, apply it. +sub applyTypeDef($) +{ + my $type = shift; + # Parse 'const' in front of it, and '*' or '&' after it + my $prefix = $type =~ s/^const\s+// ? 'const ' : ''; + my $suffix = $type =~ s/\s*([\&\*]+)$// ? $1 : ''; + + if (exists $typedeflist{$type}) { + return $prefix.$typedeflist{$type}.$suffix; + } + return $prefix.$type.$suffix; +} + +# Register type ($1) into %allTypes if not already there +sub registerType($$) { + my $type = shift; + #print "registerType: $type\n" if ($debug); + + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + return if ( $type eq 'void' or $type eq '' or $type eq '~' ); + die if ( $type eq '...' ); # ouch + + # Let's register the real type, not its known equivalent + #$type = applyTypeDef($type); + + # Enum _value_ -> get corresponding type + if (exists $enumValueToType{$type}) { + $type = $enumValueToType{$type}; + } + + # Already in allTypes + if(exists $allTypes{$type}) { + return; + } + + die if $type eq 'QTextEdit::UndoRedoInfo::Type'; + die if $type eq ''; + + my $realType = $type; + + # Look for references (&) and pointers (* or **) - this will not handle *& correctly. + # We do this parsing here because both the type list and iterproto need it + if($realType =~ s/&$//) { + $allTypes{$type}{typeFlags} = 'Smoke::tf_ref'; + } + elsif($realType ne 'void*' && $realType =~ s/\*$//) { + $allTypes{$type}{typeFlags} = 'Smoke::tf_ptr'; + } + else { + $allTypes{$type}{typeFlags} = 'Smoke::tf_stack'; + } + + if ( $realType =~ s/^const\s+// ) { # Remove 'const' + $allTypes{$type}{typeFlags} .= ' | Smoke::tf_const'; + } + + # Apply typedefs, and store the resulting type. + # For instance, if $type was Q_UINT16&, realType will be ushort + $allTypes{$type}{realType} = applyTypeDef( $realType ); + + # In the first phase we only create entries into allTypes. + # The values (indexes) are calculated afterwards, once the list is full. + $allTypes{$type}{index} = -1; + #print STDERR "Register $type. Realtype: $realType\n" if($debug); +} + +# Get type from %allTypes +# This returns a hash with {index}, {isEnum}, {typeFlags}, {realType} +# (and {typeId} after the types array is written by writeSmokeDataFile) +sub findTypeEntry($) { + my $type = shift; + my $typeIndex = -1; + $type =~ s/\s+const$//; # for 'char* const' + $type =~ s/\s+const\s*\*$/\*/; # for 'char* const*' + + return undef if ( $type =~ '~' or $type eq 'void' or $type eq '' ); + + # Enum _value_ -> get corresponding type + if (exists $enumValueToType{$type}) { + $type = $enumValueToType{$type}; + } + + die "type not known: $type" unless defined $allTypes{$type}; + return $allTypes{ $type }; +} + +# List of all java super-classes for a given class, via single inheritance. +# Excluding any which are mapped onto interfaces to avoid multiple inheritance. +sub direct_superclass_list($) +{ + my $classNode = shift; + my @super; + my $has_ancestor = 0; + my $direct_ancestor = undef; + my $name; + + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + ( $direct_ancestor, $name ) = @_; + if ($name =~ /QMemArray|QSqlFieldInfoList/) { + # Template classes, give up for now.. + $has_ancestor = 1; + } elsif (kalyptusDataDict::interfacemap($name) eq "") { + push @super, $direct_ancestor; + push @super, direct_superclass_list( $direct_ancestor ); + $has_ancestor = 1; + } + }, undef ); + + if (! $has_ancestor and defined $direct_ancestor) { + push @super, $direct_ancestor; + push @super, direct_superclass_list( $direct_ancestor ); + } + + return @super; +} + +# List of all super-classes for a given class +sub superclass_list($) +{ + my $classNode = shift; + my @super; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + push @super, @_[0]; + push @super, superclass_list( @_[0] ); + }, undef ); + return @super; +} + +sub is_kindof($$) +{ + my $classNode = shift; + my $className = shift; + + if ($classNode->{astNodeName} eq $className) { + return 1; + } + + my @superclasses = superclass_list($classNode); + foreach my $ancestor (@superclasses) { + if ($ancestor->{astNodeName} eq $className) { + return 1; + } + } + + return 0; +} + +# Store the {case} dict in the class Node (method signature -> index in the "case" switch) +# This also determines which methods should NOT be in the switch, and sets {SkipFromSwitch} for them +sub prepareCaseDict($) { + + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + $classNode->AddProp("case", {}); + my $methodNumber = 0; + + # First look at all enums for this class + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'enum'; + foreach my $val ( @{$m->{ParamList}} ) { + my $fullEnumName = "$className\::".$val->{ArgName}; + print STDERR "Enum: $fullEnumName -> case $methodNumber\n" if ($debug); + $classNode->{case}{$fullEnumName} = $methodNumber; + $enumValueToType{$fullEnumName} = "$className\::$m->{astNodeName}"; + $methodNumber++; + } + }, undef ); + + # Check for static vars + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'var'; + my $name = "$className\::".$m->{astNodeName}; + print STDERR "Var: $name -> case $methodNumber\n" if ($debug); + $classNode->{case}{$name} = $methodNumber; + $methodNumber++; + + }, undef ); + + + # Now look at all methods for this class + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + next unless $m->{NodeType} eq 'method'; + my $name = $m->{astNodeName}; + my $isConstructor = ($name eq $classNode->{astNodeName} ); + if ($isConstructor and ($m->{ReturnType} eq '~')) # destructor + { + # Remember whether we'll generate a switch entry for the destructor + $m->{SkipFromSwitch} = 1 unless ($classNode->{CanBeInstanciated} and $classNode->{HasPublicDestructor}); + next; + } + + # Don't generate bindings for protected methods (incl. signals) if + # we're not deriving from the C++ class. Only take public and public_slots + my $ok = ( $classNode->{BindingDerives} or $m->{Access} =~ /public/ ) ? 1 : 0; + + # Don't generate bindings for pure virtuals - we can't call them ;) + $ok = 0 if ( $ok && $m->{Flags} =~ "p" ); + + # Bugfix for Qt-3.0.4: those methods are NOT implemented (report sent). + $ok = 0 if ( $ok && $className eq 'QLineEdit' && ( $name eq 'setPasswordChar' || $name eq 'passwordChar' ) ); + $ok = 0 if ( $ok && $className eq 'QWidgetItem' && $name eq 'widgetSizeHint' ); + + if ( !$ok ) + { + #print STDERR "Skipping $className\::$name\n" if ($debug); + $m->{SkipFromSwitch} = 1; + next; + } + + my @args = @{ $m->{ParamList} }; + my $last = $m->{FirstDefaultParam}; + $last = scalar @args unless defined $last; + my $iterationCount = scalar(@args) - $last; + while($iterationCount >= 0) { + my $sig = methodSignature( $m, $#args ); + $classNode->{case}{$sig} = $methodNumber; + #print STDERR "prepareCaseDict: registered case number $methodNumber for $sig in $className()\n" if ($debug); + pop @args; + $iterationCount--; + $methodNumber++; + } + }, undef ); + + # Add the destructor, at the end + if ($classNode->{CanBeInstanciated} and $classNode->{HasPublicDestructor}) { + $classNode->{case}{"~$className()"} = $methodNumber; + # workaround for ~Sub::Class() being seen as Sub::~Class() + $classNode->{case}{"~$classNode->{astNodeName}()"} = $methodNumber; + #print STDERR "prepareCaseDict: registered case number $methodNumber for ~$className()\n" if ($debug); + } +} + +sub writeSmokeDataFile($) { + my $rootnode = shift; + + # Make list of classes + my %allImports; # list of all header files for all classes + my @classlist; + push @classlist, ""; # Prepend empty item for "no class" + my %enumclasslist; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = $_[0]; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + push @classlist, $className; + $enumclasslist{$className}++ if keys %{$classNode->{enumerations}}; + $classNode->{ClassIndex} = $#classlist; + addImportForClass( $classNode, \%allImports, undef ); + } ); + + my %classidx = do { my $i = 0; map { $_ => $i++ } @classlist }; + + my $file = "$outputdir/smokedata.cpp"; +# open OUT, ">$file" or die "Couldn't create $file\n"; + +# foreach my $incl (sort{ +# return 1 if $a=~/qmotif/; # move qmotif* at bottom (they include dirty X11 headers) +# return -1 if $b=~/qmotif/; +# return -1 if substr($a,0,1) eq 'q' and substr($b,0,1) ne 'q'; # move Qt headers on top +# return 1 if substr($a,0,1) ne 'q' and substr($b,0,1) eq 'q'; +# $a cmp $b +# } keys %allIncludes) { +# die if $imp eq ''; +# print OUT "import $imp;\n"; +# } + +# print OUT "\n"; + + print STDERR "Writing ${libname}_cast function\n" if ($debug); + + # Prepare descendants information for each class + my %descendants; # classname -> list of descendant nodes + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + # Get _all_ superclasses (up any number of levels) + # and store that $classNode is a descendant of $s + my @super = superclass_list($classNode); + for my $s (@super) { + my $superClassName = join( "::", kdocAstUtil::heritage($s) ); + Ast::AddPropList( \%descendants, $superClassName, $classNode ); + } + } ); + + # Iterate over all classes, to write the xtypecast function + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + # @super will contain superclasses, the class itself, and all descendants + my @super = superclass_list($classNode); + push @super, $classNode; + if ( defined $descendants{$className} ) { + push @super, @{$descendants{$className}}; + } + my $cur = $classidx{$className}; + + return if $classNode->{NodeType} eq 'namespace'; + +# print OUT " case $cur:\t//$className\n"; +# print OUT "\tswitch(to) {\n"; +# $cur = -1; +# my %casevalues; +# for my $s (@super) { +# my $superClassName = join( "::", kdocAstUtil::heritage($s) ); +# next if !defined $classidx{$superClassName}; # inherits from unknown class, see below +# next if $classidx{$superClassName} == $cur; # shouldn't happen in Qt +# next if $s->kdocAstUtil::inheritsAsVirtual($classNode); # can't cast from a virtual base class +# $cur = $classidx{$superClassName}; # KDE has MI with diamond shaped cycles (cf. KXMLGUIClient) +# next if $casevalues{$cur}; # ..so skip any duplicate parents +# print OUT "\t case $cur: return (void*)($superClassName*)($className*)xptr;\n"; +# $casevalues{$cur} = 1; +# } +# print OUT "\t default: return xptr;\n"; +# print OUT "\t}\n"; + } ); +# print OUT " default: return xptr;\n"; +# print OUT " }\n"; +# print OUT "}\n\n"; + + + # Write inheritance array + # Imagine you have "Class : public super1, super2" + # The inheritlist array will get 3 new items: super1, super2, 0 + my %inheritfinder; # key = (super1, super2) -> data = (index in @inheritlist). This one allows reuse. + my %classinherit; # we store that index in %classinherit{className} + # We don't actually need to store inheritlist in memory, we write it + # directly to the file. We only need to remember its current size. + my $inheritlistsize = 1; + +# print OUT "// Group of class IDs (0 separated) used as super class lists.\n"; +# print OUT "// Classes with super classes have an index into this array.\n"; +# print OUT "static short ${libname}_inheritanceList[] = {\n"; +# print OUT "\t0,\t// 0: (no super class)\n"; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "__", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + print STDERR "inheritanceList: looking at $className\n" if ($debug); + + # Make list of direct ancestors + my @super; + Iter::Ancestors( $classNode, $rootnode, undef, undef, sub { + my $superClassName = join( "::", kdocAstUtil::heritage($_[0]) ); + push @super, $superClassName; + }, undef ); + # Turn that into a list of class indexes + my $key = ''; + foreach my $superClass( @super ) { + if (defined $classidx{$superClass}) { + $key .= ', ' if ( length $key > 0 ); + $key .= $classidx{$superClass}; + } + } + if ( $key ne '' ) { + if ( !defined $inheritfinder{$key} ) { + print OUT "\t"; + my $index = $inheritlistsize; # Index of first entry (for this group) in inheritlist + foreach my $superClass( @super ) { + if (defined $classidx{$superClass}) { + print OUT "$classidx{$superClass}, "; + $inheritlistsize++; + } + } + $inheritlistsize++; + my $comment = join( ", ", @super ); + print OUT "0,\t// $index: $comment\n"; + $inheritfinder{$key} = $index; + } + $classinherit{$className} = $inheritfinder{$key}; + } else { # No superclass + $classinherit{$className} = 0; + } + } ); +# print OUT "};\n\n"; + + +# print OUT "// These are the xenum functions for manipulating enum pointers\n"; + for my $className (keys %enumclasslist) { + my $c = $className; + $c =~ s/::/__/g; +# print OUT "void xenum_$c\(Smoke::EnumOperation, Smoke::Index, void*&, long&);\n"; + } +# print OUT "\n"; +# print OUT "// Those are the xcall functions defined in each x_*.cpp file, for dispatching method calls\n"; + my $firstClass = 1; + for my $className (@classlist) { + if ($firstClass) { + $firstClass = 0; + next; + } + my $c = $className; # make a copy + $c =~ s/::/__/g; +# print OUT "void xcall_$c\(Smoke::Index, void*, Smoke::Stack);\n"; + } +# print OUT "\n"; + + # Write class list afterwards because it needs offsets to the inheritance array. +# print OUT "// List of all classes\n"; +# print OUT "// Name, index into inheritanceList, method dispatcher, enum dispatcher, class flags\n"; +# print OUT "static Smoke::Class ${libname}_classes[] = {\n"; + my $firstClass = 1; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "__", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + if ($firstClass) { + $firstClass = 0; + print OUT "\t{ 0L, 0, 0, 0, 0 }, \t// 0 (no class)\n"; + } + my $c = $className; + $c =~ s/::/__/g; + my $xcallFunc = "xcall_$c"; + my $xenumFunc = "0"; + $xenumFunc = "xenum_$c" if exists $enumclasslist{$className}; + # %classinherit needs Foo__Bar, not Foo::Bar? + die "problem with $className" unless defined $classinherit{$c}; + + my $xClassFlags = 0; + $xClassFlags .= "|Smoke::cf_constructor" if $classNode->{CanBeInstanciated}; # correct? + $xClassFlags .= "|Smoke::cf_deepcopy" if $classNode->{CanBeCopied}; # HasCopyConstructor would be wrong (when it's private) + $xClassFlags .= "|Smoke::cf_virtual" if hasVirtualDestructor($classNode) == 1; + # $xClassFlags .= "|Smoke::cf_undefined" if ...; + $xClassFlags =~ s/0\|//; # beautify +# print OUT "\t{ \"$className\", $classinherit{$c}, $xcallFunc, $xenumFunc, $xClassFlags }, \t//$classidx{$className}\n"; + } ); +# print OUT "};\n\n"; + + +# print OUT "// List of all types needed by the methods (arguments and return values)\n"; +# print OUT "// Name, class ID if arg is a class, and TypeId\n"; +# print OUT "static Smoke::Type ${libname}_types[] = {\n"; + my $typeCount = 0; + $allTypes{''}{index} = 0; # We need an "item 0" + for my $type (sort keys %allTypes) { + $allTypes{$type}{index} = $typeCount; # Register proper index in allTypes + if ( $typeCount == 0 ) { +# print OUT "\t{ 0, 0, 0 },\t//0 (no type)\n"; + $typeCount++; + next; + } + my $isEnum = $allTypes{$type}{isEnum}; + my $typeId; + my $typeFlags = $allTypes{$type}{typeFlags}; + my $realType = $allTypes{$type}{realType}; + die "$type" if !defined $typeFlags; +# die "$realType" if $realType =~ /\(/; + # First write the name +# print OUT "\t{ \"$type\", "; + # Then write the classId (and find out the typeid at the same time) + if(exists $classidx{$realType}) { # this one first, we want t_class for QBlah* + $typeId = 't_class'; +# print OUT "$classidx{$realType}, "; + } + elsif($type =~ /&$/ || $type =~ /\*$/) { + $typeId = 't_voidp'; +# print OUT "0, "; # no classId + } + elsif($isEnum || $allTypes{$realType}{isEnum}) { + $typeId = 't_enum'; + if($realType =~ /(.*)::/) { + my $c = $1; + if($classidx{$c}) { +# print OUT "$classidx{$c}, "; + } else { +# print OUT "0 /* unknown class $c */, "; + } + } else { +# print OUT "0 /* unknown $realType */, "; # no classId + } + } + else { + $typeId = $typeunion{$realType}; + if (defined $typeId) { + $typeId =~ s/s_/t_/; # from s_short to t_short for instance + } + else { + # Not a known class - ouch, this happens quite a lot + # (private classes, typedefs, template-based types, etc) + if ( $skippedClasses{$realType} ) { +# print STDERR "$realType has been skipped, using t_voidp for it\n"; + } else { + unless( $realType =~ /</ ) { # Don't warn for template stuff... + print STDERR "$realType isn't a known type (type=$type)\n"; + } + } + $typeId = 't_voidp'; # Unknown -> map to a void * + } +# print OUT "0, "; # no classId + } + # Then write the flags + die "$type" if !defined $typeId; +# print OUT "Smoke::$typeId | $typeFlags },"; +# print OUT "\t//$typeCount\n"; + $typeCount++; + # Remember it for coerce_type + $allTypes{$type}{typeId} = $typeId; + } +# print OUT "};\n\n"; + + + my %arglist; # registers the needs for argumentList (groups of type ids) + my %methods; + # Look for all methods and all enums, in all classes + # And fill in methods and arglist. This loop writes nothing to OUT. + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + print STDERR "writeSmokeDataFile: arglist: looking at $className\n" if ($debug); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + my $methName = $m->{astNodeName}; + # For destructors, get a proper signature that includes the '~' + if ( $m->{ReturnType} eq '~' ) + { + $methName = '~' . $methName ; + # Let's even store that change, otherwise we have to do it many times + $m->{astNodeName} = $methName; + } + + if( $m->{NodeType} eq "enum" ) { + + foreach my $enum ( @{$m->{ParamList}} ) { + my $enumName = $enum->{ArgName}; + $methods{$enumName}++; + } + + } elsif ( $m->{NodeType} eq 'var' ) { + + $methods{$m->{astNodeName}}++; + + } elsif( $m->{NodeType} eq "method" ) { + + $methods{$methName}++; + my @protos; + makeprotos(\%classidx, $m, \@protos); + + #print "made @protos from $className $methName $m->{Signature})\n" if ($debug); + for my $p (@protos) { + $methods{$p}++; + my $argcnt = 0; + $argcnt = length($1) if $p =~ /([\$\#\?]+)/; + my $sig = methodSignature($m, $argcnt-1); + # Store in a class hash named "proto", a proto+signature => method association + $classNode->{proto}{$p}{$sig} = $m; + #$classNode->{signature}{$sig} = $p; + # There's probably a way to do this better, but this is the fastest way + # to get the old code going: store classname into method + $m->{class} = $className; + } + + my $firstDefaultParam = $m->{FirstDefaultParam}; + $firstDefaultParam = scalar(@{ $m->{ParamList} }) unless defined $firstDefaultParam; + my $argNames = ''; + my $args = ''; + for(my $i = 0; $i < @{ $m->{ParamList} }; $i++) { + $args .= ', ' if $i; + $argNames .= ', ' if $i; + my $argType = $m->{ParamList}[$i]{ArgType}; + my $typeEntry = findTypeEntry( $argType ); + $args .= defined $typeEntry ? $typeEntry->{index} : 0; + $argNames .= $argType; + + if($i >= ($firstDefaultParam - 1)) { + #print "arglist entry: $args\n"; + $arglist{$args} = $argNames; + } + + } + # create an entry for e.g. "arg0,arg1,arg2" where argN is index in allTypes of type for argN + # The value, $argNames, is temporarily stored, to be written out as comment + # It gets replaced with the index in the next loop. + #print "arglist entry : $args\n"; + $arglist{$args} = $argNames; + } + }, # end of sub + undef + ); + }); + + + $arglist{''} = 0; + # Print arguments array +# print OUT "static Smoke::Index ${libname}_argumentList[] = {\n"; + my $argListCount = 0; + for my $args (sort keys %arglist) { + my @dunnohowtoavoidthat = split(',',$args); + my $numTypes = $#dunnohowtoavoidthat; + if ($args eq '') { +# print OUT "\t0,\t//0 (void)\n"; + } else { + # This is a nice trick : args can be written in one go ;) +# print OUT "\t$args, 0,\t//$argListCount $arglist{$args} \n"; + } + $arglist{$args} = $argListCount; # Register proper index in argList + $argListCount += $numTypes + 2; # Move forward by as much as we wrote out + } +# print OUT "};\n\n"; + + $methods{''} = 0; + my @methodlist = sort keys %methods; + my %methodidx = do { my $i = 0; map { $_ => $i++ } @methodlist }; + +# print OUT "// Raw list of all methods, using munged names\n"; +# print OUT "static const char *${libname}_methodNames[] = {\n"; + my $methodNameCount = $#methodlist; + for my $m (@methodlist) { +# print OUT qq( "$m",\t//$methodidx{$m}\n); + } +# print OUT "};\n\n"; + +# print OUT "// (classId, name (index in methodNames), argumentList index, number of args, method flags, return type (index in types), xcall() index)\n"; +# print OUT "static Smoke::Method ${libname}_methods[] = {\n"; + my @methods; + %allMethods = (); + my $methodCount = 0; + # Look at all classes and all enums again + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + return if $classNode->{NodeType} eq 'namespace'; + + my $classIndex = $classidx{$className}; + print STDERR "writeSmokeDataFile: methods: looking at $className\n" if ($debug); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + if( $m->{NodeType} eq "enum" ) { + + foreach my $enum ( @{$m->{ParamList}} ) { + my $enumName = $enum->{ArgName}; + my $fullEnumName = "$className\::$enumName"; + my $sig = "$className\::$enumName\()"; + my $xmethIndex = $methodidx{$enumName}; + die "'Method index' for enum $sig not found" unless defined $xmethIndex; + my $typeId = findTypeEntry( $fullEnumName )->{index}; + die "enum has no {case} value in $className: $fullEnumName" unless defined $classNode->{case}{$fullEnumName}; +# print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullEnumName}},\t//$methodCount $fullEnumName (enum)\n"; + $allMethods{$sig} = $methodCount; + print STDERR "Added entry for " . $sig . " into \$allMethods\n" if ($debug); + $methods[$methodCount] = { + c => $classIndex, + methIndex => $xmethIndex, + argcnt => '0', + args => 0, + retTypeIndex => 0, + idx => $classNode->{case}{$fullEnumName} + }; + $methodCount++; + } + + } elsif( $m->{NodeType} eq 'var' ) { + + my $name = $m->{astNodeName}; + my $fullName = "$className\::$name"; + my $sig = "$fullName\()"; + my $xmethIndex = $methodidx{$name}; + die "'Method index' for var $sig not found" unless defined $xmethIndex; + my $varType = $m->{Type}; + $varType =~ s/static\s//; + $varType =~ s/const\s+(.*)\s*&/$1/; + $varType =~ s/\s*$//; + my $typeId = findTypeEntry( $varType )->{index}; + die "var has no {case} value in $className: $fullName" unless defined $classNode->{case}{$fullName}; +# print OUT "\t{$classIndex, $xmethIndex, 0, 0, Smoke::mf_static, $typeId, $classNode->{case}{$fullName}},\t//$methodCount $fullName (static var)\n"; + $allMethods{$sig} = $methodCount; + print STDERR "Added entry for " . $sig . " into \$allMethods\n" if ($debug); + $methods[$methodCount] = { + c => $classIndex, + methIndex => $xmethIndex, + argcnt => '0', + args => 0, + retTypeIndex => 0, + idx => $classNode->{case}{$fullName} + }; + $methodCount++; + + + } elsif( $m->{NodeType} eq "method" ) { + + # We generate a method entry only if the method is in the switch() code + # BUT: for pure virtuals, they need to have a method entry, even though they + # do NOT have a switch code. + return if ( $m->{SkipFromSwitch} && $m->{Flags} !~ "p" ); + + # No switch code for destructors if we didn't derive from the class (e.g. it has private ctors only) + return if ( $m->{ReturnType} eq '~' && ! ( $classNode->{BindingDerives} and $classNode->{HasPublicDestructor}) ); + + # Is this sorting really important? + #for my $m (sort {$a->{name} cmp $b->{name}} @{ $self->{$c}{method} }) { + + my $methName = $m->{astNodeName}; + my $def = $m->{FirstDefaultParam}; + $def = scalar(@{ $m->{ParamList} }) unless defined $def; + my $last = scalar(@{ $m->{ParamList} }) - 1; + #print STDERR "writeSmokeDataFile: methods: generating for method $methName, def=$def last=$last\n" if ($debug); + + while($last >= ($def-1)) { + last if $last < -1; + my $args = [ @{ $m->{ParamList} }[0..$last] ]; + my $sig = methodSignature($m, $last); + #my $methodSig = $classNode->{signature}{$sig}; # Munged signature + #print STDERR "writeSmokeDataFile: methods: sig=$className\::$sig methodSig=$methodSig\n" if ($debug); + #my $methodIndex = $methodidx{$methodSig}; + #die "$methodSig" if !defined $methodIndex; + + my $methodIndex = $methodidx{$methName}; + die "$methName" if !defined $methodIndex; + my $case = $classNode->{case}{$sig}; + my $typeEntry = findTypeEntry( $m->{ReturnType} ); + my $retTypeIndex = defined $typeEntry ? $typeEntry->{index} : 0; + + my $i = 0; + my $t = ''; + for my $arg (@$args) { + $t .= ', ' if $i++; + my $typeEntry = findTypeEntry( $arg->{ArgType} ); + $t .= defined $typeEntry ? $typeEntry->{index} : 0; + } + my $arglist = $t eq '' ? 0 : $arglist{$t}; + die "arglist for $t not found" unless defined $arglist; + if ( $m->{Flags} =~ "p" ) { + # Pure virtuals don't have a {case} number, that's normal + die if defined $case; + $case = -1; # This remains -1, not 0 ! + } else { + ; +# die "$className\::$methName has no case number for sig=$sig" unless defined $case; + } + my $argcnt = $last + 1; + my $methodFlags = '0'; + $methodFlags .= "|Smoke::mf_static" if $m->{Flags} =~ "s"; + $methodFlags .= "|Smoke::mf_const" if $m->{Flags} =~ "c"; # useful?? probably not + $methodFlags =~ s/0\|//; # beautify + +# print OUT "\t{$classIndex, $methodIndex, $arglist, $argcnt, $methodFlags, $retTypeIndex, $case},\t//$methodCount $className\::$sig"; +# print OUT " [pure virtual]" if ( $m->{Flags} =~ "p" ); # explain why $case = -1 ;) +# print OUT "\n"; + + $allMethods{$className . "::" . $sig} = $methodCount; + $methods[$methodCount] = { + c => $classIndex, + methIndex => $methodIndex, + argcnt => $argcnt, + args => $arglist, + retTypeIndex => $retTypeIndex, + idx => $case + }; + $methodCount++; + $last--; + } # while + } # if method + } ); # Method Iter + } ); # Class Iter +# print OUT "};\n\n"; + + my @protos; + Iter::LocalCompounds( $rootnode, sub { + my $classNode = shift; + my $className = join( "::", kdocAstUtil::heritage($classNode) ); + + return if $classNode->{NodeType} eq 'namespace'; + + my $classIndex = $classidx{$className}; + print STDERR "writeSmokeDataFile: protos: looking at $className\n" if ($debug); + + Iter::MembersByType ( $classNode, undef, + sub { my ($classNode, $m ) = @_; + + if( $m->{NodeType} eq "enum" ) { + foreach my $enum ( @{$m->{ParamList}} ) { + my $enumName = $enum->{ArgName}; + my $sig = "$className\::$enumName\()"; + my $xmeth = $allMethods{$sig}; + die "'Method' for enum $sig not found" unless defined $xmeth; + my $xmethIndex = $methodidx{$enumName}; + die "'Method index' for enum $enumName not found" unless defined $xmethIndex; + push @protos, { + methIndex => $xmethIndex, + c => $classIndex, + over => { + $sig => { + sig => $sig, + } + }, + meth => $xmeth + }; + } + + } elsif( $m->{NodeType} eq 'var' ) { + + my $name = $m->{astNodeName}; + my $fullName = "$className\::$name"; + my $sig = "$fullName\()"; + my $xmeth = $allMethods{$sig}; + die "'Method' for var $sig not found" unless defined $xmeth; + my $xmethIndex = $methodidx{$name}; + die "'Method index' for var $name not found" unless defined $xmethIndex; + push @protos, { + methIndex => $xmethIndex, + c => $classIndex, + over => { + $sig => { + sig => $sig, + } + }, + meth => $xmeth + }; + + } + }); + + for my $p (keys %{ $classNode->{proto} }) { + # For each prototype + my $scratch = { %{ $classNode->{proto}{$p} } }; # sig->method association + # first, grab all the superclass voodoo + for my $supNode (superclass_list($classNode)) { + my $i = $supNode->{proto}{$p}; + next unless $i; + for my $k (keys %$i) { + $scratch->{$k} = $i->{$k} unless exists $scratch->{$k}; + } + } + + # Ok, now we have a full list + #if(scalar keys %$scratch > 1) { + #print STDERR "Overload: $p (@{[keys %$scratch]})\n" if ($debug); + #} + my $xmethIndex = $methodidx{$p}; + my $classIndex = $classidx{$className}; + for my $sig (keys %$scratch) { + #my $xsig = $scratch->{$sig}{class} . "::" . $sig; + my $xsig = $className . "::" . $sig; + $scratch->{$sig}{sig} = $xsig; + delete $scratch->{$sig} + if $scratch->{$sig}{Flags} =~ "p" # pure virtual + or not exists $allMethods{$xsig}; + } + push @protos, { + methIndex => $xmethIndex, + c => $classIndex, + over => $scratch + } if scalar keys %$scratch; + } + }); + + my @protolist = sort { $a->{c} <=> $b->{c} || $a->{methIndex} <=> $b->{methIndex} } @protos; +#for my $abc (@protos) { +#print "$abc->{methIndex}.$abc->{c}\n"; +#} + + print STDERR "Writing methodmap table\n" if ($debug); + my @resolve = (); +# print OUT "// Class ID, munged name ID (index into methodNames), method def (see methods) if >0 or number of overloads if <0\n"; + my $methodMapCount = 1; +# print OUT "static Smoke::MethodMap ${libname}_methodMaps[] = {\n"; +# print OUT "\t{ 0, 0, 0 },\t//0 (no method)\n"; + for my $cur (@protolist) { + if(scalar keys %{ $cur->{over} } > 1) { +# print OUT "\t{$cur->{c}, $cur->{methIndex}, -@{[1+scalar @resolve]}},\t//$methodMapCount $classlist[$cur->{c}]\::$methodlist[$cur->{methIndex}]\n"; + $methodMapCount++; + for my $k (keys %{ $cur->{over} }) { + my $p = $cur->{over}{$k}; + my $xsig = $p->{class} ? "$p->{class}\::$k" : $p->{sig}; + push @resolve, { k => $k, p => $p, cur => $cur, id => $allMethods{$xsig} }; + } + push @resolve, 0; + } else { + for my $k (keys %{ $cur->{over} }) { + my $p = $cur->{over}{$k}; + my $xsig = $p->{class} ? "$p->{class}\::$k" : $p->{sig}; +# print OUT "\t{$cur->{c}, $cur->{methIndex}, $allMethods{$xsig}},\t//$methodMapCount $classlist[$cur->{c}]\::$methodlist[$cur->{methIndex}]\n"; + $methodMapCount++; + } + } + } +# print OUT "};\n\n"; + + + print STDERR "Writing ambiguousMethodList\n" if ($debug); +# print OUT "static Smoke::Index ${libname}_ambiguousMethodList[] = {\n"; +# print OUT " 0,\n"; + for my $r (@resolve) { + unless($r) { +# print OUT " 0,\n"; + next; + } + my $xsig = $r->{p}{class} ? "$r->{p}{class}\::$r->{k}" : $r->{p}{sig}; + die "ambiguousMethodList: no method found for $xsig\n" if !defined $allMethods{$xsig}; +# print OUT " $allMethods{$xsig}, // $xsig\n"; + } +# print OUT "};\n\n"; + +# print OUT "extern \"C\" { // needed?\n"; +# print OUT " void init_${libname}_Smoke();\n"; +# print OUT "}\n"; +# print OUT "\n"; +# print OUT "Smoke* qt_Smoke = 0L;\n"; +# print OUT "\n"; +# print OUT "// Create the Smoke instance encapsulating all the above.\n"; +# print OUT "void init_${libname}_Smoke() {\n"; +# print OUT " qt_Smoke = new Smoke(\n"; +# print OUT " ${libname}_classes, ".$#classlist.",\n"; +# print OUT " ${libname}_methods, $methodCount,\n"; +# print OUT " ${libname}_methodMaps, $methodMapCount,\n"; +# print OUT " ${libname}_methodNames, $methodNameCount,\n"; +# print OUT " ${libname}_types, $typeCount,\n"; +# print OUT " ${libname}_inheritanceList,\n"; +# print OUT " ${libname}_argumentList,\n"; +# print OUT " ${libname}_ambiguousMethodList,\n"; +# print OUT " ${libname}_cast );\n"; +# print OUT "}\n"; +# close OUT; + +#print "@{[keys %allMethods ]}\n"; +} +=head2 printJavadocComment + + Parameters: docnode filehandle + + Converts a kdoc comment to javadoc format. + @ref's are converted to @link's; @p's and @em's are converted + to inline HTML. + +=cut + +sub printJavadocComment($$$$) +{ + my( $docnode, $name, $indent, $signalLink ) = @_; + + my $node; + my $returntext = ''; + foreach $node ( @{$docnode->{Text}} ) { + next if $node->{NodeType} ne "DocText" and $node->{NodeType} ne "ListItem" + and $node->{NodeType} ne "Param"; + my $line = ''; + + if ($node->{NodeType} eq "Param") { + if ($node->{Name} !~ /argc/) { + $line = "\@param " . $node->{Name} . " " . $node->{astNodeName}; + } + } else { + $line = $node->{astNodeName}; + } + $line =~ s/argc, ?argv/args/g; + $line =~ s/int argc, ?char ?\* ?argv(\[\])?/String[] args/g; + $line =~ s/int argc, ?char ?\*\* ?argv/String[] args/g; + if ($node->{NodeType} eq "Param") { + $line =~ s/(const )?QC?StringList(\s*&)?/String[]/g; + } else { + $line =~ s/(const )?QC?StringList(\s*&)?/ArrayList/g; + } + $line =~ s/NodeList|KTrader::OfferList/ArrayList/g; + $line =~ s/(const )?QDate(Time)?(\s*&)?/Calendar/g; + $line =~ s/(const )?QTime([^r])/Date$1/g; + $line =~ s/QString::null/null/g; + $line =~ s/(const )?QC?String(\s*&)?/String/g; + $line =~ s/QByteArray/byte[]/g; + $line =~ s/(const )?KCmdLineOptions\s*(\w+)\[\]/String[][] $2/; + $line =~ s/KCmdLineLastOption//g; + $line =~ s/virtual //g; + $line =~ s/~\w+\(\)((\s*{\s*})|;)//g; + $line =~ s/0L/null/g; + $line =~ s/(\([^\)]*\))\s*:\s*\w+\([^\)]*\)/$1/g; + $line =~ s/\(void\)//g; + $line =~ s/const char/String/g; + $line =~ s/const (\w+)\&/$1/g; + $line =~ s/bool/boolean/g; + $line =~ s/SLOT\(\s*([^\)]*)\) ?\)/SLOT("$1)")/g; + $line =~ s/SIGNAL\(\s*([^\)]*)\) ?\)/SIGNAL("$1)")/g; + $line =~ s/Q_OBJECT\n//g; + $line =~ s/class\s+([\w]+)\s*:\s*public/public class $1 implements/g; + $line =~ s/public\s*(slots)?:\n/public /g; + $line =~ s/([^0-9"]\s*)\*(\s*[^0-9"-])/$1$2/g; + $line =~ s/^(\s*)\*/$1/g; + $line =~ s/\n \*/\n /g; + $line =~ s/\@ref\s+([\w]+)::([\w]+)\s*(\([^\)]*\))(\.)?/{\@link $1#$2}$4/g; + $line =~ s/\@ref\s+#([\w:]+)(\(\))?/{\@link #$1}/g; + $line =~ s/\@ref\s+([\w]+)\s*(\([^\)]*\))/{\@link #$1}/g; + $line =~ s/\@ref\s+([\w]+)::([\w]+)/{\@link $1#$2}/g; + $line =~ s/\@ref\s+([a-z][\w]+)/{\@link #$1}/g; + $line =~ s/\@ref\s+([\w]+)/{\@link $1}/g; + while ($line =~ /\@c\s+([\w#\\\.<>]+)/ ) { + my $code = $1; + $code =~ s!<!<!g; + $code =~ s!>!>!g; + $code =~ s!\\#!#!g; + $line =~ s!\@c\s+([\w#\\\.<>]+)!<code>$code</code>!; + } + $line =~ s!\@em\s+(\w+)!<b>$1</b>!g; + $line =~ s!\@p\s+([\w\._]*)!<code>$1</code>!g; + $line =~ s!\\paragraph\s+[\w]+\s([\w]+)!<li><b>$1</b></li>!g; + $line =~ s!\\b\s+([\w -]+)\\n!<li><b>$1</b></li>!g; + $line =~ s!\\c\s+([\w\@&\\?;-]+)!<code>$1</code>!g; + $line =~ s!\\p\s+([\w\@]+)!<pre>$1</pre>!g; + $line =~ s!\\li\s+([\w\@]+)!<li>$1</li>!g; + $line =~ s!<b>([\w\t \(\)-]*:?)</b>\\n!<li><b>$1</b></li>!g; + $line =~ s!static_cast<\s*([\w\.]*)\s*>!($1)!g; + if ($name ne "") { + $line =~ s/\@link #/\@link $name\#/g; + } + + if ($node->{NodeType} eq "ListItem") { + $line =~ s/^/\n<li>\n/; + $line =~ s!$!\n</li>!; + $line =~ s/\n/\n$indent\t/g; + } else { + $line =~ s/^/$indent/; + $line =~ s/\n/\n$indent/g; + } + + $line =~ s/\n/\n$indent/g; + $returntext .= $line; + } + + $returntext .= $signalLink; + + if ( defined $docnode->{Returns} ) { + my $text = $docnode->{Returns}; + $text =~ s/QString::null/null/g; + $returntext .= "\t\t\@return $text\n"; + } + + if ( defined $docnode->{Author} ) { + $returntext .= "\t\t\@author " . $docnode->{Author} . "\n" + } + + if ( defined $docnode->{Version} ) { + my $versionStr = $docnode->{Version}; + $versionStr =~ s/\$\s*Id:([^\$]*) Exp \$/$1/; + $returntext .= "\t\t\@version $versionStr\n"; + } + + if ( defined $docnode->{ClassShort} ) { + my $shortText = $docnode->{ClassShort}; + $shortText =~ s![\*\n]! !g; + $returntext .= "\t\t\@short $shortText\n"; + } + + if ( defined $docnode->{See} ) { + foreach my $text ( @{$docnode->{See}} ) { + next if ($text =~ /QString|^\s*and\s*$|^\s*$|^[^\w]*$/); + $text =~ s/KIO:://g; + $text =~ s/KParts:://g; + $text =~ s/bool/boolean/g; + $text =~ s/::/#/g; + $text =~ s/->/#/g; + $text =~ s/\./#/g; + $text =~ s/\(\)//g; + $text =~ s/^\s*([a-z].*)/#$1/g; + $text =~ s/^\s*Q/org.kde.qt.Q/g; +# $text =~ s/^\s*K/org.kde.koala.K/g; + $returntext .= "\t\t\@see $text\n"; + } + } + + $returntext =~ s/DOM#([A-Z])/$1/g; + $returntext =~ s/KIO#([A-Z])/$1/g; + $returntext =~ s/KParts#([A-Z])/$1/g; + $returntext =~ s/const\s+(\w+)\s*\&/$1/g; + $returntext =~ s/QChar/char/g; + $returntext =~ s/QStringList/ArrayList/g; + $returntext =~ s/([Aa]) ArrayList/$1n ArrayList/g; + $returntext =~ s/QString/String/g; + $returntext =~ s/KCmdLineOptions/String[][]/; + $returntext =~ s!\\note!<b>Note:<\b>!g; + $returntext =~ s!\\(code|verbatim)!<pre>!g; + $returntext =~ s!\\(endcode|endverbatim)!</pre>!g; + $returntext =~ s!\\addtogroup\s+[\w]+\s+"([^"\@]+)"\s+\@{!<li><b>$1</b></li>!g; + $returntext =~ s![\\\@]relates\s+([a-z][\w]*)!{\@link #$1}!g; + $returntext =~ s![\\\@]relates\s+(\w+)::(\w+)!{\@link $1#$2}!g; + $returntext =~ s![\\\@]relates\s+(#?\w+)!{\@link $1}!g; + $returntext =~ s!\\c\s+([\w\@&\\?";-]+)!<code>$1</code>!g; + $returntext =~ s!\@p\s+([\w\._]*)!<code>$1</code>!g; + $returntext =~ s!\@a\s+([:\w]+)!<b>$1</b>!g; + $returntext =~ s![\@\\]b\s+[:\w]!<b>$1</b>!g; + $returntext =~ s/};/}/g; + $returntext =~ s/::/./g; + $returntext =~ s/->/./g; + + $returntext =~ s/\s*$//; + return $returntext . "\n" . $indent; +} + +1; |