[Kde-bindings] KDE/kdebindings/ruby/qtruby

Richard Dale Richard_Dale at tipitina.demon.co.uk
Tue Dec 9 16:47:46 UTC 2008


SVN commit 894931 by rdale:

* Added an ancestors() method to Qt::Base that returns an Array of the
  super classes of a class in the Smoke library. For instance:

	irb(main):001:0> Qt::Widget.ancestors
	=> [Qt::Widget, Qt::Object, Qt::PaintDevice, Object, Kernel]

* Fixed regression caused by adding to Qt::Object.connect() the feature
  to connect an arbitrary ruby method to a signal. It was causing the
  standard three argument form of connect() to not work.
* Renamed the QHash of smoke index against class name as 'IdToClassNameMap'
  instead of 'classname'.
* The child items of a QGraphicsItem are marked as not needing garbage
	  collection of they have corresponding ruby instances.

CCMAIL: kde-bindings at kde.org


 M  +15 -0     ChangeLog  
 M  +2 -5      src/Qt.cpp  
 M  +34 -2     src/handlers.cpp  
 M  +36 -5     src/lib/Qt/qtruby4.rb  
 M  +17 -5     src/qtruby.cpp  
 M  +1 -1      src/qtruby.h  


--- trunk/KDE/kdebindings/ruby/qtruby/ChangeLog #894930:894931
@@ -1,3 +1,18 @@
+2008-12-09  Richard Dale  <richard.j.dale at gmail.com>
+	* Added an ancestors() method to Qt::Base that returns an Array of the
+	  super classes of a class in the Smoke library. For instance:
+
+		irb(main):001:0> Qt::Widget.ancestors
+		=> [Qt::Widget, Qt::Object, Qt::PaintDevice, Object, Kernel]
+
+	* Fixed regression caused by adding to Qt::Object.connect() the feature
+	  to connect an arbitrary ruby method to a signal. It was causing the
+	  standard three argument form of connect() to not work.
+	* Renamed the QHash of smoke index against class name as 'IdToClassNameMap'
+	  instead of 'classname'.
+	* The child items of a QGraphicsItem are marked as not needing garbage
+	  collection of they have corresponding ruby instances.
+
 2008-12-04  Richard Dale  <richard.j.dale at gmail.com>
 
 	* From Bartosz Wadolowski (thanks for the patch):
--- trunk/KDE/kdebindings/ruby/qtruby/src/Qt.cpp #894930:894931
@@ -108,10 +108,7 @@
 QHash<QByteArray, Smoke::ModuleIndex *> methcache;
 QHash<QByteArray, Smoke::ModuleIndex *> classcache;
 
-// FIXME:
-// find some way to use a Smoke::ModuleIndex here instead of an int
-// Maps from an int id to classname in the form Qt::Widget
-QHash<Smoke::ModuleIndex, QByteArray*> classname;
+QHash<Smoke::ModuleIndex, QByteArray*> IdToClassNameMap;
 
 #define logger logger_backend
 
@@ -282,7 +279,7 @@
 char*
 Binding::className(Smoke::Index classId) {
 	Smoke::ModuleIndex mi = { smoke, classId };
-	return (char *) (const char *) *(classname.value(mi));
+	return (char *) (const char *) *(IdToClassNameMap.value(mi));
 }
 
 /*
--- trunk/KDE/kdebindings/ruby/qtruby/src/handlers.cpp #894930:894931
@@ -121,6 +121,31 @@
 }
 
 void
+mark_qgraphicsitem_children(QGraphicsItem * item)
+{
+	VALUE obj;
+	
+	const QList<QGraphicsItem*> l = item->childItems();
+	
+	if (l.count() == 0) {
+		return;
+	}
+
+	QGraphicsItem *child;
+
+	for (int i=0; i < l.size(); ++i) {
+		child = l.at(i);
+		obj = getPointerObject(child);
+		if (obj != Qnil) {
+			if(do_debug & qtdb_gc) qWarning("Marking (%s*)%p -> %p", "QGraphicsItem", child, (void*)obj);
+			rb_gc_mark(obj);
+		}
+		
+		mark_qgraphicsitem_children(child);
+	}
+}
+
+void
 mark_qtreewidgetitem_children(QTreeWidgetItem * item)
 {
 	VALUE obj;
@@ -260,7 +285,15 @@
 			return;
 		}
 
-#if QT_VERSION >= 0x40200
+		if (o->smoke->isDerivedFromByName(className, "QGraphicsItem")) {
+			QGraphicsItem * item = (QGraphicsItem *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("QGraphicsItem").index);
+			// Only mark the QGraphicsItem tree if the current item doesn't have a parent.
+			// This avoids marking parts of a tree more than once.
+			if (item->parentItem() == 0) {
+				mark_qgraphicsitem_children(item);
+			}
+		}
+
 		if (o->smoke->isDerivedFromByName(className, "QGraphicsScene")) {
 			QGraphicsScene * scene = (QGraphicsScene *) o->smoke->cast(o->ptr, o->classId, o->smoke->idClass("QGraphicsScene").index);
 			QList<QGraphicsItem *> list = scene->items();
@@ -276,7 +309,6 @@
 			}			
 			return;
 		}
-#endif
 
 		if (qstrcmp(className, "QModelIndex") == 0) {
 			QModelIndex * qmodelindex = (QModelIndex *) o->ptr;
--- trunk/KDE/kdebindings/ruby/qtruby/src/lib/Qt/qtruby4.rb #894930:894931
@@ -3,8 +3,8 @@
                           qtruby.rb  -  description
                              -------------------
     begin                : Fri Jul 4 2003
-    copyright            : (C) 2003-2005 by Richard Dale
-    email                : Richard_Dale at tipitina.demon.co.uk
+    copyright            : (C) 2003-2008 by Richard Dale
+    email                : richard.j.dale at gmail.com
  ***************************************************************************/
 
 /***************************************************************************
@@ -151,7 +151,6 @@
 #		Object has a '==' operator instance method, so pretend it
 #		don't exist by calling method_missing() explicitely
 		def ==(a)
-
 			return false if a.nil?
 			begin
 				Qt::method_missing(:==, self, a)
@@ -160,7 +159,27 @@
 			end
 		end
 
+		def self.ancestors
+			klass = self
+			classid = nil
+			loop do
+				classid = Qt::Internal::find_pclassid(klass.name)
+				break if classid.index
+      
+				klass = klass.superclass
+				if klass.nil?
+					return super
+				end
+			end
 
+			klasses = super
+			klasses.delete(Qt::Base)
+			klasses.delete(self)
+			ids = []
+			Qt::Internal::getAllParents(classid, ids)
+			return [self] + ids.map {|id| Qt::Internal.find_class(Qt::Internal.classid2name(id))} + klasses
+		end
+
 		def methods(regular=true)
 			if !regular
 				return singleton_methods
@@ -2524,7 +2543,6 @@
 			
 			if method == "new"
 				method = classname.dup 
-#				method.gsub!(/^(QTextBlock|QTextLayout|QTextFrame|QTextOption|QLocale|QAbstractFileEngine|KDateTime|KBookmark|KParts|KMediaPlayer|KIO|KNS|DOM|Kontact|Kate|KSettings|KTimeZone|KTextEditor|KWin|KWallet|Plasma|Sonnet|Soprano|Nepomuk)::/,"")
 				method.gsub!(/^.*::/,"")
 			end
 			method = "operator" + method.sub("@","") if method !~ /[a-zA-Z]+/
@@ -2790,6 +2808,11 @@
 			meta.metaobject
 		end
 
+		# Handles calls of the form:
+		#	connect(myobj, SIGNAL('mysig(int)'), mytarget) {|arg(s)| ...}
+		#	connect(myobj, SIGNAL('mysig(int)')) {|arg(s)| ...}
+		#	connect(myobj, SIGNAL(:mysig), mytarget) { ...}
+		#	connect(myobj, SIGNAL(:mysig)) { ...}
 		def Internal.connect(src, signal, target, block)
 			args = (signal =~ /\((.*)\)/) ? $1 : ""
 			signature = Qt::MetaObject.normalizedSignature("invoke(%s)" % args).to_s
@@ -2799,6 +2822,9 @@
 										SLOT(signature) )
 		end
 
+		# Handles calls of the form:
+		#	connect(SIGNAL(:mysig)) { ...}
+		#	connect(SIGNAL('mysig(int)')) {|arg(s)| ...}
 		def Internal.signal_connect(src, signal, block)
 			args = (signal =~ /\((.*)\)/) ? $1 : ""
 			signature = Qt::MetaObject.normalizedSignature("invoke(%s)" % args).to_s
@@ -2808,8 +2834,11 @@
 										SLOT(signature) )
 		end
 
+		# Handles calls of the form:
+		#	connect(:mysig, mytarget, :mymethod))
+		#	connect(SIGNAL('mysignal(int)'), mytarget, :mymethod))
 		def Internal.method_connect(src, signal, target, method)
-			signal = SIGNAL(signal.to_s + "()") if signal.is_a?Symbol
+			signal = SIGNAL(signal) if signal.is_a?Symbol
 			args = (signal =~ /\((.*)\)/) ? $1 : ""
 			signature = Qt::MetaObject.normalizedSignature("invoke(%s)" % args).to_s
 			return Qt::Object.connect(  src,
@@ -2818,6 +2847,8 @@
 										SLOT(signature) )
 		end
 
+		# Handles calls of the form:
+		#	Qt::Timer.singleShot(500, myobj) { ...}
 		def Internal.single_shot_timer_connect(interval, target, block)
 			return Qt::Timer.singleShot(	interval,
 											Qt::BlockInvocation.new(target, block, "invoke()"),
--- trunk/KDE/kdebindings/ruby/qtruby/src/qtruby.cpp #894930:894931
@@ -1476,10 +1476,11 @@
 			rb_raise(rb_eArgError, "Invalid argument list");
 		}
 	} else {
-		if (argc == 3) {
+		if (argc == 3 && TYPE(argv[1]) != T_STRING) {
 			return rb_funcall(qt_internal_module, rb_intern("method_connect"), 4, self, argv[0], argv[1], argv[2]);
-		} else
+		} else {
 			return rb_call_super(argc, argv);
+		}
 	}
 }
 
@@ -1729,19 +1730,29 @@
     int smokeidx = NUM2INT(rb_funcall(mi_value, rb_intern("smoke"), 0));
     Smoke::ModuleIndex mi = { smokeList[smokeidx], ix };
     classcache.insert(QByteArray(p), new Smoke::ModuleIndex(mi));
-    classname.insert(mi, new QByteArray(p));
+    IdToClassNameMap.insert(mi, new QByteArray(p));
     return self;
 }
 
 static VALUE
+classid2name(VALUE /*self*/, VALUE mi_value)
+{
+    int ix = NUM2INT(rb_funcall(mi_value, rb_intern("index"), 0));
+    int smokeidx = NUM2INT(rb_funcall(mi_value, rb_intern("smoke"), 0));
+    Smoke::ModuleIndex mi = { smokeList[smokeidx], ix };
+    return rb_str_new2(IdToClassNameMap[mi]->constData());
+}
+
+static VALUE
 find_pclassid(VALUE /*self*/, VALUE p_value)
 {
     char *p = StringValuePtr(p_value);
     Smoke::ModuleIndex *r = classcache.value(QByteArray(p));
-    if(r)
+    if (r != 0) {
         return rb_funcall(moduleindex_class, rb_intern("new"), 2, INT2NUM(smokeList.indexOf(r->smoke)), INT2NUM(r->index));
-    else
+    } else {
         return rb_funcall(moduleindex_class, rb_intern("new"), 2, 0, 0);
+    }
 }
 
 static VALUE
@@ -2285,6 +2296,7 @@
     rb_define_module_function(qt_internal_module, "classIsa", (VALUE (*) (...)) classIsa, 2);
     rb_define_module_function(qt_internal_module, "isEnum", (VALUE (*) (...)) isEnum, 1);
     rb_define_module_function(qt_internal_module, "insert_pclassid", (VALUE (*) (...)) insert_pclassid, 2);
+    rb_define_module_function(qt_internal_module, "classid2name", (VALUE (*) (...)) classid2name, 1);
     rb_define_module_function(qt_internal_module, "find_pclassid", (VALUE (*) (...)) find_pclassid, 1);
     rb_define_module_function(qt_internal_module, "get_value_type", (VALUE (*) (...)) get_value_type, 1);
 
--- trunk/KDE/kdebindings/ruby/qtruby/src/qtruby.h #894930:894931
@@ -117,7 +117,7 @@
 extern Q_DECL_EXPORT QHash<QByteArray, Smoke::ModuleIndex *> methcache;
 extern Q_DECL_EXPORT QHash<QByteArray, Smoke::ModuleIndex *> classcache;
 // Maps from an int id to classname in the form Qt::Widget
-extern Q_DECL_EXPORT QHash<Smoke::ModuleIndex, QByteArray*> classname;
+extern Q_DECL_EXPORT QHash<Smoke::ModuleIndex, QByteArray*> IdToClassNameMap;
 
 extern Q_DECL_EXPORT void install_handlers(TypeHandler *);
 



More information about the Kde-bindings mailing list