rwdschedule 0.93 → 0.94

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. data/Readme.txt +6 -0
  2. data/code/01rwdcore/01rwdcore.rb +20 -20
  3. data/code/01rwdcore/02helptexthashbegin.rb +4 -4
  4. data/code/01rwdcore/03helptexthash.rb +30 -47
  5. data/code/01rwdcore/04helptextend.rb +6 -6
  6. data/code/01rwdcore/openhelpwindow.rb +10 -24
  7. data/code/01rwdcore/returntomain.rb +10 -0
  8. data/code/01rwdcore/rwdtinkerversion.rb +15 -15
  9. data/code/01rwdcore/rwdwindowreturn.rb +9 -9
  10. data/code/superant.com.rwdtinkerbackwindow/controlclient.rb +100 -0
  11. data/code/superant.com.rwdtinkerbackwindow/diagnostictab.rb +21 -21
  12. data/code/superant.com.rwdtinkerbackwindow/helptexthashtinkerwin2.rb +37 -0
  13. data/code/superant.com.rwdtinkerbackwindow/installapplet.rb +21 -21
  14. data/code/superant.com.rwdtinkerbackwindow/listinstalledfiles.rb +1 -1
  15. data/code/superant.com.rwdtinkerbackwindow/listzips.rb +6 -6
  16. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationrecord.rb +31 -31
  17. data/code/superant.com.rwdtinkerbackwindow/loadconfigurationvariables.rb +13 -13
  18. data/code/superant.com.rwdtinkerbackwindow/network.rb +87 -0
  19. data/code/superant.com.rwdtinkerbackwindow/openappletname.rb +18 -18
  20. data/code/superant.com.rwdtinkerbackwindow/openhelpwindowtinkerwin2.rb +39 -0
  21. data/code/superant.com.rwdtinkerbackwindow/removeapplet.rb +28 -28
  22. data/code/superant.com.rwdtinkerbackwindow/runrwdtinkerbackwindow.rb +11 -11
  23. data/code/superant.com.rwdtinkerbackwindow/rwdtinkerwin2version.rb +14 -14
  24. data/code/superant.com.rwdtinkerbackwindow/saveconfigurationrecord.rb +18 -18
  25. data/code/superant.com.rwdtinkerbackwindow/viewappletcontents.rb +21 -0
  26. data/code/superant.com.schedule/helptexthashrwdschedule.rb +19 -3
  27. data/code/superant.com.schedule/{openhelpwindowrubyslippers.rb → openhelpwindowrwdschedule.rb} +11 -2
  28. data/code/superant.com.schedule/returntomain.rb +10 -0
  29. data/code/superant.com.schedule/runrwdschedulemenu1.rb +34 -0
  30. data/code/zz0applicationend/zz0end.rb +4 -4
  31. data/configuration/language.cnf +5 -5
  32. data/configuration/rwdapplicationidentity.cnf +3 -0
  33. data/configuration/rwdscheduleversion.cnf +1 -1
  34. data/configuration/rwdtinker.cnf +1 -0
  35. data/configuration/rwdtinkerversion.cnf +2 -2
  36. data/configuration/tinkerwin2variables.cnf +8 -8
  37. data/configuration/tinkerwin2version.cnf +3 -3
  38. data/ev/browser.rb +109 -109
  39. data/ev/ftools.rb +170 -170
  40. data/ev/net.rb +750 -750
  41. data/ev/ruby.rb +819 -819
  42. data/ev/rwd.rb +1849 -1848
  43. data/ev/sgml.rb +236 -236
  44. data/ev/thread.rb +63 -63
  45. data/ev/tree.rb +343 -343
  46. data/ev/xml.rb +4 -4
  47. data/gui/00coreguibegin/applicationguitop.rwd +4 -4
  48. data/gui/frontwindow0/superant.com.rwdschedules/gg0viewevent.rwd +1 -1
  49. data/gui/frontwindow0/superant.com.rwdschedules/gl6editrecord.rwd +10 -10
  50. data/gui/frontwindow0/superant.com.rwdschedules/gl8contactutilities.rwd +1 -0
  51. data/gui/frontwindow0/superant.com.zmenus/m01menubegin.rwd +10 -0
  52. data/gui/frontwindow0/superant.com.zmenus/m02menu.rwd +36 -0
  53. data/gui/frontwindow0/superant.com.zmenus/m03menu.rwd +12 -0
  54. data/gui/frontwindow0/superant.com.zmenus/m85menu.rwd +21 -0
  55. data/gui/frontwindow0/superant.com.zmenus/m88menu.rwd +12 -0
  56. data/gui/frontwindow0/superant.com.zmenus/m99menuend.rwd +3 -0
  57. data/gui/frontwindowselectionbegin/selectiontabbegin/selectiontabbegin.rwd +16 -16
  58. data/gui/frontwindowselections/superant.com.rwdtinkerwin2selectiontab/rwdwin2selectiontab.rwd +12 -12
  59. data/gui/frontwindowselectionzend/viewselectionzend/viewselectionend.rwd +3 -3
  60. data/gui/frontwindowtdocumentbegin/superant.com.documentsbegin/tt0documentbegin.rwd +6 -6
  61. data/gui/frontwindowtdocuments/superant.com.documents/uu5documents.rwd +15 -15
  62. data/gui/frontwindowtdocuments/superant.com.tinkerwin2documents/uu5documents.rwd +6 -6
  63. data/gui/frontwindowtdocumentzend/superant.com.documentsend/ww0documentend.rwd +12 -12
  64. data/gui/frontwindowz1end/frontwindowend/xx0rwdfirsttab.rwd +6 -6
  65. data/gui/helpaboutbegin/superant.com.helpaboutbegin/ya0helpscreenstart.rwd +3 -3
  66. data/gui/helpaboutinstalled/superant.com.rwdwin2helpabout/1appname.rwd +4 -4
  67. data/gui/helpaboutinstalled/superant.com.rwdwin2helpabout/3copyright.rwd +3 -3
  68. data/gui/helpaboutinstalled/superant.com.rwdwin2helpabout/5version.rwd +10 -10
  69. data/gui/helpaboutinstalled/superant.com.tinkerhelpabout/1appname.rwd +4 -4
  70. data/gui/helpaboutinstalled/superant.com.tinkerhelpabout/3copyright.rwd +3 -3
  71. data/gui/helpaboutinstalled/superant.com.tinkerhelpabout/5version.rwd +10 -10
  72. data/gui/helpaboutzend/superant.com.helpaboutend/helpscreenend.rwd +2 -2
  73. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/67viewconfiguration.rwd +38 -0
  74. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/m01menubegin.rwd +10 -0
  75. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/m02menu.rwd +36 -0
  76. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/m03menu.rwd +12 -0
  77. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/m85menu.rwd +21 -0
  78. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/m88menu.rwd +12 -0
  79. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/m99menuend.rwd +3 -0
  80. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/1appname.rwd +5 -5
  81. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/{50rwdlistzips.rwd → 40rwdlistzips.rwd} +42 -35
  82. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/50rwdlistapplets.rwd +44 -44
  83. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/60editconfiguration.rwd +38 -37
  84. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/70rwddiagnostics.rwd +33 -33
  85. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/75rwdcontrol.rwd +33 -0
  86. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/80tab1.rwd +11 -11
  87. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/9backend.rwd +6 -6
  88. data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/1appname.rwd +30 -31
  89. data/gui/tinkerbackwindows/superant.com.tinkerhelpwindow/9end.rwd +4 -4
  90. data/gui/tinkerbackwindows/superant.com.versionwindow/1appname.rwd +19 -19
  91. data/gui/zzcoreguiend/tinkerapplicationguiend/yy9rwdend.rwd +4 -4
  92. data/init.rb +269 -233
  93. data/installed/rwdtinkerwin2-0.5.inf +8 -8
  94. data/lang/alanguagehashbegin.rb +4 -4
  95. data/lang/en/rwdcore/languagefile.rb +15 -15
  96. data/lang/es/rwdcore/languagefile-es.rb +14 -14
  97. data/lang/jp/rwdcore/languagefile.rb +9 -9
  98. data/lang/languagehash.rb +4 -4
  99. data/lang/nl/rwdcore/languagefile.rb +19 -19
  100. data/lang/vlanguagehashend.rb +6 -6
  101. data/lang/wlocallangstart.rb +5 -5
  102. data/lang/zlocallangend.rb +2 -2
  103. data/lib/temp.rb +1 -1
  104. data/rwd_files/HowTo_Schedule.txt +6 -0
  105. data/rwd_files/HowTo_Tinker.txt +361 -348
  106. data/rwd_files/HowTo_TinkerWin2.txt +202 -202
  107. data/rwd_files/Readme.txt +57 -57
  108. data/rwd_files/rdoc-style.css +174 -174
  109. data/rwd_files/rwdapplications.html +54 -54
  110. data/tests/totranslate.lang +93 -0
  111. data/zips/rwdahelloworld-0.5.zip +0 -0
  112. data/zips/rwdwcalc-0.50.zip +0 -0
  113. metadata +33 -17
  114. data/configuration/rwdplayscriptsversion.cnf +0 -2
  115. data/gui/frontwindow0/superant.com.rwdschedules/zviewconfiguration.rwd +0 -38
  116. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/66viewconfiguration.rwd +0 -16
  117. data/gui/tinkerbackwindows/superant.com.rwdschedulebackwindow/80returntab.rwd +0 -11
  118. data/installed/rwdviewlogo-0.4.inf +0 -4
  119. data/rwd_files/tinker.png +0 -0
  120. data/updates/200502Februay01 Lynn back.sch +0 -8
  121. data/updates/200502Februay21 PCU Diner.sch +0 -8
  122. data/updates/200502february16a.sch +0 -8
  123. data/updates/200505may02a.sch +0 -8
  124. data/updates/200506june20a.sch +0 -8
  125. data/updates/200506june29a.sch +0 -8
  126. data/updates/200510october26a.sch +0 -8
data/ev/rwd.rb CHANGED
@@ -1,1848 +1,1849 @@
1
- require "ev/ruby"
2
- require "ev/xml"
3
- require "ev/net"
4
- require "ev/browser"
5
- require "ev/thread"
6
- require "md5"
7
- require "rbconfig"
8
-
9
- begin
10
- require "win32ole"
11
- require "win32/registry"
12
- rescue LoadError
13
- $".push "win32ole.so"
14
- $".push "win32/registry.rb"
15
- end
16
-
17
- $rwd_exit = ARGV.include?("--rwd-exit") # Hack ???
18
- $rwd_debug = ($rwd_debug or $DEBUG or false)
19
- $rwd_border = ($rwd_border or 0)
20
- $rwd_dir = Dir.pwd
21
- $rwd_files = File.expand_path("rwd_files", Dir.pwd)
22
- $rwd_html = {}
23
-
24
- ARGV.delete_if do |arg|
25
- arg =~ /^--rwd-/
26
- end
27
-
28
- RWDEmptyline = "..."
29
-
30
- rcfile = nil
31
- s = ENV["HOME"] ; s = s + "/.rwdrc" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil? and File.file?(s))
32
- s = ENV["USERPROFILE"] ; s = s + "/rwd.cfg" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil? and File.file?(s))
33
- s = ENV["windir"] ; s = s + "/rwd.cfg" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil? and File.file?(s))
34
-
35
- AL = "align='left'"
36
- AC = "align='center'"
37
- AR = "align='right'"
38
- VA = "valign='middle'"
39
-
40
- Format = "\n<!-- %-10s %-10s -->\t"
41
-
42
- unless rcfile.nil?
43
- puts "Reading #{rcfile} ..."
44
-
45
- Hash.file(rcfile).each do |k, v|
46
- ENV[k] = v unless ENV.include?(k)
47
- end
48
- end
49
-
50
- ENV["RWDBROWSER"] = (ENV["RWDBROWSER"] or defaultbrowser) or puts "No browser found."
51
- ENV["RWDPORTS"] = (ENV["RWDPORTS"] or "7701-7709")
52
- ENV["RWDTHEME"] = (ENV["RWDTHEME"] or "DEFAULT")
53
-
54
- trap("INT") {puts "Terminating..." ; exit}
55
-
56
- $SAFE = 2
57
-
58
- class IE
59
- def initialize(url)
60
- @ie = WIN32OLE.new("InternetExplorer.Application")
61
- @ev = WIN32OLE_EVENT.new(@ie, "DWebBrowserEvents2")
62
-
63
- @ie.navigate(url)
64
-
65
- @ie.menubar = false
66
- @ie.toolbar = false
67
- @ie.addressbar = false
68
- @ie.statusbar = false
69
-
70
- @ie.visible = true
71
-
72
- at_exit do
73
- @ie.visible = false
74
- end
75
-
76
- @ev.on_event("OnQuit") do
77
- Thread.main.exit
78
- end
79
-
80
- Thread.new do
81
- loop do
82
- WIN32OLE_EVENT.message_loop
83
- end
84
- end
85
- end
86
- end
87
-
88
- class Array
89
- def rwd_options(emptyline=nil)
90
- if emptyline.nil?
91
- a = self
92
- else
93
- a = [emptyline].concat(self)
94
- end
95
-
96
- a.numsort.collect{|s| "<option>#{s.to_html}</option>" }.join("\n")
97
- end
98
-
99
- def rwd_method(method)
100
- res = ""
101
-
102
- self.each do |s|
103
- s = s.join("/") if s.kind_of?(Array)
104
- s2 = s.dup
105
- s2[0..0] = s2[0..0].upcase
106
- res = res + "<p align='left'><a action='#{method}/#{s.to_html}'>#{s2.to_html}</a></p>"
107
- end
108
-
109
- return res
110
- end
111
-
112
- def rwd_row(key=nil, value=nil)
113
- res = ""
114
-
115
- res = res + "<row valign='top'>"
116
- res = res + "<radio name='#{key.to_html}' value='#{value.to_html}'/>" unless key.nil?
117
- res = res + self.collect{|s| "<p align='left'>#{s.to_html}</p>"}.join("")
118
- res = res + "</row>"
119
-
120
- return res
121
- end
122
-
123
- def rwd_headers(emptyfield=false)
124
- res = ""
125
-
126
- res = res + "<row>"
127
- res = res + "<p/>" if emptyfield
128
- res = res + self.collect{|s| "<p align='left'><b>#{s.to_html}</b></p>" }.join("")
129
- res = res + "</row>"
130
-
131
- return res
132
- end
133
-
134
- def rwd_form(prefix, values, twoparts=0, options={})
135
- res = []
136
-
137
- res << "<table>"
138
- self.each_index do |n|
139
- name = "#{prefix.to_html}#{self[n].downcase.to_html}"
140
-
141
- res << "<row>"
142
- res << "<p align='right'>"
143
- res << "#{self[n].to_html}:"
144
- res << "</p>"
145
-
146
- if options.keys.include?(self[n])
147
- res << "<select name='#{name}'>"
148
- res << options[self[n]].rwd_options(RWDEmptyline)
149
- res << "</select>"
150
- else
151
- s = ""
152
-
153
- s << "<text name='#{name}'"
154
- s << " value='#{values[n].to_html}'" if n < values.length
155
- s << "/>"
156
-
157
- res << s
158
- end
159
-
160
- res << "</row>"
161
-
162
- if twoparts > 0 and n == twoparts-1
163
- res << "<row><empty/></row>"
164
- end
165
- end
166
- res << "</table>"
167
-
168
- return res.join("\n")
169
- end
170
- end
171
-
172
- class Hash
173
- def rwd_table(field=nil, joinwith=nil, headers=nil)
174
- res = []
175
-
176
- res << "<table>"
177
- res << headers.rwd_headers((not field.nil?)) if not headers.nil?
178
- self.keys.numsort.each do |key|
179
- key2 = key
180
- value2 = self[key]
181
-
182
- key2 = key2.join(joinwith) if key2.kind_of?(Array)
183
- value2 = [value2] if value2.kind_of?(String)
184
-
185
- res << value2.rwd_row(field, key2)
186
- end
187
- res << "</table>"
188
-
189
- res.join("\n")
190
- end
191
- end
192
-
193
- class EVTable
194
- def rwd_table(field=nil, joinwith=@sep)
195
- super(field, joinwith, @headers)
196
- end
197
-
198
- def rwd_form(prefix="", key=nil, twoparts=false)
199
- values = self[key] if not key.nil?
200
- values = [] if values.nil?
201
- options = {}
202
-
203
- if File.file?(oldlocation("constraints.tsv"))
204
- table = File.basename(@file).gsub(/\.tsv$/, "")
205
-
206
- TSVFile.new(oldlocation("constraints.tsv")).subset(["Table", "Constraint"], [table, "key"], ["Column", "Value"]).values.each do |column, table2|
207
- options[column] = TSVFile.new(oldlocation("#{table2}.tsv")).keys.collect{|a| a.join("\t")}
208
- end
209
- end
210
-
211
- @headers.rwd_form(prefix, values, twoparts ? @key : 0, options)
212
- end
213
-
214
- def rwd_metadata
215
- res = []
216
-
217
- res << "<table>"
218
- res << "<row>"
219
- res << " <empty/>"
220
- res << " <text name='header_new' value=''/>"
221
- res << "</row>"
222
- @headers.each_index do |n|
223
- res << "<row>"
224
- res << " <text name='header_#{n}_old' value='#{@headers[n]}'/>"
225
- res << " <text name='header_#{n}_new' value=''/>"
226
- res << "</row>"
227
- end
228
- res << "</table>"
229
-
230
- return res.join("\n")
231
- end
232
- end
233
-
234
- class OpenTag
235
- def prechildren(res, before, after, varshtml, varsstring, switches, help, oneormorefields, firstaction, tabs, tab, pda)
236
- bef = before[-1]
237
- res << Format % ["Before", @subtype] if ($rwd_debug and not bef.nil?)
238
- res << bef if not bef.nil?
239
-
240
- res << Format % ["Pre", @subtype] if $rwd_debug
241
-
242
- align = AC
243
- align = "align='#{@args["align"]}'" if @args.include?("align")
244
-
245
- valign = VA
246
- valign = "valign='#{@args["valign"]}'" if @args.include?("valign")
247
-
248
- value1 = ""
249
- value1 = varshtml[@args["name"]] if varshtml.include?(@args["name"])
250
- value1 = @args["value"] if @args.include?("value")
251
-
252
- value2 = ""
253
- value2 = varsstring[@args["name"]] if varsstring.include?(@args["name"])
254
- value2 = @args["value"] if @args.include?("value")
255
-
256
- cellspacing = 3
257
- cellspacing = 0 if pda
258
-
259
- case @subtype
260
- when "application"
261
- when "window", "helpwindow"
262
- args = @args.deep_dup
263
-
264
- args["nohelpbutton"] = (not help)
265
-
266
- template = $rwd_html_1
267
- template = $rwd_html_PDA_1 if pda
268
-
269
- res <<(template(template, args))
270
- when "p" then res << "<p #{align}>"
271
- when "pre" then res << "<pre #{align}>"
272
- when "big" then res << "<p #{align}><big>"
273
- when "small" then res << "<p #{align}><small>"
274
- when "list" then res << "<ul #{align}>"
275
- when "item" then res << "<li #{align}>"
276
- when "empty" then res << "<p><br>"
277
- when "image"
278
- width = "width='#{@args["width"]}" if @args.include?("width")
279
- height = "height='#{@args["height"]}'" if @args.include?("height")
280
-
281
- res << "<img src='#{@args["src"]}' alt='#{@args["alt"]}' #{width} #{height}>"
282
- when "progressbar"
283
- width = 200
284
-
285
- res << "<table>"
286
- res << " <tr>"
287
- res << " <td colspan='2'><img src='rwd_pixel.gif' height='1' width='#{width+5}'></td>"
288
- res << " </tr>"
289
- res << " <tr>"
290
- res << " <td bgcolor='#DDDDDD'><img src='rwd_pixel.gif' height='10' width='#{(width*@args["value"].to_f).to_i}'></td>"
291
- res << " <td bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='10' width='#{(width*(1.0-@args["value"].to_f)).to_i}'></td>"
292
- res << " </tr>"
293
- res << "</table>"
294
- when "br" then res << "<br>"
295
- when "hr" then res << "<hr>"
296
- when "b" then res << "<b>"
297
- when "i" then res << "<i>"
298
- when "a"
299
- if @args.include?("href")
300
- res << "<a href='#{@args["href"]}' target='#{@args["target"] or "_blank"}'>"
301
- else
302
- res << "<a href='javascript:document.bodyform.rwd_action.value=\"#{@args["action"]}\";document.bodyform.submit();'>"
303
- end
304
- when "vertical" then res << "<table #{AC} border='#{$rwd_border}' cellspacing='#{cellspacing}' cellpadding='0'>"
305
- when "horizontal" then res << "<table #{AC} border='#{$rwd_border}' cellspacing='#{cellspacing}' cellpadding='0'><tr #{align} #{valign}>"
306
- when "table" then res << "<table #{AC} border='#{$rwd_border}' cellspacing='#{cellspacing}' cellpadding='0'>"
307
- when "row" then res << "<tr #{align} #{valign}>"
308
- when "hidden" then res << "<p #{align}><input name='#{@args["name"]}' value='#{value1}' type='hidden'>"
309
- when "text"
310
- maxlength = ""
311
- maxlength = "maxlength='%s'" % @args["maxlength"] if @args.include?("maxlength")
312
- size = ""
313
- size = "size='%s'" % 10 if pda
314
- res << "<p #{align}><input name='#{@args["name"]}' value='#{value1}' type='text' #{maxlength} #{size}>"
315
- oneormorefields << "true"
316
- when "textarea"
317
- res << "<p #{align}><textarea name='#{@args["name"]}' rows='25' cols='80'>#{value2.crlf}</textarea>"
318
- oneormorefields << "true"
319
- when "password"
320
- maxlength = ""
321
- maxlength = "maxlength='%s'" % @args["maxlength"] if @args.include?("maxlength")
322
- size = ""
323
- size = "size='%s'" % 10 if pda
324
- res << "<p #{align}><input name='#{@args["name"]}' value='#{value1}' type='password' #{maxlength} #{size}>"
325
- oneormorefields << "true"
326
- when "checkbox"
327
- if varshtml[@args["name"]] == "on"
328
- switches[@args["name"]] = true
329
- res << "<p #{align}><input name='#{@args["name"]}' checked='on' type='checkbox'>"
330
- else
331
- switches[@args["name"]] = false
332
- res << "<p #{align}><input name='#{@args["name"]}' type='checkbox'>"
333
- end
334
- oneormorefields << "true"
335
- when "radio"
336
- if varshtml[@args["name"]] == value1 # ??? 1 or 2?
337
- res << "<p #{align}><input name='#{@args["name"]}' checked='on' value='#{value1}' type='radio'>"
338
- else
339
- res << "<p #{align}><input name='#{@args["name"]}' value='#{value1}' type='radio'>"
340
- end
341
- oneormorefields << "true"
342
- when "select"
343
- res << "<select #{align} name='#{@args["name"]}' width='#{@args["width"]}'>"
344
- name = @args["name"]
345
- $select = varshtml[name]
346
- oneormorefields << "true"
347
- when "option"
348
- if $select == @children[0].text
349
- res << "<option selected='true'>"
350
- else
351
- res << "<option>"
352
- end
353
- when "button"
354
- res << "<input type='submit' value='#{@args["caption"]}' onclick='document.bodyform.rwd_action.value=\"#{@args["action"]}\";'>"
355
- firstaction << @args["action"] if (firstaction.empty? and @args.include?("action"))
356
- oneormorefields << "true"
357
- when "back"
358
- res << "<input type='submit' value='Back' onclick='document.bodyform.rwd_action.value=\"rwd_back\";'>"
359
- firstaction << "rwd_back" if firstaction.empty?
360
- oneormorefields << "true"
361
- when "cancel"
362
- res << "<input type='submit' value='Cancel' onclick='document.bodyform.rwd_action.value=\"rwd_cancel\";'>"
363
- firstaction << "rwd_cancel" if firstaction.empty?
364
- oneormorefields << "true"
365
- when "help"
366
- res << "<input type='submit' value='Help' onclick='document.bodyform.rwd_action.value=\"rwd_help\";'>"
367
- firstaction << "rwd_help" if firstaction.empty?
368
- oneormorefields << "true"
369
- when "quit"
370
- res << "<input type='submit' value='Quit' onclick='document.bodyform.rwd_action.value=\"rwd_quit\";'>"
371
- firstaction << "rwd_quit" if firstaction.empty?
372
- oneormorefields << "true"
373
- when "close"
374
- res << "<input type='submit' value='Close' onclick='window.close();'>"
375
- firstaction << "rwd_quit" if firstaction.empty?
376
- oneormorefields << "true"
377
- when "main"
378
- res << "<input type='submit' value='Main' onclick='document.bodyform.rwd_action.value=\"rwd_main\";'>"
379
- firstaction << "rwd_main" if firstaction.empty?
380
- oneormorefields << "true"
381
- when "reset"
382
- res << "<input type='reset' value='Reset'>"
383
- firstaction << "rwd_quit" if firstaction.empty? # ???
384
- oneormorefields << "true"
385
- when "closewindow"
386
- #res << "<script type='text/javascript'>\n" # ???
387
- #res << "<!--\n"
388
- #res << " window.close();\n"
389
- #res << "//-->\n"
390
- #res << "</script>"
391
- when "tabs"
392
- res << "<table #{AC} border='#{$rwd_border}' cellspacing='0' cellpadding='0'>"
393
- res << " <tr #{AL}>"
394
- res << " <td #{AL} class='tabs'>"
395
- res << " <table #{AL} border='#{$rwd_border}' cellspacing='0' cellpadding='0'>"
396
- res << " <tr #{AL}>"
397
- #res << " <td class='notab'>&nbsp;</td>"
398
- tabs.each do |obj|
399
- name = obj.args["name"]
400
- caption = obj.args["caption"]
401
-
402
- res << "<td #{AL} class='notab'>&nbsp;</td>" unless obj == tabs[0]
403
-
404
- if name == tab
405
- res << "<td #{AC} class='activetab'><tt>&nbsp;#{caption}&nbsp;</tt></td>"
406
- else
407
- res << "<td #{AC} class='passivetab'><a href='javascript:document.bodyform.rwd_action.value=\"rwd_tab_#{name}\";document.bodyform.submit();'><tt>&nbsp;#{caption}&nbsp;</tt></a></td>"
408
- end
409
- end
410
- res << " <td class='notab' width='100%'>&nbsp;</td>"
411
- res << " </tr>"
412
- res << " </table>"
413
- res << " </td>"
414
- res << " </tr>"
415
- res << " <tr #{align}>"
416
- res << " <td #{align} class='tabblad'>"
417
- when "tab"
418
- res << "<table #{AC} border='#{$rwd_border}' cellspacing='3' cellpadding='0'>"
419
- when "panel"
420
- level = (@args["level"] or "normal")
421
- res << "<table #{AC} border='#{$rwd_border}' cellspacing='0' cellpadding='0'>"
422
- res << " <tr #{align}>"
423
- res << " <td #{align} class='panel1'>" if level == "normal"
424
- res << " <td #{align} class='panel1high'>" if level == "high"
425
- res << " <td #{align} class='panel1low'>" if level == "low"
426
- res << " <table #{AC} border='#{$rwd_border}' cellspacing='0' cellpadding='0'>"
427
- res << " <tr #{align}>"
428
- res << " <td #{align} class='panel2'>" if level == "normal"
429
- res << " <td #{align} class='panel2high'>" if level == "high"
430
- res << " <td #{align} class='panel2low'>" if level == "low"
431
- res << " <table #{AC} border='#{$rwd_border}' cellspacing='3' cellpadding='0'>"
432
- else
433
- puts "<#{@subtype}>"
434
- res << "&lt;#{@subtype}&gt;"
435
- end
436
-
437
- bef = nil
438
- aft = nil
439
-
440
- case @subtype
441
- when "vertical", "window", "helpwindow", "tab", "panel"
442
- res << Format % ["AftPre", @subtype] if $rwd_debug
443
- if @args.include?("spacing")
444
- s = "<tr><td>&nbsp;</td></tr>" * (@args["spacing"].to_i)
445
- else
446
- s = ""
447
- end
448
- bef = "#{s}<tr #{align} #{valign}><td #{align}>"
449
- aft = "</td></tr>"
450
- when "horizontal", "row"
451
- res << Format % ["AftPre", @subtype] if $rwd_debug
452
- bef = "<td #{align}>"
453
- aft = "</td>"
454
- end
455
-
456
- before.push(bef)
457
- after.push(aft)
458
- end
459
-
460
- def postchildren(res, before, after, varshtml, varsstring, switches, help, oneormorefields, firstaction, tabs, tab, pda)
461
- case @subtype
462
- when "vertical", "window", "helpwindow", "tab", "panel"
463
- res << Format % ["BefPost", @subtype] if $rwd_debug
464
- if @args.include?("spacing")
465
- res << "<tr><td>&nbsp;</td></tr>" * (@args["spacing"].to_i)
466
- end
467
- when "horizontal", "row"
468
- res << Format % ["BefPost", @subtype] if $rwd_debug
469
- end
470
-
471
- res << Format % ["Post", @subtype] if $rwd_debug
472
-
473
- case @subtype
474
- when "application"
475
- when "window", "helpwindow"
476
- args = @args.deep_dup
477
-
478
- args["nohelpbutton"] = (not help)
479
-
480
- template = $rwd_html_2
481
- template = $rwd_html_PDA_2 if pda
482
-
483
- res <<(template(template, args))
484
- when "p" then res << "</p>"
485
- when "pre" then res << "</pre>"
486
- when "big" then res << "</big></p>"
487
- when "small" then res << "</small></p>"
488
- when "list" then res << "</ul>"
489
- when "item" then res << "</li>"
490
- when "empty" then res << "</p>"
491
- when "image" then res << ""
492
- when "progressbar" then res << ""
493
- when "br" then res << ""
494
- when "hr" then res << ""
495
- when "b" then res << "</b>"
496
- when "i" then res << "</i>"
497
- when "a" then res << "</a>"
498
- when "vertical" then res << "</table>"
499
- when "horizontal" then res << "</tr></table>"
500
- when "table" then res << "</table>"
501
- when "row" then res << "</tr>"
502
- when "hidden" then res << "</p>"
503
- when "text" then res << "</p>"
504
- when "textarea" then res << "</p>"
505
- when "password" then res << "</p>"
506
- when "checkbox" then res << "</p>"
507
- when "radio" then res << "</p>"
508
- when "select"
509
- res << "</select>"
510
- $select = nil
511
- when "option" then res << "</option>"
512
- when "button" then res << ""
513
- when "back" then res << ""
514
- when "cancel" then res << ""
515
- when "help" then res << ""
516
- when "quit" then res << ""
517
- when "close" then res << ""
518
- when "main" then res << ""
519
- when "reset" then res << ""
520
- when "closewindow" then res << ""
521
- when "tabs"
522
- res << " </td>"
523
- res << " </tr>"
524
- res << "</table>"
525
- when "tab"
526
- res << "</table>"
527
- when "panel"
528
- res << " </table>"
529
- res << " </td>"
530
- res << " </tr>"
531
- res << " </table>"
532
- res << " </td>"
533
- res << " </tr>"
534
- res << "</table>"
535
- else
536
- puts "</#{@subtype}>"
537
- res << "&lt;/#{@subtype}&gt;"
538
- end
539
-
540
- before.pop
541
- after.pop
542
-
543
- aft = after[-1]
544
- res << Format % ["After", @subtype] if ($rwd_debug and not aft.nil?)
545
- res << aft if not aft.nil?
546
- end
547
-
548
- def template(html, vars)
549
- res = []
550
-
551
- a = {}
552
-
553
- vars.each do |k, v|
554
- a[k.upcase] = v
555
- end
556
-
557
- logo = nil
558
- logo = File.expand_path(vars["logo"], $rwd_files) if vars.include?("logo")
559
- logo = nil unless logo.nil? or File.file?(logo)
560
-
561
- a["LOGO"] = "" unless not logo.nil?
562
-
563
- a["HELPBUTTON"] = (not (vars["nohelpbutton"]))
564
- a["BACKBUTTONS"] = (not (vars["nobackbuttons"]))
565
- a["BACKBUTTONS"] = (not (vars["nobackbuttons"]))
566
- a["CLOSEBUTTON"] = (not (vars["noclosebutton"]))
567
-
568
- if a.include?("WIDTH")
569
- a["WIDTH1"] = "width='#{a["WIDTH"]}'"
570
- a["WIDTH2"] = a["WIDTH"]
571
- else
572
- a["WIDTH1"] = " "
573
- a["WIDTH2"] = "1"
574
- end
575
-
576
- html.split(/\r*\n/).each do |line|
577
- if line =~ /%[A-Z0-9]+%/
578
- a.each do |k, v|
579
- v = false if (v.kind_of?(String) and v.empty?)
580
-
581
- if line.include?("%#{k}%")
582
- line.gsub!("%#{k}%", "#{v}") if v
583
- end
584
- end
585
-
586
- line = "<!-- #{line.scan(/%[A-Z0-9]+%/).join(" ")} -->" if line =~ /%[A-Z0-9]+%/
587
- end
588
-
589
- res << line
590
- end
591
-
592
- res.join("\n")
593
- end
594
- end
595
-
596
- class Text
597
- def prechildren(res, before, after, varshtml, varsstring, switches, help, oneormorefields, firstaction, tabs, tab, pda)
598
- if not @text.scan(/[^ \t\r\n]/).empty?
599
- res << Format % ["Text", ""] if $rwd_debug
600
- res << "#{@text}"
601
- end
602
- end
603
- end
604
-
605
- class RWDTree < XML
606
- end
607
-
608
- class RWDWindow
609
- @@windows = {} # Kind of caching.
610
- @@helpwindows = {} # Kind of caching.
611
-
612
- def initialize(rwd, window=nil)
613
- rwd = rwd.join("\n") if rwd.kind_of?(Array)
614
-
615
- if @@windows[rwd].nil?
616
- @@windows[rwd] = {}
617
- @@helpwindows[rwd] = {}
618
-
619
- tree = XML.new(rwd)
620
-
621
- tree.parse(OpenTag, "window") do |type, obj|
622
- @@windows[rwd][obj.args["name"]] = obj.to_h
623
- end
624
-
625
- tree.parse(OpenTag, "helpwindow") do |type, obj|
626
- @@helpwindows[rwd][obj.args["name"]] = obj.to_h
627
- end
628
- end
629
-
630
- @rwd = (@@windows[rwd][window] or "").dup
631
- @helprwd = (@@helpwindows[rwd][window] or "").dup
632
- end
633
-
634
- def render(pda, action=nil, vars=Hash.new, switches=Hash.new, help=false, tab="")
635
- varshtml = Hash.new
636
- varsstring = Hash.new
637
- oneormorefields = ""
638
- firstaction = ""
639
- html = []
640
-
641
- vars.each do |key, value|
642
- if not key.empty?
643
- if value.respond_to? "to_s"
644
- @rwd.gsub!(/%%#{key}%%/, value.to_s)
645
- @rwd.gsub!(/%#{key}%/, value.to_s.to_html)
646
-
647
- @helprwd.gsub!(/%%#{key}%%/, value.to_s)
648
- @helprwd.gsub!(/%#{key}%/, value.to_s.to_html)
649
-
650
- varshtml[key] = value.to_s.to_html
651
- varsstring[key] = value.to_s
652
- end
653
- end
654
- end
655
-
656
- windowobject = RWDTree.new(@rwd).children.dup.delete_if{|obj| obj.subtype != "window"}[0]
657
- helpobject = RWDTree.new(@helprwd).children.dup.delete_if{|obj| obj.subtype != "helpwindow"}[0]
658
-
659
- tabsobj = windowobject.children.dup.delete_if{|obj| obj.subtype != "tabs"}[0]
660
-
661
- if not tabsobj.nil?
662
- tabs = tabsobj.children.dup.delete_if{|obj| (not obj.kind_of?(OpenTag)) or (obj.subtype != "tab")}
663
-
664
- if tab.empty?
665
- tab = tabs[0].args["name"]
666
- end
667
-
668
- tabsobj.children.delete_if{|obj| (obj.kind_of?(OpenTag)) and (obj.subtype == "tab") and obj.args["name"] != tab}
669
- end
670
-
671
- if help
672
- helpobject.parsetree("prechildren", "postchildren", html, [""], [""], varshtml, varsstring, switches, false, oneormorefields, firstaction, tabs, tab, pda)
673
- else
674
- windowobject.parsetree("prechildren", "postchildren", html, [""], [""], varshtml, varsstring, switches, (not @helprwd.empty?), oneormorefields, firstaction, tabs, tab, pda)
675
- end
676
-
677
- html = html.join("") # ???
678
-
679
- html.gsub!(/%%*[[:alnum:]_\-]+%%*/, "") if not $rwd_debug
680
- html.gsub!(/%%/, "%")
681
- html.gsub!(/\n\n*/, "\n")
682
-
683
- if oneormorefields.empty?
684
- focus = ""
685
- else
686
- focus = "document.bodyform.elements[0].focus();"
687
- end
688
-
689
- firstaction = action if windowobject.args.keys.include?("refresh") unless action.nil?
690
-
691
- html.gsub!(/\$RWD_FIRSTACTION\$/ , firstaction)
692
- html.gsub!(/\$RWD_FOCUS\$/ , focus)
693
-
694
- html
695
- end
696
- end
697
-
698
- class RWDMessage < RWDWindow
699
- def initialize(msg)
700
- super("<window title='RWD Message' nobackbuttons noclosebutton><p>#{msg}</p><back/></window>")
701
- end
702
- end
703
-
704
- class RWDError < RWDWindow
705
- def initialize(msg)
706
- super("<window title='RWD Error' nobackbuttons noclosebutton><p><b>Error:</b> #{msg}</p><back/></window>")
707
- end
708
- end
709
-
710
- class RWDProgressBar < RWDWindow
711
- def initialize(refresh, progress)
712
- s = ""
713
- s << "<window title='RWD Progress' nobackbuttons noclosebutton refresh='#{refresh}'>"
714
- if progress.length == 1
715
- progress.each do |caption, value|
716
- s << "<p>#{caption}</p><progressbar value='#{value}'/><p>#{(100*value).to_i}%%</p>"
717
- end
718
- else
719
- s << "<table>"
720
- progress.each do |caption, value|
721
- s << "<row><p align='left'>#{caption}</p><progressbar value='#{value}'/><p align='right'>#{(100*value).to_i}%%</p></row>"
722
- end
723
- s << "</table>"
724
- end
725
- s << "<cancel/>"
726
- s << "</window>"
727
- super(s)
728
- end
729
- end
730
-
731
- class RWDDone < RWDWindow
732
- def initialize(exitbrowser)
733
- super("<window title='RWD Message' nobackbuttons noclosebutton><p>Done.</p><horizontal><close/>#{exitbrowser ? "" : "<button caption='Again'/>"}</horizontal>#{exitbrowser ? "<closewindow/>" : ""}</window>")
734
- end
735
- end
736
-
737
- class RWDialog
738
- def initialize(xml)
739
- @rwd_xml = xml
740
- @rwd_exitbrowser = false
741
- @rwd_history = []
742
- @rwd_ignore_vars = []
743
- @rwd_call_after_back = []
744
- end
745
-
746
- def self.file(rwdfile, *args)
747
- new(File.new(rwdfile).readlines, *args)
748
- end
749
-
750
- def serve(port=nil, auth=nil, realm=self.class.to_s)
751
- exit if $rwd_exit
752
-
753
- raise "RWD is not initialized." if @rwd_xml.nil?
754
-
755
- low, high = ENV["RWDPORTS"].split(/[^\d+]/)
756
- high = low if high.nil?
757
- low, high = low.to_i, high.to_i
758
-
759
- io = nil
760
-
761
- port, io = TCPServer.freeport(low, high, (not auth.nil?)) if port.nil?
762
- raise "No free TCP port." if port.nil?
763
-
764
- port = port.to_i
765
-
766
- @rwd_server = RWDServer.new(self, port, io, auth, realm)
767
- end
768
-
769
- def render(res, path, post, download, downloadfile, pda, sessionid)
770
-
771
- # Initialize some vars.
772
-
773
- vars = Hash.new if vars.nil?
774
- @rwd_switches = Hash.new if @rwd_switches.nil?
775
-
776
- done = false
777
- help = false
778
- back = false
779
- tab = ""
780
- @rwd_msgtype = nil
781
- @rwd_download = nil
782
- @rwd_download_file = nil
783
-
784
- # Switches are used for checkboxes.
785
-
786
- @rwd_switches.each do |key, value|
787
- vars[key] = "off"
788
- end
789
-
790
- @rwd_switches = Hash.new
791
-
792
- # Copy the vars from the window to vars. vars wil later on be copied to instance variables.
793
-
794
- post.sort.each do |key, value|
795
- puts "Post: #{key} -> #{value.from_html.inspect}" if $rwd_debug
796
-
797
- vars[key] = value.from_html
798
- end
799
-
800
- # Stack handling for rwd_action, rwd_window and rwd_tab.
801
-
802
- @rwd_action = vars["rwd_action"] if vars.include?("rwd_action")
803
- @rwd_action, @rwd_args = @rwd_action.split(/\//, 2) unless @rwd_action.nil?
804
- @rwd_action, rest = @rwd_action.split(/\?/) unless @rwd_action.nil?
805
-
806
- @rwd_refresh_action = (@rwd_action or @rwd_refresh_action or "main")
807
-
808
- unless rest.nil?
809
- rest.each do |s|
810
- k, v = s.split(/=/, 2)
811
- vars[k] = v
812
- end
813
- end
814
-
815
- if @rwd_action == "rwd_cancel"
816
- @rwd_progress_thread.kill unless @rwd_progress_thread.nil?
817
- @rwd_progress_thread = nil
818
- @rwd_action = "rwd_back"
819
- end
820
-
821
- if @rwd_action =~ /^rwd_tab_/
822
- @rwd_tab = @rwd_action.sub(/^rwd_tab_/, "")
823
- @rwd_history[-1][3] = @rwd_tab
824
- else
825
- case @rwd_action
826
- when "rwd_back"
827
- @rwd_history.pop
828
- @rwd_action = (@rwd_history[-1] or [nil, nil, nil])[0]
829
- @rwd_args = (@rwd_history[-1] or [nil, nil, nil])[1]
830
- @rwd_window = (@rwd_history[-1] or [nil, nil, nil])[2]
831
- @rwd_tab = (@rwd_history[-1] or [nil, nil, nil])[3]
832
- back = true
833
- when "rwd_help"
834
- help = true
835
- when "rwd_main"
836
- @rwd_action = nil
837
- @rwd_window = nil
838
- @rwd_tab = nil
839
- @rwd_history = []
840
- when "rwd_quit"
841
- done = true
842
- end
843
-
844
- # History stuff
845
-
846
- @rwd_history = @rwd_history[-100..-1] if @rwd_history.length >= 100
847
- @rwd_action = "main" if @rwd_action.nil?
848
- @rwd_action = "main" if @rwd_action.empty?
849
- @rwd_window = "main" if @rwd_window.nil?
850
- @rwd_window = "main" if @rwd_window.empty?
851
- @rwd_tab = "" if @rwd_tab.nil?
852
- @rwd_args = [] if @rwd_args.nil?
853
- @rwd_args = [] if @rwd_action == "main"
854
-
855
- vars["rwd_action"] = @rwd_action
856
- vars["rwd_window"] = @rwd_window
857
- vars["rwd_tab"] = @rwd_tab
858
-
859
- # Copy vars from window to instance.
860
-
861
- vars.each do |k, v|
862
- instance_eval "@#{k} = vars['#{k}']" if ((not k.empty?) and k.scan(/^rwd_/).empty? and not @rwd_ignore_vars.include?("@#{k}"))
863
- end
864
-
865
- # Callback.
866
-
867
- if (not back) or @rwd_call_after_back.include?(@rwd_action)
868
- unless @rwd_action =~ /^rwd_/
869
- puts "Method: #{@rwd_action}(#{@rwd_args.join(", ")})" if $rwd_debug
870
- if methods.include?(@rwd_action)
871
- method(@rwd_action).call(*@rwd_args)
872
- else
873
- puts "Method '%s' is not defined." % @rwd_action
874
- end
875
- end
876
-
877
- # History stuff
878
-
879
- @rwd_history = [["main", [], "main", ""]] if @rwd_action == "main"
880
- @rwd_history = [["main", [], "main", ""]] if @rwd_history.empty?
881
-
882
- a = [@rwd_action, @rwd_args, @rwd_window, @rwd_tab]
883
-
884
- @rwd_history.push a if (@rwd_history[-1] != a or not @rwd_msgtype.nil?)
885
- end
886
- end
887
-
888
- # Copy vars from instance to window.
889
-
890
- instance_variables.each do |k|
891
- k.sub!(/^@/, "")
892
- instance_eval "vars['#{k}'] = @#{k}.to_s" if (k.scan(/^rwd_/).empty? and not @rwd_ignore_vars.include?("@#{k}"))
893
- end
894
-
895
- # just ignore.
896
-
897
- vars.sort.each do |key, value|
898
- puts "Pre: #{key} -> #{value.inspect}" if $rwd_debug
899
- end
900
-
901
-
902
- # Answer to browser.
903
-
904
- if done
905
- res << RWDDone.new(@rwd_exitbrowser).render(pda)
906
- else
907
- if not @rwd_download.nil?
908
- puts "Download: #{@rwd_window}" if $rwd_debug
909
-
910
- download << @rwd_download
911
- downloadfile << @rwd_download_file
912
- else
913
- if not @rwd_msgtype.nil?
914
- res << RWDMessage.new(@rwd_msg).render(pda) if @rwd_msgtype == "message"
915
- res << RWDError.new(@rwd_msg).render(pda) if @rwd_msgtype == "error"
916
- else
917
- if not @rwd_progress_thread.nil?
918
- res << RWDProgressBar.new(@rwd_progress_refresh, @rwd_progress_progress).render(pda, @rwd_refresh_action)
919
- else
920
- puts "Window: #{@rwd_window}" if $rwd_debug
921
- puts "Tab: #{@rwd_tab}" if $rwd_debug
922
-
923
- res << RWDWindow.new(@rwd_xml, @rwd_window).render(pda, @rwd_refresh_action, vars, @rwd_switches, help, @rwd_tab)
924
- end
925
- end
926
- end
927
- end
928
-
929
- return done
930
- end
931
-
932
- def samewindow?
933
- @rwd_history[-1][2] == @rwd_window
934
- end
935
-
936
- def message(msg, &block)
937
- @rwd_msg = msg
938
- @rwd_msgtype = "message"
939
- end
940
-
941
- def error(msg, &block)
942
- @rwd_msg = msg
943
- @rwd_msgtype = "error"
944
- end
945
-
946
- def progressbar(refresh, *progress)
947
- @rwd_progress_refresh = (refresh or 1)
948
- @rwd_progress_progress = []
949
-
950
- while not progress.empty?
951
- s = (progress.shift or "")
952
- if s.kind_of?(Array)
953
- caption, value = s
954
- value = (value or 0.0).to_f
955
- else
956
- caption = s
957
- value = (progress.shift or 0.0).to_f
958
- end
959
-
960
- @rwd_progress_progress << [caption, value]
961
- end
962
-
963
- if @rwd_progress_thread.nil?
964
- @rwd_progress_progress.each do |a|
965
- a[1] = 0.0
966
- end
967
-
968
- @rwd_progress_thread =
969
- Thread.new do
970
- yield
971
- end
972
- Thread.pass
973
- end
974
-
975
- @rwd_progress_thread = nil unless @rwd_progress_thread.alive?
976
- end
977
-
978
- def download(data, filename="")
979
- @rwd_download = data
980
- @rwd_download_file = filename
981
- end
982
-
983
- def exitbrowser
984
- @rwd_exitbrowser = true
985
- end
986
- end
987
-
988
- class RWDLogin < RWDialog
989
- def initialize(realm)
990
- super("<window name='main' title='RWD Login for #{realm}' nobackbuttons noclosebutton><table><row><p align='right'>Username:</p><text name='rwd_a'/></row><row><p align='right'>Password:</p><password name='rwd_b'/></row></table><button caption='Login'/></window>")
991
- end
992
- end
993
-
994
- class RWDTimeOut < RWDialog
995
- def initialize
996
- super("<window name='main' title='RWD Error' nobackbuttons noclosebutton><p><b>Error:</b> Session has expired.</p><button caption='New session'/></window>")
997
- end
998
- end
999
-
1000
- class SessionCleanup
1001
- def initialize(sessions, interval, timeout)
1002
- every(interval) do
1003
- sessions.delete_if do |id, session|
1004
- time = Time.now.to_i - session.lastaccess.to_i
1005
-
1006
- puts "Session %s deleted" % id if time > timeout
1007
-
1008
- time > timeout
1009
- end
1010
- end
1011
- end
1012
- end
1013
-
1014
- class Sessions
1015
- def initialize(rack, cleanup)
1016
- @rack = rack.to_s
1017
- @cleanup = SessionCleanup.new(self, 3600, 24*3600) if cleanup
1018
- @sessions = {}
1019
- end
1020
-
1021
- def [](sessionid)
1022
- @sessions[sessionid]
1023
- end
1024
-
1025
- def []=(sessionid, value)
1026
- @sessions[sessionid] = value
1027
- end
1028
-
1029
- def delete(sessionid)
1030
- @sessions.delete(sessionid)
1031
- end
1032
-
1033
- def delete_if(&block)
1034
- @sessions.delete_if{|k, v| block.call(k, v)}
1035
- end
1036
-
1037
- def include?(sessionid)
1038
- @sessions.include?(sessionid)
1039
- end
1040
- end
1041
-
1042
- class Session < Hash
1043
- attr_reader :sessionid
1044
- attr_reader :lastaccess
1045
- attr_reader :authenticated
1046
- attr_writer :authenticated
1047
-
1048
- def initialize(sessionid=nil)
1049
- @sessionid = sessionid
1050
- @lastaccess = Time.now
1051
- @authenticated = false
1052
- end
1053
-
1054
- def touch
1055
- @lastaccess = Time.now
1056
- end
1057
- end
1058
-
1059
- class RWDSession < Session
1060
- def render(res, path, post, download, downloadfile, pda)
1061
- done = self["object"].render(res, path, post, download, downloadfile, pda, @sessionid)
1062
-
1063
- res.gsub!(/\$RWD_SESSION\$/, done ? "" : "#{@sessionid}")
1064
-
1065
- return done
1066
- end
1067
- end
1068
-
1069
- class RWDServer
1070
- def initialize(obj, port, io, auth, realm)
1071
- @object = obj
1072
- @localbrowsing = false
1073
- @browserstarted = false
1074
- @sessions = Sessions.new(obj.class, (not auth.nil?))
1075
-
1076
- if auth.nil?
1077
- @localbrowsing = true
1078
-
1079
- if ENV.include?("RWDBROWSER") and not ENV["RWDBROWSER"].nil? and not ENV["RWDBROWSER"].empty?
1080
- @browserstarted = true
1081
- @object.exitbrowser
1082
-
1083
- # Start browser.
1084
-
1085
- @browserthread =
1086
- Thread.new do
1087
- puts "Starting the browser..."
1088
-
1089
- #if ENV["RWDBROWSER"].downcase =~ /iexplore/ # ???
1090
- #@ie = IE.new("http://localhost:#{port}/")
1091
- #else
1092
- browser = ENV["RWDBROWSER"].dup
1093
- url = "http://localhost:%s/" % [port]
1094
-
1095
- if cygwin?
1096
- browser.gsub!(/\\/, "/")
1097
- browser.gsub!(/ /, "\\ ")
1098
- end
1099
-
1100
- re = /[$%]1\b/
1101
- command = "%s \"%s\"" % [browser, url]
1102
- command = browser.gsub(re, url) if browser =~ re
1103
-
1104
- command.gsub!(/%port%/, port.to_s)
1105
-
1106
- system(command) or puts "Starting of the browser failed, or the browser terminated abnormally.\nCommand => #{command}"
1107
- #end
1108
-
1109
- puts "The browser has terminated."
1110
- end
1111
- end
1112
- end
1113
-
1114
- # Start server.
1115
-
1116
- portio = port
1117
- portio = [port, io] unless io.nil?
1118
- threadlimiter = ThreadLimiter.new(1)
1119
-
1120
- HTTPServer.serve(portio, (not auth.nil?)) do |req, resp|
1121
- threadlimiter.wait do
1122
-
1123
- vars = req.vars.dup
1124
- pad = (req.request.path or "/")
1125
-
1126
- if auth.kind_of? String
1127
- file = "#{home}/#{auth}"
1128
- auths = {}
1129
- auths = Hash.file(file) if File.file?(file)
1130
- else
1131
- auths = auth
1132
- end
1133
-
1134
- #oldsessionid = vars["rwd_session"]
1135
- oldsessionid = req.cookies["sessionid"]
1136
-
1137
- # Retrieve session.
1138
-
1139
- session = @sessions[oldsessionid]
1140
-
1141
- # Eventually create new session.
1142
-
1143
- if session.nil?
1144
- sessionid = MD5.new(req.peeraddr[3].to_s + @object.inspect.to_s + ("%1.6f" % Time.now.to_f)).to_s while (sessionid == nil or @sessions.include?(sessionid))
1145
- session = RWDSession.new(sessionid)
1146
-
1147
- if auth.nil?
1148
- session["object"] = @object
1149
- else
1150
- session["object"] = @object.clone
1151
- end
1152
-
1153
- if oldsessionid.nil? or oldsessionid.empty?
1154
- if not auth.nil? and not auth.empty? and not session.authenticated and pad != "/rwd_pixel.gif"
1155
-
1156
- # Check authentication
1157
-
1158
- us = vars["rwd_a"]
1159
- pa = vars["rwd_b"]
1160
-
1161
- if us.nil? or pa.nil? or auths[us] != pa
1162
- session = RWDSession.new
1163
- session["object"] = RWDLogin.new(realm)
1164
- pad = "/"
1165
- else
1166
- session.authenticated = true
1167
- @sessions[session.sessionid] = session
1168
- end
1169
- else
1170
- session.authenticated = true
1171
- @sessions[session.sessionid] = session
1172
- end
1173
- else
1174
- session = RWDSession.new
1175
- session["object"] = RWDTimeOut.new
1176
- end
1177
-
1178
- vars = {}
1179
- end
1180
-
1181
- # Avoid timeout.
1182
-
1183
- session.touch
1184
-
1185
- if pad == "/"
1186
-
1187
- # Serve methods/callbacks.
1188
-
1189
- # Build new page.
1190
-
1191
- download = ""
1192
- downloadfile = ""
1193
- res = ""
1194
-
1195
- done = session.render(res, pad, vars, download, downloadfile, req.pda?)
1196
-
1197
- begin
1198
- if download.empty?
1199
- resp["Content-Type"] = "text/html"
1200
- if done
1201
- resp.cookies["sessionid"] = ""
1202
- else
1203
- resp.cookies["sessionid"] = session.sessionid
1204
- end
1205
-
1206
- resp << res
1207
- else
1208
- resp["Content-Type"] = "application/octet-stream"
1209
- resp["Content-Disposition"] = "attachment;"
1210
- resp["Content-Disposition"] = "attachment; filename=%s" % downloadfile unless downloadfile.empty?
1211
-
1212
- resp << download
1213
- end
1214
- rescue
1215
- puts "Sending response to browser failed."
1216
-
1217
- @sessions.delete(session.sessionid)
1218
- end
1219
-
1220
- # Eventually delete this session.
1221
-
1222
- if done
1223
- @sessions.delete(session.sessionid)
1224
-
1225
- if @localbrowsing
1226
- resp.stop
1227
-
1228
- if @browserstarted and not @browserthread.nil? and @browserthread.alive?
1229
- resp.stop do
1230
- puts "Waiting for the browser to terminate..."
1231
-
1232
- @browserthread.join
1233
- end
1234
- end
1235
- end
1236
- end
1237
-
1238
- else
1239
-
1240
- # Serve files.
1241
-
1242
- if pad == "/rwd_pixel.gif"
1243
- resp["Cache-Control"] = "max-age=86400"
1244
- resp["Content-Type"] = "image/gif"
1245
- resp << $rwd_pixel
1246
- else
1247
- if session.authenticated
1248
- pwd = Dir.pwd
1249
- file = File.expand_path(pad.gsub(/^\/*/, ""), $rwd_files)
1250
-
1251
- if not file.index(pwd) == 0
1252
- resp["Content-Type"] = "text/html"
1253
- resp.response = "HTTP/1.0 400 BAD REQUEST"
1254
- resp << "<html><body><p><b>Bad Request.</b> (<tt>#{pad}</tt>)</p></body></html>"
1255
- elsif File.file?(file)
1256
- resp << File.new(file, "rb").read rescue nil
1257
- else
1258
- resp["Content-Type"] = "text/html"
1259
- resp.response = "HTTP/1.0 404 NOT FOUND"
1260
- resp << "<html><body><p><b>Not found.</b> (<tt>#{pad}</tt>)</p></body></html>"
1261
- end
1262
- else
1263
- resp["Content-Type"] = "text/html"
1264
- resp.response = "HTTP/1.0 ??? NOT AUTHORIZED"
1265
- resp << "<html><body><p><b>Not Authorized.</b></p></body></html>"
1266
- end
1267
- end
1268
-
1269
- end
1270
-
1271
- end
1272
- end
1273
- end
1274
- end
1275
-
1276
- $rwd_html["DEFAULT"] = "
1277
- <!-- Generated by RubyWebDialog. -->
1278
- <!-- For more information, please contact Erik Veenstra <rwd@erikveen.dds.nl>. -->
1279
- <html>
1280
- <head>
1281
- <title>%TITLE%</title>
1282
-
1283
- <meta http-equiv='Content-Type' content='text/html; charset=%CHARSET%'>
1284
- <meta http-equiv='Content-Style-Type' content='text/css'>
1285
- <meta http-equiv='Refresh' content='%REFRESH%, javascript:document.bodyform.submit();'>
1286
-
1287
- <link rel='shortcut icon' href='%LOGO%'>
1288
-
1289
- <style type='text/css'>
1290
- <!--
1291
-
1292
- a {
1293
- text-decoration : none;
1294
- }
1295
-
1296
- a:hover {
1297
- background : #AAAAAA;
1298
- }
1299
-
1300
- td.panel1 {
1301
- border-color : #888888 #EEEEEE #EEEEEE #888888;
1302
- border-width : 1pt;
1303
- border-style : solid solid solid solid;
1304
- }
1305
-
1306
- td.panel2 {
1307
- border-color : #EEEEEE #888888 #888888 #EEEEEE;
1308
- border-width : 1pt;
1309
- border-style : solid solid solid solid;
1310
- }
1311
-
1312
- td.panel1high {
1313
- border-color : #EEEEEE #888888 #888888 #EEEEEE;
1314
- border-width : 1pt;
1315
- border-style : solid solid solid solid;
1316
- }
1317
-
1318
- td.panel2high {
1319
- border-color : #EEEEEE #888888 #888888 #EEEEEE;
1320
- border-width : 1pt;
1321
- border-style : none none none none;
1322
- }
1323
-
1324
- td.panel1low {
1325
- border-color : #888888 #EEEEEE #EEEEEE #888888;
1326
- border-width : 1pt;
1327
- border-style : solid solid solid solid;
1328
- }
1329
-
1330
- td.panel2low {
1331
- border-color : #888888 #EEEEEE #EEEEEE #888888;
1332
- border-width : 1pt;
1333
- border-style : none none none none;
1334
- }
1335
-
1336
- td.tabblad {
1337
- border-color : #EEEEEE #888888 #888888 #EEEEEE;
1338
- border-width : 1pt;
1339
- border-style : none solid solid solid;
1340
- }
1341
-
1342
- td.passivetab {
1343
- background-color : #BBBBBB;
1344
- border-color : #DDDDDD #DDDDDD #EEEEEE #DDDDDD;
1345
- border-width : 1pt;
1346
- border-style : solid solid solid solid;
1347
- }
1348
-
1349
- td.activetab {
1350
- border-color : #EEEEEE #888888 #888888 #EEEEEE;
1351
- border-width : 1pt;
1352
- border-style : solid solid none solid;
1353
- }
1354
-
1355
- td.notab {
1356
- border-color : #EEEEEE #EEEEEE #EEEEEE #EEEEEE;
1357
- border-width : 1pt;
1358
- border-style : none none solid none;
1359
- }
1360
-
1361
- //-->
1362
- </style>
1363
-
1364
- <script type='text/javascript'>
1365
- <!--
1366
- function BodyGo() {
1367
- $RWD_FOCUS$
1368
- }
1369
- //-->
1370
- </script>
1371
- </head>
1372
-
1373
- <body bgcolor='white' onload='BodyGo()' link='#000000' vlink='#000000' alink='#000000'>
1374
- <form name='bodyform' action='/' method='post'>
1375
- <table align='center' border='0' cellspacing='0' cellpadding='0' width='100%' height='100%'>
1376
- <tr align='center' valign='middle'>
1377
- <td align='center'>
1378
-
1379
- <table align='center' border='0' cellspacing='0' cellpadding='0'>
1380
-
1381
- <tr align='center'>
1382
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1383
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1384
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1385
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1386
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1387
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1388
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1389
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1390
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1391
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1392
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1393
- </tr>
1394
-
1395
- <tr align='center'>
1396
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1397
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1398
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1399
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1400
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1401
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1402
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1403
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1404
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1405
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1406
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1407
- </tr>
1408
-
1409
- <tr align='center'>
1410
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1411
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1412
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1413
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1414
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1415
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1416
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1417
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1418
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1419
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1420
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1421
- </tr>
1422
-
1423
- <tr align='center'>
1424
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1425
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1426
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1427
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1428
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1429
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1430
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1431
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1432
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1433
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1434
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1435
- </tr>
1436
-
1437
- <tr align='center'>
1438
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1439
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1440
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1441
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1442
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1443
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1444
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1445
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1446
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1447
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1448
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1449
- </tr>
1450
-
1451
- <tr align='center'>
1452
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1453
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1454
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1455
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1456
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1457
-
1458
- <td align='center'>
1459
-
1460
- <table align='center' border='0' cellspacing='0' cellpadding='0' %WIDTH1%>
1461
- <tr align='center'>
1462
- <td align='center' bgcolor='#444488'>
1463
-
1464
- <table align='left' border='0' cellspacing='1' cellpadding='0'>
1465
- <tr align='center'>
1466
- <td align='border'><img src='%LOGO%' width='14' height='14'></td>
1467
- <td align='center'><b><small><font color='#FFFFFF'>&nbsp;%TITLE%&nbsp;</font></small></b></td>
1468
- </tr>
1469
- </table>
1470
-
1471
- <table align='right' border='0' cellspacing='1' cellpadding='0'>
1472
- <tr align='center'>
1473
- <!-- %HELPBUTTON% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_help\";document.bodyform.submit();'>&nbsp;?&nbsp;</a></small></b></td>
1474
- <!-- %BACKBUTTONS% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_main\";document.bodyform.submit();'>&nbsp;&lt;&lt;&nbsp;</a></small></b></td>
1475
- <!-- %BACKBUTTONS% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_back\";document.bodyform.submit();'>&nbsp;&lt;&nbsp;</a></small></b></td>
1476
- <!-- %CLOSEBUTTON% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_quit\";document.bodyform.submit();'>&nbsp;X&nbsp;</a></small></b></td>
1477
- </tr>
1478
- </table>
1479
-
1480
- </td>
1481
- </tr>
1482
-
1483
- <tr align='center'>
1484
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='%WIDTH2%'></td>
1485
- </tr>
1486
-
1487
- <tr align='center'>
1488
- <td align='center' bgcolor='#CCCCCC'>
1489
- <table align='center' border='0' cellspacing='3' cellpadding='0'>
1490
- %BODY%
1491
- </table>
1492
-
1493
- <input name='rwd_action' value='$RWD_FIRSTACTION$' type='hidden'>
1494
- <input name='rwd_session' value='$RWD_SESSION$' type='hidden'>
1495
- </td>
1496
- </tr>
1497
- </table>
1498
-
1499
- </td>
1500
-
1501
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1502
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1503
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1504
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1505
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1506
- </tr>
1507
-
1508
- <tr align='center'>
1509
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1510
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1511
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1512
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1513
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1514
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1515
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1516
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1517
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1518
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1519
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1520
- </tr>
1521
-
1522
- <tr align='center'>
1523
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1524
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1525
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1526
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1527
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1528
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1529
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1530
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1531
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1532
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1533
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1534
- </tr>
1535
-
1536
- <tr align='center'>
1537
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1538
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1539
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1540
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1541
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1542
- <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1543
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1544
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1545
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1546
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1547
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1548
- </tr>
1549
-
1550
- <tr align='center'>
1551
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1552
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1553
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1554
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1555
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1556
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1557
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1558
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1559
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1560
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1561
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1562
- </tr>
1563
-
1564
- <tr align='center'>
1565
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1566
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1567
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1568
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1569
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1570
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1571
- <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1572
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1573
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1574
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1575
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1576
- </tr>
1577
-
1578
- </table>
1579
-
1580
- </td>
1581
- </tr>
1582
- </table>
1583
- </form>
1584
- </body>
1585
- </html>
1586
- "
1587
-
1588
- $rwd_html["WINDOWSLOOKALIKE"] = "
1589
- <!-- Generated by RubyWebDialog. -->
1590
- <!-- For more information, please contact Erik Veenstra <rwd@erikveen.dds.nl>. -->
1591
- <html>
1592
- <head>
1593
- <title>%TITLE%</title>
1594
-
1595
- <meta http-equiv='Content-Type' content='text/html; charset=%CHARSET%'>
1596
- <meta http-equiv='Content-Style-Type' content='text/css'>
1597
- <meta http-equiv='Refresh' content='%REFRESH%, javascript:document.bodyform.submit();'>
1598
-
1599
- <link rel='shortcut icon' href='%LOGO%'>
1600
-
1601
- <style type='text/css'>
1602
- <!--
1603
-
1604
- a {
1605
- text-decoration : none;
1606
- }
1607
-
1608
- a:hover {
1609
- background : #AAAAAA;
1610
- }
1611
-
1612
- td.window {
1613
- border-color : #EEEEEE #888888 #888888 #EEEEEE;
1614
- border-width : 3pt;
1615
- border-style : solid solid solid solid;
1616
- }
1617
-
1618
- td.panel1 {
1619
- border-color : #888888 #EEEEEE #EEEEEE #888888;
1620
- border-width : 1pt;
1621
- border-style : solid solid solid solid;
1622
- }
1623
-
1624
- td.panel2 {
1625
- border-color : #EEEEEE #888888 #888888 #EEEEEE;
1626
- border-width : 1pt;
1627
- border-style : solid solid solid solid;
1628
- }
1629
-
1630
- td.panel1high {
1631
- border-color : #EEEEEE #888888 #888888 #EEEEEE;
1632
- border-width : 1pt;
1633
- border-style : solid solid solid solid;
1634
- }
1635
-
1636
- td.panel2high {
1637
- border-color : #EEEEEE #888888 #888888 #EEEEEE;
1638
- border-width : 1pt;
1639
- border-style : none none none none;
1640
- }
1641
-
1642
- td.panel1low {
1643
- border-color : #888888 #EEEEEE #EEEEEE #888888;
1644
- border-width : 1pt;
1645
- border-style : solid solid solid solid;
1646
- }
1647
-
1648
- td.panel2low {
1649
- border-color : #888888 #EEEEEE #EEEEEE #888888;
1650
- border-width : 1pt;
1651
- border-style : none none none none;
1652
- }
1653
-
1654
- td.tabblad {
1655
- border-color : #EEEEEE #888888 #888888 #EEEEEE;
1656
- border-width : 1pt;
1657
- border-style : none solid solid solid;
1658
- }
1659
-
1660
- td.passivetab {
1661
- background-color : #BBBBBB;
1662
- border-color : #DDDDDD #DDDDDD #EEEEEE #DDDDDD;
1663
- border-width : 1pt;
1664
- border-style : solid solid solid solid;
1665
- }
1666
-
1667
- td.activetab {
1668
- border-color : #EEEEEE #888888 #888888 #EEEEEE;
1669
- border-width : 1pt;
1670
- border-style : solid solid none solid;
1671
- }
1672
-
1673
- td.notab {
1674
- border-color : #EEEEEE #EEEEEE #EEEEEE #EEEEEE;
1675
- border-width : 1pt;
1676
- border-style : none none solid none;
1677
- }
1678
-
1679
- //-->
1680
- </style>
1681
-
1682
- <script type='text/javascript'>
1683
- <!--
1684
- function BodyGo() {
1685
- $RWD_FOCUS$
1686
- }
1687
- //-->
1688
- </script>
1689
- </head>
1690
-
1691
- <body bgcolor='white' onload='BodyGo()' link='#000000' vlink='#000000' alink='#000000'>
1692
- <form name='bodyform' action='/' method='post'>
1693
- <table align='center' border='0' cellspacing='0' cellpadding='0' width='100%' height='100%'>
1694
- <tr align='center' valign='middle'>
1695
- <td align='center'>
1696
-
1697
- <table align='center' border='0' cellspacing='0' cellpadding='0'>
1698
-
1699
- <tr align='center'>
1700
- <td align='center' class='window'>
1701
-
1702
- <table align='center' border='0' cellspacing='0' cellpadding='0' %WIDTH1%>
1703
- <tr align='center'>
1704
- <td align='center' bgcolor='#444488'>
1705
-
1706
- <table align='left' border='0' cellspacing='1' cellpadding='0'>
1707
- <tr align='center'>
1708
- <td align='border'><img src='%LOGO%' width='14' height='14'></td>
1709
- <td align='center'><b><small><font color='#FFFFFF'>&nbsp;%TITLE%&nbsp;</font></small></b></td>
1710
- </tr>
1711
- </table>
1712
-
1713
- <table align='right' border='0' cellspacing='1' cellpadding='0'>
1714
- <tr align='center'>
1715
- <!-- %HELPBUTTON% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_help\";document.bodyform.submit();'>&nbsp;?&nbsp;</a></small></b></td>
1716
- <!-- %BACKBUTTONS% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_main\";document.bodyform.submit();'>&nbsp;&lt;&lt;&nbsp;</a></small></b></td>
1717
- <!-- %BACKBUTTONS% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_back\";document.bodyform.submit();'>&nbsp;&lt;&nbsp;</a></small></b></td>
1718
- <!-- %CLOSEBUTTON% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_quit\";document.bodyform.submit();'>&nbsp;X&nbsp;</a></small></b></td>
1719
- </tr>
1720
- </table>
1721
-
1722
- </td>
1723
- </tr>
1724
-
1725
- <tr align='center'>
1726
- <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='%WIDTH2%'></td>
1727
- </tr>
1728
-
1729
- <tr align='center'>
1730
- <td align='center' bgcolor='#CCCCCC'>
1731
- <table align='center' border='0' cellspacing='3' cellpadding='0'>
1732
- %BODY%
1733
- </table>
1734
-
1735
- <input name='rwd_action' value='$RWD_FIRSTACTION$' type='hidden'>
1736
- <input name='rwd_session' value='$RWD_SESSION$' type='hidden'>
1737
- </td>
1738
- </tr>
1739
- </table>
1740
-
1741
- </td>
1742
- </tr>
1743
-
1744
- </table>
1745
-
1746
- </td>
1747
- </tr>
1748
- </table>
1749
- </form>
1750
- </body>
1751
- </html>
1752
- "
1753
-
1754
- $rwd_html["PDA"] = "
1755
- <!-- Generated by RubyWebDialog. -->
1756
- <!-- For more information, please contact Erik Veenstra <rwd@erikveen.dds.nl>. -->
1757
- <html>
1758
- <head>
1759
- <title>%TITLE%</title>
1760
-
1761
- <meta http-equiv='Content-Type' content='text/html; charset=%CHARSET%'>
1762
- <meta http-equiv='Refresh' content='%REFRESH%, javascript:document.bodyform.submit();'>
1763
-
1764
- <link rel='shortcut icon' href='%LOGO%'>
1765
-
1766
- <script type='text/javascript'>
1767
- <!--
1768
- function BodyGo() {
1769
- $RWD_FOCUS$
1770
- }
1771
- //-->
1772
- </script>
1773
- </head>
1774
-
1775
- <body bgcolor='white' onload='BodyGo()' link='#000000' vlink='#000000' alink='#000000'>
1776
- <form name='bodyform' action='/' method='post'>
1777
- <table align='center' border='0' cellspacing='0' cellpadding='0' width='100%' height='100%'>
1778
-
1779
- <tr align='center'>
1780
- <td align='center' bgcolor='#444488'>
1781
-
1782
- <table align='left' border='0' cellspacing='1' cellpadding='0'>
1783
- <tr align='center'>
1784
- <td align='border'><img src='%LOGO%' width='14' height='14'></td>
1785
- <td align='center'><b><small><font color='#FFFFFF'>&nbsp;%TITLE%&nbsp;</font></small></b></td>
1786
- </tr>
1787
- </table>
1788
-
1789
- <table align='right' border='0' cellspacing='1' cellpadding='0'>
1790
- <tr align='center'>
1791
- <!-- %HELPBUTTON% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_help\";document.bodyform.submit();'>&nbsp;?&nbsp;</a></small></b></td>
1792
- <!-- %BACKBUTTONS% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_main\";document.bodyform.submit();'>&nbsp;&lt;&lt;&nbsp;</a></small></b></td>
1793
- <!-- %BACKBUTTONS% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_back\";document.bodyform.submit();'>&nbsp;&lt;&nbsp;</a></small></b></td>
1794
- <!-- %CLOSEBUTTON% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_quit\";document.bodyform.submit();'>&nbsp;X&nbsp;</a></small></b></td>
1795
- </tr>
1796
- </table>
1797
-
1798
- </td>
1799
- </tr>
1800
-
1801
- <!--
1802
- <tr align='center'>
1803
- <td align='center' bgcolor='#FFFFFF'>&nbsp;</td>
1804
- </tr>
1805
- -->
1806
-
1807
- <tr align='center'>
1808
- <td align='center' bgcolor='#FFFFFF'>
1809
-
1810
- <table align='center' border='0' cellspacing='0' cellpadding='0'>
1811
- %BODY%
1812
- </table>
1813
-
1814
- <input name='rwd_action' value='$RWD_FIRSTACTION$' type='hidden'>
1815
- <input name='rwd_session' value='$RWD_SESSION$' type='hidden'>
1816
- </td>
1817
- </tr>
1818
-
1819
- </table>
1820
- </form>
1821
- </body>
1822
- </html>
1823
- "
1824
-
1825
- $rwd_pixel = "
1826
- R0lGODlhAQABAOcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoK
1827
- CgsLCwwMDA0NDQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZ
1828
- GRoaGhsbGxwcHB0dHR4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygo
1829
- KCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0NDU1NTY2Njc3
1830
- Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZG
1831
- RkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVV
1832
- VVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2Rk
1833
- ZGVlZWZmZmdnZ2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNz
1834
- c3R0dHV1dXZ2dnd3d3h4eHl5eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKC
1835
- goODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouLi4yMjI2NjY6Ojo+Pj5CQkJGR
1836
- kZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2dnZ6enp+fn6Cg
1837
- oKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+v
1838
- r7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+
1839
- vr+/v8DAwMHBwcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3N
1840
- zc7Ozs/Pz9DQ0NHR0dLS0tPT09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc
1841
- 3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6erq6uvr
1842
- 6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pn5+fr6
1843
- +vv7+/z8/P39/f7+/v///yH+FUNyZWF0ZWQgd2l0aCBUaGUgR0lNUAAh+QQB
1844
- CgD/ACwAAAAAAQABAAAIBAD/BQQAOw==
1845
- ".unpack("m").shift
1846
-
1847
- $rwd_html_1, $rwd_html_2 = $rwd_html[ENV["RWDTHEME"]].split(/^\s*%BODY%\s*\r*$/)
1848
- $rwd_html_PDA_1, $rwd_html_PDA_2 = $rwd_html["PDA"].split(/^\s*%BODY%\s*\r*$/)
1
+ require "ev/ruby"
2
+ require "ev/xml"
3
+ require "ev/net"
4
+ require "ev/browser"
5
+ require "ev/thread"
6
+ require "md5"
7
+ require "rbconfig"
8
+
9
+ begin
10
+ require "win32ole"
11
+ require "win32/registry"
12
+ rescue LoadError
13
+ $".push "win32ole.so"
14
+ $".push "win32/registry.rb"
15
+ end
16
+
17
+ $rwd_exit = ARGV.include?("--rwd-exit") # Hack ???
18
+ $rwd_debug = ($rwd_debug or $DEBUG or false)
19
+ $rwd_border = ($rwd_border or 0)
20
+ $rwd_dir = Dir.pwd
21
+ $rwd_files = File.expand_path("rwd_files", Dir.pwd)
22
+ $rwd_html = {}
23
+
24
+ ARGV.delete_if do |arg|
25
+ arg =~ /^--rwd-/
26
+ end
27
+
28
+ RWDEmptyline = "..."
29
+
30
+ rcfile = nil
31
+ s = ENV["HOME"] ; s = s + "/.rwdrc" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil? and File.file?(s))
32
+ s = ENV["USERPROFILE"] ; s = s + "/rwd.cfg" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil? and File.file?(s))
33
+ s = ENV["windir"] ; s = s + "/rwd.cfg" if not s.nil? ; rcfile = s if (not s.nil? and rcfile.nil? and File.file?(s))
34
+
35
+ AL = "align='left'"
36
+ AC = "align='center'"
37
+ AR = "align='right'"
38
+ VA = "valign='middle'"
39
+
40
+ Format = "\n<!-- %-10s %-10s -->\t"
41
+
42
+ unless rcfile.nil?
43
+ puts "Reading #{rcfile} ..."
44
+
45
+ Hash.file(rcfile).each do |k, v|
46
+ ENV[k] = v unless ENV.include?(k)
47
+ end
48
+ end
49
+
50
+ ENV["RWDBROWSER"] = (ENV["RWDBROWSER"] or defaultbrowser) or puts "No browser found."
51
+ ENV["RWDPORTS"] = (ENV["RWDPORTS"] or "7701-7709")
52
+ ENV["RWDTHEME"] = (ENV["RWDTHEME"] or "DEFAULT")
53
+
54
+ trap("INT") {puts "Terminating..." ; exit}
55
+
56
+ $SAFE = 2
57
+
58
+ class IE
59
+ def initialize(url)
60
+ @ie = WIN32OLE.new("InternetExplorer.Application")
61
+ @ev = WIN32OLE_EVENT.new(@ie, "DWebBrowserEvents2")
62
+
63
+ @ie.navigate(url)
64
+
65
+ @ie.menubar = false
66
+ @ie.toolbar = false
67
+ @ie.addressbar = false
68
+ @ie.statusbar = false
69
+
70
+ @ie.visible = true
71
+
72
+ at_exit do
73
+ @ie.visible = false
74
+ end
75
+
76
+ @ev.on_event("OnQuit") do
77
+ Thread.main.exit
78
+ end
79
+
80
+ Thread.new do
81
+ loop do
82
+ WIN32OLE_EVENT.message_loop
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ class Array
89
+ def rwd_options(emptyline=nil)
90
+ if emptyline.nil?
91
+ a = self
92
+ else
93
+ a = [emptyline].concat(self)
94
+ end
95
+
96
+ a.numsort.collect{|s| "<option>#{s.to_html}</option>" }.join("\n")
97
+ end
98
+
99
+ def rwd_method(method)
100
+ res = ""
101
+
102
+ self.each do |s|
103
+ s = s.join("/") if s.kind_of?(Array)
104
+ s2 = s.dup
105
+ s2[0..0] = s2[0..0].upcase
106
+ res = res + "<p align='left'><a action='#{method}/#{s.to_html}'>#{s2.to_html}</a></p>"
107
+ end
108
+
109
+ return res
110
+ end
111
+
112
+ def rwd_row(key=nil, value=nil)
113
+ res = ""
114
+
115
+ res = res + "<row valign='top'>"
116
+ res = res + "<radio name='#{key.to_html}' value='#{value.to_html}'/>" unless key.nil?
117
+ res = res + self.collect{|s| "<p align='left'>#{s.to_html}</p>"}.join("")
118
+ res = res + "</row>"
119
+
120
+ return res
121
+ end
122
+
123
+ def rwd_headers(emptyfield=false)
124
+ res = ""
125
+
126
+ res = res + "<row>"
127
+ res = res + "<p/>" if emptyfield
128
+ res = res + self.collect{|s| "<p align='left'><b>#{s.to_html}</b></p>" }.join("")
129
+ res = res + "</row>"
130
+
131
+ return res
132
+ end
133
+
134
+ def rwd_form(prefix, values, twoparts=0, options={})
135
+ res = []
136
+
137
+ res << "<table>"
138
+ self.each_index do |n|
139
+ name = "#{prefix.to_html}#{self[n].downcase.to_html}"
140
+
141
+ res << "<row>"
142
+ res << "<p align='right'>"
143
+ res << "#{self[n].to_html}:"
144
+ res << "</p>"
145
+
146
+ if options.keys.include?(self[n])
147
+ res << "<select name='#{name}'>"
148
+ res << options[self[n]].rwd_options(RWDEmptyline)
149
+ res << "</select>"
150
+ else
151
+ s = ""
152
+
153
+ s << "<text name='#{name}'"
154
+ s << " value='#{values[n].to_html}'" if n < values.length
155
+ s << "/>"
156
+
157
+ res << s
158
+ end
159
+
160
+ res << "</row>"
161
+
162
+ if twoparts > 0 and n == twoparts-1
163
+ res << "<row><empty/></row>"
164
+ end
165
+ end
166
+ res << "</table>"
167
+
168
+ return res.join("\n")
169
+ end
170
+ end
171
+
172
+ class Hash
173
+ def rwd_table(field=nil, joinwith=nil, headers=nil)
174
+ res = []
175
+
176
+ res << "<table>"
177
+ res << headers.rwd_headers((not field.nil?)) if not headers.nil?
178
+ self.keys.numsort.each do |key|
179
+ key2 = key
180
+ value2 = self[key]
181
+
182
+ key2 = key2.join(joinwith) if key2.kind_of?(Array)
183
+ value2 = [value2] if value2.kind_of?(String)
184
+
185
+ res << value2.rwd_row(field, key2)
186
+ end
187
+ res << "</table>"
188
+
189
+ res.join("\n")
190
+ end
191
+ end
192
+
193
+ class EVTable
194
+ def rwd_table(field=nil, joinwith=@sep)
195
+ super(field, joinwith, @headers)
196
+ end
197
+
198
+ def rwd_form(prefix="", key=nil, twoparts=false)
199
+ values = self[key] if not key.nil?
200
+ values = [] if values.nil?
201
+ options = {}
202
+
203
+ if File.file?(oldlocation("constraints.tsv"))
204
+ table = File.basename(@file).gsub(/\.tsv$/, "")
205
+
206
+ TSVFile.new(oldlocation("constraints.tsv")).subset(["Table", "Constraint"], [table, "key"], ["Column", "Value"]).values.each do |column, table2|
207
+ options[column] = TSVFile.new(oldlocation("#{table2}.tsv")).keys.collect{|a| a.join("\t")}
208
+ end
209
+ end
210
+
211
+ @headers.rwd_form(prefix, values, twoparts ? @key : 0, options)
212
+ end
213
+
214
+ def rwd_metadata
215
+ res = []
216
+
217
+ res << "<table>"
218
+ res << "<row>"
219
+ res << " <empty/>"
220
+ res << " <text name='header_new' value=''/>"
221
+ res << "</row>"
222
+ @headers.each_index do |n|
223
+ res << "<row>"
224
+ res << " <text name='header_#{n}_old' value='#{@headers[n]}'/>"
225
+ res << " <text name='header_#{n}_new' value=''/>"
226
+ res << "</row>"
227
+ end
228
+ res << "</table>"
229
+
230
+ return res.join("\n")
231
+ end
232
+ end
233
+
234
+ class OpenTag
235
+ def prechildren(res, before, after, varshtml, varsstring, switches, help, oneormorefields, firstaction, tabs, tab, pda)
236
+ bef = before[-1]
237
+ res << Format % ["Before", @subtype] if ($rwd_debug and not bef.nil?)
238
+ res << bef if not bef.nil?
239
+
240
+ res << Format % ["Pre", @subtype] if $rwd_debug
241
+
242
+ align = AC
243
+ align = "align='#{@args["align"]}'" if @args.include?("align")
244
+
245
+ valign = VA
246
+ valign = "valign='#{@args["valign"]}'" if @args.include?("valign")
247
+
248
+ value1 = ""
249
+ value1 = varshtml[@args["name"]] if varshtml.include?(@args["name"])
250
+ value1 = @args["value"] if @args.include?("value")
251
+
252
+ value2 = ""
253
+ value2 = varsstring[@args["name"]] if varsstring.include?(@args["name"])
254
+ value2 = @args["value"] if @args.include?("value")
255
+
256
+ cellspacing = 3
257
+ cellspacing = 0 if pda
258
+
259
+ case @subtype
260
+ when "application"
261
+ when "window", "helpwindow"
262
+ args = @args.deep_dup
263
+
264
+ args["nohelpbutton"] = (not help)
265
+
266
+ template = $rwd_html_1
267
+ template = $rwd_html_PDA_1 if pda
268
+
269
+ res <<(template(template, args))
270
+ when "p" then res << "<p #{align} > "
271
+ when "pre" then res << "<pre #{align}>"
272
+ when "big" then res << "<p #{align}><big>"
273
+ when "small" then res << "<p #{align}><small>"
274
+ when "list" then res << "<ul #{align}>"
275
+ when "item" then res << "<li #{align}>"
276
+ when "empty" then res << "<p><br>"
277
+ when "image"
278
+ width = "width='#{@args["width"]}" if @args.include?("width")
279
+ height = "height='#{@args["height"]}'" if @args.include?("height")
280
+
281
+ res << "<img src='#{@args["src"]}' alt='#{@args["alt"]}' #{width} #{height}>"
282
+ when "progressbar"
283
+ width = 200
284
+
285
+ res << "<table>"
286
+ res << " <tr>"
287
+ res << " <td colspan='2'><img src='rwd_pixel.gif' height='1' width='#{width+5}'></td>"
288
+ res << " </tr>"
289
+ res << " <tr>"
290
+ res << " <td bgcolor='#DDDDDD'><img src='rwd_pixel.gif' height='10' width='#{(width*@args["value"].to_f).to_i}'></td>"
291
+ res << " <td bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='10' width='#{(width*(1.0-@args["value"].to_f)).to_i}'></td>"
292
+ res << " </tr>"
293
+ res << "</table>"
294
+ when "br" then res << "<br>"
295
+ when "hr" then res << "<hr>"
296
+ when "b" then res << "<b>"
297
+ when "i" then res << "<i>"
298
+ when "a"
299
+ if @args.include?("href")
300
+ res << "<a href='#{@args["href"]}' target='#{@args["target"] or "_blank"}'>"
301
+ else
302
+ res << "<a href='javascript:document.bodyform.rwd_action.value=\"#{@args["action"]}\";document.bodyform.submit();'>"
303
+ end
304
+ when "vertical" then res << "<table #{AC} border='#{$rwd_border}' cellspacing='#{cellspacing}' cellpadding='0'>"
305
+ when "horizontal" then res << "<table #{AC} border='#{$rwd_border}' cellspacing='#{cellspacing}' cellpadding='0'><tr #{align} #{valign}>"
306
+ when "table" then res << "<table #{AC} border='#{$rwd_border}' cellspacing='#{cellspacing}' cellpadding='0'>"
307
+ when "row" then res << "<tr #{align} #{valign}>"
308
+ when "hidden" then res << "<p #{align}><input name='#{@args["name"]}' value='#{value1}' type='hidden'>"
309
+ when "text"
310
+ maxlength = ""
311
+ maxlength = "maxlength='%s'" % @args["maxlength"] if @args.include?("maxlength")
312
+ size = ""
313
+ size = "size='%s'" % @args["size"] if @args.include?("size")
314
+ size = "size='%s'" % 10 if pda
315
+ res << "<p #{align}><input name='#{@args["name"]}' value='#{value1}' type='text' #{maxlength} #{size}>"
316
+ oneormorefields << "true"
317
+ when "textarea"
318
+ res << "<p #{align}><textarea name='#{@args["name"]}' rows='25' cols='80'>#{value2.crlf}</textarea>"
319
+ oneormorefields << "true"
320
+ when "password"
321
+ maxlength = ""
322
+ maxlength = "maxlength='%s'" % @args["maxlength"] if @args.include?("maxlength")
323
+ size = ""
324
+ size = "size='%s'" % 10 if pda
325
+ res << "<p #{align}><input name='#{@args["name"]}' value='#{value1}' type='password' #{maxlength} #{size}>"
326
+ oneormorefields << "true"
327
+ when "checkbox"
328
+ if varshtml[@args["name"]] == "on"
329
+ switches[@args["name"]] = true
330
+ res << "<p #{align}><input name='#{@args["name"]}' checked='on' type='checkbox'>"
331
+ else
332
+ switches[@args["name"]] = false
333
+ res << "<p #{align}><input name='#{@args["name"]}' type='checkbox'>"
334
+ end
335
+ oneormorefields << "true"
336
+ when "radio"
337
+ if varshtml[@args["name"]] == value1 # ??? 1 or 2?
338
+ res << "<p #{align}><input name='#{@args["name"]}' checked='on' value='#{value1}' type='radio'>"
339
+ else
340
+ res << "<p #{align}><input name='#{@args["name"]}' value='#{value1}' type='radio'>"
341
+ end
342
+ oneormorefields << "true"
343
+ when "select"
344
+ res << "<select #{align} name='#{@args["name"]}' width='#{@args["width"]}'>"
345
+ name = @args["name"]
346
+ $select = varshtml[name]
347
+ oneormorefields << "true"
348
+ when "option"
349
+ if $select == @children[0].text
350
+ res << "<option selected='true'>"
351
+ else
352
+ res << "<option>"
353
+ end
354
+ when "button"
355
+ res << "<input type='submit' value='#{@args["caption"]}' onclick='document.bodyform.rwd_action.value=\"#{@args["action"]}\";'>"
356
+ firstaction << @args["action"] if (firstaction.empty? and @args.include?("action"))
357
+ oneormorefields << "true"
358
+ when "back"
359
+ res << "<input type='submit' value='Back' onclick='document.bodyform.rwd_action.value=\"rwd_back\";'>"
360
+ firstaction << "rwd_back" if firstaction.empty?
361
+ oneormorefields << "true"
362
+ when "cancel"
363
+ res << "<input type='submit' value='Cancel' onclick='document.bodyform.rwd_action.value=\"rwd_cancel\";'>"
364
+ firstaction << "rwd_cancel" if firstaction.empty?
365
+ oneormorefields << "true"
366
+ when "help"
367
+ res << "<input type='submit' value='Help' onclick='document.bodyform.rwd_action.value=\"rwd_help\";'>"
368
+ firstaction << "rwd_help" if firstaction.empty?
369
+ oneormorefields << "true"
370
+ when "quit"
371
+ res << "<input type='submit' value='Quit' onclick='document.bodyform.rwd_action.value=\"rwd_quit\";'>"
372
+ firstaction << "rwd_quit" if firstaction.empty?
373
+ oneormorefields << "true"
374
+ when "close"
375
+ res << "<input type='submit' value='Close' onclick='window.close();'>"
376
+ firstaction << "rwd_quit" if firstaction.empty?
377
+ oneormorefields << "true"
378
+ when "main"
379
+ res << "<input type='submit' value='Main' onclick='document.bodyform.rwd_action.value=\"rwd_main\";'>"
380
+ firstaction << "rwd_main" if firstaction.empty?
381
+ oneormorefields << "true"
382
+ when "reset"
383
+ res << "<input type='reset' value='Reset'>"
384
+ firstaction << "rwd_quit" if firstaction.empty? # ???
385
+ oneormorefields << "true"
386
+ when "closewindow"
387
+ #res << "<script type='text/javascript'>\n" # ???
388
+ #res << "<!--\n"
389
+ #res << " window.close();\n"
390
+ #res << "//-->\n"
391
+ #res << "</script>"
392
+ when "tabs"
393
+ res << "<table #{AC} border='#{$rwd_border}' cellspacing='0' cellpadding='0'>"
394
+ res << " <tr #{AL}>"
395
+ res << " <td #{AL} class='tabs'>"
396
+ res << " <table #{AL} border='#{$rwd_border}' cellspacing='0' cellpadding='0'>"
397
+ res << " <tr #{AL}>"
398
+ #res << " <td class='notab'>&nbsp;</td>"
399
+ tabs.each do |obj|
400
+ name = obj.args["name"]
401
+ caption = obj.args["caption"]
402
+
403
+ res << "<td #{AL} class='notab'>&nbsp;</td>" unless obj == tabs[0]
404
+
405
+ if name == tab
406
+ res << "<td #{AC} class='activetab'><tt>&nbsp;#{caption}&nbsp;</tt></td>"
407
+ else
408
+ res << "<td #{AC} class='passivetab'><a href='javascript:document.bodyform.rwd_action.value=\"rwd_tab_#{name}\";document.bodyform.submit();'><tt>&nbsp;#{caption}&nbsp;</tt></a></td>"
409
+ end
410
+ end
411
+ res << " <td class='notab' width='100%'>&nbsp;</td>"
412
+ res << " </tr>"
413
+ res << " </table>"
414
+ res << " </td>"
415
+ res << " </tr>"
416
+ res << " <tr #{align}>"
417
+ res << " <td #{align} class='tabblad'>"
418
+ when "tab"
419
+ res << "<table #{AC} border='#{$rwd_border}' cellspacing='3' cellpadding='0'>"
420
+ when "panel"
421
+ level = (@args["level"] or "normal")
422
+ res << "<table #{AC} border='#{$rwd_border}' cellspacing='0' cellpadding='0'>"
423
+ res << " <tr #{align}>"
424
+ res << " <td #{align} class='panel1'>" if level == "normal"
425
+ res << " <td #{align} class='panel1high'>" if level == "high"
426
+ res << " <td #{align} class='panel1low'>" if level == "low"
427
+ res << " <table #{AC} border='#{$rwd_border}' cellspacing='0' cellpadding='0'>"
428
+ res << " <tr #{align}>"
429
+ res << " <td #{align} class='panel2'>" if level == "normal"
430
+ res << " <td #{align} class='panel2high'>" if level == "high"
431
+ res << " <td #{align} class='panel2low'>" if level == "low"
432
+ res << " <table #{AC} border='#{$rwd_border}' cellspacing='3' cellpadding='0'>"
433
+ else
434
+ puts "<#{@subtype}>"
435
+ res << "&lt;#{@subtype}&gt;"
436
+ end
437
+
438
+ bef = nil
439
+ aft = nil
440
+
441
+ case @subtype
442
+ when "vertical", "window", "helpwindow", "tab", "panel"
443
+ res << Format % ["AftPre", @subtype] if $rwd_debug
444
+ if @args.include?("spacing")
445
+ s = "<tr><td>&nbsp;</td></tr>" * (@args["spacing"].to_i)
446
+ else
447
+ s = ""
448
+ end
449
+ bef = "#{s}<tr #{align} #{valign}><td #{align}>"
450
+ aft = "</td></tr>"
451
+ when "horizontal", "row"
452
+ res << Format % ["AftPre", @subtype] if $rwd_debug
453
+ bef = "<td #{align}>"
454
+ aft = "</td>"
455
+ end
456
+
457
+ before.push(bef)
458
+ after.push(aft)
459
+ end
460
+
461
+ def postchildren(res, before, after, varshtml, varsstring, switches, help, oneormorefields, firstaction, tabs, tab, pda)
462
+ case @subtype
463
+ when "vertical", "window", "helpwindow", "tab", "panel"
464
+ res << Format % ["BefPost", @subtype] if $rwd_debug
465
+ if @args.include?("spacing")
466
+ res << "<tr><td>&nbsp;</td></tr>" * (@args["spacing"].to_i)
467
+ end
468
+ when "horizontal", "row"
469
+ res << Format % ["BefPost", @subtype] if $rwd_debug
470
+ end
471
+
472
+ res << Format % ["Post", @subtype] if $rwd_debug
473
+
474
+ case @subtype
475
+ when "application"
476
+ when "window", "helpwindow"
477
+ args = @args.deep_dup
478
+
479
+ args["nohelpbutton"] = (not help)
480
+
481
+ template = $rwd_html_2
482
+ template = $rwd_html_PDA_2 if pda
483
+
484
+ res <<(template(template, args))
485
+ when "p" then res << "</p>"
486
+ when "pre" then res << "</pre>"
487
+ when "big" then res << "</big></p>"
488
+ when "small" then res << "</small></p>"
489
+ when "list" then res << "</ul>"
490
+ when "item" then res << "</li>"
491
+ when "empty" then res << "</p>"
492
+ when "image" then res << ""
493
+ when "progressbar" then res << ""
494
+ when "br" then res << ""
495
+ when "hr" then res << ""
496
+ when "b" then res << "</b>"
497
+ when "i" then res << "</i>"
498
+ when "a" then res << "</a>"
499
+ when "vertical" then res << "</table>"
500
+ when "horizontal" then res << "</tr></table>"
501
+ when "table" then res << "</table>"
502
+ when "row" then res << "</tr>"
503
+ when "hidden" then res << "</p>"
504
+ when "text" then res << "</p>"
505
+ when "textarea" then res << "</p>"
506
+ when "password" then res << "</p>"
507
+ when "checkbox" then res << "</p>"
508
+ when "radio" then res << "</p>"
509
+ when "select"
510
+ res << "</select>"
511
+ $select = nil
512
+ when "option" then res << "</option>"
513
+ when "button" then res << ""
514
+ when "back" then res << ""
515
+ when "cancel" then res << ""
516
+ when "help" then res << ""
517
+ when "quit" then res << ""
518
+ when "close" then res << ""
519
+ when "main" then res << ""
520
+ when "reset" then res << ""
521
+ when "closewindow" then res << ""
522
+ when "tabs"
523
+ res << " </td>"
524
+ res << " </tr>"
525
+ res << "</table>"
526
+ when "tab"
527
+ res << "</table>"
528
+ when "panel"
529
+ res << " </table>"
530
+ res << " </td>"
531
+ res << " </tr>"
532
+ res << " </table>"
533
+ res << " </td>"
534
+ res << " </tr>"
535
+ res << "</table>"
536
+ else
537
+ puts "</#{@subtype}>"
538
+ res << "&lt;/#{@subtype}&gt;"
539
+ end
540
+
541
+ before.pop
542
+ after.pop
543
+
544
+ aft = after[-1]
545
+ res << Format % ["After", @subtype] if ($rwd_debug and not aft.nil?)
546
+ res << aft if not aft.nil?
547
+ end
548
+
549
+ def template(html, vars)
550
+ res = []
551
+
552
+ a = {}
553
+
554
+ vars.each do |k, v|
555
+ a[k.upcase] = v
556
+ end
557
+
558
+ logo = nil
559
+ logo = File.expand_path(vars["logo"], $rwd_files) if vars.include?("logo")
560
+ logo = nil unless logo.nil? or File.file?(logo)
561
+
562
+ a["LOGO"] = "" unless not logo.nil?
563
+
564
+ a["HELPBUTTON"] = (not (vars["nohelpbutton"]))
565
+ a["BACKBUTTONS"] = (not (vars["nobackbuttons"]))
566
+ a["BACKBUTTONS"] = (not (vars["nobackbuttons"]))
567
+ a["CLOSEBUTTON"] = (not (vars["noclosebutton"]))
568
+
569
+ if a.include?("WIDTH")
570
+ a["WIDTH1"] = "width='#{a["WIDTH"]}'"
571
+ a["WIDTH2"] = a["WIDTH"]
572
+ else
573
+ a["WIDTH1"] = " "
574
+ a["WIDTH2"] = "1"
575
+ end
576
+
577
+ html.split(/\r*\n/).each do |line|
578
+ if line =~ /%[A-Z0-9]+%/
579
+ a.each do |k, v|
580
+ v = false if (v.kind_of?(String) and v.empty?)
581
+
582
+ if line.include?("%#{k}%")
583
+ line.gsub!("%#{k}%", "#{v}") if v
584
+ end
585
+ end
586
+
587
+ line = "<!-- #{line.scan(/%[A-Z0-9]+%/).join(" ")} -->" if line =~ /%[A-Z0-9]+%/
588
+ end
589
+
590
+ res << line
591
+ end
592
+
593
+ res.join("\n")
594
+ end
595
+ end
596
+
597
+ class Text
598
+ def prechildren(res, before, after, varshtml, varsstring, switches, help, oneormorefields, firstaction, tabs, tab, pda)
599
+ if not @text.scan(/[^ \t\r\n]/).empty?
600
+ res << Format % ["Text", ""] if $rwd_debug
601
+ res << "#{@text}"
602
+ end
603
+ end
604
+ end
605
+
606
+ class RWDTree < XML
607
+ end
608
+
609
+ class RWDWindow
610
+ @@windows = {} # Kind of caching.
611
+ @@helpwindows = {} # Kind of caching.
612
+
613
+ def initialize(rwd, window=nil)
614
+ rwd = rwd.join("\n") if rwd.kind_of?(Array)
615
+
616
+ if @@windows[rwd].nil?
617
+ @@windows[rwd] = {}
618
+ @@helpwindows[rwd] = {}
619
+
620
+ tree = XML.new(rwd)
621
+
622
+ tree.parse(OpenTag, "window") do |type, obj|
623
+ @@windows[rwd][obj.args["name"]] = obj.to_h
624
+ end
625
+
626
+ tree.parse(OpenTag, "helpwindow") do |type, obj|
627
+ @@helpwindows[rwd][obj.args["name"]] = obj.to_h
628
+ end
629
+ end
630
+
631
+ @rwd = (@@windows[rwd][window] or "").dup
632
+ @helprwd = (@@helpwindows[rwd][window] or "").dup
633
+ end
634
+
635
+ def render(pda, action=nil, vars=Hash.new, switches=Hash.new, help=false, tab="")
636
+ varshtml = Hash.new
637
+ varsstring = Hash.new
638
+ oneormorefields = ""
639
+ firstaction = ""
640
+ html = []
641
+
642
+ vars.each do |key, value|
643
+ if not key.empty?
644
+ if value.respond_to? "to_s"
645
+ @rwd.gsub!(/%%#{key}%%/, value.to_s)
646
+ @rwd.gsub!(/%#{key}%/, value.to_s.to_html)
647
+
648
+ @helprwd.gsub!(/%%#{key}%%/, value.to_s)
649
+ @helprwd.gsub!(/%#{key}%/, value.to_s.to_html)
650
+
651
+ varshtml[key] = value.to_s.to_html
652
+ varsstring[key] = value.to_s
653
+ end
654
+ end
655
+ end
656
+
657
+ windowobject = RWDTree.new(@rwd).children.dup.delete_if{|obj| obj.subtype != "window"}[0]
658
+ helpobject = RWDTree.new(@helprwd).children.dup.delete_if{|obj| obj.subtype != "helpwindow"}[0]
659
+
660
+ tabsobj = windowobject.children.dup.delete_if{|obj| obj.subtype != "tabs"}[0]
661
+
662
+ if not tabsobj.nil?
663
+ tabs = tabsobj.children.dup.delete_if{|obj| (not obj.kind_of?(OpenTag)) or (obj.subtype != "tab")}
664
+
665
+ if tab.empty?
666
+ tab = tabs[0].args["name"]
667
+ end
668
+
669
+ tabsobj.children.delete_if{|obj| (obj.kind_of?(OpenTag)) and (obj.subtype == "tab") and obj.args["name"] != tab}
670
+ end
671
+
672
+ if help
673
+ helpobject.parsetree("prechildren", "postchildren", html, [""], [""], varshtml, varsstring, switches, false, oneormorefields, firstaction, tabs, tab, pda)
674
+ else
675
+ windowobject.parsetree("prechildren", "postchildren", html, [""], [""], varshtml, varsstring, switches, (not @helprwd.empty?), oneormorefields, firstaction, tabs, tab, pda)
676
+ end
677
+
678
+ html = html.join("") # ???
679
+
680
+ html.gsub!(/%%*[[:alnum:]_\-]+%%*/, "") if not $rwd_debug
681
+ html.gsub!(/%%/, "%")
682
+ html.gsub!(/\n\n*/, "\n")
683
+
684
+ if oneormorefields.empty?
685
+ focus = ""
686
+ else
687
+ focus = "document.bodyform.elements[0].focus();"
688
+ end
689
+
690
+ firstaction = action if windowobject.args.keys.include?("refresh") unless action.nil?
691
+
692
+ html.gsub!(/\$RWD_FIRSTACTION\$/ , firstaction)
693
+ html.gsub!(/\$RWD_FOCUS\$/ , focus)
694
+
695
+ html
696
+ end
697
+ end
698
+
699
+ class RWDMessage < RWDWindow
700
+ def initialize(msg)
701
+ super("<window title='RWD Message' nobackbuttons noclosebutton><p>#{msg}</p><back/></window>")
702
+ end
703
+ end
704
+
705
+ class RWDError < RWDWindow
706
+ def initialize(msg)
707
+ super("<window title='RWD Error' nobackbuttons noclosebutton><p><b>Error:</b> #{msg}</p><back/></window>")
708
+ end
709
+ end
710
+
711
+ class RWDProgressBar < RWDWindow
712
+ def initialize(refresh, progress)
713
+ s = ""
714
+ s << "<window title='RWD Progress' nobackbuttons noclosebutton refresh='#{refresh}'>"
715
+ if progress.length == 1
716
+ progress.each do |caption, value|
717
+ s << "<p>#{caption}</p><progressbar value='#{value}'/><p>#{(100*value).to_i}%%</p>"
718
+ end
719
+ else
720
+ s << "<table>"
721
+ progress.each do |caption, value|
722
+ s << "<row><p align='left'>#{caption}</p><progressbar value='#{value}'/><p align='right'>#{(100*value).to_i}%%</p></row>"
723
+ end
724
+ s << "</table>"
725
+ end
726
+ s << "<cancel/>"
727
+ s << "</window>"
728
+ super(s)
729
+ end
730
+ end
731
+
732
+ class RWDDone < RWDWindow
733
+ def initialize(exitbrowser)
734
+ super("<window title='RWD Message' nobackbuttons noclosebutton><p>Done.</p><horizontal><close/>#{exitbrowser ? "" : "<button caption='Again'/>"}</horizontal>#{exitbrowser ? "<closewindow/>" : ""}</window>")
735
+ end
736
+ end
737
+
738
+ class RWDialog
739
+ def initialize(xml)
740
+ @rwd_xml = xml
741
+ @rwd_exitbrowser = false
742
+ @rwd_history = []
743
+ @rwd_ignore_vars = []
744
+ @rwd_call_after_back = []
745
+ end
746
+
747
+ def self.file(rwdfile, *args)
748
+ new(File.new(rwdfile).readlines, *args)
749
+ end
750
+
751
+ def serve(port=nil, auth=nil, realm=self.class.to_s)
752
+ exit if $rwd_exit
753
+
754
+ raise "RWD is not initialized." if @rwd_xml.nil?
755
+
756
+ low, high = ENV["RWDPORTS"].split(/[^\d+]/)
757
+ high = low if high.nil?
758
+ low, high = low.to_i, high.to_i
759
+
760
+ io = nil
761
+
762
+ port, io = TCPServer.freeport(low, high, (not auth.nil?)) if port.nil?
763
+ raise "No free TCP port." if port.nil?
764
+
765
+ port = port.to_i
766
+
767
+ @rwd_server = RWDServer.new(self, port, io, auth, realm)
768
+ end
769
+
770
+ def render(res, path, post, download, downloadfile, pda, sessionid)
771
+
772
+ # Initialize some vars.
773
+
774
+ vars = Hash.new if vars.nil?
775
+ @rwd_switches = Hash.new if @rwd_switches.nil?
776
+
777
+ done = false
778
+ help = false
779
+ back = false
780
+ tab = ""
781
+ @rwd_msgtype = nil
782
+ @rwd_download = nil
783
+ @rwd_download_file = nil
784
+
785
+ # Switches are used for checkboxes.
786
+
787
+ @rwd_switches.each do |key, value|
788
+ vars[key] = "off"
789
+ end
790
+
791
+ @rwd_switches = Hash.new
792
+
793
+ # Copy the vars from the window to vars. vars wil later on be copied to instance variables.
794
+
795
+ post.sort.each do |key, value|
796
+ puts "Post: #{key} -> #{value.from_html.inspect}" if $rwd_debug
797
+
798
+ vars[key] = value.from_html
799
+ end
800
+
801
+ # Stack handling for rwd_action, rwd_window and rwd_tab.
802
+
803
+ @rwd_action = vars["rwd_action"] if vars.include?("rwd_action")
804
+ @rwd_action, @rwd_args = @rwd_action.split(/\//, 2) unless @rwd_action.nil?
805
+ @rwd_action, rest = @rwd_action.split(/\?/) unless @rwd_action.nil?
806
+
807
+ @rwd_refresh_action = (@rwd_action or @rwd_refresh_action or "main")
808
+
809
+ unless rest.nil?
810
+ rest.each do |s|
811
+ k, v = s.split(/=/, 2)
812
+ vars[k] = v
813
+ end
814
+ end
815
+
816
+ if @rwd_action == "rwd_cancel"
817
+ @rwd_progress_thread.kill unless @rwd_progress_thread.nil?
818
+ @rwd_progress_thread = nil
819
+ @rwd_action = "rwd_back"
820
+ end
821
+
822
+ if @rwd_action =~ /^rwd_tab_/
823
+ @rwd_tab = @rwd_action.sub(/^rwd_tab_/, "")
824
+ @rwd_history[-1][3] = @rwd_tab
825
+ else
826
+ case @rwd_action
827
+ when "rwd_back"
828
+ @rwd_history.pop
829
+ @rwd_action = (@rwd_history[-1] or [nil, nil, nil])[0]
830
+ @rwd_args = (@rwd_history[-1] or [nil, nil, nil])[1]
831
+ @rwd_window = (@rwd_history[-1] or [nil, nil, nil])[2]
832
+ @rwd_tab = (@rwd_history[-1] or [nil, nil, nil])[3]
833
+ back = true
834
+ when "rwd_help"
835
+ help = true
836
+ when "rwd_main"
837
+ @rwd_action = nil
838
+ @rwd_window = nil
839
+ @rwd_tab = nil
840
+ @rwd_history = []
841
+ when "rwd_quit"
842
+ done = true
843
+ end
844
+
845
+ # History stuff
846
+
847
+ @rwd_history = @rwd_history[-100..-1] if @rwd_history.length >= 100
848
+ @rwd_action = "main" if @rwd_action.nil?
849
+ @rwd_action = "main" if @rwd_action.empty?
850
+ @rwd_window = "main" if @rwd_window.nil?
851
+ @rwd_window = "main" if @rwd_window.empty?
852
+ @rwd_tab = "" if @rwd_tab.nil?
853
+ @rwd_args = [] if @rwd_args.nil?
854
+ @rwd_args = [] if @rwd_action == "main"
855
+
856
+ vars["rwd_action"] = @rwd_action
857
+ vars["rwd_window"] = @rwd_window
858
+ vars["rwd_tab"] = @rwd_tab
859
+
860
+ # Copy vars from window to instance.
861
+
862
+ vars.each do |k, v|
863
+ instance_eval "@#{k} = vars['#{k}']" if ((not k.empty?) and k.scan(/^rwd_/).empty? and not @rwd_ignore_vars.include?("@#{k}"))
864
+ end
865
+
866
+ # Callback.
867
+
868
+ if (not back) or @rwd_call_after_back.include?(@rwd_action)
869
+ unless @rwd_action =~ /^rwd_/
870
+ puts "Method: #{@rwd_action}(#{@rwd_args.join(", ")})" if $rwd_debug
871
+ if methods.include?(@rwd_action)
872
+ method(@rwd_action).call(*@rwd_args)
873
+ else
874
+ puts "Method '%s' is not defined." % @rwd_action
875
+ end
876
+ end
877
+
878
+ # History stuff
879
+
880
+ @rwd_history = [["main", [], "main", ""]] if @rwd_action == "main"
881
+ @rwd_history = [["main", [], "main", ""]] if @rwd_history.empty?
882
+
883
+ a = [@rwd_action, @rwd_args, @rwd_window, @rwd_tab]
884
+
885
+ @rwd_history.push a if (@rwd_history[-1] != a or not @rwd_msgtype.nil?)
886
+ end
887
+ end
888
+
889
+ # Copy vars from instance to window.
890
+
891
+ instance_variables.each do |k|
892
+ k.sub!(/^@/, "")
893
+ instance_eval "vars['#{k}'] = @#{k}.to_s" if (k.scan(/^rwd_/).empty? and not @rwd_ignore_vars.include?("@#{k}"))
894
+ end
895
+
896
+ # just ignore.
897
+
898
+ vars.sort.each do |key, value|
899
+ puts "Pre: #{key} -> #{value.inspect}" if $rwd_debug
900
+ end
901
+
902
+
903
+ # Answer to browser.
904
+
905
+ if done
906
+ res << RWDDone.new(@rwd_exitbrowser).render(pda)
907
+ else
908
+ if not @rwd_download.nil?
909
+ puts "Download: #{@rwd_window}" if $rwd_debug
910
+
911
+ download << @rwd_download
912
+ downloadfile << @rwd_download_file
913
+ else
914
+ if not @rwd_msgtype.nil?
915
+ res << RWDMessage.new(@rwd_msg).render(pda) if @rwd_msgtype == "message"
916
+ res << RWDError.new(@rwd_msg).render(pda) if @rwd_msgtype == "error"
917
+ else
918
+ if not @rwd_progress_thread.nil?
919
+ res << RWDProgressBar.new(@rwd_progress_refresh, @rwd_progress_progress).render(pda, @rwd_refresh_action)
920
+ else
921
+ puts "Window: #{@rwd_window}" if $rwd_debug
922
+ puts "Tab: #{@rwd_tab}" if $rwd_debug
923
+
924
+ res << RWDWindow.new(@rwd_xml, @rwd_window).render(pda, @rwd_refresh_action, vars, @rwd_switches, help, @rwd_tab)
925
+ end
926
+ end
927
+ end
928
+ end
929
+
930
+ return done
931
+ end
932
+
933
+ def samewindow?
934
+ @rwd_history[-1][2] == @rwd_window
935
+ end
936
+
937
+ def message(msg, &block)
938
+ @rwd_msg = msg
939
+ @rwd_msgtype = "message"
940
+ end
941
+
942
+ def error(msg, &block)
943
+ @rwd_msg = msg
944
+ @rwd_msgtype = "error"
945
+ end
946
+
947
+ def progressbar(refresh, *progress)
948
+ @rwd_progress_refresh = (refresh or 1)
949
+ @rwd_progress_progress = []
950
+
951
+ while not progress.empty?
952
+ s = (progress.shift or "")
953
+ if s.kind_of?(Array)
954
+ caption, value = s
955
+ value = (value or 0.0).to_f
956
+ else
957
+ caption = s
958
+ value = (progress.shift or 0.0).to_f
959
+ end
960
+
961
+ @rwd_progress_progress << [caption, value]
962
+ end
963
+
964
+ if @rwd_progress_thread.nil?
965
+ @rwd_progress_progress.each do |a|
966
+ a[1] = 0.0
967
+ end
968
+
969
+ @rwd_progress_thread =
970
+ Thread.new do
971
+ yield
972
+ end
973
+ Thread.pass
974
+ end
975
+
976
+ @rwd_progress_thread = nil unless @rwd_progress_thread.alive?
977
+ end
978
+
979
+ def download(data, filename="")
980
+ @rwd_download = data
981
+ @rwd_download_file = filename
982
+ end
983
+
984
+ def exitbrowser
985
+ @rwd_exitbrowser = true
986
+ end
987
+ end
988
+
989
+ class RWDLogin < RWDialog
990
+ def initialize(realm)
991
+ super("<window name='main' title='RWD Login for #{realm}' nobackbuttons noclosebutton><table><row><p align='right'>Username:</p><text name='rwd_a'/></row><row><p align='right'>Password:</p><password name='rwd_b'/></row></table><button caption='Login'/></window>")
992
+ end
993
+ end
994
+
995
+ class RWDTimeOut < RWDialog
996
+ def initialize
997
+ super("<window name='main' title='RWD Error' nobackbuttons noclosebutton><p><b>Error:</b> Session has expired.</p><button caption='New session'/></window>")
998
+ end
999
+ end
1000
+
1001
+ class SessionCleanup
1002
+ def initialize(sessions, interval, timeout)
1003
+ every(interval) do
1004
+ sessions.delete_if do |id, session|
1005
+ time = Time.now.to_i - session.lastaccess.to_i
1006
+
1007
+ puts "Session %s deleted" % id if time > timeout
1008
+
1009
+ time > timeout
1010
+ end
1011
+ end
1012
+ end
1013
+ end
1014
+
1015
+ class Sessions
1016
+ def initialize(rack, cleanup)
1017
+ @rack = rack.to_s
1018
+ @cleanup = SessionCleanup.new(self, 3600, 24*3600) if cleanup
1019
+ @sessions = {}
1020
+ end
1021
+
1022
+ def [](sessionid)
1023
+ @sessions[sessionid]
1024
+ end
1025
+
1026
+ def []=(sessionid, value)
1027
+ @sessions[sessionid] = value
1028
+ end
1029
+
1030
+ def delete(sessionid)
1031
+ @sessions.delete(sessionid)
1032
+ end
1033
+
1034
+ def delete_if(&block)
1035
+ @sessions.delete_if{|k, v| block.call(k, v)}
1036
+ end
1037
+
1038
+ def include?(sessionid)
1039
+ @sessions.include?(sessionid)
1040
+ end
1041
+ end
1042
+
1043
+ class Session < Hash
1044
+ attr_reader :sessionid
1045
+ attr_reader :lastaccess
1046
+ attr_reader :authenticated
1047
+ attr_writer :authenticated
1048
+
1049
+ def initialize(sessionid=nil)
1050
+ @sessionid = sessionid
1051
+ @lastaccess = Time.now
1052
+ @authenticated = false
1053
+ end
1054
+
1055
+ def touch
1056
+ @lastaccess = Time.now
1057
+ end
1058
+ end
1059
+
1060
+ class RWDSession < Session
1061
+ def render(res, path, post, download, downloadfile, pda)
1062
+ done = self["object"].render(res, path, post, download, downloadfile, pda, @sessionid)
1063
+
1064
+ res.gsub!(/\$RWD_SESSION\$/, done ? "" : "#{@sessionid}")
1065
+
1066
+ return done
1067
+ end
1068
+ end
1069
+
1070
+ class RWDServer
1071
+ def initialize(obj, port, io, auth, realm)
1072
+ @object = obj
1073
+ @localbrowsing = false
1074
+ @browserstarted = false
1075
+ @sessions = Sessions.new(obj.class, (not auth.nil?))
1076
+
1077
+ if auth.nil?
1078
+ @localbrowsing = true
1079
+
1080
+ if ENV.include?("RWDBROWSER") and not ENV["RWDBROWSER"].nil? and not ENV["RWDBROWSER"].empty?
1081
+ @browserstarted = true
1082
+ @object.exitbrowser
1083
+
1084
+ # Start browser.
1085
+
1086
+ @browserthread =
1087
+ Thread.new do
1088
+ puts "Starting the browser..."
1089
+
1090
+ #if ENV["RWDBROWSER"].downcase =~ /iexplore/ # ???
1091
+ #@ie = IE.new("http://localhost:#{port}/")
1092
+ #else
1093
+ browser = ENV["RWDBROWSER"].dup
1094
+ url = "http://localhost:%s/" % [port]
1095
+
1096
+ if cygwin?
1097
+ browser.gsub!(/\\/, "/")
1098
+ browser.gsub!(/ /, "\\ ")
1099
+ end
1100
+
1101
+ re = /[$%]1\b/
1102
+ command = "%s \"%s\"" % [browser, url]
1103
+ command = browser.gsub(re, url) if browser =~ re
1104
+
1105
+ command.gsub!(/%port%/, port.to_s)
1106
+
1107
+ system(command) or puts "Starting of the browser failed, or the browser terminated abnormally.\nCommand => #{command}"
1108
+ #end
1109
+
1110
+ puts "The browser has terminated."
1111
+ end
1112
+ end
1113
+ end
1114
+
1115
+ # Start server.
1116
+
1117
+ portio = port
1118
+ portio = [port, io] unless io.nil?
1119
+ threadlimiter = ThreadLimiter.new(1)
1120
+
1121
+ HTTPServer.serve(portio, (not auth.nil?)) do |req, resp|
1122
+ threadlimiter.wait do
1123
+
1124
+ vars = req.vars.dup
1125
+ pad = (req.request.path or "/")
1126
+
1127
+ if auth.kind_of? String
1128
+ file = "#{home}/#{auth}"
1129
+ auths = {}
1130
+ auths = Hash.file(file) if File.file?(file)
1131
+ else
1132
+ auths = auth
1133
+ end
1134
+
1135
+ #oldsessionid = vars["rwd_session"]
1136
+ oldsessionid = req.cookies["sessionid"]
1137
+
1138
+ # Retrieve session.
1139
+
1140
+ session = @sessions[oldsessionid]
1141
+
1142
+ # Eventually create new session.
1143
+
1144
+ if session.nil?
1145
+ sessionid = MD5.new(req.peeraddr[3].to_s + @object.inspect.to_s + ("%1.6f" % Time.now.to_f)).to_s while (sessionid == nil or @sessions.include?(sessionid))
1146
+ session = RWDSession.new(sessionid)
1147
+
1148
+ if auth.nil?
1149
+ session["object"] = @object
1150
+ else
1151
+ session["object"] = @object.clone
1152
+ end
1153
+
1154
+ if oldsessionid.nil? or oldsessionid.empty?
1155
+ if not auth.nil? and not auth.empty? and not session.authenticated and pad != "/rwd_pixel.gif"
1156
+
1157
+ # Check authentication
1158
+
1159
+ us = vars["rwd_a"]
1160
+ pa = vars["rwd_b"]
1161
+
1162
+ if us.nil? or pa.nil? or auths[us] != pa
1163
+ session = RWDSession.new
1164
+ session["object"] = RWDLogin.new(realm)
1165
+ pad = "/"
1166
+ else
1167
+ session.authenticated = true
1168
+ @sessions[session.sessionid] = session
1169
+ end
1170
+ else
1171
+ session.authenticated = true
1172
+ @sessions[session.sessionid] = session
1173
+ end
1174
+ else
1175
+ session = RWDSession.new
1176
+ session["object"] = RWDTimeOut.new
1177
+ end
1178
+
1179
+ vars = {}
1180
+ end
1181
+
1182
+ # Avoid timeout.
1183
+
1184
+ session.touch
1185
+
1186
+ if pad == "/"
1187
+
1188
+ # Serve methods/callbacks.
1189
+
1190
+ # Build new page.
1191
+
1192
+ download = ""
1193
+ downloadfile = ""
1194
+ res = ""
1195
+
1196
+ done = session.render(res, pad, vars, download, downloadfile, req.pda?)
1197
+
1198
+ begin
1199
+ if download.empty?
1200
+ resp["Content-Type"] = "text/html"
1201
+ if done
1202
+ resp.cookies["sessionid"] = ""
1203
+ else
1204
+ resp.cookies["sessionid"] = session.sessionid
1205
+ end
1206
+
1207
+ resp << res
1208
+ else
1209
+ resp["Content-Type"] = "application/octet-stream"
1210
+ resp["Content-Disposition"] = "attachment;"
1211
+ resp["Content-Disposition"] = "attachment; filename=%s" % downloadfile unless downloadfile.empty?
1212
+
1213
+ resp << download
1214
+ end
1215
+ rescue
1216
+ puts "Sending response to browser failed."
1217
+
1218
+ @sessions.delete(session.sessionid)
1219
+ end
1220
+
1221
+ # Eventually delete this session.
1222
+
1223
+ if done
1224
+ @sessions.delete(session.sessionid)
1225
+
1226
+ if @localbrowsing
1227
+ resp.stop
1228
+
1229
+ if @browserstarted and not @browserthread.nil? and @browserthread.alive?
1230
+ resp.stop do
1231
+ puts "Waiting for the browser to terminate..."
1232
+
1233
+ @browserthread.join
1234
+ end
1235
+ end
1236
+ end
1237
+ end
1238
+
1239
+ else
1240
+
1241
+ # Serve files.
1242
+
1243
+ if pad == "/rwd_pixel.gif"
1244
+ resp["Cache-Control"] = "max-age=86400"
1245
+ resp["Content-Type"] = "image/gif"
1246
+ resp << $rwd_pixel
1247
+ else
1248
+ if session.authenticated
1249
+ pwd = Dir.pwd
1250
+ file = File.expand_path(pad.gsub(/^\/*/, ""), $rwd_files)
1251
+
1252
+ if not file.index(pwd) == 0
1253
+ resp["Content-Type"] = "text/html"
1254
+ resp.response = "HTTP/1.0 400 BAD REQUEST"
1255
+ resp << "<html><body><p><b>Bad Request.</b> (<tt>#{pad}</tt>)</p></body></html>"
1256
+ elsif File.file?(file)
1257
+ resp << File.new(file, "rb").read rescue nil
1258
+ else
1259
+ resp["Content-Type"] = "text/html"
1260
+ resp.response = "HTTP/1.0 404 NOT FOUND"
1261
+ resp << "<html><body><p><b>Not found.</b> (<tt>#{pad}</tt>)</p></body></html>"
1262
+ end
1263
+ else
1264
+ resp["Content-Type"] = "text/html"
1265
+ resp.response = "HTTP/1.0 ??? NOT AUTHORIZED"
1266
+ resp << "<html><body><p><b>Not Authorized.</b></p></body></html>"
1267
+ end
1268
+ end
1269
+
1270
+ end
1271
+
1272
+ end
1273
+ end
1274
+ end
1275
+ end
1276
+
1277
+ $rwd_html["DEFAULT"] = "
1278
+ <!-- Generated by RubyWebDialog. -->
1279
+ <!-- For more information, please contact Erik Veenstra <rwd@erikveen.dds.nl>. -->
1280
+ <html>
1281
+ <head>
1282
+ <title>%TITLE%</title>
1283
+
1284
+ <meta http-equiv='Content-Type' content='text/html; charset=%CHARSET%'>
1285
+ <meta http-equiv='Content-Style-Type' content='text/css'>
1286
+ <meta http-equiv='Refresh' content='%REFRESH%, javascript:document.bodyform.submit();'>
1287
+
1288
+ <link rel='shortcut icon' href='%LOGO%'>
1289
+
1290
+ <style type='text/css'>
1291
+ <!--
1292
+
1293
+ a {
1294
+ text-decoration : none;
1295
+ }
1296
+
1297
+ a:hover {
1298
+ background : #AAAAAA;
1299
+ }
1300
+
1301
+ td.panel1 {
1302
+ border-color : #888888 #EEEEEE #EEEEEE #888888;
1303
+ border-width : 1pt;
1304
+ border-style : solid solid solid solid;
1305
+ }
1306
+
1307
+ td.panel2 {
1308
+ border-color : #EEEEEE #888888 #888888 #EEEEEE;
1309
+ border-width : 1pt;
1310
+ border-style : solid solid solid solid;
1311
+ }
1312
+
1313
+ td.panel1high {
1314
+ border-color : #EEEEEE #888888 #888888 #EEEEEE;
1315
+ border-width : 1pt;
1316
+ border-style : solid solid solid solid;
1317
+ }
1318
+
1319
+ td.panel2high {
1320
+ border-color : #EEEEEE #888888 #888888 #EEEEEE;
1321
+ border-width : 1pt;
1322
+ border-style : none none none none;
1323
+ }
1324
+
1325
+ td.panel1low {
1326
+ border-color : #888888 #EEEEEE #EEEEEE #888888;
1327
+ border-width : 1pt;
1328
+ border-style : solid solid solid solid;
1329
+ }
1330
+
1331
+ td.panel2low {
1332
+ border-color : #888888 #EEEEEE #EEEEEE #888888;
1333
+ border-width : 1pt;
1334
+ border-style : none none none none;
1335
+ }
1336
+
1337
+ td.tabblad {
1338
+ border-color : #EEEEEE #888888 #888888 #EEEEEE;
1339
+ border-width : 1pt;
1340
+ border-style : none solid solid solid;
1341
+ }
1342
+
1343
+ td.passivetab {
1344
+ background-color : #BBBBBB;
1345
+ border-color : #DDDDDD #DDDDDD #EEEEEE #DDDDDD;
1346
+ border-width : 1pt;
1347
+ border-style : solid solid solid solid;
1348
+ }
1349
+
1350
+ td.activetab {
1351
+ border-color : #EEEEEE #888888 #888888 #EEEEEE;
1352
+ border-width : 1pt;
1353
+ border-style : solid solid none solid;
1354
+ }
1355
+
1356
+ td.notab {
1357
+ border-color : #EEEEEE #EEEEEE #EEEEEE #EEEEEE;
1358
+ border-width : 1pt;
1359
+ border-style : none none solid none;
1360
+ }
1361
+
1362
+ //-->
1363
+ </style>
1364
+
1365
+ <script type='text/javascript'>
1366
+ <!--
1367
+ function BodyGo() {
1368
+ $RWD_FOCUS$
1369
+ }
1370
+ //-->
1371
+ </script>
1372
+ </head>
1373
+
1374
+ <body bgcolor='white' onload='BodyGo()' link='#000000' vlink='#000000' alink='#000000'>
1375
+ <form name='bodyform' action='/' method='post'>
1376
+ <table align='center' border='0' cellspacing='0' cellpadding='0' width='100%' height='100%'>
1377
+ <tr align='center' valign='middle'>
1378
+ <td align='center'>
1379
+
1380
+ <table align='center' border='0' cellspacing='0' cellpadding='0'>
1381
+
1382
+ <tr align='center'>
1383
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1384
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1385
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1386
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1387
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1388
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1389
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1390
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1391
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1392
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1393
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1394
+ </tr>
1395
+
1396
+ <tr align='center'>
1397
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1398
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1399
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1400
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1401
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1402
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1403
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1404
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1405
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1406
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1407
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1408
+ </tr>
1409
+
1410
+ <tr align='center'>
1411
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1412
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1413
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1414
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1415
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1416
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1417
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1418
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1419
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1420
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1421
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1422
+ </tr>
1423
+
1424
+ <tr align='center'>
1425
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1426
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1427
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1428
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1429
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1430
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1431
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1432
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1433
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1434
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1435
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1436
+ </tr>
1437
+
1438
+ <tr align='center'>
1439
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1440
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1441
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1442
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1443
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1444
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1445
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1446
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1447
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1448
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1449
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1450
+ </tr>
1451
+
1452
+ <tr align='center'>
1453
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1454
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1455
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1456
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1457
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1458
+
1459
+ <td align='center'>
1460
+
1461
+ <table align='center' border='0' cellspacing='0' cellpadding='0' %WIDTH1%>
1462
+ <tr align='center'>
1463
+ <td align='center' bgcolor='#444488'>
1464
+
1465
+ <table align='left' border='0' cellspacing='1' cellpadding='0'>
1466
+ <tr align='center'>
1467
+ <td align='border'><img src='%LOGO%' width='14' height='14'></td>
1468
+ <td align='center'><b><small><font color='#FFFFFF'>&nbsp;%TITLE%&nbsp;</font></small></b></td>
1469
+ </tr>
1470
+ </table>
1471
+
1472
+ <table align='right' border='0' cellspacing='1' cellpadding='0'>
1473
+ <tr align='center'>
1474
+ <!-- %HELPBUTTON% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_help\";document.bodyform.submit();'>&nbsp;?&nbsp;</a></small></b></td>
1475
+ <!-- %BACKBUTTONS% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_main\";document.bodyform.submit();'>&nbsp;&lt;&lt;&nbsp;</a></small></b></td>
1476
+ <!-- %BACKBUTTONS% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_back\";document.bodyform.submit();'>&nbsp;&lt;&nbsp;</a></small></b></td>
1477
+ <!-- %CLOSEBUTTON% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_quit\";document.bodyform.submit();'>&nbsp;X&nbsp;</a></small></b></td>
1478
+ </tr>
1479
+ </table>
1480
+
1481
+ </td>
1482
+ </tr>
1483
+
1484
+ <tr align='center'>
1485
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='%WIDTH2%'></td>
1486
+ </tr>
1487
+
1488
+ <tr align='center'>
1489
+ <td align='center' bgcolor='#CCCCCC'>
1490
+ <table align='center' border='0' cellspacing='3' cellpadding='0'>
1491
+ %BODY%
1492
+ </table>
1493
+
1494
+ <input name='rwd_action' value='$RWD_FIRSTACTION$' type='hidden'>
1495
+ <input name='rwd_session' value='$RWD_SESSION$' type='hidden'>
1496
+ </td>
1497
+ </tr>
1498
+ </table>
1499
+
1500
+ </td>
1501
+
1502
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1503
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1504
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1505
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1506
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1507
+ </tr>
1508
+
1509
+ <tr align='center'>
1510
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1511
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1512
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1513
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1514
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1515
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1516
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1517
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1518
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1519
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1520
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1521
+ </tr>
1522
+
1523
+ <tr align='center'>
1524
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1525
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1526
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1527
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1528
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1529
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1530
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1531
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1532
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1533
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1534
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1535
+ </tr>
1536
+
1537
+ <tr align='center'>
1538
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1539
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1540
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1541
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1542
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1543
+ <td align='center' bgcolor='#EEEEEE'><img src='rwd_pixel.gif' height='1' width='1'></td>
1544
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1545
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1546
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1547
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1548
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1549
+ </tr>
1550
+
1551
+ <tr align='center'>
1552
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1553
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1554
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1555
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1556
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1557
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1558
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1559
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1560
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1561
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1562
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1563
+ </tr>
1564
+
1565
+ <tr align='center'>
1566
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1567
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1568
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1569
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1570
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1571
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1572
+ <td align='center' bgcolor='black'><img src='rwd_pixel.gif' height='1' width='1'></td>
1573
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1574
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1575
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1576
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='1'></td>
1577
+ </tr>
1578
+
1579
+ </table>
1580
+
1581
+ </td>
1582
+ </tr>
1583
+ </table>
1584
+ </form>
1585
+ </body>
1586
+ </html>
1587
+ "
1588
+
1589
+ $rwd_html["WINDOWSLOOKALIKE"] = "
1590
+ <!-- Generated by RubyWebDialog. -->
1591
+ <!-- For more information, please contact Erik Veenstra <rwd@erikveen.dds.nl>. -->
1592
+ <html>
1593
+ <head>
1594
+ <title>%TITLE%</title>
1595
+
1596
+ <meta http-equiv='Content-Type' content='text/html; charset=%CHARSET%'>
1597
+ <meta http-equiv='Content-Style-Type' content='text/css'>
1598
+ <meta http-equiv='Refresh' content='%REFRESH%, javascript:document.bodyform.submit();'>
1599
+
1600
+ <link rel='shortcut icon' href='%LOGO%'>
1601
+
1602
+ <style type='text/css'>
1603
+ <!--
1604
+
1605
+ a {
1606
+ text-decoration : none;
1607
+ }
1608
+
1609
+ a:hover {
1610
+ background : #AAAAAA;
1611
+ }
1612
+
1613
+ td.window {
1614
+ border-color : #EEEEEE #888888 #888888 #EEEEEE;
1615
+ border-width : 3pt;
1616
+ border-style : solid solid solid solid;
1617
+ }
1618
+
1619
+ td.panel1 {
1620
+ border-color : #888888 #EEEEEE #EEEEEE #888888;
1621
+ border-width : 1pt;
1622
+ border-style : solid solid solid solid;
1623
+ }
1624
+
1625
+ td.panel2 {
1626
+ border-color : #EEEEEE #888888 #888888 #EEEEEE;
1627
+ border-width : 1pt;
1628
+ border-style : solid solid solid solid;
1629
+ }
1630
+
1631
+ td.panel1high {
1632
+ border-color : #EEEEEE #888888 #888888 #EEEEEE;
1633
+ border-width : 1pt;
1634
+ border-style : solid solid solid solid;
1635
+ }
1636
+
1637
+ td.panel2high {
1638
+ border-color : #EEEEEE #888888 #888888 #EEEEEE;
1639
+ border-width : 1pt;
1640
+ border-style : none none none none;
1641
+ }
1642
+
1643
+ td.panel1low {
1644
+ border-color : #888888 #EEEEEE #EEEEEE #888888;
1645
+ border-width : 1pt;
1646
+ border-style : solid solid solid solid;
1647
+ }
1648
+
1649
+ td.panel2low {
1650
+ border-color : #888888 #EEEEEE #EEEEEE #888888;
1651
+ border-width : 1pt;
1652
+ border-style : none none none none;
1653
+ }
1654
+
1655
+ td.tabblad {
1656
+ border-color : #EEEEEE #888888 #888888 #EEEEEE;
1657
+ border-width : 1pt;
1658
+ border-style : none solid solid solid;
1659
+ }
1660
+
1661
+ td.passivetab {
1662
+ background-color : #BBBBBB;
1663
+ border-color : #DDDDDD #DDDDDD #EEEEEE #DDDDDD;
1664
+ border-width : 1pt;
1665
+ border-style : solid solid solid solid;
1666
+ }
1667
+
1668
+ td.activetab {
1669
+ border-color : #EEEEEE #888888 #888888 #EEEEEE;
1670
+ border-width : 1pt;
1671
+ border-style : solid solid none solid;
1672
+ }
1673
+
1674
+ td.notab {
1675
+ border-color : #EEEEEE #EEEEEE #EEEEEE #EEEEEE;
1676
+ border-width : 1pt;
1677
+ border-style : none none solid none;
1678
+ }
1679
+
1680
+ //-->
1681
+ </style>
1682
+
1683
+ <script type='text/javascript'>
1684
+ <!--
1685
+ function BodyGo() {
1686
+ $RWD_FOCUS$
1687
+ }
1688
+ //-->
1689
+ </script>
1690
+ </head>
1691
+
1692
+ <body bgcolor='white' onload='BodyGo()' link='#000000' vlink='#000000' alink='#000000'>
1693
+ <form name='bodyform' action='/' method='post'>
1694
+ <table align='center' border='0' cellspacing='0' cellpadding='0' width='100%' height='100%'>
1695
+ <tr align='center' valign='middle'>
1696
+ <td align='center'>
1697
+
1698
+ <table align='center' border='0' cellspacing='0' cellpadding='0'>
1699
+
1700
+ <tr align='center'>
1701
+ <td align='center' class='window'>
1702
+
1703
+ <table align='center' border='0' cellspacing='0' cellpadding='0' %WIDTH1%>
1704
+ <tr align='center'>
1705
+ <td align='center' bgcolor='#444488'>
1706
+
1707
+ <table align='left' border='0' cellspacing='1' cellpadding='0'>
1708
+ <tr align='center'>
1709
+ <td align='border'><img src='%LOGO%' width='14' height='14'></td>
1710
+ <td align='center'><b><small><font color='#FFFFFF'>&nbsp;%TITLE%&nbsp;</font></small></b></td>
1711
+ </tr>
1712
+ </table>
1713
+
1714
+ <table align='right' border='0' cellspacing='1' cellpadding='0'>
1715
+ <tr align='center'>
1716
+ <!-- %HELPBUTTON% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_help\";document.bodyform.submit();'>&nbsp;?&nbsp;</a></small></b></td>
1717
+ <!-- %BACKBUTTONS% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_main\";document.bodyform.submit();'>&nbsp;&lt;&lt;&nbsp;</a></small></b></td>
1718
+ <!-- %BACKBUTTONS% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_back\";document.bodyform.submit();'>&nbsp;&lt;&nbsp;</a></small></b></td>
1719
+ <!-- %CLOSEBUTTON% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_quit\";document.bodyform.submit();'>&nbsp;X&nbsp;</a></small></b></td>
1720
+ </tr>
1721
+ </table>
1722
+
1723
+ </td>
1724
+ </tr>
1725
+
1726
+ <tr align='center'>
1727
+ <td align='center' bgcolor='white'><img src='rwd_pixel.gif' height='1' width='%WIDTH2%'></td>
1728
+ </tr>
1729
+
1730
+ <tr align='center'>
1731
+ <td align='center' bgcolor='#CCCCCC'>
1732
+ <table align='center' border='0' cellspacing='3' cellpadding='0'>
1733
+ %BODY%
1734
+ </table>
1735
+
1736
+ <input name='rwd_action' value='$RWD_FIRSTACTION$' type='hidden'>
1737
+ <input name='rwd_session' value='$RWD_SESSION$' type='hidden'>
1738
+ </td>
1739
+ </tr>
1740
+ </table>
1741
+
1742
+ </td>
1743
+ </tr>
1744
+
1745
+ </table>
1746
+
1747
+ </td>
1748
+ </tr>
1749
+ </table>
1750
+ </form>
1751
+ </body>
1752
+ </html>
1753
+ "
1754
+
1755
+ $rwd_html["PDA"] = "
1756
+ <!-- Generated by RubyWebDialog. -->
1757
+ <!-- For more information, please contact Erik Veenstra <rwd@erikveen.dds.nl>. -->
1758
+ <html>
1759
+ <head>
1760
+ <title>%TITLE%</title>
1761
+
1762
+ <meta http-equiv='Content-Type' content='text/html; charset=%CHARSET%'>
1763
+ <meta http-equiv='Refresh' content='%REFRESH%, javascript:document.bodyform.submit();'>
1764
+
1765
+ <link rel='shortcut icon' href='%LOGO%'>
1766
+
1767
+ <script type='text/javascript'>
1768
+ <!--
1769
+ function BodyGo() {
1770
+ $RWD_FOCUS$
1771
+ }
1772
+ //-->
1773
+ </script>
1774
+ </head>
1775
+
1776
+ <body bgcolor='white' onload='BodyGo()' link='#000000' vlink='#000000' alink='#000000'>
1777
+ <form name='bodyform' action='/' method='post'>
1778
+ <table align='center' border='0' cellspacing='0' cellpadding='0' width='100%' height='100%'>
1779
+
1780
+ <tr align='center'>
1781
+ <td align='center' bgcolor='#444488'>
1782
+
1783
+ <table align='left' border='0' cellspacing='1' cellpadding='0'>
1784
+ <tr align='center'>
1785
+ <td align='border'><img src='%LOGO%' width='14' height='14'></td>
1786
+ <td align='center'><b><small><font color='#FFFFFF'>&nbsp;%TITLE%&nbsp;</font></small></b></td>
1787
+ </tr>
1788
+ </table>
1789
+
1790
+ <table align='right' border='0' cellspacing='1' cellpadding='0'>
1791
+ <tr align='center'>
1792
+ <!-- %HELPBUTTON% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_help\";document.bodyform.submit();'>&nbsp;?&nbsp;</a></small></b></td>
1793
+ <!-- %BACKBUTTONS% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_main\";document.bodyform.submit();'>&nbsp;&lt;&lt;&nbsp;</a></small></b></td>
1794
+ <!-- %BACKBUTTONS% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_back\";document.bodyform.submit();'>&nbsp;&lt;&nbsp;</a></small></b></td>
1795
+ <!-- %CLOSEBUTTON% --><td align='center' bgcolor='#EEEEEE'><b><small><a href='javascript:document.bodyform.rwd_action.value=\"rwd_quit\";document.bodyform.submit();'>&nbsp;X&nbsp;</a></small></b></td>
1796
+ </tr>
1797
+ </table>
1798
+
1799
+ </td>
1800
+ </tr>
1801
+
1802
+ <!--
1803
+ <tr align='center'>
1804
+ <td align='center' bgcolor='#FFFFFF'>&nbsp;</td>
1805
+ </tr>
1806
+ -->
1807
+
1808
+ <tr align='center'>
1809
+ <td align='center' bgcolor='#FFFFFF'>
1810
+
1811
+ <table align='center' border='0' cellspacing='0' cellpadding='0'>
1812
+ %BODY%
1813
+ </table>
1814
+
1815
+ <input name='rwd_action' value='$RWD_FIRSTACTION$' type='hidden'>
1816
+ <input name='rwd_session' value='$RWD_SESSION$' type='hidden'>
1817
+ </td>
1818
+ </tr>
1819
+
1820
+ </table>
1821
+ </form>
1822
+ </body>
1823
+ </html>
1824
+ "
1825
+
1826
+ $rwd_pixel = "
1827
+ R0lGODlhAQABAOcAAAAAAAEBAQICAgMDAwQEBAUFBQYGBgcHBwgICAkJCQoK
1828
+ CgsLCwwMDA0NDQ4ODg8PDxAQEBERERISEhMTExQUFBUVFRYWFhcXFxgYGBkZ
1829
+ GRoaGhsbGxwcHB0dHR4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygo
1830
+ KCkpKSoqKisrKywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0NDU1NTY2Njc3
1831
+ Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZG
1832
+ RkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVV
1833
+ VVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2Rk
1834
+ ZGVlZWZmZmdnZ2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNz
1835
+ c3R0dHV1dXZ2dnd3d3h4eHl5eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKC
1836
+ goODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouLi4yMjI2NjY6Ojo+Pj5CQkJGR
1837
+ kZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2dnZ6enp+fn6Cg
1838
+ oKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+v
1839
+ r7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+
1840
+ vr+/v8DAwMHBwcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3N
1841
+ zc7Ozs/Pz9DQ0NHR0dLS0tPT09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc
1842
+ 3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6erq6uvr
1843
+ 6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pn5+fr6
1844
+ +vv7+/z8/P39/f7+/v///yH+FUNyZWF0ZWQgd2l0aCBUaGUgR0lNUAAh+QQB
1845
+ CgD/ACwAAAAAAQABAAAIBAD/BQQAOw==
1846
+ ".unpack("m").shift
1847
+
1848
+ $rwd_html_1, $rwd_html_2 = $rwd_html[ENV["RWDTHEME"]].split(/^\s*%BODY%\s*\r*$/)
1849
+ $rwd_html_PDA_1, $rwd_html_PDA_2 = $rwd_html["PDA"].split(/^\s*%BODY%\s*\r*$/)