[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