Add 'open' action.
[kaya.git] / lib / qtutils.rb
blobb8ea28ac366471689e0678f3e7689350bf4cfbdc
1 require 'korundum4'
3 ParseException = Class.new(Exception)
5 class Object
6   def tap
7     yield self
8     self
9   end
10   
11   def metaclass
12     class << self
13       self
14     end
15   end
16   
17   def metaclass_eval(&blk)
18     metaclass.instance_eval(&blk)
19   end
20 end
22 module Enumerable
23   def detect_index
24     i = 0
25     each do |item|
26       return i if yield item
27       i += 1
28     end
29     
30     nil
31   end
32 end
34 class Qt::Painter
35   def paint
36     yield self
37   ensure
38     self.end
39   end
40   
41   def saving
42     save
43     yield self
44   ensure
45     restore
46   end
47 end
49 class Qt::Image
50   def to_pix
51     Qt::Pixmap.from_image self
52   end
53   
54   def self.painted(size, &blk)
55     Qt::Image.new(size.x, size.y, Qt::Image::Format_ARGB32_Premultiplied).tap do |img|
56       img.fill(0)
57       Qt::Painter.new(img).paint(&blk)
58     end
59   end
61   def self.from_renderer(size, renderer, id = nil)
62     img = Qt::Image.painted(size) do |p| 
63       if id
64         renderer.render(p, id)
65       else
66         renderer.render(p)
67       end
68     end
69     img
70   end
71 end
73 module PrintablePoint
74   def ==(other)
75     self.x == other.x and self.y == other.y
76   end
77   
78   def to_s
79     "(#{self.x}, #{self.y})"
80   end
81 end
83 module PrintableRect
84   def to_s
85     "[#{self.x}, #{self.y} - #{self.width}, #{self.height}]"
86   end
87 end
89 class Qt::Point
90   include PrintablePoint
91   
92   def to_f
93     Qt::PointF.new(x, y)
94   end
95 end
97 class Qt::PointF
98   include PrintablePoint
99   
100   def to_i
101     Qt::Point.new(x.to_i, y.to_i)
102   end
105 class Qt::Size
106   include PrintablePoint
107   
108   def x
109     width
110   end
111   
112   def y
113     height
114   end
117 class Qt::SizeF
118   include PrintablePoint
119   
120   def x
121     width
122   end
123   
124   def y
125     height
126   end
129 class Qt::Rect
130   include PrintableRect
133 class Qt::RectF
134   include PrintableRect
137 class Qt::Pixmap
138   def self.from_svg(size, file, id = nil)
139     from_renderer(size, Qt::SvgRenderer.new(file), id)
140   end
141   
142   def self.from_renderer(size, renderer, id = nil)
143     Qt::Image.from_renderer(size, renderer, id).to_pix
144   end
147 class Qt::Base
148   def self.signal_map(sigmap)
149     @signal_map = sigmap
150     signals *sigmap.map{|k, v| v || k }
151   end
153   def self.get_signal(sig)
154     (@signal_map || {})[sig] || sig
155   end
157   def on(sig, &blk)
158     connect(SIGNAL(self.class.get_signal(sig)), &blk)
159   end  
161   def in(interval, &blk)
162     Qt::Timer.in(interval, self, &blk)
163   end
165   def run_later(&blk)
166     self.in(0, &blk)
167   end
170 class Qt::Timer
171   def self.every(interval, &blk)
172     time = Qt::Time.new
173     time.restart
174     
175     timer = new
176     timer.connect(SIGNAL('timeout()')) { blk[time.elapsed] }
177     timer.start(interval)
178     # return the timer, so that the caller
179     # has a chance to keep it referenced, so
180     # that it is not garbage collected
181     timer
182   end
184   def self.in(interval, target = nil, &blk)
185     single_shot(interval,
186                 Qt::BlockInvocation.new(target, blk, 'invoke()'),
187                 SLOT('invoke()'))
188   end
191 module ModelUtils
192   def removing_rows(parent, first, last)
193     if first > last
194       yield
195     else
196       begin
197         begin_remove_rows(parent || Qt::ModelIndex.new, first, last)
198         yield
199       ensure
200         end_remove_rows
201       end
202     end
203   end
204   
205   def inserting_rows(parent, first, last)
206     if first > last
207       yield
208     else
209       begin
210         begin_insert_rows(parent || Qt::ModelIndex.new, first, last)
211         yield
212       ensure
213         end_insert_rows
214       end
215     end
216   end
219 class KDE::Application
220   def self.init(data)
221     about = KDE::AboutData.new(
222       data[:id],
223       data[:id],
224       data[:name],
225       data[:version],
226       data[:description],
227       KDE::AboutData::License_GPL,
228       data[:copyright])
229     data[:authors].each do |name, email|
230       about.addAuthor(name, KDE::LocalizedString.new, email)
231     end
232     data[:contributors].each do |name, contribution|
233       about.addCredit(name, contribution)
234     end
235     about.bug_address = Qt::ByteArray.new(data[:bug_tracker])
236     
237     KDE::CmdLineArgs.init(ARGV, about)
238     KDE::CmdLineOptions.new.tap do |opts|
239       data[:options].each do |opt, desc|
240         opts.add(opt, desc)
241       end
242       KDE::CmdLineArgs.add_cmd_line_options opts
243     end
245     KDE::Application.new
246   end
249 module ActionHandler
250   def std_action(action, opts = {}, &blk)
251     target, slot = get_slot(opts[:slot], &blk)
252     KDE::StandardAction.method_missing(action, target, slot, action_collection)
253   end
254   
255   def get_slot(s = nil, &blk)
256     target, slot = if block_given?
257       [Qt::BlockInvocation.new(self, blk, 'invoke()'), SLOT(:invoke)]
258     else
259       [self, SLOT(s)]
260     end
261   end
262   
263   def regular_action(name, opts, &blk)
264     icon = if opts[:icon]
265       case opts[:icon]
266       when Qt::Icon
267         opts[:icon]
268       else
269         KDE::Icon.new(opts[:icon].to_s)
270       end
271     end
272     
273     KDE::Action.new(icon, opts[:text], self).tap do |a|
274       action_collection.add_action(name.to_s, a)
275       target, slot = get_slot(opts[:slot], &blk)
276       connect(a, SIGNAL('triggered(bool)'), target, slot)
277     end
278   end