qt_connect 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,657 @@
1
+ =begin
2
+
3
+ Author: Cees Zeelenberg (c.zeelenberg@computer.org)
4
+ Copyright: (c) 2010-2012 by Cees Zeelenberg
5
+ License: This program is free software; you can redistribute it and/or modify
6
+ it under the terms of the GNU Lesser General Public License as published
7
+ by the Free Software Foundation; either version 2 of the License, or
8
+ (at your option) any later version.
9
+
10
+ Provides the basic Ruby bindings for the Qt Jambi Java classes and an interface to the
11
+ Signals and Slots mechanism. Appropriate classes are extended with overloaded operators
12
+ such as +, - , | and &. Both Ruby-ish underscore and Java-ish camel case naming for
13
+ methods can be used. Like with QtRuby, constructors can be called in a conventional
14
+ style or with an initializer block. If you want an API which follows closely the QtJambi
15
+ documentation and programming examples all you need to do is 'require qt_jambi'. A
16
+ minimalist example to display just a button which connects to a website when clicked:
17
+
18
+ require 'qt_jambi'
19
+
20
+ app=Qt::Application.new(ARGV)
21
+ button=Qt::PushButton.new( "Hello World")
22
+ button.clicked.connect{ Qt::DesktopServices.openUrl(Qt::Url.new('www.hello-world.com'))}
23
+ button.show
24
+ app.exec
25
+
26
+ If you want more compatibility with QtRuby, use:
27
+ require 'qt_connect'
28
+
29
+ =end
30
+ $VERB=false
31
+ include Java
32
+ include_class Java::SignalActions
33
+
34
+ module Qt
35
+ module Internal
36
+ #define here which packages to include
37
+ Packages=%w{
38
+ com.trolltech.qt
39
+ com.trolltech.qt.core
40
+ com.trolltech.qt.gui
41
+ com.trolltech.qt.network
42
+ com.trolltech.qt.opengl
43
+ com.trolltech.qt.phonon
44
+ com.trolltech.qt.sql
45
+ com.trolltech.qt.svg
46
+ com.trolltech.qt.webkit
47
+ com.trolltech.qt.xml
48
+ com.trolltech.qt.xmlpatterns
49
+ }
50
+ #keep track of RUBY extensions for classexplorer
51
+ RUBY_extensions=[]
52
+
53
+ def signature(*args)
54
+ RUBY_extensions.concat(args)
55
+ end
56
+ #allow the use of 'signature' within this module
57
+ extend self
58
+ alias :signatures :signature
59
+ end
60
+ end
61
+
62
+
63
+
64
+ module QtJambi
65
+ Qt::Internal::Packages.each { |pkg| include_package pkg}
66
+ ABSTRACTSIGNAL=QSignalEmitter::AbstractSignal.java_class
67
+ SIGNALEMITTERS={
68
+ QSignalEmitter::Signal0 => 'signal0()',
69
+ QSignalEmitter::Signal1 => 'signal1(Object)',
70
+ QSignalEmitter::Signal2 => 'signal2(Object,Object)',
71
+ QSignalEmitter::Signal3 => 'signal3(Object,Object,Object)',
72
+ QSignalEmitter::Signal4 => 'signal4(Object,Object,Object,Object)',
73
+ QSignalEmitter::Signal5 => 'signal5(Object,Object,Object,Object,Object)',
74
+ QSignalEmitter::Signal6 => 'signal6(Object,Object,Object,Object,Object,Object)',
75
+ QSignalEmitter::Signal7 => 'signal7(Object,Object,Object,Object,Object,Object,Object)',
76
+ QSignalEmitter::Signal8 => 'signal8(Object,Object,Object,Object,Object,Object,Object,Object)',
77
+ QSignalEmitter::Signal9 => 'signal9(Object,Object,Object,Object,Object,Object,Object,Object,Object)',
78
+ }
79
+
80
+ end
81
+ # AbstractSignal is the QtJambi class which implements the functionality to emit signals
82
+ # it interoperates with a matching Ruby Qt:Signal class
83
+ # here we extend the existing AbstractSignal 'connect' method with the ability to connect to
84
+ #either a Ruby block or a Ruby Object method through an instance of the RubySignalAction class
85
+ #the signature for the connect is derived from the underlying Signal class (e.g. Signal0..Signal9)
86
+ #SignalEmitters can also be connected to other SignalEmitters (eiher inheriting from the QtJambi
87
+ #AbstractSignal class or the Ruby Signal class)
88
+
89
+ #A: QtJambi::AbstractSignal#connect{ |*args| .......} connect this signal emitter to a Ruby Block
90
+ #B: QtJambi::AbstractSignal#connect(self,:my_method) connect this signal emitter to a receiver/method
91
+ #C: QtJambi::AbstractSignal#connect(Qt::Signal signal2) connect this signal to a Qt::Signal instance
92
+ #D: QtJambi::AbstractSignal#connect(QtJambi::AbstractSignal signal2) connect this signal to another QtJambi::AbstractSignal instance
93
+
94
+ QtJambi::QSignalEmitter::AbstractSignal.class_eval{
95
+ alias :orig_connect :connect
96
+ def connect(a1=nil,a2=nil,&block)
97
+ if a1
98
+ if QtJambi::SIGNALEMITTERS[a1.class]
99
+ orig_connect(a1) #connecting [D]
100
+ return
101
+ end
102
+
103
+ if a1.kind_of?(Qt::Signal)
104
+ @action=Qt::RubySignalAction.new{ |*a| a1.emit(*a)}
105
+ orig_connect(@action,'signal0()') #connecting [C]
106
+ return
107
+ end
108
+ end
109
+ #
110
+ if signature=QtJambi::SIGNALEMITTERS[self.class]
111
+ @action=Qt::RubySignalAction.new(a1,a2,&block)
112
+ orig_connect(@action,signature) #connecting [A,B]
113
+ return
114
+ else
115
+ raise "cannot connect signal #{self} to #{a1}"
116
+ return
117
+ end
118
+ end
119
+ }
120
+
121
+ module Qt
122
+ include com.trolltech.qt.core.Qt
123
+
124
+ class Signal
125
+ def initialize(sender=nil)
126
+ @actions=[]
127
+ @args=nil
128
+ @sender=sender
129
+ end
130
+
131
+ #E: Qt::Signal#connect{ |*args| ......... } connect this signal emitter to a Ruby Block
132
+ #F: Qt::Signal#connect(self,:my_method) connect this signal emitter to a receiver/method
133
+ #G: Qt::Signal#connect(Qt::Signal signal2) connect this signal to another Qt::Signal instance
134
+ #H: Qt::Signal#connect(QtJambi::AbstractSignal signal2) connect this signal to a QtJambi::AbstractSignal instance
135
+
136
+ def connect(a1=nil,a2=nil,&block)
137
+ if (a1 && (a1.kind_of?(Qt::Signal))) ||
138
+ (a1.respond_to?(:java_class) &&
139
+ (a1.java_class.superclass==QtJambi::ABSTRACTSIGNAL))
140
+ @actions << Qt::RubySignalAction.new{ |*args| a1.emit(*args)} #connecting [G,H]
141
+ return
142
+ end
143
+ @actions << Qt::RubySignalAction.new(a1,a2,&block) #connecting [E,F]
144
+ end
145
+
146
+ def setargs(*args)
147
+ @args=args
148
+ end
149
+
150
+ #(Qt::Signal signal).emit(*args)
151
+ def emit(*args)
152
+ @args=args if args.size>0 || @args.nil?
153
+ @actions.each{ |action| action.emit(@args) }
154
+ @args=nil
155
+ end
156
+
157
+ #disconnect() disconnects all connections originating in this signal emitter
158
+ #disconnect(object) disconnects all connections made from this signal emitter to a specific receiver
159
+ #disconnect(object,method) disconnects all connections made from this signal emitter to a specific receiver method
160
+ def disconnect(a1=nil,a2=nil,&block)
161
+ @actions.map{ |action|
162
+ next action if a1 && (action.receiver != a1)
163
+ next action if a2 && (action.method != a2)
164
+ next action if block_given? && (action.block != block)
165
+ action.receiver=nil
166
+ action.method=nil
167
+ action.block=nil
168
+ nil
169
+ }
170
+ @actions.compact!
171
+ end
172
+
173
+ end
174
+
175
+
176
+ # RubySignalAction is the Ruby class which implements the functionality to activate
177
+ # a Ruby Block or Object Method as a result of a Qt emitted Signal
178
+ #the Ruby method names match the names of the Java interface SignalActions:
179
+ #(see SignalActions.java)
180
+
181
+ class RubySignalAction < QtJambi::QObject
182
+ include SignalActions
183
+ attr_accessor :receiver, :method, :block
184
+ def initialize(receiver=nil,method=nil,&block)
185
+ super()
186
+ @receiver=receiver
187
+ @method=method
188
+ @block=block
189
+ @args=[]
190
+ end
191
+
192
+ def append_args(*args)
193
+ @args=args
194
+ end
195
+
196
+ #generate the Ruby method names to match the names of the Java interface SignalAction
197
+ #e.g. def signal6(a1,a2,a3,a4,a5,a6,a7) ; emit([a1,a2,a3,a4,a5,a6]) ; end
198
+ #e.g. def signal7(a1,a2,a3,a4,a5,a6,a7) ; emit([a1,a2,a3,a4,a5,a6,a7]) ; end
199
+ QtJambi::SIGNALEMITTERS.values.each{ |signature|
200
+ i=0
201
+ s1=signature.gsub(/Object/){ |m| i+=1 ; "a#{i}"}
202
+ s2=s1.gsub(/signal\d\(/,"emit([").gsub(')','])')
203
+ eval "def #{s1} ; #{s2} ; end"
204
+ }
205
+
206
+ def emit(a)
207
+ args=a+@args
208
+ n=nil
209
+ if @method && (md=@method.to_s.match(/([0-9]*)(.+)/x)) #??????????????????
210
+ n=md[1].to_i unless md[1]==''
211
+ @method=md[2].gsub('()','').to_sym
212
+ end
213
+ if (m=args.size)>0
214
+ @block.call(*args) if @block
215
+ if @receiver && @method
216
+ #cap the number of arguments to number wanted by receiver
217
+ #e.g. triggered uses signal1 iso signal0 as in example
218
+ n ||=@receiver.method(@method).arity
219
+ if (n==0)
220
+ @receiver.send(@method)
221
+ else
222
+ args.slice!(0,n) if (m>n) && (n>0)
223
+ @receiver.send(@method,*args)
224
+ end
225
+ end
226
+ else
227
+ @block.call if @block
228
+ @receiver.send(@method) if @receiver && @method
229
+ end
230
+ end
231
+ end
232
+
233
+ class << self
234
+ #come here on missing constant in the Qt namespace
235
+ #if the missing name maps to an existing QtJambi class, equate the missing constant to that class and
236
+ # - make Signal fields accessable to Ruby methods
237
+ # - define a 'new' classmethod with optional iterator block initialization
238
+ # - define 'shorthand' constants to be compatible with qtbindings (optional, require 'qt_compat.rb' )
239
+ # - monkeypatch the underlying class with extensions defined in Qt::Internal (optional, require 'qt_compat.rb' )
240
+ def const_missing(name)
241
+ qtclass = QtJambi.const_get("Q#{name}") rescue qtclass = QtJambi.const_get("Qt#{name}") rescue qtclass = QtJambi.const_get("#{name}")
242
+ qtclass.class_eval do if self.class==Class # no constructor for modules
243
+ class << self
244
+ def new(*args,&block)
245
+ instance=self.allocate
246
+ instance.send(:initialize,*args)
247
+ if block_given?
248
+ if block.arity == -1 || block.arity == 0
249
+ instance.instance_eval(&block)
250
+ elsif block.arity == 1
251
+ block.call(instance)
252
+ else
253
+ raise ArgumentError, "Wrong number of arguments to block(#{block.arity} for 1)"
254
+ end
255
+ end
256
+ return instance
257
+ end
258
+ end
259
+ end
260
+ #Ruby extensions for a class are stored in Qt::Internal as Procs with the same name as the class
261
+ #the signature for each extension is logged in Qt::Internal::RUBY_extensions (for documentation only)
262
+ #see examples in qt_compat.rb
263
+ if Qt::Internal.const_defined?(name)
264
+ puts "include extension #{name}" if $VERB
265
+ self.class_eval(&Qt::Internal.const_get(name))
266
+ end
267
+
268
+ end
269
+ const_set(name, qtclass)
270
+ Qt.create_constants(qtclass,"Qt::#{name}") if Qt.respond_to? :create_constants
271
+ Qt.setup_qt_signals(qtclass)
272
+ return qtclass
273
+ end
274
+
275
+ end
276
+
277
+ #qtclass # => Java::ComTrolltechQtCore::QPoint (Class)
278
+ # JRuby exposes Java classes fields as Ruby instance methods, class methods or constants.
279
+ # there is a problem with the implementation of Signals in Jambi in that there is a
280
+ # (public) Java field and (private) Java methods with the same name (e.g. clicked)
281
+ #we want to access the field, but get the method. The logic here defines a new method which acesses the field
282
+ #this is done for the Qt class being activated PLUS all Qt signal emitting classes for which this class may
283
+ #return instances (e.g. Qt::WebPage also activates Qt::WebFrame because Qt::WebPage.mainPage returns an
284
+ #instance of Qt::WebFrame which is a signalemitter)
285
+ @@activated={}
286
+ def Qt.setup_qt_signals(qtclass)
287
+ return if @@activated[qtclass.java_class.name]
288
+ org.jruby.javasupport.JavaClass.getMethods(qtclass).to_a.
289
+ map{ |jm| returnclass=jm.getReturnType}.
290
+ select{ |jc| jc.getClasses.to_a.include? QtJambi::ABSTRACTSIGNAL}.
291
+ map{ |jc| jc.getName}.
292
+ uniq.
293
+ delete_if{ |jn| @@activated[jn]}.
294
+ each { |klassname| klass=eval(klassname)
295
+ klass.class_eval do
296
+ next if @@activated[java_class.name]
297
+ java_class.fields.each do |field|
298
+ next unless field.type.superclass==QtJambi::ABSTRACTSIGNAL
299
+ puts " #{java_class.name} fieldname: #{field.name} fieldtype: #{field.type.to_s}" if $VERB
300
+ uscore_name = if (field.name =~ /\A[A-Z]+\z/)
301
+ field.name.downcase
302
+ else
303
+ field.name.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2').tr("-","_").downcase
304
+ end
305
+ self.class_eval %Q[
306
+ def #{field.name}(*args, &block)
307
+ #puts '===> #{klass.name}.#{field.name} <=> #{field.type.to_s} -1-'
308
+ return self.java_class.field(:#{field.name}).value(self)
309
+ end
310
+ #{(uscore_name==field.name) ? '' : "alias :#{uscore_name} :#{field.name}"}
311
+ ]
312
+ end
313
+ @@activated[java_class.name]=true
314
+ end
315
+
316
+ }
317
+ #@@activated[qtclass.java_class.name]=true
318
+ end
319
+
320
+
321
+ module Internal #namespace Qt::Internal
322
+
323
+
324
+ #bitwise operations on an enumerator:
325
+ #return a Flag object if a Flag creation class is defined for this object (in table QtJambi::Flag)
326
+ #otherwise return an integer value
327
+ #'other' object must be integer or respond_to value method
328
+ QtJambi::QtEnumerator.class_eval{
329
+ def |(other) ; int_op(other) { |a,b| a|b} ; end
330
+ def &(other) ; int_op(other) { |a,b| a&b} ; end
331
+ def ^(other) ; int_op(other) { |a,b| a^b} ; end
332
+ def ~ ; unary_op{ |a| ~a} ; end
333
+
334
+ def ==(other)
335
+ o=other.respond_to?(:value) ? other.value : other
336
+ self.value==o
337
+ end
338
+
339
+ def to_i
340
+ return value
341
+ end
342
+ def to_int
343
+ return value
344
+ end
345
+ #~ def coerce(other)
346
+ #~ [(other.respond_to?(:value)) ? other.value : other, value]
347
+ #~ end
348
+ private
349
+
350
+ def unary_op
351
+ r=yield(value)
352
+ return self.class.new(r) if self.class.ancestors.include? com.trolltech.qt.QFlags
353
+ begin
354
+ obj=self.class.createQFlags(self)
355
+ obj.value=r
356
+ return obj
357
+ rescue
358
+ return r
359
+ end
360
+ end
361
+
362
+ def int_op(other)
363
+ r=yield(value,other.respond_to?(:value) ? other.value : other)
364
+ return self.class.new(r) if self.class.ancestors.include? com.trolltech.qt.QFlags
365
+ return other.class.new(r) if other.class.ancestors.include? com.trolltech.qt.QFlags
366
+ begin
367
+ obj=self.class.createQFlags(self)
368
+ obj.value=r
369
+ return obj
370
+ rescue
371
+ end
372
+ begin
373
+ obj=other.class.createQFlags(self)
374
+ obj.value=r
375
+ return obj
376
+ rescue
377
+ #raise ArgumentError, "operation not defined between #{self.class} and #{other.class}"
378
+ return r
379
+ end
380
+ end
381
+ }
382
+ ########################################################
383
+ signature "Qt::Line Qt::Line.*Qt::Matrix"
384
+ signature "Qt::LineF Qt::LineF.*Qt::Matrix"
385
+ signature "boolean Qt::Line.==Qt::Line"
386
+ signature "boolean Qt::LineF.==Qt::LineF"
387
+ [QtJambi::QLine,QtJambi::QLineF].each{ |javaclass| javaclass.class_eval{
388
+ def ==(other) ; (x1==other.x1) && (y1==other.y1) &&
389
+ (x2==other.x2) && (y2==other.y2) ; end
390
+ def *(other) return other.map(self) if other.kind_of?(Qt::Matrix) ; end
391
+ def <<(a); writeString(a) ; end
392
+ def >>(a) ; a.replace(readString) ; end
393
+ }
394
+ }
395
+
396
+ signature "boolean Qt::Matrix.==Qt::Matrix"
397
+ signature "Qt::Matrix Qt::Matrix.*Qt::Matrix"
398
+ QtJambi::QMatrix.class_eval{
399
+ def ==(other) ; (m11==other.m11) && (m12==other.m12) &&
400
+ (m21==other.m21) && (m22==other.m22) &&
401
+ (dx==other.dx) && (dy==other.dy) ; end
402
+ def *(other) ; clone.multiply(other) ; end
403
+ #~ def =(other) ; self.m11=other.m11 ; self.m12=other.m12
404
+ #~ self.m21=other.m21 ; self.m22=other.m22
405
+ #~ self.dx=other.dx ; self.dy=other.dy ; end
406
+ }
407
+
408
+ signature "Qt::PainterPath Qt::PainterPath.&Qt::PainterPath"
409
+ signature "Qt::PainterPath Qt::PainterPath.|Qt::PainterPath"
410
+ signature "Qt::PainterPath Qt::PainterPath.+Qt::PainterPath"
411
+ signature "Qt::PainterPath Qt::PainterPath.-Qt::PainterPath"
412
+ signature "Qt::PainterPath Qt::PainterPath.*Qt::Matrix"
413
+ QtJambi::QPainterPath.class_eval{
414
+ def &(other) ; operator_and(other) ; end
415
+ def |(other) ; operator_or(other) ; end
416
+ def +(other) ; operator_add(other) ; end
417
+ def -(other) ; operator_subtract(other) ; end
418
+ def *(other) return other.map(self) if other.kind_of?(Qt::Matrix) ; end
419
+ def <<(a); writeString(a) ; end
420
+ def >>(a) ; a.replace(readString) ; end
421
+ }
422
+
423
+ signature "boolean Qt::Point.==Qt::Point"
424
+ signature "Qt::Point Qt::Point.+Qt::Point"
425
+ signature "Qt::Point Qt::Point.-Qt::Point"
426
+ signature "Qt::Point Qt::Point./double"
427
+ signature "Qt::Point Qt::Point.*double"
428
+ signature "Qt::Point Qt::Point.-@Qt::Point"
429
+ signature "boolean Qt::PointF.==Qt::PointF"
430
+ signature "Qt::PointF Qt::PointF.+Qt::PointF"
431
+ signature "Qt::PointF Qt::PointF.-Qt::PointF"
432
+ signature "Qt::PointF Qt::PointF./double"
433
+ signature "Qt::PointF Qt::PointF.*double"
434
+ signature "Qt::PointF Qt::PointF.-@Qt::PointF"
435
+ [QtJambi::QPoint,QtJambi::QPointF].each{ |javaclass| javaclass.class_eval{
436
+ def ==(other) ; (x==other.x) && (y==other.y) ; end
437
+ def +(other) ; clone.add(other) ; end
438
+ def -(other) ; clone.subtract(other) ; end
439
+ def -@ ; cl=clone ; cl.setX(-x) ; cl.setY(-y) ; cl ; end
440
+ def /(other) ; clone.divide(other) ; end
441
+ def *(other) ; clone.multiply(other) ; end
442
+ def <<(a); writeString(a) ; end
443
+ def >>(a) ; a.replace(readString) ; end
444
+
445
+ }
446
+ }
447
+
448
+ signature "Qt::Polygon Qt::Polygon.*Qt::Matrix"
449
+ signature "Qt::PolygonF Qt::PolygonF.*Qt::Matrix"
450
+ [QtJambi::QPolygon,QtJambi::QPolygonF].each{ |javaclass| javaclass.class_eval{
451
+ def *(other) return other.map(self) if other.kind_of?(Qt::Matrix) ; end
452
+ }
453
+
454
+ signature "Qt::Rect Qt::Rect.&Qt::Rect"
455
+ signature "Qt::Rect Qt::Rect.|Qt::Rect"
456
+ signature "boolean Qt::Rect.==Qt::Rect"
457
+ signature "Qt::RectF Qt::RectF.&Qt::RectF"
458
+ signature "Qt::RectF Qt::RectF.|Qt::RectF"
459
+ signature "boolean Qt::RectF.==Qt::RectF"
460
+ [QtJambi::QRect,QtJambi::QRectF].each{ |javaclass| javaclass.class_eval{
461
+ def &(other) ; clone.intersected(other) ; end
462
+ def |(other) ; clone.united(other) ; end
463
+ def ==(other) ; (x==other.x) && (y==other.y) && (width==other.width) && (height==other.height) ; end
464
+ def <<(a); writeString(a) ; end
465
+ def >>(a) ; a.replace(readString) ; end
466
+ }
467
+ }
468
+ }
469
+
470
+ signature "Qt::Region Qt::Region.&Qt::Region"
471
+ signature "Qt::Region Qt::Region.|Qt::Region"
472
+ signature "Qt::Region Qt::Region.+Qt::Region"
473
+ signature "Qt::Region Qt::Region.-Qt::Region"
474
+ signature "Qt::Region Qt::Region.-@Qt::Region"
475
+ signature "boolean Qt::Region.==Qt::Region"
476
+ QtJambi::QRegion.class_eval{
477
+ def ==(other) ; (x==other.x) && (y==other.y) ; end
478
+ def &(other) ; clone.intersected(other) ; end
479
+ def |(other) ; clone.united(other) ; end
480
+ def +(other) ; operator_add(other) ; end
481
+ def -(other) ; clone.subtracted(other) ; end
482
+ def -@ ; clone.setX(-x).setY(-y) ; end
483
+ #def /(other) ; clone.divide(other) ; end
484
+ #def *(other) ; clone.multiply(other) ; end
485
+ def <<(a); writeTo(a) ; end
486
+ def >>(a) ; a.replace(readString) ; end
487
+ }
488
+
489
+ signature "Qt::Size Qt::Size.*Numeric"
490
+ signature "Qt::Size Qt::Size./Numeric"
491
+ signature "Qt::Size Qt::Size.+Qt::Size"
492
+ signature "Qt::Size Qt::Size.-Qt::Size"
493
+ signature "boolean Qt::Size.==Qt::Size"
494
+ QtJambi::QSize.class_eval{
495
+ def ==(other) ; (height==other.height) && (width==other.width) ; end
496
+ def +(other) ; add(other) ; end
497
+ def -(other) ; subtract(other) ; end
498
+ def /(other) ; divide(other) ; end
499
+ def *(other) ; multiply(other) ; end
500
+ }
501
+
502
+ # addAction(Icon,String text)
503
+ #addAction(Icon,String text,java.lang.Object receiver, java.lang.String method) <= 4 n=2
504
+ # addAction(Icon, String text, java.lang.Object receiver, java.lang.String method, Qt::KeySequence shortcut) <= 5 n=2
505
+ # addAction(Icon, String text, QSignalEmitter.AbstractSignal signal) <= 3
506
+ # addAction(Icon, String text, QSignalEmitter.AbstractSignal signal, Qt::KeySequence shortcut) <= 4
507
+ # addAction(String text)
508
+ # addAction(String text, java.lang.Object Receiver, java.lang.String method) <= 3 n=1
509
+ # addAction(String text, java.lang.Object Receiver, java.lang.String method, Qt::KeySequence shortcut) <= 4 n=1
510
+ # addAction(String text, QSignalEmitter.AbstractSignal signal)
511
+ # addAction(String text, QSignalEmitter.AbstractSignal signal, Qt::KeySequence shortcut)<= 3 n=
512
+ # map (receiver,method) combinations
513
+ signature "Qt::Action Qt::Menu.addAction(Qt::Icon, String, Object, Symbol rubymethod)"
514
+ signature "Qt::Action Qt::Menu.addAction(Qt::Icon, String, Object, Symbol rubymethod,Qt::KeySequence)"
515
+ signature "Qt::Action Qt::Menu.addAction(String, Object, Symbol rubymethod)"
516
+ signature "Qt::Action Qt::Menu.addAction(String, Object, Symbol rubymethod,Qt::KeySequence)"
517
+ QtJambi::QMenu.class_eval {
518
+ alias :orig_addAction :addAction
519
+ def addAction(*a)
520
+ args=a.dup
521
+ n=0
522
+ if args.size > 2
523
+ if args[0].kind_of?(String)
524
+ n=1 if args[2].kind_of?(String)
525
+ else
526
+ n=2 if (args.size > 3) && (args[3].kind_of?(String))
527
+ end
528
+ end
529
+ if n>0
530
+ @rubysignalactions ||= []
531
+ @rubysignalactions << Qt::RubySignalAction.new(args[n],args[n+1])
532
+ args[n]=@rubysignalactions[-1]
533
+ args[n+1]='signal0()'
534
+ #args[0]=args[0].value if args[0].respond_to?(:value)
535
+ end
536
+ orig_addAction(*args)
537
+ end
538
+ }
539
+
540
+ # addAction(Icon, text)
541
+ # addAction(Icon, text, receiver, method) <= n=2
542
+ # addAction(Icon, text, signal) <= n=0
543
+ # addAction(text)
544
+ # addAction(text, receiver, method) <= n=1
545
+ # addAction(text, signal)
546
+ # map (receiver,method) combinations
547
+ signature "Qt::Action Qt::ToolBar.addAction(Qt::Icon, String, Object rubyreceiver, Symbol rubymethod)"
548
+ signature "Qt::Action Qt::ToolBar.addAction(String, Object rubyreceiver, Symbol rubymethod)"
549
+ QtJambi::QToolBar.class_eval {
550
+ alias :orig_addAction :addAction
551
+ def addAction(*a)
552
+ args=a.dup
553
+ n=0
554
+ if args.size > 2
555
+ if args[0].kind_of?(String)
556
+ n=1
557
+ else
558
+ n=2 if args.size==4
559
+ end
560
+ end
561
+ if n>0
562
+ @rubysignalactions ||= []
563
+ @rubysignalactions << Qt::RubySignalAction.new(args[n],args[n+1])
564
+ args[n]=@rubysignalactions[-1]
565
+ args[n+1]='signal0()'
566
+ end
567
+ orig_addAction(*args)
568
+ end
569
+ }
570
+
571
+ # addAction(text)
572
+ # addAction(text, receiver, method) <=
573
+ # addAction(text, signal)
574
+ # map (receiver,method) combinations
575
+ signature "Qt::Action Qt::MenuBar.addAction(String, Object rubyreceiver, Symbol rubymethod)"
576
+ QtJambi::QMenuBar.class_eval {
577
+ alias :orig_addAction :addAction
578
+ def addAction(*a)
579
+ args=a.dup
580
+ if args.size > 2
581
+ @rubysignalactions ||= []
582
+ @rubysignalactions << Qt::RubySignalAction.new(args[1],args[2])
583
+ args[1]=@rubysignalactions[-1]
584
+ args[2]='signal0()'
585
+ end
586
+ orig_addAction(*args)
587
+ end
588
+ }
589
+
590
+ # singleShot(timeout,receiver,method)
591
+ # map (receiver,method) combinations
592
+ #N.B singleShot is a Qt::Timer class method
593
+ #so there is only one instance of class Class
594
+ signature "static void Qt::Timer.singleShot(Fixnum msecs, Object rubyreceiver, Symbol rubymethod)"
595
+ QtJambi::QTimer.class_eval {
596
+ class << self
597
+ alias :orig_singleShot :singleShot
598
+ def singleShot(timeout,receiver,method)
599
+ method =(md=method.match(/([^(]+)\([.]*/)) ? md[1].to_sym : method.to_sym unless method.kind_of? Symbol
600
+ @pendingactions ||= []
601
+ action=Qt::RubySignalAction.new(self,:_singleShot)
602
+ action.append_args(action,receiver,method)
603
+ @pendingactions << action
604
+ orig_singleShot(timeout,action,'signal0()')
605
+ end
606
+
607
+ def _singleShot(action,receiver,method)
608
+ receiver.send(method)
609
+ @pendingactions.delete(action)
610
+ end
611
+
612
+ end
613
+ }
614
+
615
+ #Some classes do not like to be initialized with nil
616
+ #compatibility with legacy software
617
+ [QtJambi::QWidget,QtJambi::QLayout].each{ |klass| klass.class_eval{
618
+ alias :orig_initialize :initialize
619
+ def initialize(*args)
620
+ if ((args.size==0) || ((args.size==1) && args[0].nil?))
621
+ orig_initialize()
622
+ else
623
+ orig_initialize(*args)
624
+ end
625
+ end
626
+ }
627
+ }
628
+ signature "static Qt::Application Qt::Application.new(Array)"
629
+ signature "static java.lang.String Qt::Application.translate(java.lang.String,java.lang.String,java.lang.String,Qt::Enumerator)"
630
+ signature "static java.lang.String Qt::Application.translate(java.lang.String,java.lang.String)"
631
+ Application=Proc.new do
632
+ class << self
633
+ #QAppplication has only a single instance, which needs to be initialized
634
+ #in an uninitialized object unexpected things don't work
635
+ #e.g. it can't process plug-ins like jpeg
636
+ #java_send used to avoid confusion with Ruby initialize constructor
637
+ def new(args)
638
+ java_send(:initialize,[java.lang.String[]],args.to_java(:string))
639
+ $qApp=self
640
+ return self
641
+ end
642
+
643
+ alias :orig_translate :translate
644
+ def translate(context,sourcetext,comment=nil,encoding=nil)
645
+ if encoding
646
+ int=(encoding.respond_to? :value) ? encoding.value : encoding
647
+ orig_translate(context,sourcetext,comment,int)
648
+ else
649
+ orig_translate(context,sourcetext)
650
+ end
651
+ end
652
+
653
+ end
654
+ end
655
+ end #Module Internal
656
+ end #Module Qt
657
+