rwdmovies 0.6 → 0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. data/Readme.txt +47 -30
  2. data/code/ag1core/aa0begin.rb +18 -18
  3. data/code/ag1core/rwdtinkerversion.rb +15 -15
  4. data/code/xa5rwdtinkercallable/callable.rb +12 -12
  5. data/code/xb1rwdtinkerbackwindow/diagnostictab.rb +21 -21
  6. data/code/xb1rwdtinkerbackwindow/{lm1installapplet.rb → installapplet.rb} +21 -20
  7. data/code/xb1rwdtinkerbackwindow/{05listinstalledfiles.rb → listinstalledfiles.rb} +1 -1
  8. data/code/xb1rwdtinkerbackwindow/{ll5listzips.rb → listzips.rb} +9 -7
  9. data/code/xb1rwdtinkerbackwindow/loadconfigurationrecord.rb +32 -0
  10. data/code/xb1rwdtinkerbackwindow/loadconfigurationvariables.rb +13 -0
  11. data/code/xb1rwdtinkerbackwindow/{ll1openname.rb → openappletname.rb} +18 -18
  12. data/code/xb1rwdtinkerbackwindow/{mm1removeapplet.rb → removeapplet.rb} +28 -28
  13. data/code/xb1rwdtinkerbackwindow/rwdtinkerwin2version.rb +14 -14
  14. data/code/xb1rwdtinkerbackwindow/saveconfigurationrecord.rb +18 -0
  15. data/code/zz0applicationend/zz0end.rb +4 -4
  16. data/configuration/language.cnf +5 -0
  17. data/configuration/rwdmovies.cnf +0 -1
  18. data/configuration/rwdmoviesversion.cnf +2 -0
  19. data/configuration/rwdplayscriptsversion.cnf +2 -0
  20. data/configuration/rwdtinker.cnf +12 -0
  21. data/configuration/rwdtinkerversion.cnf +2 -0
  22. data/configuration/tinkerwin2variables.cnf +8 -0
  23. data/configuration/tinkerwin2version.cnf +3 -0
  24. data/ev/browser.rb +109 -109
  25. data/ev/ftools.rb +170 -170
  26. data/ev/net.rb +750 -750
  27. data/ev/ruby.rb +819 -819
  28. data/ev/rwd.rb +1848 -1848
  29. data/ev/sgml.rb +236 -236
  30. data/ev/thread.rb +63 -63
  31. data/ev/tree.rb +343 -343
  32. data/ev/xml.rb +4 -4
  33. data/gui/00coreguibegin/applicationguitop.rwd +4 -0
  34. data/gui/{ee1rwdmovies → frontwindow0/superant.com.rwdmovies}/1openmoviedata.rwd +0 -0
  35. data/gui/{ee1rwdmovies → frontwindow0/superant.com.rwdmovies}/2openmoviephoto.rwd +0 -0
  36. data/gui/{ee1rwdmovies → frontwindow0/superant.com.rwdmovies}/3listmoviegfiles.rwd +0 -0
  37. data/gui/{ee1rwdmovies → frontwindow0/superant.com.rwdmovies}/6editrecord.rwd +0 -0
  38. data/gui/{ee1rwdmovies → frontwindow0/superant.com.rwdmovies}/movieutilities.rwd +0 -0
  39. data/gui/{ee1rwdmovies → frontwindow0/superant.com.rwdmovies}/viewconfiguration.rwd +0 -0
  40. data/gui/{ll1selectiontabbegin → frontwindowselectionbegin/selectiontabbegin}/selectiontabbegin.rwd +16 -16
  41. data/gui/{ll5rwdtinkerwin2selectiontab → frontwindowselections/superant.com.rwdtinkerwin2selectiontab}/rwdwin2selectiontab.rwd +12 -12
  42. data/gui/{lz1selectiontabend/endselectiontab.rwd → frontwindowselectionzend/viewselectionzend/viewselectionend.rwd} +3 -3
  43. data/gui/{tt0documentsbegin → frontwindowtdocumentbegin/superant.com.documentsbegin}/tt0documentbegin.rwd +6 -6
  44. data/gui/{uu5rwddocuments → frontwindowtdocuments/superant.com.documents}/uu5documents.rwd +15 -15
  45. data/gui/{uv7rwdmovies → frontwindowtdocuments/superant.com.rwdmovies}/uv7docmovies.rwd +0 -0
  46. data/gui/{uu6rwdtinkerwin2documents → frontwindowtdocuments/superant.com.tinkerwin2documents}/uu5documents.rwd +6 -6
  47. data/gui/{ww0documentsend → frontwindowtdocumentzend/superant.com.documentsend}/ww0documentend.rwd +7 -7
  48. data/gui/{wz6finaltabs → frontwindowz1end/frontwindowend}/xx0rwdfirsttab.rwd +6 -6
  49. data/gui/{ya1helpaboutbegin → helpaboutbegin/superant.com.helpaboutbegin}/ya0helpscreenstart.rwd +3 -3
  50. data/gui/{yl2rwdmovieshelpabout → helpaboutinstalled/superant.com.rwdmovieshelpabout}/1movies.rwd +0 -0
  51. data/gui/{yl2rwdmovieshelpabout → helpaboutinstalled/superant.com.rwdmovieshelpabout}/2movies.rwd +0 -0
  52. data/gui/{yl2rwdmovieshelpabout → helpaboutinstalled/superant.com.rwdmovieshelpabout}/5version.rwd +0 -0
  53. data/gui/{yg6rwdwin2helpabout → helpaboutinstalled/superant.com.rwdwin2helpabout}/1appname.rwd +4 -4
  54. data/gui/{yg5rwdhelpabout → helpaboutinstalled/superant.com.rwdwin2helpabout}/3copyright.rwd +3 -3
  55. data/gui/{yg6rwdwin2helpabout → helpaboutinstalled/superant.com.rwdwin2helpabout}/5version.rwd +10 -10
  56. data/gui/{yg5rwdhelpabout → helpaboutinstalled/superant.com.tinkerhelpabout}/1appname.rwd +4 -4
  57. data/gui/{yg6rwdwin2helpabout → helpaboutinstalled/superant.com.tinkerhelpabout}/3copyright.rwd +3 -3
  58. data/gui/helpaboutinstalled/superant.com.tinkerhelpabout/5version.rwd +10 -0
  59. data/gui/helpaboutzend/superant.com.helpaboutend/helpscreenend.rwd +3 -0
  60. data/gui/{xx8rwdmoviespicture → tinkerbackwindows/superant.com.rwdmoviespicture}/xx8moviephotoview.rwd +0 -0
  61. data/gui/{xa5rwdtinkercallablewindow → tinkerbackwindows/superant.com.tinercallablewindow}/1appname.rwd +17 -17
  62. data/gui/{xa5rwdtinkercallablewindow → tinkerbackwindows/superant.com.tinercallablewindow}/9end.rwd +4 -4
  63. data/gui/{xb1rwdtinkerbackwindow → tinkerbackwindows/superant.com.tinkerbackwindow}/1appname.rwd +5 -5
  64. data/gui/{xb1rwdtinkerbackwindow → tinkerbackwindows/superant.com.tinkerbackwindow}/3arwddiagnostics.rwd +33 -33
  65. data/gui/tinkerbackwindows/superant.com.tinkerbackwindow/40editconfiguration.rwd +36 -0
  66. data/gui/{xb1rwdtinkerbackwindow/4arwdlistapplets.rwd → tinkerbackwindows/superant.com.tinkerbackwindow/50rwdlistapplets.rwd} +44 -44
  67. data/gui/{xb1rwdtinkerbackwindow/4arwdlistzips.rwd → tinkerbackwindows/superant.com.tinkerbackwindow/50rwdlistzips.rwd} +35 -35
  68. data/gui/{xb1rwdtinkerbackwindow/2tab1.rwd → tinkerbackwindows/superant.com.tinkerbackwindow/80tab1.rwd} +11 -11
  69. data/gui/{xb1rwdtinkerbackwindow → tinkerbackwindows/superant.com.tinkerbackwindow}/9backend.rwd +6 -6
  70. data/gui/{xa1versionwindow → tinkerbackwindows/superant.com.versionwindow}/1appname.rwd +19 -19
  71. data/gui/{za1applicationend → zzcoreguiend/tinkerapplicationguiend}/yy9rwdend.rwd +4 -4
  72. data/init.rb +233 -233
  73. data/installed/rwdtinkerwin2-0.5.inf +8 -8
  74. data/installed/rwdviewlogo-0.4.inf +4 -0
  75. data/lang/alanguagehashbegin.rb +4 -4
  76. data/lang/en/rwdcore/languagefile.rb +15 -15
  77. data/lang/es/rwdcore/languagefile-es.rb +14 -14
  78. data/lang/jp/rwdcore/languagefile.rb +9 -0
  79. data/lang/languagehash.rb +4 -4
  80. data/lang/nl/rwdcore/languagefile.rb +19 -0
  81. data/lang/templangfile.rb +15 -21
  82. data/lang/vlanguagehashend.rb +6 -6
  83. data/lang/wlocallangstart.rb +5 -5
  84. data/lang/xlocallangfile.rb +16 -10
  85. data/lang/zlocallangend.rb +2 -2
  86. data/lib/temp.rb +1 -1
  87. data/rwd_files/HowTo_Movies.txt +2 -0
  88. data/rwd_files/HowTo_Tinker.txt +318 -276
  89. data/rwd_files/HowTo_TinkerWin2.txt +202 -202
  90. data/rwd_files/Readme.txt +57 -57
  91. data/rwd_files/moviestmp.jpg +0 -0
  92. data/rwd_files/rdoc-style.css +174 -174
  93. data/rwd_files/rwdapplications.html +54 -54
  94. data/rwd_files/tinker.png +0 -0
  95. data/tests/rwdtinkertestEN.rb +163 -0
  96. data/tests/test.result +32 -0
  97. data/tests/totranslate.lang +93 -93
  98. data/zips/rwdahelloworld-0.5.zip +0 -0
  99. metadata +96 -75
  100. data/code/gh9calendar/gh9calendar.rb +0 -16
  101. data/configuration/aa0rwdframework.cnf +0 -14
  102. data/configuration/ab1tinkerwin2.cnf +0 -4
  103. data/gui/aa2core/aa0rwdtop.rwd +0 -4
  104. data/gui/yg5rwdhelpabout/5version.rwd +0 -10
  105. data/gui/yy5helpaboutend/helpscreenend.rwd +0 -3
  106. data/installed/rubyslippers-0.94.inf +0 -9
  107. data/installed/rwdcalendar-0.5.inf +0 -8
  108. data/lang/en/rwdcalendar/calendar-nl.rb +0 -6
  109. data/lang/es/rwdcalendar/calendar-nl.rb +0 -6
  110. data/lang/nl/rwdcalendar/calendar-nl.rb +0 -6
  111. data/lang/nl/rwdcore/languagefile-nl.rb +0 -4
  112. data/zips/rwdacalendar-0.5.zip +0 -0
  113. data/zips/rwdhelloworld-0.3.zip +0 -0
  114. data/zips/rwdwshell-0.91.zip +0 -0
  115. data/zips/wrubyslippers-0.93.zip +0 -0
data/ev/rwd.rb CHANGED
@@ -1,1848 +1,1848 @@
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'" % 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*$/)