tk-win 0.2.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (329) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +17 -0
  5. data/Rakefile +46 -0
  6. data/VERSION +1 -0
  7. data/lib/tcltk.rb +367 -0
  8. data/lib/tk.rb +5682 -0
  9. data/lib/tk/after.rb +6 -0
  10. data/lib/tk/autoload.rb +760 -0
  11. data/lib/tk/bgerror.rb +29 -0
  12. data/lib/tk/bindtag.rb +138 -0
  13. data/lib/tk/button.rb +31 -0
  14. data/lib/tk/canvas.rb +816 -0
  15. data/lib/tk/canvastag.rb +459 -0
  16. data/lib/tk/checkbutton.rb +32 -0
  17. data/lib/tk/clipboard.rb +75 -0
  18. data/lib/tk/clock.rb +71 -0
  19. data/lib/tk/composite.rb +484 -0
  20. data/lib/tk/console.rb +52 -0
  21. data/lib/tk/dialog.rb +326 -0
  22. data/lib/tk/encodedstr.rb +187 -0
  23. data/lib/tk/entry.rb +120 -0
  24. data/lib/tk/event.rb +562 -0
  25. data/lib/tk/font.rb +2351 -0
  26. data/lib/tk/frame.rb +132 -0
  27. data/lib/tk/grid.rb +279 -0
  28. data/lib/tk/image.rb +275 -0
  29. data/lib/tk/itemconfig.rb +1222 -0
  30. data/lib/tk/itemfont.rb +327 -0
  31. data/lib/tk/kinput.rb +71 -0
  32. data/lib/tk/label.rb +22 -0
  33. data/lib/tk/labelframe.rb +31 -0
  34. data/lib/tk/listbox.rb +284 -0
  35. data/lib/tk/macpkg.rb +80 -0
  36. data/lib/tk/menu.rb +718 -0
  37. data/lib/tk/menubar.rb +137 -0
  38. data/lib/tk/menuspec.rb +456 -0
  39. data/lib/tk/message.rb +24 -0
  40. data/lib/tk/mngfocus.rb +33 -0
  41. data/lib/tk/msgcat.rb +296 -0
  42. data/lib/tk/namespace.rb +551 -0
  43. data/lib/tk/optiondb.rb +377 -0
  44. data/lib/tk/optionobj.rb +212 -0
  45. data/lib/tk/pack.rb +107 -0
  46. data/lib/tk/package.rb +143 -0
  47. data/lib/tk/palette.rb +55 -0
  48. data/lib/tk/panedwindow.rb +260 -0
  49. data/lib/tk/place.rb +128 -0
  50. data/lib/tk/radiobutton.rb +73 -0
  51. data/lib/tk/root.rb +95 -0
  52. data/lib/tk/scale.rb +112 -0
  53. data/lib/tk/scrollable.rb +82 -0
  54. data/lib/tk/scrollbar.rb +183 -0
  55. data/lib/tk/scrollbox.rb +39 -0
  56. data/lib/tk/selection.rb +86 -0
  57. data/lib/tk/spinbox.rb +144 -0
  58. data/lib/tk/tagfont.rb +43 -0
  59. data/lib/tk/text.rb +1604 -0
  60. data/lib/tk/textimage.rb +88 -0
  61. data/lib/tk/textmark.rb +204 -0
  62. data/lib/tk/texttag.rb +321 -0
  63. data/lib/tk/textwindow.rb +154 -0
  64. data/lib/tk/timer.rb +669 -0
  65. data/lib/tk/toplevel.rb +264 -0
  66. data/lib/tk/ttk_selector.rb +98 -0
  67. data/lib/tk/txtwin_abst.rb +39 -0
  68. data/lib/tk/validation.rb +397 -0
  69. data/lib/tk/variable.rb +1799 -0
  70. data/lib/tk/virtevent.rb +139 -0
  71. data/lib/tk/winfo.rb +392 -0
  72. data/lib/tk/winpkg.rb +156 -0
  73. data/lib/tk/wm.rb +552 -0
  74. data/lib/tk/xim.rb +122 -0
  75. data/lib/tkafter.rb +4 -0
  76. data/lib/tkbgerror.rb +4 -0
  77. data/lib/tkcanvas.rb +4 -0
  78. data/lib/tkclass.rb +47 -0
  79. data/lib/tkconsole.rb +4 -0
  80. data/lib/tkdialog.rb +4 -0
  81. data/lib/tkentry.rb +4 -0
  82. data/lib/tkextlib/ICONS.rb +13 -0
  83. data/lib/tkextlib/ICONS/icons.rb +129 -0
  84. data/lib/tkextlib/ICONS/setup.rb +8 -0
  85. data/lib/tkextlib/SUPPORT_STATUS +198 -0
  86. data/lib/tkextlib/blt.rb +189 -0
  87. data/lib/tkextlib/blt/barchart.rb +79 -0
  88. data/lib/tkextlib/blt/bitmap.rb +112 -0
  89. data/lib/tkextlib/blt/busy.rb +83 -0
  90. data/lib/tkextlib/blt/component.rb +2218 -0
  91. data/lib/tkextlib/blt/container.rb +28 -0
  92. data/lib/tkextlib/blt/cutbuffer.rb +23 -0
  93. data/lib/tkextlib/blt/dragdrop.rb +269 -0
  94. data/lib/tkextlib/blt/eps.rb +32 -0
  95. data/lib/tkextlib/blt/graph.rb +67 -0
  96. data/lib/tkextlib/blt/htext.rb +112 -0
  97. data/lib/tkextlib/blt/setup.rb +8 -0
  98. data/lib/tkextlib/blt/spline.rb +23 -0
  99. data/lib/tkextlib/blt/stripchart.rb +74 -0
  100. data/lib/tkextlib/blt/table.rb +412 -0
  101. data/lib/tkextlib/blt/tabnotebook.rb +110 -0
  102. data/lib/tkextlib/blt/tabset.rb +504 -0
  103. data/lib/tkextlib/blt/ted.rb +68 -0
  104. data/lib/tkextlib/blt/tile.rb +25 -0
  105. data/lib/tkextlib/blt/tile/button.rb +16 -0
  106. data/lib/tkextlib/blt/tile/checkbutton.rb +17 -0
  107. data/lib/tkextlib/blt/tile/frame.rb +16 -0
  108. data/lib/tkextlib/blt/tile/label.rb +16 -0
  109. data/lib/tkextlib/blt/tile/radiobutton.rb +17 -0
  110. data/lib/tkextlib/blt/tile/scrollbar.rb +16 -0
  111. data/lib/tkextlib/blt/tile/toplevel.rb +16 -0
  112. data/lib/tkextlib/blt/tree.rb +1058 -0
  113. data/lib/tkextlib/blt/treeview.rb +1287 -0
  114. data/lib/tkextlib/blt/unix_dnd.rb +141 -0
  115. data/lib/tkextlib/blt/vector.rb +256 -0
  116. data/lib/tkextlib/blt/watch.rb +175 -0
  117. data/lib/tkextlib/blt/win_printer.rb +61 -0
  118. data/lib/tkextlib/blt/winop.rb +107 -0
  119. data/lib/tkextlib/bwidget.rb +153 -0
  120. data/lib/tkextlib/bwidget/arrowbutton.rb +21 -0
  121. data/lib/tkextlib/bwidget/bitmap.rb +21 -0
  122. data/lib/tkextlib/bwidget/button.rb +31 -0
  123. data/lib/tkextlib/bwidget/buttonbox.rb +90 -0
  124. data/lib/tkextlib/bwidget/combobox.rb +62 -0
  125. data/lib/tkextlib/bwidget/dialog.rb +194 -0
  126. data/lib/tkextlib/bwidget/dragsite.rb +31 -0
  127. data/lib/tkextlib/bwidget/dropsite.rb +39 -0
  128. data/lib/tkextlib/bwidget/dynamichelp.rb +63 -0
  129. data/lib/tkextlib/bwidget/entry.rb +43 -0
  130. data/lib/tkextlib/bwidget/label.rb +41 -0
  131. data/lib/tkextlib/bwidget/labelentry.rb +80 -0
  132. data/lib/tkextlib/bwidget/labelframe.rb +52 -0
  133. data/lib/tkextlib/bwidget/listbox.rb +361 -0
  134. data/lib/tkextlib/bwidget/mainframe.rb +132 -0
  135. data/lib/tkextlib/bwidget/messagedlg.rb +192 -0
  136. data/lib/tkextlib/bwidget/notebook.rb +166 -0
  137. data/lib/tkextlib/bwidget/pagesmanager.rb +73 -0
  138. data/lib/tkextlib/bwidget/panedwindow.rb +42 -0
  139. data/lib/tkextlib/bwidget/panelframe.rb +67 -0
  140. data/lib/tkextlib/bwidget/passwddlg.rb +44 -0
  141. data/lib/tkextlib/bwidget/progressbar.rb +20 -0
  142. data/lib/tkextlib/bwidget/progressdlg.rb +58 -0
  143. data/lib/tkextlib/bwidget/scrollableframe.rb +40 -0
  144. data/lib/tkextlib/bwidget/scrolledwindow.rb +48 -0
  145. data/lib/tkextlib/bwidget/scrollview.rb +25 -0
  146. data/lib/tkextlib/bwidget/selectcolor.rb +73 -0
  147. data/lib/tkextlib/bwidget/selectfont.rb +91 -0
  148. data/lib/tkextlib/bwidget/separator.rb +20 -0
  149. data/lib/tkextlib/bwidget/setup.rb +8 -0
  150. data/lib/tkextlib/bwidget/spinbox.rb +98 -0
  151. data/lib/tkextlib/bwidget/statusbar.rb +62 -0
  152. data/lib/tkextlib/bwidget/titleframe.rb +33 -0
  153. data/lib/tkextlib/bwidget/tree.rb +500 -0
  154. data/lib/tkextlib/bwidget/widget.rb +129 -0
  155. data/lib/tkextlib/itcl.rb +13 -0
  156. data/lib/tkextlib/itcl/incr_tcl.rb +178 -0
  157. data/lib/tkextlib/itcl/setup.rb +13 -0
  158. data/lib/tkextlib/itk.rb +13 -0
  159. data/lib/tkextlib/itk/incr_tk.rb +446 -0
  160. data/lib/tkextlib/itk/setup.rb +13 -0
  161. data/lib/tkextlib/iwidgets.rb +94 -0
  162. data/lib/tkextlib/iwidgets/buttonbox.rb +121 -0
  163. data/lib/tkextlib/iwidgets/calendar.rb +125 -0
  164. data/lib/tkextlib/iwidgets/canvasprintbox.rb +53 -0
  165. data/lib/tkextlib/iwidgets/canvasprintdialog.rb +38 -0
  166. data/lib/tkextlib/iwidgets/checkbox.rb +130 -0
  167. data/lib/tkextlib/iwidgets/combobox.rb +104 -0
  168. data/lib/tkextlib/iwidgets/dateentry.rb +20 -0
  169. data/lib/tkextlib/iwidgets/datefield.rb +58 -0
  170. data/lib/tkextlib/iwidgets/dialog.rb +20 -0
  171. data/lib/tkextlib/iwidgets/dialogshell.rb +121 -0
  172. data/lib/tkextlib/iwidgets/disjointlistbox.rb +50 -0
  173. data/lib/tkextlib/iwidgets/entryfield.rb +185 -0
  174. data/lib/tkextlib/iwidgets/extbutton.rb +40 -0
  175. data/lib/tkextlib/iwidgets/extfileselectionbox.rb +46 -0
  176. data/lib/tkextlib/iwidgets/extfileselectiondialog.rb +33 -0
  177. data/lib/tkextlib/iwidgets/feedback.rb +35 -0
  178. data/lib/tkextlib/iwidgets/fileselectionbox.rb +46 -0
  179. data/lib/tkextlib/iwidgets/fileselectiondialog.rb +33 -0
  180. data/lib/tkextlib/iwidgets/finddialog.rb +42 -0
  181. data/lib/tkextlib/iwidgets/hierarchy.rb +365 -0
  182. data/lib/tkextlib/iwidgets/hyperhelp.rb +50 -0
  183. data/lib/tkextlib/iwidgets/labeledframe.rb +39 -0
  184. data/lib/tkextlib/iwidgets/labeledwidget.rb +45 -0
  185. data/lib/tkextlib/iwidgets/mainwindow.rb +67 -0
  186. data/lib/tkextlib/iwidgets/menubar.rb +212 -0
  187. data/lib/tkextlib/iwidgets/messagebox.rb +93 -0
  188. data/lib/tkextlib/iwidgets/messagedialog.rb +20 -0
  189. data/lib/tkextlib/iwidgets/notebook.rb +175 -0
  190. data/lib/tkextlib/iwidgets/optionmenu.rb +92 -0
  191. data/lib/tkextlib/iwidgets/panedwindow.rb +134 -0
  192. data/lib/tkextlib/iwidgets/promptdialog.rb +131 -0
  193. data/lib/tkextlib/iwidgets/pushbutton.rb +35 -0
  194. data/lib/tkextlib/iwidgets/radiobox.rb +121 -0
  195. data/lib/tkextlib/iwidgets/scopedobject.rb +24 -0
  196. data/lib/tkextlib/iwidgets/scrolledcanvas.rb +353 -0
  197. data/lib/tkextlib/iwidgets/scrolledframe.rb +59 -0
  198. data/lib/tkextlib/iwidgets/scrolledhtml.rb +58 -0
  199. data/lib/tkextlib/iwidgets/scrolledlistbox.rb +207 -0
  200. data/lib/tkextlib/iwidgets/scrolledtext.rb +568 -0
  201. data/lib/tkextlib/iwidgets/scrolledwidget.rb +20 -0
  202. data/lib/tkextlib/iwidgets/selectionbox.rb +102 -0
  203. data/lib/tkextlib/iwidgets/selectiondialog.rb +92 -0
  204. data/lib/tkextlib/iwidgets/setup.rb +8 -0
  205. data/lib/tkextlib/iwidgets/shell.rb +38 -0
  206. data/lib/tkextlib/iwidgets/spindate.rb +48 -0
  207. data/lib/tkextlib/iwidgets/spinint.rb +30 -0
  208. data/lib/tkextlib/iwidgets/spinner.rb +169 -0
  209. data/lib/tkextlib/iwidgets/spintime.rb +48 -0
  210. data/lib/tkextlib/iwidgets/tabnotebook.rb +181 -0
  211. data/lib/tkextlib/iwidgets/tabset.rb +145 -0
  212. data/lib/tkextlib/iwidgets/timeentry.rb +25 -0
  213. data/lib/tkextlib/iwidgets/timefield.rb +58 -0
  214. data/lib/tkextlib/iwidgets/toolbar.rb +112 -0
  215. data/lib/tkextlib/iwidgets/watch.rb +56 -0
  216. data/lib/tkextlib/pkg_checker.rb +184 -0
  217. data/lib/tkextlib/setup.rb +8 -0
  218. data/lib/tkextlib/tcllib.rb +105 -0
  219. data/lib/tkextlib/tcllib/autoscroll.rb +158 -0
  220. data/lib/tkextlib/tcllib/ctext.rb +160 -0
  221. data/lib/tkextlib/tcllib/cursor.rb +97 -0
  222. data/lib/tkextlib/tcllib/datefield.rb +57 -0
  223. data/lib/tkextlib/tcllib/dialog.rb +84 -0
  224. data/lib/tkextlib/tcllib/getstring.rb +134 -0
  225. data/lib/tkextlib/tcllib/history.rb +73 -0
  226. data/lib/tkextlib/tcllib/ico.rb +146 -0
  227. data/lib/tkextlib/tcllib/ip_entry.rb +75 -0
  228. data/lib/tkextlib/tcllib/panelframe.rb +78 -0
  229. data/lib/tkextlib/tcllib/plotchart.rb +1404 -0
  230. data/lib/tkextlib/tcllib/ruler.rb +65 -0
  231. data/lib/tkextlib/tcllib/screenruler.rb +68 -0
  232. data/lib/tkextlib/tcllib/scrollwin.rb +61 -0
  233. data/lib/tkextlib/tcllib/setup.rb +8 -0
  234. data/lib/tkextlib/tcllib/style.rb +61 -0
  235. data/lib/tkextlib/tcllib/superframe.rb +51 -0
  236. data/lib/tkextlib/tcllib/swaplist.rb +150 -0
  237. data/lib/tkextlib/tcllib/tablelist.rb +28 -0
  238. data/lib/tkextlib/tcllib/tablelist_core.rb +1072 -0
  239. data/lib/tkextlib/tcllib/tablelist_tile.rb +43 -0
  240. data/lib/tkextlib/tcllib/tkpiechart.rb +314 -0
  241. data/lib/tkextlib/tcllib/tooltip.rb +104 -0
  242. data/lib/tkextlib/tcllib/widget.rb +82 -0
  243. data/lib/tkextlib/tclx.rb +13 -0
  244. data/lib/tkextlib/tclx/setup.rb +8 -0
  245. data/lib/tkextlib/tclx/tclx.rb +74 -0
  246. data/lib/tkextlib/tile.rb +449 -0
  247. data/lib/tkextlib/tile/dialog.rb +102 -0
  248. data/lib/tkextlib/tile/setup.rb +8 -0
  249. data/lib/tkextlib/tile/sizegrip.rb +32 -0
  250. data/lib/tkextlib/tile/style.rb +336 -0
  251. data/lib/tkextlib/tile/tbutton.rb +34 -0
  252. data/lib/tkextlib/tile/tcheckbutton.rb +38 -0
  253. data/lib/tkextlib/tile/tcombobox.rb +55 -0
  254. data/lib/tkextlib/tile/tentry.rb +49 -0
  255. data/lib/tkextlib/tile/tframe.rb +34 -0
  256. data/lib/tkextlib/tile/tlabel.rb +34 -0
  257. data/lib/tkextlib/tile/tlabelframe.rb +38 -0
  258. data/lib/tkextlib/tile/tmenubutton.rb +38 -0
  259. data/lib/tkextlib/tile/tnotebook.rb +147 -0
  260. data/lib/tkextlib/tile/tpaned.rb +245 -0
  261. data/lib/tkextlib/tile/tprogressbar.rb +57 -0
  262. data/lib/tkextlib/tile/tradiobutton.rb +38 -0
  263. data/lib/tkextlib/tile/treeview.rb +1306 -0
  264. data/lib/tkextlib/tile/tscale.rb +56 -0
  265. data/lib/tkextlib/tile/tscrollbar.rb +63 -0
  266. data/lib/tkextlib/tile/tseparator.rb +34 -0
  267. data/lib/tkextlib/tile/tsquare.rb +30 -0
  268. data/lib/tkextlib/tkDND.rb +18 -0
  269. data/lib/tkextlib/tkDND/setup.rb +8 -0
  270. data/lib/tkextlib/tkDND/shape.rb +125 -0
  271. data/lib/tkextlib/tkDND/tkdnd.rb +182 -0
  272. data/lib/tkextlib/tkHTML.rb +13 -0
  273. data/lib/tkextlib/tkHTML/htmlwidget.rb +453 -0
  274. data/lib/tkextlib/tkHTML/setup.rb +8 -0
  275. data/lib/tkextlib/tkimg.rb +36 -0
  276. data/lib/tkextlib/tkimg/bmp.rb +33 -0
  277. data/lib/tkextlib/tkimg/gif.rb +33 -0
  278. data/lib/tkextlib/tkimg/ico.rb +33 -0
  279. data/lib/tkextlib/tkimg/jpeg.rb +33 -0
  280. data/lib/tkextlib/tkimg/pcx.rb +33 -0
  281. data/lib/tkextlib/tkimg/pixmap.rb +44 -0
  282. data/lib/tkextlib/tkimg/png.rb +33 -0
  283. data/lib/tkextlib/tkimg/ppm.rb +33 -0
  284. data/lib/tkextlib/tkimg/ps.rb +33 -0
  285. data/lib/tkextlib/tkimg/setup.rb +8 -0
  286. data/lib/tkextlib/tkimg/sgi.rb +33 -0
  287. data/lib/tkextlib/tkimg/sun.rb +33 -0
  288. data/lib/tkextlib/tkimg/tga.rb +33 -0
  289. data/lib/tkextlib/tkimg/tiff.rb +33 -0
  290. data/lib/tkextlib/tkimg/window.rb +33 -0
  291. data/lib/tkextlib/tkimg/xbm.rb +33 -0
  292. data/lib/tkextlib/tkimg/xpm.rb +33 -0
  293. data/lib/tkextlib/tktable.rb +14 -0
  294. data/lib/tkextlib/tktable/setup.rb +8 -0
  295. data/lib/tkextlib/tktable/tktable.rb +966 -0
  296. data/lib/tkextlib/tktrans.rb +14 -0
  297. data/lib/tkextlib/tktrans/setup.rb +8 -0
  298. data/lib/tkextlib/tktrans/tktrans.rb +64 -0
  299. data/lib/tkextlib/treectrl.rb +13 -0
  300. data/lib/tkextlib/treectrl/setup.rb +8 -0
  301. data/lib/tkextlib/treectrl/tktreectrl.rb +2522 -0
  302. data/lib/tkextlib/trofs.rb +13 -0
  303. data/lib/tkextlib/trofs/setup.rb +8 -0
  304. data/lib/tkextlib/trofs/trofs.rb +51 -0
  305. data/lib/tkextlib/version.rb +6 -0
  306. data/lib/tkextlib/vu.rb +48 -0
  307. data/lib/tkextlib/vu/bargraph.rb +61 -0
  308. data/lib/tkextlib/vu/charts.rb +53 -0
  309. data/lib/tkextlib/vu/dial.rb +102 -0
  310. data/lib/tkextlib/vu/pie.rb +286 -0
  311. data/lib/tkextlib/vu/setup.rb +8 -0
  312. data/lib/tkextlib/vu/spinbox.rb +22 -0
  313. data/lib/tkextlib/winico.rb +14 -0
  314. data/lib/tkextlib/winico/setup.rb +8 -0
  315. data/lib/tkextlib/winico/winico.rb +224 -0
  316. data/lib/tkfont.rb +4 -0
  317. data/lib/tkmacpkg.rb +4 -0
  318. data/lib/tkmenubar.rb +4 -0
  319. data/lib/tkmngfocus.rb +4 -0
  320. data/lib/tkpalette.rb +4 -0
  321. data/lib/tkscrollbox.rb +4 -0
  322. data/lib/tktext.rb +4 -0
  323. data/lib/tkvirtevent.rb +4 -0
  324. data/lib/tkwinpkg.rb +4 -0
  325. data/spec/spec.opts +1 -0
  326. data/spec/spec_helper.rb +9 -0
  327. data/spec/tk-win_spec.rb +7 -0
  328. data/tk-win.gemspec +373 -0
  329. metadata +412 -0
@@ -0,0 +1,1799 @@
1
+ #
2
+ # tk/variable.rb : treat Tk variable object
3
+ #
4
+ require 'tk'
5
+
6
+ class TkVariable
7
+ include Tk
8
+ extend TkCore
9
+
10
+ include Comparable
11
+
12
+ #TkCommandNames = ['tkwait'.freeze].freeze
13
+ TkCommandNames = ['vwait'.freeze].freeze
14
+
15
+ #TkVar_CB_TBL = {}
16
+ #TkVar_ID_TBL = {}
17
+ TkVar_CB_TBL = TkCore::INTERP.create_table
18
+ TkVar_ID_TBL = TkCore::INTERP.create_table
19
+ (Tk_VARIABLE_ID = ["v".freeze, TkUtil.untrust("00000")]).instance_eval{
20
+ @mutex = Mutex.new
21
+ def mutex; @mutex; end
22
+ freeze
23
+ }
24
+ TkCore::INTERP.init_ip_env{
25
+ TkVar_CB_TBL.mutex.synchronize{ TkVar_CB_TBL.clear }
26
+ TkVar_ID_TBL.mutex.synchronize{ TkVar_ID_TBL.clear }
27
+ }
28
+
29
+ major, minor, type, patchlevel = TclTkLib.get_version
30
+ USE_OLD_TRACE_OPTION_STYLE = (major < 8) || (major == 8 && minor < 4)
31
+
32
+ #TkCore::INTERP.add_tk_procs('rb_var', 'args',
33
+ # "ruby [format \"TkVariable.callback %%Q!%s!\" $args]")
34
+ TkCore::INTERP.add_tk_procs('rb_var', 'args', <<-'EOL')
35
+ if {[set st [catch {eval {ruby_cmd TkVariable callback} $args} ret]] != 0} {
36
+ set idx [string first "\n\n" $ret]
37
+ if {$idx > 0} {
38
+ global errorInfo
39
+ set tcl_backtrace $errorInfo
40
+ set errorInfo [string range $ret [expr $idx + 2] \
41
+ [string length $ret]]
42
+ append errorInfo "\n" $tcl_backtrace
43
+ bgerror [string range $ret 0 [expr $idx - 1]]
44
+ } else {
45
+ bgerror $ret
46
+ }
47
+ return ""
48
+ #return -code $st $ret
49
+ } else {
50
+ return $ret
51
+ }
52
+ EOL
53
+
54
+ #def TkVariable.callback(args)
55
+ def TkVariable.callback(id, name1, name2, op)
56
+ #name1,name2,op = tk_split_list(args)
57
+ #name1,name2,op = tk_split_simplelist(args)
58
+ if cb_obj = TkVar_CB_TBL[id]
59
+ #_get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op))
60
+ begin
61
+ _get_eval_string(cb_obj.trace_callback(name2, op))
62
+ rescue SystemExit
63
+ exit(0)
64
+ rescue Interrupt
65
+ exit!(1)
66
+ rescue Exception => e
67
+ begin
68
+ msg = _toUTF8(e.class.inspect) + ': ' +
69
+ _toUTF8(e.message) + "\n" +
70
+ "\n---< backtrace of Ruby side >-----\n" +
71
+ _toUTF8(e.backtrace.join("\n")) +
72
+ "\n---< backtrace of Tk side >-------"
73
+ if TkCore::WITH_ENCODING
74
+ msg.force_encoding('utf-8')
75
+ else
76
+ msg.instance_variable_set(:@encoding, 'utf-8')
77
+ end
78
+ rescue Exception
79
+ msg = e.class.inspect + ': ' + e.message + "\n" +
80
+ "\n---< backtrace of Ruby side >-----\n" +
81
+ e.backtrace.join("\n") +
82
+ "\n---< backtrace of Tk side >-------"
83
+ end
84
+ fail(e, msg)
85
+ end
86
+ =begin
87
+ begin
88
+ raise 'check backtrace'
89
+ rescue
90
+ # ignore backtrace before 'callback'
91
+ pos = -($!.backtrace.size)
92
+ end
93
+ begin
94
+ _get_eval_string(TkVar_CB_TBL[name1].trace_callback(name2,op))
95
+ rescue
96
+ trace = $!.backtrace
97
+ raise $!, "\n#{trace[0]}: #{$!.message} (#{$!.class})\n" +
98
+ "\tfrom #{trace[1..pos].join("\n\tfrom ")}"
99
+ end
100
+ =end
101
+ else
102
+ ''
103
+ end
104
+ end
105
+
106
+ def self.new_hash(val = {})
107
+ if val.kind_of?(Hash)
108
+ self.new(val)
109
+ else
110
+ fail ArgumentError, 'Hash is expected'
111
+ end
112
+ end
113
+
114
+ #
115
+ # default_value is available only when the variable is an assoc array.
116
+ #
117
+ def default_value(val=nil, &b)
118
+ if b
119
+ @def_default = :proc
120
+ @default_val = proc(&b)
121
+ else
122
+ @def_default = :val
123
+ @default_val = val
124
+ end
125
+ self
126
+ end
127
+ def set_default_value(val)
128
+ @def_default = :val
129
+ @default_val = val
130
+ self
131
+ end
132
+ alias default_value= set_default_value
133
+ def default_proc(cmd = Proc.new)
134
+ @def_default = :proc
135
+ @default_val = cmd
136
+ self
137
+ end
138
+
139
+ def undef_default
140
+ @default_val = nil
141
+ @def_default = false
142
+ self
143
+ end
144
+
145
+ def default_value_type
146
+ @type
147
+ end
148
+ def default_element_value_type(idxs)
149
+ if idxs.kind_of?(Array)
150
+ index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',')
151
+ else
152
+ index = _get_eval_string(idxs, true)
153
+ end
154
+ @element_type[index]
155
+ end
156
+
157
+ def _set_default_value_type_core(type, idxs)
158
+ if type.kind_of?(Class)
159
+ if type == NilClass
160
+ type = nil
161
+ elsif type == Numeric
162
+ type = :numeric
163
+ elsif type == TrueClass || type == FalseClass
164
+ type = :bool
165
+ elsif type == String
166
+ type = :string
167
+ elsif type == Symbol
168
+ type = :symbol
169
+ elsif type == Array
170
+ type = :list
171
+ elsif type <= TkVariable
172
+ type = :variable
173
+ elsif type <= TkWindow
174
+ type = :window
175
+ elsif TkComm._callback_entry_class?(type)
176
+ type = :procedure
177
+ else
178
+ type = nil
179
+ end
180
+ else
181
+ case(type)
182
+ when nil
183
+ type = nil
184
+ when :numeric, 'numeric'
185
+ type = :numeric
186
+ when true, false, :bool, 'bool'
187
+ type = :bool
188
+ when :string, 'string'
189
+ type = :string
190
+ when :symbol, 'symbol'
191
+ type = :symbol
192
+ when :list, 'list'
193
+ type = :list
194
+ when :numlist, 'numlist'
195
+ type = :numlist
196
+ when :variable, 'variable'
197
+ type = :variable
198
+ when :window, 'window'
199
+ type = :window
200
+ when :procedure, 'procedure'
201
+ type = :procedure
202
+ else
203
+ return _set_default_value_type_core(type.class, idxs)
204
+ end
205
+ end
206
+ if idxs
207
+ if idxs.kind_of?(Array)
208
+ index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',')
209
+ else
210
+ index = _get_eval_string(idxs, true)
211
+ end
212
+ @element_type[index] = type
213
+ else
214
+ @type = type
215
+ end
216
+ type
217
+ end
218
+ private :_set_default_value_type_core
219
+
220
+ def set_default_value_type(type)
221
+ _set_default_value_type_core(type, nil)
222
+ self
223
+ end
224
+ alias default_value_type= set_default_value_type
225
+
226
+ def set_default_element_value_type(idxs, type)
227
+ _set_default_value_type_core(type, idxs)
228
+ self
229
+ end
230
+
231
+ def _to_default_type(val, idxs = nil)
232
+ if idxs
233
+ if idxs.kind_of?(Array)
234
+ index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',')
235
+ else
236
+ index = _get_eval_string(idxs, true)
237
+ end
238
+ type = @element_type[index]
239
+ else
240
+ type = @type
241
+ end
242
+ return val unless type
243
+ if val.kind_of?(Hash)
244
+ val.keys.each{|k| val[k] = _to_default_type(val[k], idxs) }
245
+ val
246
+ else
247
+ begin
248
+ case(type)
249
+ when :numeric
250
+ number(val)
251
+ when :bool
252
+ TkComm.bool(val)
253
+ when :string
254
+ val
255
+ when :symbol
256
+ val.intern
257
+ when :list
258
+ tk_split_simplelist(val)
259
+ when :numlist
260
+ tk_split_simplelist(val).collect!{|v| number(v)}
261
+ when :variable
262
+ TkVarAccess.new(val)
263
+ when :window
264
+ TkComm.window(val)
265
+ when :procedure
266
+ TkComm.procedure(val)
267
+ else
268
+ val
269
+ end
270
+ rescue
271
+ val
272
+ end
273
+ end
274
+ end
275
+ private :_to_default_type
276
+
277
+ def _to_default_element_type(idxs, val)
278
+ _to_default_type(val, idxs)
279
+ end
280
+ private :_to_default_element_type
281
+
282
+ def initialize(val="", type=nil)
283
+ # @id = Tk_VARIABLE_ID.join('')
284
+ begin
285
+ Tk_VARIABLE_ID.mutex.synchronize{
286
+ @id = Tk_VARIABLE_ID.join(TkCore::INTERP._ip_id_)
287
+ Tk_VARIABLE_ID[1].succ!
288
+ }
289
+ end until INTERP._invoke_without_enc('info', 'globals', @id).empty?
290
+
291
+ TkVar_ID_TBL.mutex.synchronize{
292
+ TkVar_ID_TBL[@id] = self
293
+ }
294
+
295
+ @var = @id
296
+ @elem = nil
297
+
298
+ @def_default = false
299
+ @default_val = nil
300
+
301
+ @trace_var = nil
302
+ @trace_elem = nil
303
+ @trace_opts = nil
304
+
305
+ @type = nil
306
+ var = self
307
+ @element_type = Hash.new{|k,v| var.default_value_type }
308
+
309
+ self.default_value_type = type
310
+
311
+ # teach Tk-ip that @id is global var
312
+ INTERP._invoke_without_enc('global', @id)
313
+ #INTERP._invoke('global', @id)
314
+
315
+ # create and init
316
+ if val.kind_of?(Hash)
317
+ # assoc-array variable
318
+ self[''] = 0
319
+ self.clear
320
+ end
321
+ self.value = val
322
+
323
+ =begin
324
+ if val == []
325
+ # INTERP._eval(format('global %s; set %s(0) 0; unset %s(0)',
326
+ # @id, @id, @id))
327
+ elsif val.kind_of?(Array)
328
+ a = []
329
+ # val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e))}
330
+ # s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"'
331
+ val.each_with_index{|e,i| a.push(i); a.push(e)}
332
+ #s = '"' + array2tk_list(a).gsub(/[\[\]$"]/, '\\\\\&') + '"'
333
+ s = '"' + array2tk_list(a).gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
334
+ INTERP._eval(format('global %s; array set %s %s', @id, @id, s))
335
+ elsif val.kind_of?(Hash)
336
+ #s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
337
+ # .gsub(/[\[\]$"]/, '\\\\\&') + '"'
338
+ s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
339
+ .gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
340
+ INTERP._eval(format('global %s; array set %s %s', @id, @id, s))
341
+ else
342
+ #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"'
343
+ s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
344
+ INTERP._eval(format('global %s; set %s %s', @id, @id, s))
345
+ end
346
+ =end
347
+ =begin
348
+ if val.kind_of?(Hash)
349
+ #s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
350
+ # .gsub(/[\[\]$"]/, '\\\\\&') + '"'
351
+ s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
352
+ .gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
353
+ INTERP._eval(Kernel.format('global %s; array set %s %s', @id, @id, s))
354
+ else
355
+ #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"'
356
+ s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
357
+ INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s))
358
+ end
359
+ =end
360
+ end
361
+
362
+ def wait(on_thread = false, check_root = false)
363
+ if $SAFE >= 4
364
+ fail SecurityError, "can't wait variable at $SAFE >= 4"
365
+ end
366
+ on_thread &= (Thread.list.size != 1)
367
+ if on_thread
368
+ if check_root
369
+ INTERP._thread_tkwait('variable', @id)
370
+ else
371
+ INTERP._thread_vwait(@id)
372
+ end
373
+ else
374
+ if check_root
375
+ INTERP._invoke_without_enc('tkwait', 'variable', @id)
376
+ else
377
+ INTERP._invoke_without_enc('vwait', @id)
378
+ end
379
+ end
380
+ end
381
+ def eventloop_wait(check_root = false)
382
+ wait(false, check_root)
383
+ end
384
+ def thread_wait(check_root = false)
385
+ wait(true, check_root)
386
+ end
387
+ def tkwait(on_thread = true)
388
+ wait(on_thread, true)
389
+ end
390
+ def eventloop_tkwait
391
+ wait(false, true)
392
+ end
393
+ def thread_tkwait
394
+ wait(true, true)
395
+ end
396
+
397
+ def id
398
+ @id
399
+ end
400
+
401
+ def ref(*idxs)
402
+ # "#{@id}(#{idxs.collect{|idx| _get_eval_string(idx)}.join(',')})"
403
+ TkVarAccess.new("#{@id}(#{idxs.collect{|idx| _get_eval_string(idx)}.join(',')})")
404
+ end
405
+
406
+ def is_hash?
407
+ #ITNERP._eval("global #{@id}; array exist #{@id}") == '1'
408
+ INTERP._invoke_without_enc('global', @id)
409
+ # INTERP._invoke_without_enc('array', 'exist', @id) == '1'
410
+ TkComm.bool(INTERP._invoke_without_enc('array', 'exist', @id))
411
+ end
412
+
413
+ def is_scalar?
414
+ ! is_hash?
415
+ end
416
+
417
+ def exist?(*elems)
418
+ INTERP._invoke_without_enc('global', @id)
419
+ if elems.empty?
420
+ TkComm.bool(tk_call('info', 'exist', @id))
421
+ else
422
+ # array
423
+ index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',')
424
+ TkComm.bool(tk_call('info', 'exist', "#{@id}")) &&
425
+ TkComm.bool(tk_call('info', 'exist', "#{@id}(#{index})"))
426
+ end
427
+ end
428
+
429
+ def keys
430
+ if (is_scalar?)
431
+ fail RuntimeError, 'cannot get keys from a scalar variable'
432
+ end
433
+ #tk_split_simplelist(INTERP._eval("global #{@id}; array get #{@id}"))
434
+ INTERP._invoke_without_enc('global', @id)
435
+ #tk_split_simplelist(INTERP._fromUTF8(INTERP._invoke_without_enc('array', 'names', @id)))
436
+ tk_split_simplelist(INTERP._invoke_without_enc('array', 'names', @id),
437
+ false, true)
438
+ end
439
+
440
+ def size
441
+ INTERP._invoke_without_enc('global', @id)
442
+ TkComm.number(INTERP._invoke_without_enc('array', 'size', @id))
443
+ end
444
+
445
+ def clear
446
+ if (is_scalar?)
447
+ fail RuntimeError, 'cannot clear a scalar variable'
448
+ end
449
+ keys.each{|k| unset(k)}
450
+ self
451
+ end
452
+
453
+ def update(hash)
454
+ if (is_scalar?)
455
+ fail RuntimeError, 'cannot update a scalar variable'
456
+ end
457
+ hash.each{|k,v| self[k] = v}
458
+ self
459
+ end
460
+
461
+ unless const_defined?(:USE_TCLs_SET_VARIABLE_FUNCTIONS)
462
+ USE_TCLs_SET_VARIABLE_FUNCTIONS = true
463
+ end
464
+
465
+ if USE_TCLs_SET_VARIABLE_FUNCTIONS
466
+ ###########################################################################
467
+ # use Tcl function version of set tkvariable
468
+ ###########################################################################
469
+
470
+ def _value
471
+ #if INTERP._eval("global #{@id}; array exist #{@id}") == '1'
472
+ INTERP._invoke_without_enc('global', @id)
473
+ # if INTERP._invoke('array', 'exist', @id) == '1'
474
+ if TkComm.bool(INTERP._invoke('array', 'exist', @id))
475
+ #Hash[*tk_split_simplelist(INTERP._eval("global #{@id}; array get #{@id}"))]
476
+ Hash[*tk_split_simplelist(INTERP._invoke('array', 'get', @id))]
477
+ else
478
+ _fromUTF8(INTERP._get_global_var(@id))
479
+ end
480
+ end
481
+
482
+ def value=(val)
483
+ val = val._value if !@type && @type != :variable && val.kind_of?(TkVariable)
484
+ if val.kind_of?(Hash)
485
+ self.clear
486
+ val.each{|k, v|
487
+ #INTERP._set_global_var2(@id, _toUTF8(_get_eval_string(k)),
488
+ # _toUTF8(_get_eval_string(v)))
489
+ INTERP._set_global_var2(@id, _get_eval_string(k, true),
490
+ _get_eval_string(v, true))
491
+ }
492
+ self.value
493
+ # elsif val.kind_of?(Array)
494
+ =begin
495
+ INTERP._set_global_var(@id, '')
496
+ val.each{|v|
497
+ #INTERP._set_variable(@id, _toUTF8(_get_eval_string(v)),
498
+ INTERP._set_variable(@id, _get_eval_string(v, true),
499
+ TclTkLib::VarAccessFlag::GLOBAL_ONLY |
500
+ TclTkLib::VarAccessFlag::LEAVE_ERR_MSG |
501
+ TclTkLib::VarAccessFlag::APPEND_VALUE |
502
+ TclTkLib::VarAccessFlag::LIST_ELEMENT)
503
+ }
504
+ self.value
505
+ =end
506
+ # _fromUTF8(INTERP._set_global_var(@id, array2tk_list(val, true)))
507
+ else
508
+ #_fromUTF8(INTERP._set_global_var(@id, _toUTF8(_get_eval_string(val))))
509
+ _fromUTF8(INTERP._set_global_var(@id, _get_eval_string(val, true)))
510
+ end
511
+ end
512
+
513
+ def _element_value(*idxs)
514
+ index = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',')
515
+ begin
516
+ _fromUTF8(INTERP._get_global_var2(@id, index))
517
+ rescue => e
518
+ case @def_default
519
+ when :proc
520
+ @default_val.call(self, *idxs)
521
+ when :val
522
+ @default_val
523
+ else
524
+ fail e
525
+ end
526
+ end
527
+ #_fromUTF8(INTERP._get_global_var2(@id, index))
528
+ #_fromUTF8(INTERP._get_global_var2(@id, _toUTF8(_get_eval_string(index))))
529
+ #_fromUTF8(INTERP._get_global_var2(@id, _get_eval_string(index, true)))
530
+ end
531
+
532
+ def []=(*args)
533
+ val = args.pop
534
+ type = default_element_value_type(args)
535
+ val = val._value if !type && type != :variable && val.kind_of?(TkVariable)
536
+ index = args.collect{|idx| _get_eval_string(idx, true)}.join(',')
537
+ _fromUTF8(INTERP._set_global_var2(@id, index, _get_eval_string(val, true)))
538
+ #_fromUTF8(INTERP._set_global_var2(@id, _toUTF8(_get_eval_string(index)),
539
+ # _toUTF8(_get_eval_string(val))))
540
+ #_fromUTF8(INTERP._set_global_var2(@id, _get_eval_string(index, true),
541
+ # _get_eval_string(val, true)))
542
+ end
543
+
544
+ def unset(*elems)
545
+ if elems.empty?
546
+ INTERP._unset_global_var(@id)
547
+ else
548
+ index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',')
549
+ INTERP._unset_global_var2(@id, index)
550
+ end
551
+ end
552
+ alias remove unset
553
+
554
+ else
555
+ ###########################################################################
556
+ # use Ruby script version of set tkvariable (traditional methods)
557
+ ###########################################################################
558
+
559
+ def _value
560
+ begin
561
+ INTERP._eval(Kernel.format('global %s; set %s', @id, @id))
562
+ #INTERP._eval(Kernel.format('set %s', @id))
563
+ #INTERP._invoke_without_enc('set', @id)
564
+ rescue
565
+ if INTERP._eval(Kernel.format('global %s; array exists %s',
566
+ @id, @id)) != "1"
567
+ #if INTERP._eval(Kernel.format('array exists %s', @id)) != "1"
568
+ #if INTERP._invoke_without_enc('array', 'exists', @id) != "1"
569
+ fail
570
+ else
571
+ Hash[*tk_split_simplelist(INTERP._eval(Kernel.format('global %s; array get %s', @id, @id)))]
572
+ #Hash[*tk_split_simplelist(_fromUTF8(INTERP._invoke_without_enc('array', 'get', @id)))]
573
+ end
574
+ end
575
+ end
576
+
577
+ def value=(val)
578
+ val = val._value if !@type && @type != :variable && val.kind_of?(TkVariable)
579
+ begin
580
+ #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"'
581
+ s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
582
+ INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s))
583
+ #INTERP._eval(Kernel.format('set %s %s', @id, s))
584
+ #_fromUTF8(INTERP._invoke_without_enc('set', @id, _toUTF8(s)))
585
+ rescue
586
+ if INTERP._eval(Kernel.format('global %s; array exists %s',
587
+ @id, @id)) != "1"
588
+ #if INTERP._eval(Kernel.format('array exists %s', @id)) != "1"
589
+ #if INTERP._invoke_without_enc('array', 'exists', @id) != "1"
590
+ fail
591
+ else
592
+ if val == []
593
+ INTERP._eval(Kernel.format('global %s; unset %s; set %s(0) 0; unset %s(0)', @id, @id, @id, @id))
594
+ #INTERP._eval(Kernel.format('unset %s; set %s(0) 0; unset %s(0)',
595
+ # @id, @id, @id))
596
+ #INTERP._invoke_without_enc('unset', @id)
597
+ #INTERP._invoke_without_enc('set', @id+'(0)', 0)
598
+ #INTERP._invoke_without_enc('unset', @id+'(0)')
599
+ elsif val.kind_of?(Array)
600
+ a = []
601
+ val.each_with_index{|e,i| a.push(i); a.push(array2tk_list(e, true))}
602
+ #s = '"' + a.join(" ").gsub(/[\[\]$"]/, '\\\\\&') + '"'
603
+ s = '"' + a.join(" ").gsub(/[\[\]$"\\]/, '\\\\\&') + '"'
604
+ INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s',
605
+ @id, @id, @id, s))
606
+ #INTERP._eval(Kernel.format('unset %s; array set %s %s',
607
+ # @id, @id, s))
608
+ #INTERP._invoke_without_enc('unset', @id)
609
+ #_fromUTF8(INTERP._invoke_without_enc('array','set', @id, _toUTF8(s)))
610
+ elsif val.kind_of?(Hash)
611
+ #s = '"' + val.to_a.collect{|e| array2tk_list(e)}.join(" ")\
612
+ # .gsub(/[\[\]$"]/, '\\\\\&') + '"'
613
+ s = '"' + val.to_a.collect{|e| array2tk_list(e, true)}.join(" ")\
614
+ .gsub(/[\[\]$\\"]/, '\\\\\&') + '"'
615
+ INTERP._eval(Kernel.format('global %s; unset %s; array set %s %s',
616
+ @id, @id, @id, s))
617
+ #INTERP._eval(Kernel.format('unset %s; array set %s %s',
618
+ # @id, @id, s))
619
+ #INTERP._invoke_without_enc('unset', @id)
620
+ #_fromUTF8(INTERP._invoke_without_enc('array','set', @id, _toUTF8(s)))
621
+ else
622
+ fail
623
+ end
624
+ end
625
+ end
626
+ end
627
+
628
+ def _element_value(*idxs)
629
+ index = idxs.collect{|idx| _get_eval_string(idx)}.join(',')
630
+ begin
631
+ INTERP._eval(Kernel.format('global %s; set %s(%s)', @id, @id, index))
632
+ rescue => e
633
+ case @def_default
634
+ when :proc
635
+ @default_val.call(self, *idxs)
636
+ when :val
637
+ @default_val
638
+ else
639
+ fail e
640
+ end
641
+ end
642
+ #INTERP._eval(Kernel.format('global %s; set %s(%s)', @id, @id, index))
643
+ #INTERP._eval(Kernel.format('global %s; set %s(%s)',
644
+ # @id, @id, _get_eval_string(index)))
645
+ #INTERP._eval(Kernel.format('set %s(%s)', @id, _get_eval_string(index)))
646
+ #INTERP._eval('set ' + @id + '(' + _get_eval_string(index) + ')')
647
+ end
648
+
649
+ def []=(*args)
650
+ val = args.pop
651
+ type = default_element_value_type(args)
652
+ val = val._value if !type && type != :variable && val.kind_of?(TkVariable)
653
+ index = args.collect{|idx| _get_eval_string(idx)}.join(',')
654
+ INTERP._eval(Kernel.format('global %s; set %s(%s) %s', @id, @id,
655
+ index, _get_eval_string(val)))
656
+ #INTERP._eval(Kernel.format('global %s; set %s(%s) %s', @id, @id,
657
+ # _get_eval_string(index), _get_eval_string(val)))
658
+ #INTERP._eval(Kernel.format('set %s(%s) %s', @id,
659
+ # _get_eval_string(index), _get_eval_string(val)))
660
+ #INTERP._eval('set ' + @id + '(' + _get_eval_string(index) + ') ' +
661
+ # _get_eval_string(val))
662
+ end
663
+
664
+ def unset(*elems)
665
+ if elems.empty?
666
+ INTERP._eval(Kernel.format('global %s; unset %s', @id, @id))
667
+ #INTERP._eval(Kernel.format('unset %s', @id))
668
+ #INTERP._eval('unset ' + @id)
669
+ else
670
+ index = elems.collect{|idx| _get_eval_string(idx, true)}.join(',')
671
+ INTERP._eval(Kernel.format('global %s; unset %s(%s)', @id, @id, index))
672
+ #INTERP._eval(Kernel.format('global %s; unset %s(%s)',
673
+ # @id, @id, _get_eval_string(elem)))
674
+ #INTERP._eval(Kernel.format('unset %s(%s)', @id, tk_tcl2ruby(elem)))
675
+ #INTERP._eval('unset ' + @id + '(' + _get_eval_string(elem) + ')')
676
+ end
677
+ end
678
+ alias remove unset
679
+
680
+ end
681
+
682
+ protected :_value, :_element_value
683
+
684
+ def value
685
+ _to_default_type(_value)
686
+ end
687
+
688
+ def [](*idxs)
689
+ _to_default_element_type(idxs, _element_value(*idxs))
690
+ end
691
+
692
+ def set_value(val)
693
+ self.value = val
694
+ self
695
+ end
696
+
697
+ def to_hash
698
+ hash = {}
699
+ self.keys.each{|k|
700
+ hash[k] = self[k]
701
+ }
702
+ hash
703
+ end
704
+
705
+ def set_element_value(idxs, val)
706
+ if idxs.kind_of?(Array)
707
+ self[*idxs]=val
708
+ else
709
+ self[idxs]=val
710
+ end
711
+ self
712
+ end
713
+
714
+ def set_value_type(val)
715
+ self.default_value_type = val.class
716
+ self.value = val
717
+ self
718
+ end
719
+
720
+ alias value_type= set_value_type
721
+
722
+ def set_element_value_type(idxs, val)
723
+ self.set_default_element_value_type(idxs, val.class)
724
+ if idxs.kind_of?(Array)
725
+ self[*idxs]=val
726
+ else
727
+ self[idxs]=val
728
+ end
729
+ self
730
+ end
731
+
732
+ def numeric
733
+ number(_value)
734
+ end
735
+ def numeric_element(*idxs)
736
+ number(_element_value(*idxs))
737
+ end
738
+ def set_numeric(val)
739
+ case val
740
+ when Numeric
741
+ self.value=(val)
742
+ when TkVariable
743
+ self.value=(val.numeric)
744
+ else
745
+ raise ArgumentError, "Numeric is expected"
746
+ end
747
+ self
748
+ end
749
+ alias numeric= set_numeric
750
+ def set_numeric_element(idxs, val)
751
+ case val
752
+ when Numeric
753
+ val
754
+ when TkVariable
755
+ val = val.numeric
756
+ else
757
+ raise ArgumentError, "Numeric is expected"
758
+ end
759
+ if idxs.kind_of?(Array)
760
+ self[*idxs]=val
761
+ else
762
+ self[idxs]=val
763
+ end
764
+ self
765
+ end
766
+ def set_numeric_type(val)
767
+ @type = :numeric
768
+ self.numeric=(val)
769
+ self
770
+ end
771
+ alias numeric_type= set_numeric_type
772
+ def set_numeric_element_type(idxs, val)
773
+ self.set_default_element_value_type(idxs, :numeric)
774
+ self.set_numeric_element(idxs, val)
775
+ end
776
+
777
+ def bool
778
+ TkComm.bool(_value)
779
+ =begin
780
+ # see Tcl_GetBoolean man-page
781
+ case _value.downcase
782
+ when '0', 'false', 'no', 'off'
783
+ false
784
+ else
785
+ true
786
+ end
787
+ =end
788
+ end
789
+ def bool_element(*idxs)
790
+ TkComm.bool(_element_value(*idxs))
791
+ end
792
+ def set_bool(val)
793
+ if ! val
794
+ self.value = '0'
795
+ else
796
+ case val.to_s.downcase
797
+ when 'false', '0', 'no', 'off'
798
+ self.value = '0'
799
+ else
800
+ self.value = '1'
801
+ end
802
+ end
803
+ self
804
+ end
805
+ alias bool= set_bool
806
+ def set_bool_element(idxs, val)
807
+ if ! val
808
+ val = '0'
809
+ else
810
+ case val.to_s.downcase
811
+ when 'false', '0', 'no', 'off'
812
+ val = '0'
813
+ else
814
+ val = '1'
815
+ end
816
+ end
817
+ if idxs.kind_of?(Array)
818
+ self[*idxs]=val
819
+ else
820
+ self[idxs]=val
821
+ end
822
+ self
823
+ end
824
+ def set_bool_type(val)
825
+ @type = :bool
826
+ self.bool=(val)
827
+ self
828
+ end
829
+ alias bool_type= set_bool_type
830
+ def set_bool_element_type(idxs, val)
831
+ self.set_default_element_value_type(idxs, :bool)
832
+ self.set_bool_element(idxs, val)
833
+ end
834
+
835
+ def variable
836
+ # keeps a Tcl's variable name
837
+ TkVarAccess.new(self._value)
838
+ end
839
+ def variable_element(*idxs)
840
+ TkVarAccess.new(_element_value(*idxs))
841
+ end
842
+ def set_variable(var)
843
+ var = var.id if var.kind_of?(TkVariable)
844
+ self.value = var
845
+ self
846
+ end
847
+ alias variable= set_variable
848
+ def set_variable_element(idxs, var)
849
+ var = var.id if var.kind_of?(TkVariable)
850
+ if idxs.kind_of?(Array)
851
+ self[*idxs]=var
852
+ else
853
+ self[idxs]=var
854
+ end
855
+ self
856
+ end
857
+ def set_variable_type(var)
858
+ @type = :variable
859
+ var = var.id if var.kind_of?(TkVariable)
860
+ self.value = var
861
+ self
862
+ end
863
+ alias variable_type= set_variable_type
864
+ def set_variable_element_type(idxs, var)
865
+ self.set_default_element_value_type(idxs, :variable)
866
+ self.set_variable_element(idxs, var)
867
+ end
868
+
869
+ def window
870
+ TkComm.window(self._value)
871
+ end
872
+ def window_element(*idxs)
873
+ TkComm.window(_element_value(*idxs))
874
+ end
875
+ def set_window(win)
876
+ win = win._value if win.kind_of?(TkVariable)
877
+ self.value = win
878
+ self
879
+ end
880
+ alias window= set_window
881
+ def set_window_element(idxs, win)
882
+ win = win._value if win.kind_of?(TkVariable)
883
+ if idxs.kind_of?(Array)
884
+ self[*idxs]=win
885
+ else
886
+ self[idxs]=win
887
+ end
888
+ self
889
+ end
890
+ def set_window_type(win)
891
+ @type = :window
892
+ self.window=(win)
893
+ self
894
+ end
895
+ alias window_type= set_window_type
896
+ def set_window_element_type(idxs, win)
897
+ self.set_default_element_value_type(idxs, :window)
898
+ self.set_window_element(idxs, win)
899
+ end
900
+
901
+ def procedure
902
+ TkComm.procedure(self._value)
903
+ end
904
+ def procedure_element(*idxs)
905
+ TkComm.procedure(_element_value(*idxs))
906
+ end
907
+ def set_procedure(cmd)
908
+ self.value = cmd
909
+ self
910
+ end
911
+ alias procedure= set_procedure
912
+ def set_procedure_element(idxs, cmd)
913
+ cmd = cmd._value if cmd.kind_of?(TkVariable)
914
+ if idxs.kind_of?(Array)
915
+ self[*idxs]=cmd
916
+ else
917
+ self[idxs]=cmd
918
+ end
919
+ self
920
+ end
921
+ def set_procedure_type(cmd)
922
+ @type = :procedure
923
+ self.procedure=(cmd)
924
+ self
925
+ end
926
+ alias procedure_type= set_procedure_type
927
+ def set_procedure_element_type(idxs, cmd)
928
+ self.set_default_element_value_type(idxs, :procedure)
929
+ self.set_proceure_element(idxs, cmd)
930
+ end
931
+
932
+ def to_proc
933
+ cmd = self.procedure
934
+ if cmd.respond_to?(:call)
935
+ cmd
936
+ else
937
+ # cmd is a String
938
+ cmd.to_sym.to_proc
939
+ end
940
+ end
941
+
942
+ def to_i
943
+ number(_value).to_i
944
+ end
945
+ alias to_int to_i
946
+ def element_to_i(*idxs)
947
+ number(_element_value(*idxs)).to_i
948
+ end
949
+
950
+ def to_f
951
+ number(_value).to_f
952
+ end
953
+ def element_to_f(*idxs)
954
+ number(_element_value(*idxs)).to_f
955
+ end
956
+
957
+ def to_s
958
+ #string(value).to_s
959
+ _value
960
+ end
961
+ alias string to_s
962
+ alias to_str to_s
963
+ def element_to_s(*idxs)
964
+ _element_value(*idxs)
965
+ end
966
+ def string_element(*idxs)
967
+ _element_value(*idxs)
968
+ end
969
+ def set_string(val)
970
+ val = val._value if val.kind_of?(TkVariable)
971
+ self.value=val
972
+ self
973
+ end
974
+ alias string= set_string
975
+ def set_string_element(idxs, val)
976
+ val = val._value if val.kind_of?(TkVariable)
977
+ if idxs.kind_of?(Array)
978
+ self[*idxs]=val
979
+ else
980
+ self[idxs]=val
981
+ end
982
+ self
983
+ end
984
+ def set_string_type(val)
985
+ @type = :string
986
+ self.string=(val)
987
+ self
988
+ end
989
+ alias string_type= set_string_type
990
+ def set_string_element_type(idxs, val)
991
+ self.set_default_element_value_type(idxs, :string)
992
+ self.set_string_element(idxs, val)
993
+ end
994
+
995
+ def to_sym
996
+ _value.intern
997
+ end
998
+ alias symbol to_sym
999
+ def element_to_sym(*idxs)
1000
+ _element_value(*idxs).intern
1001
+ end
1002
+ alias symbol_element element_to_sym
1003
+ def set_symbol(val)
1004
+ val = val._value if val.kind_of?(TkVariable)
1005
+ self.value=val
1006
+ self
1007
+ end
1008
+ alias symbol= set_symbol
1009
+ def set_symbol_element(idxs, val)
1010
+ val = val._value if val.kind_of?(TkVariable)
1011
+ if idxs.kind_of?(Array)
1012
+ self[*idxs]=val
1013
+ else
1014
+ self[idxs]=val
1015
+ end
1016
+ self
1017
+ end
1018
+ def set_symbol_type(val)
1019
+ @type = :symbol
1020
+ self.value=(val)
1021
+ self
1022
+ end
1023
+ alias symbol_type= set_symbol_type
1024
+ def set_symbol_element_type(idxs, val)
1025
+ self.set_default_element_value_type(idxs, :symbol)
1026
+ self.set_symbol_element(idxs, val)
1027
+ end
1028
+
1029
+ def list
1030
+ #tk_split_list(value)
1031
+ tk_split_simplelist(_value)
1032
+ end
1033
+ alias to_a list
1034
+ alias to_ary list
1035
+ def list_element(*idxs)
1036
+ tk_split_simplelist(_element_value(*idxs))
1037
+ end
1038
+ alias element_to_a list_element
1039
+
1040
+ def numlist
1041
+ list.collect!{|val| number(val)}
1042
+ end
1043
+ def numlist_element(*idxs)
1044
+ list_element(*idxs).collect!{|val| number(val)}
1045
+ end
1046
+
1047
+ def set_list(val)
1048
+ case val
1049
+ when Array
1050
+ self.value=(val)
1051
+ when TkVariable
1052
+ self.value=(val.list)
1053
+ else
1054
+ raise ArgumentError, "Array is expected"
1055
+ end
1056
+ self
1057
+ end
1058
+ alias list= set_list
1059
+
1060
+ alias set_numlist set_list
1061
+ alias numlist= set_numlist
1062
+
1063
+ def set_list_element(idxs, val)
1064
+ case val
1065
+ when Array
1066
+ val
1067
+ when TkVariable
1068
+ val = val.list
1069
+ else
1070
+ raise ArgumentError, "Array is expected"
1071
+ end
1072
+ if idxs.kind_of?(Array)
1073
+ self[*idxs]=val
1074
+ else
1075
+ self[idxs]=val
1076
+ end
1077
+ self
1078
+ end
1079
+ alias set_numlist_element set_list_element
1080
+
1081
+ def set_list_type(val)
1082
+ @type = :list
1083
+ self.list=(val)
1084
+ self
1085
+ end
1086
+ alias list_type= set_list_type
1087
+ def set_list_element_type(idxs, val)
1088
+ self.set_default_element_value_type(idxs, :list)
1089
+ self.set_list_element(idxs, val)
1090
+ end
1091
+ def set_numlist_type(val)
1092
+ @type = :numlist
1093
+ self.numlist=(val)
1094
+ self
1095
+ end
1096
+ alias numlist_type= set_numlist_type
1097
+ def set_numlist_element_type(idxs, val)
1098
+ self.set_default_element_value_type(idxs, :numlist)
1099
+ self.set_numlist_element(idxs, val)
1100
+ end
1101
+
1102
+ def lappend(*elems)
1103
+ tk_call('lappend', @id, *elems)
1104
+ self
1105
+ end
1106
+ def element_lappend(idxs, *elems)
1107
+ if idxs.kind_of?(Array)
1108
+ idxs = idxs.collect{|idx| _get_eval_string(idx, true)}.join(',')
1109
+ end
1110
+ tk_call('lappend', "#{@id}(#{idxs})", *elems)
1111
+ self
1112
+ end
1113
+
1114
+ def lindex(idx)
1115
+ tk_call('lindex', self._value, idx)
1116
+ end
1117
+ alias lget lindex
1118
+ def element_lindex(elem_idxs, idx)
1119
+ if elem_idxs.kind_of?(Array)
1120
+ val = _element_value(*elem_idxs)
1121
+ else
1122
+ val = _element_value(elem_idxs)
1123
+ end
1124
+ tk_call('lindex', val, idx)
1125
+ end
1126
+ alias element_lget element_lindex
1127
+
1128
+ def lget_i(idx)
1129
+ number(lget(idx)).to_i
1130
+ end
1131
+ def element_lget_i(elem_idxs, idx)
1132
+ number(element_lget(elem_idxs, idx)).to_i
1133
+ end
1134
+
1135
+ def lget_f(idx)
1136
+ number(lget(idx)).to_f
1137
+ end
1138
+ def element_lget_f(elem_idxs, idx)
1139
+ number(element_lget(elem_idxs, idx)).to_f
1140
+ end
1141
+
1142
+ def lset(idx, val)
1143
+ tk_call('lset', @id, idx, val)
1144
+ self
1145
+ end
1146
+ def element_lset(elem_idxs, idx, val)
1147
+ if elem_idxs.kind_of?(Array)
1148
+ idxs = elem_idxs.collect{|i| _get_eval_string(i, true)}.join(',')
1149
+ end
1150
+ tk_call('lset', "#{@id}(#{idxs})", idx, val)
1151
+ self
1152
+ end
1153
+
1154
+ def inspect
1155
+ #Kernel.format "#<TkVariable: %s>", @id
1156
+ '#<TkVariable: ' + @id + '>'
1157
+ end
1158
+
1159
+ def coerce(other)
1160
+ case other
1161
+ when TkVariable
1162
+ [other._value, self._value]
1163
+ when String
1164
+ [other, self.to_s]
1165
+ when Symbol
1166
+ [other, self.to_sym]
1167
+ when Numeric
1168
+ [other, self.numeric]
1169
+ when Array
1170
+ [other, self.to_a]
1171
+ else
1172
+ [other, self._value]
1173
+ end
1174
+ end
1175
+
1176
+ def +@
1177
+ self.numeric
1178
+ end
1179
+ def -@
1180
+ -(self.numeric)
1181
+ end
1182
+
1183
+ def &(other)
1184
+ if other.kind_of?(Array)
1185
+ self.to_a & other.to_a
1186
+ else
1187
+ self.to_i & other.to_i
1188
+ end
1189
+ end
1190
+ def |(other)
1191
+ if other.kind_of?(Array)
1192
+ self.to_a | other.to_a
1193
+ else
1194
+ self.to_i | other.to_i
1195
+ end
1196
+ end
1197
+ def +(other)
1198
+ case other
1199
+ when Array
1200
+ self.to_a + other
1201
+ when String
1202
+ self._value + other
1203
+ else
1204
+ begin
1205
+ number(self._value) + other
1206
+ rescue
1207
+ self._value + other.to_s
1208
+ end
1209
+ end
1210
+ end
1211
+ def -(other)
1212
+ if other.kind_of?(Array)
1213
+ self.to_a - other
1214
+ else
1215
+ number(self._value) - other
1216
+ end
1217
+ end
1218
+ def *(other)
1219
+ num_or_str(self._value) * other
1220
+ #begin
1221
+ # number(self._value) * other
1222
+ #rescue
1223
+ # self._value * other
1224
+ #end
1225
+ end
1226
+ def /(other)
1227
+ number(self._value) / other
1228
+ end
1229
+ def %(other)
1230
+ num_or_str(self._value) % other
1231
+ #begin
1232
+ # number(self._value) % other
1233
+ #rescue
1234
+ # self._value % other
1235
+ #end
1236
+ end
1237
+ def **(other)
1238
+ number(self._value) ** other
1239
+ end
1240
+ def =~(other)
1241
+ self._value =~ other
1242
+ end
1243
+
1244
+ def ==(other)
1245
+ case other
1246
+ when TkVariable
1247
+ #self.equal?(other)
1248
+ self._value == other._value
1249
+ when String
1250
+ self.to_s == other
1251
+ when Symbol
1252
+ self.to_sym == other
1253
+ when Integer
1254
+ self.to_i == other
1255
+ when Float
1256
+ self.to_f == other
1257
+ when Array
1258
+ self.to_a == other
1259
+ when Hash
1260
+ # false if self is not an assoc array
1261
+ self._value == other
1262
+ else
1263
+ # false
1264
+ self._value == _get_eval_string(other)
1265
+ end
1266
+ end
1267
+
1268
+ def ===(other)
1269
+ if other.kind_of?(TkVariable)
1270
+ self.id == other.id
1271
+ else
1272
+ super
1273
+ end
1274
+ end
1275
+
1276
+ def zero?
1277
+ numeric.zero?
1278
+ end
1279
+ def nonzero?
1280
+ !(numeric.zero?)
1281
+ end
1282
+
1283
+ def <=>(other)
1284
+ if other.kind_of?(TkVariable)
1285
+ begin
1286
+ val = other.numeric
1287
+ other = val
1288
+ rescue
1289
+ other = other._value
1290
+ end
1291
+ elsif other.kind_of?(Numeric)
1292
+ begin
1293
+ return self.numeric <=> other
1294
+ rescue
1295
+ return self._value <=> other.to_s
1296
+ end
1297
+ elsif other.kind_of?(Array)
1298
+ return self.list <=> other
1299
+ else
1300
+ return self._value <=> other
1301
+ end
1302
+ end
1303
+
1304
+ def to_eval
1305
+ @id
1306
+ end
1307
+
1308
+ def trace_callback(elem, op)
1309
+ if @trace_var.kind_of? Array
1310
+ @trace_var.each{|m,e| e.call(self,elem,op) if m.index(op)}
1311
+ end
1312
+ if elem.kind_of?(String) && elem != ''
1313
+ if @trace_elem.kind_of?(Hash) && @trace_elem[elem].kind_of?(Array)
1314
+ @trace_elem[elem].each{|m,e| e.call(self,elem,op) if m.index(op)}
1315
+ end
1316
+ end
1317
+ end
1318
+
1319
+ def _check_trace_opt(opts)
1320
+ if opts.kind_of?(Array)
1321
+ opt_str = opts.map{|s| s.to_s}.join(' ')
1322
+ else
1323
+ opt_str = opts.to_s
1324
+ end
1325
+
1326
+ fail ArgumentError, 'null trace option' if opt_str.empty?
1327
+
1328
+ if opt_str =~ /[^arwu\s]/
1329
+ # new format (Tcl/Tk8.4+?)
1330
+ if opts.kind_of?(Array)
1331
+ opt_ary = opts.map{|opt| opt.to_s.strip}
1332
+ else
1333
+ opt_ary = opt_str.split(/\s+|\|/)
1334
+ opt_ary.delete('')
1335
+ end
1336
+ if USE_OLD_TRACE_OPTION_STYLE
1337
+ opt_ary.uniq.map{|opt|
1338
+ case opt
1339
+ when 'array'
1340
+ 'a'
1341
+ when 'read'
1342
+ 'r'
1343
+ when 'write'
1344
+ 'w'
1345
+ when 'unset'
1346
+ 'u'
1347
+ else
1348
+ fail ArgumentError, "unsupported trace option '#{opt}' on Tcl/Tk#{Tk::TCL_PATCHLEVEL}"
1349
+ end
1350
+ }.join
1351
+ else
1352
+ opt_ary
1353
+ end
1354
+ else
1355
+ # old format
1356
+ opt_ary = opt_str.delete('^arwu').split(//).uniq
1357
+ if USE_OLD_TRACE_OPTION_STYLE
1358
+ opt_ary.join
1359
+ else
1360
+ opt_ary.map{|c|
1361
+ case c
1362
+ when 'a'
1363
+ 'array'
1364
+ when 'r'
1365
+ 'read'
1366
+ when 'w'
1367
+ 'write'
1368
+ when 'u'
1369
+ 'unset'
1370
+ end
1371
+ }
1372
+ end
1373
+ end
1374
+ end
1375
+ private :_check_trace_opt
1376
+
1377
+ def trace(opts, cmd = Proc.new)
1378
+ opts = _check_trace_opt(opts)
1379
+ (@trace_var ||= []).unshift([opts,cmd])
1380
+
1381
+ if @trace_opts == nil
1382
+ TkVar_CB_TBL[@id] = self
1383
+ @trace_opts = opts.dup
1384
+ if USE_OLD_TRACE_OPTION_STYLE
1385
+ Tk.tk_call_without_enc('trace', 'variable',
1386
+ @id, @trace_opts, 'rb_var ' << @id)
1387
+ else
1388
+ Tk.tk_call_without_enc('trace', 'add', 'variable',
1389
+ @id, @trace_opts, 'rb_var ' << @id)
1390
+ end
1391
+ else
1392
+ newopts = @trace_opts.dup
1393
+ if USE_OLD_TRACE_OPTION_STYLE
1394
+ opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
1395
+ if newopts != @trace_opts
1396
+ Tk.tk_call_without_enc('trace', 'vdelete',
1397
+ @id, @trace_opts, 'rb_var ' << @id)
1398
+ @trace_opts.replace(newopts)
1399
+ Tk.tk_call_without_enc('trace', 'variable',
1400
+ @id, @trace_opts, 'rb_var ' << @id)
1401
+ end
1402
+ else
1403
+ newopts |= opts
1404
+ unless (newopts - @trace_opts).empty?
1405
+ Tk.tk_call_without_enc('trace', 'remove', 'variable',
1406
+ @id, @trace_opts, 'rb_var ' << @id)
1407
+ @trace_opts.replace(newopts)
1408
+ Tk.tk_call_without_enc('trace', 'add', 'variable',
1409
+ @id, @trace_opts, 'rb_var ' << @id)
1410
+ end
1411
+ end
1412
+ end
1413
+
1414
+ self
1415
+ end
1416
+
1417
+ def trace_element(elem, opts, cmd = Proc.new)
1418
+ if @elem
1419
+ fail(RuntimeError,
1420
+ "invalid for a TkVariable which denotes an element of Tcl's array")
1421
+ end
1422
+
1423
+ opts = _check_trace_opt(opts)
1424
+
1425
+ ((@trace_elem ||= {})[elem] ||= []).unshift([opts,cmd])
1426
+
1427
+ if @trace_opts == nil
1428
+ TkVar_CB_TBL[@id] = self
1429
+ @trace_opts = opts.dup
1430
+ if USE_OLD_TRACE_OPTION_STYLE
1431
+ Tk.tk_call_without_enc('trace', 'add', 'variable',
1432
+ @id, @trace_opts, 'rb_var ' << @id)
1433
+ else
1434
+ Tk.tk_call_without_enc('trace', 'variable',
1435
+ @id, @trace_opts, 'rb_var ' << @id)
1436
+ end
1437
+ else
1438
+ newopts = @trace_opts.dup
1439
+ if USE_OLD_TRACE_OPTION_STYLE
1440
+ opts.each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
1441
+ if newopts != @trace_opts
1442
+ Tk.tk_call_without_enc('trace', 'vdelete',
1443
+ @id, @trace_opts, 'rb_var ' << @id)
1444
+ @trace_opts.replace(newopts)
1445
+ Tk.tk_call_without_enc('trace', 'variable',
1446
+ @id, @trace_opts, 'rb_var ' << @id)
1447
+ end
1448
+ else
1449
+ newopts |= opts
1450
+ unless (newopts - @trace_opts).empty?
1451
+ Tk.tk_call_without_enc('trace', 'remove', 'variable',
1452
+ @id, @trace_opts, 'rb_var ' << @id)
1453
+ @trace_opts.replace(newopts)
1454
+ Tk.tk_call_without_enc('trace', 'add', 'variable',
1455
+ @id, @trace_opts, 'rb_var ' << @id)
1456
+ end
1457
+ end
1458
+ end
1459
+
1460
+ self
1461
+ end
1462
+
1463
+ def trace_info
1464
+ return [] unless @trace_var
1465
+ @trace_var.dup
1466
+ end
1467
+ alias trace_vinfo trace_info
1468
+
1469
+ def trace_info_for_element(elem)
1470
+ if @elem
1471
+ fail(RuntimeError,
1472
+ "invalid for a TkVariable which denotes an element of Tcl's array")
1473
+ end
1474
+ return [] unless @trace_elem
1475
+ return [] unless @trace_elem[elem]
1476
+ @trace_elem[elem].dup
1477
+ end
1478
+ alias trace_vinfo_for_element trace_info_for_element
1479
+
1480
+ def trace_remove(opts,cmd)
1481
+ return self unless @trace_var.kind_of? Array
1482
+
1483
+ opts = _check_trace_opt(opts)
1484
+
1485
+ idx = -1
1486
+ if USE_OLD_TRACE_OPTION_STYLE
1487
+ newopts = ''
1488
+ @trace_var.each_with_index{|e, i|
1489
+ if idx < 0 && e[1] == cmd
1490
+ diff = false
1491
+ ['a', 'r', 'w', 'u'].each{|c|
1492
+ break if (diff = e[0].index(c) ^ opts.index(c))
1493
+ }
1494
+ unless diff
1495
+ #find
1496
+ idx = i
1497
+ next
1498
+ end
1499
+ end
1500
+ e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
1501
+ }
1502
+ else
1503
+ newopts = []
1504
+ @trace_var.each_with_index{|e, i|
1505
+ if idx < 0 && e[1] == cmd &&
1506
+ e[0].size == opts.size && (e[0] - opts).empty?
1507
+ # find
1508
+ idx = i
1509
+ next
1510
+ end
1511
+ newopts |= e[0]
1512
+ }
1513
+ end
1514
+
1515
+ if idx >= 0
1516
+ @trace_var.delete_at(idx)
1517
+ else
1518
+ return self
1519
+ end
1520
+
1521
+ (@trace_elem ||= {}).each{|elem|
1522
+ @trace_elem[elem].each{|e|
1523
+ if USE_OLD_TRACE_OPTION_STYLE
1524
+ e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
1525
+ else
1526
+ newopts |= e[0]
1527
+ end
1528
+ }
1529
+ }
1530
+
1531
+ if USE_OLD_TRACE_OPTION_STYLE
1532
+ diff = false
1533
+ @trace_opts.each_byte{|c| break if (diff = ! newopts.index(c))}
1534
+ if diff
1535
+ Tk.tk_call_without_enc('trace', 'vdelete',
1536
+ @id, @trace_opts, 'rb_var ' << @id)
1537
+ @trace_opts.replace(newopts)
1538
+ unless @trace_opts.empty?
1539
+ Tk.tk_call_without_enc('trace', 'variable',
1540
+ @id, @trace_opts, 'rb_var ' << @id)
1541
+ end
1542
+ end
1543
+ else
1544
+ unless (@trace_opts - newopts).empty?
1545
+ Tk.tk_call_without_enc('trace', 'remove', 'variable',
1546
+ @id, @trace_opts, 'rb_var ' << @id)
1547
+ @trace_opts.replace(newopts)
1548
+ unless @trace_opts.empty?
1549
+ Tk.tk_call_without_enc('trace', 'add', 'variable',
1550
+ @id, @trace_opts, 'rb_var ' << @id)
1551
+ end
1552
+ end
1553
+ end
1554
+
1555
+ self
1556
+ end
1557
+ alias trace_delete trace_remove
1558
+ alias trace_vdelete trace_remove
1559
+
1560
+ def trace_remove_for_element(elem,opts,cmd)
1561
+ if @elem
1562
+ fail(RuntimeError,
1563
+ "invalid for a TkVariable which denotes an element of Tcl's array")
1564
+ end
1565
+ return self unless @trace_elem.kind_of? Hash
1566
+ return self unless @trace_elem[elem].kind_of? Array
1567
+
1568
+ opts = _check_trace_opt(opts)
1569
+
1570
+ idx = -1
1571
+ if USE_OLD_TRACE_OPTION_STYLE
1572
+ @trace_elem[elem].each_with_index{|e, i|
1573
+ if idx < 0 && e[1] == cmd
1574
+ diff = false
1575
+ ['a', 'r', 'w', 'u'].each{|c|
1576
+ break if (diff = e[0].index(c) ^ opts.index(c))
1577
+ }
1578
+ unless diff
1579
+ #find
1580
+ idx = i
1581
+ next
1582
+ end
1583
+ end
1584
+ }
1585
+ else
1586
+ @trace_elem[elem].each_with_index{|e, i|
1587
+ if idx < 0 && e[1] == cmd &&
1588
+ e[0].size == opts.size && (e[0] - opts).empty?
1589
+ # find
1590
+ idx = i
1591
+ next
1592
+ end
1593
+ }
1594
+ end
1595
+
1596
+ if idx >= 0
1597
+ @trace_elem[elem].delete_at(idx)
1598
+ else
1599
+ return self
1600
+ end
1601
+
1602
+ if USE_OLD_TRACE_OPTION_STYLE
1603
+ newopts = ''
1604
+ @trace_var.each{|e|
1605
+ e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
1606
+ }
1607
+ @trace_elem.each{|elem|
1608
+ @trace_elem[elem].each{|e|
1609
+ e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
1610
+ }
1611
+ }
1612
+ else
1613
+ newopts = []
1614
+ @trace_var.each{|e|
1615
+ newopts |= e[0]
1616
+ }
1617
+ @trace_elem.each{|elem|
1618
+ @trace_elem[elem].each{|e|
1619
+ e[0].each_byte{|c| newopts.concat(c.chr) unless newopts.index(c.chr)}
1620
+ }
1621
+ }
1622
+ end
1623
+
1624
+ if USE_OLD_TRACE_OPTION_STYLE
1625
+ diff = false
1626
+ @trace_opts.each_byte{|c| break if (diff = ! newopts.index(c))}
1627
+ if diff
1628
+ Tk.tk_call_without_enc('trace', 'vdelete',
1629
+ @id, @trace_opts, 'rb_var ' << @id)
1630
+ @trace_opts.replace(newopts)
1631
+ unless @trace_opts.empty?
1632
+ Tk.tk_call_without_enc('trace', 'variable',
1633
+ @id, @trace_opts, 'rb_var ' << @id)
1634
+ end
1635
+ end
1636
+ else
1637
+ unless (@trace_opts - newopts).empty?
1638
+ Tk.tk_call_without_enc('trace', 'remove', 'variable',
1639
+ @id, @trace_opts, 'rb_var ' << @id)
1640
+ @trace_opts.replace(newopts)
1641
+ unless @trace_opts.empty?
1642
+ Tk.tk_call_without_enc('trace', 'add', 'variable',
1643
+ @id, @trace_opts, 'rb_var ' << @id)
1644
+ end
1645
+ end
1646
+ end
1647
+
1648
+ self
1649
+ end
1650
+ alias trace_delete_for_element trace_remove_for_element
1651
+ alias trace_vdelete_for_element trace_remove_for_element
1652
+ end
1653
+
1654
+ class TkVarAccess<TkVariable
1655
+ def self.new(name, *args)
1656
+ if name.kind_of?(TkVariable)
1657
+ name.value = args[0] unless args.empty?
1658
+ return name
1659
+ end
1660
+
1661
+ name = name.to_s
1662
+ v = nil
1663
+ TkVar_ID_TBL.mutex.synchronize{
1664
+ if v = TkVar_ID_TBL[name]
1665
+ v.value = args[0] unless args.empty?
1666
+ return v
1667
+ else
1668
+ (v = self.allocate).instance_eval{
1669
+ @id = name
1670
+ TkVar_ID_TBL[@id] = self
1671
+ @var = @id
1672
+ }
1673
+ end
1674
+ }
1675
+
1676
+ v.instance_eval{ initialize(name, *args) }
1677
+ v
1678
+ end
1679
+
1680
+ def self.new_hash(name, *args)
1681
+ if name.kind_of?(TkVariable)
1682
+ unless name.is_hash?
1683
+ fail ArgumentError, "already exist as a scalar variable"
1684
+ end
1685
+ name.value = args[0] unless args.empty?
1686
+ return name
1687
+ end
1688
+
1689
+ name = name.to_s
1690
+ v = nil
1691
+ TkVar_ID_TBL.mutex.synchronize{
1692
+ if v = TkVar_ID_TBL[name]
1693
+ unless v.is_hash?
1694
+ fail ArgumentError, "already exist as a scalar variable"
1695
+ end
1696
+ v.value = args[0] unless args.empty?
1697
+ return v
1698
+ else
1699
+ (v = self.allocate).instance_eval{
1700
+ @id = name
1701
+ TkVar_ID_TBL[@id] = self
1702
+ @var = @id
1703
+ }
1704
+ end
1705
+ }
1706
+
1707
+ INTERP._invoke_without_enc('global', name)
1708
+ if args.empty? && INTERP._invoke_without_enc('array', 'exist', name) == '0'
1709
+ v.instance_eval{ initialize(name, {}) } # force creating
1710
+ else
1711
+ v.instance_eval{ initialize(name, *args) }
1712
+ end
1713
+ v
1714
+ end
1715
+
1716
+ def initialize(varname, val=nil)
1717
+ # @id = varname
1718
+ # TkVar_ID_TBL[@id] = self
1719
+
1720
+ # @var = @id
1721
+ @elem = nil
1722
+
1723
+ @def_default = false
1724
+ @default_val = nil
1725
+
1726
+ @trace_var = nil
1727
+ @trace_elem = nil
1728
+ @trace_opts = nil
1729
+
1730
+ @type = nil
1731
+ var = self
1732
+ @element_type = Hash.new{|k,v| var.default_value_type }
1733
+
1734
+ # is an element?
1735
+ if @id =~ /^([^(]+)\((.+)\)$/
1736
+ # is an element --> var == $1, elem == $2
1737
+ @var = $1
1738
+ @elem = $2
1739
+ end
1740
+
1741
+ # teach Tk-ip that @id is global var
1742
+ INTERP._invoke_without_enc('global', @var)
1743
+ =begin
1744
+ begin
1745
+ INTERP._invoke_without_enc('global', @id)
1746
+ rescue => e
1747
+ if @id =~ /^(.+)\([^()]+\)$/
1748
+ # is an element --> varname == $1
1749
+ INTERP._invoke_without_enc('global', $1)
1750
+ else
1751
+ fail e
1752
+ end
1753
+ end
1754
+ =end
1755
+
1756
+ if val
1757
+ if val.kind_of?(Hash)
1758
+ # assoc-array variable
1759
+ self[''] = 0
1760
+ self.clear
1761
+ end
1762
+ #s = '"' + _get_eval_string(val).gsub(/[\[\]$"]/, '\\\\\&') + '"' #"
1763
+ #s = '"' + _get_eval_string(val).gsub(/[\[\]$"\\]/, '\\\\\&') + '"' #"
1764
+ #INTERP._eval(Kernel.format('global %s; set %s %s', @id, @id, s))
1765
+ #INTERP._set_global_var(@id, _toUTF8(_get_eval_string(val)))
1766
+ self.value = val
1767
+ end
1768
+ end
1769
+ end
1770
+
1771
+ module Tk
1772
+ begin
1773
+ INTERP._invoke_without_enc('global', 'auto_path')
1774
+ auto_path = INTERP._invoke('set', 'auto_path')
1775
+ rescue => e
1776
+ begin
1777
+ INTERP._invoke_without_enc('global', 'env')
1778
+ auto_path = INTERP._invoke('set', 'env(TCLLIBPATH)')
1779
+ rescue => e
1780
+ auto_path = Tk::LIBRARY
1781
+ end
1782
+ end
1783
+
1784
+ AUTO_PATH = TkVarAccess.new('auto_path', auto_path)
1785
+
1786
+ =begin
1787
+ AUTO_OLDPATH = tk_split_simplelist(INTERP._invoke('set', 'auto_oldpath'))
1788
+ AUTO_OLDPATH.each{|s| s.freeze}
1789
+ AUTO_OLDPATH.freeze
1790
+ =end
1791
+
1792
+ TCL_PACKAGE_PATH = TkVarAccess.new('tcl_pkgPath')
1793
+ PACKAGE_PATH = TCL_PACKAGE_PATH
1794
+
1795
+ TCL_LIBRARY_PATH = TkVarAccess.new('tcl_libPath')
1796
+ LIBRARY_PATH = TCL_LIBRARY_PATH
1797
+
1798
+ TCL_PRECISION = TkVarAccess.new('tcl_precision')
1799
+ end