summaryrefslogtreecommitdiffstats
path: root/korundum/README
blob: cb283bd827de167ed94ec022ad74a27a93efc126 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
Please see kdebindings/qtruby/README

KDE Specific Infomation:

	- Instead of require 'Qt', use require 'Korundum' for KDE programs. 
	
	- The KDE K* classes such as KApplication are renamed as KDE::Application. 
	  The other KDE classes are in the KParts::, KIO:: or DOM:: namespaces,
	  with the same names as their C++ counterparts. 
	
	- Use the 'rbkdeapi' script to introspect the Korundum api from the command
	  line. For example:
	  
	  	$ rbkdeapi KDE::Action
	  
	  Will list all the methods in the KDE::Action class. There are currently
	  (as at KDE 3.3 beta 2) 977 classes/30841 methods in the Smoke library 
	  runtime, so the coverage of the Qt/KDE api is pretty complete.

	- DCOP Support. Here is a minimal ruby dcop slot implementation:
	
			require 'Korundum'
			
			class MyWidget < KDE::PushButton
				k_dcop 'QPoint mySlot(int,QString)'
	
				def initialize(parent, name)
					super
				end
			
				def mySlot(counter,greeting)
					return Qt::Point.new(50, 100)
				end
			end

		This slot is passed an integer and a string, and returns a Qt::Point.
		
		Note that the class doesn't have to inherit from DCOPObject. If you
		include a 'k_dcop' slots declaration a 'listener' dcop object 
		instance is created automatically, and these four methods are added
		to your class:
		  
		  	interfaces()
			functions()
			connectDCOPSignal()
			disconnectDCOPSignal()
			
		The name of the object is always the ruby classname, and you can only
		instantiate one instance for each ruby class that has 'k_dcop' 
		declarations. See examples/dcop/dcopslot.rb and dcopsignal.rb for an 
		example of the simplest approach.
			
		If you wish to use the full functionality of a DCOPObject, you can
		subclass it and call all the methods, not just the four above. 
		Additionally, you can instantiate more than one instance per class and 
		rename the dcop object with the setObjId() method or by passing the name 
		to the constructor. See the examples/dcop/petshop.rb code for an 
		example of a more complex dcop object.
	
	- Define a dcop slot like this in one ruby program:

	    k_dcop 'QPoint getPoint(QString)'

	    def getPoint(msg)
		    puts "message: #{msg}"
		    return Qt::Point.new(50, 100)
	    end

	- Call it from another program and print the reply, like this:

	    dcopRef = KDE::DCOPRef.new("dcopslot", "MyWidget")
		
		There are three different ways to specify a DCOP call:
	    1) res = dcopRef.call("getPoint(QString)", "Hello from dcopsend")
	    2) res = dcopRef.call("getPoint", "Hello from dcopsend")
		3) res = dcopRef.getPoint("Hello from dcopsend")
		
	    puts "result class: #{res.class.name} x: #{res.x} y: #{res.y}"
		
		If the dcop slot has a 'void' or 'ASYNC' type, the result will be true
		if the call succeeds or nil if it fails
		
	- DCOP Attributes
	
		You can set a dcop attribute like this, instead of calling 
		'klipper.setClipboardContents("Hello there klipper")':
		
		klipper = DCOPRef.new("klipper", "klipper")
		klipper.clipboardContents = "Hello there klipper"
		
		Amaze your friends! Do the programming equivalent of leaping
		over tall buildings in one bound! Here with one line of quite
		clear code, we read a file from disc and assign it the 
		'clipboardContents' klipper attribute via dcop:
		
		klipper.clipboardContents = IO.readlines("myfile").to_s
		
	- DCOP Predicates
		
		Instead of:
		
		result = dcopRef.isFoo()
		
		You can use this more rubyish form:
		
		if dcopRef.foo?
			puts "foo is true"
		else
			puts "foo? is false"
		end

		Similarly you can use foo? as an alias for methods of the form 
		hasFoo(). 
		See examples/dcop/dcoppredicate.rb and dcopslot.rb
		
	- Underscore to camel case DCOP method name conversion
	
		Any underscores in a method name are removed, and the following
		character is capitalised. For example:
		
		res = dcopRef.get_point("Hello from dcopsend")
		
		Is a synonym for:
		
		res = dcopRef.getPoint("Hello from dcopsend")
			
	- Send to a DCOPRef:
	    
		There are two different ways to specify a DCOP send:
		1) res = dcopRef.send("mySlot(QString)", "Hello from dcopsend")
	    2) res = dcopRef.send("mySlot", "Hello from dcopsend")
		
		The result will either be true or false (but not nil for fail like the
		DCOPRef.call() method described above).
	
	- When a call of the form 'dcopRef.getPoint(5, "foobar")' is made, the C++
	  type signature is obtained from the list of those returned by 
	  DCOPRef.functions(). However, if a method name is overloaded the ruby 
	  argument types are used to derive a type signature, in order to resolve 
	  the call like this:
	  
			String => QString
			Float => double
			Integer => int
			TrueClass|FalseClass (ie 'true' or 'false') => bool
			Qt::Widget etc => QWidget
			KDE::URL etc => KURL
			Array => QStringList
			
	  Specify the full C++ type signature using the form
	  'dcopRef.call("getPoint(int,QString)", 5, "foobar")' if these rules fail 
	  to pick the right method.
	  
	- DCOP Signals are defined like this:
	
	    k_dcop_signals 'void testEmitSignal(QString)'
		
	    def doit()
	        emit testEmitSignal("Hello DCOP Slot")
	    end
	  	  
	- Connect slot 'mySlot' to a DCOP signal like this:
	
	    res = slottest.connectDCOPSignal("dcopsignal", "SenderWidget", 
		                                 "testEmitSignal(QString)", "mySlot(QString)", 
										 true)

	- Use the '-kde' option with the rbuic tool to require the 'Korundum' 
		extension rather than the 'Qt' one. If the '-x' option is used in 
		conjunction, it generates a KDE top level. For example:
		
		$ rbuic -x -kde knotifywidgetbase.ui -o knotifywidgetbase.rb

		Will generate this top level code:

			if $0 == __FILE__
    			about = KDE::AboutData.new("knotifywidgetbase", "KNotifyWidgetBase", "0.1")
    			KDE::CmdLineArgs.init(ARGV, about)
    			a = KDE::Application.new()
    			w = KNotifyWidgetBase.new
    			a.setMainWidget(w)
    			w.show
    			a.exec
			end