qt_connect 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+