=begin /*************************************************************************** qtruby.rb - description ------------------- begin : Fri Jul 4 2003 copyright : (C) 2003 by Richard Dale email : Richard_Dale@tipitina.demon.co.uk ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ =end module TQt module DebugLevel Off, Minimal, High, Extensive = 0, 1, 2, 3 end module QtDebugChannel TQTDB_NONE = 0x00 TQTDB_AMBIGUOUS = 0x01 TQTDB_METHOD_MISSING = 0x02 TQTDB_CALLS = 0x04 TQTDB_GC = 0x08 TQTDB_VIRTUAL = 0x10 TQTDB_VERBOSE = 0x20 TQTDB_ALL = TQTDB_VERBOSE | TQTDB_VIRTUAL | TQTDB_GC | TQTDB_CALLS | TQTDB_METHOD_MISSING | TQTDB_AMBIGUOUS end @@debug_level = DebugLevel::Off def TQt.debug_level=(level) @@debug_level = level Internal::setDebug TQt::QtDebugChannel::TQTDB_ALL if level >= DebugLevel::Extensive end def TQt.debug_level @@debug_level end class Base def self.signals(*signal_list) meta = TQt::Meta[self.name] || TQt::MetaInfo.new(self) meta.add_signals(signal_list) meta.changed = true end def self.slots(*slot_list) meta = TQt::Meta[self.name] || TQt::MetaInfo.new(self) meta.add_slots(slot_list) meta.changed = true end def **(a) return TQt::**(self, a) end def +(a) return TQt::+(self, a) end def ~(a) return TQt::~(self, a) end def -@() return TQt::-(self) end def -(a) return TQt::-(self, a) end def *(a) return TQt::*(self, a) end def /(a) return TQt::/(self, a) end def %(a) return TQt::%(self, a) end def >>(a) return TQt::>>(self, a) end def <<(a) return TQt::<<(self, a) end def &(a) return TQt::&(self, a) end def ^(a) return TQt::^(self, a) end def |(a) return TQt::|(self, a) end # Module has '<', '<=', '>' and '>=' operator instance methods, so pretend they # don't exist by calling method_missing() explicitely def <(a) begin TQt::method_missing(:<, self, a) rescue super(a) end end def <=(a) begin TQt::method_missing(:<=, self, a) rescue super(a) end end def >(a) begin TQt::method_missing(:>, self, a) rescue super(a) end end def >=(a) begin TQt::method_missing(:>=, self, a) rescue super(a) end end # Object has a '==' operator instance method, so pretend it # don't exist by calling method_missing() explicitely def ==(a) begin TQt::method_missing(:==, self, a) rescue super(a) end end def methods(regular=true) if !regular return singleton_methods end qt_methods(super, 0x0) end def protected_methods # From smoke.h, Smoke::mf_protected 0x80 qt_methods(super, 0x80) end def public_methods methods end def singleton_methods # From smoke.h, Smoke::mf_static 0x01 qt_methods(super, 0x01) end private def qt_methods(meths, flags) ids = [] # These methods are all defined in TQt::Base, even if they aren't supported by a particular # subclass, so remove them to avoid confusion meths -= ["%", "&", "*", "**", "+", "-", "-@", "/", "<", "<<", "<=", ">", ">=", ">>", "|", "~", "^"] classid = TQt::Internal::idInstance(self) TQt::Internal::getAllParents(classid, ids) ids << classid ids.each { |c| TQt::Internal::findAllMethodNames(meths, c, flags) } return meths.uniq end end # TQt::Base # Delete the underlying C++ instance after exec returns # Otherwise, rb_gc_call_finalizer_at_exit() can delete # stuff that TQt::Application still needs for its cleanup. class Application < TQt::Base def exec method_missing(:exec) self.dispose TQt::Internal.application_terminated = true end def exit(*args) method_missing(:exit, *args) end def type(*args) method_missing(:type, *args) end end class BoxLayout < TQt::Base include Enumerable def each it = iterator() while it.current yield it.current it += 1 end end end class Buffer < TQt::Base def open(*args) method_missing(:open, *args) end end class ButtonGroup < TQt::Base def id(*args) method_missing(:id, *args) end end class ByteArray < TQt::Base def to_s return data() end def length return size() end def data=(data) setRawData(data) end end class CheckListItem < TQt::Base def type(*args) method_missing(:type, *args) end end class ChildEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class ClassInfo < TQt::Base def name(*args) method_missing(:name, *args) end end class CloseEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class Color < TQt::Base def inspect str = super str.sub(/>$/, " %s>" % name) end def pretty_print(pp) str = to_s pp.text str.sub(/>$/, " %s>" % name) end def name(*args) method_missing(:name, *args) end end class Connection < TQt::Base def inspect str = super str.sub(/>$/, " memberName=%s, memberType=%s, object=%s>" % [memberName.inspect, memberType == 1 ? "TQ_SLOT" : "TQ_SIGNAL", object.inspect] ) end def pretty_print(pp) str = to_s pp.text str.sub(/>$/, "\n memberName=%s,\n memberType=%s,\n object=%s>" % [memberName.inspect, memberType == 1 ? "TQ_SLOT" : "TQ_SIGNAL", object.inspect] ) end end class ContextMenuEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class Cursor < TQt::Base def inspect str = super str.sub(/>$/, " shape=%d>" % shape) end def pretty_print(pp) str = to_s pp.text str.sub(/>$/, " shape=%d>" % shape) end end class CustomEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class Date < TQt::Base def inspect str = super str.sub(/>$/, " %s>" % toString) end def pretty_print(pp) str = to_s pp.text str.sub(/>$/, " %s>" % toString) end end class DateTime < TQt::Base def inspect str = super str.sub(/>$/, " %s>" % toString) end def pretty_print(pp) str = to_s pp.text str.sub(/>$/, " %s>" % toString) end end class Dialog < TQt::Base def exec(*args) method_missing(:exec, *args) end end class DomAttr < TQt::Base def name(*args) method_missing(:name, *args) end end class DomDocumentType < TQt::Base def name(*args) method_missing(:name, *args) end end class DragLeaveEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class DropEvent < TQt::Base def format(*args) method_missing(:format, *args) end def type(*args) method_missing(:type, *args) end end class EucJpCodec < TQt::Base def name(*args) method_missing(:name, *args) end end class EucKrCodec < TQt::Base def name(*args) method_missing(:name, *args) end end class Event < TQt::Base def type(*args) method_missing(:type, *args) end end class EventLoop < TQt::Base def exec(*args) method_missing(:exec, *args) end def exit(*args) method_missing(:exit, *args) end end class File < TQt::Base def name(*args) method_missing(:name, *args) end def open(*args) method_missing(:open, *args) end end class FocusEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class Font < TQt::Base def inspect str = super str.sub(/>$/, " family=%s, pointSize=%d, weight=%d, italic=%s, bold=%s, underline=%s, strikeOut=%s>" % [family.inspect, pointSize, weight, italic, bold, underline, strikeOut]) end def pretty_print(pp) str = to_s pp.text str.sub(/>$/, "\n family=%s,\n pointSize=%d,\n weight=%d,\n italic=%s,\n bold=%s,\n underline=%s,\n strikeOut=%s>" % [family.inspect, pointSize, weight, italic, bold, underline, strikeOut]) end end class Ftp < TQt::Base def abort(*args) method_missing(:abort, *args) end end class GLContext < TQt::Base def format(*args) method_missing(:format, *args) end end class GLWidget < TQt::Base def format(*args) method_missing(:format, *args) end end class Gb18030Codec < TQt::Base def name(*args) method_missing(:name, *args) end end class Gb2312Codec < TQt::Base def name(*args) method_missing(:name, *args) end end class GbkCodec < TQt::Base def name(*args) method_missing(:name, *args) end end class GridLayout < TQt::Base include Enumerable def each it = iterator() while it.current yield it.current it += 1 end end end class HBoxLayout < TQt::Base include Enumerable def each it = iterator() while it.current yield it.current it += 1 end end end class HebrewCodec < TQt::Base def name(*args) method_missing(:name, *args) end end class HideEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class Http < TQt::Base def abort(*args) method_missing(:abort, *args) end end class HttpRequestHeader < TQt::Base def method(*args) method_missing(:method, *args) end end class IconDrag < TQt::Base def format(*args) method_missing(:format, *args) end def type(*args) method_missing(:type, *args) end end class Image < TQt::Base def load(*args) method_missing(:load, *args) end end class ImageDecoder < TQt::Base def format(*args) method_missing(:format, *args) end end class ImageDrag < TQt::Base def format(*args) method_missing(:format, *args) end end class ImageIO < TQt::Base def format(*args) method_missing(:format, *args) end end class IMEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class JisCodec < TQt::Base def name(*args) method_missing(:name, *args) end end class KeyEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class LCDNumber < TQt::Base def display(item) method_missing(:display, item) end end class Layout < TQt::Base def freeze(*args) method_missing(:freeze, *args) end end class LayoutIterator < TQt::Base def +(a) for i in 1..a send("operator++".to_sym) end return self end end class Library < TQt::Base def load(*args) method_missing(:load, *args) end end class ListView < TQt::Base include Enumerable def each it = TQt::ListViewItemIterator.new(self) while it.current yield it.current it += 1 end end def sort(*args) method_missing(:sort, *args) end end class ListViewItem < TQt::Base include Enumerable def each it = TQt::ListViewItemIterator.new(self) while it.current yield it.current it += 1 end end def sort(*args) method_missing(:sort, *args) end def inspect str = super str.sub!(/>$/, "") for i in 0..(listView.columns - 1) str << " text%d=%s," % [i, self.text(i)] end str.sub!(/,?$/, ">") end def pretty_print(pp) str = to_s str.sub!(/>$/, "") for i in 0..(listView.columns - 1) str << " text%d=%s," % [i, self.text(i)] end str.sub!(/,?$/, ">") pp.text str end end class Locale < TQt::Base def name(*args) method_missing(:name, *args) end def system(*args) method_missing(:system, *args) end end class MenuItem < TQt::Base def id(*args) method_missing(:id, *args) end end class MetaData < TQt::Base def method(*args) method_missing(:method, *args) end def name(*args) method_missing(:name, *args) end end class MetaEnum < TQt::Base def name(*args) method_missing(:name, *args) end end class MetaProperty < TQt::Base def id(*args) method_missing(:id, *args) end def name(*args) method_missing(:name, *args) end def type(*args) method_missing(:type, *args) end end class MouseEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class MoveEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class Object < TQt::Base def name(*args) method_missing(:name, *args) end end class PaintEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class Picture < TQt::Base def load(*args) method_missing(:load, *args) end end class Pixmap < TQt::Base def load(*args) method_missing(:load, *args) end end class Point < TQt::Base def inspect str = super str.sub(/>$/, " x=%d, y=%d>" % [x, y]) end def pretty_print(pp) str = to_s pp.text str.sub(/>$/, "\n x=%d,\n y=%d>" % [x, y]) end end class PolygonScanner < TQt::Base def scan(*args) method_missing(:scan, *args) end end class PopupMenu < TQt::Base def exec(*args) method_missing(:exec, *args) end end class Printer < TQt::Base def abort(*args) method_missing(:abort, *args) end end class MetaObject < TQt::Base def inspect str = super str.sub!(/>$/, "") str << " className=%s," % className str << " propertyNames=Array (%d element(s))," % numProperties unless numProperties == 0 str << " signalNames=Array (%d element(s))," % numSignals unless numSignals == 0 str << " slotNames=Array (%d element(s))," % numSlots unless numSlots == 0 str << " superClass=%s," % superClass.inspect unless superClass == nil str.chop! str << ">" end def pretty_print(pp) str = to_s str.sub!(/>$/, "") str << "\n className=%s," % className str << "\n propertyNames=Array (%d element(s))," % numProperties unless numProperties == 0 str << "\n signalNames=Array (%d element(s))," % numSignals unless numSignals == 0 str << "\n slotNames=Array (%d element(s))," % numSlots unless numSlots == 0 str << "\n superClass=%s," % superClass.inspect unless superClass == nil str.chop! str << ">" pp.text str end end class Rect < TQt::Base def inspect str = super str.sub(/>$/, " left=%d, right=%d, top=%d, bottom=%d>" % [left, right, top, bottom]) end def pretty_print(pp) str = to_s pp.text str.sub(/>$/, "\n left=%d,\n right=%d,\n top=%d,\n bottom=%d>" % [left, right, top, bottom]) end end class ResizeEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class ShowEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class Size < TQt::Base def inspect str = super str.sub(/>$/, " width=%d, height=%d>" % [width, height]) end def pretty_print(pp) str = to_s pp.text str.sub(/>$/, "\n width=%d,\n height=%d>" % [width, height]) end end class SizePolicy < TQt::Base def inspect str = super str.sub(/>$/, " horData=%d, verData=%d>" % [horData, verData]) end def pretty_print(pp) str = to_s pp.text str.sub(/>$/, "\n horData=%d,\n verData=%d>" % [horData, verData]) end end class SjisCodec < TQt::Base def name(*args) method_missing(:name, *args) end end class Socket < TQt::Base def open(*args) method_missing(:open, *args) end end class SocketDevice < TQt::Base def open(*args) method_missing(:open, *args) end def type(*args) method_missing(:type, *args) end end class SocketNotifier < TQt::Base def type(*args) method_missing(:type, *args) end end class SqlCursor < TQt::Base def exec(*args) method_missing(:exec, *args) end def name(*args) method_missing(:name, *args) end def select(*args) method_missing(:select, *args) end end class SqlDatabase < TQt::Base def exec(*args) method_missing(:exec, *args) end def open(*args) method_missing(:open, *args) end end class SqlDriver < TQt::Base def open(*args) method_missing(:open, *args) end end class SqlError < TQt::Base def type(*args) method_missing(:type, *args) end end class SqlField < TQt::Base def name(*args) method_missing(:name, *args) end def type(*args) method_missing(:type, *args) end end class SqlFieldInfo < TQt::Base def name(*args) method_missing(:name, *args) end def type(*args) method_missing(:type, *args) end end class SqlIndex < TQt::Base def name(*args) method_missing(:name, *args) end end class SqlQuery < TQt::Base def exec(*args) method_missing(:exec, *args) end end class SqlSelectCursor < TQt::Base def exec(*args) method_missing(:exec, *args) end def name(*args) method_missing(:name, *args) end def select(*args) method_missing(:select, *args) end end class StoredDrag < TQt::Base def format(*args) method_missing(:format, *args) end end class StyleSheetItem < TQt::Base def name(*args) method_missing(:name, *args) end end class TextDrag < TQt::Base def format(*args) method_missing(:format, *args) end end class TabletEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class Time < TQt::Base def inspect str = super str.sub(/>$/, " %s>" % toString) end def pretty_print(pp) str = to_s pp.text str.sub(/>$/, " %s>" % toString) end end class TimeEdit < TQt::Base def display method_missing(:display) end end class TimerEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class Translator < TQt::Base def load(*args) method_missing(:load, *args) end end class TranslatorMessage < TQt::Base def hash(*args) method_missing(:hash, *args) end end class TsciiCodec < TQt::Base def name(*args) method_missing(:name, *args) end end class UrlInfo < TQt::Base def name(*args) method_missing(:name, *args) end end class Utf16Codec < TQt::Base def name(*args) method_missing(:name, *args) end end class Utf8Codec < TQt::Base def name(*args) method_missing(:name, *args) end end class Variant < TQt::Base String = 3 Date = 26 Time = 27 DateTime = 28 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 if args[0] == true || args[0] == false super(args[0], 0) else super end end def to_a return toStringList() end def to_f return toDouble() end def to_i return toInt() end def to_int return toInt() end def to_ruby case type() when TQt::Variant::Bitmap return toBitmap when TQt::Variant::Bool return toBool when TQt::Variant::Brush return toBrush when TQt::Variant::ByteArray return toByteArray when TQt::Variant::Color return toColor when TQt::Variant::ColorGroup return toColorGroup when TQt::Variant::CString return toCString when TQt::Variant::Cursor return toCursor when TQt::Variant::Date return toDate when TQt::Variant::DateTime return toDateTime when TQt::Variant::Double return toDouble when TQt::Variant::Font return toFont when TQt::Variant::IconSet return toIconSet when TQt::Variant::Image return toImage when TQt::Variant::Int return toInt when TQt::Variant::KeySequence return toKeySequence when TQt::Variant::List return toList when TQt::Variant::LongLong return toLongLong when TQt::Variant::Map return toMap when TQt::Variant::Palette return toPalette when TQt::Variant::Pen return toPen when TQt::Variant::Pixmap return toPixmap when TQt::Variant::Point return toPoint when TQt::Variant::PointArray return toPointArray when TQt::Variant::Rect return toRect when TQt::Variant::Region return toRegion when TQt::Variant::Size return toSize when TQt::Variant::SizePolicy return toSizePolicy when TQt::Variant::String return toString when TQt::Variant::StringList return toStringList when TQt::Variant::Time return toTime when TQt::Variant::UInt return toUint when TQt::Variant::ULongLong return toULongLong end end def inspect str = super str.sub(/>$/, " typeName=%s>" % typeName) end def pretty_print(pp) str = to_s pp.text str.sub(/>$/, " typeName=%s>" % typeName) end def load(*args) method_missing(:load, *args) end def type(*args) method_missing(:type, *args) end end class VBoxLayout < TQt::Base include Enumerable def each it = iterator() while it.current yield it.current it += 1 end end end class WhatsThis < TQt::Base def WhatsThis.display(*k) method_missing(:display, *k) end end class WheelEvent < TQt::Base def type(*args) method_missing(:type, *args) end end class Widget < TQt::Base def raise(*args) method_missing(:raise, *args) end end class WidgetStack < TQt::Base def id(*args) method_missing(:id, *args) end end class XmlAttributes < TQt::Base def type(*args) method_missing(:type, *args) end end # Provides a mutable numeric class for passing to methods with # C++ 'int*' or 'int&' arg types class Integer attr_accessor :value def initialize(n=0) @value = n end def +(n) return Integer.new(@value + n.to_i) end def -(n) return Integer.new(@value - n.to_i) end def *(n) return Integer.new(@value * n.to_i) end def /(n) return Integer.new(@value / n.to_i) end def %(n) return Integer.new(@value % n.to_i) end def **(n) return Integer.new(@value ** n.to_i) end def |(n) return Integer.new(@value | n.to_i) end def &(n) return Integer.new(@value & n.to_i) end def ^(n) return Integer.new(@value ^ n.to_i) end def <<(n) return Integer.new(@value << n.to_i) end def >>(n) return Integer.new(@value >> n.to_i) end def >(n) return @value > n.to_i end def >=(n) return @value >= n.to_i end def <(n) return @value < n.to_i end def <=(n) return @value <= n.to_i end def <=>(n) if @value < n return -1 elsif @value > n return 1 else return 0 end end def to_f() return @value.to_f end def to_i() return @value.to_i end def to_s() return @value.to_s end def coerce(n) [n, @value] end end # If a C++ enum was converted to an ordinary ruby Integer, the # name of the type is lost. The enum type name is needed for overloaded # method resolution when two methods differ only by an enum type. class Enum < TQt::Integer attr_accessor :type def initialize(n, type) super(n) @value = n @type = type end def |(n) return Enum.new(@value | n.to_i, @type) end def &(n) return Enum.new(@value & n.to_i, @type) end def ^(n) return Enum.new(@value ^ n.to_i, @type) end def <(n) return @value < n.to_i end def <=(n) return @value <= n.to_i end def >(n) return @value > n.to_i end def >=(n) return @value >= n.to_i end def <<(n) return Enum.new(@value << n.to_i, @type) end def >>(n) return Enum.new(@value >> n.to_i, @type) end def ==(n) return @value == n.to_i end def to_i() return @value end def inspect to_s end def pretty_print(pp) pp.text "#<%s:0x%8.8x @type=%s, @value=%d>" % [self.class.name, object_id, type, value] end end # Provides a mutable boolean class for passing to methods with # C++ 'bool*' or 'bool&' arg types class Boolean attr_accessor :value def initialize(b=false) @value = b end def nil? return !@value end end class SignalBlockInvocation < TQt::Object def initialize(parent, block, args) super(parent) self.class.slots "invoke(#{args})" @block = block end def invoke(*args) @block.call(*args) end end class BlockInvocation < TQt::Object def initialize(target, block, args) super(target) self.class.slots "invoke(#{args})" @target = target @block = block end def invoke(*args) @target.instance_exec(*args, &@block) end end module Internal @@classes = {} @@cpp_names = {} @@idclass = [] def Internal.normalize_classname(classname) if classname =~ /^Qext/ now = classname.sub(/^Qext(?=[A-Z])/,'Qext::') elsif classname =~ /^Q/ now = classname.sub(/^Q(?=[A-Z])/,'TQt::') elsif classname =~ /^(TDEConfigSkeleton|KWin)::/ now = classname.sub(/^K?(?=[A-Z])/,'KDE::') elsif classname !~ /::/ now = classname.sub(/^K?(?=[A-Z])/,'KDE::') else now = classname end # puts "normalize_classname = was::#{classname}, now::#{now}" now end def Internal.init_class(c) classname = TQt::Internal::normalize_classname(c) classId = TQt::Internal.idClass(c) insert_pclassid(classname, classId) @@idclass[classId] = classname @@cpp_names[classname] = c klass = isTQObject(classId) ? create_qobject_class(classname) \ : create_qt_class(classname) @@classes[classname] = klass unless klass.nil? end def Internal.debug_level Qt.debug_level end def Internal.checkarg(argtype, typename) puts " #{typename} (#{argtype})" if debug_level >= DebugLevel::High if argtype == 'i' if typename =~ /^int&?$|^signed int&?$|^signed$|^TQ_INT32&?$/ return 1 elsif typename =~ /^(?:short|ushort|unsigned short int|uchar|uint|long|ulong|unsigned long int|unsigned|float|double|TQ_UINT32|TQ_UINT16|TQ_INT16)$/ return 0 else t = typename.sub(/^const\s+/, '') t.sub!(/[&*]$/, '') if isEnum(t) return 0 end end elsif argtype == 'n' if typename =~ /^double$/ return 2 elsif typename =~ /^float$/ return 1 elsif typename =~ /^int&?$/ return 0 elsif typename =~ /^(?:short|ushort|uint|long|ulong|signed|unsigned|float|double)$/ return 0 else t = typename.sub(/^const\s+/, '') t.sub!(/[&*]$/, '') if isEnum(t) return 0 end end elsif argtype == 'B' if typename =~ /^(?:bool)[*&]?$/ return 0 end elsif argtype == 's' if typename =~ /^(const )?((TQChar)[*&]?)$/ return 1 elsif typename =~ /^(?:u?char\*|const u?char\*|(?:const )?(Q(C?)String)[*&]?)$/ qstring = !$1.nil? c = ("C" == $2) return c ? 2 : (qstring ? 3 : 0) end elsif argtype == 'a' # FIXME: shouldn't be hardcoded. Installed handlers should tell what ruby type they expect. if typename =~ /^(?: const\ TQCOORD\*| (?:const\ )? (?: TQStringList[\*&]?| TQValueList[\*&]?| TQRgb\*| char\*\* ) )$/x return 0 end elsif argtype == 'u' # Give nil matched against string types a higher score than anything else if typename =~ /^(?:u?char\*|const u?char\*|(?:const )?((Q(C?)String))[*&]?)$/ return 1 # Numerics will give a runtime conversion error, so they fail the match elsif typename =~ /^(?:short|ushort|uint|long|ulong|signed|unsigned|int)$/ return -99 else return 0 end elsif argtype == 'U' if typename =~ /TQStringList/ return 1 else return 0 end else t = typename.sub(/^const\s+/, '') t.sub!(/[&*]$/, '') if argtype == t return 1 elsif classIsa(argtype, t) return 0 elsif isEnum(argtype) and (t =~ /int|TQ_INT32|uint|TQ_UINT32|long|ulong/ or isEnum(t)) return 0 end end return -99 end def Internal.find_class(classname) # puts @@classes.keys.sort.join "\n" @@classes[classname] end # Runs the initializer as far as allocating the Qt C++ instance. # Then use a throw to jump back to here with the C++ instance # wrapped in a new ruby variable of type T_DATA def Internal.try_initialize(instance, *args) initializer = instance.method(:initialize) catch "newqt" do initializer.call(*args) end end # If a block was passed to the constructor, then # run that now. Either run the context of the new instance # if no args were passed to the block. Or otherwise, # run the block in the context of the arg. def Internal.run_initializer_block(instance, block) if block.arity == -1 instance.instance_eval(&block) elsif block.arity == 1 block.call(instance) else raise ArgumentError, "Wrong number of arguments to block(#{block.arity} for 1)" end end def Internal.do_method_missing(package, method, klass, this, *args) if klass.class == Module classname = klass.name else classname = @@cpp_names[klass.name] if classname.nil? if klass != Object and klass != Qt return do_method_missing(package, method, klass.superclass, this, *args) else return nil end end end if method == "new" method = classname.dup method.gsub!(/^(KParts|TDEIO|KNS|DOM|Kontact|Kate|KTextEditor|TDEConfigSkeleton::ItemEnum|TDEConfigSkeleton|KWin)::/,"") end method = "operator" + method.sub("@","") if method !~ /[a-zA-Z]+/ # Change foobar= to setFoobar() method = 'set' + method[0,1].upcase + method[1,method.length].sub("=", "") if method =~ /.*[^-+%\/|=]=$/ methods = [] methods << method.dup args.each do |arg| if arg.nil? # For each nil arg encountered, triple the number of munged method # templates, in order to cover all possible types that can match nil temp = [] methods.collect! do |meth| temp << meth + '?' temp << meth + '#' meth << '$' end methods.concat(temp) elsif isObject(arg) methods.collect! { |meth| meth << '#' } elsif arg.kind_of? Array or arg.kind_of? Hash methods.collect! { |meth| meth << '?' } else methods.collect! { |meth| meth << '$' } end end methodIds = [] methods.collect { |meth| methodIds.concat( findMethod(classname, meth) ) } if method =~ /_/ && methodIds.length == 0 # If the method name contains underscores, convert to camel case # form and try again method.gsub!(/(.)_(.)/) {$1 + $2.upcase} return do_method_missing(package, method, klass, this, *args) end if debug_level >= DebugLevel::High puts "classname == #{classname}" puts ":: method == #{method}" puts "-> methodIds == #{methodIds.inspect}" puts "candidate list:" prototypes = dumpCandidates(methodIds).split("\n") line_len = (prototypes.collect { |p| p.length }).max prototypes.zip(methodIds) { |prototype,id| puts "#{prototype.ljust line_len} (#{id})" } end chosen = nil if methodIds.length > 0 best_match = -1 methodIds.each do |id| puts "matching => #{id}" if debug_level >= DebugLevel::High current_match = 0 (0...args.length).each do |i| current_match += checkarg( getVALUEtype(args[i]), getTypeNameOfArg(id, i) ) end # Note that if current_match > best_match, then chosen must be nil if current_match > best_match best_match = current_match chosen = id # Multiple matches are an error; the equality test below _cannot_ be commented out. # If ambiguous matches occur the problem must be fixed be adjusting the relative # ranking of the arg types involved in checkarg(). elsif current_match == best_match chosen = nil end puts "match => #{id} score: #{current_match}" if debug_level >= DebugLevel::High end puts "Resolved to id: #{chosen}" if !chosen.nil? && debug_level >= DebugLevel::High end if debug_level >= DebugLevel::Minimal && chosen.nil? && method !~ /^operator/ id = find_pclassid(normalize_classname(klass.name)) hash = findAllMethods(id) constructor_names = nil if method == classname puts "No matching constructor found, possibles:\n" constructor_names = hash.keys.grep(/^#{classname}/) else puts "Possible prototypes:" constructor_names = hash.keys end method_ids = hash.values_at(*constructor_names).flatten puts dumpCandidates(method_ids) end puts "setCurrentMethod(#{chosen})" if debug_level >= DebugLevel::High setCurrentMethod(chosen) if chosen return nil end def Internal.init_all_classes() TQt::Internal::getClassList().each do |c| if c == "Qt" # Don't change Qt to TQt::t, just leave as is @@cpp_names["Qt"] = c elsif c != "TQInternal" TQt::Internal::init_class(c) end end @@classes['TQt::Integer'] = TQt::Integer @@classes['TQt::Boolean'] = TQt::Boolean @@classes['TQt::Enum'] = TQt::Enum end def Internal.get_qinteger(num) return num.value end def Internal.set_qinteger(num, val) return num.value = val end def Internal.create_qenum(num, type) return TQt::Enum.new(num, type) end def Internal.get_qenum_type(e) return e.type end def Internal.get_qboolean(b) return b.value end def Internal.set_qboolean(b, val) return b.value = val end def Internal.getAllParents(class_id, res) getIsa(class_id).each do |s| c = idClass(s) res << c getAllParents(c, res) end end def Internal.getSignalNames(klass) meta = Meta[klass.name] || MetaInfo.new(klass) signal_names = [] meta.get_signals.each do |signal| signal_names.push signal.name end return signal_names end def Internal.signalInfo(qobject, signal_name) signals = Meta[qobject.class.name].get_signals signals.each_with_index do |signal, i| if signal.name == signal_name return [signal.full_name, i] end end end def Internal.signalAt(qobject, index) klass = qobject.class begin meta = Meta[klass.name] klass = klass.superclass end while meta.nil? and klass != Object meta.get_signals[index].full_name end def Internal.slotAt(qobject, index) klass = qobject.class begin meta = Meta[klass.name] klass = klass.superclass end while meta.nil? and klass != Object meta.get_slots[index].full_name end def Internal.getMocArguments(member) argStr = member.sub(/.*\(/, '').sub(/\)$/, '') args = argStr.scan(/([^,]*<[^>]+>)|([^,]+)/) mocargs = allocateMocArguments(args.length) args.each_with_index do |arg, i| arg = arg.to_s a = arg.sub(/^const\s+/, '') a = (a =~ /^(bool|int|double|char\*|TQString)&?$/) ? $1 : 'ptr' valid = setMocType(mocargs, i, arg, a) end result = [] result << args.length << mocargs result end def Internal.makeMetaData(data) return nil if data.nil? tbl = [] data.each do |entry| name = entry.name argStr = entry.arg_types params = [] args = argStr.scan(/[^,]+/) args.each do |arg| name = '' # umm.. is this the aim?, well. it works. soo... ;-) param = make_QUParameter(name, arg, 0, 1) params << param end method = make_QUMethod(name, params) tbl << make_QMetaData(entry.full_name, method) end make_QMetaData_tbl(tbl) end def Internal.getMetaObject(qobject) klass = qobject.class begin meta = Meta[klass.name] klass = klass.superclass end while meta.nil? and klass != Object return nil if meta.nil? if meta.metaobject.nil? or meta.changed slots = meta.get_slots slotTable = makeMetaData(slots) signals = meta.get_signals signalTable = makeMetaData(signals) meta.metaobject = make_metaObject(qobject.class.name, qobject.staticMetaObject(), slotTable, slots.length, signalTable, signals.length) addSignalMethods(qobject.class, getSignalNames(qobject.class)) meta.changed = false end meta.metaobject end def Internal.connect(src, signal, target, block) signature = (signal =~ /\((.*)\)/) ? $1 : "" return TQt::Object.connect( src, signal, TQt::BlockInvocation.new(target, block, signature), TQ_SLOT("invoke(#{signature})") ) end def Internal.signal_connect(src, signal, block) signature = (signal =~ /\((.*)\)/) ? $1 : "" return TQt::Object.connect( src, signal, TQt::SignalBlockInvocation.new(src, block, signature), TQ_SLOT("invoke(#{signature})") ) end end # TQt::Internal Meta = {} # An entry for each signal or slot # Example # foobar(TQString,bool) # :name is 'foobar' # :full_name is 'foobar(TQString,bool)' # :arg_types is 'TQString,bool' TQObjectMember = Struct.new :name, :full_name, :arg_types class MetaInfo attr_accessor :signals, :slots, :metaobject, :mocargs, :changed def initialize(klass) Meta[klass.name] = self @klass = klass @metaobject = nil @signals = [] @slots = [] @changed = false Internal.addMetaObjectMethods(klass) end def add_signals(signal_list) signal_list.each do |signal| if signal.kind_of? Symbol signal = signal.to_s + "()" end signal = TQt::Object.normalizeSignalSlot(signal) if signal =~ /([^\s]*)\((.*)\)/ @signals.push TQObjectMember.new($1, signal, $2) else tqWarning( "#{@klass.name}: Invalid signal format: '#{signal}'" ) end end end # Return a list of signals, including inherited ones def get_signals all_signals = [] current = @klass while current != TQt::Base meta = Meta[current.name] if !meta.nil? all_signals.concat meta.signals end current = current.superclass end return all_signals end def add_slots(slot_list) slot_list.each do |slot| if slot.kind_of? Symbol slot = slot.to_s + "()" end slot = TQt::Object.normalizeSignalSlot(slot) if slot =~ /([^\s]*)\((.*)\)/ @slots.push TQObjectMember.new($1, slot, $2) else tqWarning( "#{@klass.name}: Invalid slot format: '#{slot}'" ) end end end # Return a list of slots, including inherited ones def get_slots all_slots = [] current = @klass while current != TQt::Base meta = Meta[current.name] if !meta.nil? all_slots.concat meta.slots end current = current.superclass end return all_slots end end # TQt::MetaInfo IO_Direct = 0x0100 IO_Sequential = 0x0200 IO_Combined = 0x0300 IO_TypeMask = 0x0f00 IO_Raw = 0x0040 IO_Async = 0x0080 IO_ReadOnly = 0x0001 IO_WriteOnly = 0x0002 IO_ReadWrite = 0x0003 IO_Append = 0x0004 IO_Truncate = 0x0008 IO_Translate = 0x0010 IO_ModeMask = 0x00ff IO_Open = 0x1000 IO_StateMask = 0xf000 IO_Ok = 0 IO_ReadError = 1 IO_WriteError = 2 IO_FatalError = 3 IO_ResourceError = 4 IO_OpenError = 5 IO_ConnectError = 5 IO_AbortError = 6 IO_TimeOutError = 7 IO_UnspecifiedError= 8 end # Qt class Object def TQ_SIGNAL(signal) if signal.kind_of? Symbol return "2" + signal.to_s + "()" else return "2" + signal end end def TQ_SLOT(slot) if slot.kind_of? Symbol return "1" + slot.to_s + "()" else return "1" + slot end end def emit(signal) return signal end # See the discussion here: http://eigenclass.org/hiki.rb?instance_exec # about implementations of the ruby 1.9 method instance_exec(). This # version is the one from Rails. It isn't thread safe, but that doesn't # matter for the intended use in invoking blocks as Qt slots. def instance_exec(*arguments, &block) block.bind(self)[*arguments] end end class Proc # Part of the Rails Object#instance_exec implementation def bind(object) block, time = self, Time.now (class << object; self end).class_eval do method_name = "__bind_#{time.to_i}_#{time.usec}" define_method(method_name, &block) method = instance_method(method_name) remove_method(method_name) method end.bind(object) end end class Module alias_method :_constants, :constants alias_method :_instance_methods, :instance_methods alias_method :_protected_instance_methods, :protected_instance_methods alias_method :_public_instance_methods, :public_instance_methods private :_constants, :_instance_methods private :_protected_instance_methods, :_public_instance_methods def constants qt_methods(_constants, 0x10, true) end def instance_methods(inc_super=true) qt_methods(_instance_methods(inc_super), 0x0, inc_super) end def protected_instance_methods(inc_super=true) qt_methods(_protected_instance_methods(inc_super), 0x80, inc_super) end def public_instance_methods(inc_super=true) qt_methods(_public_instance_methods(inc_super), 0x0, inc_super) end private def qt_methods(meths, flags, inc_super=true) if !self.kind_of? Class return meths end klass = self classid = 0 loop do classid = TQt::Internal::find_pclassid(klass.name) break if classid > 0 klass = klass.superclass if klass.nil? return meths end end # These methods are all defined in TQt::Base, even if they aren't supported by a particular # subclass, so remove them to avoid confusion meths -= ["%", "&", "*", "**", "+", "-", "-@", "/", "<", "<<", "<=", ">", ">=", ">>", "|", "~", "^"] ids = [] if inc_super TQt::Internal::getAllParents(classid, ids) end ids << classid ids.each { |c| TQt::Internal::findAllMethodNames(meths, c, flags) } return meths.uniq end end