rUtilAnts 0.1.0.20091014
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.
- data/AUTHORS +3 -0
- data/ChangeLog +74 -0
- data/Credits +14 -0
- data/LICENSE +31 -0
- data/README +18 -0
- data/TODO +10 -0
- data/lib/rUtilAnts/GUI/Bug.png +0 -0
- data/lib/rUtilAnts/GUI/BugReportDialog.rb +104 -0
- data/lib/rUtilAnts/GUI.rb +577 -0
- data/lib/rUtilAnts/Logging.rb +445 -0
- data/lib/rUtilAnts/Misc.rb +132 -0
- data/lib/rUtilAnts/Platform.rb +30 -0
- data/lib/rUtilAnts/Platforms/i386-linux/PlatformInfo.rb +149 -0
- data/lib/rUtilAnts/Platforms/i386-mswin32/PlatformInfo.rb +141 -0
- data/lib/rUtilAnts/Plugins.rb +480 -0
- data/lib/rUtilAnts/URLAccess.rb +228 -0
- data/lib/rUtilAnts/URLCache.rb +145 -0
- data/lib/rUtilAnts/URLHandlers/DataImage.rb +104 -0
- data/lib/rUtilAnts/URLHandlers/FTP.rb +120 -0
- data/lib/rUtilAnts/URLHandlers/HTTP.rb +126 -0
- data/lib/rUtilAnts/URLHandlers/LocalFile.rb +100 -0
- metadata +80 -0
@@ -0,0 +1,577 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2009 Muriel Salvan (murielsalvan@users.sourceforge.net)
|
3
|
+
# Licensed under the terms specified in LICENSE file. No warranty is provided.
|
4
|
+
#++
|
5
|
+
|
6
|
+
# WxRuby has to be loaded correctly in the environment before requiring this file
|
7
|
+
|
8
|
+
module RUtilAnts
|
9
|
+
|
10
|
+
module GUI
|
11
|
+
|
12
|
+
# The class that assigns dynamically images to a given TreeCtrl items
|
13
|
+
class ImageListManager
|
14
|
+
|
15
|
+
# Constructor
|
16
|
+
#
|
17
|
+
# Parameters:
|
18
|
+
# * *ioImageList* (<em>Wx::ImageList</em>): The image list this manager will handle
|
19
|
+
# * *iWidth* (_Integer_): The images width
|
20
|
+
# * *iHeight* (_Integer_): The images height
|
21
|
+
def initialize(ioImageList, iWidth, iHeight)
|
22
|
+
@ImageList = ioImageList
|
23
|
+
# TODO (WxRuby): Get the size directly from ioImageList (get_size does not work)
|
24
|
+
@Width = iWidth
|
25
|
+
@Height = iHeight
|
26
|
+
# The internal map of image IDs => indexes
|
27
|
+
# map< Object, Integer >
|
28
|
+
@Id2Idx = {}
|
29
|
+
end
|
30
|
+
|
31
|
+
# Get the image index for a given image ID
|
32
|
+
#
|
33
|
+
# Parameters:
|
34
|
+
# * *iID* (_Object_): Id of the image
|
35
|
+
# * *CodeBlock*: The code that will be called if the image ID is unknown. This code has to return a Wx::Bitmap object, representing the bitmap for the given image ID.
|
36
|
+
def getImageIndex(iID)
|
37
|
+
if (@Id2Idx[iID] == nil)
|
38
|
+
# Bitmap unknown.
|
39
|
+
# First create it.
|
40
|
+
lBitmap = yield
|
41
|
+
# Then check if we need to resize it
|
42
|
+
lBitmap = getResizedBitmap(lBitmap, @Width, @Height)
|
43
|
+
# Then add it to the image list, and register it
|
44
|
+
@Id2Idx[iID] = @ImageList.add(lBitmap)
|
45
|
+
end
|
46
|
+
|
47
|
+
return @Id2Idx[iID]
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
# Generic progress dialog, meant to be overriden to customize behaviour
|
53
|
+
class ProgressDialog < Wx::Dialog
|
54
|
+
|
55
|
+
# Value for the undetermined range
|
56
|
+
DEFAULT_UNDETERMINED_RANGE = 10
|
57
|
+
|
58
|
+
# Is the current dialog in determined mode ?
|
59
|
+
# Boolean
|
60
|
+
attr_reader :Determined
|
61
|
+
|
62
|
+
# Has the current dialog been cancelled ?
|
63
|
+
# Boolean
|
64
|
+
attr_reader :Cancelled
|
65
|
+
|
66
|
+
# Constructor
|
67
|
+
#
|
68
|
+
# Parameters:
|
69
|
+
# * *iParentWindow* (<em>Wx::Window</em>): Parent window
|
70
|
+
# * *iCodeToExecute* (_Proc_): The code to execute that will update the progression
|
71
|
+
# * *iParameters* (<em>map<Symbol,Object></em>): Additional parameters:
|
72
|
+
# ** *:Cancellable* (_Boolean_): Can we cancel this dialog ? [optional = false]
|
73
|
+
# ** *:Title* (_String_): Caption of the progress dialog [optional = '']
|
74
|
+
# ** *:Icon* (<em>Wx::Bitmap</em>): Icon of the progress dialog [optional = nil]
|
75
|
+
def initialize(iParentWindow, iCodeToExecute, iParameters = {})
|
76
|
+
lCancellable = iParameters[:Cancellable]
|
77
|
+
if (lCancellable == nil)
|
78
|
+
lCancellable = false
|
79
|
+
end
|
80
|
+
lTitle = iParameters[:Title]
|
81
|
+
if (lTitle == nil)
|
82
|
+
lTitle = ''
|
83
|
+
end
|
84
|
+
lIcon = iParameters[:Icon]
|
85
|
+
super(iParentWindow,
|
86
|
+
:title => lTitle,
|
87
|
+
:style => Wx::THICK_FRAME|Wx::CAPTION
|
88
|
+
)
|
89
|
+
if (lIcon != nil)
|
90
|
+
lRealIcon = Wx::Icon.new
|
91
|
+
lRealIcon.copy_from_bitmap(lIcon)
|
92
|
+
set_icon(lRealIcon)
|
93
|
+
end
|
94
|
+
|
95
|
+
@CodeToExecute = iCodeToExecute
|
96
|
+
|
97
|
+
# Has the transaction been cancelled ?
|
98
|
+
@Cancelled = false
|
99
|
+
|
100
|
+
# Create components
|
101
|
+
@GProgress = Wx::Gauge.new(self, Wx::ID_ANY, 0)
|
102
|
+
@GProgress.set_size_hints(-1,12,-1,12)
|
103
|
+
lBCancel = nil
|
104
|
+
if (lCancellable)
|
105
|
+
lBCancel = Wx::Button.new(self, Wx::CANCEL, 'Cancel')
|
106
|
+
end
|
107
|
+
lPTitle = getTitlePanel
|
108
|
+
|
109
|
+
# Put them into sizers
|
110
|
+
lMainSizer = Wx::BoxSizer.new(Wx::VERTICAL)
|
111
|
+
lMainSizer.add_item(lPTitle, :flag => Wx::GROW|Wx::ALL, :proportion => 1, :border => 8)
|
112
|
+
if (lCancellable)
|
113
|
+
lBottomSizer = Wx::BoxSizer.new(Wx::HORIZONTAL)
|
114
|
+
lBottomSizer.add_item(@GProgress, :flag => Wx::ALIGN_CENTER|Wx::ALL, :proportion => 1, :border => 4)
|
115
|
+
lBottomSizer.add_item(lBCancel, :flag => Wx::ALIGN_CENTER, :proportion => 0)
|
116
|
+
lMainSizer.add_item(lBottomSizer, :flag => Wx::GROW|Wx::ALL, :proportion => 0, :border => 8)
|
117
|
+
else
|
118
|
+
lMainSizer.add_item(@GProgress, :flag => Wx::GROW|Wx::ALL, :proportion => 0, :border => 4)
|
119
|
+
end
|
120
|
+
self.sizer = lMainSizer
|
121
|
+
|
122
|
+
# Set events
|
123
|
+
if (lCancellable)
|
124
|
+
evt_button(lBCancel) do |iEvent|
|
125
|
+
@Cancelled = true
|
126
|
+
lBCancel.enable(false)
|
127
|
+
lBCancel.label = 'Cancelling ...'
|
128
|
+
self.fit
|
129
|
+
end
|
130
|
+
end
|
131
|
+
lExecCompleted = false
|
132
|
+
evt_idle do |iEvent|
|
133
|
+
# Execute the code once
|
134
|
+
if (!lExecCompleted)
|
135
|
+
lExecCompleted = true
|
136
|
+
@CodeToExecute.call(self)
|
137
|
+
end
|
138
|
+
self.end_modal(Wx::ID_OK)
|
139
|
+
end
|
140
|
+
|
141
|
+
# By default, consider that we don't know the range of progression
|
142
|
+
# That's why we set a default range (undetermined progression needs a range > 0 to have visual effects)
|
143
|
+
@GProgress.range = DEFAULT_UNDETERMINED_RANGE
|
144
|
+
@Determined = false
|
145
|
+
|
146
|
+
self.fit
|
147
|
+
|
148
|
+
refreshState
|
149
|
+
end
|
150
|
+
|
151
|
+
# Called to refresh our dialog
|
152
|
+
def refreshState
|
153
|
+
self.refresh
|
154
|
+
self.update
|
155
|
+
# Process eventual user request to stop transaction
|
156
|
+
Wx.get_app.yield
|
157
|
+
end
|
158
|
+
|
159
|
+
# Set the progress range
|
160
|
+
#
|
161
|
+
# Parameters:
|
162
|
+
# * *iRange* (_Integer_): The progress range
|
163
|
+
def setRange(iRange)
|
164
|
+
@GProgress.range = iRange
|
165
|
+
if (!@Determined)
|
166
|
+
@Determined = true
|
167
|
+
@GProgress.value = 0
|
168
|
+
end
|
169
|
+
refreshState
|
170
|
+
end
|
171
|
+
|
172
|
+
# Set the progress value
|
173
|
+
#
|
174
|
+
# Parameters:
|
175
|
+
# * *iValue* (_Integer_): The progress value
|
176
|
+
def setValue(iValue)
|
177
|
+
@GProgress.value = iValue
|
178
|
+
refreshState
|
179
|
+
end
|
180
|
+
|
181
|
+
# Increment the progress value
|
182
|
+
#
|
183
|
+
# Parameters:
|
184
|
+
# * *iIncrement* (_Integer_): Value to increment [optional = 1]
|
185
|
+
def incValue(iIncrement = 1)
|
186
|
+
@GProgress.value += iIncrement
|
187
|
+
refreshState
|
188
|
+
end
|
189
|
+
|
190
|
+
# Increment the progress range
|
191
|
+
#
|
192
|
+
# Parameters:
|
193
|
+
# * *iIncrement* (_Integer_): Value to increment [optional = 1]
|
194
|
+
def incRange(iIncrement = 1)
|
195
|
+
if (@Determined)
|
196
|
+
@GProgress.range += iIncrement
|
197
|
+
else
|
198
|
+
@Determined = true
|
199
|
+
@GProgress.range = iIncrement
|
200
|
+
@GProgress.value = 0
|
201
|
+
end
|
202
|
+
refreshState
|
203
|
+
end
|
204
|
+
|
205
|
+
# Pulse the progression (to be used when we don't know the range)
|
206
|
+
def pulse
|
207
|
+
if (@Determined)
|
208
|
+
@Determined = false
|
209
|
+
@GProgress.range = DEFAULT_UNDETERMINED_RANGE
|
210
|
+
end
|
211
|
+
@GProgress.pulse
|
212
|
+
refreshState
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
|
217
|
+
# Text progress dialog
|
218
|
+
class TextProgressDialog < ProgressDialog
|
219
|
+
|
220
|
+
# Constructor
|
221
|
+
#
|
222
|
+
# Parameters:
|
223
|
+
# * *iParentWindow* (<em>Wx::Window</em>): Parent window
|
224
|
+
# * *iCodeToExecute* (_Proc_): The code to execute that will update the progression
|
225
|
+
# * *iText* (_String_): The text to display
|
226
|
+
# * *iParameters* (<em>map<Symbol,Object></em>): Additional parameters (check RUtilAnts::GUI::ProgressDialog#initialize documentation):
|
227
|
+
def initialize(iParentWindow, iCodeToExecute, iText, iParameters = {})
|
228
|
+
@Text = iText
|
229
|
+
super(iParentWindow, iCodeToExecute, iParameters)
|
230
|
+
end
|
231
|
+
|
232
|
+
# Get the panel to display as title
|
233
|
+
#
|
234
|
+
# Return:
|
235
|
+
# * <em>Wx::Panel</em>: The panel to use as a title
|
236
|
+
def getTitlePanel
|
237
|
+
rPanel = Wx::Panel.new(self)
|
238
|
+
|
239
|
+
# Create components
|
240
|
+
@STText = Wx::StaticText.new(rPanel, Wx::ID_ANY, @Text, :style => Wx::ALIGN_CENTRE)
|
241
|
+
|
242
|
+
# Put them into sizers
|
243
|
+
lMainSizer = Wx::BoxSizer.new(Wx::VERTICAL)
|
244
|
+
lMainSizer.add_item(@STText, :flag => Wx::GROW, :proportion => 1)
|
245
|
+
rPanel.sizer = lMainSizer
|
246
|
+
|
247
|
+
return rPanel
|
248
|
+
end
|
249
|
+
|
250
|
+
# Set the text
|
251
|
+
#
|
252
|
+
# Parameters:
|
253
|
+
# * *iText* (_String_): The text
|
254
|
+
def setText(iText)
|
255
|
+
@STText.label = iText
|
256
|
+
self.fit
|
257
|
+
refreshState
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
|
262
|
+
# Bitmap progress dialog
|
263
|
+
class BitmapProgressDialog < ProgressDialog
|
264
|
+
|
265
|
+
# Constructor
|
266
|
+
#
|
267
|
+
# Parameters:
|
268
|
+
# * *iParentWindow* (<em>Wx::Window</em>): Parent window
|
269
|
+
# * *iCodeToExecute* (_Proc_): The code to execute that will update the progression
|
270
|
+
# * *iBitmap* (<em>Wx::Bitmap</em>): The bitmap to display (can be nil)
|
271
|
+
# * *iParameters* (<em>map<Symbol,Object></em>): Additional parameters (check RUtilAnts::GUI::ProgressDialog#initialize documentation):
|
272
|
+
def initialize(iParentWindow, iCodeToExecute, iBitmap, iParameters = {})
|
273
|
+
@Bitmap = iBitmap
|
274
|
+
super(iParentWindow, iCodeToExecute, iParameters)
|
275
|
+
end
|
276
|
+
|
277
|
+
# Get the panel to display as title
|
278
|
+
#
|
279
|
+
# Return:
|
280
|
+
# * <em>Wx::Panel</em>: The panel to use as a title
|
281
|
+
def getTitlePanel
|
282
|
+
rPanel = Wx::Panel.new(self)
|
283
|
+
|
284
|
+
# Create components
|
285
|
+
if (@Bitmap == nil)
|
286
|
+
@SBBitmap = Wx::StaticBitmap.new(rPanel, Wx::ID_ANY, Wx::Bitmap.new)
|
287
|
+
else
|
288
|
+
@SBBitmap = Wx::StaticBitmap.new(rPanel, Wx::ID_ANY, @Bitmap)
|
289
|
+
end
|
290
|
+
|
291
|
+
# Put them into sizers
|
292
|
+
lMainSizer = Wx::BoxSizer.new(Wx::VERTICAL)
|
293
|
+
lMainSizer.add_item(@SBBitmap, :flag => Wx::GROW, :proportion => 1)
|
294
|
+
rPanel.sizer = lMainSizer
|
295
|
+
|
296
|
+
return rPanel
|
297
|
+
end
|
298
|
+
|
299
|
+
# Set the bitmap
|
300
|
+
#
|
301
|
+
# Parameters:
|
302
|
+
# * *iBitmap* (<em>Wx::Bitmap</em>): The bitmap
|
303
|
+
def setBitmap(iBitmap)
|
304
|
+
@SBBitmap.bitmap = iBitmap
|
305
|
+
self.fit
|
306
|
+
refreshState
|
307
|
+
end
|
308
|
+
|
309
|
+
end
|
310
|
+
|
311
|
+
# Manager that handles normal Wx::Timer, integrating a mechanism that can kill it and wait until it has been safely killed.
|
312
|
+
# Very handy for timers processing data that might be destroyed.
|
313
|
+
# To be used with safeTimerAfter and safeTimerEvery.
|
314
|
+
class SafeTimersManager
|
315
|
+
|
316
|
+
# Constructor
|
317
|
+
def initialize
|
318
|
+
# List of registered timers
|
319
|
+
# list< Wx::Timer >
|
320
|
+
@Timers = []
|
321
|
+
end
|
322
|
+
|
323
|
+
# Register a given timer
|
324
|
+
#
|
325
|
+
# Parameters:
|
326
|
+
# * *iTimer* (<em>Wx::Timer</em>): The timer to register
|
327
|
+
def registerTimer(iTimer)
|
328
|
+
@Timers << iTimer
|
329
|
+
end
|
330
|
+
|
331
|
+
# Unregister a given timer
|
332
|
+
#
|
333
|
+
# Parameters:
|
334
|
+
# * *iTimer* (<em>Wx::Timer</em>): The timer to unregister
|
335
|
+
# Return:
|
336
|
+
# * _Boolean_: Was the Timer registered ?
|
337
|
+
def unregisterTimer(iTimer)
|
338
|
+
rFound = false
|
339
|
+
|
340
|
+
@Timers.delete_if do |iRegisteredTimer|
|
341
|
+
if (iRegisteredTimer == iTimer)
|
342
|
+
rFound = true
|
343
|
+
next true
|
344
|
+
else
|
345
|
+
next false
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
return rFound
|
350
|
+
end
|
351
|
+
|
352
|
+
# Kill all registered Timers and wait for their completion.
|
353
|
+
# Does not return unless they are stopped.
|
354
|
+
def killTimers
|
355
|
+
# Notify each Timer that it has to stop
|
356
|
+
@Timers.each do |ioTimer|
|
357
|
+
ioTimer.stop
|
358
|
+
end
|
359
|
+
# Wait for each one to be stopped
|
360
|
+
lTimersToStop = []
|
361
|
+
# Try first time, to not enter the loop if they were already stopped
|
362
|
+
@Timers.each do |iTimer|
|
363
|
+
if (iTimer.is_running)
|
364
|
+
lTimersToStop << iTimer
|
365
|
+
end
|
366
|
+
end
|
367
|
+
while (!lTimersToStop.empty?)
|
368
|
+
lTimersToStop.delete_if do |iTimer|
|
369
|
+
next (!iTimer.is_running)
|
370
|
+
end
|
371
|
+
# Give time to the application to effectively stop its timers
|
372
|
+
Wx.get_app.yield
|
373
|
+
# Little sleep
|
374
|
+
sleep(0.1)
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
end
|
379
|
+
|
380
|
+
# Initialize the GUI methods in the Kernel namespace
|
381
|
+
def self.initializeGUI
|
382
|
+
Object.module_eval('include RUtilAnts::GUI')
|
383
|
+
end
|
384
|
+
|
385
|
+
# Get a bitmap resized to a given size if it differs from it
|
386
|
+
#
|
387
|
+
# Parameters:
|
388
|
+
# * *iBitmap* (<em>Wx::Bitmap</em>): The original bitmap
|
389
|
+
# * *iWidth* (_Integer_): The width of the resized bitmap
|
390
|
+
# * *iHeight* (_Integer_): The height of the resized bitmap
|
391
|
+
# Return:
|
392
|
+
# * <em>Wx::Bitmap</em>: The resized bitmap (can be the same object as iBitmap)
|
393
|
+
def getResizedBitmap(iBitmap, iWidth, iHeight)
|
394
|
+
rResizedBitmap = iBitmap
|
395
|
+
|
396
|
+
if ((iBitmap.width != iWidth) or
|
397
|
+
(iBitmap.height != iHeight))
|
398
|
+
rResizedBitmap = Wx::Bitmap.new(iBitmap.convert_to_image.scale(iWidth, iHeight))
|
399
|
+
end
|
400
|
+
|
401
|
+
return rResizedBitmap
|
402
|
+
end
|
403
|
+
|
404
|
+
# Display a dialog in modal mode, ensuring it is destroyed afterwards.
|
405
|
+
#
|
406
|
+
# Parameters:
|
407
|
+
# * *iDialogClass* (_class_): Class of the dialog to display
|
408
|
+
# * *iParentWindow* (<em>Wx::Window</em>): Parent window (can be nil)
|
409
|
+
# * *iParameters* (...): List of parameters to give the constructor
|
410
|
+
# * *CodeBlock*: The code called once the dialog has been displayed and modally closed
|
411
|
+
# ** *iModalResult* (_Integer_): Modal result
|
412
|
+
# ** *iDialog* (<em>Wx::Dialog</em>): The dialog
|
413
|
+
def showModal(iDialogClass, iParentWindow, *iParameters)
|
414
|
+
# If the parent is nil, we fall into a buggy behaviour in the case of GC enabled:
|
415
|
+
# * If we destroy the window after show_modal, random core dumps occur in the application
|
416
|
+
# * If not, the application can't exit normally
|
417
|
+
# Therefore, in case of nil, we assign the top window as the parent.
|
418
|
+
# Sometimes, there is no top_window. So we'll stick with nil.
|
419
|
+
lParentWindow = iParentWindow
|
420
|
+
if (lParentWindow == nil)
|
421
|
+
lParentWindow = Wx.get_app.get_top_window
|
422
|
+
end
|
423
|
+
lDialog = iDialogClass.new(lParentWindow, *iParameters)
|
424
|
+
lDialog.centre(Wx::CENTRE_ON_SCREEN|Wx::BOTH)
|
425
|
+
lModalResult = lDialog.show_modal
|
426
|
+
yield(lModalResult, lDialog)
|
427
|
+
# If we destroy windows having parents, we get SegFaults during execution when mouse hovers some toolbar icons and moves (except if we disable GC: in this case it works perfectly fine, but consumes tons of memory).
|
428
|
+
# If we don't destroy, we got ObjectPreviouslyDeleted exceptions on exit with wxRuby 2.0.0 (seems to have disappeared in 2.0.1).
|
429
|
+
# TODO (wxRuby): Correct bug on Tray before enabling GC and find the good solution for modal destruction.
|
430
|
+
if (lParentWindow == nil)
|
431
|
+
lDialog.destroy
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
# Get a bitmap/icon from a URL.
|
436
|
+
# If no type has been provided, it detects the type of icon based on the file extension.
|
437
|
+
# Use URL caching.
|
438
|
+
#
|
439
|
+
# Parameters:
|
440
|
+
# * *iFileName* (_String_): The file name
|
441
|
+
# * *iIconIndex* (_Integer_): Specify the icon index (used by Windows for EXE/DLL/ICO...) [optional = nil]
|
442
|
+
# * *iBitmapTypes* (_Integer_ or <em>list<Integer></em>): Bitmap/Icon type. Can be nil for autodetection. Can be the list of types to try. [optional = nil]
|
443
|
+
# Return:
|
444
|
+
# * <em>Wx::Bitmap</em>: The bitmap, or nil in case of failure
|
445
|
+
# * _Exception_: The exception containing details about the error, or nil in case of success
|
446
|
+
def getBitmapFromURL(iFileName, iIconIndex = nil, iBitmapTypes = nil)
|
447
|
+
rReadBitmap = nil
|
448
|
+
rReadError = nil
|
449
|
+
|
450
|
+
rReadBitmap, rReadError = getURLContent(iFileName, :LocalFileAccess => true) do |iRealFileName|
|
451
|
+
rBitmap = nil
|
452
|
+
rError = nil
|
453
|
+
|
454
|
+
lBitmapTypesToTry = iBitmapTypes
|
455
|
+
if (iBitmapTypes == nil)
|
456
|
+
# Autodetect
|
457
|
+
lBitmapTypesToTry = [ Wx::Bitmap::BITMAP_TYPE_GUESS[File.extname(iRealFileName).downcase[1..-1]] ]
|
458
|
+
if (lBitmapTypesToTry == [ nil ])
|
459
|
+
# Here we handle extensions that wxruby is not aware of
|
460
|
+
case File.extname(iRealFileName).upcase
|
461
|
+
when '.CUR', '.ANI', '.EXE', '.DLL'
|
462
|
+
lBitmapTypesToTry = [ Wx::BITMAP_TYPE_ICO ]
|
463
|
+
else
|
464
|
+
logErr "Unable to determine the bitmap type corresponding to extension #{File.extname(iRealFileName).upcase}. Assuming ICO."
|
465
|
+
lBitmapTypesToTry = [ Wx::BITMAP_TYPE_ICO ]
|
466
|
+
end
|
467
|
+
end
|
468
|
+
elsif (!iBitmapTypes.is_a?(Array))
|
469
|
+
lBitmapTypesToTry = [ iBitmapTypes ]
|
470
|
+
end
|
471
|
+
# Try each type
|
472
|
+
lBitmapTypesToTry.each do |iBitmapType|
|
473
|
+
# Special case for the ICO type
|
474
|
+
if (iBitmapType == Wx::BITMAP_TYPE_ICO)
|
475
|
+
lIconID = iRealFileName
|
476
|
+
if ((iIconIndex != nil) and
|
477
|
+
(iIconIndex != 0))
|
478
|
+
# TODO: Currently this implementation does not work. Uncomment when ok.
|
479
|
+
#lIconID += ";#{iIconIndex}"
|
480
|
+
end
|
481
|
+
rBitmap = Wx::Bitmap.new
|
482
|
+
begin
|
483
|
+
rBitmap.copy_from_icon(Wx::Icon.new(lIconID, Wx::BITMAP_TYPE_ICO))
|
484
|
+
rescue Exception
|
485
|
+
rError = $!
|
486
|
+
rBitmap = nil
|
487
|
+
end
|
488
|
+
else
|
489
|
+
rBitmap = Wx::Bitmap.new(iRealFileName, iBitmapType)
|
490
|
+
end
|
491
|
+
if (rBitmap != nil)
|
492
|
+
if (rBitmap.is_ok)
|
493
|
+
break
|
494
|
+
else
|
495
|
+
# File seems to be corrupted
|
496
|
+
rError = RuntimeError.new("Bitmap #{iFileName} is corrupted.")
|
497
|
+
rBitmap = nil
|
498
|
+
end
|
499
|
+
else
|
500
|
+
rBitmap = nil
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
return rBitmap, rError
|
505
|
+
end
|
506
|
+
|
507
|
+
# Check if it is ok and the error set correctly
|
508
|
+
if ((rReadBitmap == nil) and
|
509
|
+
(rReadError == nil))
|
510
|
+
rError = RuntimeError.new("Unable to get bitmap from #{iFileName}")
|
511
|
+
end
|
512
|
+
|
513
|
+
return rReadBitmap, rReadError
|
514
|
+
end
|
515
|
+
|
516
|
+
# Setup a progress bar with some text in it and call code around it
|
517
|
+
#
|
518
|
+
# Parameters:
|
519
|
+
# * *iParentWindow* (<em>Wx::Window</em>): The parent window
|
520
|
+
# * *iText* (_String_): The text to display
|
521
|
+
# * *iParameters* (<em>map<Symbol,Object></em>): Additional parameters (check RUtilAnts::GUI::ProgressDialog#initialize documentation):
|
522
|
+
# * _CodeBlock_: The code called with the progress bar created:
|
523
|
+
# ** *ioProgressDlg* (<em>RUtilAnts::GUI::ProgressDialog</em>): The progress dialog
|
524
|
+
def setupTextProgress(iParentWindow, iText, iParameters = {}, &iCodeToExecute)
|
525
|
+
showModal(TextProgressDialog, iParentWindow, iCodeToExecute, iText, iParameters) do |iModalResult, iDialog|
|
526
|
+
# Nothing to do
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
# Setup a progress bar with some bitmap in it and call code around it
|
531
|
+
#
|
532
|
+
# Parameters:
|
533
|
+
# * *iParentWindow* (<em>Wx::Window</em>): The parent window
|
534
|
+
# * *iBitmap* (<em>Wx::Bitmap</em>): The bitmap to display
|
535
|
+
# * *iParameters* (<em>map<Symbol,Object></em>): Additional parameters (check RUtilAnts::GUI::ProgressDialog#initialize documentation):
|
536
|
+
# * _CodeBlock_: The code called with the progress bar created:
|
537
|
+
# ** *ioProgressDlg* (<em>RUtilAnts::GUI::ProgressDialog</em>): The progress dialog
|
538
|
+
def setupBitmapProgress(iParentWindow, iBitmap, iParameters = {}, &iCodeToExecute)
|
539
|
+
showModal(BitmapProgressDialog, iParentWindow, iCodeToExecute, iBitmap, iParameters) do |iModalResult, iDialog|
|
540
|
+
# Nothing to do
|
541
|
+
end
|
542
|
+
end
|
543
|
+
|
544
|
+
# Execute some code after some elapsed time.
|
545
|
+
#
|
546
|
+
# Parameters:
|
547
|
+
# * *ioSafeTimersManager* (_SafeTimersManager_): The manager that handles this SafeTimer
|
548
|
+
# * *iElapsedTime* (_Integer_): The elapsed time to wait before running the code
|
549
|
+
# * _CodeBlock_: The code to execute
|
550
|
+
def safeTimerAfter(ioSafeTimersManager, iElapsedTime)
|
551
|
+
# Create the Timer and register it
|
552
|
+
lTimer = nil
|
553
|
+
lTimer = Wx::Timer.after(iElapsedTime) do
|
554
|
+
yield
|
555
|
+
# Now the Timer can be safely destroyed.
|
556
|
+
ioSafeTimersManager.unregisterTimer(lTimer)
|
557
|
+
end
|
558
|
+
ioSafeTimersManager.registerTimer(lTimer)
|
559
|
+
end
|
560
|
+
|
561
|
+
# Execute some code every some elapsed time.
|
562
|
+
#
|
563
|
+
# Parameters:
|
564
|
+
# * *ioSafeTimersManager* (_SafeTimersManager_): The manager that handles this SafeTimer
|
565
|
+
# * *iElapsedTime* (_Integer_): The elapsed time to wait before running the code
|
566
|
+
# * _CodeBlock_: The code to execute
|
567
|
+
def safeTimerEvery(ioSafeTimersManager, iElapsedTime)
|
568
|
+
# Create the Timer and register it
|
569
|
+
lTimer = Wx::Timer.every(iElapsedTime) do
|
570
|
+
yield
|
571
|
+
end
|
572
|
+
ioSafeTimersManager.registerTimer(lTimer)
|
573
|
+
end
|
574
|
+
|
575
|
+
end
|
576
|
+
|
577
|
+
end
|