[Kde-bindings] branches/KDE/3.5/kdebindings/qtruby/rubylib/qtruby
Richard Dale
Richard_Dale at tipitina.demon.co.uk
Tue Dec 5 02:13:13 UTC 2006
SVN commit 610700 by rdale:
* Backported some improvements to Qt::Variants from Qt4 QtRuby
* When marhalling QMap types with QVariant values, if the Ruby value isn't
a Qt::Variant then one is created
* Qt::Variants can now be constructed with Hash's of String/Qt::Variant
pairs, and from Arrays of Qt::Variants
* When marshalling QValueList<QVariant> types from Ruby to C++, if any elements
aren't Ruby Qt::Variants, they are automatically converted. Hence, the
following will work:
v = Qt::Variant.new([1, 2, 3])
The Qt::Variant v will contain a list of 3 QVariants with typeName 'int'
* Change all instances of strcmp() to qstrcmp()
CCMAIL: kde-bindings at kde.org
M +75 -31 Qt.cpp
M +49 -28 handlers.cpp
M +5 -0 lib/Qt/qtruby.rb
M +2 -2 smokeruby.h
--- branches/KDE/3.5/kdebindings/qtruby/rubylib/qtruby/Qt.cpp #610699:610700
@@ -138,7 +138,7 @@
VALUE getPointerObject(void *ptr);
bool isQObject(Smoke *smoke, Smoke::Index classId) {
- if(strcmp(smoke->classes[classId].className, "QObject") == 0)
+ if(qstrcmp(smoke->classes[classId].className, "QObject") == 0)
return true;
for(Smoke::Index *p = smoke->inheritanceList + smoke->classes[classId].parents;
*p;
@@ -346,7 +346,7 @@
void unsupported() {
rb_raise(rb_eArgError, "Cannot handle '%s' as return-type of %s::%s",
type().name(),
- strcmp(_smoke->className(method().classId), "QGlobalSpace") == 0 ? "" : _smoke->className(method().classId),
+ qstrcmp(_smoke->className(method().classId), "QGlobalSpace") == 0 ? "" : _smoke->className(method().classId),
_smoke->methodNames[method().name]);
}
Smoke *smoke() { return _smoke; }
@@ -411,7 +411,7 @@
}
void unsupported() {
- if (strcmp(_smoke->className(method().classId), "QGlobalSpace") == 0) {
+ if (qstrcmp(_smoke->className(method().classId), "QGlobalSpace") == 0) {
rb_raise(rb_eArgError, "Cannot handle '%s' as argument to %s",
type().name(),
_smoke->methodNames[method().name]);
@@ -954,15 +954,15 @@
const char *r = "";
if(ruby_value == Qnil)
r = "u";
- else if(TYPE(ruby_value) == T_FIXNUM || TYPE(ruby_value) == T_BIGNUM || strcmp(classname, "Qt::Integer") == 0)
+ else if(TYPE(ruby_value) == T_FIXNUM || TYPE(ruby_value) == T_BIGNUM || qstrcmp(classname, "Qt::Integer") == 0)
r = "i";
else if(TYPE(ruby_value) == T_FLOAT)
r = "n";
else if(TYPE(ruby_value) == T_STRING)
r = "s";
- else if(ruby_value == Qtrue || ruby_value == Qfalse || strcmp(classname, "Qt::Boolean") == 0)
+ else if(ruby_value == Qtrue || ruby_value == Qfalse || qstrcmp(classname, "Qt::Boolean") == 0)
r = "B";
- else if(strcmp(classname, "Qt::Enum") == 0) {
+ else if(qstrcmp(classname, "Qt::Enum") == 0) {
VALUE temp = rb_funcall(qt_internal_module, rb_intern("get_qenum_type"), 1, ruby_value);
r = StringValuePtr(temp);
} else if(TYPE(ruby_value) == T_DATA) {
@@ -1351,6 +1351,49 @@
return obj;
}
+static VALUE
+new_qvariant(int argc, VALUE * argv, VALUE self)
+{
+static Smoke::Index new_qvariant_qlist = 0;
+static Smoke::Index new_qvariant_qmap = 0;
+
+ if (new_qvariant_qlist == 0) {
+ Smoke::Index nameId = qt_Smoke->idMethodName("QVariant?");
+ Smoke::Index meth = qt_Smoke->findMethod(qt_Smoke->idClass("QVariant"), nameId);
+ Smoke::Index i = qt_Smoke->methodMaps[meth].method;
+ i = -i; // turn into ambiguousMethodList index
+ while (qt_Smoke->ambiguousMethodList[i] != 0) {
+ const char * argType = qt_Smoke->types[qt_Smoke->argumentList[qt_Smoke->methods[qt_Smoke->ambiguousMethodList[i]].args]].name;
+
+ if (qstrcmp(argType, "const QValueList<QVariant>&" ) == 0) {
+ new_qvariant_qlist = qt_Smoke->ambiguousMethodList[i];
+ } else if (qstrcmp(argType, "const QMap<QString,QVariant>&" ) == 0) {
+ new_qvariant_qmap = qt_Smoke->ambiguousMethodList[i];
+ }
+
+ i++;
+ }
+ }
+
+ if (argc == 1 && TYPE(argv[0]) == T_HASH) {
+ _current_method = new_qvariant_qmap;
+ MethodCall c(qt_Smoke, _current_method, self, argv, argc-1);
+ c.next();
+ return *(c.var());
+ } else if ( argc == 1
+ && TYPE(argv[0]) == T_ARRAY
+ && RARRAY(argv[0])->len > 0
+ && TYPE(rb_ary_entry(argv[0], 0)) != T_STRING )
+ {
+ _current_method = new_qvariant_qlist;
+ MethodCall c(qt_Smoke, _current_method, self, argv, argc-1);
+ c.next();
+ return *(c.var());
+ }
+
+ return rb_call_super(argc, argv);
+}
+
static QCString *
find_cached_selector(int argc, VALUE * argv, VALUE klass, char * methodName)
{
@@ -1819,7 +1862,7 @@
// Now, I need to find out if this means me
int index;
char *slotname;
- bool isSignal = strcmp(rb_id2name(rb_frame_last_func()), "qt_emit") == 0;
+ bool isSignal = qstrcmp(rb_id2name(rb_frame_last_func()), "qt_emit") == 0;
VALUE mocArgs = getslotinfo(self, id, slotname, index, isSignal);
if(mocArgs == Qnil) {
// No ruby slot/signal found, assume the target is a C++ one
@@ -1997,17 +2040,17 @@
MocArgument *arg = 0;
Data_Get_Struct(ptr, MocArgument, arg);
arg[idx].st.set(qt_Smoke, typeId);
- if(strcmp(static_type, "ptr") == 0)
+ if(qstrcmp(static_type, "ptr") == 0)
arg[idx].argType = xmoc_ptr;
- else if(strcmp(static_type, "bool") == 0)
+ else if(qstrcmp(static_type, "bool") == 0)
arg[idx].argType = xmoc_bool;
- else if(strcmp(static_type, "int") == 0)
+ else if(qstrcmp(static_type, "int") == 0)
arg[idx].argType = xmoc_int;
- else if(strcmp(static_type, "double") == 0)
+ else if(qstrcmp(static_type, "double") == 0)
arg[idx].argType = xmoc_double;
- else if(strcmp(static_type, "char*") == 0)
+ else if(qstrcmp(static_type, "char*") == 0)
arg[idx].argType = xmoc_charstar;
- else if(strcmp(static_type, "QString") == 0)
+ else if(qstrcmp(static_type, "QString") == 0)
arg[idx].argType = xmoc_QString;
return Qtrue;
}
@@ -2113,16 +2156,16 @@
QUParameter *p = new QUParameter;
p->name = new char[strlen(name) + 1];
strcpy((char*)p->name, name);
- if(strcmp(type, "bool") == 0)
+ if(qstrcmp(type, "bool") == 0)
p->type = &static_QUType_bool;
- else if(strcmp(type, "int") == 0)
+ else if(qstrcmp(type, "int") == 0)
p->type = &static_QUType_int;
- else if(strcmp(type, "double") == 0)
+ else if(qstrcmp(type, "double") == 0)
p->type = &static_QUType_double;
- else if(strcmp(type, "char*") == 0 || strcmp(type, "const char*") == 0)
+ else if(qstrcmp(type, "char*") == 0 || qstrcmp(type, "const char*") == 0)
p->type = &static_QUType_charstar;
- else if(strcmp(type, "QString") == 0 || strcmp(type, "QString&") == 0 ||
- strcmp(type, "const QString") == 0 || strcmp(type, "const QString&") == 0)
+ else if(qstrcmp(type, "QString") == 0 || qstrcmp(type, "QString&") == 0 ||
+ qstrcmp(type, "const QString") == 0 || qstrcmp(type, "const QString&") == 0)
p->type = &static_QUType_QString;
else
p->type = &static_QUType_ptr;
@@ -2424,7 +2467,7 @@
if(!icmp) {
for(Smoke::Index i=methmin ; i <= methmax ; i++) {
Smoke::Index m = qt_Smoke->methodMaps[i].name;
- if(!pat || !strncmp(qt_Smoke->methodNames[m], pat, strlen(pat))) {
+ if(!pat || !qstrncmp(qt_Smoke->methodNames[m], pat, strlen(pat))) {
Smoke::Index ix= qt_Smoke->methodMaps[i].method;
VALUE meths = rb_ary_new();
if(ix >= 0) { // single match
@@ -2460,11 +2503,11 @@
#define PUSH_QTRUBY_METHOD \
if ( (methodRef.flags & (Smoke::mf_internal|Smoke::mf_ctor|Smoke::mf_dtor)) == 0 \
- && strcmp(qt_Smoke->methodNames[methodRef.name], "operator=") != 0 \
- && strcmp(qt_Smoke->methodNames[methodRef.name], "operator!=") != 0 \
- && strcmp(qt_Smoke->methodNames[methodRef.name], "operator--") != 0 \
- && strcmp(qt_Smoke->methodNames[methodRef.name], "operator++") != 0 \
- && strncmp(qt_Smoke->methodNames[methodRef.name], "operator ", strlen("operator ")) != 0 \
+ && qstrcmp(qt_Smoke->methodNames[methodRef.name], "operator=") != 0 \
+ && qstrcmp(qt_Smoke->methodNames[methodRef.name], "operator!=") != 0 \
+ && qstrcmp(qt_Smoke->methodNames[methodRef.name], "operator--") != 0 \
+ && qstrcmp(qt_Smoke->methodNames[methodRef.name], "operator++") != 0 \
+ && qstrncmp(qt_Smoke->methodNames[methodRef.name], "operator ", strlen("operator ")) != 0 \
&& ( (flags == 0 && (methodRef.flags & (Smoke::mf_static|Smoke::mf_enum|Smoke::mf_protected)) == 0) \
|| ( flags == Smoke::mf_static \
&& (methodRef.flags & Smoke::mf_enum) == 0 \
@@ -2473,7 +2516,7 @@
|| ( flags == Smoke::mf_protected \
&& (methodRef.flags & Smoke::mf_static) == 0 \
&& (methodRef.flags & Smoke::mf_protected) == Smoke::mf_protected ) ) ) { \
- if (strncmp(qt_Smoke->methodNames[methodRef.name], "operator", strlen("operator")) == 0) { \
+ if (qstrncmp(qt_Smoke->methodNames[methodRef.name], "operator", strlen("operator")) == 0) { \
if (op_re.search(qt_Smoke->methodNames[methodRef.name]) != -1) { \
rb_ary_push(result, rb_str_new2(op_re.cap(1) + op_re.cap(2))); \
} else { \
@@ -2694,7 +2737,7 @@
if (QString(package).startsWith("Qt::")) {
klass = rb_define_class_under(qt_module, package+strlen("Qt::"), qt_base_class);
- if (strcmp(package, "Qt::Application") == 0) {
+ if (qstrcmp(package, "Qt::Application") == 0) {
rb_define_singleton_method(klass, "new", (VALUE (*) (...)) new_qapplication, -1);
rb_define_method(klass, "ARGV", (VALUE (*) (...)) qapplication_argv, 0);
}
@@ -2735,15 +2778,16 @@
klass = kde_package_to_class(package, qt_base_class);
}
- if (strcmp(package, "Qt::MetaObject") == 0) {
+ if (qstrcmp(package, "Qt::MetaObject") == 0) {
qmetaobject_class = klass;
- } else if (strcmp(package, "Qt::Variant") == 0) {
+ } else if (qstrcmp(package, "Qt::Variant") == 0) {
qvariant_class = klass;
- } else if (strcmp(package, "Qt::ByteArray") == 0) {
+ rb_define_singleton_method(qvariant_class, "new", (VALUE (*) (...)) new_qvariant, -1);
+ } else if (qstrcmp(package, "Qt::ByteArray") == 0) {
rb_define_method(klass, "data", (VALUE (*) (...)) qbytearray_data, 0);
rb_define_method(klass, "size", (VALUE (*) (...)) qbytearray_size, 0);
rb_define_method(klass, "setRawData", (VALUE (*) (...)) qbytearray_setRawData, 1);
- } else if (strcmp(package, "Qt::Char") == 0) {
+ } else if (qstrcmp(package, "Qt::Char") == 0) {
rb_define_method(klass, "to_s", (VALUE (*) (...)) qchar_to_s, 0);
}
--- branches/KDE/3.5/kdebindings/qtruby/rubylib/qtruby/handlers.cpp #610699:610700
@@ -50,6 +50,7 @@
extern "C" {
extern VALUE set_obj_info(const char * className, smokeruby_object * o);
extern VALUE qt_internal_module;
+extern VALUE qvariant_class;
extern bool application_terminated;
};
@@ -183,15 +184,15 @@
unmapPointer(o, o->classId, 0);
object_count --;
- if ( strcmp(className, "QObject") == 0
- || strcmp(className, "QListBoxItem") == 0
- || strcmp(className, "QStyleSheetItem") == 0
- || strcmp(className, "KCommand") == 0
- || strcmp(className, "KNamedCommand") == 0
- || strcmp(className, "KMacroCommand") == 0
- || strcmp(className, "KAboutData") == 0
- || strcmp(className, "KCmdLineArgs") == 0
- || strcmp(className, "QSqlCursor") == 0 )
+ if ( qstrcmp(className, "QObject") == 0
+ || qstrcmp(className, "QListBoxItem") == 0
+ || qstrcmp(className, "QStyleSheetItem") == 0
+ || qstrcmp(className, "KCommand") == 0
+ || qstrcmp(className, "KNamedCommand") == 0
+ || qstrcmp(className, "KMacroCommand") == 0
+ || qstrcmp(className, "KAboutData") == 0
+ || qstrcmp(className, "KCmdLineArgs") == 0
+ || qstrcmp(className, "QSqlCursor") == 0 )
{
// Don't delete instances of these classes for now
free(o);
@@ -202,19 +203,19 @@
free(o);
return;
}
- } else if (strcmp(className, "QIconViewItem") == 0) {
+ } else if (qstrcmp(className, "QIconViewItem") == 0) {
QIconViewItem * item = (QIconViewItem *) o->ptr;
if (item->iconView() != 0) {
free(o);
return;
}
- } else if (strcmp(className, "QCheckListItem") == 0) {
+ } else if (qstrcmp(className, "QCheckListItem") == 0) {
QCheckListItem * item = (QCheckListItem *) o->ptr;
if (item->parent() != 0 || item->listView() != 0) {
free(o);
return;
}
- } else if (strcmp(className, "QListViewItem") == 0) {
+ } else if (qstrcmp(className, "QListViewItem") == 0) {
QListViewItem * item = (QListViewItem *) o->ptr;
if (item->parent() != 0 || item->listView() != 0) {
free(o);
@@ -226,7 +227,7 @@
free(o);
return;
}
- } else if (strcmp(className, "QPopupMenu") == 0) {
+ } else if (qstrcmp(className, "QPopupMenu") == 0) {
QPopupMenu * item = (QPopupMenu *) o->ptr;
if (item->parentWidget(false) != 0) {
free(o);
@@ -400,9 +401,7 @@
{
Smoke::Index *arg = smoke->argumentList + smoke->methods[meth].args + argidx;
SmokeType type = SmokeType(smoke, *arg);
- if(type.name() && !strcmp(type.name(), argtype))
- return true;
- return false;
+ return type.name() && qstrcmp(type.name(), argtype) == 0;
}
void *
@@ -810,9 +809,9 @@
init_codec() {
VALUE temp = rb_gv_get("$KCODE");
KCODE = StringValuePtr(temp);
- if (strcmp(KCODE, "EUC") == 0) {
+ if (qstrcmp(KCODE, "EUC") == 0) {
codec = QTextCodec::codecForName("eucJP");
- } else if (strcmp(KCODE, "SJIS") == 0) {
+ } else if (qstrcmp(KCODE, "SJIS") == 0) {
codec = QTextCodec::codecForName("Shift-JIS");
}
}
@@ -824,13 +823,13 @@
}
QString * s;
- if (strcmp(KCODE, "UTF8") == 0)
+ if (qstrcmp(KCODE, "UTF8") == 0)
s = new QString(QString::fromUtf8(StringValuePtr(rstring), RSTRING(rstring)->len));
- else if (strcmp(KCODE, "EUC") == 0)
+ else if (qstrcmp(KCODE, "EUC") == 0)
s = new QString(codec->toUnicode(StringValuePtr(rstring)));
- else if (strcmp(KCODE, "SJIS") == 0)
+ else if (qstrcmp(KCODE, "SJIS") == 0)
s = new QString(codec->toUnicode(StringValuePtr(rstring)));
- else if(strcmp(KCODE, "NONE") == 0)
+ else if(qstrcmp(KCODE, "NONE") == 0)
s = new QString(QString::fromLatin1(StringValuePtr(rstring)));
else
s = new QString(QString::fromLocal8Bit(StringValuePtr(rstring), RSTRING(rstring)->len));
@@ -843,13 +842,13 @@
init_codec();
}
- if (strcmp(KCODE, "UTF8") == 0)
+ if (qstrcmp(KCODE, "UTF8") == 0)
return rb_str_new2(s->utf8());
- else if (strcmp(KCODE, "EUC") == 0)
+ else if (qstrcmp(KCODE, "EUC") == 0)
return rb_str_new2(codec->fromUnicode(*s));
- else if (strcmp(KCODE, "SJIS") == 0)
+ else if (qstrcmp(KCODE, "SJIS") == 0)
return rb_str_new2(codec->fromUnicode(*s));
- else if (strcmp(KCODE, "NONE") == 0)
+ else if (qstrcmp(KCODE, "NONE") == 0)
return rb_str_new2(s->latin1());
else
return rb_str_new2(s->local8Bit());
@@ -1575,8 +1574,16 @@
VALUE value = rb_ary_entry(rb_ary_entry(temp, i), 1);
smokeruby_object *o = value_obj_info(value);
- if( !o || !o->ptr)
- continue;
+ if (!o || !o->ptr || o->classId != o->smoke->idClass("QVariant")) {
+ // If the value isn't a Qt::Variant, then try and construct
+ // a Qt::Variant from it
+ value = rb_funcall(qvariant_class, rb_intern("new"), 1, value);
+ if (value == Qnil) {
+ continue;
+ }
+ o = value_obj_info(value);
+ }
+
void * ptr = o->ptr;
ptr = o->smoke->cast(ptr, o->classId, o->smoke->idClass("QVariant"));
@@ -1770,6 +1777,20 @@
VALUE item = rb_ary_entry(list, i);
// TODO do type checking!
smokeruby_object *o = value_obj_info(item);
+
+ // Special case for the QValueList<QVariant> type
+ if ( qstrcmp(ItemSTR, "QVariant") == 0
+ && (!o || !o->ptr || o->classId != o->smoke->idClass("QVariant")) )
+ {
+ // If the value isn't a Qt::Variant, then try and construct
+ // a Qt::Variant from it
+ item = rb_funcall(qvariant_class, rb_intern("new"), 1, item);
+ if (item == Qnil) {
+ continue;
+ }
+ o = value_obj_info(item);
+ }
+
if(!o || !o->ptr)
continue;
void *ptr = o->ptr;
--- branches/KDE/3.5/kdebindings/qtruby/rubylib/qtruby/lib/Qt/qtruby.rb #610699:610700
@@ -1013,6 +1013,11 @@
end
class Variant < Qt::Base
+ String = 3
+ Date = 26
+ Time = 27
+ DateTime = 27
+
def initialize(*args)
# In C++, the boolean constructor needs an ugly dummy int argument,
# so special case that here to avoid needing it in Ruby
--- branches/KDE/3.5/kdebindings/qtruby/rubylib/qtruby/smokeruby.h #610699:610700
@@ -64,7 +64,7 @@
bool operator ==(const SmokeType &b) const {
const SmokeType &a = *this;
if(a.name() == b.name()) return true;
- if(a.name() && b.name() && !strcmp(a.name(), b.name()))
+ if(a.name() && b.name() && qstrcmp(a.name(), b.name()) == 0)
return true;
return false;
}
@@ -98,7 +98,7 @@
bool operator ==(const SmokeClass &b) const {
const SmokeClass &a = *this;
if(a.className() == b.className()) return true;
- if(a.className() && b.className() && !strcmp(a.className(), b.className()))
+ if(a.className() && b.className() && qstrcmp(a.className(), b.className()) == 0)
return true;
return false;
}
More information about the Kde-bindings
mailing list