rwdtorrent 0.01

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